- now passing access rights when creating a named pipe in NTDLL
- reimplemented Kernel32.CreatePipe purely on top of NTDLL APIs
- anonymous pipe handles should have the SYNCHRONIZE bit set
diff --git a/dlls/kernel/sync.c b/dlls/kernel/sync.c
index a93e322..8390ef7 100644
--- a/dlls/kernel/sync.c
+++ b/dlls/kernel/sync.c
@@ -1133,10 +1133,10 @@
SetLastError(0);
- status = NtCreateNamedPipeFile(&handle, 0, &attr, &iosb, 0, FILE_OVERWRITE_IF,
- options, pipe_type, read_mode, non_block,
- nMaxInstances, nInBufferSize, nOutBufferSize,
- &timeout);
+ status = NtCreateNamedPipeFile(&handle, GENERIC_READ|GENERIC_WRITE, &attr, &iosb,
+ 0, FILE_OVERWRITE_IF, options, pipe_type,
+ read_mode, non_block, nMaxInstances,
+ nInBufferSize, nOutBufferSize, &timeout);
RtlFreeUnicodeString( &nt_name );
if (status)
@@ -1537,31 +1537,58 @@
BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
LPSECURITY_ATTRIBUTES sa, DWORD size )
{
- static unsigned index = 0;
- WCHAR name[64];
- HANDLE hr, hw;
- unsigned in_index = index;
+ static unsigned index /* = 0 */;
+ WCHAR name[64];
+ HANDLE hr, hw;
+ unsigned in_index = index;
+ UNICODE_STRING nt_name;
+ OBJECT_ATTRIBUTES attr;
+ NTSTATUS status;
+ IO_STATUS_BLOCK iosb;
+ LARGE_INTEGER timeout;
*hReadPipe = *hWritePipe = INVALID_HANDLE_VALUE;
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &nt_name;
+ attr.Attributes = OBJ_CASE_INSENSITIVE |
+ (sa && sa->bInheritHandle) ? OBJ_INHERIT : 0;
+ attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ timeout.QuadPart = (ULONGLONG)NMPWAIT_USE_DEFAULT_WAIT * -10000;
/* generate a unique pipe name (system wide) */
do
{
- static const WCHAR nameFmt[] = { '\\','\\','.','\\','p','i','p','e',
+ static const WCHAR nameFmt[] = { '\\','?','?','\\','p','i','p','e',
'\\','W','i','n','3','2','.','P','i','p','e','s','.','%','0','8','l',
'u','.','%','0','8','u','\0' };
+
snprintfW(name, sizeof(name) / sizeof(name[0]), nameFmt,
GetCurrentProcessId(), ++index);
- hr = CreateNamedPipeW(name, PIPE_ACCESS_INBOUND,
- PIPE_TYPE_BYTE | PIPE_WAIT, 1, size, size,
- NMPWAIT_USE_DEFAULT_WAIT, sa);
+ RtlInitUnicodeString(&nt_name, name);
+ status = NtCreateNamedPipeFile(&hr, GENERIC_READ | SYNCHRONIZE, &attr, &iosb,
+ 0, FILE_OVERWRITE_IF,
+ FILE_SYNCHRONOUS_IO_ALERT | FILE_PIPE_INBOUND,
+ FALSE, FALSE, FALSE,
+ 1, size, size, &timeout);
+ if (status)
+ {
+ SetLastError( RtlNtStatusToDosError(status) );
+ hr = INVALID_HANDLE_VALUE;
+ }
} while (hr == INVALID_HANDLE_VALUE && index != in_index);
/* from completion sakeness, I think system resources might be exhausted before this happens !! */
if (hr == INVALID_HANDLE_VALUE) return FALSE;
- hw = CreateFileW(name, GENERIC_WRITE, 0, sa, OPEN_EXISTING, 0, 0);
- if (hw == INVALID_HANDLE_VALUE)
+ status = NtOpenFile(&hw, GENERIC_WRITE | SYNCHRONIZE, &attr, &iosb, 0,
+ FILE_SYNCHRONOUS_IO_ALERT | FILE_NON_DIRECTORY_FILE);
+
+ if (status)
{
- CloseHandle(hr);
+ SetLastError( RtlNtStatusToDosError(status) );
+ NtClose(hr);
return FALSE;
}
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index cfd2c21..4c0da1a 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1940,7 +1940,8 @@
SERVER_START_REQ( create_named_pipe )
{
- req->options = options; /* FIXME not used in server yet !!!! */
+ req->access = access;
+ req->options = options;
req->flags =
(pipe_type) ? NAMED_PIPE_MESSAGE_STREAM_WRITE : 0 |
(read_mode) ? NAMED_PIPE_MESSAGE_STREAM_READ : 0 |
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 2f1ada88..77c548d 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2366,6 +2366,7 @@
struct create_named_pipe_request
{
struct request_header __header;
+ unsigned int access;
unsigned int options;
unsigned int flags;
unsigned int maxinstances;
@@ -4206,6 +4207,6 @@
struct set_mailslot_info_reply set_mailslot_info_reply;
};
-#define SERVER_PROTOCOL_VERSION 192
+#define SERVER_PROTOCOL_VERSION 193
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 55a8ee0..ba56d2f 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -583,7 +583,7 @@
if (server)
{
reply->handle = alloc_handle( current->process, server,
- GENERIC_READ|GENERIC_WRITE, req->inherit );
+ req->access, req->inherit );
server->pipe->instances++;
release_object( server );
}
diff --git a/server/protocol.def b/server/protocol.def
index 9e93f53..118ffc0 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1680,6 +1680,7 @@
/* Create a named pipe */
@REQ(create_named_pipe)
+ unsigned int access;
unsigned int options;
unsigned int flags;
unsigned int maxinstances;
diff --git a/server/trace.c b/server/trace.c
index 2c00f2e..4a28595 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2140,6 +2140,7 @@
static void dump_create_named_pipe_request( const struct create_named_pipe_request *req )
{
+ fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " options=%08x,", req->options );
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " maxinstances=%08x,", req->maxinstances );