Signed-off-by: Zebediah Figura z.figura12@gmail.com --- I know of no application yet that requires this behaviour, or in fact even tries to query file/object information from a device file. These tests are rather meant to illustrate how ObjectNameInformation is implemented for files, which in turn may help to inform our implementation for server-based objects such as regular files and named pipes.
dlls/ntoskrnl.exe/tests/driver.c | 120 +++++++++++++++++++++++++++-- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 114 +++++++++++++++++++++++++++ 2 files changed, 226 insertions(+), 8 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 0671a56efc7..d3f62879a40 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -37,6 +37,19 @@
#include "utils.h"
+/* memcmp() isn't exported from ntoskrnl on i386 */ +static int kmemcmp( const void *ptr1, const void *ptr2, size_t n ) +{ + const unsigned char *p1, *p2; + + for (p1 = ptr1, p2 = ptr2; n; n--, p1++, p2++) + { + if (*p1 < *p2) return -1; + if (*p1 > *p2) return 1; + } + return 0; +} + static const WCHAR device_name[] = {'\','D','e','v','i','c','e', '\','W','i','n','e','T','e','s','t','D','r','i','v','e','r',0}; static const WCHAR upper_name[] = {'\','D','e','v','i','c','e', @@ -55,6 +68,13 @@ static PETHREAD create_irp_thread;
NTSTATUS WINAPI ZwQueryInformationProcess(HANDLE,PROCESSINFOCLASS,void*,ULONG,ULONG*);
+struct file_context +{ + DWORD id; + ULONG namelen; + WCHAR name[10]; +}; + static void *get_proc_address(const char *name) { UNICODE_STRING name_u; @@ -2175,15 +2195,15 @@ static NTSTATUS get_fscontext(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *inf { ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength; char *buffer = irp->AssociatedIrp.SystemBuffer; - DWORD *context = stack->FileObject->FsContext; + struct file_context *context = stack->FileObject->FsContext;
- if (!buffer || !context) + if (!buffer) return STATUS_ACCESS_VIOLATION;
if (length < sizeof(DWORD)) return STATUS_BUFFER_TOO_SMALL;
- *(DWORD*)buffer = *context; + *(DWORD*)buffer = context->id; *info = sizeof(DWORD); return STATUS_SUCCESS; } @@ -2271,13 +2291,21 @@ static NTSTATUS test_completion_ioctl(DEVICE_OBJECT *device, IRP *irp) static NTSTATUS WINAPI driver_Create(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); - DWORD *context = ExAllocatePool(PagedPool, sizeof(*context)); + struct file_context *context = ExAllocatePool(PagedPool, sizeof(*context));
- last_created_file = irpsp->FileObject; - ++create_count; - if (context) - *context = create_count; + if (!context) + { + irp->IoStatus.Status = STATUS_NO_MEMORY; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_NO_MEMORY; + } + + context->id = ++create_count; + context->namelen = min(irpsp->FileObject->FileName.Length, sizeof(context->name)); + memcpy(context->name, irpsp->FileObject->FileName.Buffer, context->namelen); irpsp->FileObject->FsContext = context; + + last_created_file = irpsp->FileObject; create_caller_thread = KeGetCurrentThread(); create_irp_thread = irp->Tail.Overlay.Thread;
@@ -2356,6 +2384,81 @@ static NTSTATUS WINAPI driver_FlushBuffers(DEVICE_OBJECT *device, IRP *irp) return STATUS_PENDING; }
+static BOOL compare_file_name(const struct file_context *context, const WCHAR *expect) +{ + return context->namelen == wcslen(expect) * sizeof(WCHAR) + && !kmemcmp(context->name, expect, context->namelen); +} + +static NTSTATUS WINAPI driver_QueryInformation(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + NTSTATUS ret; + + switch (stack->Parameters.QueryFile.FileInformationClass) + { + case FileNameInformation: + { + const struct file_context *context = stack->FileObject->FsContext; + FILE_NAME_INFORMATION *info = irp->AssociatedIrp.SystemBuffer; + ULONG len; + + if (stack->Parameters.QueryFile.Length < sizeof(*info)) + { + ret = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + if (compare_file_name(context, L"\notimpl")) + { + ret = STATUS_NOT_IMPLEMENTED; + break; + } + else if (compare_file_name(context, L"")) + { + ret = STATUS_INVALID_DEVICE_REQUEST; + break; + } + else if (compare_file_name(context, L"\badparam")) + { + ret = STATUS_INVALID_PARAMETER; + break; + } + else if (compare_file_name(context, L"\genfail")) + { + ret = STATUS_UNSUCCESSFUL; + break; + } + else if (compare_file_name(context, L"\badtype")) + { + ret = STATUS_OBJECT_TYPE_MISMATCH; + break; + } + + len = stack->Parameters.QueryFile.Length - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName); + if (len < context->namelen) + ret = STATUS_BUFFER_OVERFLOW; + else + { + len = context->namelen; + ret = STATUS_SUCCESS; + } + irp->IoStatus.Information = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + len; + info->FileNameLength = context->namelen; + memcpy(info->FileName, context->name, len); + break; + } + + default: + ret = STATUS_NOT_IMPLEMENTED; + break; + } + + irp->IoStatus.Status = ret; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return ret; +} + static NTSTATUS WINAPI driver_Close(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); @@ -2400,6 +2503,7 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry) driver->MajorFunction[IRP_MJ_CREATE] = driver_Create; driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = driver_IoControl; driver->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = driver_FlushBuffers; + driver->MajorFunction[IRP_MJ_QUERY_INFORMATION] = driver_QueryInformation; driver->MajorFunction[IRP_MJ_CLOSE] = driver_Close;
RtlInitUnicodeString(&nameW, IoDriverObjectTypeW); diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index b4ef9d0dcb7..61b1e401c56 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -493,6 +493,119 @@ static void test_return_status(void) ok(ret_size == 3, "got size %u\n", ret_size); }
+static BOOL compare_unicode_string(const WCHAR *buffer, ULONG len, const WCHAR *expect) +{ + return len == wcslen(expect) * sizeof(WCHAR) && !memcmp(buffer, expect, len); +} + +static void test_object_info(void) +{ + char buffer[200]; + OBJECT_NAME_INFORMATION *name_info = (OBJECT_NAME_INFORMATION *)buffer; + OBJECT_TYPE_INFORMATION *type_info = (OBJECT_TYPE_INFORMATION *)buffer; + FILE_NAME_INFORMATION *file_info = (FILE_NAME_INFORMATION *)buffer; + HANDLE file; + NTSTATUS status; + IO_STATUS_BLOCK io; + ULONG size; + + status = NtQueryObject(device, ObjectNameInformation, buffer, sizeof(buffer), NULL); + ok(!status, "got %#x\n", status); + todo_wine ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\Device\WineTestDriver"), + "wrong name %s\n", debugstr_w(name_info->Name.Buffer)); + + status = NtQueryObject(device, ObjectTypeInformation, buffer, sizeof(buffer), NULL); + ok(!status, "got %#x\n", status); + ok(compare_unicode_string(type_info->TypeName.Buffer, type_info->TypeName.Length, L"File"), + "wrong name %s\n", debugstr_wn(type_info->TypeName.Buffer, type_info->TypeName.Length / sizeof(WCHAR))); + + status = NtQueryInformationFile(device, &io, buffer, sizeof(buffer), FileNameInformation); + todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got %#x\n", status); + + file = CreateFileA("\\.\WineTestDriver\subfile", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + todo_wine ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + if (file == INVALID_HANDLE_VALUE) return; + + memset(buffer, 0xcc, sizeof(buffer)); + status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), &size); + ok(!status, "got %#x\n", status); + ok(size == sizeof(*name_info) + sizeof(L"\Device\WineTestDriver\subfile"), "wrong size %u\n", size); + ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\Device\WineTestDriver\subfile"), + "wrong name %s\n", debugstr_w(name_info->Name.Buffer)); + + memset(buffer, 0xcc, sizeof(buffer)); + status = NtQueryObject(file, ObjectNameInformation, buffer, size - 2, &size); + ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status); + ok(size == sizeof(*name_info) + sizeof(L"\Device\WineTestDriver\subfile"), "wrong size %u\n", size); + ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\Device\WineTestDriver\subfil"), + "wrong name %s\n", debugstr_w(name_info->Name.Buffer)); + + memset(buffer, 0xcc, sizeof(buffer)); + status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(*name_info), &size); + ok(status == STATUS_BUFFER_OVERFLOW, "got %#x\n", status); + ok(size == sizeof(*name_info) + sizeof(L"\Device\WineTestDriver\subfile"), "wrong size %u\n", size); + + status = NtQueryObject(file, ObjectTypeInformation, buffer, sizeof(buffer), NULL); + ok(!status, "got %#x\n", status); + ok(compare_unicode_string(type_info->TypeName.Buffer, type_info->TypeName.Length, L"File"), + "wrong name %s\n", debugstr_wn(type_info->TypeName.Buffer, type_info->TypeName.Length / sizeof(WCHAR))); + + status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation); + ok(!status, "got %#x\n", status); + ok(compare_unicode_string(file_info->FileName, file_info->FileNameLength, L"\subfile"), + "wrong name %s\n", debugstr_wn(file_info->FileName, file_info->FileNameLength / sizeof(WCHAR))); + + CloseHandle(file); + + file = CreateFileA("\\.\WineTestDriver\notimpl", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL); + ok(!status, "got %#x\n", status); + ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\Device\WineTestDriver"), + "wrong name %s\n", debugstr_w(name_info->Name.Buffer)); + + status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation); + ok(status == STATUS_NOT_IMPLEMENTED, "got %#x\n", status); + + CloseHandle(file); + + file = CreateFileA("\\.\WineTestDriver\badparam", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL); + ok(!status, "got %#x\n", status); + ok(compare_unicode_string(name_info->Name.Buffer, name_info->Name.Length, L"\Device\WineTestDriver"), + "wrong name %s\n", debugstr_w(name_info->Name.Buffer)); + + status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation); + ok(status == STATUS_INVALID_PARAMETER, "got %#x\n", status); + + CloseHandle(file); + + file = CreateFileA("\\.\WineTestDriver\genfail", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL); + ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status); + + status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation); + ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status); + + CloseHandle(file); + + file = CreateFileA("\\.\WineTestDriver\badtype", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + status = NtQueryObject(file, ObjectNameInformation, buffer, sizeof(buffer), NULL); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, "got %#x\n", status); + + status = NtQueryInformationFile(file, &io, buffer, sizeof(buffer), FileNameInformation); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, "got %#x\n", status); + + CloseHandle(file); +} + static void test_driver3(void) { char filename[MAX_PATH]; @@ -644,6 +757,7 @@ START_TEST(ntoskrnl) test_load_driver(service2); test_file_handles(); test_return_status(); + test_object_info();
/* We need a separate ioctl to call IoDetachDevice(); calling it in the * driver unload routine causes a live-lock. */
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- Similarly, these tests do not replicate the behaviour of any application that I know of.
dlls/ntdll/tests/file.c | 66 +++++++++++++++++++++++ dlls/ntdll/tests/om.c | 117 +++++++++++++++++++++++++--------------- dlls/ntdll/tests/pipe.c | 23 +++++--- 3 files changed, 156 insertions(+), 50 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 2fa12410c93..9c749ace1fe 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -4997,6 +4997,71 @@ static void test_file_readonly_access(void) DeleteFileW(path); }
+static void test_mailslot_name(void) +{ + char buffer[1024] = {0}; + const FILE_NAME_INFORMATION *name = (const FILE_NAME_INFORMATION *)buffer; + HANDLE server, client, device; + IO_STATUS_BLOCK io; + NTSTATUS ret; + + server = CreateMailslotA( "\\.\mailslot\winetest", 100, 1000, NULL ); + ok(server != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + ret = NtQueryInformationFile( server, &io, buffer, 0, FileNameInformation ); + ok(ret == STATUS_INFO_LENGTH_MISMATCH, "got %#x\n", ret); + + memset(buffer, 0xcc, sizeof(buffer)); + ret = NtQueryInformationFile( server, &io, buffer, + offsetof(FILE_NAME_INFORMATION, FileName[5]), FileNameInformation ); + todo_wine ok(ret == STATUS_BUFFER_OVERFLOW, "got %#x\n", ret); + if (ret == STATUS_BUFFER_OVERFLOW) + { + ok(name->FileNameLength == 18, "got length %u\n", name->FileNameLength); + ok(!memcmp(name->FileName, L"\wine", 10), "got %s\n", + debugstr_wn(name->FileName, name->FileNameLength / sizeof(WCHAR))); + } + + memset(buffer, 0xcc, sizeof(buffer)); + ret = NtQueryInformationFile( server, &io, buffer, sizeof(buffer), FileNameInformation ); + todo_wine ok(!ret, "got %#x\n", ret); + if (!ret) + { + ok(name->FileNameLength == 18, "got length %u\n", name->FileNameLength); + ok(!memcmp(name->FileName, L"\winetest", 18), "got %s\n", + debugstr_wn(name->FileName, name->FileNameLength / sizeof(WCHAR))); + } + + client = CreateFileA( "\\.\mailslot\winetest", 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); + ok(client != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + ret = NtQueryInformationFile( client, &io, buffer, 0, FileNameInformation ); + ok(ret == STATUS_INFO_LENGTH_MISMATCH, "got %#x\n", ret); + + ret = NtQueryInformationFile( client, &io, buffer, sizeof(buffer), FileNameInformation ); + todo_wine ok(ret == STATUS_INVALID_PARAMETER || !ret /* win8+ */, "got %#x\n", ret); + if (!ret) + { + ok(name->FileNameLength == 18, "got length %u\n", name->FileNameLength); + ok(!memcmp(name->FileName, L"\winetest", 18), "got %s\n", + debugstr_wn(name->FileName, name->FileNameLength / sizeof(WCHAR))); + } + + CloseHandle( server ); + CloseHandle( client ); + + device = CreateFileA("\\.\mailslot", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(device != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + ret = NtQueryInformationFile( device, &io, buffer, 0, FileNameInformation ); + ok(ret == STATUS_INFO_LENGTH_MISMATCH, "got %#x\n", ret); + + ret = NtQueryInformationFile( device, &io, buffer, sizeof(buffer), FileNameInformation ); + todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret); + + CloseHandle( device ); +} + START_TEST(file) { HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); @@ -5067,4 +5132,5 @@ START_TEST(file) test_query_attribute_information_file(); test_ioctl(); test_flush_buffers_file(); + test_mailslot_name(); } diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index 06dd1bd95b6..c83052d2881 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -1231,8 +1231,15 @@ static void _test_no_file_info(unsigned line, HANDLE handle) "FileIoCompletionNotificationInformation returned %x\n", status); }
-#define test_object_type(a,b) _test_object_type(__LINE__,a,b) -static void _test_object_type( unsigned line, HANDLE handle, const WCHAR *expected_name ) +static BOOL compare_unicode_string( const UNICODE_STRING *string, const WCHAR *expect ) +{ + return string->Length == wcslen( expect ) * sizeof(WCHAR) + && !wcsnicmp( string->Buffer, expect, string->Length / sizeof(WCHAR) ); +} + +#define test_object_type(a,b) _test_object_type(__LINE__,a,b,FALSE) +#define test_object_type_todo(a,b) _test_object_type(__LINE__,a,b,TRUE) +static void _test_object_type( unsigned line, HANDLE handle, const WCHAR *expected_name, BOOL todo ) { char buffer[1024]; UNICODE_STRING *str = (UNICODE_STRING *)buffer, expect; @@ -1245,9 +1252,27 @@ static void _test_object_type( unsigned line, HANDLE handle, const WCHAR *expect status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len ); ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status ); ok_(__FILE__,line)( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); - ok_(__FILE__,line)( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len ); - ok_(__FILE__,line)( str->Length == expect.Length && !memcmp( str->Buffer, expect.Buffer, expect.Length ), - "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer ); + ok_(__FILE__,line)( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length, "unexpected len %u\n", len ); + todo_wine_if (todo) + ok_(__FILE__,line)(compare_unicode_string( str, expected_name ), "wrong name %s\n", debugstr_w( str->Buffer )); +} + +#define test_object_name(a,b,c) _test_object_name(__LINE__,a,b,c) +static void _test_object_name( unsigned line, HANDLE handle, const WCHAR *expected_name, BOOL todo ) +{ + char buffer[1024]; + UNICODE_STRING *str = (UNICODE_STRING *)buffer, expect; + ULONG len = 0; + NTSTATUS status; + + RtlInitUnicodeString( &expect, expected_name ); + + memset( buffer, 0, sizeof(buffer) ); + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status ); + ok_(__FILE__,line)( len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "unexpected len %u\n", len ); + todo_wine_if (todo) + ok_(__FILE__,line)(compare_unicode_string( str, expected_name ), "wrong name %s\n", debugstr_w( str->Buffer )); }
static void test_query_object(void) @@ -1393,19 +1418,35 @@ static void test_query_object(void)
handle = CreateMailslotA( "\\.\mailslot\test_mailslot", 100, 1000, NULL ); ok( handle != INVALID_HANDLE_VALUE, "CreateMailslot failed err %u\n", GetLastError() ); + + test_object_name( handle, L"\Device\Mailslot\test_mailslot", FALSE ); + test_object_type( handle, L"File" ); + test_file_info( handle ); + + client = CreateFileA( "\\.\mailslot\test_mailslot", 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); + ok( client != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError() ); + len = 0; - status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); - str = (UNICODE_STRING *)buffer; - ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + status = pNtQueryObject( client, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status ); str = (UNICODE_STRING *)buffer; - expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); - ok( len == expected_len, "unexpected len %u\n", len ); - ok( len > sizeof(UNICODE_STRING) + sizeof("\test_mailslot") * sizeof(WCHAR), - "name too short %s\n", wine_dbgstr_w(str->Buffer) ); - trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + ok( len == sizeof(UNICODE_STRING) + str->MaximumLength, "unexpected len %u\n", len ); + todo_wine + ok( compare_unicode_string( str, L"\Device\Mailslot" ) || + compare_unicode_string( str, L"\Device\Mailslot\test_mailslot" ) /* win8+ */, + "wrong name %s\n", debugstr_w( str->Buffer ));
- test_object_type( handle, L"File" ); + test_object_type( client, L"File" ); + test_file_info( client ); + + pNtClose( client ); + pNtClose( handle ); + + handle = CreateFileA( "\\.\mailslot", 0, 0, NULL, OPEN_EXISTING, 0, 0 ); + ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError() ); + + test_object_name( handle, L"\Device\Mailslot", FALSE ); + test_object_type_todo( handle, L"File" ); test_file_info( handle );
pNtClose( handle ); @@ -1413,21 +1454,8 @@ static void test_query_object(void) handle = CreateNamedPipeA( "\\.\pipe\test_pipe", PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE, 1, 1000, 1000, 1000, NULL ); ok( handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed err %u\n", GetLastError() ); - len = 0; - status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); - str = (UNICODE_STRING *)buffer; - todo_wine - ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); - str = (UNICODE_STRING *)buffer; - expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); - todo_wine - ok( len == expected_len, "unexpected len %u\n", len ); - todo_wine - ok( len > sizeof(UNICODE_STRING) + sizeof("\test_pipe") * sizeof(WCHAR), - "name too short %s\n", wine_dbgstr_w(str->Buffer) ); - trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
+ test_object_name( handle, L"\Device\NamedPipe\test_pipe", TRUE ); test_object_type( handle, L"File" ); test_file_info( handle );
@@ -1441,39 +1469,40 @@ static void test_query_object(void) pNtClose( client ); pNtClose( handle );
- RtlInitUnicodeString( &path, L"\REGISTRY\Machine\Software\Classes" ); + handle = CreateFileA( "\\.\pipe", 0, 0, NULL, OPEN_EXISTING, 0, 0 ); + ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError() ); + + test_object_name( handle, L"\Device\NamedPipe", TRUE ); + test_object_type_todo( handle, L"File" ); + test_file_info( handle ); + + pNtClose( handle ); + + RtlInitUnicodeString( &path, L"\REGISTRY\Machine" ); status = pNtCreateKey( &handle, KEY_READ, &attr, 0, 0, 0, 0 ); ok( status == STATUS_SUCCESS, "NtCreateKey failed status %x\n", status );
- len = 0; - status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); - ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); - str = (UNICODE_STRING *)buffer; - todo_wine - ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); - str = (UNICODE_STRING *)buffer; - expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); - ok( len == expected_len || len == expected_len - sizeof(WCHAR) /* wow64 */, "unexpected len %u\n", len ); - todo_wine - ok( len > sizeof(UNICODE_STRING) + sizeof("\Classes") * sizeof(WCHAR), - "name too short %s\n", wine_dbgstr_w(str->Buffer) ); - trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + test_object_name( handle, L"\REGISTRY\MACHINE", TRUE ); + test_object_type( handle, L"Key" ); + pNtClose( handle );
+ test_object_name( GetCurrentProcess(), L"", FALSE ); test_object_type( GetCurrentProcess(), L"Process" ); test_no_file_info( GetCurrentProcess() );
+ test_object_name( GetCurrentThread(), L"", FALSE ); test_object_type( GetCurrentThread(), L"Thread" ); test_no_file_info( GetCurrentThread() );
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &handle); ok(ret, "OpenProcessToken failed: %u\n", GetLastError());
+ test_object_name( handle, L"", FALSE ); test_object_type( handle, L"Token" ); test_no_file_info( handle );
pNtClose(handle); - }
static void test_type_mismatch(void) diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index a70f19b0563..4eb957b1c2a 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -1679,16 +1679,20 @@ static void test_volume_info(void) CloseHandle( write ); }
-#define test_file_name_fail(a,b) _test_file_name_fail(__LINE__,a,b) -static void _test_file_name_fail(unsigned line, HANDLE pipe, NTSTATUS expected_status) +#define test_file_name_fail(a,b,c) _test_file_name_fail(__LINE__,a,b,c) +static void _test_file_name_fail(unsigned line, HANDLE pipe, NTSTATUS expected_status, BOOL todo) { char buffer[512]; IO_STATUS_BLOCK iosb; NTSTATUS status;
+ status = NtQueryInformationFile( pipe, &iosb, buffer, 0, FileNameInformation ); + ok_(__FILE__,line)( status == STATUS_INFO_LENGTH_MISMATCH, + "expected STATUS_INFO_LENGTH_MISMATCH, got %#x\n", status ); + status = NtQueryInformationFile( pipe, &iosb, buffer, sizeof(buffer), FileNameInformation ); - ok_(__FILE__,line)( status == expected_status, "NtQueryInformationFile failed: %x, expected %x\n", - status, expected_status ); + todo_wine_if (todo) + ok_(__FILE__,line)( status == expected_status, "expected %#x, got %#x\n", expected_status, status ); }
#define test_file_name(a) _test_file_name(__LINE__,a) @@ -2163,7 +2167,7 @@ static void test_pipe_local_info(HANDLE pipe, BOOL is_server, DWORD state)
static void test_file_info(void) { - HANDLE server, client; + HANDLE server, client, device;
if (!create_pipe_pair( &server, &client, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE, 4096 )) return; @@ -2172,10 +2176,17 @@ static void test_file_info(void) test_file_name( server );
DisconnectNamedPipe( server ); - test_file_name_fail( client, STATUS_PIPE_DISCONNECTED ); + test_file_name_fail( client, STATUS_PIPE_DISCONNECTED, FALSE );
CloseHandle( server ); CloseHandle( client ); + + device = CreateFileA("\\.\pipe", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(device != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + test_file_name_fail( device, STATUS_INVALID_PARAMETER, TRUE ); + + CloseHandle( device ); }
static PSECURITY_DESCRIPTOR get_security_descriptor(HANDLE handle, BOOL todo)