Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions source/usbhsfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ static Mutex g_devoptabDefaultDeviceMutex = 0;

static const u8 g_microsoftBasicDataPartitionGuid[0x10] = { 0xA2, 0xA0, 0xD0, 0xEB, 0xE5, 0xB9, 0x33, 0x44, 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 }; /* EBD0A0A2-B9E5-4433-87C0-68B6B72699C7. */
static const u8 g_linuxFilesystemDataGuid[0x10] = { 0xAF, 0x3D, 0xC6, 0x0F, 0x83, 0x84, 0x72, 0x47, 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4 }; /* 0FC63DAF-8483-4772-8E79-3D69D8477DE4. */
static const u8 g_emptyPartitionGuid[0x10] = {0};

static u32 g_fileSystemMountFlags = UsbHsFsMountFlags_Default;

Expand Down Expand Up @@ -714,6 +715,16 @@ static void usbHsFsMountParseGuidPartitionTableEntry(UsbHsFsDriveLogicalUnitCont
u64 entry_size = ((gpt_entry->lba_end + 1) - gpt_entry->lba_start);
UsbHsFsDriveLogicalUnitFileSystemType fs_type = UsbHsFsDriveLogicalUnitFileSystemType_Invalid;

/* Discard entries whose LBA span falls outside this logical unit before any branch below issues a read. */
/* This filters out uninitialized/garbage partition array entries (e.g. a type GUID 0xF4-filled with an */
/* lba_start of 0xF4F4F4F4F4F4F4F4), whose reads would target absurd LBAs that can stall flaky USB drives, */
/* force a BOT reset and knock them off the bus. */
Comment on lines +719 to +721

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section of the comment block isn't really necessary here. It is more closely related to the extra memcmp call you're adding.

if (entry_lba >= lun_ctx->block_count || gpt_entry->lba_end >= lun_ctx->block_count || gpt_entry->lba_end < entry_lba)
{
USBHSFS_LOG_MSG("Discarding GPT partition entry with out-of-range LBA span (0x%lX - 0x%lX) (interface %d, LUN %u).", entry_lba, gpt_entry->lba_end, lun_ctx->usb_if_id, lun_ctx->lun);
return;
}

if (!memcmp(gpt_entry->type_guid, g_microsoftBasicDataPartitionGuid, sizeof(g_microsoftBasicDataPartitionGuid)))
{
/* We're dealing with a Microsoft Basic Data Partition entry. */
Expand All @@ -738,6 +749,23 @@ static void usbHsFsMountParseGuidPartitionTableEntry(UsbHsFsDriveLogicalUnitCont
#ifdef GPL_BUILD
/* Check if this LBA points to a valid EXT superblock. Register the EXT volume if so. */
fs_type = usbHsFsMountInspectExtSuperBlock(lun_ctx, block, entry_lba);
#endif
} else
if (memcmp(gpt_entry->type_guid, g_emptyPartitionGuid, sizeof(g_emptyPartitionGuid)))
{
/* This entry carries a non-empty type GUID that none of the branches above recognised; entries with an */
/* all-zero (empty) type GUID are unused and skipped here. Some tools place standard exFAT/FAT/NTFS (or */
/* even EXT) volumes behind such GUIDs -- e.g. the Windows Recovery Environment partition created by */
/* Windows Setup uses type GUID DE94BBA4-06D1-4D40-A16A-BFD50179D6AC yet holds an NTFS volume. Probe the */
/* VBR (and, on GPL builds, the EXT superblock) before skipping the entry. */
USBHSFS_LOG_MSG("Found unrecognized GPT partition type at LBA 0x%lX. Probing VBR (interface %d, LUN %u).", entry_lba, lun_ctx->usb_if_id, lun_ctx->lun);
fs_type = usbHsFsMountInspectVolumeBootRecord(lun_ctx, block, entry_lba);
#ifdef GPL_BUILD
if (fs_type == UsbHsFsDriveLogicalUnitFileSystemType_Invalid)
{
/* The entry may instead point to an EXT volume sitting behind a non-standard GUID. */
fs_type = usbHsFsMountInspectExtSuperBlock(lun_ctx, block, entry_lba);
}
#endif
}

Expand Down