Store all object names as Unicode in the server.

diff --git a/include/server.h b/include/server.h
index d30d839..62fe2e1 100644
--- a/include/server.h
+++ b/include/server.h
@@ -278,7 +278,7 @@
     IN  int          initial_state; /* initial state of the event */
     IN  int          inherit;       /* inherit flag */
     OUT int          handle;        /* handle to the event */
-    IN  char         name[1];       /* event name */
+    IN  WCHAR        name[1];       /* event name */
 };
 
 /* Event operation */
@@ -296,7 +296,7 @@
     IN  unsigned int access;        /* wanted access rights */
     IN  int          inherit;       /* inherit flag */
     OUT int          handle;        /* handle to the event */
-    IN  char         name[1];       /* object name */
+    IN  WCHAR        name[1];       /* object name */
 };
 
 
@@ -306,7 +306,7 @@
     IN  int          owned;         /* initially owned? */
     IN  int          inherit;       /* inherit flag */
     OUT int          handle;        /* handle to the mutex */
-    IN  char         name[1];       /* mutex name */
+    IN  WCHAR        name[1];       /* mutex name */
 };
 
 
@@ -323,7 +323,7 @@
     IN  unsigned int access;        /* wanted access rights */
     IN  int          inherit;       /* inherit flag */
     OUT int          handle;        /* handle to the mutex */
-    IN  char         name[1];       /* object name */
+    IN  WCHAR        name[1];       /* object name */
 };
 
 
@@ -334,7 +334,7 @@
     IN  unsigned int max;           /* maximum count */
     IN  int          inherit;       /* inherit flag */
     OUT int          handle;        /* handle to the semaphore */
-    IN  char         name[1];       /* semaphore name */
+    IN  WCHAR        name[1];       /* semaphore name */
 };
 
 
@@ -353,7 +353,7 @@
     IN  unsigned int access;        /* wanted access rights */
     IN  int          inherit;       /* inherit flag */
     OUT int          handle;        /* handle to the semaphore */
-    IN  char         name[1];       /* object name */
+    IN  WCHAR        name[1];       /* object name */
 };
 
 
@@ -642,7 +642,7 @@
     IN  int          inherit;       /* inherit flag */
     IN  int          file_handle;   /* file handle */
     OUT int          handle;        /* handle to the mapping */
-    IN  char         name[1];       /* object name */
+    IN  WCHAR        name[1];       /* object name */
 };
 /* protection flags */
 #define VPROT_READ       0x01
@@ -660,7 +660,7 @@
     IN  unsigned int access;        /* wanted access rights */
     IN  int          inherit;       /* inherit flag */
     OUT int          handle;        /* handle to the mapping */
-    IN  char         name[1];       /* object name */
+    IN  WCHAR        name[1];       /* object name */
 };
 
 
@@ -1097,6 +1097,28 @@
     return res;
 }
 
+/* copy a Unicode string to the server buffer */
+static inline void server_strcpyW( WCHAR *dst, const WCHAR *src )
+{
+    if (src)
+    {
+        WCHAR *end = (WCHAR *)((char *)NtCurrentTeb()->buffer + NtCurrentTeb()->buffer_size) - 1;
+        while ((dst < end) && *src) *dst++ = *src++;
+    }
+    *dst = 0;
+}
+
+/* copy and convert an ASCII string to the server buffer */
+static inline void server_strcpyAtoW( WCHAR *dst, const char *src )
+{
+    if (src)
+    {
+        WCHAR *end = (WCHAR *)((char *)NtCurrentTeb()->buffer + NtCurrentTeb()->buffer_size) - 1;
+        while ((dst < end) && *src) *dst++ = (WCHAR)(unsigned char)*src++;
+    }
+    *dst = 0;
+}
+
 extern int CLIENT_InitServer(void);
 extern int CLIENT_SetDebug( int level );
 extern int CLIENT_DebuggerRequest( int op );
diff --git a/memory/virtual.c b/memory/virtual.c
index b70bf4f..7cb6c25 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -22,7 +22,6 @@
 #include "winbase.h"
 #include "winerror.h"
 #include "file.h"
-#include "heap.h"
 #include "process.h"
 #include "xmalloc.h"
 #include "global.h"
