From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernel32/tests/volume.c | 11 +++++++++++ dlls/mountmgr.sys/device.c | 27 +++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index e331b373206..aa403abf52d 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -595,6 +595,7 @@ static void test_disk_extents(void) DWORD size; HANDLE handle; static DWORD data[16]; + VOLUME_DISK_EXTENTS *d;
handle = CreateFileA( "\\.\c:", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); if (handle == INVALID_HANDLE_VALUE) @@ -611,8 +612,18 @@ static void test_disk_extents(void) CloseHandle( handle ); return; } + size = 0xdeadbeef; + ret = DeviceIoControl( handle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, data, + sizeof(data), &data, sizeof(*d) - 4, &size, NULL ); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got ret %d, error %lu.\n", ret, GetLastError()); + ok(size == 0xdeadbeef, "expected 32, got %lu\n", size); + ret = DeviceIoControl( handle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, data, + sizeof(data), &data, sizeof(*d), &size, NULL ); ok(ret, "DeviceIoControl failed %lu\n", GetLastError()); ok(size == 32, "expected 32, got %lu\n", size); + d = (VOLUME_DISK_EXTENTS *)data; + ok(d->NumberOfDiskExtents == 1, "got %lu.\n", d->NumberOfDiskExtents); + ok(d->Extents[0].ExtentLength.QuadPart > 0, "got %lu.\n", d->NumberOfDiskExtents); CloseHandle( handle ); }
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index 271f2c86d77..d0308a3c993 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -1848,11 +1848,30 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp ) break; case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: { - DWORD len = min( 32, irpsp->Parameters.DeviceIoControl.OutputBufferLength ); + struct size_info size_info = { 0, 0, 0, 0, 0 }; + struct get_volume_size_info_params params = { dev->unix_mount, &size_info }; + VOLUME_DISK_EXTENTS info = { 0 };
- FIXME( "returning zero-filled buffer for IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS\n" ); - memset( irp->AssociatedIrp.SystemBuffer, 0, len ); - irp->IoStatus.Information = len; + if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(info)) + { + TRACE( "len %lu is too small.\n", irpsp->Parameters.DeviceIoControl.OutputBufferLength ); + status = STATUS_INVALID_PARAMETER; + break; + } + FIXME( "IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS semi-stub.\n" ); + + info.NumberOfDiskExtents = 1; + info.Extents[0].DiskNumber = dev->devnum.DeviceNumber; + info.Extents[0].StartingOffset.QuadPart = 0; + + if ((status = MOUNTMGR_CALL( get_volume_size_info, ¶ms )) == STATUS_SUCCESS) + { + info.Extents[0].ExtentLength.QuadPart = size_info.total_allocation_units + * size_info.sectors_per_allocation_unit + * size_info.bytes_per_sector; + } + memcpy( irp->AssociatedIrp.SystemBuffer, &info, sizeof(info) ); + irp->IoStatus.Information = sizeof(info); status = STATUS_SUCCESS; break; }