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.h"
18 #include "apr_general.h"
19 #include "apr_pools.h"
20 #include "apr_signal.h"
21
22 #include "apr_arch_misc.h" /* for WSAHighByte / WSALowByte */
23 #include "apr_arch_proc_mutex.h" /* for apr_proc_mutex_unix_setup_lock() */
24 #include "apr_arch_internal_time.h"
25 #include "apr_ldap.h" /* for apr_ldap_rebind_init() */
26
27 #ifdef USE_WINSOCK
28 /* Prototypes missing from older NDKs */
29 int WSAStartupRTags(WORD wVersionRequested,
30 LPWSADATA lpWSAData,
31 rtag_t WSAStartupRTag,
32 rtag_t WSPSKTRTag,
33 rtag_t lookUpServiceBeginRTag,
34 rtag_t WSAEventRTag,
35 rtag_t WSPCPRTag);
36
37 int WSACleanupRTag(rtag_t rTag);
38
39 /*
40 ** Resource tag signatures for using NetWare WinSock 2. These will no longer
41 ** be needed by anyone once the new WSAStartupWithNlmHandle() is available
42 ** since WinSock will make the calls to AllocateResourceTag().
43 */
44 #define WS_LOAD_ENTRY_SIGNATURE (*(unsigned long *) "WLDE")
45 #define WS_SKT_SIGNATURE (*(unsigned long *) "WSKT")
46 #define WS_LOOKUP_SERVICE_SIGNATURE (*(unsigned long *) "WLUP")
47 #define WS_WSAEVENT_SIGNATURE (*(unsigned long *) "WEVT")
48 #define WS_CPORT_SIGNATURE (*(unsigned long *) "WCPT")
49
50
51 int (*WSAStartupWithNLMHandle)( WORD version, LPWSADATA data, void *handle ) = NULL;
52 int (*WSACleanupWithNLMHandle)( void *handle ) = NULL;
53
wsa_startup_with_handle(WORD wVersionRequested,LPWSADATA data,void * handle)54 static int wsa_startup_with_handle (WORD wVersionRequested, LPWSADATA data, void *handle)
55 {
56 APP_DATA *app_data;
57
58 if (!(app_data = (APP_DATA*) get_app_data(gLibId)))
59 return APR_EGENERAL;
60
61 app_data->gs_startup_rtag = AllocateResourceTag(handle, "WinSock Start-up", WS_LOAD_ENTRY_SIGNATURE);
62 app_data->gs_socket_rtag = AllocateResourceTag(handle, "WinSock socket()", WS_SKT_SIGNATURE);
63 app_data->gs_lookup_rtag = AllocateResourceTag(handle, "WinSock Look-up", WS_LOOKUP_SERVICE_SIGNATURE);
64 app_data->gs_event_rtag = AllocateResourceTag(handle, "WinSock Event", WS_WSAEVENT_SIGNATURE);
65 app_data->gs_pcp_rtag = AllocateResourceTag(handle, "WinSock C-Port", WS_CPORT_SIGNATURE);
66
67 return WSAStartupRTags(wVersionRequested, data,
68 app_data->gs_startup_rtag,
69 app_data->gs_socket_rtag,
70 app_data->gs_lookup_rtag,
71 app_data->gs_event_rtag,
72 app_data->gs_pcp_rtag);
73 }
74
wsa_cleanup_with_handle(void * handle)75 static int wsa_cleanup_with_handle (void *handle)
76 {
77 APP_DATA *app_data;
78
79 if (!(app_data = (APP_DATA*) get_app_data(gLibId)))
80 return APR_EGENERAL;
81
82 return WSACleanupRTag(app_data->gs_startup_rtag);
83 }
84
UnregisterAppWithWinSock(void * nlm_handle)85 static int UnregisterAppWithWinSock (void *nlm_handle)
86 {
87 if (!WSACleanupWithNLMHandle)
88 {
89 if (!(WSACleanupWithNLMHandle = ImportPublicObject(gLibHandle, "WSACleanupWithNLMHandle")))
90 WSACleanupWithNLMHandle = wsa_cleanup_with_handle;
91 }
92
93 return (*WSACleanupWithNLMHandle)(nlm_handle);
94 }
95
RegisterAppWithWinSock(void * nlm_handle)96 static int RegisterAppWithWinSock (void *nlm_handle)
97 {
98 int err;
99 WSADATA wsaData;
100 WORD wVersionRequested = MAKEWORD(WSAHighByte, WSALowByte);
101
102 if (!WSAStartupWithNLMHandle)
103 {
104 if (!(WSAStartupWithNLMHandle = ImportPublicObject(gLibHandle, "WSAStartupWithNLMHandle")))
105 WSAStartupWithNLMHandle = wsa_startup_with_handle;
106 }
107
108 err = (*WSAStartupWithNLMHandle)(wVersionRequested, &wsaData, nlm_handle);
109
110 if (LOBYTE(wsaData.wVersion) != WSAHighByte ||
111 HIBYTE(wsaData.wVersion) != WSALowByte) {
112
113 UnregisterAppWithWinSock (nlm_handle);
114 return APR_EEXIST;
115 }
116
117 return err;
118 }
119 #endif
120
121
122
apr_app_initialize(int * argc,const char * const ** argv,const char * const ** env)123 APR_DECLARE(apr_status_t) apr_app_initialize(int *argc,
124 const char * const * *argv,
125 const char * const * *env)
126 {
127 /* An absolute noop. At present, only Win32 requires this stub, but it's
128 * required in order to move command arguments passed through the service
129 * control manager into the process, and it's required to fix the char*
130 * data passed in from win32 unicode into utf-8, win32's apr internal fmt.
131 */
132 return apr_initialize();
133 }
134
apr_initialize(void)135 APR_DECLARE(apr_status_t) apr_initialize(void)
136 {
137 apr_pool_t *pool;
138 void *nlmhandle = getnlmhandle();
139
140 /* Register the NLM as using APR. If it is already
141 registered then just return. */
142 if (register_NLM(nlmhandle) != 0) {
143 return APR_SUCCESS;
144 }
145
146 /* apr_pool_initialize() is being called from the library
147 startup code since all of the memory resources belong
148 to the library rather than the application. */
149
150 if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
151 return APR_ENOPOOL;
152 }
153
154 apr_pool_tag(pool, "apr_initilialize");
155
156 #ifdef USE_WINSOCK
157 {
158 int err;
159 if ((err = RegisterAppWithWinSock (nlmhandle))) {
160 return err;
161 }
162 }
163 #endif
164
165 apr_signal_init(pool);
166 #if APR_HAS_LDAP
167 apr_ldap_rebind_init(pool);
168 #endif
169
170 return APR_SUCCESS;
171 }
172
apr_terminate(void)173 APR_DECLARE_NONSTD(void) apr_terminate(void)
174 {
175 APP_DATA *app_data;
176
177 /* Get our instance data for shutting down. */
178 if (!(app_data = (APP_DATA*) get_app_data(gLibId)))
179 return;
180
181 /* Unregister the NLM. If it is not registered
182 then just return. */
183 if (unregister_NLM(app_data->gs_nlmhandle) != 0) {
184 return;
185 }
186
187 /* apr_pool_terminate() is being called from the
188 library shutdown code since the memory resources
189 belong to the library rather than the application */
190
191 /* Just clean up the memory for the app that is going
192 away. */
193 netware_pool_proc_cleanup ();
194
195 #ifdef USE_WINSOCK
196 UnregisterAppWithWinSock (app_data->gs_nlmhandle);
197 #endif
198 }
199
apr_terminate2(void)200 APR_DECLARE(void) apr_terminate2(void)
201 {
202 apr_terminate();
203 }
204