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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "apr_private.h"
18 #include "apr_general.h"
19 #include "apr_pools.h"
20 #include "apr_signal.h"
23 #include "apr_arch_misc.h" /* for WSAHighByte / WSALowByte */
25 #include "apr_arch_file_io.h" /* bring in unicode-ness */
26 #include "apr_arch_threadproc.h" /* bring in apr_threadproc_init */
30 /* This symbol is _private_, although it must be exported.
32 int APR_DECLARE_DATA apr_app_init_complete = 0;
34 #if !defined(_WIN32_WCE)
35 /* Used by apr_app_initialize to reprocess the environment
37 * An internal apr function to convert a double-null terminated set
38 * of single-null terminated strings from wide Unicode to narrow utf-8
39 * as a list of strings. These are allocated from the MSVCRT's
40 * _CRT_BLOCK to trick the system into trusting our store.
42 static int warrsztoastr(const char * const * *retarr,
43 const wchar_t * arrsz, int args)
45 const apr_wchar_t *wch;
53 for (args = 1, wch = arrsz; wch[0] || wch[1]; ++wch)
57 wsize = 1 + wch - arrsz;
59 newarr = _malloc_dbg((args + 1) * sizeof(char *),
60 _CRT_BLOCK, __FILE__, __LINE__);
62 /* This is a safe max allocation, we will realloc after
63 * processing and return the excess to the free store.
64 * 3 ucs bytes hold any single wchar_t value (16 bits)
65 * 4 ucs bytes will hold a wchar_t pair value (20 bits)
67 newlen = totlen = wsize * 3 + 1;
68 newarr[0] = _malloc_dbg(newlen * sizeof(char),
69 _CRT_BLOCK, __FILE__, __LINE__);
71 (void)apr_conv_ucs2_to_utf8(arrsz, &wsize,
74 assert(newlen && !wsize);
75 /* Return to the free store if the heap realloc is the least bit optimized
77 newarr[0] = _realloc_dbg(newarr[0], totlen - newlen,
78 _CRT_BLOCK, __FILE__, __LINE__);
80 for (arg = 1; arg < args; ++arg) {
81 newarr[arg] = newarr[arg - 1] + 2;
82 while (*(newarr[arg]++)) {
94 /* Reprocess the arguments to main() for a completely apr-ized application
97 APR_DECLARE(apr_status_t) apr_app_initialize(int *argc,
98 const char * const * *argv,
99 const char * const * *env)
101 apr_status_t rv = apr_initialize();
103 if (rv != APR_SUCCESS) {
107 #if defined(_WIN32_WCE)
108 apr_app_init_complete = 1;
109 #elif APR_HAS_UNICODE_FS
117 if (apr_app_init_complete) {
121 apr_app_init_complete = 1;
123 sysstr = GetCommandLineW();
125 wstrs = CommandLineToArgvW(sysstr, &wstrc);
127 *argc = apr_wastrtoastr(argv, wstrs, wstrc);
132 sysstr = GetEnvironmentStringsW();
133 dupenv = warrsztoastr(&_environ, sysstr, -1);
136 *env = _malloc_dbg((dupenv + 1) * sizeof (char *),
137 _CRT_BLOCK, __FILE__, __LINE__ );
138 memcpy((void*)*env, _environ, (dupenv + 1) * sizeof (char *));
143 FreeEnvironmentStringsW(sysstr);
145 /* MSVCRT will attempt to maintain the wide environment calls
146 * on _putenv(), which is bogus if we've passed a non-ascii
147 * string to _putenv(), since they use MultiByteToWideChar
148 * and breaking the implicit utf-8 assumption we've built.
150 * Reset _wenviron for good measure.
153 apr_wchar_t **wenv = _wenviron;
163 static int initialized = 0;
165 /* Provide to win32/thread.c */
166 extern DWORD tls_apr_thread;
168 APR_DECLARE(apr_status_t) apr_initialize(void)
172 int iVersionRequested;
181 /* Initialize apr_os_level global */
182 if (apr_get_oslevel(&osver) != APR_SUCCESS) {
186 tls_apr_thread = TlsAlloc();
187 if ((status = apr_pool_initialize()) != APR_SUCCESS)
190 if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
194 apr_pool_tag(pool, "apr_initialize");
196 iVersionRequested = MAKEWORD(WSAHighByte, WSALowByte);
197 err = WSAStartup((WORD) iVersionRequested, &wsaData);
201 if (LOBYTE(wsaData.wVersion) != WSAHighByte ||
202 HIBYTE(wsaData.wVersion) != WSALowByte) {
207 apr_signal_init(pool);
209 apr_threadproc_init(pool);
214 APR_DECLARE_NONSTD(void) apr_terminate(void)
220 apr_pool_terminate();
224 TlsFree(tls_apr_thread);
227 APR_DECLARE(void) apr_terminate2(void)