forked from Mirrors/freeswitch
0488a5109a
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3733 d0543943-73ff-0310-b7d9-9358b9ac24b2
246 lines
8.0 KiB
C
246 lines
8.0 KiB
C
/* 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 "crtdbg.h"
|
|
#include "apr_arch_file_io.h"
|
|
#include "assert.h"
|
|
#include "apr_lib.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)
|
|
{
|
|
static OSVERSIONINFO oslev;
|
|
oslev.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
GetVersionEx(&oslev);
|
|
|
|
if (oslev.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
static unsigned int servpack = 0;
|
|
char *pservpack;
|
|
if (pservpack = oslev.szCSDVersion) {
|
|
while (*pservpack && !apr_isdigit(*pservpack)) {
|
|
pservpack++;
|
|
}
|
|
if (*pservpack)
|
|
servpack = atoi(pservpack);
|
|
}
|
|
|
|
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 {
|
|
apr_os_level = APR_WIN_XP;
|
|
}
|
|
}
|
|
#ifndef WINNT
|
|
else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
|
|
char *prevision;
|
|
if (prevision = oslev.szCSDVersion) {
|
|
while (*prevision && !apr_isupper(*prevision)) {
|
|
prevision++;
|
|
}
|
|
}
|
|
else prevision = "";
|
|
|
|
if (oslev.dwMinorVersion < 10) {
|
|
if (*prevision < 'C')
|
|
apr_os_level = APR_WIN_95;
|
|
else
|
|
apr_os_level = APR_WIN_95_OSR2;
|
|
}
|
|
else if (oslev.dwMinorVersion < 90) {
|
|
if (*prevision < '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" };
|
|
static HMODULE lateDllHandle[DLL_defined] = {
|
|
NULL, NULL, NULL, NULL, NULL, NULL };
|
|
|
|
FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char* fnName, int ordinal)
|
|
{
|
|
if (!lateDllHandle[fnLib]) {
|
|
lateDllHandle[fnLib] = LoadLibrary(lateDllName[fnLib]);
|
|
if (!lateDllHandle[fnLib])
|
|
return NULL;
|
|
}
|
|
if (ordinal)
|
|
return GetProcAddress(lateDllHandle[fnLib], (char *) ordinal);
|
|
else
|
|
return GetProcAddress(lateDllHandle[fnLib], fnName);
|
|
}
|
|
|
|
/* 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) {
|
|
(GetModuleFileName)(NULL, sbuf, 250);
|
|
sprintf(strchr(sbuf, '\0'), ".%d",
|
|
(GetCurrentProcessId)());
|
|
fh = (CreateFile)(sbuf, GENERIC_WRITE, 0, NULL,
|
|
CREATE_ALWAYS, 0, NULL);
|
|
(InitializeCriticalSection)(&cs);
|
|
}
|
|
}
|
|
|
|
if (!nh) {
|
|
(sprintf)(sbuf, "%08x %08x %08x %s() %s:%d\n",
|
|
(DWORD)ha, seq, 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 ((DWORD)ha >= STATUS_WAIT_0
|
|
&& (DWORD)ha < STATUS_ABANDONED_WAIT_0) {
|
|
hv += (DWORD)ha;
|
|
}
|
|
else if ((DWORD)ha >= STATUS_ABANDONED_WAIT_0
|
|
&& (DWORD)ha < STATUS_USER_APC) {
|
|
hv += (DWORD)ha - STATUS_ABANDONED_WAIT_0;
|
|
dsc = "Abandoned";
|
|
}
|
|
else if ((DWORD)ha == WAIT_TIMEOUT) {
|
|
dsc = "Timed Out";
|
|
}
|
|
}
|
|
(sprintf)(sbuf, "%08x %08x %08x %s(%s) %s:%d\n",
|
|
(DWORD*)*hv, seq, GetCurrentThreadId(),
|
|
fn, dsc, fl, ln);
|
|
(WriteFile)(fh, sbuf, (DWORD)strlen(sbuf), &wrote, NULL);
|
|
} while (--nh);
|
|
(LeaveCriticalSection)(&cs);
|
|
va_end(a);
|
|
}
|
|
return ha;
|
|
}
|