access mask. (CreateMutexW): Create mutex object with MUTEX_ALL_ACCESS access mask. (CreateSemaphoreW): Create semaphore object with SEMAPHORE_ALL_ACCESS access mask.
		
			
				
	
	
		
			440 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			440 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* kernel32.cc: Win32 replacement functions.
 | 
						|
 | 
						|
   Copyright 2008, 2010 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"
 | 
						|
#include <wchar.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, EVENT_ALL_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, MUTEX_ALL_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, SEMAPHORE_ALL_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 & (SEC_RESERVE | SEC_COMMIT)))
 | 
						|
    attribs |= SEC_COMMIT;
 | 
						|
  if (hFile == INVALID_HANDLE_VALUE)
 | 
						|
    hFile = NULL;
 | 
						|
  status = NtCreateSection (§, access, &attr, psize, prot, attribs, hFile);
 | 
						|
  if (!NT_SUCCESS (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);
 | 
						|
}
 | 
						|
 | 
						|
/* When Terminal Services are installed, the GetWindowsDirectory function
 | 
						|
   does not return the system installation dir, but a user specific directory
 | 
						|
   instead.  That's not what we have in mind when calling GetWindowsDirectory
 | 
						|
   from within Cygwin.  So we're calling GetSystemWindowsDirectory from here,
 | 
						|
   except on NT4 where we use the method as described in KB186498. */
 | 
						|
 | 
						|
#define SYSTEM32	(sizeof ("\\System32") - 1)
 | 
						|
 | 
						|
UINT WINAPI
 | 
						|
GetWindowsDirectoryW (LPWSTR buf, UINT size)
 | 
						|
{
 | 
						|
  if (wincap.has_terminal_services ())
 | 
						|
    return GetSystemWindowsDirectoryW (buf, size);
 | 
						|
  /* NT4 */
 | 
						|
  WCHAR name [size + SYSTEM32];
 | 
						|
  UINT ret = GetSystemDirectoryW (name, size + SYSTEM32);
 | 
						|
  if (ret < size + SYSTEM32)
 | 
						|
    {
 | 
						|
      name[ret - SYSTEM32] = L'\0';
 | 
						|
      wcscpy (buf, name);
 | 
						|
    }
 | 
						|
  return ret - SYSTEM32;
 | 
						|
}
 | 
						|
 | 
						|
UINT WINAPI
 | 
						|
GetWindowsDirectoryA (LPSTR buf, UINT size)
 | 
						|
{
 | 
						|
  WCHAR name[MAX_PATH];
 | 
						|
  UINT ret = GetWindowsDirectoryW (name, min (size, MAX_PATH));
 | 
						|
  if (ret < size)
 | 
						|
    sys_wcstombs (buf, size, name);
 | 
						|
  return ret;
 | 
						|
}
 |