summaryrefslogtreecommitdiffstats
path: root/misc/win32/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc/win32/misc.c')
-rw-r--r--misc/win32/misc.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/misc/win32/misc.c b/misc/win32/misc.c
new file mode 100644
index 0000000..bfb7efa
--- /dev/null
+++ b/misc/win32/misc.c
@@ -0,0 +1,266 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_private.h"
+#include "apr_arch_misc.h"
+#include "apr_arch_file_io.h"
+#include "assert.h"
+#include "apr_lib.h"
+#include "tchar.h"
+
+APR_DECLARE_DATA apr_oslevel_e apr_os_level = APR_WIN_UNK;
+
+apr_status_t apr_get_oslevel(apr_oslevel_e *level)
+{
+ if (apr_os_level == APR_WIN_UNK)
+ {
+ OSVERSIONINFOEXW oslev;
+ oslev.dwOSVersionInfoSize = sizeof(oslev);
+ if (!GetVersionExW((OSVERSIONINFOW*) &oslev)) {
+ return apr_get_os_error();
+ }
+
+ if (oslev.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ {
+ unsigned int servpack = oslev.wServicePackMajor;
+
+ if (oslev.dwMajorVersion < 3) {
+ apr_os_level = APR_WIN_UNSUP;
+ }
+ else if (oslev.dwMajorVersion == 3) {
+ if (oslev.dwMajorVersion < 50) {
+ apr_os_level = APR_WIN_UNSUP;
+ }
+ else if (oslev.dwMajorVersion == 50) {
+ apr_os_level = APR_WIN_NT_3_5;
+ }
+ else {
+ apr_os_level = APR_WIN_NT_3_51;
+ }
+ }
+ else if (oslev.dwMajorVersion == 4) {
+ if (servpack < 2)
+ apr_os_level = APR_WIN_NT_4;
+ else if (servpack <= 2)
+ apr_os_level = APR_WIN_NT_4_SP2;
+ else if (servpack <= 3)
+ apr_os_level = APR_WIN_NT_4_SP3;
+ else if (servpack <= 4)
+ apr_os_level = APR_WIN_NT_4_SP4;
+ else if (servpack <= 5)
+ apr_os_level = APR_WIN_NT_4_SP5;
+ else
+ apr_os_level = APR_WIN_NT_4_SP6;
+ }
+ else if (oslev.dwMajorVersion == 5) {
+ if (oslev.dwMinorVersion == 0) {
+ if (servpack == 0)
+ apr_os_level = APR_WIN_2000;
+ else if (servpack == 1)
+ apr_os_level = APR_WIN_2000_SP1;
+ else
+ apr_os_level = APR_WIN_2000_SP2;
+ }
+ else if (oslev.dwMinorVersion == 2) {
+ apr_os_level = APR_WIN_2003;
+ }
+ else {
+ if (servpack < 1)
+ apr_os_level = APR_WIN_XP;
+ else if (servpack == 1)
+ apr_os_level = APR_WIN_XP_SP1;
+ else
+ apr_os_level = APR_WIN_XP_SP2;
+ }
+ }
+ else if (oslev.dwMajorVersion == 6) {
+ if (oslev.dwMinorVersion == 0)
+ apr_os_level = APR_WIN_VISTA;
+ else if (oslev.dwMinorVersion == 1) {
+ if (servpack < 1)
+ apr_os_level = APR_WIN_7;
+ else
+ apr_os_level = APR_WIN_7_SP1;
+ }
+ else if (oslev.dwMinorVersion == 2)
+ apr_os_level = APR_WIN_8;
+ else
+ apr_os_level = APR_WIN_8_1;
+ }
+ else {
+ apr_os_level = APR_WIN_10;
+ }
+ }
+#ifndef WINNT
+ else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
+ TCHAR *prevision;
+ if (prevision = oslev.szCSDVersion) {
+ while (*prevision && !apr_isupper(*prevision)) {
+ prevision++;
+ }
+ }
+ else prevision = _T("");
+
+ if (oslev.dwMinorVersion < 10) {
+ if (*prevision < _T('C'))
+ apr_os_level = APR_WIN_95;
+ else
+ apr_os_level = APR_WIN_95_OSR2;
+ }
+ else if (oslev.dwMinorVersion < 90) {
+ if (*prevision < _T('A'))
+ apr_os_level = APR_WIN_98;
+ else
+ apr_os_level = APR_WIN_98_SE;
+ }
+ else {
+ apr_os_level = APR_WIN_ME;
+ }
+ }
+#endif
+#ifdef _WIN32_WCE
+ else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_CE)
+ {
+ if (oslev.dwMajorVersion < 3) {
+ apr_os_level = APR_WIN_UNSUP;
+ }
+ else {
+ apr_os_level = APR_WIN_CE_3;
+ }
+ }
+#endif
+ else {
+ apr_os_level = APR_WIN_UNSUP;
+ }
+ }
+
+ *level = apr_os_level;
+
+ if (apr_os_level <= APR_WIN_UNSUP) {
+ return APR_EGENERAL;
+ }
+
+ return APR_SUCCESS;
+}
+
+
+/* This is the helper code to resolve late bound entry points
+ * missing from one or more releases of the Win32 API
+ */
+
+static const char* const lateDllName[DLL_defined] = {
+ "kernel32", "advapi32", "mswsock", "ws2_32", "shell32", "ntdll.dll",
+ "Iphplapi" };
+static HMODULE lateDllHandle[DLL_defined] = {
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL };
+
+FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char* fnName, int ordinal)
+{
+ if (!lateDllHandle[fnLib]) {
+ lateDllHandle[fnLib] = LoadLibraryA(lateDllName[fnLib]);
+ if (!lateDllHandle[fnLib])
+ return NULL;
+ }
+#if defined(_WIN32_WCE)
+ if (ordinal)
+ return GetProcAddressA(lateDllHandle[fnLib], (const char *)
+ (apr_ssize_t)ordinal);
+ else
+ return GetProcAddressA(lateDllHandle[fnLib], fnName);
+#else
+ if (ordinal)
+ return GetProcAddress(lateDllHandle[fnLib], (const char *)
+ (apr_ssize_t)ordinal);
+ else
+ return GetProcAddress(lateDllHandle[fnLib], fnName);
+#endif
+}
+
+/* Declared in include/arch/win32/apr_dbg_win32_handles.h
+ */
+APR_DECLARE_NONSTD(HANDLE) apr_dbg_log(char* fn, HANDLE ha, char* fl, int ln,
+ int nh, /* HANDLE hv, char *dsc */...)
+{
+ static DWORD tlsid = 0xFFFFFFFF;
+ static HANDLE fh = NULL;
+ static long ctr = 0;
+ static CRITICAL_SECTION cs;
+ long seq;
+ DWORD wrote;
+ char *sbuf;
+
+ seq = (InterlockedIncrement)(&ctr);
+
+ if (tlsid == 0xFFFFFFFF) {
+ tlsid = (TlsAlloc)();
+ }
+
+ sbuf = (TlsGetValue)(tlsid);
+ if (!fh || !sbuf) {
+ sbuf = (malloc)(1024);
+ (TlsSetValue)(tlsid, sbuf);
+ sbuf[1023] = '\0';
+ if (!fh) {
+ (GetModuleFileNameA)(NULL, sbuf, 250);
+ sprintf(strchr(sbuf, '\0'), ".%u",
+ (unsigned int)(GetCurrentProcessId)());
+ fh = (CreateFileA)(sbuf, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, 0, NULL);
+ (InitializeCriticalSection)(&cs);
+ }
+ }
+
+ if (!nh) {
+ (sprintf)(sbuf, "%p %08x %08x %s() %s:%d\n",
+ ha, (unsigned int)seq, (unsigned int)GetCurrentThreadId(),
+ fn, fl, ln);
+ (EnterCriticalSection)(&cs);
+ (WriteFile)(fh, sbuf, (DWORD)strlen(sbuf), &wrote, NULL);
+ (LeaveCriticalSection)(&cs);
+ }
+ else {
+ va_list a;
+ va_start(a,nh);
+ (EnterCriticalSection)(&cs);
+ do {
+ HANDLE *hv = va_arg(a, HANDLE*);
+ char *dsc = va_arg(a, char*);
+ if (strcmp(dsc, "Signaled") == 0) {
+ if ((apr_ssize_t)ha >= STATUS_WAIT_0
+ && (apr_ssize_t)ha < STATUS_ABANDONED_WAIT_0) {
+ hv += (apr_ssize_t)ha;
+ }
+ else if ((apr_ssize_t)ha >= STATUS_ABANDONED_WAIT_0
+ && (apr_ssize_t)ha < STATUS_USER_APC) {
+ hv += (apr_ssize_t)ha - STATUS_ABANDONED_WAIT_0;
+ dsc = "Abandoned";
+ }
+ else if ((apr_ssize_t)ha == WAIT_TIMEOUT) {
+ dsc = "Timed Out";
+ }
+ }
+ (sprintf)(sbuf, "%p %08x %08x %s(%s) %s:%d\n",
+ *hv, (unsigned int)seq,
+ (unsigned int)GetCurrentThreadId(),
+ fn, dsc, fl, ln);
+ (WriteFile)(fh, sbuf, (DWORD)strlen(sbuf), &wrote, NULL);
+ } while (--nh);
+ (LeaveCriticalSection)(&cs);
+ va_end(a);
+ }
+ return ha;
+}