Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/kernel32/tests/volume.c | 89 +++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index ed3897a6b94..1670ab69222 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,87 @@ static void test_GetVolumeInformationByHandle(void) CloseHandle( file ); }
+static void test_mountmgr_query_points(void) +{ + char input_buffer[64]; + MOUNTMGR_MOUNT_POINTS *output; + MOUNTMGR_MOUNT_POINT *input = (MOUNTMGR_MOUNT_POINT *)input_buffer; + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE file; + + output = malloc(1024); + + 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, 0xcc, sizeof(*output)); + 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, 0xcc, sizeof(*output)); + 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); + + output = realloc(output, output->Size); + + io.Status = 0xdeadf00d; + io.Information = 0xdeadf00d; + status = NtDeviceIoControlFile( file, NULL, NULL, NULL, &io, + IOCTL_MOUNTMGR_QUERY_POINTS, input, sizeof(*input), output, output->Size ); + 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 ); + + free(output); +} + START_TEST(volume) { hdll = GetModuleHandleA("kernel32.dll"); @@ -1650,4 +1734,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 1670ab69222..4915e744eba 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -1658,7 +1658,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);
@@ -1667,10 +1667,10 @@ static void test_mountmgr_query_points(void) memset(output, 0xcc, sizeof(*output)); 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 4915e744eba..cb35de6add1 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -1678,8 +1678,8 @@ static void test_mountmgr_query_points(void) memset(output, 0xcc, sizeof(*output)); 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 );
Signed-off-by: Huw Davies huw@codeweavers.com
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 312442f6e7c..8ede0e55513 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))
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=96817
Your paranoid android.
=== w7u_el (32 bit report) ===
ntoskrnl.exe: ntoskrnl: Timeout