1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef MISC_H
18#define MISC_H
19
20#include "apr.h"
21#include "apr_portable.h"
22#include "apr_private.h"
23#include "apr_general.h"
24#include "apr_pools.h"
25#include "apr_getopt.h"
26#include "apr_thread_proc.h"
27#include "apr_file_io.h"
28#include "apr_errno.h"
29#include "apr_getopt.h"
30
31#if APR_HAVE_STDIO_H
32#include <stdio.h>
33#endif
34#if APR_HAVE_SIGNAL_H
35#include <signal.h>
36#endif
37#if APR_HAVE_PTHREAD_H
38#include <pthread.h>
39#endif
40#if APR_HAVE_STDLIB_H
41#include <stdlib.h>
42#endif
43#if APR_HAVE_STRING_H
44#include <string.h>
45#endif
46#ifndef _WIN32_WCE
47#include <tlhelp32.h>
48#endif
49
50struct apr_other_child_rec_t {
51    apr_pool_t *p;
52    struct apr_other_child_rec_t *next;
53    apr_proc_t *proc;
54    void (*maintenance) (int, void *, int);
55    void *data;
56    apr_os_file_t write_fd;
57};
58
59#define WSAHighByte 2
60#define WSALowByte 0
61
62/* start.c and apr_app.c helpers and communication within misc.c
63 *
64 * They are not for public consumption, although apr_app_init_complete
65 * must be an exported symbol to avoid reinitialization.
66 */
67extern int APR_DECLARE_DATA apr_app_init_complete;
68
69int apr_wastrtoastr(char const * const * *retarr,
70                    wchar_t const * const *arr, int args);
71
72/* Platform specific designation of run time os version.
73 * Gaps allow for specific service pack levels that
74 * export new kernel or winsock functions or behavior.
75 */
76typedef enum {
77    APR_WIN_UNK =       0,
78    APR_WIN_UNSUP =     1,
79    APR_WIN_95 =       10,
80    APR_WIN_95_B =     11,
81    APR_WIN_95_OSR2 =  12,
82    APR_WIN_98 =       14,
83    APR_WIN_98_SE =    16,
84    APR_WIN_ME =       18,
85
86    APR_WIN_UNICODE =  20, /* Prior versions support only narrow chars */
87
88    APR_WIN_CE_3 =     23, /* CE is an odd beast, not supporting */
89                           /* some pre-NT features, such as the    */
90    APR_WIN_NT =       30, /* narrow charset APIs (fooA fns), while  */
91    APR_WIN_NT_3_5 =   35, /* not supporting some NT-family features.  */
92    APR_WIN_NT_3_51 =  36,
93
94    APR_WIN_NT_4 =     40,
95    APR_WIN_NT_4_SP2 = 42,
96    APR_WIN_NT_4_SP3 = 43,
97    APR_WIN_NT_4_SP4 = 44,
98    APR_WIN_NT_4_SP5 = 45,
99    APR_WIN_NT_4_SP6 = 46,
100
101    APR_WIN_2000 =     50,
102    APR_WIN_2000_SP1 = 51,
103    APR_WIN_2000_SP2 = 52,
104    APR_WIN_XP =       60,
105    APR_WIN_XP_SP1 =   61,
106    APR_WIN_XP_SP2 =   62,
107    APR_WIN_2003 =     70,
108    APR_WIN_VISTA =    80
109} apr_oslevel_e;
110
111extern APR_DECLARE_DATA apr_oslevel_e apr_os_level;
112
113apr_status_t apr_get_oslevel(apr_oslevel_e *);
114
115/* The APR_HAS_ANSI_FS symbol is PRIVATE, and internal to APR.
116 * APR only supports char data for filenames.  Like most applications,
117 * characters >127 are essentially undefined.  APR_HAS_UNICODE_FS lets
118 * the application know that utf-8 is the encoding method of APR, and
119 * only incidently hints that we have Wide OS calls.
120 *
121 * APR_HAS_ANSI_FS is simply an OS flag to tell us all calls must be
122 * the unicode eqivilant.
123 */
124
125#if defined(_WIN32_WCE) || defined(WINNT)
126#define APR_HAS_ANSI_FS           0
127#else
128#define APR_HAS_ANSI_FS           1
129#endif
130
131/* IF_WIN_OS_IS_UNICODE / ELSE_WIN_OS_IS_ANSI help us keep the code trivial
132 * where have runtime tests for unicode-ness, that aren't needed in any
133 * build which supports only WINNT or WCE.
134 */
135#if APR_HAS_ANSI_FS && APR_HAS_UNICODE_FS
136#define IF_WIN_OS_IS_UNICODE if (apr_os_level >= APR_WIN_UNICODE)
137#define ELSE_WIN_OS_IS_ANSI else
138#else /* APR_HAS_UNICODE_FS */
139#define IF_WIN_OS_IS_UNICODE
140#define ELSE_WIN_OS_IS_ANSI
141#endif /* WINNT */
142
143#if defined(_MSC_VER) && !defined(_WIN32_WCE)
144#include "crtdbg.h"
145
146static APR_INLINE void* apr_malloc_dbg(size_t size, const char* filename,
147                                       int linenumber)
148{
149    return _malloc_dbg(size, _CRT_BLOCK, filename, linenumber);
150}
151
152static APR_INLINE void* apr_realloc_dbg(void* userData, size_t newSize,
153                                        const char* filename, int linenumber)
154{
155    return _realloc_dbg(userData, newSize, _CRT_BLOCK, filename, linenumber);
156}
157
158#else
159
160static APR_INLINE void* apr_malloc_dbg(size_t size, const char* filename,
161                                       int linenumber)
162{
163    return malloc(size);
164}
165
166static APR_INLINE void* apr_realloc_dbg(void* userData, size_t newSize,
167                                        const char* filename, int linenumber)
168{
169    return realloc(userData, newSize);
170}
171
172#endif  /* ! _MSC_VER */
173
174typedef enum {
175    DLL_WINBASEAPI = 0,    /* kernel32 From WinBase.h       */
176    DLL_WINADVAPI = 1,     /* advapi32 From WinBase.h       */
177    DLL_WINSOCKAPI = 2,    /* mswsock  From WinSock.h       */
178    DLL_WINSOCK2API = 3,   /* ws2_32   From WinSock2.h      */
179    DLL_SHSTDAPI = 4,      /* shell32  From ShellAPI.h      */
180    DLL_NTDLL = 5,         /* shell32  From our real kernel */
181    DLL_defined = 6        /* must define as last idx_ + 1  */
182} apr_dlltoken_e;
183
184FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char *fnName, int ordinal);
185
186/* The apr_load_dll_func call WILL return 0 set error to
187 * ERROR_INVALID_FUNCTION if the function cannot be loaded
188 */
189#define APR_DECLARE_LATE_DLL_FUNC(lib, rettype, calltype, fn, ord, args, names) \
190    typedef rettype (calltype *apr_winapi_fpt_##fn) args; \
191    static apr_winapi_fpt_##fn apr_winapi_pfn_##fn = NULL; \
192    static int apr_winapi_chk_##fn = 0; \
193    static APR_INLINE int apr_winapi_ld_##fn(void) \
194    {   if (apr_winapi_pfn_##fn) return 1; \
195        if (apr_winapi_chk_##fn ++) return 0; \
196        if (!apr_winapi_pfn_##fn) \
197            apr_winapi_pfn_##fn = (apr_winapi_fpt_##fn) \
198                                      apr_load_dll_func(lib, #fn, ord); \
199        if (apr_winapi_pfn_##fn) return 1; else return 0; }; \
200    static APR_INLINE rettype apr_winapi_##fn args \
201    {   if (apr_winapi_ld_##fn()) \
202            return (*(apr_winapi_pfn_##fn)) names; \
203        else { SetLastError(ERROR_INVALID_FUNCTION); return 0;} }; \
204
205#define APR_HAVE_LATE_DLL_FUNC(fn) apr_winapi_ld_##fn()
206
207/* Provide late bound declarations of every API function missing from
208 * one or more supported releases of the Win32 API
209 *
210 * lib is the enumerated token from apr_dlltoken_e, and must correspond
211 * to the string table entry in start.c used by the apr_load_dll_func().
212 * Token names (attempt to) follow Windows.h declarations prefixed by DLL_
213 * in order to facilitate comparison.  Use the exact declaration syntax
214 * and names from Windows.h to prevent ambigutity and bugs.
215 *
216 * rettype and calltype follow the original declaration in Windows.h
217 * fn is the true function name - beware Ansi/Unicode #defined macros
218 * ord is the ordinal within the library, use 0 if it varies between versions
219 * args is the parameter list following the original declaration, in parens
220 * names is the parameter list sans data types, enclosed in parens
221 *
222 * #undef/re#define the Ansi/Unicode generic name to abate confusion
223 * In the case of non-text functions, simply #define the original name
224 */
225
226#if !defined(_WIN32_WCE) && !defined(WINNT)
227/* This group is available to all versions of WINNT 4.0 SP6 and later */
228
229#ifdef GetFileAttributesExA
230#undef GetFileAttributesExA
231#endif
232APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, GetFileAttributesExA, 0, (
233    IN LPCSTR lpFileName,
234    IN GET_FILEEX_INFO_LEVELS fInfoLevelId,
235    OUT LPVOID lpFileInformation),
236    (lpFileName, fInfoLevelId, lpFileInformation));
237#define GetFileAttributesExA apr_winapi_GetFileAttributesExA
238#undef GetFileAttributesEx
239#define GetFileAttributesEx apr_winapi_GetFileAttributesExA
240
241#ifdef GetFileAttributesExW
242#undef GetFileAttributesExW
243#endif
244APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, GetFileAttributesExW, 0, (
245    IN LPCWSTR lpFileName,
246    IN GET_FILEEX_INFO_LEVELS fInfoLevelId,
247    OUT LPVOID lpFileInformation),
248    (lpFileName, fInfoLevelId, lpFileInformation));
249#define GetFileAttributesExW apr_winapi_GetFileAttributesExW
250
251APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, CancelIo, 0, (
252    IN HANDLE hFile),
253    (hFile));
254#define CancelIo apr_winapi_CancelIo
255
256APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, TryEnterCriticalSection, 0, (
257    LPCRITICAL_SECTION lpCriticalSection),
258    (lpCriticalSection));
259#define TryEnterCriticalSection apr_winapi_TryEnterCriticalSection
260
261APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, SwitchToThread, 0, (
262    void),
263    ());
264#define SwitchToThread apr_winapi_SwitchToThread
265
266APR_DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI, GetEffectiveRightsFromAclW, 0, (
267    IN PACL pacl,
268    IN PTRUSTEE_W pTrustee,
269    OUT PACCESS_MASK pAccessRights),
270    (pacl, pTrustee, pAccessRights));
271#define GetEffectiveRightsFromAclW apr_winapi_GetEffectiveRightsFromAclW
272
273APR_DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI, GetNamedSecurityInfoW, 0, (
274    IN LPWSTR pObjectName,
275    IN SE_OBJECT_TYPE ObjectType,
276    IN SECURITY_INFORMATION SecurityInfo,
277    OUT PSID *ppsidOwner,
278    OUT PSID *ppsidGroup,
279    OUT PACL *ppDacl,
280    OUT PACL *ppSacl,
281    OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor),
282    (pObjectName, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup,
283        ppDacl, ppSacl, ppSecurityDescriptor));
284#define GetNamedSecurityInfoW apr_winapi_GetNamedSecurityInfoW
285
286APR_DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI, GetNamedSecurityInfoA, 0, (
287    IN LPSTR pObjectName,
288    IN SE_OBJECT_TYPE ObjectType,
289    IN SECURITY_INFORMATION SecurityInfo,
290    OUT PSID *ppsidOwner,
291    OUT PSID *ppsidGroup,
292    OUT PACL *ppDacl,
293    OUT PACL *ppSacl,
294    OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor),
295    (pObjectName, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup,
296        ppDacl, ppSacl, ppSecurityDescriptor));
297#define GetNamedSecurityInfoA apr_winapi_GetNamedSecurityInfoA
298#undef GetNamedSecurityInfo
299#define GetNamedSecurityInfo apr_winapi_GetNamedSecurityInfoA
300
301APR_DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI, GetSecurityInfo, 0, (
302    IN HANDLE handle,
303    IN SE_OBJECT_TYPE ObjectType,
304    IN SECURITY_INFORMATION SecurityInfo,
305    OUT PSID *ppsidOwner,
306    OUT PSID *ppsidGroup,
307    OUT PACL *ppDacl,
308    OUT PACL *ppSacl,
309    OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor),
310    (handle, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup,
311        ppDacl, ppSacl, ppSecurityDescriptor));
312#define GetSecurityInfo apr_winapi_GetSecurityInfo
313
314APR_DECLARE_LATE_DLL_FUNC(DLL_SHSTDAPI, LPWSTR *, WINAPI, CommandLineToArgvW, 0, (
315    LPCWSTR lpCmdLine,
316    int *pNumArgs),
317    (lpCmdLine, pNumArgs));
318#define CommandLineToArgvW apr_winapi_CommandLineToArgvW
319
320#endif /* !defined(_WIN32_WCE) && !defined(WINNT) */
321
322#if !defined(_WIN32_WCE)
323/* This group is NOT available to all versions of WinNT,
324 * these we must always look up
325 */
326
327#ifdef GetCompressedFileSizeA
328#undef GetCompressedFileSizeA
329#endif
330APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, DWORD, WINAPI, GetCompressedFileSizeA, 0, (
331    IN LPCSTR lpFileName,
332    OUT LPDWORD lpFileSizeHigh),
333    (lpFileName, lpFileSizeHigh));
334#define GetCompressedFileSizeA apr_winapi_GetCompressedFileSizeA
335#undef GetCompressedFileSize
336#define GetCompressedFileSize apr_winapi_GetCompressedFileSizeA
337
338#ifdef GetCompressedFileSizeW
339#undef GetCompressedFileSizeW
340#endif
341APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, DWORD, WINAPI, GetCompressedFileSizeW, 0, (
342    IN LPCWSTR lpFileName,
343    OUT LPDWORD lpFileSizeHigh),
344    (lpFileName, lpFileSizeHigh));
345#define GetCompressedFileSizeW apr_winapi_GetCompressedFileSizeW
346
347
348APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtQueryTimerResolution, 0, (
349    ULONG *pMaxRes,  /* Minimum NS Resolution */
350    ULONG *pMinRes,  /* Maximum NS Resolution */
351    ULONG *pCurRes), /* Current NS Resolution */
352    (pMaxRes, pMinRes, pCurRes));
353#define QueryTimerResolution apr_winapi_NtQueryTimerResolution
354
355APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtSetTimerResolution, 0, (
356    ULONG ReqRes,    /* Requested NS Clock Resolution */
357    BOOL  Acquire,   /* Aquire (1) or Release (0) our interest */
358    ULONG *pNewRes), /* The NS Clock Resolution granted */
359    (ReqRes, Acquire, pNewRes));
360#define SetTimerResolution apr_winapi_NtSetTimerResolution
361
362typedef struct PBI {
363    LONG      ExitStatus;
364    PVOID     PebBaseAddress;
365    apr_uintptr_t AffinityMask;
366    LONG      BasePriority;
367    apr_uintptr_t UniqueProcessId;
368    apr_uintptr_t InheritedFromUniqueProcessId;
369} PBI, *PPBI;
370
371APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtQueryInformationProcess, 0, (
372    HANDLE hProcess,  /* Obvious */
373    INT   info,       /* Use 0 for PBI documented above */
374    PVOID pPI,        /* The PIB buffer */
375    ULONG LenPI,      /* Use sizeof(PBI) */
376    ULONG *pSizePI),  /* returns pPI buffer used (may pass NULL) */
377    (hProcess, info, pPI, LenPI, pSizePI));
378#define QueryInformationProcess apr_winapi_NtQueryInformationProcess
379
380APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtQueryObject, 0, (
381    HANDLE hObject,   /* Obvious */
382    INT   info,       /* Use 0 for PBI documented above */
383    PVOID pOI,        /* The PIB buffer */
384    ULONG LenOI,      /* Use sizeof(PBI) */
385    ULONG *pSizeOI),  /* returns pPI buffer used (may pass NULL) */
386    (hObject, info, pOI, LenOI, pSizeOI));
387#define QueryObject apr_winapi_NtQueryObject
388
389typedef struct IOSB {
390    union {
391    UINT Status;
392    PVOID reserved;
393    };
394    apr_uintptr_t Information; /* Varies by op, consumed buffer size for FSI below */
395} IOSB, *PIOSB;
396
397typedef struct FSI {
398    LONGLONG AllocationSize;
399    LONGLONG EndOfFile;
400    ULONG    NumberOfLinks;
401    BOOL     DeletePending;
402    BOOL     Directory;
403} FSI, *PFSI;
404
405APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, ZwQueryInformationFile, 0, (
406    HANDLE hObject,    /* Obvious */
407    PVOID  pIOSB,      /* Point to the IOSB buffer for detailed return results */
408    PVOID  pFI,        /* The buffer, using FIB above */
409    ULONG  LenFI,      /* Use sizeof(FI) */
410    ULONG  info),      /* Use 5 for FSI documented above*/
411    (hObject, pIOSB, pFI, LenFI, info));
412#define ZwQueryInformationFile apr_winapi_ZwQueryInformationFile
413
414#ifdef CreateToolhelp32Snapshot
415#undef CreateToolhelp32Snapshot
416#endif
417APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, HANDLE, WINAPI, CreateToolhelp32Snapshot, 0, (
418    DWORD dwFlags,
419    DWORD th32ProcessID),
420    (dwFlags, th32ProcessID));
421#define CreateToolhelp32Snapshot apr_winapi_CreateToolhelp32Snapshot
422
423#ifdef Process32FirstW
424#undef Process32FirstW
425#endif
426APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, Process32FirstW, 0, (
427    HANDLE hSnapshot,
428    LPPROCESSENTRY32W lppe),
429    (hSnapshot, lppe));
430#define Process32FirstW apr_winapi_Process32FirstW
431
432#ifdef Process32NextW
433#undef Process32NextW
434#endif
435APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, Process32NextW, 0, (
436    HANDLE hSnapshot,
437    LPPROCESSENTRY32W lppe),
438    (hSnapshot, lppe));
439#define Process32NextW apr_winapi_Process32NextW
440
441#if !defined(POLLERR)
442/* Event flag definitions for WSAPoll(). */
443#define POLLRDNORM  0x0100
444#define POLLRDBAND  0x0200
445#define POLLIN      (POLLRDNORM | POLLRDBAND)
446#define POLLPRI     0x0400
447
448#define POLLWRNORM  0x0010
449#define POLLOUT     (POLLWRNORM)
450#define POLLWRBAND  0x0020
451
452#define POLLERR     0x0001
453#define POLLHUP     0x0002
454#define POLLNVAL    0x0004
455
456typedef struct pollfd {
457    SOCKET  fd;
458    SHORT   events;
459    SHORT   revents;
460
461} WSAPOLLFD, *PWSAPOLLFD, FAR *LPWSAPOLLFD;
462
463#endif /* !defined(POLLERR) */
464#ifdef WSAPoll
465#undef WSAPoll
466#endif
467APR_DECLARE_LATE_DLL_FUNC(DLL_WINSOCK2API, int, WSAAPI, WSAPoll, 0, (
468    IN OUT LPWSAPOLLFD fdArray,
469    IN ULONG fds,
470    IN INT timeout),
471    (fdArray, fds, timeout));
472#define WSAPoll apr_winapi_WSAPoll
473#define HAVE_POLL   1
474
475#ifdef SetDllDirectoryW
476#undef SetDllDirectoryW
477#endif
478APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, SetDllDirectoryW, 0, (
479    IN LPCWSTR lpPathName),
480    (lpPathName));
481#define SetDllDirectoryW apr_winapi_SetDllDirectoryW
482
483#endif /* !defined(_WIN32_WCE) */
484
485#endif  /* ! MISC_H */
486
487