From 55396b701857e441eff6ecf6431c4b9c6fc9c079 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 21 Aug 2014 05:41:15 +0200 Subject: [PATCH] kernel32: Implement SetNamedPipeHandleState. Based on a patch by Adam Martinson. --- dlls/kernel32/sync.c | 35 ++++++++++++++++++++++++++++------- dlls/kernel32/tests/pipe.c | 10 +--------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c index 21b24f2688a..8379c1dab15 100644 --- a/dlls/kernel32/sync.c +++ b/dlls/kernel32/sync.c @@ -1790,9 +1790,34 @@ BOOL WINAPI SetNamedPipeHandleState( { /* should be a fixme, but this function is called a lot by the RPC * runtime, and it slows down InstallShield a fair bit. */ - WARN("stub: %p %p/%d %p %p\n", + WARN("semi-stub: %p %p/%d %p %p\n", hNamedPipe, lpMode, lpMode ? *lpMode : 0, lpMaxCollectionCount, lpCollectDataTimeout); - return FALSE; + + if (lpMode) + { + FILE_PIPE_INFORMATION fpi; + IO_STATUS_BLOCK iosb; + NTSTATUS status; + + if (*lpMode & ~(PIPE_READMODE_MESSAGE | PIPE_NOWAIT)) + status = STATUS_INVALID_PARAMETER; + else + { + fpi.CompletionMode = (*lpMode & PIPE_NOWAIT) ? + FILE_PIPE_COMPLETE_OPERATION : FILE_PIPE_QUEUE_OPERATION; + fpi.ReadMode = (*lpMode & PIPE_READMODE_MESSAGE) ? + FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE; + status = NtSetInformationFile(hNamedPipe, &iosb, &fpi, sizeof(fpi), FilePipeInformation); + } + + if (status) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + } + + return TRUE; } /*********************************************************************** @@ -1854,15 +1879,11 @@ BOOL WINAPI CallNamedPipeW( mode = PIPE_READMODE_MESSAGE; ret = SetNamedPipeHandleState(pipe, &mode, NULL, NULL); - - /* Currently SetNamedPipeHandleState() is a stub returning FALSE */ - if (ret) FIXME("Now that SetNamedPipeHandleState() is more than a stub, please update CallNamedPipeW\n"); - /* if (!ret) { CloseHandle(pipe); return FALSE; - }*/ + } ret = TransactNamedPipe(pipe, lpInput, lpInputSize, lpOutput, lpOutputSize, lpBytesRead, NULL); CloseHandle(pipe); diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 20c2c61f57e..457e62bd003 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -233,9 +233,7 @@ static void test_CreateNamedPipe(int pipemode) ok(!SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); } else { - todo_wine { - ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); - } + ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); memset(ibuf, 0, sizeof(ibuf)); ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile5a\n"); @@ -1685,7 +1683,6 @@ static void test_NamedPipeHandleState(void) state = PIPE_READMODE_MESSAGE; SetLastError(0xdeadbeef); ret = SetNamedPipeHandleState(server, &state, NULL, NULL); - todo_wine ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); @@ -1695,13 +1692,11 @@ static void test_NamedPipeHandleState(void) state = PIPE_READMODE_BYTE; ret = SetNamedPipeHandleState(client, &state, NULL, NULL); - todo_wine ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); /* A byte-mode pipe client can't be changed to message mode, either. */ state = PIPE_READMODE_MESSAGE; SetLastError(0xdeadbeef); ret = SetNamedPipeHandleState(server, &state, NULL, NULL); - todo_wine ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); @@ -1731,7 +1726,6 @@ static void test_NamedPipeHandleState(void) */ state = PIPE_READMODE_BYTE; ret = SetNamedPipeHandleState(server, &state, NULL, NULL); - todo_wine ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, @@ -1740,13 +1734,11 @@ static void test_NamedPipeHandleState(void) state = PIPE_READMODE_MESSAGE; ret = SetNamedPipeHandleState(client, &state, NULL, NULL); - todo_wine ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); /* A message-mode pipe client can also be changed to byte mode. */ state = PIPE_READMODE_BYTE; ret = SetNamedPipeHandleState(client, &state, NULL, NULL); - todo_wine ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); CloseHandle(client);