Cygwin: cygwin_GetCommandLineW/A: don't rely on __argv[0] content
[newlib-cygwin.git] / winsup / cygwin / kernel32.cc
blobf07f80d59ddc5dc97c689d6767d839d092ea58a3
1 /* kernel32.cc: Win32 replacement functions.
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
9 #include "winsup.h"
10 #include "shared_info.h"
11 #include "ntdll.h"
12 #include "cygerrno.h"
13 #include "security.h"
14 #include "path.h"
15 #include "fhandler.h"
16 #include "dtable.h"
17 #include "cygheap.h"
18 #include "tls_pbuf.h"
19 #include "winf.h"
20 #include "sys/cygwin.h"
22 /* Implement CreateEvent/OpenEvent so that named objects are always created in
23 Cygwin shared object namespace. */
25 HANDLE
26 CreateEventW (LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
27 BOOL bInitialState, LPCWSTR lpName)
29 HANDLE evt;
30 UNICODE_STRING uname;
31 OBJECT_ATTRIBUTES attr;
32 NTSTATUS status;
33 ULONG flags = 0;
35 if (lpEventAttributes && lpEventAttributes->bInheritHandle)
36 flags |= OBJ_INHERIT;
37 if (lpName)
39 RtlInitUnicodeString (&uname, lpName);
40 flags |= OBJ_OPENIF | OBJ_CASE_INSENSITIVE;
42 InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags,
43 lpName ? get_shared_parent_dir () : NULL,
44 lpEventAttributes
45 ? lpEventAttributes->lpSecurityDescriptor : NULL);
46 status = NtCreateEvent (&evt, EVENT_ALL_ACCESS, &attr,
47 bManualReset ? NotificationEvent
48 : SynchronizationEvent,
49 bInitialState);
50 if (!NT_SUCCESS (status))
52 SetLastError (RtlNtStatusToDosError (status));
53 return NULL;
55 SetLastError (status == STATUS_OBJECT_NAME_EXISTS
56 ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
57 return evt;
60 HANDLE
61 CreateEventA (LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
62 BOOL bInitialState, LPCSTR lpName)
64 WCHAR name[MAX_PATH];
66 if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName))
68 SetLastError (ERROR_FILENAME_EXCED_RANGE);
69 return NULL;
71 return CreateEventW (lpEventAttributes, bManualReset, bInitialState,
72 lpName ? name : NULL);
75 HANDLE
76 OpenEventW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
78 HANDLE evt;
79 UNICODE_STRING uname;
80 OBJECT_ATTRIBUTES attr;
81 NTSTATUS status;
82 ULONG flags = 0;
84 if (bInheritHandle)
85 flags |= OBJ_INHERIT;
86 if (lpName)
88 RtlInitUnicodeString (&uname, lpName);
89 flags |= OBJ_CASE_INSENSITIVE;
91 InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags,
92 lpName ? get_shared_parent_dir () : NULL,
93 NULL);
94 status = NtOpenEvent (&evt, dwDesiredAccess, &attr);
95 if (!NT_SUCCESS (status))
97 SetLastError (RtlNtStatusToDosError (status));
98 return NULL;
100 return evt;
103 HANDLE
104 OpenEventA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
106 WCHAR name[MAX_PATH];
108 if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName))
110 SetLastError (ERROR_FILENAME_EXCED_RANGE);
111 return NULL;
113 return OpenEventW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL);
116 /* Implement CreateMutex/OpenMutex so that named objects are always created in
117 Cygwin shared object namespace. */
119 HANDLE
120 CreateMutexW (LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner,
121 LPCWSTR lpName)
123 HANDLE mtx;
124 UNICODE_STRING uname;
125 OBJECT_ATTRIBUTES attr;
126 NTSTATUS status;
127 ULONG flags = 0;
129 if (lpMutexAttributes && lpMutexAttributes->bInheritHandle)
130 flags |= OBJ_INHERIT;
131 if (lpName)
133 RtlInitUnicodeString (&uname, lpName);
134 flags |= OBJ_OPENIF | OBJ_CASE_INSENSITIVE;
136 InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags,
137 lpName ? get_shared_parent_dir () : NULL,
138 lpMutexAttributes
139 ? lpMutexAttributes->lpSecurityDescriptor : NULL);
140 status = NtCreateMutant (&mtx, MUTEX_ALL_ACCESS, &attr, bInitialOwner);
141 if (!NT_SUCCESS (status))
143 SetLastError (RtlNtStatusToDosError (status));
144 return NULL;
146 SetLastError (status == STATUS_OBJECT_NAME_EXISTS
147 ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
148 return mtx;
151 HANDLE
152 CreateMutexA (LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner,
153 LPCSTR lpName)
155 WCHAR name[MAX_PATH];
157 if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName))
159 SetLastError (ERROR_FILENAME_EXCED_RANGE);
160 return NULL;
162 return CreateMutexW (lpMutexAttributes, bInitialOwner, lpName ? name : NULL);
165 HANDLE
166 OpenMutexW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
168 HANDLE mtx;
169 UNICODE_STRING uname;
170 OBJECT_ATTRIBUTES attr;
171 NTSTATUS status;
172 ULONG flags = 0;
174 if (bInheritHandle)
175 flags |= OBJ_INHERIT;
176 if (lpName)
178 RtlInitUnicodeString (&uname, lpName);
179 flags |= OBJ_CASE_INSENSITIVE;
181 InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags,
182 lpName ? get_shared_parent_dir () : NULL,
183 NULL);
184 status = NtOpenMutant (&mtx, dwDesiredAccess, &attr);
185 if (!NT_SUCCESS (status))
187 SetLastError (RtlNtStatusToDosError (status));
188 return NULL;
190 return mtx;
193 HANDLE
194 OpenMutexA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
196 WCHAR name[MAX_PATH];
198 if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName))
200 SetLastError (ERROR_FILENAME_EXCED_RANGE);
201 return NULL;
203 return OpenMutexW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL);
206 /* Implement CreateSemaphore/OpenSemaphore so that named objects are always
207 created in Cygwin shared object namespace. */
209 HANDLE
210 CreateSemaphoreW (LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
211 LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName)
213 HANDLE sem;
214 UNICODE_STRING uname;
215 OBJECT_ATTRIBUTES attr;
216 NTSTATUS status;
217 ULONG flags = 0;
219 if (lpSemaphoreAttributes && lpSemaphoreAttributes->bInheritHandle)
220 flags |= OBJ_INHERIT;
221 if (lpName)
223 RtlInitUnicodeString (&uname, lpName);
224 flags |= OBJ_OPENIF | OBJ_CASE_INSENSITIVE;
226 InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags,
227 lpName ? get_shared_parent_dir () : NULL,
228 lpSemaphoreAttributes
229 ? lpSemaphoreAttributes->lpSecurityDescriptor
230 : NULL);
231 status = NtCreateSemaphore (&sem, SEMAPHORE_ALL_ACCESS, &attr,
232 lInitialCount, lMaximumCount);
233 if (!NT_SUCCESS (status))
235 SetLastError (RtlNtStatusToDosError (status));
236 return NULL;
238 SetLastError (status == STATUS_OBJECT_NAME_EXISTS
239 ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
240 return sem;
243 HANDLE
244 CreateSemaphoreA (LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
245 LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName)
247 WCHAR name[MAX_PATH];
249 if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName))
251 SetLastError (ERROR_FILENAME_EXCED_RANGE);
252 return NULL;
254 return CreateSemaphoreW (lpSemaphoreAttributes, lInitialCount, lMaximumCount,
255 lpName ? name : NULL);
258 HANDLE
259 OpenSemaphoreW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
261 HANDLE sem;
262 UNICODE_STRING uname;
263 OBJECT_ATTRIBUTES attr;
264 NTSTATUS status;
265 ULONG flags = 0;
267 if (bInheritHandle)
268 flags |= OBJ_INHERIT;
269 if (lpName)
271 RtlInitUnicodeString (&uname, lpName);
272 flags |= OBJ_CASE_INSENSITIVE;
274 InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags,
275 lpName ? get_shared_parent_dir () : NULL,
276 NULL);
277 status = NtOpenSemaphore (&sem, dwDesiredAccess, &attr);
278 if (!NT_SUCCESS (status))
280 SetLastError (RtlNtStatusToDosError (status));
281 return NULL;
283 return sem;
286 HANDLE
287 OpenSemaphoreA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
289 WCHAR name[MAX_PATH];
291 if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName))
293 SetLastError (ERROR_FILENAME_EXCED_RANGE);
294 return NULL;
296 return OpenSemaphoreW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL);
299 /* Implement CreateFileMapping/OpenFileMapping so that named objects are always
300 created in Cygwin shared object namespace. */
302 HANDLE
303 CreateFileMappingW (HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes,
304 DWORD flProtect, DWORD dwMaximumSizeHigh,
305 DWORD dwMaximumSizeLow, LPCWSTR lpName)
307 HANDLE sect;
308 UNICODE_STRING uname;
309 OBJECT_ATTRIBUTES attr;
310 NTSTATUS status;
311 ULONG flags = 0;
312 ACCESS_MASK access = STANDARD_RIGHTS_REQUIRED
313 | SECTION_QUERY | SECTION_MAP_READ;
314 ULONG prot = flProtect & (PAGE_NOACCESS | PAGE_READONLY | PAGE_READWRITE
315 | PAGE_WRITECOPY | PAGE_EXECUTE
316 | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE
317 | PAGE_EXECUTE_WRITECOPY);
318 ULONG attribs = flProtect & (SEC_COMMIT | SEC_IMAGE | SEC_NOCACHE
319 | SEC_RESERVE);
320 LARGE_INTEGER size = {{ LowPart : dwMaximumSizeLow,
321 HighPart : (LONG) dwMaximumSizeHigh }};
322 PLARGE_INTEGER psize = size.QuadPart ? &size : NULL;
324 if (prot & (PAGE_READWRITE | PAGE_WRITECOPY
325 | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY))
326 access |= SECTION_MAP_WRITE;
327 if (prot & (PAGE_EXECUTE | PAGE_EXECUTE_READ
328 | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY))
329 access |= SECTION_MAP_EXECUTE;
330 if (lpAttributes && lpAttributes->bInheritHandle)
331 flags |= OBJ_INHERIT;
332 if (lpName)
334 RtlInitUnicodeString (&uname, lpName);
335 flags |= OBJ_OPENIF | OBJ_CASE_INSENSITIVE;
337 InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags,
338 lpName ? get_shared_parent_dir () : NULL,
339 lpAttributes
340 ? lpAttributes->lpSecurityDescriptor
341 : NULL);
342 if (!(attribs & (SEC_RESERVE | SEC_COMMIT)))
343 attribs |= SEC_COMMIT;
344 if (hFile == INVALID_HANDLE_VALUE)
345 hFile = NULL;
346 status = NtCreateSection (&sect, access, &attr, psize, prot, attribs, hFile);
347 if (!NT_SUCCESS (status))
349 SetLastError (RtlNtStatusToDosError (status));
350 return NULL;
352 SetLastError (status == STATUS_OBJECT_NAME_EXISTS
353 ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
354 return sect;
357 HANDLE
358 CreateFileMappingA (HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes,
359 DWORD flProtect, DWORD dwMaximumSizeHigh,
360 DWORD dwMaximumSizeLow, LPCSTR lpName)
362 WCHAR name[MAX_PATH];
364 if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName))
366 SetLastError (ERROR_FILENAME_EXCED_RANGE);
367 return NULL;
369 return CreateFileMappingW (hFile, lpAttributes, flProtect, dwMaximumSizeHigh,
370 dwMaximumSizeLow, lpName ? name : NULL);
373 HANDLE
374 OpenFileMappingW (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
376 HANDLE sect;
377 UNICODE_STRING uname;
378 OBJECT_ATTRIBUTES attr;
379 NTSTATUS status;
380 ULONG flags = 0;
382 if (bInheritHandle)
383 flags |= OBJ_INHERIT;
384 if (lpName)
386 RtlInitUnicodeString (&uname, lpName);
387 flags |= OBJ_CASE_INSENSITIVE;
389 InitializeObjectAttributes (&attr, lpName ? &uname : NULL, flags,
390 lpName ? get_shared_parent_dir () : NULL,
391 NULL);
392 status = NtOpenSection (&sect, dwDesiredAccess, &attr);
393 if (!NT_SUCCESS (status))
395 SetLastError (RtlNtStatusToDosError (status));
396 return NULL;
398 return sect;
401 HANDLE
402 OpenFileMappingA (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
404 WCHAR name[MAX_PATH];
406 if (lpName && !sys_mbstowcs (name, MAX_PATH, lpName))
408 SetLastError (ERROR_FILENAME_EXCED_RANGE);
409 return NULL;
411 return OpenFileMappingW (dwDesiredAccess, bInheritHandle, lpName ? name : NULL);
414 /* The external functions below wrap Windows functions of the same name
415 and provide a Windows interface to Cygwin functionality. */
417 /* Construct a unicode version of the Cygwin command line from __argv) */
418 static UNICODE_STRING *
419 ucmd ()
421 static UNICODE_STRING wcmd;
422 tmp_pathbuf tp;
424 if (!wcmd.Buffer)
426 linebuf cmd;
427 char *win_progname = tp.c_get ();
428 sys_wcstombs (win_progname, NT_MAX_PATH, global_progname);
429 av newargv (__argc, __argv);
430 if (newargv.argc)
432 cmd.fromargv (newargv, win_progname, true);
433 RtlInitUnicodeString (&wcmd, cmd);
436 return &wcmd;
439 /* Cygwin replacement for GetCommandLineW. Returns a concatenated wide string
440 representing the argv list, constructed using roughly the same mechanism as
441 child_info_spawn::worker */
442 extern "C" LPWSTR
443 cygwin_GetCommandLineW (void)
445 return ucmd ()->Buffer;
448 /* Cygwin replacement for GetCommandLineA. Returns a concatenated string
449 representing the argv list, constructed using roughly the same mechanism
450 as child_info_spawn::worker */
451 extern "C" LPSTR
452 cygwin_GetCommandLineA (void)
454 static ANSI_STRING cmd;
455 if (!cmd.Buffer)
456 RtlUnicodeStringToAnsiString (&cmd, ucmd (), TRUE);
457 return cmd.Buffer;