diff --git a/drivers/filesystems/fs_rec/fs_rec.h b/drivers/filesystems/fs_rec/fs_rec.h index db3112b06c78c..bd78691a9ca5e 100644 --- a/drivers/filesystems/fs_rec/fs_rec.h +++ b/drivers/filesystems/fs_rec/fs_rec.h @@ -137,6 +137,9 @@ typedef struct BIOS_PARAMETER_BLOCK USHORT BackupBootSector; } BIOS_PARAMETER_BLOCK, *PBIOS_PARAMETER_BLOCK; +/* UDFS Tag Identifier for Anchor Volume Descriptor Pointer (ECMA-167 7.2) */ +#define UDFS_TAG_ID_AVDP 0x0002 + /* UDFS Structures */ #include typedef struct _TAG diff --git a/drivers/filesystems/fs_rec/udfs.c b/drivers/filesystems/fs_rec/udfs.c index 655b6ea28c627..c2bf6af10da43 100644 --- a/drivers/filesystems/fs_rec/udfs.c +++ b/drivers/filesystems/fs_rec/udfs.c @@ -29,7 +29,12 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject, int i; PAGED_CODE(); - Offset.QuadPart = 16 * SectorSize; + /* Per ECMA-167 section 8.4.1, the Volume Recognition Sequence starts at + * a fixed byte offset of 32768, regardless of the physical sector size. + * Using 16 * SectorSize is only correct for 2048-byte sectors (CD-ROM); + * for 512-byte sector devices (e.g. VHDs) it gives 8192 instead of 32768, + * causing the VRS to be missed entirely. */ + Offset.QuadPart = UDFS_VRS_START_OFFSET; for (i = 0; i < 16; i++) { if (!FsRecReadBlock(DeviceObject, @@ -55,6 +60,7 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject, { DPRINT("NSR03 found\n"); ret = TRUE; + break; } if (!strncmp((const char*)VolumeStructDesc->Ident, @@ -63,6 +69,7 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject, { DPRINT("NSR02 found\n"); ret = TRUE; + break; } if (!strncmp((const char*)VolumeStructDesc->Ident, @@ -98,6 +105,34 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject, if (VolumeStructDesc) ExFreePool(VolumeStructDesc); + + /* If the VRS scan did not find an NSR descriptor, fall back to checking + * for the Anchor Volume Descriptor Pointer at sector 256. This covers + * disks where the VRS is absent or could not be read, and mirrors the + * detection approach used by the UDFS driver itself. */ + if (!ret) + { + PAVDP AnchorVDP = NULL; + + Offset.QuadPart = (LONGLONG)UDFS_AVDP_SECTOR * SectorSize; + if (FsRecReadBlock(DeviceObject, + &Offset, + sizeof(AVDP), + SectorSize, + (PVOID *)&AnchorVDP, + NULL)) + { + /* Tag identifier 2 = Anchor Volume Descriptor Pointer (ECMA-167 7.2) */ + if (AnchorVDP->DescriptorTag.Identifier == UDFS_TAG_ID_AVDP && + AnchorVDP->DescriptorTag.Location == UDFS_AVDP_SECTOR) + { + DPRINT("AVDP found at sector 256\n"); + ret = TRUE; + } + ExFreePool(AnchorVDP); + } + } + return ret; } diff --git a/drivers/filesystems/udfs/udfs_reg.inf b/drivers/filesystems/udfs/udfs_reg.inf index 2822dbdce371c..532ecdcdbf918 100644 --- a/drivers/filesystems/udfs/udfs_reg.inf +++ b/drivers/filesystems/udfs/udfs_reg.inf @@ -1,7 +1,7 @@ ; UDF Filesystem driver [AddReg] HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Group",0x00000000,"File System" +HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Group",0x00000000,"Boot File System" HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","ImagePath",0x00020000,"system32\drivers\udfs.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Start",0x00010001,0x00000003 HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Type",0x00010001,0x00000002