mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-24 01:06:23 +00:00
ntdll/tests: Add pipe state tests.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6ec5b57a1f
commit
5efd706c22
|
@ -118,7 +118,7 @@ static const WCHAR testpipe[] = { '\\', '\\', '.', '\\', 'p', 'i', 'p', 'e', '\\
|
||||||
static const WCHAR testpipe_nt[] = { '\\', '?', '?', '\\', 'p', 'i', 'p', 'e', '\\',
|
static const WCHAR testpipe_nt[] = { '\\', '?', '?', '\\', 'p', 'i', 'p', 'e', '\\',
|
||||||
't', 'e', 's', 't', 'p', 'i', 'p', 'e', 0 };
|
't', 'e', 's', 't', 'p', 'i', 'p', 'e', 0 };
|
||||||
|
|
||||||
static NTSTATUS create_pipe(PHANDLE handle, ULONG sharing, ULONG options)
|
static NTSTATUS create_pipe(PHANDLE handle, ULONG access, ULONG sharing, ULONG options)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK iosb;
|
IO_STATUS_BLOCK iosb;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
@ -137,8 +137,8 @@ static NTSTATUS create_pipe(PHANDLE handle, ULONG sharing, ULONG options)
|
||||||
|
|
||||||
timeout.QuadPart = -100000000;
|
timeout.QuadPart = -100000000;
|
||||||
|
|
||||||
res = pNtCreateNamedPipeFile(handle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr, &iosb, sharing, 2 /*FILE_CREATE*/,
|
res = pNtCreateNamedPipeFile(handle, FILE_READ_ATTRIBUTES | SYNCHRONIZE | access, &attr, &iosb, sharing,
|
||||||
options, 1, 0, 0, 0xFFFFFFFF, 500, 500, &timeout);
|
FILE_CREATE, options, 1, 0, 0, 0xFFFFFFFF, 500, 500, &timeout);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ static void test_create(void)
|
||||||
HANDLE hclient;
|
HANDLE hclient;
|
||||||
BOOL should_succeed = TRUE;
|
BOOL should_succeed = TRUE;
|
||||||
|
|
||||||
res = create_pipe(&hserver, sharing[j], 0);
|
res = create_pipe(&hserver, 0, sharing[j], 0);
|
||||||
if (res) {
|
if (res) {
|
||||||
ok(0, "NtCreateNamedPipeFile returned %x, sharing: %x\n", res, sharing[j]);
|
ok(0, "NtCreateNamedPipeFile returned %x, sharing: %x\n", res, sharing[j]);
|
||||||
continue;
|
continue;
|
||||||
|
@ -290,7 +290,7 @@ static void test_overlapped(void)
|
||||||
hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
ok(hEvent != INVALID_HANDLE_VALUE, "can't create event, GetLastError: %x\n", GetLastError());
|
ok(hEvent != INVALID_HANDLE_VALUE, "can't create event, GetLastError: %x\n", GetLastError());
|
||||||
|
|
||||||
res = create_pipe(&hPipe, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
|
res = create_pipe(&hPipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
|
||||||
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
||||||
|
|
||||||
memset(&iosb, 0x55, sizeof(iosb));
|
memset(&iosb, 0x55, sizeof(iosb));
|
||||||
|
@ -313,7 +313,7 @@ static void test_overlapped(void)
|
||||||
CloseHandle(hPipe);
|
CloseHandle(hPipe);
|
||||||
CloseHandle(hClient);
|
CloseHandle(hClient);
|
||||||
|
|
||||||
res = create_pipe(&hPipe, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
|
res = create_pipe(&hPipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
|
||||||
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
||||||
|
|
||||||
hClient = CreateFileW(testpipe, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
|
hClient = CreateFileW(testpipe, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
|
||||||
|
@ -385,7 +385,7 @@ static void test_alertable(void)
|
||||||
hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
ok(hEvent != INVALID_HANDLE_VALUE, "can't create event, GetLastError: %x\n", GetLastError());
|
ok(hEvent != INVALID_HANDLE_VALUE, "can't create event, GetLastError: %x\n", GetLastError());
|
||||||
|
|
||||||
res = create_pipe(&hPipe, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT);
|
res = create_pipe(&hPipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT);
|
||||||
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
||||||
|
|
||||||
/* queue an user apc before calling listen */
|
/* queue an user apc before calling listen */
|
||||||
|
@ -455,7 +455,7 @@ static void test_nonalertable(void)
|
||||||
hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
ok(hEvent != INVALID_HANDLE_VALUE, "can't create event, GetLastError: %x\n", GetLastError());
|
ok(hEvent != INVALID_HANDLE_VALUE, "can't create event, GetLastError: %x\n", GetLastError());
|
||||||
|
|
||||||
res = create_pipe(&hPipe, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT);
|
res = create_pipe(&hPipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
||||||
|
|
||||||
hThread = CreateThread(NULL, 0, &thread, 0, 0, 0);
|
hThread = CreateThread(NULL, 0, &thread, 0, 0, 0);
|
||||||
|
@ -497,7 +497,7 @@ static void test_cancelio(void)
|
||||||
hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
ok(hEvent != INVALID_HANDLE_VALUE, "can't create event, GetLastError: %x\n", GetLastError());
|
ok(hEvent != INVALID_HANDLE_VALUE, "can't create event, GetLastError: %x\n", GetLastError());
|
||||||
|
|
||||||
res = create_pipe(&hPipe, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
|
res = create_pipe(&hPipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
|
||||||
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
||||||
|
|
||||||
memset(&iosb, 0x55, sizeof(iosb));
|
memset(&iosb, 0x55, sizeof(iosb));
|
||||||
|
@ -521,7 +521,7 @@ static void test_cancelio(void)
|
||||||
|
|
||||||
if (pNtCancelIoFileEx)
|
if (pNtCancelIoFileEx)
|
||||||
{
|
{
|
||||||
res = create_pipe(&hPipe, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
|
res = create_pipe(&hPipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
|
||||||
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
ok(!res, "NtCreateNamedPipeFile returned %x\n", res);
|
||||||
|
|
||||||
memset(&iosb, 0x55, sizeof(iosb));
|
memset(&iosb, 0x55, sizeof(iosb));
|
||||||
|
@ -1221,6 +1221,283 @@ static void _test_file_name(unsigned line, HANDLE pipe)
|
||||||
ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationFile failed: %x\n", status );
|
ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationFile failed: %x\n", status );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HANDLE create_pipe_server(void)
|
||||||
|
{
|
||||||
|
HANDLE handle;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
status = create_pipe(&handle, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
|
||||||
|
ok(status == STATUS_SUCCESS, "create_pipe failed: %x\n", status);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE connect_pipe(HANDLE server)
|
||||||
|
{
|
||||||
|
HANDLE client;
|
||||||
|
|
||||||
|
client = CreateFileW(testpipe, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||||
|
FILE_FLAG_OVERLAPPED, 0);
|
||||||
|
ok(client != INVALID_HANDLE_VALUE, "can't open pipe: %u\n", GetLastError());
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE connect_and_write_pipe(HANDLE server)
|
||||||
|
{
|
||||||
|
BYTE buf[10] = {0};
|
||||||
|
HANDLE client;
|
||||||
|
DWORD written;
|
||||||
|
BOOL res;
|
||||||
|
|
||||||
|
client = connect_pipe(server);
|
||||||
|
|
||||||
|
res = WriteFile(client, buf, sizeof(buf), &written, NULL);
|
||||||
|
ok(res, "WriteFile failed: %u\n", GetLastError());
|
||||||
|
res = WriteFile(server, buf, sizeof(buf), &written, NULL);
|
||||||
|
ok(res, "WriteFile failed: %u\n", GetLastError());
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_pipe_state(HANDLE pipe, BOOL is_server, DWORD state)
|
||||||
|
{
|
||||||
|
FILE_PIPE_PEEK_BUFFER peek_buf;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
static char buf[] = "test";
|
||||||
|
NTSTATUS status, expected_status;
|
||||||
|
|
||||||
|
memset(&peek_buf, 0xcc, sizeof(peek_buf));
|
||||||
|
memset(&io, 0xcc, sizeof(io));
|
||||||
|
status = NtFsControlFile(pipe, NULL, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0, &peek_buf, sizeof(peek_buf));
|
||||||
|
if (!status || status == STATUS_PENDING)
|
||||||
|
status = io.Status;
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case FILE_PIPE_DISCONNECTED_STATE:
|
||||||
|
expected_status = is_server ? STATUS_INVALID_PIPE_STATE : STATUS_PIPE_DISCONNECTED;
|
||||||
|
break;
|
||||||
|
case FILE_PIPE_LISTENING_STATE:
|
||||||
|
expected_status = STATUS_INVALID_PIPE_STATE;
|
||||||
|
break;
|
||||||
|
case FILE_PIPE_CONNECTED_STATE:
|
||||||
|
expected_status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
expected_status = STATUS_PIPE_BROKEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
todo_wine_if(expected_status && expected_status != STATUS_PIPE_BROKEN)
|
||||||
|
ok(status == expected_status, "status = %x, expected %x in %s state %u\n",
|
||||||
|
status, expected_status, is_server ? "server" : "client", state);
|
||||||
|
if (!status)
|
||||||
|
todo_wine
|
||||||
|
ok(peek_buf.NamedPipeState == state, "NamedPipeState = %u, expected %u\n",
|
||||||
|
peek_buf.NamedPipeState, state);
|
||||||
|
|
||||||
|
if (state != FILE_PIPE_CONNECTED_STATE)
|
||||||
|
{
|
||||||
|
if (state == FILE_PIPE_CLOSING_STATE)
|
||||||
|
expected_status = STATUS_INVALID_PIPE_STATE;
|
||||||
|
status = NtFsControlFile(pipe, NULL, NULL, NULL, &io, FSCTL_PIPE_TRANSCEIVE,
|
||||||
|
buf, 1, buf+1, 1);
|
||||||
|
if (!status || status == STATUS_PENDING)
|
||||||
|
status = io.Status;
|
||||||
|
todo_wine
|
||||||
|
ok(status == expected_status,
|
||||||
|
"NtFsControlFile(FSCTL_PIPE_TRANSCEIVE) failed in %s state %u: %x\n",
|
||||||
|
is_server ? "server" : "client", state, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&io, 0xcc, sizeof(io));
|
||||||
|
status = NtFlushBuffersFile(pipe, &io);
|
||||||
|
if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE)
|
||||||
|
{
|
||||||
|
todo_wine
|
||||||
|
ok(status == STATUS_PIPE_DISCONNECTED, "status = %x in %s state %u\n",
|
||||||
|
status, is_server ? "server" : "client", state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok(status == STATUS_SUCCESS, "status = %x in %s state %u\n",
|
||||||
|
status, is_server ? "server" : "client", state);
|
||||||
|
todo_wine
|
||||||
|
ok(io.Status == status, "io.Status = %x\n", io.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != FILE_PIPE_CONNECTED_STATE)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case FILE_PIPE_DISCONNECTED_STATE:
|
||||||
|
expected_status = STATUS_PIPE_DISCONNECTED;
|
||||||
|
break;
|
||||||
|
case FILE_PIPE_LISTENING_STATE:
|
||||||
|
expected_status = STATUS_PIPE_LISTENING;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
expected_status = STATUS_PIPE_BROKEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
status = NtReadFile(pipe, NULL, NULL, NULL, &io, buf, 1, NULL, NULL);
|
||||||
|
todo_wine_if(state == FILE_PIPE_DISCONNECTED_STATE && !is_server)
|
||||||
|
ok(status == expected_status, "NtReadFile failed in %s state %u: %x\n",
|
||||||
|
is_server ? "server" : "client", state, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_pipe_with_data_state(HANDLE pipe, BOOL is_server, DWORD state)
|
||||||
|
{
|
||||||
|
FILE_PIPE_LOCAL_INFORMATION local_info;
|
||||||
|
FILE_PIPE_INFORMATION pipe_info;
|
||||||
|
FILE_PIPE_PEEK_BUFFER peek_buf;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
char buf[] = "test";
|
||||||
|
NTSTATUS status, expected_status;
|
||||||
|
|
||||||
|
memset(&io, 0xcc, sizeof(io));
|
||||||
|
status = pNtQueryInformationFile(pipe, &io, &local_info, sizeof(local_info), FilePipeLocalInformation);
|
||||||
|
if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE)
|
||||||
|
todo_wine
|
||||||
|
ok(status == STATUS_PIPE_DISCONNECTED,
|
||||||
|
"NtQueryInformationFile(FilePipeLocalInformation) failed in %s state %u: %x\n",
|
||||||
|
is_server ? "server" : "client", state, status);
|
||||||
|
else
|
||||||
|
ok(status == STATUS_SUCCESS,
|
||||||
|
"NtQueryInformationFile(FilePipeLocalInformation) failed in %s state %u: %x\n",
|
||||||
|
is_server ? "server" : "client", state, status);
|
||||||
|
if (!status)
|
||||||
|
todo_wine
|
||||||
|
ok(local_info.NamedPipeState == state, "%s NamedPipeState = %u, expected %u\n",
|
||||||
|
is_server ? "server" : "client", local_info.NamedPipeState, state);
|
||||||
|
|
||||||
|
status = pNtQueryInformationFile(pipe, &io, &pipe_info, sizeof(pipe_info), FilePipeInformation);
|
||||||
|
if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE)
|
||||||
|
todo_wine
|
||||||
|
ok(status == STATUS_PIPE_DISCONNECTED,
|
||||||
|
"NtQueryInformationFile(FilePipeInformation) failed in %s state %u: %x\n",
|
||||||
|
is_server ? "server" : "client", state, status);
|
||||||
|
else
|
||||||
|
ok(status == STATUS_SUCCESS,
|
||||||
|
"NtQueryInformationFile(FilePipeInformation) failed in %s state %u: %x\n",
|
||||||
|
is_server ? "server" : "client", state, status);
|
||||||
|
|
||||||
|
memset(&peek_buf, 0xcc, sizeof(peek_buf));
|
||||||
|
memset(&io, 0xcc, sizeof(io));
|
||||||
|
status = NtFsControlFile(pipe, NULL, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0, &peek_buf, sizeof(peek_buf));
|
||||||
|
if (!status || status == STATUS_PENDING)
|
||||||
|
status = io.Status;
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case FILE_PIPE_DISCONNECTED_STATE:
|
||||||
|
expected_status = is_server ? STATUS_INVALID_PIPE_STATE : STATUS_PIPE_DISCONNECTED;
|
||||||
|
break;
|
||||||
|
case FILE_PIPE_LISTENING_STATE:
|
||||||
|
expected_status = STATUS_INVALID_PIPE_STATE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
expected_status = STATUS_BUFFER_OVERFLOW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
todo_wine
|
||||||
|
ok(status == expected_status, "status = %x, expected %x in %s state %u\n",
|
||||||
|
status, expected_status, is_server ? "server" : "client", state);
|
||||||
|
if (status == STATUS_BUFFER_OVERFLOW)
|
||||||
|
ok(peek_buf.NamedPipeState == state, "NamedPipeState = %u, expected %u\n",
|
||||||
|
peek_buf.NamedPipeState, state);
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case FILE_PIPE_DISCONNECTED_STATE:
|
||||||
|
expected_status = STATUS_PIPE_DISCONNECTED;
|
||||||
|
break;
|
||||||
|
case FILE_PIPE_LISTENING_STATE:
|
||||||
|
expected_status = STATUS_PIPE_LISTENING;
|
||||||
|
break;
|
||||||
|
case FILE_PIPE_CONNECTED_STATE:
|
||||||
|
expected_status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
expected_status = STATUS_PIPE_CLOSING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
status = NtWriteFile(pipe, NULL, NULL, NULL, &io, buf, 1, NULL, NULL);
|
||||||
|
todo_wine_if(expected_status == STATUS_PIPE_CLOSING)
|
||||||
|
ok(status == expected_status, "NtWriteFile failed in %s state %u: %x\n",
|
||||||
|
is_server ? "server" : "client", state, status);
|
||||||
|
|
||||||
|
if (state == FILE_PIPE_CLOSING_STATE)
|
||||||
|
expected_status = STATUS_SUCCESS;
|
||||||
|
status = NtReadFile(pipe, NULL, NULL, NULL, &io, buf, 1, NULL, NULL);
|
||||||
|
todo_wine_if(state == FILE_PIPE_DISCONNECTED_STATE && status != STATUS_PIPE_DISCONNECTED)
|
||||||
|
ok(status == expected_status, "NtReadFile failed in %s state %u: %x\n",
|
||||||
|
is_server ? "server" : "client", state, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pipe_for_each_state(HANDLE (*create_server)(void),
|
||||||
|
HANDLE (*connect_client)(HANDLE),
|
||||||
|
void (*test)(HANDLE pipe, BOOL is_server, DWORD pipe_state))
|
||||||
|
{
|
||||||
|
HANDLE client, server;
|
||||||
|
IO_STATUS_BLOCK iosb;
|
||||||
|
NTSTATUS status;
|
||||||
|
HANDLE event;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
event = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
|
|
||||||
|
server = create_server();
|
||||||
|
test(server, TRUE, FILE_PIPE_LISTENING_STATE);
|
||||||
|
|
||||||
|
status = listen_pipe(server, event, &iosb, FALSE);
|
||||||
|
ok(status == STATUS_PENDING, "listen_pipe returned %x\n", status);
|
||||||
|
test(server, TRUE, FILE_PIPE_LISTENING_STATE);
|
||||||
|
|
||||||
|
client = connect_client(server);
|
||||||
|
test(server, TRUE, FILE_PIPE_CONNECTED_STATE);
|
||||||
|
test(client, FALSE, FILE_PIPE_CONNECTED_STATE);
|
||||||
|
|
||||||
|
/* server closed, but not disconnected */
|
||||||
|
CloseHandle(server);
|
||||||
|
test(client, FALSE, FILE_PIPE_CLOSING_STATE);
|
||||||
|
CloseHandle(client);
|
||||||
|
|
||||||
|
server = create_server();
|
||||||
|
status = listen_pipe(server, event, &iosb, FALSE);
|
||||||
|
ok(status == STATUS_PENDING, "listen_pipe returned %x\n", status);
|
||||||
|
|
||||||
|
client = connect_client(server);
|
||||||
|
ret = DisconnectNamedPipe(server);
|
||||||
|
ok(ret, "DisconnectNamedPipe failed: %u\n", GetLastError());
|
||||||
|
test(server, TRUE, FILE_PIPE_DISCONNECTED_STATE);
|
||||||
|
test(client, FALSE, FILE_PIPE_DISCONNECTED_STATE);
|
||||||
|
CloseHandle(server);
|
||||||
|
test(client, FALSE, FILE_PIPE_DISCONNECTED_STATE);
|
||||||
|
CloseHandle(client);
|
||||||
|
|
||||||
|
server = create_server();
|
||||||
|
status = listen_pipe(server, event, &iosb, FALSE);
|
||||||
|
ok(status == STATUS_PENDING, "listen_pipe returned %x\n", status);
|
||||||
|
|
||||||
|
client = connect_client(server);
|
||||||
|
CloseHandle(client);
|
||||||
|
test(server, TRUE, FILE_PIPE_CLOSING_STATE);
|
||||||
|
ret = DisconnectNamedPipe(server);
|
||||||
|
ok(ret, "DisconnectNamedPipe failed: %u\n", GetLastError());
|
||||||
|
test(server, TRUE, FILE_PIPE_DISCONNECTED_STATE);
|
||||||
|
|
||||||
|
if(broken(1)) { /* FIXME: Remove once Wine can handle this case */
|
||||||
|
status = listen_pipe(server, event, &iosb, FALSE);
|
||||||
|
ok(status == STATUS_PENDING, "listen_pipe returned %x\n", status);
|
||||||
|
client = connect_client(server);
|
||||||
|
test(server, TRUE, FILE_PIPE_CONNECTED_STATE);
|
||||||
|
test(client, FALSE, FILE_PIPE_CONNECTED_STATE);
|
||||||
|
CloseHandle(client);
|
||||||
|
}
|
||||||
|
CloseHandle(server);
|
||||||
|
|
||||||
|
CloseHandle(event);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_file_info(void)
|
static void test_file_info(void)
|
||||||
{
|
{
|
||||||
HANDLE server, client;
|
HANDLE server, client;
|
||||||
|
@ -1497,4 +1774,7 @@ START_TEST(pipe)
|
||||||
test_volume_info();
|
test_volume_info();
|
||||||
test_file_info();
|
test_file_info();
|
||||||
test_security_info();
|
test_security_info();
|
||||||
|
|
||||||
|
pipe_for_each_state(create_pipe_server, connect_pipe, test_pipe_state);
|
||||||
|
pipe_for_each_state(create_pipe_server, connect_and_write_pipe, test_pipe_with_data_state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -737,6 +737,11 @@ typedef struct _FILE_PIPE_LOCAL_INFORMATION {
|
||||||
ULONG NamedPipeEnd;
|
ULONG NamedPipeEnd;
|
||||||
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
|
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
|
||||||
|
|
||||||
|
#define FILE_PIPE_DISCONNECTED_STATE 0x00000001
|
||||||
|
#define FILE_PIPE_LISTENING_STATE 0x00000002
|
||||||
|
#define FILE_PIPE_CONNECTED_STATE 0x00000003
|
||||||
|
#define FILE_PIPE_CLOSING_STATE 0x00000004
|
||||||
|
|
||||||
typedef struct _FILE_OBJECTID_INFORMATION {
|
typedef struct _FILE_OBJECTID_INFORMATION {
|
||||||
LONGLONG FileReference;
|
LONGLONG FileReference;
|
||||||
UCHAR ObjectId[16];
|
UCHAR ObjectId[16];
|
||||||
|
|
Loading…
Reference in a new issue