Move event and mutex objects into directory name space.
diff --git a/dlls/kernel/kernel_private.h b/dlls/kernel/kernel_private.h
index 73c3f22..3ed5f67 100644
--- a/dlls/kernel/kernel_private.h
+++ b/dlls/kernel/kernel_private.h
@@ -146,4 +146,7 @@
void (* BiosTick)(WORD timer);
} winedos;
+/* returns directory handle for named objects */
+extern HANDLE get_BaseNamedObjects_handle(void);
+
#endif
diff --git a/dlls/kernel/sync.c b/dlls/kernel/sync.c
index fafdc33..659ee30 100644
--- a/dlls/kernel/sync.c
+++ b/dlls/kernel/sync.c
@@ -52,6 +52,7 @@
#include "winnls.h"
#include "winternl.h"
#include "winioctl.h"
+#include "ddk/wdm.h"
#include "wine/server.h"
#include "wine/unicode.h"
@@ -68,6 +69,31 @@
return !(GetVersion() & 0x80000000);
}
+/* returns directory handle to \\BaseNamedObjects */
+HANDLE get_BaseNamedObjects_handle(void)
+{
+ static HANDLE handle = NULL;
+ static const WCHAR basenameW[] =
+ {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',0};
+ UNICODE_STRING str;
+ OBJECT_ATTRIBUTES attr;
+
+ if (!handle)
+ {
+ HANDLE dir;
+
+ RtlInitUnicodeString(&str, basenameW);
+ InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
+ NtOpenDirectoryObject(&dir, DIRECTORY_CREATE_OBJECT|DIRECTORY_TRAVERSE,
+ &attr);
+ if (InterlockedCompareExchangePointer( (PVOID)&handle, dir, 0 ) != 0)
+ {
+ /* someone beat us here... */
+ CloseHandle( dir );
+ }
+ }
+ return handle;
+}
/***********************************************************************
* Sleep (KERNEL32.@)
@@ -454,6 +480,7 @@
{
RtlInitUnicodeString( &nameW, name );
attr.ObjectName = &nameW;
+ attr.RootDirectory = get_BaseNamedObjects_handle();
}
status = NtCreateEvent( &ret, EVENT_ALL_ACCESS, &attr, manual_reset, initial_state );
@@ -514,6 +541,7 @@
{
RtlInitUnicodeString( &nameW, name );
attr.ObjectName = &nameW;
+ attr.RootDirectory = get_BaseNamedObjects_handle();
}
status = NtOpenEvent( &ret, access, &attr );
@@ -652,6 +680,7 @@
{
RtlInitUnicodeString( &nameW, name );
attr.ObjectName = &nameW;
+ attr.RootDirectory = get_BaseNamedObjects_handle();
}
status = NtCreateMutant( &ret, MUTEX_ALL_ACCESS, &attr, owner );
@@ -703,6 +732,7 @@
{
RtlInitUnicodeString( &nameW, name );
attr.ObjectName = &nameW;
+ attr.RootDirectory = get_BaseNamedObjects_handle();
}
status = NtOpenMutant( &ret, access, &attr );
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index 7ed7060..f5d85ae 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -177,6 +177,7 @@
{
req->access = DesiredAccess;
req->attributes = (attr) ? attr->Attributes : 0;
+ req->rootdir = attr ? attr->RootDirectory : 0;
req->manual_reset = ManualReset;
req->initial_state = InitialState;
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
@@ -205,6 +206,7 @@
{
req->access = DesiredAccess;
req->attributes = (attr) ? attr->Attributes : 0;
+ req->rootdir = attr ? attr->RootDirectory : 0;
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = wine_server_call( req );
*EventHandle = reply->handle;
@@ -324,6 +326,7 @@
{
req->access = access;
req->attributes = (attr) ? attr->Attributes : 0;
+ req->rootdir = attr ? attr->RootDirectory : 0;
req->owned = InitialOwner;
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
status = wine_server_call( req );
@@ -350,6 +353,7 @@
{
req->access = access;
req->attributes = (attr) ? attr->Attributes : 0;
+ req->rootdir = attr ? attr->RootDirectory : 0;
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
status = wine_server_call( req );
*MutantHandle = reply->handle;
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 79bd6b6..492033d 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -90,7 +90,7 @@
attr.Attributes = 0;
status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE);
- todo_wine ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
+ ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
"NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
pNtClose(Event);
@@ -191,13 +191,13 @@
DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS)
pNtClose(h);
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
- todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
+ ok(status == STATUS_OBJECT_TYPE_MISMATCH,
"NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
pRtlFreeUnicodeString(&str);
pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
- todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
+ ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
"NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
pRtlFreeUnicodeString(&str);
@@ -420,18 +420,18 @@
/* Test inavalid paths */
pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant");
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
- todo_wine ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
+ ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
"NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
pRtlFreeUnicodeString(&str);
pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\");
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
- todo_wine ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
+ ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD,
"NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status);
pRtlFreeUnicodeString(&str);
pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant");
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
- todo_wine ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
+ ok(status == STATUS_OBJECT_PATH_NOT_FOUND,
"NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status);
pRtlFreeUnicodeString(&str);
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index fcbf8b0..1818846 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -614,6 +614,7 @@
struct request_header __header;
unsigned int access;
unsigned int attributes;
+ obj_handle_t rootdir;
int manual_reset;
int initial_state;
/* VARARG(name,unicode_str); */
@@ -644,6 +645,7 @@
struct request_header __header;
unsigned int access;
unsigned int attributes;
+ obj_handle_t rootdir;
/* VARARG(name,unicode_str); */
};
struct open_event_reply
@@ -659,6 +661,7 @@
struct request_header __header;
unsigned int access;
unsigned int attributes;
+ obj_handle_t rootdir;
int owned;
/* VARARG(name,unicode_str); */
};
@@ -688,6 +691,7 @@
struct request_header __header;
unsigned int access;
unsigned int attributes;
+ obj_handle_t rootdir;
/* VARARG(name,unicode_str); */
};
struct open_mutex_reply
@@ -4302,6 +4306,6 @@
struct query_symlink_reply query_symlink_reply;
};
-#define SERVER_PROTOCOL_VERSION 201
+#define SERVER_PROTOCOL_VERSION 202
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/console.c b/server/console.c
index d13c7de..e567d60 100644
--- a/server/console.c
+++ b/server/console.c
@@ -233,7 +233,7 @@
console_input->history_index = 0;
console_input->history_mode = 0;
console_input->edition_mode = 0;
- console_input->event = create_event( NULL, 0, 1, 0 );
+ console_input->event = create_event( NULL, NULL, 0, 1, 0 );
if (!console_input->history || !console_input->evt)
{
diff --git a/server/event.c b/server/event.c
index bd73b88..8443837 100644
--- a/server/event.c
+++ b/server/event.c
@@ -63,12 +63,12 @@
};
-struct event *create_event( const struct unicode_str *name, unsigned int attr,
- int manual_reset, int initial_state )
+struct event *create_event( struct directory *root, const struct unicode_str *name,
+ unsigned int attr, int manual_reset, int initial_state )
{
struct event *event;
- if ((event = create_named_object( sync_namespace, &event_ops, name, attr )))
+ if ((event = create_named_object_dir( root, name, attr, &event_ops )))
{
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
@@ -150,24 +150,36 @@
{
struct event *event;
struct unicode_str name;
+ struct directory *root = NULL;
reply->handle = 0;
get_req_unicode_str( &name );
- if ((event = create_event( &name, req->attributes, req->manual_reset, req->initial_state )))
+ if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
+ return;
+
+ if ((event = create_event( root, &name, req->attributes, req->manual_reset, req->initial_state )))
{
reply->handle = alloc_handle( current->process, event, req->access,
req->attributes & OBJ_INHERIT );
release_object( event );
}
+
+ if (root) release_object( root );
}
/* open a handle to an event */
DECL_HANDLER(open_event)
{
struct unicode_str name;
+ struct directory *root = NULL;
get_req_unicode_str( &name );
- reply->handle = open_object( sync_namespace, &name, &event_ops, req->access, req->attributes );
+ if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
+ return;
+
+ reply->handle = open_object_dir( root, &name, req->attributes, &event_ops, req->access );
+
+ if (root) release_object( root );
}
/* do an event operation */
diff --git a/server/mutex.c b/server/mutex.c
index 0953f3f..9e3bdc3 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -66,11 +66,12 @@
};
-static struct mutex *create_mutex( const struct unicode_str *name, unsigned int attr, int owned )
+static struct mutex *create_mutex( struct directory *root, const struct unicode_str *name,
+ unsigned int attr, int owned )
{
struct mutex *mutex;
- if ((mutex = create_named_object( sync_namespace, &mutex_ops, name, attr )))
+ if ((mutex = create_named_object_dir( root, name, attr, &mutex_ops )))
{
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
@@ -175,24 +176,36 @@
{
struct mutex *mutex;
struct unicode_str name;
+ struct directory *root = NULL;
reply->handle = 0;
get_req_unicode_str( &name );
- if ((mutex = create_mutex( &name, req->attributes, req->owned )))
+ if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
+ return;
+
+ if ((mutex = create_mutex( root, &name, req->attributes, req->owned )))
{
reply->handle = alloc_handle( current->process, mutex, req->access,
req->attributes & OBJ_INHERIT );
release_object( mutex );
}
+
+ if (root) release_object( root );
}
/* open a handle to a mutex */
DECL_HANDLER(open_mutex)
{
struct unicode_str name;
+ struct directory *root = NULL;
get_req_unicode_str( &name );
- reply->handle = open_object( sync_namespace, &name, &mutex_ops, req->access, req->attributes );
+ if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
+ return;
+
+ reply->handle = open_object_dir( root, &name, req->attributes, &mutex_ops, req->access );
+
+ if (root) release_object( root );
}
/* release a mutex */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 37eaf2c..0aa5733 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -402,7 +402,7 @@
/* this kind of sux -
there's no unix way to be alerted when a pipe becomes empty */
- server->event = create_event( NULL, 0, 0, 0 );
+ server->event = create_event( NULL, NULL, 0, 0, 0 );
if (!server->event)
return 0;
gettimeofday( &tv, NULL );
diff --git a/server/object.h b/server/object.h
index c30c137..d138729 100644
--- a/server/object.h
+++ b/server/object.h
@@ -129,8 +129,8 @@
struct event;
-extern struct event *create_event( const struct unicode_str *name, unsigned int attr,
- int manual_reset, int initial_state );
+extern struct event *create_event( struct directory *root, const struct unicode_str *name,
+ unsigned int attr, int manual_reset, int initial_state );
extern struct event *get_event_obj( struct process *process, obj_handle_t handle, unsigned int access );
extern void pulse_event( struct event *event );
extern void set_event( struct event *event );
diff --git a/server/process.c b/server/process.c
index fab6761..6e65da5 100644
--- a/server/process.c
+++ b/server/process.c
@@ -997,7 +997,7 @@
generate_startup_debug_events( process, req->entry );
set_process_startup_state( process, STARTUP_DONE );
- if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 );
+ if (req->gui) process->idle_event = create_event( NULL, NULL, 0, 1, 0 );
if (current->suspend + process->suspend > 0) stop_thread( current );
if (process->debugger) set_process_debug_flag( process, 1 );
}
diff --git a/server/protocol.def b/server/protocol.def
index 91256e5..934ae42 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -496,6 +496,7 @@
@REQ(create_event)
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
+ obj_handle_t rootdir; /* root directory */
int manual_reset; /* manual reset event */
int initial_state; /* initial state of the event */
VARARG(name,unicode_str); /* object name */
@@ -515,6 +516,7 @@
@REQ(open_event)
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
+ obj_handle_t rootdir; /* root directory */
VARARG(name,unicode_str); /* object name */
@REPLY
obj_handle_t handle; /* handle to the event */
@@ -525,6 +527,7 @@
@REQ(create_mutex)
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
+ obj_handle_t rootdir; /* root directory */
int owned; /* initially owned? */
VARARG(name,unicode_str); /* object name */
@REPLY
@@ -544,6 +547,7 @@
@REQ(open_mutex)
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
+ obj_handle_t rootdir; /* root directory */
VARARG(name,unicode_str); /* object name */
@REPLY
obj_handle_t handle; /* handle to the mutex */
diff --git a/server/trace.c b/server/trace.c
index 2237e7c..04c4bb4 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -893,6 +893,7 @@
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes );
+ fprintf( stderr, " rootdir=%p,", req->rootdir );
fprintf( stderr, " manual_reset=%d,", req->manual_reset );
fprintf( stderr, " initial_state=%d,", req->initial_state );
fprintf( stderr, " name=" );
@@ -914,6 +915,7 @@
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes );
+ fprintf( stderr, " rootdir=%p,", req->rootdir );
fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size );
}
@@ -927,6 +929,7 @@
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes );
+ fprintf( stderr, " rootdir=%p,", req->rootdir );
fprintf( stderr, " owned=%d,", req->owned );
fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size );
@@ -951,6 +954,7 @@
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes );
+ fprintf( stderr, " rootdir=%p,", req->rootdir );
fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size );
}