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