2008-04-21 20:46:58 +08:00
|
|
|
/* kernel32.cc: Win32 replacement functions.
|
|
|
|
|
|
|
|
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"
|
2013-07-20 01:28:34 +08:00
|
|
|
#include "cygerrno.h"
|
|
|
|
#include "security.h"
|
|
|
|
#include "path.h"
|
|
|
|
#include "fhandler.h"
|
|
|
|
#include "dtable.h"
|
|
|
|
#include "cygheap.h"
|
|
|
|
#include "tls_pbuf.h"
|
|
|
|
#include "winf.h"
|
|
|
|
#include "sys/cygwin.h"
|
2008-04-21 20:46:58 +08:00
|
|
|
|
|
|
|
/* Implement CreateEvent/OpenEvent so that named objects are always created in
|
|
|
|
Cygwin shared object namespace. */
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
2010-04-16 01:20:59 +08:00
|
|
|
status = NtCreateEvent (&evt, EVENT_ALL_ACCESS, &attr,
|
2008-04-21 20:46:58 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
OpenEventW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
|
|
|
|
{
|
|
|
|
HANDLE evt;
|
|
|
|
UNICODE_STRING uname;
|
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
NTSTATUS status;
|
|
|
|
ULONG flags = 0;
|
2008-11-27 01:21:04 +08:00
|
|
|
|
2008-04-21 20:46:58 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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. */
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
2010-04-16 01:20:59 +08:00
|
|
|
status = NtCreateMutant (&mtx, MUTEX_ALL_ACCESS, &attr, bInitialOwner);
|
2008-04-21 20:46:58 +08:00
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
SetLastError (RtlNtStatusToDosError (status));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
SetLastError (status == STATUS_OBJECT_NAME_EXISTS
|
|
|
|
? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
|
|
|
|
return mtx;
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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. */
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
2010-04-16 01:20:59 +08:00
|
|
|
status = NtCreateSemaphore (&sem, SEMAPHORE_ALL_ACCESS, &attr,
|
2008-04-21 20:46:58 +08:00
|
|
|
lInitialCount, lMaximumCount);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
SetLastError (RtlNtStatusToDosError (status));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
SetLastError (status == STATUS_OBJECT_NAME_EXISTS
|
|
|
|
? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
|
|
|
|
return sem;
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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. */
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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;
|
2014-08-27 18:44:50 +08:00
|
|
|
ACCESS_MASK access = STANDARD_RIGHTS_REQUIRED
|
|
|
|
| SECTION_QUERY | SECTION_MAP_READ;
|
2008-04-21 20:46:58 +08:00
|
|
|
ULONG prot = flProtect & (PAGE_NOACCESS | PAGE_READONLY | PAGE_READWRITE
|
|
|
|
| PAGE_WRITECOPY | PAGE_EXECUTE
|
|
|
|
| PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE
|
|
|
|
| PAGE_EXECUTE_WRITECOPY);
|
2012-06-29 04:06:23 +08:00
|
|
|
ULONG attribs = flProtect & (SEC_COMMIT | SEC_IMAGE | SEC_NOCACHE
|
|
|
|
| SEC_RESERVE);
|
2008-04-21 20:46:58 +08:00
|
|
|
LARGE_INTEGER size = {{ LowPart : dwMaximumSizeLow,
|
2013-04-23 17:44:36 +08:00
|
|
|
HighPart : (LONG) dwMaximumSizeHigh }};
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
2008-04-21 21:17:36 +08:00
|
|
|
if (!(attribs & (SEC_RESERVE | SEC_COMMIT)))
|
|
|
|
attribs |= SEC_COMMIT;
|
2008-04-21 20:46:58 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-08-05 03:16:32 +08:00
|
|
|
HANDLE
|
2008-04-21 20:46:58 +08:00
|
|
|
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);
|
|
|
|
}
|
2013-07-20 01:28:34 +08:00
|
|
|
|
|
|
|
/* The external functions below wrap Windows functions of the same name
|
|
|
|
and provide a Windows interface to Cygwin functionality. */
|
|
|
|
|
|
|
|
/* Construct a unicode version of the Cygwin command line from __argv) */
|
|
|
|
static UNICODE_STRING *
|
|
|
|
ucmd ()
|
|
|
|
{
|
|
|
|
static UNICODE_STRING wcmd;
|
|
|
|
if (!wcmd.Buffer)
|
|
|
|
{
|
|
|
|
linebuf cmd;
|
|
|
|
path_conv real_path (__argv[0]);
|
|
|
|
av newargv (__argc, __argv);
|
Cygwin: execve: drop argument size limit
Before commit 44f73c5a6206 ("Cygwin: Fix segfalt when too many command
line args are specified.") we had no actual argument size limit, except
for the fact that the child process created another copy of the argv
array on the stack, which could result in a stack overflow and a
subsequent SEGV. Commit 44f73c5a6206 changed that by allocating the
additional argv array via malloc, and it introduced a new SC_ARG_MAX
limit along the lines of the typical Linux limit.
However, this new limit is artificial. Cygwin allocates all argument
and environment data on the cygheap. We only run out of ARG_MAX space
if we're out of memory resources.
Change argument size handling accordingly:
- Drop the args size check from child_info_spawn::worker.
- Return -1 from sysconf (SC_ARG_MAX), i. e., the argument size limit
is undefined.
- Change argv handling in class av, so that a failing cmalloc is not
fatal. This allows the parent process to return E2BIG if it's out
of cygheap resources.
- In the child, add a check around the new malloc call, so that it
doesn't result in a SEGV if the child process gets unexpectedly into
an ENOMEM situation at this point. In this (unlikely) case, proceed
with the original __argv array instead. Add comment to explain why.
Fixes: 44f73c5a6206 ("Cygwin: Fix segfalt when too many command line args are specified.")
Tested-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2023-08-29 17:55:10 +08:00
|
|
|
if (newargv.argc)
|
|
|
|
{
|
|
|
|
cmd.fromargv (newargv, real_path.get_win32 (), true);
|
|
|
|
RtlInitUnicodeString (&wcmd, cmd);
|
|
|
|
}
|
2013-07-20 01:28:34 +08:00
|
|
|
}
|
|
|
|
return &wcmd;
|
|
|
|
}
|
|
|
|
|
2013-07-20 01:44:08 +08:00
|
|
|
/* Cygwin replacement for GetCommandLineW. Returns a concatenated wide string
|
2013-07-20 01:28:34 +08:00
|
|
|
representing the argv list, constructed using roughly the same mechanism as
|
|
|
|
child_info_spawn::worker */
|
2022-08-05 03:16:32 +08:00
|
|
|
extern "C" LPWSTR
|
2013-07-20 01:28:34 +08:00
|
|
|
cygwin_GetCommandLineW (void)
|
|
|
|
{
|
|
|
|
return ucmd ()->Buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cygwin replacement for GetCommandLineA. Returns a concatenated string
|
|
|
|
representing the argv list, constructed using roughly the same mechanism
|
|
|
|
as child_info_spawn::worker */
|
2022-08-05 03:16:32 +08:00
|
|
|
extern "C" LPSTR
|
2013-07-20 01:28:34 +08:00
|
|
|
cygwin_GetCommandLineA (void)
|
|
|
|
{
|
|
|
|
static ANSI_STRING cmd;
|
|
|
|
if (!cmd.Buffer)
|
|
|
|
RtlUnicodeStringToAnsiString (&cmd, ucmd (), TRUE);
|
|
|
|
return cmd.Buffer;
|
|
|
|
}
|