From abbde487046d0f1a775a85057d51ec4ee074e33d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Apr 2008 12:46:58 +0000 Subject: [PATCH] * Makefile.in (DLL_OFILES): Add kernel32.o. * autoload.cc (WSACloseEvent): Remove. (WSACreateEvent): Remove. * cygheap.cc (cygheap_init): Drop initializing shared_prefix. * cygheap.h (struct init_cygheap): Drop shared_prefix and shared_prefix_buf members. * fhandler_socket.cc (sock_shared_name): New static function. (search_wsa_event_slot): Convert name buffers to WCHAR. Call NtCreateMutant/NtOpenMutant to create mutexes in session local namespace. (fhandler_socket::init_events): Ditto. Fix debug output. (fhandler_socket::release_events): Close mutexes using NtClose. (fhandler_socket::dup): Ditto. * kernel32.cc: New file, implementing Win32 calls in a Cygwin-specific way. * mmap.cc (MapView): Make static. * ntdll.h: Fix status code sorting. (STATUS_OBJECT_NAME_EXISTS): Define. (SEMAPHORE_QUERY_STATE): Define. (CYG_SHARED_DIR_ACCESS): Define. (CYG_MUTANT_ACCESS): Define. (CYG_EVENT_ACCESS): Define. (CYG_SEMAPHORE_ACCESS): Define. (enum _PROCESSINFOCLASS): Define ProcessSessionInformation. (struct _PROCESS_SESSION_INFORMATION): Define. (NtCreateSemaphore): Declare. (NtOpenSemaphore): Declare. * flock.cc: Use CYG_xxx_ACCESS access masks where appropriate. * posix_ipc.cc (ipc_mutex_init): Use native functions to create mutex. Create in cygwin-shared subdir. (ipc_cond_init): Ditto for event. (ipc_mutex_close): Use NtClose. (ipc_cond_close): Ditto. (mq_open): Drop "cyg" prefix from mqh_uname. * shared.cc (CYG_SHARED_DIR_ACCESS): Drop definition here. (_cygwin_testing): Declare extern on file level. (get_shared_parent_dir): Change name of shared directory. Add name to api_fatal output. (get_session_parent_dir): New function. (shared_name): Simplify. (shared_info::initialize): Call get_session_parent_dir. * shared_info.h (get_session_parent_dir): Declare. * smallprint.cc (__small_vswprintf): Fix bug in multibyte string conversion. * thread.cc (semaphore::semaphore): Align semaphore name to object names in posix IPC functions. * include/cygwin/version.h (CYGWIN_VERSION_SHARED_DATA): Bump. --- winsup/cygwin/ChangeLog | 50 +++ winsup/cygwin/Makefile.in | 21 +- winsup/cygwin/autoload.cc | 2 - winsup/cygwin/cygheap.cc | 6 - winsup/cygwin/cygheap.h | 2 - winsup/cygwin/fhandler_socket.cc | 78 +++-- winsup/cygwin/flock.cc | 10 +- winsup/cygwin/include/cygwin/version.h | 2 +- winsup/cygwin/kernel32.cc | 405 +++++++++++++++++++++++++ winsup/cygwin/mmap.cc | 2 +- winsup/cygwin/ntdll.h | 47 ++- winsup/cygwin/posix_ipc.cc | 21 +- winsup/cygwin/shared.cc | 65 ++-- winsup/cygwin/shared_info.h | 1 + winsup/cygwin/smallprint.cc | 2 +- winsup/cygwin/thread.cc | 2 +- 16 files changed, 623 insertions(+), 93 deletions(-) create mode 100644 winsup/cygwin/kernel32.cc diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1d4c7fea3..d36d11f41 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,53 @@ +2008-04-20 Corinna Vinschen + + * Makefile.in (DLL_OFILES): Add kernel32.o. + * autoload.cc (WSACloseEvent): Remove. + (WSACreateEvent): Remove. + * cygheap.cc (cygheap_init): Drop initializing shared_prefix. + * cygheap.h (struct init_cygheap): Drop shared_prefix and + shared_prefix_buf members. + * fhandler_socket.cc (sock_shared_name): New static function. + (search_wsa_event_slot): Convert name buffers to WCHAR. Call + NtCreateMutant/NtOpenMutant to create mutexes in session local + namespace. + (fhandler_socket::init_events): Ditto. Fix debug output. + (fhandler_socket::release_events): Close mutexes using NtClose. + (fhandler_socket::dup): Ditto. + * kernel32.cc: New file, implementing Win32 calls in a Cygwin-specific + way. + * mmap.cc (MapView): Make static. + * ntdll.h: Fix status code sorting. + (STATUS_OBJECT_NAME_EXISTS): Define. + (SEMAPHORE_QUERY_STATE): Define. + (CYG_SHARED_DIR_ACCESS): Define. + (CYG_MUTANT_ACCESS): Define. + (CYG_EVENT_ACCESS): Define. + (CYG_SEMAPHORE_ACCESS): Define. + (enum _PROCESSINFOCLASS): Define ProcessSessionInformation. + (struct _PROCESS_SESSION_INFORMATION): Define. + (NtCreateSemaphore): Declare. + (NtOpenSemaphore): Declare. + * flock.cc: Use CYG_xxx_ACCESS access masks where appropriate. + * posix_ipc.cc (ipc_mutex_init): Use native functions to create mutex. + Create in cygwin-shared subdir. + (ipc_cond_init): Ditto for event. + (ipc_mutex_close): Use NtClose. + (ipc_cond_close): Ditto. + (mq_open): Drop "cyg" prefix from mqh_uname. + * shared.cc (CYG_SHARED_DIR_ACCESS): Drop definition here. + (_cygwin_testing): Declare extern on file level. + (get_shared_parent_dir): Change name of shared directory. Add name + to api_fatal output. + (get_session_parent_dir): New function. + (shared_name): Simplify. + (shared_info::initialize): Call get_session_parent_dir. + * shared_info.h (get_session_parent_dir): Declare. + * smallprint.cc (__small_vswprintf): Fix bug in multibyte string + conversion. + * thread.cc (semaphore::semaphore): Align semaphore name to object + names in posix IPC functions. + * include/cygwin/version.h (CYGWIN_VERSION_SHARED_DATA): Bump. + 2008-04-18 Corinna Vinschen Revert thinko in previous patch. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 77178d858..88b7cfa13 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -136,16 +136,17 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \ fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \ fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \ grp.o heap.o hookapi.o inet_addr.o inet_network.o init.o ioctl.o ipc.o \ - localtime.o lsearch.o malloc_wrapper.o minires-os-if.o minires.o \ - miscfuncs.o mktemp.o mmap.o msg.o mount.o net.o netdb.o nftw.o ntea.o \ - passwd.o path.o pinfo.o pipe.o poll.o posix_ipc.o pthread.o random.o \ - regcomp.o regerror.o regexec.o regfree.o registry.o resource.o rexec.o \ - rcmd.o scandir.o sched.o sec_acl.o sec_auth.o sec_helper.o security.o \ - select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \ - spawn.o strace.o strfuncs.o strptime.o strsep.o strsig.o sync.o \ - syscalls.o sysconf.o syslog.o termios.o thread.o timelocal.o timer.o \ - times.o tls_pbuf.o tty.o uinfo.o uname.o v8_regexp.o v8_regerror.o \ - v8_regsub.o wait.o wincap.o window.o winf.o xsique.o \ + kernel32.o localtime.o lsearch.o malloc_wrapper.o minires-os-if.o \ + minires.o miscfuncs.o mktemp.o mmap.o msg.o mount.o net.o netdb.o \ + nftw.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o posix_ipc.o \ + pthread.o random.o regcomp.o regerror.o regexec.o regfree.o registry.o \ + resource.o rexec.o rcmd.o scandir.o sched.o sec_acl.o sec_auth.o \ + sec_helper.o security.o select.o sem.o shared.o shm.o sigfe.o signal.o \ + sigproc.o smallprint.o spawn.o strace.o strfuncs.o strptime.o strsep.o \ + strsig.o sync.o syscalls.o sysconf.o syslog.o termios.o thread.o \ + timelocal.o timer.o times.o tls_pbuf.o tty.o uinfo.o uname.o \ + v8_regexp.o v8_regerror.o v8_regsub.o wait.o wincap.o window.o winf.o \ + xsique.o \ $(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS) GMON_OFILES:=gmon.o mcount.o profil.o diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 89dcbc974..fdbebb332 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -377,8 +377,6 @@ LoadDLLfunc (setsockopt, 20, ws2_32) LoadDLLfunc (shutdown, 8, ws2_32) LoadDLLfunc (socket, 12, ws2_32) LoadDLLfunc (WSAAsyncSelect, 16, ws2_32) -LoadDLLfunc (WSACloseEvent, 4, ws2_32) -LoadDLLfunc (WSACreateEvent, 0, ws2_32) LoadDLLfunc (WSAEnumNetworkEvents, 12, ws2_32) LoadDLLfunc (WSAEventSelect, 12, ws2_32) LoadDLLfunc (WSAGetLastError, 0, ws2_32) diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 8245eff62..f33ba2ea8 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -161,12 +161,6 @@ cygheap_init () cygheap->fdtab.init (); if (!cygheap->sigs) sigalloc (); - - /* Should this ever change, keep in mind that shared_prefix_buf is exactly - 8 bytes long, just enough to match the size of the "Global\\" string. */ - if (!cygheap->shared_prefix) - strcpy (cygheap->shared_prefix = cygheap->shared_prefix_buf, - wincap.has_terminal_services () ? "Global\\" : ""); } /* Copyright (C) 1997, 2000 DJ Delorie */ diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index bda082b76..0e937ee7c 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -280,8 +280,6 @@ struct init_cygheap HANDLE console_h; cwdstuff cwd; dtable fdtab; - char *shared_prefix; - char shared_prefix_buf[8]; #ifdef DEBUGGING cygheap_debug debug; #endif diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index e718db097..c0df1fb66 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -414,17 +414,31 @@ static LONG socket_serial_number __attribute__((section (".cygwin_dll_common"), static HANDLE wsa_slot_mtx; +static PWCHAR +sock_shared_name (PWCHAR buf, LONG num) +{ + __small_swprintf (buf, L"socket.%d", num); + return buf; +} + static wsa_event * search_wsa_event_slot (LONG new_serial_number) { - char name[MAX_PATH], searchname[MAX_PATH]; + WCHAR name[32], searchname[32]; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; if (!wsa_slot_mtx) { - wsa_slot_mtx = CreateMutex (&sec_all, FALSE, - shared_name (name, "sock", 0)); - if (!wsa_slot_mtx) - api_fatal ("Couldn't create/open shared socket mutex, %E"); + RtlInitUnicodeString (&uname, sock_shared_name (name, 0)); + InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, + get_session_parent_dir (), + everyone_sd (CYG_MUTANT_ACCESS)); + status = NtCreateMutant (&wsa_slot_mtx, CYG_MUTANT_ACCESS, &attr, FALSE); + if (!NT_SUCCESS (status)) + api_fatal ("Couldn't create/open shared socket mutex %S, %p", + &uname, status); } switch (WaitForSingleObject (wsa_slot_mtx, INFINITE)) { @@ -438,12 +452,16 @@ search_wsa_event_slot (LONG new_serial_number) unsigned int slot = new_serial_number % NUM_SOCKS; while (wsa_events[slot].serial_number) { - HANDLE searchmtx = OpenMutex (STANDARD_RIGHTS_READ, FALSE, - shared_name (searchname, "sock", wsa_events[slot].serial_number)); - if (!searchmtx) + HANDLE searchmtx; + RtlInitUnicodeString (&uname, sock_shared_name (searchname, + wsa_events[slot].serial_number)); + InitializeObjectAttributes (&attr, &uname, 0, get_session_parent_dir (), + NULL); + status = NtOpenMutant (&searchmtx, READ_CONTROL, &attr); + if (!NT_SUCCESS (status)) break; /* Mutex still exists, attached socket is active, try next slot. */ - CloseHandle (searchmtx); + NtClose (searchmtx); slot = (slot + 1) % NUM_SOCKS; if (slot == (new_serial_number % NUM_SOCKS)) { @@ -463,8 +481,10 @@ bool fhandler_socket::init_events () { LONG new_serial_number; - char name[MAX_PATH]; - DWORD err = 0; + WCHAR name[32]; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; do { @@ -472,33 +492,35 @@ fhandler_socket::init_events () InterlockedIncrement (&socket_serial_number); if (!new_serial_number) /* 0 is reserved for global mutex */ InterlockedIncrement (&socket_serial_number); - wsock_mtx = CreateMutex (&sec_all, FALSE, - shared_name (name, "sock", new_serial_number)); - if (!wsock_mtx) + RtlInitUnicodeString (&uname, sock_shared_name (name, new_serial_number)); + InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, + get_session_parent_dir (), + everyone_sd (CYG_MUTANT_ACCESS)); + status = NtCreateMutant (&wsock_mtx, CYG_MUTANT_ACCESS, &attr, FALSE); + if (!NT_SUCCESS (status)) { - debug_printf ("CreateMutex, %E"); + debug_printf ("NtCreateMutant(%S), %p", &uname, status); set_errno (ENOBUFS); return false; } - err = GetLastError (); - if (err == ERROR_ALREADY_EXISTS) - CloseHandle (wsock_mtx); + if (status == STATUS_OBJECT_NAME_EXISTS) + NtClose (wsock_mtx); } - while (err == ERROR_ALREADY_EXISTS); + while (status == STATUS_OBJECT_NAME_EXISTS); if ((wsock_evt = CreateEvent (&sec_all, TRUE, FALSE, NULL)) == WSA_INVALID_EVENT) { - debug_printf ("WSACreateEvent, %E"); + debug_printf ("CreateEvent, %E"); set_errno (ENOBUFS); - CloseHandle (wsock_mtx); + NtClose (wsock_mtx); return false; } if (WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK) == SOCKET_ERROR) { debug_printf ("WSAEventSelect, %E"); set_winsock_errno (); - CloseHandle (wsock_evt); - CloseHandle (wsock_mtx); + NtClose (wsock_evt); + NtClose (wsock_mtx); return false; } wsock_events = search_wsa_event_slot (new_serial_number); @@ -601,8 +623,8 @@ fhandler_socket::wait_for_events (const long event_mask) void fhandler_socket::release_events () { - CloseHandle (wsock_evt); - CloseHandle (wsock_mtx); + NtClose (wsock_evt); + NtClose (wsock_mtx); } void @@ -629,7 +651,7 @@ fhandler_socket::dup (fhandler_base *child) TRUE, DUPLICATE_SAME_ACCESS)) { __seterrno (); - CloseHandle (fhs->wsock_mtx); + NtClose (fhs->wsock_mtx); return -1; } fhs->wsock_events = wsock_events; @@ -653,8 +675,8 @@ fhandler_socket::dup (fhandler_base *child) int ret = fhandler_base::dup (child); if (ret) { - CloseHandle (fhs->wsock_evt); - CloseHandle (fhs->wsock_mtx); + NtClose (fhs->wsock_evt); + NtClose (fhs->wsock_mtx); } return ret; } diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc index d0993a41d..b2ca288d9 100644 --- a/winsup/cygwin/flock.cc +++ b/winsup/cygwin/flock.cc @@ -139,10 +139,6 @@ static NO_COPY muto lockf_guard; | DIRECTORY_CREATE_OBJECT \ | READ_CONTROL) -#define FLOCK_MUTANT_ACCESS (MUTANT_QUERY_STATE \ - | SYNCHRONIZE \ - | READ_CONTROL) - #define FLOCK_EVENT_ACCESS (EVENT_QUERY_STATE \ | SYNCHRONIZE \ | READ_CONTROL) @@ -462,8 +458,8 @@ inode_t::inode_t (__dev32_t dev, __ino64_t ino) access synchronization on the dir and its objects. */ RtlInitUnicodeString (&uname, L"mtx"); InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, i_dir, - everyone_sd (FLOCK_MUTANT_ACCESS)); - status = NtCreateMutant (&i_mtx, FLOCK_MUTANT_ACCESS, &attr, FALSE); + everyone_sd (CYG_MUTANT_ACCESS)); + status = NtCreateMutant (&i_mtx, CYG_MUTANT_ACCESS, &attr, FALSE); if (!NT_SUCCESS (status)) api_fatal ("NtCreateMutant(inode): %p", status); } @@ -554,7 +550,7 @@ lockf_t::create_lock_obj () LOCK_OBJ_NAME_LEN * sizeof (WCHAR)); InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, lf_inode->i_dir, everyone_sd (FLOCK_EVENT_ACCESS)); - status = NtCreateEvent (&lf_obj, EVENT_ALL_ACCESS, &attr, + status = NtCreateEvent (&lf_obj, CYG_EVENT_ACCESS, &attr, NotificationEvent, FALSE); if (!NT_SUCCESS (status)) api_fatal ("NtCreateEvent(lock): %p", status); diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index a4081d6ab..f9ece9e62 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -342,7 +342,7 @@ details. */ Bump to 4 since this hasn't been rigorously updated in a while. */ -#define CYGWIN_VERSION_SHARED_DATA 4 +#define CYGWIN_VERSION_SHARED_DATA 5 /* An identifier used in the names used to create shared objects. The full names include the CYGWIN_VERSION_SHARED_DATA version diff --git a/winsup/cygwin/kernel32.cc b/winsup/cygwin/kernel32.cc new file mode 100644 index 000000000..f8953327d --- /dev/null +++ b/winsup/cygwin/kernel32.cc @@ -0,0 +1,405 @@ +/* kernel32.cc: Win32 replacement functions. + + Copyright 2008 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include "shared_info.h" +#include "ntdll.h" + +/* Implement CreateEvent/OpenEvent so that named objects are always created in + Cygwin shared object namespace. */ + +HANDLE WINAPI +CreateEventW (LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, + BOOL bInitialState, LPCWSTR lpName) +{ + HANDLE evt; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + ULONG flags = 0; + + if (lpEventAttributes && lpEventAttributes->bInheritHandle) + flags |= OBJ_INHERIT; + if (lpName) + { + RtlInitUnicodeString (&uname, lpName); + flags |= OBJ_OPENIF | OBJ_CASE_INSENSITIVE; + } + InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags, + lpName ? get_shared_parent_dir () : NULL, + lpEventAttributes + ? lpEventAttributes->lpSecurityDescriptor : NULL); + status = NtCreateEvent (&evt, CYG_EVENT_ACCESS, &attr, + bManualReset ? NotificationEvent + : SynchronizationEvent, + bInitialState); + if (!NT_SUCCESS (status)) + { + SetLastError (RtlNtStatusToDosError (status)); + return NULL; + } + SetLastError (status == STATUS_OBJECT_NAME_EXISTS + ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS); + return evt; +} + +HANDLE WINAPI +CreateEventA (LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, + BOOL bInitialState, LPCSTR lpName) +{ + WCHAR name[MAX_PATH]; + + if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName)) + { + SetLastError (ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + return CreateEventW (lpEventAttributes, bManualReset, bInitialState, + lpName ? name : NULL); +} + +HANDLE WINAPI +OpenEventW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName) +{ + HANDLE evt; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + ULONG flags = 0; + + if (bInheritHandle) + flags |= OBJ_INHERIT; + if (lpName) + { + RtlInitUnicodeString (&uname, lpName); + flags |= OBJ_CASE_INSENSITIVE; + } + InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags, + lpName ? get_shared_parent_dir () : NULL, + NULL); + status = NtOpenEvent (&evt, dwDesiredAccess, &attr); + if (!NT_SUCCESS (status)) + { + SetLastError (RtlNtStatusToDosError (status)); + return NULL; + } + return evt; +} + +HANDLE WINAPI +OpenEventA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName) +{ + WCHAR name[MAX_PATH]; + + if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName)) + { + SetLastError (ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + return OpenEventW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL); +} + +/* Implement CreateMutex/OpenMutex so that named objects are always created in + Cygwin shared object namespace. */ + +HANDLE WINAPI +CreateMutexW (LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, + LPCWSTR lpName) +{ + HANDLE mtx; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + ULONG flags = 0; + + if (lpMutexAttributes && lpMutexAttributes->bInheritHandle) + flags |= OBJ_INHERIT; + if (lpName) + { + RtlInitUnicodeString (&uname, lpName); + flags |= OBJ_OPENIF | OBJ_CASE_INSENSITIVE; + } + InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags, + lpName ? get_shared_parent_dir () : NULL, + lpMutexAttributes + ? lpMutexAttributes->lpSecurityDescriptor : NULL); + status = NtCreateMutant (&mtx, CYG_EVENT_ACCESS, &attr, bInitialOwner); + if (!NT_SUCCESS (status)) + { + SetLastError (RtlNtStatusToDosError (status)); + return NULL; + } + SetLastError (status == STATUS_OBJECT_NAME_EXISTS + ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS); + return mtx; +} + +HANDLE WINAPI +CreateMutexA (LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, + LPCSTR lpName) +{ + WCHAR name[MAX_PATH]; + + if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName)) + { + SetLastError (ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + return CreateMutexW (lpMutexAttributes, bInitialOwner, lpName ? name : NULL); +} + +HANDLE WINAPI +OpenMutexW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName) +{ + HANDLE mtx; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + ULONG flags = 0; + + if (bInheritHandle) + flags |= OBJ_INHERIT; + if (lpName) + { + RtlInitUnicodeString (&uname, lpName); + flags |= OBJ_CASE_INSENSITIVE; + } + InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags, + lpName ? get_shared_parent_dir () : NULL, + NULL); + status = NtOpenMutant (&mtx, dwDesiredAccess, &attr); + if (!NT_SUCCESS (status)) + { + SetLastError (RtlNtStatusToDosError (status)); + return NULL; + } + return mtx; +} + +HANDLE WINAPI +OpenMutexA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName) +{ + WCHAR name[MAX_PATH]; + + if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName)) + { + SetLastError (ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + return OpenMutexW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL); +} + +/* Implement CreateSemaphore/OpenSemaphore so that named objects are always + created in Cygwin shared object namespace. */ + +HANDLE WINAPI +CreateSemaphoreW (LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, + LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName) +{ + HANDLE sem; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + ULONG flags = 0; + + if (lpSemaphoreAttributes && lpSemaphoreAttributes->bInheritHandle) + flags |= OBJ_INHERIT; + if (lpName) + { + RtlInitUnicodeString (&uname, lpName); + flags |= OBJ_OPENIF | OBJ_CASE_INSENSITIVE; + } + InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags, + lpName ? get_shared_parent_dir () : NULL, + lpSemaphoreAttributes + ? lpSemaphoreAttributes->lpSecurityDescriptor + : NULL); + status = NtCreateSemaphore (&sem, CYG_EVENT_ACCESS, &attr, + lInitialCount, lMaximumCount); + if (!NT_SUCCESS (status)) + { + SetLastError (RtlNtStatusToDosError (status)); + return NULL; + } + SetLastError (status == STATUS_OBJECT_NAME_EXISTS + ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS); + return sem; +} + +HANDLE WINAPI +CreateSemaphoreA (LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, + LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName) +{ + WCHAR name[MAX_PATH]; + + if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName)) + { + SetLastError (ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + return CreateSemaphoreW (lpSemaphoreAttributes, lInitialCount, lMaximumCount, + lpName ? name : NULL); +} + +HANDLE WINAPI +OpenSemaphoreW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName) +{ + HANDLE sem; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + ULONG flags = 0; + + if (bInheritHandle) + flags |= OBJ_INHERIT; + if (lpName) + { + RtlInitUnicodeString (&uname, lpName); + flags |= OBJ_CASE_INSENSITIVE; + } + InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags, + lpName ? get_shared_parent_dir () : NULL, + NULL); + status = NtOpenSemaphore (&sem, dwDesiredAccess, &attr); + if (!NT_SUCCESS (status)) + { + SetLastError (RtlNtStatusToDosError (status)); + return NULL; + } + return sem; +} + +HANDLE WINAPI +OpenSemaphoreA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName) +{ + WCHAR name[MAX_PATH]; + + if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName)) + { + SetLastError (ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + return OpenSemaphoreW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL); +} + +/* Implement CreateFileMapping/OpenFileMapping so that named objects are always + created in Cygwin shared object namespace. */ + +HANDLE WINAPI +CreateFileMappingW (HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes, + DWORD flProtect, DWORD dwMaximumSizeHigh, + DWORD dwMaximumSizeLow, LPCWSTR lpName) +{ + HANDLE sect; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + ULONG flags = 0; + ACCESS_MASK access = READ_CONTROL | SECTION_QUERY | SECTION_MAP_READ; + ULONG prot = flProtect & (PAGE_NOACCESS | PAGE_READONLY | PAGE_READWRITE + | PAGE_WRITECOPY | PAGE_EXECUTE + | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE + | PAGE_EXECUTE_WRITECOPY); + ULONG attribs = flProtect & (SEC_BASED | SEC_NO_CHANGE | SEC_IMAGE | SEC_VLM + | SEC_RESERVE | SEC_COMMIT | SEC_NOCACHE); + LARGE_INTEGER size = {{ LowPart : dwMaximumSizeLow, + HighPart : dwMaximumSizeHigh }}; + PLARGE_INTEGER psize = size.QuadPart ? &size : NULL; + + if (prot & (PAGE_READWRITE | PAGE_WRITECOPY + | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) + access |= SECTION_MAP_WRITE; + if (prot & (PAGE_EXECUTE | PAGE_EXECUTE_READ + | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) + access |= SECTION_MAP_EXECUTE; + if (lpAttributes && lpAttributes->bInheritHandle) + flags |= OBJ_INHERIT; + if (lpName) + { + RtlInitUnicodeString (&uname, lpName); + flags |= OBJ_OPENIF | OBJ_CASE_INSENSITIVE; + } + InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags, + lpName ? get_shared_parent_dir () : NULL, + lpAttributes + ? lpAttributes->lpSecurityDescriptor + : NULL); + if (!attribs) + attribs = SEC_COMMIT; + if (hFile == INVALID_HANDLE_VALUE) + hFile = NULL; + status = NtCreateSection (§, access, &attr, psize, prot, attribs, hFile); + if (!NT_SUCCESS (status)) + { + small_printf ("status %p\n", status); + SetLastError (RtlNtStatusToDosError (status)); + return NULL; + } + SetLastError (status == STATUS_OBJECT_NAME_EXISTS + ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS); + return sect; +} + +HANDLE WINAPI +CreateFileMappingA (HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes, + DWORD flProtect, DWORD dwMaximumSizeHigh, + DWORD dwMaximumSizeLow, LPCSTR lpName) +{ + WCHAR name[MAX_PATH]; + + if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName)) + { + SetLastError (ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + return CreateFileMappingW (hFile, lpAttributes, flProtect, dwMaximumSizeHigh, + dwMaximumSizeLow, lpName ? name : NULL); +} + +HANDLE WINAPI +OpenFileMappingW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName) +{ + HANDLE sect; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + ULONG flags = 0; + + if (bInheritHandle) + flags |= OBJ_INHERIT; + if (lpName) + { + RtlInitUnicodeString (&uname, lpName); + flags |= OBJ_CASE_INSENSITIVE; + } + InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags, + lpName ? get_shared_parent_dir () : NULL, + NULL); + status = NtOpenSection (§, dwDesiredAccess, &attr); + if (!NT_SUCCESS (status)) + { + SetLastError (RtlNtStatusToDosError (status)); + return NULL; + } + return sect; +} + +HANDLE WINAPI +OpenFileMappingA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName) +{ + WCHAR name[MAX_PATH]; + + if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName)) + { + SetLastError (ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + return OpenFileMappingW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL); +} diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 48c3455fd..e09c11c8d 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -189,7 +189,7 @@ CreateMapping (HANDLE fhdl, size_t len, _off64_t off, DWORD openflags, return h; } -void * +static void * MapView (HANDLE h, void *addr, size_t len, DWORD openflags, int prot, int flags, _off64_t off) { diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index 529a3be89..2d7d6f640 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -8,6 +8,9 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ +#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000) +#define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005) +#define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006) #ifndef STATUS_INVALID_INFO_CLASS /* Some w32api header file defines this so we need to conditionalize this define to avoid warnings. */ @@ -35,13 +38,10 @@ #define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xc0000101) #define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106) #define STATUS_INVALID_LEVEL ((NTSTATUS) 0xc0000148) -#define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005) -#define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006) -#define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xC0000135) -#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000139) -#define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xC0000251) -#define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xC0000269) - +#define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xc0000135) +#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xc0000139) +#define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xc0000251) +#define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xc0000269) #define PDI_MODULES 0x01 #define PDI_HEAPS 0x04 @@ -195,6 +195,28 @@ typedef struct _FILE_ID_BOTH_DIR_INFORMATION #define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f) #define EVENT_QUERY_STATE 1 +#define SEMAPHORE_QUERY_STATE 1 + +/* Specific ACCESS_MASKSs for objects created in Cygwin. */ +#define CYG_SHARED_DIR_ACCESS (DIRECTORY_QUERY \ + | DIRECTORY_TRAVERSE \ + | DIRECTORY_CREATE_SUBDIRECTORY \ + | DIRECTORY_CREATE_OBJECT \ + | READ_CONTROL) + +#define CYG_MUTANT_ACCESS (MUTANT_QUERY_STATE \ + | SYNCHRONIZE \ + | READ_CONTROL) + +#define CYG_EVENT_ACCESS (EVENT_QUERY_STATE \ + | EVENT_MODIFY_STATE \ + | SYNCHRONIZE \ + | READ_CONTROL) + +#define CYG_SEMAPHORE_ACCESS (SEMAPHORE_QUERY_STATE \ + | SEMAPHORE_MODIFY_STATE \ + | SYNCHRONIZE \ + | READ_CONTROL) typedef ULONG KAFFINITY; @@ -440,7 +462,8 @@ typedef enum _PROCESSINFOCLASS ProcessBasicInformation = 0, ProcessQuotaLimits = 1, ProcessVmCounters = 3, - ProcessTimes =4, + ProcessTimes = 4, + ProcessSessionInformation = 24, } PROCESSINFOCLASS; typedef struct _DEBUG_BUFFER @@ -560,6 +583,11 @@ typedef struct _PROCESS_BASIC_INFORMATION ULONG InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; +typedef struct _PROCESS_SESSION_INFORMATION +{ + ULONG SessionId; +} PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION; + typedef enum _MEMORY_INFORMATION_CLASS { MemoryBasicInformation, @@ -840,6 +868,8 @@ extern "C" BOOLEAN); NTSTATUS NTAPI NtCreateSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PLARGE_INTEGER, ULONG, ULONG, HANDLE); + NTSTATUS NTAPI NtCreateSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, + LONG, LONG); NTSTATUS NTAPI NtCreateToken (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, TOKEN_TYPE, PLUID, PLARGE_INTEGER, PTOKEN_USER, PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER, @@ -863,6 +893,7 @@ extern "C" PIO_STATUS_BLOCK, ULONG, ULONG); NTSTATUS NTAPI NtOpenMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); + NTSTATUS NTAPI NtOpenSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); /* WARNING! Don't rely on the timestamp information returned by NtQueryAttributesFile. Only the DOS file attribute info is reliable. */ NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES, diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc index f9090ae14..102691ecb 100644 --- a/winsup/cygwin/posix_ipc.cc +++ b/winsup/cygwin/posix_ipc.cc @@ -16,6 +16,7 @@ details. */ #include "dtable.h" #include "cygheap.h" #include "sigproc.h" +#include "ntdll.h" #include #include #include @@ -87,10 +88,13 @@ static int ipc_mutex_init (HANDLE *pmtx, const char *name) { char buf[MAX_PATH]; - __small_sprintf (buf, "%scyg_pmtx/%s", cygheap->shared_prefix, name); - *pmtx = CreateMutex (&sec_all, FALSE, buf); + SECURITY_ATTRIBUTES sa = sec_none; + + __small_sprintf (buf, "mqueue/mtx_%W", name); + sa.lpSecurityDescriptor = everyone_sd (CYG_MUTANT_ACCESS); + *pmtx = CreateMutex (&sa, FALSE, buf); if (!*pmtx) - debug_printf ("failed: %E\n"); + debug_printf ("CreateMutex: %E"); return *pmtx ? 0 : geterrno_from_win_error (); } @@ -129,10 +133,13 @@ static int ipc_cond_init (HANDLE *pevt, const char *name) { char buf[MAX_PATH]; - __small_sprintf (buf, "%scyg_pevt/%s", cygheap->shared_prefix, name); - *pevt = CreateEvent (&sec_all, TRUE, FALSE, buf); + SECURITY_ATTRIBUTES sa = sec_none; + + __small_sprintf (buf, "mqueue/evt_%W", name); + sa.lpSecurityDescriptor = everyone_sd (CYG_EVENT_ACCESS); + *pevt = CreateEvent (&sa, TRUE, FALSE, buf); if (!*pevt) - debug_printf ("failed: %E\n"); + debug_printf ("CreateEvent: %E"); return *pevt ? 0 : geterrno_from_win_error (); } @@ -387,7 +394,7 @@ again: __seterrno (); goto err; } - __small_sprintf (mqhdr->mqh_uname, "cyg%016X%08x%08x", + __small_sprintf (mqhdr->mqh_uname, "%016X%08x%08x", hash_path_name (0,mqname), luid.HighPart, luid.LowPart); mqhdr->mqh_head = 0; diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index 6f47d2e85..760c33288 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -32,13 +32,7 @@ HANDLE NO_COPY cygwin_user_h; /* This function returns a handle to the top-level directory in the global NT namespace used to implement global objects including shared memory. */ - -#define CYG_SHARED_DIR_ACCESS (DIRECTORY_QUERY \ - | DIRECTORY_TRAVERSE \ - | DIRECTORY_CREATE_SUBDIRECTORY \ - | DIRECTORY_CREATE_OBJECT \ - | READ_CONTROL) - +extern bool _cygwin_testing; HANDLE get_shared_parent_dir () @@ -47,15 +41,53 @@ get_shared_parent_dir () UNICODE_STRING uname; OBJECT_ATTRIBUTES attr; NTSTATUS status; - + if (!dir) { - RtlInitUnicodeString (&uname, L"\\BaseNamedObjects\\cygwin-shared"); + WCHAR bnoname[MAX_PATH]; + __small_swprintf (bnoname, L"\\BaseNamedObjects\\%s%s", + cygwin_version.shared_id, + _cygwin_testing ? cygwin_version.dll_build_date : ""); + RtlInitUnicodeString (&uname, bnoname); InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, NULL, everyone_sd (CYG_SHARED_DIR_ACCESS)); status = NtCreateDirectoryObject (&dir, CYG_SHARED_DIR_ACCESS, &attr); if (!NT_SUCCESS (status)) - api_fatal ("NtCreateDirectoryObject(parent): %p", status); + api_fatal ("NtCreateDirectoryObject(%S): %p", &uname, status); + } + return dir; +} + +HANDLE +get_session_parent_dir () +{ + static HANDLE dir; + UNICODE_STRING uname; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + + if (!dir) + { + PROCESS_SESSION_INFORMATION psi; + status = NtQueryInformationProcess (GetCurrentProcess (), + ProcessSessionInformation, + &psi, sizeof psi, NULL); + if (!NT_SUCCESS (status) || psi.SessionId == 0) + dir = get_shared_parent_dir (); + else + { + WCHAR bnoname[MAX_PATH]; + __small_swprintf (bnoname, + L"\\Sessions\\BNOLINKS\\%d\\%s%s", + psi.SessionId, cygwin_version.shared_id, + _cygwin_testing ? cygwin_version.dll_build_date : ""); + RtlInitUnicodeString (&uname, bnoname); + InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, + NULL, everyone_sd(CYG_SHARED_DIR_ACCESS)); + status = NtCreateDirectoryObject (&dir, CYG_SHARED_DIR_ACCESS, &attr); + if (!NT_SUCCESS (status)) + api_fatal ("NtCreateDirectoryObject(%S): %p", &uname, status); + } } return dir; } @@ -63,14 +95,7 @@ get_shared_parent_dir () char * __stdcall shared_name (char *ret_buf, const char *str, int num) { - extern bool _cygwin_testing; - - get_shared_parent_dir (); - __small_sprintf (ret_buf, "%scygwin-shared\\%s.%s.%d", - cygheap->shared_prefix, - cygwin_version.shared_id, str, num); - if (_cygwin_testing) - strcat (ret_buf, cygwin_version.dll_build_date); + __small_sprintf (ret_buf, "%s.%d", str, num); return ret_buf; } @@ -239,7 +264,9 @@ shared_info::initialize () cb = sizeof (*this); /* Do last, after all shared memory initialization */ } - mt.initialize (); + mt.initialize (); /* Initialize shared tape information. */ + + get_session_parent_dir (); /* Create session dir if first process. */ if (cb != SHARED_INFO_CB) system_printf ("size of shared memory region changed from %u to %u", diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index ea504d2e3..8af156226 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -179,6 +179,7 @@ struct console_state #endif HANDLE get_shared_parent_dir (); +HANDLE get_session_parent_dir (); char *__stdcall shared_name (char *, const char *, int); void *__stdcall open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations&, PSECURITY_ATTRIBUTES psa = &sec_all, diff --git a/winsup/cygwin/smallprint.cc b/winsup/cygwin/smallprint.cc index 8a904a484..44fc05134 100644 --- a/winsup/cygwin/smallprint.cc +++ b/winsup/cygwin/smallprint.cc @@ -435,7 +435,7 @@ __small_vswprintf (PWCHAR dst, const WCHAR *fmt, va_list ap) s = va_arg (ap, char *); if (s == NULL) s = "(null)"; - sys_mbstowcs (tmp, NT_MAX_PATH, s, n); + sys_mbstowcs (tmp, NT_MAX_PATH, s, n < 0x7fff ? (int) n : -1); RtlInitUnicodeString (us = &uw, tmp); goto fillin; break; diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index d7cc0b790..73007386b 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -2938,7 +2938,7 @@ semaphore::semaphore (unsigned long long shash, LUID sluid, int sfd, { char name[MAX_PATH]; - __small_sprintf (name, "%scyg_psem/cyg%016X%08x%08x", cygheap->shared_prefix, + __small_sprintf (name, "semaphore/%016X%08x%08x", hash, luid.HighPart, luid.LowPart); this->win32_obj_id = ::CreateSemaphore (&sec_all, value, LONG_MAX, name); if (!this->win32_obj_id)