Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernel32/tests/volume.c | 84 +++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index ed3897a6b94..3c4db6d60f3 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -18,14 +18,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "wine/test.h" +#include <stdio.h> +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" #include "winbase.h" #include "winioctl.h" #include "ntddstor.h" #include "winternl.h" -#include <stdio.h> #include "ddk/ntddcdvd.h" #include "ddk/mountmgr.h" +#include "wine/test.h"
#include <pshpack1.h> struct COMPLETE_DVD_LAYER_DESCRIPTOR @@ -1619,6 +1622,82 @@ static void test_GetVolumeInformationByHandle(void) CloseHandle( file ); }
+static void test_mountmgr_query_points(void) +{ + char input_buffer[64], output_buffer[2048]; + MOUNTMGR_MOUNT_POINTS *output = (MOUNTMGR_MOUNT_POINTS *)output_buffer; + MOUNTMGR_MOUNT_POINT *input = (MOUNTMGR_MOUNT_POINT *)input_buffer; + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE file; + + file = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, 0, 0, NULL, OPEN_EXISTING, 0, NULL ); + ok(file != INVALID_HANDLE_VALUE, "failed to open mountmgr, error %u\n", GetLastError()); + + io.Status = 0xdeadf00d; + io.Information = 0xdeadf00d; + status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, + IOCTL_MOUNTMGR_QUERY_POINTS, NULL, 0, NULL, 0 ); + ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); + todo_wine ok(io.Status == 0xdeadf00d, "got status %#x\n", io.Status); + todo_wine ok(io.Information == 0xdeadf00d, "got information %#Ix\n", io.Information); + + memset( input, 0, sizeof(*input) ); + + io.Status = 0xdeadf00d; + io.Information = 0xdeadf00d; + status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, + IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input) - 1, NULL, 0 ); + ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); + todo_wine ok(io.Status == 0xdeadf00d, "got status %#x\n", io.Status); + todo_wine ok(io.Information == 0xdeadf00d, "got information %#Ix\n", io.Information); + + io.Status = 0xdeadf00d; + io.Information = 0xdeadf00d; + status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, + IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input), NULL, 0 ); + todo_wine ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); + todo_wine ok(io.Status == 0xdeadf00d, "got status %#x\n", io.Status); + todo_wine ok(io.Information == 0xdeadf00d, "got information %#Ix\n", io.Information); + + io.Status = 0xdeadf00d; + io.Information = 0xdeadf00d; + memset(output_buffer, 0xcc, sizeof(output_buffer)); + status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, + IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input), output, sizeof(*output) - 1 ); + todo_wine ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); + todo_wine ok(io.Status == 0xdeadf00d, "got status %#x\n", io.Status); + todo_wine ok(io.Information == 0xdeadf00d, "got information %#Ix\n", io.Information); + todo_wine ok(output->Size == 0xcccccccc, "got size %u\n", output->Size); + ok(output->NumberOfMountPoints == 0xcccccccc, "got count %u\n", output->NumberOfMountPoints); + + io.Status = 0xdeadf00d; + io.Information = 0xdeadf00d; + memset(output_buffer, 0xcc, sizeof(output_buffer)); + status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, + IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input), output, sizeof(*output) ); + todo_wine ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status); + todo_wine ok(io.Status == STATUS_BUFFER_OVERFLOW, "got status %#x\n", io.Status); + todo_wine ok(io.Information == offsetof(MOUNTMGR_MOUNT_POINTS, MountPoints[0]), "got information %#Ix\n", io.Information); + ok(output->Size > offsetof(MOUNTMGR_MOUNT_POINTS, MountPoints[0]), "got size %u\n", output->Size); + todo_wine ok(output->NumberOfMountPoints && output->NumberOfMountPoints != 0xcccccccc, + "got count %u\n", output->NumberOfMountPoints); + + io.Status = 0xdeadf00d; + io.Information = 0xdeadf00d; + memset(output_buffer, 0xcc, sizeof(output_buffer)); + status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, + IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input), output, sizeof(output_buffer) ); + ok(!status, "got %#x\n", status); + ok(!io.Status, "got status %#x\n", io.Status); + ok(io.Information == output->Size, "got size %u, information %#Ix\n", output->Size, io.Information); + ok(output->Size > offsetof(MOUNTMGR_MOUNT_POINTS, MountPoints[0]), "got size %u\n", output->Size); + ok(output->NumberOfMountPoints && output->NumberOfMountPoints != 0xcccccccc, + "got count %u\n", output->NumberOfMountPoints); + + CloseHandle( file ); +} + START_TEST(volume) { hdll = GetModuleHandleA("kernel32.dll"); @@ -1650,4 +1729,5 @@ START_TEST(volume) test_cdrom_ioctl(); test_mounted_folder(); test_GetVolumeInformationByHandle(); + test_mountmgr_query_points(); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernel32/tests/volume.c | 6 +++--- dlls/mountmgr.sys/mountmgr.c | 12 ++++-------- 2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 3c4db6d60f3..4c6c7f9cb68 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -1656,7 +1656,7 @@ static void test_mountmgr_query_points(void) io.Information = 0xdeadf00d; status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input), NULL, 0 ); - todo_wine ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); + ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); todo_wine ok(io.Status == 0xdeadf00d, "got status %#x\n", io.Status); todo_wine ok(io.Information == 0xdeadf00d, "got information %#Ix\n", io.Information);
@@ -1665,10 +1665,10 @@ static void test_mountmgr_query_points(void) memset(output_buffer, 0xcc, sizeof(output_buffer)); status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input), output, sizeof(*output) - 1 ); - todo_wine ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); + ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); todo_wine ok(io.Status == 0xdeadf00d, "got status %#x\n", io.Status); todo_wine ok(io.Information == 0xdeadf00d, "got information %#Ix\n", io.Information); - todo_wine ok(output->Size == 0xcccccccc, "got size %u\n", output->Size); + ok(output->Size == 0xcccccccc, "got size %u\n", output->Size); ok(output->NumberOfMountPoints == 0xcccccccc, "got count %u\n", output->NumberOfMountPoints);
io.Status = 0xdeadf00d; diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index 50be9eb740f..a61140d847e 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -168,8 +168,9 @@ static NTSTATUS query_mount_points( void *buff, SIZE_T insize, MOUNTMGR_MOUNT_POINTS *info; struct mount_point *mount;
- /* sanity checks */ - if (input->SymbolicLinkNameOffset + input->SymbolicLinkNameLength > insize || + if (insize < sizeof(*input) || + outsize < sizeof(*info) || + input->SymbolicLinkNameOffset + input->SymbolicLinkNameLength > insize || input->UniqueIdOffset + input->UniqueIdLength > insize || input->DeviceNameOffset + input->DeviceNameLength > insize || input->SymbolicLinkNameOffset + input->SymbolicLinkNameLength < input->SymbolicLinkNameOffset || @@ -193,7 +194,7 @@ static NTSTATUS query_mount_points( void *buff, SIZE_T insize, if (size > outsize) { info = buff; - if (size >= sizeof(info->Size)) info->Size = size; + info->Size = size; iosb->Information = sizeof(info->Size); return STATUS_MORE_ENTRIES; } @@ -907,11 +908,6 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp ) switch(irpsp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_MOUNTMGR_QUERY_POINTS: - if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT)) - { - status = STATUS_INVALID_PARAMETER; - break; - } status = query_mount_points( irp->AssociatedIrp.SystemBuffer, irpsp->Parameters.DeviceIoControl.InputBufferLength, irpsp->Parameters.DeviceIoControl.OutputBufferLength,
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernel32/tests/volume.c | 4 ++-- dlls/mountmgr.sys/mountmgr.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 4c6c7f9cb68..2f1458fc50e 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -1676,8 +1676,8 @@ static void test_mountmgr_query_points(void) memset(output_buffer, 0xcc, sizeof(output_buffer)); status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input), output, sizeof(*output) ); - todo_wine ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status); - todo_wine ok(io.Status == STATUS_BUFFER_OVERFLOW, "got status %#x\n", io.Status); + ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status); + ok(io.Status == STATUS_BUFFER_OVERFLOW, "got status %#x\n", io.Status); todo_wine ok(io.Information == offsetof(MOUNTMGR_MOUNT_POINTS, MountPoints[0]), "got information %#Ix\n", io.Information); ok(output->Size > offsetof(MOUNTMGR_MOUNT_POINTS, MountPoints[0]), "got size %u\n", output->Size); todo_wine ok(output->NumberOfMountPoints && output->NumberOfMountPoints != 0xcccccccc, diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index a61140d847e..d5cf1ae5c4b 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -196,7 +196,7 @@ static NTSTATUS query_mount_points( void *buff, SIZE_T insize, info = buff; info->Size = size; iosb->Information = sizeof(info->Size); - return STATUS_MORE_ENTRIES; + return STATUS_BUFFER_OVERFLOW; }
input = HeapAlloc( GetProcessHeap(), 0, insize );
STATUS_MORE_ENTRIES is used for directory enumeration APIs, and signals that a continuation will be returned on the next call.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mountmgr.sys/mountmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index d5cf1ae5c4b..757983c3f0b 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -319,7 +319,7 @@ static void WINAPI query_dhcp_request_params( TP_CALLBACK_INSTANCE *instance, vo { if (offset >= sizeof(query->size)) query->size = offset; offset = sizeof(query->size); - irp->IoStatus.u.Status = STATUS_MORE_ENTRIES; + irp->IoStatus.u.Status = STATUS_BUFFER_OVERFLOW; goto err; } }
STATUS_MORE_ENTRIES is used for directory enumeration APIs, and signals that a continuation will be returned on the next call.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mountmgr.sys/mountmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index 757983c3f0b..1e018a9fc0b 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -877,7 +877,7 @@ static NTSTATUS enumerate_credentials( void *buff, SIZE_T insize, SIZE_T outsize { if (size >= sizeof(list->size)) list->size = size; iosb->Information = sizeof(list->size); - status = STATUS_MORE_ENTRIES; + status = STATUS_BUFFER_OVERFLOW; } else {
STATUS_MORE_ENTRIES is used for directory enumeration APIs, and signals that a continuation will be returned on the next call.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/nsiproxy.sys/device.c | 2 +- dlls/nsiproxy.sys/ip.c | 6 +++--- dlls/nsiproxy.sys/ndis.c | 2 +- dlls/nsiproxy.sys/tcp.c | 2 +- dlls/nsiproxy.sys/udp.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c index aa1d7a08bf7..c4db45dfad2 100644 --- a/dlls/nsiproxy.sys/device.c +++ b/dlls/nsiproxy.sys/device.c @@ -74,7 +74,7 @@ static void nsiproxy_enumerate_all( IRP *irp ) enum_all.count = in->count;
irp->IoStatus.u.Status = nsi_enumerate_all_ex( &enum_all ); - if (irp->IoStatus.u.Status == STATUS_SUCCESS || irp->IoStatus.u.Status == STATUS_MORE_ENTRIES) + if (irp->IoStatus.u.Status == STATUS_SUCCESS || irp->IoStatus.u.Status == STATUS_BUFFER_OVERFLOW) { irp->IoStatus.Information = out_len; *(DWORD *)out = enum_all.count; diff --git a/dlls/nsiproxy.sys/ip.c b/dlls/nsiproxy.sys/ip.c index e2e292f4b59..12fae3f2f12 100644 --- a/dlls/nsiproxy.sys/ip.c +++ b/dlls/nsiproxy.sys/ip.c @@ -754,7 +754,7 @@ static NTSTATUS ip_unicast_enumerate_all( int family, void *key_data, DWORD key_ freeifaddrs( addrs );
if (!want_data || num <= *count) *count = num; - else status = STATUS_MORE_ENTRIES; + else status = STATUS_BUFFER_OVERFLOW;
return status; } @@ -990,7 +990,7 @@ static NTSTATUS ipv4_neighbour_enumerate_all( void *key_data, DWORD key_size, vo #endif
if (!want_data || num <= *count) *count = num; - else status = STATUS_MORE_ENTRIES; + else status = STATUS_BUFFER_OVERFLOW;
return status; } @@ -1233,7 +1233,7 @@ static NTSTATUS ipv4_forward_enumerate_all( void *key_data, DWORD key_size, void #endif
if (!want_data || num <= *count) *count = num; - else status = STATUS_MORE_ENTRIES; + else status = STATUS_BUFFER_OVERFLOW;
return status; } diff --git a/dlls/nsiproxy.sys/ndis.c b/dlls/nsiproxy.sys/ndis.c index 40a60e45c46..bf237ea16db 100644 --- a/dlls/nsiproxy.sys/ndis.c +++ b/dlls/nsiproxy.sys/ndis.c @@ -488,7 +488,7 @@ static NTSTATUS ifinfo_enumerate_all( void *key_data, DWORD key_size, void *rw_d LeaveCriticalSection( &if_list_cs );
if (!want_data || num <= *count) *count = num; - else status = STATUS_MORE_ENTRIES; + else status = STATUS_BUFFER_OVERFLOW;
return status; } diff --git a/dlls/nsiproxy.sys/tcp.c b/dlls/nsiproxy.sys/tcp.c index 603aefadfe9..f9ddf1a2b23 100644 --- a/dlls/nsiproxy.sys/tcp.c +++ b/dlls/nsiproxy.sys/tcp.c @@ -736,7 +736,7 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key * #endif
if (!want_data || num <= *count) *count = num; - else status = STATUS_MORE_ENTRIES; + else status = STATUS_BUFFER_OVERFLOW;
heap_free( pid_map ); heap_free( addr_scopes ); diff --git a/dlls/nsiproxy.sys/udp.c b/dlls/nsiproxy.sys/udp.c index 190eb7f21f5..112170782f7 100644 --- a/dlls/nsiproxy.sys/udp.c +++ b/dlls/nsiproxy.sys/udp.c @@ -390,7 +390,7 @@ static NTSTATUS udp_endpoint_enumerate_all( void *key_data, DWORD key_size, void #endif
if (!want_data || num <= *count) *count = num; - else status = STATUS_MORE_ENTRIES; + else status = STATUS_BUFFER_OVERFLOW;
heap_free( pid_map ); heap_free( addr_scopes );
Likely a similar treatment should be given to other kernelbase APIs, but it's not immediately clear which.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernelbase/file.c | 7 ++++++- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index d21ad299d1f..74e713b7593 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -4116,7 +4116,12 @@ BOOL WINAPI DECLSPEC_HOTPATCH DeviceIoControl( HANDLE handle, DWORD code, void * in_buff, in_count, out_buff, out_count );
if (returned) *returned = piosb->Information; - return set_ntstatus( status ); + if (status == STATUS_PENDING || !NT_SUCCESS( status )) + { + SetLastError( RtlNtStatusToDosError( status )); + return FALSE; + } + return TRUE; }
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index dc10497caee..9ee2f55a826 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -663,17 +663,17 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) size = 0xdeadf00d; SetLastError(0xdeadf00d); ret = DeviceIoControl(device, ioctl, params, sizeof(*params), buffer, sizeof(buffer), &size, NULL); - todo_wine_if (NT_SUCCESS(expect_status) != !params->iosb_status) + todo_wine_if (NT_SUCCESS(expect_status) != NT_SUCCESS(params->iosb_status)) ok(ret == NT_SUCCESS(expect_status), "got %d\n", ret); if (NT_SUCCESS(expect_status)) { - todo_wine_if (params->iosb_status) + todo_wine_if (!NT_SUCCESS(params->iosb_status)) ok(GetLastError() == 0xdeadf00d, "got error %u\n", GetLastError()); } else { todo_wine_if (RtlNtStatusToDosError(expect_status) != RtlNtStatusToDosError(params->iosb_status) - || params->iosb_status == STATUS_PENDING) + || NT_SUCCESS(params->iosb_status)) ok(GetLastError() == RtlNtStatusToDosError(expect_status), "got error %u\n", GetLastError()); } if (NT_ERROR(expect_status))
Zebediah Figura zfigura@codeweavers.com writes:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
dlls/kernel32/tests/volume.c | 84 +++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-)
The tests fail here:
tools/runtest -q -P wine -T . -M kernel32.dll -p dlls/kernel32/tests/kernel32_test.exe volume && touch dlls/kernel32/tests/volume.ok volume.c:1126: Tests skipped: IOCTL_DVD_READ_STRUCTURE not supported: 87 volume.c:1315: Tests skipped: Not enough permissions to create a mounted folder. volume.c:1691: Test failed: got 0x105 volume.c:1692: Test failed: got status 0x105 volume.c:1693: Test failed: got size 2518, information 0x4 volume.c:1695: Test failed: got count 3435973836 make: *** [Makefile:68203: dlls/kernel32/tests/volume.ok] Error 4