📄 util_win32.c
字号:
/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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_strings.h"#include "arch/win32/apr_arch_file_io.h"#include "arch/win32/apr_arch_misc.h"#include "httpd.h"#include "http_log.h"#include <stdarg.h>#include <time.h>#include <stdlib.h>AP_DECLARE(apr_status_t) ap_os_proc_filepath(char **binpath, apr_pool_t *p){ apr_wchar_t wbinpath[APR_PATH_MAX];#if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { apr_size_t binlen; apr_size_t wbinlen; apr_status_t rv; if (!GetModuleFileNameW(NULL, wbinpath, sizeof(wbinpath) / sizeof(apr_wchar_t))) { return apr_get_os_error(); } wbinlen = wcslen(wbinpath) + 1; binlen = (wbinlen - 1) * 3 + 1; *binpath = apr_palloc(p, binlen); rv = apr_conv_ucs2_to_utf8(wbinpath, &wbinlen, *binpath, &binlen); if (rv != APR_SUCCESS) return rv; else if (wbinlen) return APR_ENAMETOOLONG; }#endif /* APR_HAS_UNICODE_FS */#if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { /* share the same scratch buffer */ char *pathbuf = (char*) wbinpath; if (!GetModuleFileName(NULL, pathbuf, sizeof(wbinpath))) { return apr_get_os_error(); } *binpath = apr_pstrdup(p, pathbuf); }#endif return APR_SUCCESS;}AP_DECLARE(apr_status_t) ap_os_create_privileged_process( const request_rec *r, apr_proc_t *newproc, const char *progname, const char * const *args, const char * const *env, apr_procattr_t *attr, apr_pool_t *p){ return apr_proc_create(newproc, progname, args, env, attr, p);}/* This code is stolen from misc/win32/misc.c and apr_private.h * This helper code resolves late bound entry points * missing from one or more releases of the Win32 API... * but it sure would be nice if we didn't duplicate this code * from the APR ;-) */static const char* const lateDllName[DLL_defined] = { "kernel32", "advapi32", "mswsock", "ws2_32" };static HMODULE lateDllHandle[DLL_defined] = { NULL, NULL, NULL, NULL };FARPROC ap_load_dll_func(ap_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);}/* To share the semaphores with other processes, we need a NULL ACL * Code from MS KB Q106387 */PSECURITY_ATTRIBUTES GetNullACL(){ PSECURITY_DESCRIPTOR pSD; PSECURITY_ATTRIBUTES sa; sa = (PSECURITY_ATTRIBUTES) LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES)); sa->nLength = sizeof(sizeof(SECURITY_ATTRIBUTES)); pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); sa->lpSecurityDescriptor = pSD; if (pSD == NULL || sa == NULL) { return NULL; } apr_set_os_error(0); if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) || apr_get_os_error()) { LocalFree( pSD ); LocalFree( sa ); return NULL; } if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE) || apr_get_os_error()) { LocalFree( pSD ); LocalFree( sa ); return NULL; } sa->bInheritHandle = FALSE; return sa;}void CleanNullACL(void *sa) { if (sa) { LocalFree(((PSECURITY_ATTRIBUTES)sa)->lpSecurityDescriptor); LocalFree(sa); }}/* * The Win32 call WaitForMultipleObjects will only allow you to wait for * a maximum of MAXIMUM_WAIT_OBJECTS (current 64). Since the threading * model in the multithreaded version of apache wants to use this call, * we are restricted to a maximum of 64 threads. This is a simplistic * routine that will increase this size. */DWORD wait_for_many_objects(DWORD nCount, CONST HANDLE *lpHandles, DWORD dwSeconds){ time_t tStopTime; DWORD dwRet = WAIT_TIMEOUT; DWORD dwIndex=0; BOOL bFirst = TRUE; tStopTime = time(NULL) + dwSeconds; do { if (!bFirst) Sleep(1000); else bFirst = FALSE; for (dwIndex = 0; dwIndex * MAXIMUM_WAIT_OBJECTS < nCount; dwIndex++) { dwRet = WaitForMultipleObjects( min(MAXIMUM_WAIT_OBJECTS, nCount - (dwIndex * MAXIMUM_WAIT_OBJECTS)), lpHandles + (dwIndex * MAXIMUM_WAIT_OBJECTS), 0, 0); if (dwRet != WAIT_TIMEOUT) { break; } } } while((time(NULL) < tStopTime) && (dwRet == WAIT_TIMEOUT)); return dwRet;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -