• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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