@@ -1090,7 +1089,7 @@
     req->size_low    = size_low;
     req->protect     = vprot;
     req->inherit     = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_strcpyAtoW( req->name, name );
     SetLastError(0);
     server_call( REQ_CREATE_MAPPING );
     if (req->handle == -1) return 0;
@@ -1102,15 +1101,42 @@
  *             CreateFileMapping32W   (KERNEL32.47)
  * See CreateFileMapping32A
  */
-HANDLE WINAPI CreateFileMappingW( HFILE hFile, LPSECURITY_ATTRIBUTES attr, 
-                                      DWORD protect, DWORD size_high,  
-                                      DWORD size_low, LPCWSTR name )
+HANDLE WINAPI CreateFileMappingW( HFILE hFile, LPSECURITY_ATTRIBUTES sa, 
+                                  DWORD protect, DWORD size_high,  
+                                  DWORD size_low, LPCWSTR name )
 {
-    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    HANDLE ret = CreateFileMappingA( hFile, attr, protect,
-                                         size_high, size_low, nameA );
-    HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
+    struct create_mapping_request *req = get_req_buffer();
+    BYTE vprot;
+
+    /* Check parameters */
+
+    TRACE("(%x,%p,%08lx,%08lx%08lx,%s)\n",
+          hFile, sa, protect, size_high, size_low, debugstr_w(name) );
+
+    vprot = VIRTUAL_GetProt( protect );
+    if (protect & SEC_RESERVE)
+    {
+        if (hFile != INVALID_HANDLE_VALUE)
+        {
+            SetLastError( ERROR_INVALID_PARAMETER );
+            return 0;
+        }
+    }
+    else vprot |= VPROT_COMMITTED;
+    if (protect & SEC_NOCACHE) vprot |= VPROT_NOCACHE;
+
+    /* Create the server object */
+
+    req->file_handle = hFile;
+    req->size_high   = size_high;
+    req->size_low    = size_low;
+    req->protect     = vprot;
+    req->inherit     = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    server_strcpyW( req->name, name );
+    SetLastError(0);
+    server_call( REQ_CREATE_MAPPING );
+    if (req->handle == -1) return 0;
+    return req->handle;
 }
 
 
@@ -1131,7 +1157,7 @@
 
     req->access  = access;
     req->inherit = inherit;
-    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_strcpyAtoW( req->name, name );
     server_call( REQ_OPEN_MAPPING );
     if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
     return req->handle;
@@ -1144,10 +1170,14 @@
  */
 HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name)
 {
-    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    HANDLE ret = OpenFileMappingA( access, inherit, nameA );
-    HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
+    struct open_mapping_request *req = get_req_buffer();
+
+    req->access  = access;
+    req->inherit = inherit;
+    server_strcpyW( req->name, name );
+    server_call( REQ_OPEN_MAPPING );
+    if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
+    return req->handle;
 }
 
 
diff --git a/scheduler/event.c b/scheduler/event.c
index 9c37bc3..1004ead 100644
--- a/scheduler/event.c
+++ b/scheduler/event.c
@@ -7,7 +7,6 @@
 #include <assert.h>
 #include <string.h>
 #include "winerror.h"
-#include "heap.h"
 #include "syslevel.h"
 #include "server.h"
 
@@ -16,14 +15,14 @@
  *           CreateEvent32A    (KERNEL32.156)
  */
 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
-                                BOOL initial_state, LPCSTR name )
+                            BOOL initial_state, LPCSTR name )
 {
     struct create_event_request *req = get_req_buffer();
 
     req->manual_reset = manual_reset;
     req->initial_state = initial_state;
     req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_strcpyAtoW( req->name, name );
     SetLastError(0);
     server_call( REQ_CREATE_EVENT );
     if (req->handle == -1) return 0;
@@ -35,12 +34,18 @@
  *           CreateEvent32W    (KERNEL32.157)
  */
 HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
-                                BOOL initial_state, LPCWSTR name )
+                            BOOL initial_state, LPCWSTR name )
 {
-    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    HANDLE ret = CreateEventA( sa, manual_reset, initial_state, nameA );
-    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
+    struct create_event_request *req = get_req_buffer();
+
+    req->manual_reset = manual_reset;
+    req->initial_state = initial_state;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    server_strcpyW( req->name, name );
+    SetLastError(0);
+    server_call( REQ_CREATE_EVENT );
+    if (req->handle == -1) return 0;
+    return req->handle;
 }
 
 /***********************************************************************
@@ -61,7 +66,7 @@
 
     req->access  = access;
     req->inherit = inherit;
-    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_strcpyAtoW( req->name, name );
     server_call( REQ_OPEN_EVENT );
     if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
     return req->handle;
@@ -73,10 +78,14 @@
  */
 HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
 {
-    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    HANDLE ret = OpenEventA( access, inherit, nameA );
-    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
+    struct open_event_request *req = get_req_buffer();
+
+    req->access  = access;
+    req->inherit = inherit;
+    server_strcpyW( req->name, name );
+    server_call( REQ_OPEN_EVENT );
+    if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
+    return req->handle;
 }
 
 
