]> granicus.if.org Git - apache/blob - os/win32/util_win32.c
update after backport
[apache] / os / win32 / util_win32.c
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_strings.h"
18 #include "arch/win32/apr_arch_file_io.h"
19 #include "arch/win32/apr_arch_misc.h"
20
21 #include "httpd.h"
22 #include "http_log.h"
23 #include "ap_mpm.h"
24
25 #include <stdarg.h>
26 #include <time.h>
27 #include <stdlib.h>
28
29
30 AP_DECLARE(apr_status_t) ap_os_proc_filepath(char **binpath, apr_pool_t *p)
31 {
32     apr_wchar_t wbinpath[APR_PATH_MAX];
33
34 #if APR_HAS_UNICODE_FS
35     IF_WIN_OS_IS_UNICODE
36     {
37         apr_size_t binlen;
38         apr_size_t wbinlen;
39         apr_status_t rv;
40         if (!GetModuleFileNameW(NULL, wbinpath, sizeof(wbinpath)
41                                               / sizeof(apr_wchar_t))) {
42             return apr_get_os_error();
43         }
44         wbinlen = wcslen(wbinpath) + 1;
45         binlen = (wbinlen - 1) * 3 + 1;
46         *binpath = apr_palloc(p, binlen);
47         rv = apr_conv_ucs2_to_utf8(wbinpath, &wbinlen, *binpath, &binlen);
48         if (rv != APR_SUCCESS)
49             return rv;
50         else if (wbinlen)
51             return APR_ENAMETOOLONG;
52     }
53 #endif /* APR_HAS_UNICODE_FS */
54 #if APR_HAS_ANSI_FS
55     ELSE_WIN_OS_IS_ANSI
56     {
57         /* share the same scratch buffer */
58         char *pathbuf = (char*) wbinpath;
59         if (!GetModuleFileName(NULL, pathbuf, sizeof(wbinpath))) {
60             return apr_get_os_error();
61         }
62         *binpath = apr_pstrdup(p, pathbuf);
63     }
64 #endif
65     return APR_SUCCESS;
66 }
67
68
69 AP_DECLARE(apr_status_t) ap_os_create_privileged_process(
70     const request_rec *r,
71     apr_proc_t *newproc, const char *progname,
72     const char * const *args,
73     const char * const *env,
74     apr_procattr_t *attr, apr_pool_t *p)
75 {
76     return apr_proc_create(newproc, progname, args, env, attr, p);
77 }
78
79
80 /* This code is stolen from misc/win32/misc.c and apr_private.h
81  * This helper code resolves late bound entry points
82  * missing from one or more releases of the Win32 API...
83  * but it sure would be nice if we didn't duplicate this code
84  * from the APR ;-)
85  */
86 static const char* const lateDllName[DLL_defined] = {
87     "kernel32", "advapi32", "mswsock",  "ws2_32"  };
88 static HMODULE lateDllHandle[DLL_defined] = {
89     NULL,       NULL,       NULL,       NULL      };
90
91
92 FARPROC ap_load_dll_func(ap_dlltoken_e fnLib, char* fnName, int ordinal)
93 {
94     if (!lateDllHandle[fnLib]) {
95         lateDllHandle[fnLib] = LoadLibrary(lateDllName[fnLib]);
96         if (!lateDllHandle[fnLib])
97             return NULL;
98     }
99     if (ordinal)
100         return GetProcAddress(lateDllHandle[fnLib], (char *) ordinal);
101     else
102         return GetProcAddress(lateDllHandle[fnLib], fnName);
103 }
104
105
106 /* To share the semaphores with other processes, we need a NULL ACL
107  * Code from MS KB Q106387
108  */
109 PSECURITY_ATTRIBUTES GetNullACL(void)
110 {
111     PSECURITY_DESCRIPTOR pSD;
112     PSECURITY_ATTRIBUTES sa;
113
114     sa  = (PSECURITY_ATTRIBUTES) LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES));
115     sa->nLength = sizeof(SECURITY_ATTRIBUTES);
116
117     pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
118     sa->lpSecurityDescriptor = pSD;
119
120     if (pSD == NULL || sa == NULL) {
121         return NULL;
122     }
123     apr_set_os_error(0);
124     if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)
125         || apr_get_os_error()) {
126         LocalFree( pSD );
127         LocalFree( sa );
128         return NULL;
129     }
130     if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE)
131         || apr_get_os_error()) {
132         LocalFree( pSD );
133         LocalFree( sa );
134         return NULL;
135     }
136
137     sa->bInheritHandle = FALSE;
138     return sa;
139 }
140
141
142 void CleanNullACL(void *sa)
143 {
144     if (sa) {
145         LocalFree(((PSECURITY_ATTRIBUTES)sa)->lpSecurityDescriptor);
146         LocalFree(sa);
147     }
148 }