xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/misc/win32/misc.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #include "apr_private.h"
18 #include "apr_arch_misc.h"
19 #include "apr_arch_file_io.h"
20 #include "assert.h"
21 #include "apr_lib.h"
22 #include "tchar.h"
23 
24 APR_DECLARE_DATA apr_oslevel_e apr_os_level = APR_WIN_UNK;
25 
apr_get_oslevel(apr_oslevel_e * level)26 apr_status_t apr_get_oslevel(apr_oslevel_e *level)
27 {
28     if (apr_os_level == APR_WIN_UNK)
29     {
30         static OSVERSIONINFO oslev;
31         oslev.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
32         GetVersionEx(&oslev);
33 
34         if (oslev.dwPlatformId == VER_PLATFORM_WIN32_NT)
35         {
36             static unsigned int servpack = 0;
37             TCHAR *pservpack;
38             if ((pservpack = oslev.szCSDVersion)) {
39                 while (*pservpack && !apr_isdigit(*pservpack)) {
40                     pservpack++;
41                 }
42                 if (*pservpack)
43 #ifdef _UNICODE
44                     servpack = _wtoi(pservpack);
45 #else
46                     servpack = atoi(pservpack);
47 #endif
48             }
49 
50             if (oslev.dwMajorVersion < 3) {
51                 apr_os_level = APR_WIN_UNSUP;
52             }
53             else if (oslev.dwMajorVersion == 3) {
54                 if (oslev.dwMajorVersion < 50) {
55                     apr_os_level = APR_WIN_UNSUP;
56                 }
57                 else if (oslev.dwMajorVersion == 50) {
58                     apr_os_level = APR_WIN_NT_3_5;
59                 }
60                 else {
61                     apr_os_level = APR_WIN_NT_3_51;
62                 }
63             }
64             else if (oslev.dwMajorVersion == 4) {
65                 if (servpack < 2)
66                     apr_os_level = APR_WIN_NT_4;
67                 else if (servpack <= 2)
68                     apr_os_level = APR_WIN_NT_4_SP2;
69                 else if (servpack <= 3)
70                     apr_os_level = APR_WIN_NT_4_SP3;
71                 else if (servpack <= 4)
72                     apr_os_level = APR_WIN_NT_4_SP4;
73                 else if (servpack <= 5)
74                     apr_os_level = APR_WIN_NT_4_SP5;
75                 else
76                     apr_os_level = APR_WIN_NT_4_SP6;
77             }
78             else if (oslev.dwMajorVersion == 5) {
79                 if (oslev.dwMinorVersion == 0) {
80                     if (servpack == 0)
81                         apr_os_level = APR_WIN_2000;
82                     else if (servpack == 1)
83                         apr_os_level = APR_WIN_2000_SP1;
84                     else
85                         apr_os_level = APR_WIN_2000_SP2;
86                 }
87                 else if (oslev.dwMinorVersion == 2) {
88                     apr_os_level = APR_WIN_2003;
89                 }
90                 else {
91                     if (servpack < 1)
92                         apr_os_level = APR_WIN_XP;
93                     else if (servpack == 1)
94                         apr_os_level = APR_WIN_XP_SP1;
95                     else
96                         apr_os_level = APR_WIN_XP_SP2;
97                 }
98             }
99             else if (oslev.dwMajorVersion == 6) {
100                 if (oslev.dwMinorVersion == 0)
101                     apr_os_level = APR_WIN_VISTA;
102                 else
103                     apr_os_level = APR_WIN_7;
104             }
105             else {
106                 apr_os_level = APR_WIN_XP;
107             }
108         }
109 #ifndef WINNT
110         else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
111             TCHAR *prevision;
112             if (prevision = oslev.szCSDVersion) {
113                 while (*prevision && !apr_isupper(*prevision)) {
114                      prevision++;
115                 }
116             }
117             else prevision = _T("");
118 
119             if (oslev.dwMinorVersion < 10) {
120                 if (*prevision < _T('C'))
121                     apr_os_level = APR_WIN_95;
122                 else
123                     apr_os_level = APR_WIN_95_OSR2;
124             }
125             else if (oslev.dwMinorVersion < 90) {
126                 if (*prevision < _T('A'))
127                     apr_os_level = APR_WIN_98;
128                 else
129                     apr_os_level = APR_WIN_98_SE;
130             }
131             else {
132                 apr_os_level = APR_WIN_ME;
133             }
134         }
135 #endif
136 #ifdef _WIN32_WCE
137         else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_CE)
138         {
139             if (oslev.dwMajorVersion < 3) {
140                 apr_os_level = APR_WIN_UNSUP;
141             }
142             else {
143                 apr_os_level = APR_WIN_CE_3;
144             }
145         }
146 #endif
147         else {
148             apr_os_level = APR_WIN_UNSUP;
149         }
150     }
151 
152     *level = apr_os_level;
153 
154     if (apr_os_level < APR_WIN_UNSUP) {
155         return APR_EGENERAL;
156     }
157 
158     return APR_SUCCESS;
159 }
160 
161 
162 /* This is the helper code to resolve late bound entry points
163  * missing from one or more releases of the Win32 API
164  */
165 
166 static const char* const lateDllName[DLL_defined] = {
167     "kernel32", "advapi32", "mswsock",  "ws2_32", "shell32", "ntdll.dll"  };
168 static HMODULE lateDllHandle[DLL_defined] = {
169      NULL,       NULL,       NULL,       NULL,     NULL,       NULL       };
170 
apr_load_dll_func(apr_dlltoken_e fnLib,char * fnName,int ordinal)171 FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char* fnName, int ordinal)
172 {
173     if (!lateDllHandle[fnLib]) {
174         lateDllHandle[fnLib] = LoadLibraryA(lateDllName[fnLib]);
175         if (!lateDllHandle[fnLib])
176             return NULL;
177     }
178 #if defined(_WIN32_WCE)
179     if (ordinal)
180         return GetProcAddressA(lateDllHandle[fnLib], (const char *)
181                                                      (apr_ssize_t)ordinal);
182     else
183         return GetProcAddressA(lateDllHandle[fnLib], fnName);
184 #else
185     if (ordinal)
186         return GetProcAddress(lateDllHandle[fnLib], (const char *)
187                                                     (apr_ssize_t)ordinal);
188     else
189         return GetProcAddress(lateDllHandle[fnLib], fnName);
190 #endif
191 }
192 
193 /* Declared in include/arch/win32/apr_dbg_win32_handles.h
194  */
apr_dbg_log(char * fn,HANDLE ha,char * fl,int ln,int nh,...)195 APR_DECLARE_NONSTD(HANDLE) apr_dbg_log(char* fn, HANDLE ha, char* fl, int ln,
196                                        int nh, /* HANDLE hv, char *dsc */...)
197 {
198     static DWORD tlsid = 0xFFFFFFFF;
199     static HANDLE fh = NULL;
200     static long ctr = 0;
201     static CRITICAL_SECTION cs;
202     long seq;
203     DWORD wrote;
204     char *sbuf;
205 
206     seq = (InterlockedIncrement)(&ctr);
207 
208     if (tlsid == 0xFFFFFFFF) {
209         tlsid = (TlsAlloc)();
210     }
211 
212     sbuf = (TlsGetValue)(tlsid);
213     if (!fh || !sbuf) {
214         sbuf = (malloc)(1024);
215         (TlsSetValue)(tlsid, sbuf);
216         sbuf[1023] = '\0';
217         if (!fh) {
218             (GetModuleFileNameA)(NULL, sbuf, 250);
219             sprintf(strchr(sbuf, '\0'), ".%u",
220                     (unsigned int)(GetCurrentProcessId)());
221             fh = (CreateFileA)(sbuf, GENERIC_WRITE, 0, NULL,
222                             CREATE_ALWAYS, 0, NULL);
223             (InitializeCriticalSection)(&cs);
224         }
225     }
226 
227     if (!nh) {
228         (sprintf)(sbuf, "%p %08x %08x %s() %s:%d\n",
229                   ha, (unsigned int)seq, (unsigned int)GetCurrentThreadId(),
230                   fn, fl, ln);
231         (EnterCriticalSection)(&cs);
232         (WriteFile)(fh, sbuf, (DWORD)strlen(sbuf), &wrote, NULL);
233         (LeaveCriticalSection)(&cs);
234     }
235     else {
236         va_list a;
237         va_start(a,nh);
238         (EnterCriticalSection)(&cs);
239         do {
240             HANDLE *hv = va_arg(a, HANDLE*);
241             char *dsc = va_arg(a, char*);
242             if (strcmp(dsc, "Signaled") == 0) {
243                 if ((apr_ssize_t)ha >= STATUS_WAIT_0
244                        && (apr_ssize_t)ha < STATUS_ABANDONED_WAIT_0) {
245                     hv += (apr_ssize_t)ha;
246                 }
247                 else if ((apr_ssize_t)ha >= STATUS_ABANDONED_WAIT_0
248                             && (apr_ssize_t)ha < STATUS_USER_APC) {
249                     hv += (apr_ssize_t)ha - STATUS_ABANDONED_WAIT_0;
250                     dsc = "Abandoned";
251                 }
252                 else if ((apr_ssize_t)ha == WAIT_TIMEOUT) {
253                     dsc = "Timed Out";
254                 }
255             }
256             (sprintf)(sbuf, "%p %08x %08x %s(%s) %s:%d\n",
257                       *hv, (unsigned int)seq,
258                       (unsigned int)GetCurrentThreadId(),
259                       fn, dsc, fl, ln);
260             (WriteFile)(fh, sbuf, (DWORD)strlen(sbuf), &wrote, NULL);
261         } while (--nh);
262         (LeaveCriticalSection)(&cs);
263         va_end(a);
264     }
265     return ha;
266 }
267