diff --git a/scheduler/mutex.c b/scheduler/mutex.c
index 94110f1..24bbe19 100644
--- a/scheduler/mutex.c
+++ b/scheduler/mutex.c
@@ -7,7 +7,6 @@
 #include <assert.h>
 #include <string.h>
 #include "winerror.h"
-#include "heap.h"
 #include "server.h"
 
 
@@ -20,7 +19,7 @@
 
     req->owned   = owner;
     req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_strcpyAtoW( req->name, name );
     SetLastError(0);
     server_call( REQ_CREATE_MUTEX );
     if (req->handle == -1) return 0;
@@ -31,13 +30,17 @@
 /***********************************************************************
  *           CreateMutex32W   (KERNEL32.167)
  */
-HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner,
-                                LPCWSTR name )
+HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
 {
-    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    HANDLE ret = CreateMutexA( sa, owner, nameA );
-    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
+    struct create_mutex_request *req = get_req_buffer();
+
+    req->owned   = owner;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    server_strcpyW( req->name, name );
+    SetLastError(0);
+    server_call( REQ_CREATE_MUTEX );
+    if (req->handle == -1) return 0;
+    return req->handle;
 }
 
 
@@ -50,7 +53,7 @@
 
     req->access  = access;
     req->inherit = inherit;
-    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_strcpyAtoW( req->name, name );
     server_call( REQ_OPEN_MUTEX );
     if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
     return req->handle;
@@ -62,10 +65,14 @@
  */
 HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
 {
-    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    HANDLE ret = OpenMutexA( access, inherit, nameA );
-    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
+    struct open_mutex_request *req = get_req_buffer();
+
+    req->access  = access;
+    req->inherit = inherit;
+    server_strcpyW( req->name, name );
+    server_call( REQ_OPEN_MUTEX );
+    if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
+    return req->handle;
 }
 
 
diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c
index 890efa8..a9b130f 100644
--- a/scheduler/semaphore.c
+++ b/scheduler/semaphore.c
@@ -7,7 +7,6 @@
 #include <assert.h>
 #include <string.h>
 #include "winerror.h"
-#include "heap.h"
 #include "server.h"
 
 
@@ -29,7 +28,7 @@
     req->initial = (unsigned int)initial;
     req->max     = (unsigned int)max;
     req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_strcpyAtoW( req->name, name );
     SetLastError(0);
     server_call( REQ_CREATE_SEMAPHORE );
     if (req->handle == -1) return 0;
@@ -43,10 +42,24 @@
 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
                                     LONG max, LPCWSTR name )
 {
-    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    HANDLE ret = CreateSemaphoreA( sa, initial, max, nameA );
-    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
+    struct create_semaphore_request *req = get_req_buffer();
+
+    /* Check parameters */
+
+    if ((max <= 0) || (initial < 0) || (initial > max))
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+
+    req->initial = (unsigned int)initial;
+    req->max     = (unsigned int)max;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    server_strcpyW( req->name, name );
+    SetLastError(0);
+    server_call( REQ_CREATE_SEMAPHORE );
+    if (req->handle == -1) return 0;
+    return req->handle;
 }
 
 
@@ -59,7 +72,7 @@
 
     req->access  = access;
     req->inherit = inherit;
-    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_strcpyAtoW( req->name, name );
     server_call( REQ_OPEN_SEMAPHORE );
     if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
     return req->handle;
