Commit d74b084e authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Pass the NtCreateNamedPipeFile disposition to the server.

parent 2436964d
......@@ -1307,7 +1307,7 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateNamedPipeW( LPCWSTR name, DWORD open_mode,
time.QuadPart = (ULONGLONG)timeout * -10000;
SetLastError( 0 );
status = NtCreateNamedPipeFile( &handle, access, &attr, &iosb, sharing,
FILE_OVERWRITE_IF, options, pipe_type,
FILE_OPEN_IF, options, pipe_type,
read_mode, non_block, instances, in_buff, out_buff, &time );
RtlFreeUnicodeString( &nt_name );
if (!set_ntstatus( status )) return INVALID_HANDLE_VALUE;
......@@ -1348,7 +1348,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreatePipe( HANDLE *read_pipe, HANDLE *write_pipe,
GetCurrentProcessId(), ++index );
RtlInitUnicodeString( &nt_name, name );
if (!NtCreateNamedPipeFile( read_pipe, GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
&attr, &iosb, FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
&attr, &iosb, FILE_SHARE_WRITE, FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
FALSE, FALSE, FALSE, 1, size, size, &timeout ))
break;
......
......@@ -272,7 +272,8 @@ static void test_name_collisions(void)
OBJECT_ATTRIBUTES attr;
HANDLE dir, h, h1, h2;
DWORD winerr;
LARGE_INTEGER size;
LARGE_INTEGER size, timeout;
IO_STATUS_BLOCK iosb;
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
RtlInitUnicodeString(&str, L"\\");
......@@ -332,7 +333,7 @@ static void test_name_collisions(void)
pNtClose(h);
pNtClose(h1);
pNtClose(h2);
h = CreateWaitableTimerA(NULL, TRUE, "om.c-test");
ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%ld)\n", h, GetLastError());
status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer);
......@@ -362,6 +363,62 @@ static void test_name_collisions(void)
pNtClose(h2);
pNtClose(dir);
RtlInitUnicodeString(&str, L"\\??\\PIPE\\named_pipe");
attr.RootDirectory = 0;
timeout.QuadPart = -10000;
status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, FILE_PIPE_FULL_DUPLEX,
FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "failed to create pipe %08lx\n", status);
memset( &iosb, 0xcc, sizeof(iosb) );
status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN_IF, FILE_PIPE_FULL_DUPLEX,
FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
todo_wine
ok( iosb.Information == FILE_CREATED, "wrong info %Ix\n", iosb.Information );
pNtClose( h );
memset( &iosb, 0xcc, sizeof(iosb) );
status = pNtCreateNamedPipeFile( &h, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_CREATE, FILE_PIPE_FULL_DUPLEX,
FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
todo_wine
ok( iosb.Information == FILE_CREATED, "wrong info %Ix\n", iosb.Information );
memset( &iosb, 0xcc, sizeof(iosb) );
status = pNtCreateNamedPipeFile( &h1, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, FILE_PIPE_FULL_DUPLEX,
FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
todo_wine
ok( iosb.Information == FILE_OPENED, "wrong info %Ix\n", iosb.Information );
pNtClose(h1);
memset( &iosb, 0xcc, sizeof(iosb) );
status = pNtCreateNamedPipeFile( &h1, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN_IF, FILE_PIPE_FULL_DUPLEX,
FALSE, FALSE, FALSE, 10, 256, 256, &timeout );
ok(status == STATUS_SUCCESS, "failed to create pipe %08lx\n", status);
todo_wine
ok( iosb.Information == FILE_OPENED, "wrong info %Ix\n", iosb.Information );
pNtClose(h1);
h1 = CreateNamedPipeA( "\\\\.\\pipe\\named_pipe", PIPE_ACCESS_DUPLEX,
PIPE_READMODE_BYTE, 10, 256, 256, 1000, NULL );
winerr = GetLastError();
todo_wine
ok(h1 != 0 && winerr == ERROR_ALREADY_EXISTS, "CreateNamedPipeA got ret=%p (%ld)\n", h1, winerr);
pNtClose(h1);
pNtClose(h);
}
static void test_all_kernel_objects( UINT line, OBJECT_ATTRIBUTES *attr,
......
......@@ -260,14 +260,14 @@ static void test_create_invalid(void)
/* create a pipe with FILE_OVERWRITE */
res = pNtCreateNamedPipeFile(&handle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr, &iosb, FILE_SHARE_READ, 4 /*FILE_OVERWRITE*/,
0, 1, 0, 0, 0xFFFFFFFF, 500, 500, &timeout);
todo_wine ok(res == STATUS_INVALID_PARAMETER, "NtCreateNamedPipeFile returned %lx\n", res);
ok(res == STATUS_INVALID_PARAMETER, "NtCreateNamedPipeFile returned %lx\n", res);
if (!res)
CloseHandle(handle);
/* create a pipe with FILE_OVERWRITE_IF */
res = pNtCreateNamedPipeFile(&handle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr, &iosb, FILE_SHARE_READ, 5 /*FILE_OVERWRITE_IF*/,
0, 1, 0, 0, 0xFFFFFFFF, 500, 500, &timeout);
todo_wine ok(res == STATUS_INVALID_PARAMETER, "NtCreateNamedPipeFile returned %lx\n", res);
ok(res == STATUS_INVALID_PARAMETER, "NtCreateNamedPipeFile returned %lx\n", res);
if (!res)
CloseHandle(handle);
......@@ -289,7 +289,7 @@ static void test_create_invalid(void)
/* test FILE_CREATE creation disposition */
res = pNtCreateNamedPipeFile(&handle2, SYNCHRONIZE, &attr, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, 2 /*FILE_CREATE*/,
0, 1, 0, 0, 0xFFFFFFFF, 500, 500, &timeout);
todo_wine ok(res == STATUS_ACCESS_DENIED, "NtCreateNamedPipeFile returned %lx\n", res);
ok(res == STATUS_ACCESS_DENIED, "NtCreateNamedPipeFile returned %lx\n", res);
if (!res)
CloseHandle(handle2);
......
......@@ -4138,6 +4138,7 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( HANDLE *handle, ULONG access, OBJECT_ATTR
(pipe_type ? NAMED_PIPE_MESSAGE_STREAM_WRITE : 0) |
(read_mode ? NAMED_PIPE_MESSAGE_STREAM_READ : 0) |
(completion_mode ? NAMED_PIPE_NONBLOCKING_MODE : 0);
req->disposition = dispo;
req->maxinstances = max_inst;
req->outsize = outbound_quota;
req->insize = inbound_quota;
......
......@@ -3073,10 +3073,10 @@ struct create_named_pipe_request
unsigned int access;
unsigned int options;
unsigned int sharing;
unsigned int disposition;
unsigned int maxinstances;
unsigned int outsize;
unsigned int insize;
char __pad_36[4];
timeout_t timeout;
unsigned int flags;
/* VARARG(objattr,object_attributes); */
......@@ -6356,7 +6356,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 758
#define SERVER_PROTOCOL_VERSION 759
/* ### protocol_version end ### */
......
......@@ -1403,12 +1403,25 @@ DECL_HANDLER(create_named_pipe)
if (!(root = get_handle_obj( current->process, objattr->rootdir, 0, NULL ))) return;
}
pipe = create_named_object( root, &named_pipe_ops, &name, objattr->attributes | OBJ_OPENIF, NULL );
switch (req->disposition)
{
case FILE_OPEN:
pipe = open_named_object( root, &named_pipe_ops, &name, objattr->attributes );
break;
case FILE_CREATE:
case FILE_OPEN_IF:
pipe = create_named_object( root, &named_pipe_ops, &name, objattr->attributes | OBJ_OPENIF, NULL );
break;
default:
pipe = NULL;
set_error( STATUS_INVALID_PARAMETER );
break;
}
if (root) release_object( root );
if (!pipe) return;
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
if (get_error() != STATUS_OBJECT_NAME_EXISTS && req->disposition != FILE_OPEN)
{
/* initialize it if it didn't already exist */
pipe->instances = 0;
......@@ -1433,7 +1446,7 @@ DECL_HANDLER(create_named_pipe)
release_object( pipe );
return;
}
if (pipe->sharing != req->sharing)
if (pipe->sharing != req->sharing || req->disposition == FILE_CREATE)
{
set_error( STATUS_ACCESS_DENIED );
release_object( pipe );
......
......@@ -2270,6 +2270,7 @@ enum message_type
unsigned int access;
unsigned int options;
unsigned int sharing;
unsigned int disposition;
unsigned int maxinstances;
unsigned int outsize;
unsigned int insize;
......
......@@ -1451,9 +1451,10 @@ C_ASSERT( sizeof(struct set_irp_result_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, access) == 12 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, options) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, sharing) == 20 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, maxinstances) == 24 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, outsize) == 28 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, insize) == 32 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, disposition) == 24 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, maxinstances) == 28 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, outsize) == 32 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, insize) == 36 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, timeout) == 40 );
C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, flags) == 48 );
C_ASSERT( sizeof(struct create_named_pipe_request) == 56 );
......
......@@ -2861,6 +2861,7 @@ static void dump_create_named_pipe_request( const struct create_named_pipe_reque
fprintf( stderr, " access=%08x", req->access );
fprintf( stderr, ", options=%08x", req->options );
fprintf( stderr, ", sharing=%08x", req->sharing );
fprintf( stderr, ", disposition=%08x", req->disposition );
fprintf( stderr, ", maxinstances=%08x", req->maxinstances );
fprintf( stderr, ", outsize=%08x", req->outsize );
fprintf( stderr, ", insize=%08x", req->insize );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment