* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
static HANDLE alarm_event;
static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,
SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE);
+static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
+static BOOL user_apc_ran;
+static void CALLBACK user_apc(ULONG_PTR param)
+{
+ user_apc_ran = TRUE;
+}
static void test_CreateNamedPipe(int pipemode)
{
DWORD readden;
DWORD avail;
DWORD lpmode;
+ BOOL ret;
if (pipemode == PIPE_TYPE_BYTE)
trace("test_CreateNamedPipe starting in byte mode\n");
ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME,
"CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
+ if (pipemode == PIPE_TYPE_BYTE)
+ {
+ /* Bad parameter checks */
+ hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE,
+ /* nMaxInstances */ 1,
+ /* nOutBufSize */ 1024,
+ /* nInBufSize */ 1024,
+ /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
+ /* lpSecurityAttrib */ NULL);
+ ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
+ "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n");
+ }
+
hnp = CreateNamedPipe(NULL,
PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
/* lpSecurityAttrib */ NULL);
ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
- ok(WaitNamedPipeA(PIPENAME, 2000), "WaitNamedPipe failed (%d)\n", GetLastError());
+ ret = WaitNamedPipeA(PIPENAME, 2000);
+ ok(ret, "WaitNamedPipe failed (%d)\n", GetLastError());
hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError());
ok(!WaitNamedPipeA(PIPENAME, 1000), "WaitNamedPipe succeeded\n");
+
ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError());
/* don't try to do i/o if one side couldn't be opened, as it hangs */
ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT,
- /* nMaxInstances */ 1,
+ /* nMaxInstances */ 2,
/* nOutBufSize */ 1024,
/* nInBufSize */ 1024,
/* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
ok(CloseHandle(hnp), "CloseHandle\n");
- /* etc, etc */
+ /* check everything else */
+ hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
+ /* nMaxInstances */ 4,
+ /* nOutBufSize */ 1024,
+ /* nInBufSize */ 1024,
+ /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
+ /* lpSecurityAttrib */ NULL);
+ ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
+
+ hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE,
+ /* nMaxInstances */ 3,
+ /* nOutBufSize */ 102,
+ /* nInBufSize */ 24,
+ /* nDefaultWait */ 1234,
+ /* lpSecurityAttrib */ NULL);
+ ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
+
+ ok(CloseHandle(hnp), "CloseHandle\n");
+ ok(CloseHandle(hnp2), "CloseHandle\n");
}
/** implementation of alarm() */
return 1;
}
-HANDLE hnp = INVALID_HANDLE_VALUE;
+static HANDLE hnp = INVALID_HANDLE_VALUE;
/** Trivial byte echo server - disconnects after each session */
static DWORD CALLBACK serverThreadMain1(LPVOID arg)
DWORD readden;
DWORD success;
+ user_apc_ran = FALSE;
+ if (i == 0 && pQueueUserAPC) {
+ trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
+ success = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
+ ok(success, "QueueUserAPC failed: %d\n", GetLastError());
+ }
+
/* Wait for client to connect */
trace("Server calling ConnectNamedPipe...\n");
ok(ConnectNamedPipe(hnp, NULL)
ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
+ ok(user_apc_ran == FALSE, "UserAPC ran, pipe using alertable io mode\n");
+
+ if (i == 0 && pQueueUserAPC)
+ SleepEx(0, TRUE); /* get rid of apc */
+
/* Set up next echo server */
hnpNext =
CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
{
int i;
HANDLE hcompletion;
+ BOOL ret;
trace("serverThreadMain4\n");
/* Set up a simple echo server */
ok(success, "DisconnectNamedPipe failed, err %u\n", GetLastError());
}
- ok(CloseHandle(hnp), "CloseHandle named pipe failed, err=%i\n", GetLastError());
- ok(CloseHandle(hcompletion), "CloseHandle completion failed, err=%i\n", GetLastError());
+ ret = CloseHandle(hnp);
+ ok(ret, "CloseHandle named pipe failed, err=%i\n", GetLastError());
+ ret = CloseHandle(hcompletion);
+ ok(ret, "CloseHandle completion failed, err=%i\n", GetLastError());
return 0;
}
BYTE *buffer;
char readbuf[32];
+ user_apc_ran = FALSE;
+ if (pQueueUserAPC)
+ ok(pQueueUserAPC(user_apc, GetCurrentThread(), 0), "couldn't create user apc\n");
+
pipe_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
pipe_attr.bInheritHandle = TRUE;
- pipe_attr.lpSecurityDescriptor = NULL;
+ pipe_attr.lpSecurityDescriptor = NULL;
ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n");
ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n");
ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %d bytes\n", written);
ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n");
ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
HeapFree(GetProcessHeap(), 0, buffer);
+
+ ok(user_apc_ran == FALSE, "user apc ran, pipe using alertable io mode\n");
+ SleepEx(0, TRUE); /* get rid of apc */
}
struct named_pipe_client_params
{
DWORD tid, num;
HANDLE thread, pipe;
- int ret;
+ BOOL ret;
struct overlapped_server_args args;
args.pipe_created = CreateEventA(0, 1, 0, 0);
Sleep(1);
ret = WriteFile(pipe, "x", 1, &num, NULL);
- ok(ret == 1, "ret %d\n", ret);
+ ok(ret, "WriteFile failed with error %d\n", GetLastError());
WaitForSingleObject(thread, INFINITE);
CloseHandle(pipe);
hmod = GetModuleHandle("advapi32.dll");
pDuplicateTokenEx = (void *) GetProcAddress(hmod, "DuplicateTokenEx");
+ hmod = GetModuleHandle("kernel32.dll");
+ pQueueUserAPC = (void *) GetProcAddress(hmod, "QueueUserAPC");
if (test_DisconnectNamedPipe())
return;