@@ -71,10 +84,14 @@
  */
 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
 {
-    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
-    HANDLE ret = OpenSemaphoreA( access, inherit, nameA );
-    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
-    return ret;
+    struct open_semaphore_request *req = get_req_buffer();
+
+    req->access  = access;
+    req->inherit = inherit;
+    server_strcpyW( req->name, name );
+    server_call( REQ_OPEN_SEMAPHORE );
+    if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
+    return req->handle;
 }
 
 
@@ -83,6 +100,7 @@
  */
 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
 {
+    BOOL ret = FALSE;
     struct release_semaphore_request *req = get_req_buffer();
 
     if (count < 0)
@@ -92,7 +110,10 @@
     }
     req->handle = handle;
     req->count  = (unsigned int)count;
-    if (server_call( REQ_RELEASE_SEMAPHORE )) return FALSE;
-    if (previous) *previous = req->prev_count;
-    return TRUE;
+    if (!server_call( REQ_RELEASE_SEMAPHORE ))
+    {
+        if (previous) *previous = req->prev_count;
+        ret = TRUE;
+    }
+    return ret;
 }
diff --git a/server/Makefile.in b/server/Makefile.in
index 81f3401..d917cfe 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -27,7 +27,8 @@
 	sock.c \
 	socket.c \
 	thread.c \
-	trace.c
+	trace.c \
+	unicode.c
 
 EXTRA_SRCS = main.c
 MAIN_OBJS = main.o
diff --git a/server/event.c b/server/event.c
index 100adb8..77d036b 100644
--- a/server/event.c
+++ b/server/event.c
@@ -42,7 +42,7 @@
 };
 
 
