Details
-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
None
-
None
Description
(SVN r74221)
A call to ntoskrnl/fstub/fstubex.c:FstubAllocateDiskInformation() may incorrectly return STATUS_DEVICE_NOT_READY by checking and finding DiskInformation->DiskGeometry.DiskSize.QuadPart == 0.
The flow involved is the preceding cal (to the check for zero)l to FstubGetDiskGeometry() in FStubAllocateDiskInformation() which ultimately leads to
drivers\storage\class\class2\class2.c:ScsiClassReadDriveCapacity()
which makes a call to
ScsiClassSendSrbSynchronous()
which returns a successful status and data - but, apparently nowhere, after the successful ScsiClassSendSrbSynchronous(), is the appropriate DiskGeometry.DiskSize.QuadPart set to a non-zero value before returning to the point in FstubAllocateDiskInformation() where it is checked for zero and STATUS_DEVICE_NOT_READY incorrectly returned on that basis.
The failing scenario observed involved a sequence starting in
ntoskrnl/io/iomgr/arcname.c:CreateArcNamesDisk() which executes an IOCTL_DISK_GET_DRIVE_GEOMETRY that results in this failure, with the request being against a USB flash drive (from which boot is being attempted.)
Possible solution (but uncertain of absolute correctness/appropriateness) is to coincidentally set the DiskSize.QuadPart at the same time as modifying PartitionLength.QuadPart with its shift factor in ScsiClassReadDriveCapacity(), as in
deviceExtension->DiskGeometry->DiskSize.QuadPart =
deviceExtension->PartitionLength.QuadPart =
(deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
Note: Having attempted the above solution, some form of which I'm confident is necessary (i.e. DiskSize.QuadPart needs to be set somewhere), arcnames:CreateArcNamesDisk() is completing successfully, having found the boot device (which I was unable to do prior to that change)...
BUT subsequent to that a failure occurs where memory has apparently been corrupted (which of course leads me to the uncertainty about the absolute correctness of the above fix, since I haven't yet determined the root cause of the memory corruption. Even if the 'fix' is generally correct, I am also uncertain whether that is the most appropriate place to set DiskSize.QuadPart, or if that should be done elsewhere in-between that point and the incorrect check/return of STATUS_DRIVE_NOT_READY.)
This memory corruption may be the result of a data transfer from that device (appearing to occur in a following IopEnumerateDevices()), and as I've tracked through the arcnames scenario, I've been slightly suspicious regarding some possible recent changes to requests for reads/buffers based on page size, where perhaps all buffers involved may not actually be allocated large enough to hold a read transfer of page size or multiple.