Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v2 -> v3: move some tests from om.c to pipe.c
dlls/ntdll/tests/om.c | 9 ++++ dlls/ntdll/tests/pipe.c | 93 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index f872d6709a1..04acf5b2241 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -1871,6 +1871,15 @@ static void test_query_object(void)
pNtClose( handle );
+ 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( 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 ); diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index 6940e0020b7..f5ca6077605 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -51,6 +51,13 @@ typedef struct { ULONG NamedPipeEnd; } FILE_PIPE_LOCAL_INFORMATION;
+typedef struct _FILE_PIPE_WAIT_FOR_BUFFER { + LARGE_INTEGER Timeout; + ULONG NameLength; + BOOLEAN TimeoutSpecified; + WCHAR Name[1]; +} FILE_PIPE_WAIT_FOR_BUFFER, *PFILE_PIPE_WAIT_FOR_BUFFER; + #ifndef FILE_SYNCHRONOUS_IO_ALERT #define FILE_SYNCHRONOUS_IO_ALERT 0x10 #endif @@ -62,6 +69,10 @@ typedef struct { #ifndef FSCTL_PIPE_LISTEN #define FSCTL_PIPE_LISTEN CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif + +#ifndef FSCTL_PIPE_WAIT +#define FSCTL_PIPE_WAIT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 6, METHOD_BUFFERED, FILE_ANY_ACCESS) +#endif #endif
static NTSTATUS (WINAPI *pNtFsControlFile) (HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code, PVOID in_buffer, ULONG in_size, PVOID out_buffer, ULONG out_size); @@ -177,6 +188,51 @@ static NTSTATUS listen_pipe(HANDLE hPipe, HANDLE hEvent, PIO_STATUS_BLOCK iosb, return pNtFsControlFile(hPipe, hEvent, use_apc ? &ioapc: NULL, use_apc ? &dummy: NULL, iosb, FSCTL_PIPE_LISTEN, 0, 0, 0, 0); }
+static NTSTATUS wait_pipe(HANDLE handle, PUNICODE_STRING name, const LARGE_INTEGER* timeout) +{ + HANDLE event; + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK iosb; + FILE_PIPE_WAIT_FOR_BUFFER *pipe_wait; + ULONG pipe_wait_size; + + pipe_wait_size = offsetof(FILE_PIPE_WAIT_FOR_BUFFER, Name[0]) + name->Length; + pipe_wait = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pipe_wait_size); + if (!pipe_wait) return STATUS_NO_MEMORY; + + pipe_wait->TimeoutSpecified = !!timeout; + pipe_wait->NameLength = name->Length; + if (timeout) pipe_wait->Timeout = *timeout; + memcpy(pipe_wait->Name, name->Buffer, name->Length); + + InitializeObjectAttributes(&attr, NULL, 0, 0, NULL); + status = NtCreateEvent(&event, GENERIC_ALL, &attr, NotificationEvent, FALSE); + if (status != STATUS_SUCCESS) + { + ok(0, "NtCreateEvent failure: %08x\n", status); + HeapFree(GetProcessHeap(), 0, pipe_wait); + return status; + } + + memset(&iosb, 0, sizeof(iosb)); + iosb.Status = STATUS_PENDING; + status = pNtFsControlFile(handle, event, NULL, NULL, &iosb, FSCTL_PIPE_WAIT, + pipe_wait, pipe_wait_size, NULL, 0); + if (status == STATUS_PENDING && iosb.Status == STATUS_PENDING) + { + WaitForSingleObject(event, INFINITE); + } + if (SUCCEEDED(status) && iosb.Status != STATUS_PENDING) + { + status = iosb.Status; + } + + NtClose(event); + HeapFree(GetProcessHeap(), 0, pipe_wait); + return status; +} + static void test_create_invalid(void) { IO_STATUS_BLOCK iosb; @@ -2420,6 +2476,7 @@ static void test_security_info(void)
static void test_empty_name(void) { + static const LARGE_INTEGER zero_timeout = {{ 0 }}; HANDLE hdirectory, hpipe, hpipe2, hwrite, hwrite2, handle; OBJECT_TYPE_INFORMATION *type_info; OBJECT_NAME_INFORMATION *name_info; @@ -2450,6 +2507,10 @@ static void test_empty_name(void) FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 ); ok(!status, "Got unexpected status %#x.\n", status);
+ pRtlInitUnicodeString(&name, L"nonexistent_pipe"); + status = wait_pipe(hdirectory, &name, &zero_timeout); + todo_wine ok(status == STATUS_ILLEGAL_FUNCTION, "unexpected status for FSCTL_PIPE_WAIT on \Device\NamedPipe: %08x\n", status); + name.Buffer = NULL; name.Length = 0; name.MaximumLength = 0; @@ -2462,6 +2523,17 @@ static void test_empty_name(void) todo_wine ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#x.\n", status); if (!status) CloseHandle(hpipe); + + pRtlInitUnicodeString(&name, L"test3\pipe"); + attr.RootDirectory = hdirectory; + attr.ObjectName = &name; + timeout.QuadPart = -(LONG64)10000000; + status = pNtCreateNamedPipeFile(&hpipe, GENERIC_READ|GENERIC_WRITE, &attr, &io, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout); + ok(status == STATUS_OBJECT_NAME_INVALID, "unexpected status from NtCreateNamedPipeFile: %08x\n", status); + if (!status) + CloseHandle(hpipe); + CloseHandle(hdirectory);
pRtlInitUnicodeString(&name, L"\Device\NamedPipe\"); @@ -2475,6 +2547,10 @@ static void test_empty_name(void) FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 ); ok(!status, "Got unexpected status %#x.\n", status);
+ pRtlInitUnicodeString(&name, L"nonexistent_pipe"); + status = wait_pipe(hdirectory, &name, &zero_timeout); + ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "unexpected status for FSCTL_PIPE_WAIT on \Device\NamedPipe\: %08x\n", status); + name.Buffer = NULL; name.Length = 0; name.MaximumLength = 0; @@ -2565,9 +2641,24 @@ static void test_empty_name(void)
CloseHandle(hwrite); CloseHandle(hpipe); - CloseHandle(hdirectory); CloseHandle(hpipe2); CloseHandle(hwrite2); + + pRtlInitUnicodeString(&name, L"test3\pipe"); + attr.RootDirectory = hdirectory; + attr.ObjectName = &name; + timeout.QuadPart = -(LONG64)10000000; + status = pNtCreateNamedPipeFile(&hpipe, GENERIC_READ|GENERIC_WRITE, &attr, &io, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout); + todo_wine ok(!status, "unexpected failure from NtCreateNamedPipeFile: %08x\n", status); + + handle = CreateFileA("\\.\pipe\test3\pipe", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, 0 ); + todo_wine ok(handle != INVALID_HANDLE_VALUE, "Failed to open NamedPipe (%u)\n", GetLastError()); + + CloseHandle(handle); + CloseHandle(hpipe); + CloseHandle(hdirectory); }
START_TEST(pipe)