-static struct event *create_event( const char *name, size_t len,
+static struct event *create_event( const WCHAR *name, size_t len,
                                    int manual_reset, int initial_state )
 {
     struct event *event;
@@ -88,9 +88,10 @@
 {
     struct event *event = (struct event *)obj;
     assert( obj->ops == &event_ops );
-    fprintf( stderr, "Event manual=%d signaled=%d name='%s'\n",
-             event->manual_reset, event->signaled,
-             get_object_name( &event->obj ) );
+    fprintf( stderr, "Event manual=%d signaled=%d ",
+             event->manual_reset, event->signaled );
+    dump_object_name( &event->obj );
+    fputc( '\n', stderr );
 }
 
 static int event_signaled( struct object *obj, struct thread *thread )
@@ -112,7 +113,7 @@
 /* create an event */
 DECL_HANDLER(create_event)
 {
-    size_t len = get_req_strlen( req->name );
+    size_t len = get_req_strlenW( req->name );
     struct event *event;
 
     req->handle = -1;
@@ -126,7 +127,7 @@
 /* open a handle to an event */
 DECL_HANDLER(open_event)
 {
-    size_t len = get_req_strlen( req->name );
+    size_t len = get_req_strlenW( req->name );
     req->handle = open_object( req->name, len, &event_ops, req->access, req->inherit );
 }
 
diff --git a/server/handle.c b/server/handle.c
index 541dc5c..ea6d6c8 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -399,22 +399,22 @@
 }
 
 /* open a new handle to an existing object */
-int open_object( const char *name, size_t len, const struct object_ops *ops,
+int open_object( const WCHAR *name, size_t len, const struct object_ops *ops,
                  unsigned int access, int inherit )
 {
+    int handle = -1;
     struct object *obj = find_object( name, len );
-    if (!obj) 
+    if (obj)
     {
-        set_error( ERROR_FILE_NOT_FOUND );
-        return -1;
-    }
-    if (ops && obj->ops != ops)
-    {
+        if (ops && obj->ops != ops)
+            set_error( ERROR_INVALID_HANDLE );
+        else
+            handle = alloc_handle( current->process, obj, access, inherit );
         release_object( obj );
-        set_error( ERROR_INVALID_HANDLE );  /* FIXME: not the right type */ 
-        return -1;
     }
-    return alloc_handle( current->process, obj, access, inherit );
+    else
+        set_error( ERROR_FILE_NOT_FOUND );
+    return handle;
 }
 
 /* close a handle */
diff --git a/server/handle.h b/server/handle.h
index 5763714..7bba30b 100644
--- a/server/handle.h
+++ b/server/handle.h
@@ -12,6 +12,7 @@
 #endif
 
 #include <stdlib.h>
+#include "windef.h"
 
 struct process;
 struct object_ops;
@@ -27,7 +28,7 @@
                                       unsigned int access, const struct object_ops *ops );
 extern int duplicate_handle( struct process *src, int src_handle, struct process *dst,
                              unsigned int access, int inherit, int options );
-extern int open_object( const char *name, size_t len, const struct object_ops *ops,
+extern int open_object( const WCHAR *name, size_t len, const struct object_ops *ops,
                         unsigned int access, int inherit );
 extern struct object *alloc_handle_table( struct process *process, int count );
 extern struct object *copy_handle_table( struct process *process, struct process *parent );
diff --git a/server/mapping.c b/server/mapping.c
index a273ed5..bf45e04 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -84,7 +84,7 @@
 
 
 static struct object *create_mapping( int size_high, int size_low, int protect,
-                                      int handle, const char *name, size_t len )
+                                      int handle, const WCHAR *name, size_t len )
 {
     struct mapping *mapping;
     int access = 0;
@@ -137,9 +137,10 @@
 {
     struct mapping *mapping = (struct mapping *)obj;
     assert( obj->ops == &mapping_ops );
-    fprintf( stderr, "Mapping size=%08x%08x prot=%08x file=%p name='%s'\n",
-             mapping->size_high, mapping->size_low, mapping->protect,
-             mapping->file, get_object_name( &mapping->obj ) );
+    fprintf( stderr, "Mapping size=%08x%08x prot=%08x file=%p ",
+             mapping->size_high, mapping->size_low, mapping->protect, mapping->file );
+    dump_object_name( &mapping->obj );
+    fputc( '\n', stderr );
 }
 
 static void mapping_destroy( struct object *obj )
@@ -158,7 +159,7 @@
 /* create a file mapping */
 DECL_HANDLER(create_mapping)
 {
-    size_t len = get_req_strlen( req->name );
+    size_t len = get_req_strlenW( req->name );
     struct object *obj;
 
     req->handle = -1;
@@ -175,7 +176,7 @@
 /* open a handle to a mapping */
 DECL_HANDLER(open_mapping)
 {
-    size_t len = get_req_strlen( req->name );
+    size_t len = get_req_strlenW( req->name );
     req->handle = open_object( req->name, len, &mapping_ops, req->access, req->inherit );
 }
 
diff --git a/server/mutex.c b/server/mutex.c
index 1173d5d..1ce86f9 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -46,7 +46,7 @@
 };
 
 
-static struct mutex *create_mutex( const char *name, size_t len, int owned )
+static struct mutex *create_mutex( const WCHAR *name, size_t len, int owned )
 {
     struct mutex *mutex;
 
@@ -94,8 +94,9 @@
 {
     struct mutex *mutex = (struct mutex *)obj;
     assert( obj->ops == &mutex_ops );
-    printf( "Mutex count=%u owner=%p name='%s'\n",
-            mutex->count, mutex->owner, get_object_name( &mutex->obj) );
+    fprintf( stderr, "Mutex count=%u owner=%p ", mutex->count, mutex->owner );
+    dump_object_name( &mutex->obj );
+    fputc( '\n', stderr );
 }
 
 static int mutex_signaled( struct object *obj, struct thread *thread )
@@ -137,7 +138,7 @@
 /* create a mutex */
 DECL_HANDLER(create_mutex)
 {
-    size_t len = get_req_strlen( req->name );
+    size_t len = get_req_strlenW( req->name );
     struct mutex *mutex;
 
     req->handle = -1;
@@ -151,7 +152,7 @@
 /* open a handle to a mutex */
 DECL_HANDLER(open_mutex)
 {
-    size_t len = get_req_strlen( req->name );
+    size_t len = get_req_strlenW( req->name );
     req->handle = open_object( req->name, len, &mutex_ops, req->access, req->inherit );
 }
 
diff --git a/server/object.c b/server/object.c
index 31d522c..9d44965 100644
--- a/server/object.c
+++ b/server/object.c
@@ -13,6 +13,7 @@
 
 #include "winerror.h"
 #include "thread.h"
+#include "unicode.h"
 
 int debug_level = 0;
 
@@ -22,7 +23,7 @@
     struct object_name *prev;
     struct object      *obj;
     size_t              len;
-    char                name[1];
+    WCHAR               name[1];
 };
 
 #define NAME_HASH_SIZE 37
@@ -66,22 +67,22 @@
 
 /*****************************************************************/
 
-static int get_name_hash( const char *name, size_t len )
+static int get_name_hash( const WCHAR *name, size_t len )
 {
-    char hash = 0;
+    WCHAR hash = 0;
     while (len--) hash ^= *name++;
     return hash % NAME_HASH_SIZE;
 }
 
 /* allocate a name for an object */
-static struct object_name *alloc_name( const char *name, size_t len )
+static struct object_name *alloc_name( const WCHAR *name, size_t len )
 {
     struct object_name *ptr;
 
-    if ((ptr = mem_alloc( sizeof(*ptr) + len )))
+    if ((ptr = mem_alloc( sizeof(*ptr) + len * sizeof(ptr->name[0]) )))
     {
         ptr->len = len;
-        memcpy( ptr->name, name, len );
+        memcpy( ptr->name, name, len * sizeof(ptr->name[0]) );
         ptr->name[len] = 0;
     }
     return ptr;
@@ -139,7 +140,7 @@
     return obj;
 }
 
-void *create_named_object( const struct object_ops *ops, const char *name, size_t len )
+void *create_named_object( const struct object_ops *ops, const WCHAR *name, size_t len )
 {
     struct object *obj;
     struct object_name *name_ptr;
@@ -167,11 +168,16 @@
     return obj;
 }
 
-/* return a pointer to the object name, or to an empty string */
-const char *get_object_name( struct object *obj )
+/* dump the name of an object to stderr */
+void dump_object_name( struct object *obj )
 {
-    if (!obj->name) return "";
-    return obj->name->name;
+    if (!obj->name) fprintf( stderr, "name=\"\"" );
+    else
+    {
+        fprintf( stderr, "name=L\"" );
+        dump_strW( obj->name->name, strlenW(obj->name->name), stderr, "\"\"" );
+        fputc( '\"', stderr );
+    }
 }
 
 /* grab an object (i.e. increment its refcount) and return the object */
@@ -206,14 +212,14 @@
 }
 
 /* find an object by its name; the refcount is incremented */
-struct object *find_object( const char *name, size_t len )
+struct object *find_object( const WCHAR *name, size_t len )
 {
     struct object_name *ptr;
     if (!name || !len) return NULL;
     for (ptr = names[ get_name_hash( name, len ) ]; ptr; ptr = ptr->next)
     {
         if (ptr->len != len) continue;
-        if (!memcmp( ptr->name, name, len )) return grab_object( ptr->obj );
+        if (!memcmp( ptr->name, name, len*sizeof(WCHAR) )) return grab_object( ptr->obj );
     }
     return NULL;
 }
diff --git a/server/object.h b/server/object.h
index 5c1a97b..46c9c6c 100644
--- a/server/object.h
+++ b/server/object.h
@@ -68,13 +68,13 @@
 extern void *mem_alloc( size_t size );  /* malloc wrapper */
 extern void *memdup( const void *data, size_t len );
 extern void *alloc_object( const struct object_ops *ops );
-extern const char *get_object_name( struct object *obj );
-extern void *create_named_object( const struct object_ops *ops, const char *name, size_t len );
+extern void dump_object_name( struct object *obj );
+extern void *create_named_object( const struct object_ops *ops, const WCHAR *name, size_t len );
 /* grab/release_object can take any pointer, but you better make sure */
 /* that the thing pointed to starts with a struct object... */
 extern struct object *grab_object( void *obj );
 extern void release_object( void *obj );
-extern struct object *find_object( const char *name, size_t len );
+extern struct object *find_object( const WCHAR *name, size_t len );
 extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
 extern int no_satisfied( struct object *obj, struct thread *thread );
 extern int no_read_fd( struct object *obj );
diff --git a/server/registry.c b/server/registry.c
index c33561f..854e647 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -129,50 +129,6 @@
  * - REG_EXPAND_SZ and REG_MULTI_SZ are saved as strings instead of hex
  */
 
-/* dump a string to a text file with proper escaping */
-static int dump_strW( const WCHAR *str, int len, FILE *f, char escape[2] )
-{
-    static const char escapes[32] = ".......abtnvfr.............e....";
-    char buffer[256];
-    char *pos = buffer;
-    int count = 0;
-
-    for (; len; str++, len--)
-    {
-        if (pos > buffer + sizeof(buffer) - 8)
-        {
-            fwrite( buffer, pos - buffer, 1, f );
-            count += pos - buffer;
-            pos = buffer;
-        }
-        if (*str > 127)  /* hex escape */
-        {
-            if (len > 1 && str[1] < 128 && isxdigit((char)str[1]))
-                pos += sprintf( pos, "\\x%04x", *str );
-            else
-                pos += sprintf( pos, "\\x%x", *str );
-            continue;
-        }
-        if (*str < 32)  /* octal or C escape */
-        {
-            if (!*str && len == 1) continue;  /* do not output terminating NULL */
-            if (escapes[*str] != '.')
-                pos += sprintf( pos, "\\%c", escapes[*str] );
-            else if (len > 1 && str[1] >= '0' && str[1] <= '7')
-                pos += sprintf( pos, "\\%03o", *str );
-            else
-                pos += sprintf( pos, "\\%o", *str );
-            continue;
-        }
-        if (*str == '\\' || *str == escape[0] || *str == escape[1]) *pos++ = '\\';
-        *pos++ = *str;
-    }
-    fwrite( buffer, pos - buffer, 1, f );
-    count += pos - buffer;
-    return count;
-}
-
-
 static inline char to_hex( char ch )
 {
     if (isdigit(ch)) return ch - '0';
diff --git a/server/semaphore.c b/server/semaphore.c
index f9fb671..36656f4 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -42,7 +42,7 @@
 };
 
 
-static struct semaphore *create_semaphore( const char *name, size_t len,
+static struct semaphore *create_semaphore( const WCHAR *name, size_t len,
                                            unsigned int initial, unsigned int max )
 {
     struct semaphore *sem;
@@ -97,8 +97,9 @@
 {
     struct semaphore *sem = (struct semaphore *)obj;
     assert( obj->ops == &semaphore_ops );
-    fprintf( stderr, "Semaphore count=%d max=%d name='%s'\n",
-             sem->count, sem->max, get_object_name( &sem->obj ) );
+    fprintf( stderr, "Semaphore count=%d max=%d ", sem->count, sem->max );
+    dump_object_name( &sem->obj );
+    fputc( '\n', stderr );
 }
 
 static int semaphore_signaled( struct object *obj, struct thread *thread )
@@ -120,7 +121,7 @@
 /* create a semaphore */
 DECL_HANDLER(create_semaphore)
 {
-    size_t len = get_req_strlen( req->name );
+    size_t len = get_req_strlenW( req->name );
     struct semaphore *sem;
 
     req->handle = -1;
@@ -134,7 +135,7 @@
 /* open a handle to a semaphore */
 DECL_HANDLER(open_semaphore)
 {
-    size_t len = get_req_strlen( req->name );
+    size_t len = get_req_strlenW( req->name );
     req->handle = open_object( req->name, len, &semaphore_ops, req->access, req->inherit );
 }
 
diff --git a/server/trace.c b/server/trace.c
index 69786c9..b05af06 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -10,6 +10,7 @@
 #include <sys/uio.h>
 #include "winsock2.h"
 #include "request.h"
+#include "unicode.h"
 
 
 /* utility functions */
@@ -39,12 +40,8 @@
 static void dump_unicode_string( const WCHAR *str )
 {
     fprintf( stderr, "L\"" );
-    while (*str)
-    {
-        fprintf( stderr, "%c", isprint( (char)*str ) ? (char )*str : '?' );
-        str++;
-    }
-    fprintf( stderr, "\"" );
+    dump_strW( str, strlenW(str), stderr, "\"\"" );
+    fputc( '\"', stderr );
 }
 
 
@@ -341,7 +338,8 @@
     fprintf( stderr, " manual_reset=%d,", req->manual_reset );
     fprintf( stderr, " initial_state=%d,", req->initial_state );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=\"%s\"", req->name );
+    fprintf( stderr, " name=" );
+    dump_unicode_string( req->name );
 }
 
 static void dump_create_event_reply( struct create_event_request *req )
@@ -359,7 +357,8 @@
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=\"%s\"", req->name );
+    fprintf( stderr, " name=" );
+    dump_unicode_string( req->name );
 }
 
 static void dump_open_event_reply( struct open_event_request *req )
@@ -371,7 +370,8 @@
 {
     fprintf( stderr, " owned=%d,", req->owned );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=\"%s\"", req->name );
+    fprintf( stderr, " name=" );
+    dump_unicode_string( req->name );
 }
 
 static void dump_create_mutex_reply( struct create_mutex_request *req )
@@ -388,7 +388,8 @@
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=\"%s\"", req->name );
+    fprintf( stderr, " name=" );
+    dump_unicode_string( req->name );
 }
 
 static void dump_open_mutex_reply( struct open_mutex_request *req )
