From 88eba446455d7b451b59bed06f3571ed22a600e9 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Wed, 19 Feb 2003 22:06:36 +0000 Subject: [PATCH] Added check for illegal pipe names. Added regression test. --- dlls/kernel/sync.c | 16 ++++- dlls/kernel/tests/Makefile.in | 1 + dlls/kernel/tests/pipe.c | 117 ++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 dlls/kernel/tests/pipe.c diff --git a/dlls/kernel/sync.c b/dlls/kernel/sync.c index 6faa7d7ac5d..53671c7d5e4 100644 --- a/dlls/kernel/sync.c +++ b/dlls/kernel/sync.c @@ -507,16 +507,28 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr ) { HANDLE ret; - DWORD len = name ? strlenW(name) : 0; + DWORD len; + static const WCHAR leadin[] = {'\\','\\','.','\\','P','I','P','E','\\'}; TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n", debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances, nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr ); + if (!name) + { + SetLastError( ERROR_PATH_NOT_FOUND ); + return INVALID_HANDLE_VALUE; + } + len = strlenW(name); if (len >= MAX_PATH) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; + return INVALID_HANDLE_VALUE; + } + if (strncmpiW(name, leadin, sizeof(leadin)/sizeof(leadin[0]))) + { + SetLastError( ERROR_INVALID_NAME ); + return INVALID_HANDLE_VALUE; } SERVER_START_REQ( create_named_pipe ) { diff --git a/dlls/kernel/tests/Makefile.in b/dlls/kernel/tests/Makefile.in index bf933b07c77..76d9d39ddba 100644 --- a/dlls/kernel/tests/Makefile.in +++ b/dlls/kernel/tests/Makefile.in @@ -17,6 +17,7 @@ CTESTS = \ generated.c \ locale.c \ path.c \ + pipe.c \ process.c \ thread.c diff --git a/dlls/kernel/tests/pipe.c b/dlls/kernel/tests/pipe.c new file mode 100644 index 00000000000..1c642d4127d --- /dev/null +++ b/dlls/kernel/tests/pipe.c @@ -0,0 +1,117 @@ +/* + * Unit tests for named pipe functions in Wine + * + * Copyright (c) 2002 Dan Kegel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#ifndef STANDALONE +#include "wine/test.h" +#else +#include +#define START_TEST(name) main(int argc, char **argv) +#define ok(condition, msg) assert(condition) +#endif + +#include +#include +#include +#include + +#define PIPENAME "\\\\.\\PiPe\\tests_" __FILE__ + +void test_CreateNamedPipeA(void) +{ + HANDLE hnp; + HANDLE hFile; + const char obuf[] = "Bit Bucket"; + char ibuf[32]; + DWORD written; + DWORD gelesen; + + /* Bad parameter checks */ + hnp = CreateNamedPipeA("not a named pipe", + PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, + /* nMaxInstances */ 1, + /* nOutBufSize */ 1024, + /* nInBufSize */ 1024, + /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, + /* lpSecurityAttrib */ NULL); + + if (hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { + /* Is this the right way to notify user of skipped tests? */ + ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, + "CreateNamedPipe not supported on this platform, skipping tests."); + return; + } + ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME, + "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe"); + + hnp = CreateNamedPipeA(NULL, + PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, + 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); + ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND, + "CreateNamedPipe should fail if name is NULL"); + + /* Functional checks */ + + hnp = CreateNamedPipeA(PIPENAME, + PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, + /* nMaxInstances */ 1, + /* nOutBufSize */ 1024, + /* nInBufSize */ 1024, + /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, + /* lpSecurityAttrib */ NULL); + ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed"); + + hFile = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, 0, 0); + todo_wine + { + ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed"); + } + + /* don't try to do i/o if one side couldn't be opened, as it hangs */ + if (hFile != INVALID_HANDLE_VALUE) { + /* Make sure we can read and write a few bytes in both directions*/ + memset(ibuf, 0, sizeof(ibuf)); + ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile"); + ok(written == sizeof(obuf), "write file len"); + ok(ReadFile(hFile, ibuf, sizeof(obuf), &gelesen, NULL), "ReadFile"); + ok(gelesen == sizeof(obuf), "read file len"); + ok(memcmp(obuf, ibuf, written) == 0, "content check"); + + memset(ibuf, 0, sizeof(ibuf)); + ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile"); + ok(written == sizeof(obuf), "write file len"); + ok(ReadFile(hnp, ibuf, sizeof(obuf), &gelesen, NULL), "ReadFile"); + ok(gelesen == sizeof(obuf), "read file len"); + ok(memcmp(obuf, ibuf, written) == 0, "content check"); + + CloseHandle(hFile); + } + + CloseHandle(hnp); +} + +START_TEST(pipe) +{ + test_CreateNamedPipeA(); +}