@@ -401,7 +402,8 @@
     fprintf( stderr, " initial=%08x,", req->initial );
     fprintf( stderr, " max=%08x,", req->max );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=\"%s\"", req->name );
+    fprintf( stderr, " name=" );
+    dump_unicode_string( req->name );
 }
 
 static void dump_create_semaphore_reply( struct create_semaphore_request *req )
@@ -424,7 +426,8 @@
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=\"%s\"", req->name );
+    fprintf( stderr, " name=" );
+    dump_unicode_string( req->name );
 }
 
 static void dump_open_semaphore_reply( struct open_semaphore_request *req )
@@ -718,7 +721,8 @@
     fprintf( stderr, " protect=%d,", req->protect );
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " file_handle=%d,", req->file_handle );
-    fprintf( stderr, " name=\"%s\"", req->name );
+    fprintf( stderr, " name=" );
+    dump_unicode_string( req->name );
 }
 
 static void dump_create_mapping_reply( struct create_mapping_request *req )
@@ -730,7 +734,8 @@
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=\"%s\"", req->name );
+    fprintf( stderr, " name=" );
+    dump_unicode_string( req->name );
 }
 
 static void dump_open_mapping_reply( struct open_mapping_request *req )
diff --git a/server/unicode.c b/server/unicode.c
new file mode 100644
index 0000000..3ba4e03
--- /dev/null
+++ b/server/unicode.c
@@ -0,0 +1,52 @@
+/*
+ * Unicode routines for use inside the server
+ *
+ * Copyright (C) 1999 Alexandre Julliard
+ */
+
+#include <stdio.h>
+
+#include "unicode.h"
+
+/* dump a Unicode string with proper escaping */
+int dump_strW( const WCHAR *str, size_t len, FILE *f, char escape[2] )
+{
+    static const char escapes[32] = ".......abtnvfr.............e....";
+    char buffer[256];
+    char *pos = buffer;
+    int count = 0;
+
+    for (; len; str++, len--)
+    {
+        if (pos > buffer + sizeof(buffer) - 8)
+        {
+            fwrite( buffer, pos - buffer, 1, f );
+            count += pos - buffer;
+            pos = buffer;
+        }
+        if (*str > 127)  /* hex escape */
+        {
+            if (len > 1 && str[1] < 128 && isxdigit((char)str[1]))
+                pos += sprintf( pos, "\\x%04x", *str );
+            else
+                pos += sprintf( pos, "\\x%x", *str );
+            continue;
+        }
+        if (*str < 32)  /* octal or C escape */
+        {
+            if (!*str && len == 1) continue;  /* do not output terminating NULL */
+            if (escapes[*str] != '.')
+                pos += sprintf( pos, "\\%c", escapes[*str] );
+            else if (len > 1 && str[1] >= '0' && str[1] <= '7')
+                pos += sprintf( pos, "\\%03o", *str );
+            else
+                pos += sprintf( pos, "\\%o", *str );
+            continue;
+        }
+        if (*str == '\\' || *str == escape[0] || *str == escape[1]) *pos++ = '\\';
+        *pos++ = *str;
+    }
+    fwrite( buffer, pos - buffer, 1, f );
+    count += pos - buffer;
+    return count;
+}
diff --git a/server/unicode.h b/server/unicode.h
index 614f2ca..c1df7f5 100644
--- a/server/unicode.h
+++ b/server/unicode.h
@@ -19,6 +19,7 @@
 #endif
 
 #include "windef.h"
+#include "object.h"
 
 static inline size_t strlenW( const WCHAR *str )
 {
@@ -52,4 +53,6 @@
     return memdup( str, len );
 }
 
+extern int dump_strW( const WCHAR *str, size_t len, FILE *f, char escape[2] );
+
 #endif  /* __WINE_SERVER_UNICODE_H */