1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32/src/dprocess.c
5 * PURPOSE: Process Object
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ws2_32.h>
12
13 /* DATA **********************************************************************/
14
15 PWSPROCESS CurrentWsProcess;
16
17 #define WsProcLock() EnterCriticalSection(&Process->ThreadLock)
18 #define WsProcUnlock() LeaveCriticalSection(&Process->ThreadLock)
19
20 /* FUNCTIONS *****************************************************************/
21
22 INT
23 WSAAPI
WsProcInitialize(IN PWSPROCESS Process)24 WsProcInitialize(IN PWSPROCESS Process)
25 {
26 INT ErrorCode = WSAEFAULT;
27 HKEY RootKey = NULL;
28
29 /* Initialize the thread list lock */
30 InitializeCriticalSection(&Process->ThreadLock);
31 Process->LockReady = TRUE;
32
33 /* Open the Winsock Key */
34 RootKey = WsOpenRegistryRoot();
35
36 /* Create the LP Catalog change event and catalog */
37 Process->ProtocolCatalogEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
38 Process->ProtocolCatalog = WsTcAllocate();
39
40 // FIXME: Check for Process->ProtocolCatalog == NULL
41
42 /* Initialize it */
43 WsTcInitializeFromRegistry(Process->ProtocolCatalog,
44 RootKey,
45 Process->ProtocolCatalogEvent);
46
47 /* Create the NS Catalog change event and catalog */
48 Process->NamespaceCatalogEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
49 Process->NamespaceCatalog = WsNcAllocate();
50
51 // FIXME: Check for Process->NamespaceCatalog == NULL
52
53 /* Initialize it */
54 ErrorCode = WsNcInitializeFromRegistry(Process->NamespaceCatalog,
55 RootKey,
56 Process->NamespaceCatalogEvent);
57
58 /* Close the root key */
59 RegCloseKey(RootKey);
60 return ErrorCode;
61 }
62
63 PWSPROCESS
64 WSAAPI
WsProcAllocate(VOID)65 WsProcAllocate(VOID)
66 {
67 PWSPROCESS Process;
68
69 /* Allocate the structure */
70 Process = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Process));
71 if (Process)
72 {
73 /* Set default non-zero values */
74 Process->Version = MAKEWORD(2,2);
75 }
76
77 /* Return it */
78 return Process;
79 }
80
81 INT
82 WSAAPI
WsProcOpenAsyncHelperDevice(IN PWSPROCESS Process,OUT PHANDLE Handle)83 WsProcOpenAsyncHelperDevice(IN PWSPROCESS Process,
84 OUT PHANDLE Handle)
85 {
86 INT ErrorCode = WSASYSCALLFAILURE;
87
88 /* Lock the process */
89 WsProcLock();
90
91 /* Check if we have a handle, and if not, create one */
92 if ((Process->ApcHelper) ||
93 (WahOpenApcHelper(&Process->ApcHelper) == ERROR_SUCCESS))
94 {
95 /* Return the handle */
96 *Handle = Process->ApcHelper;
97 ErrorCode = ERROR_SUCCESS;
98 }
99
100 /* Unload the process and return */
101 WsProcUnlock();
102 return ErrorCode;
103 }
104
105 INT
106 WSAAPI
WsProcGetAsyncHelper(IN PWSPROCESS Process,OUT PHANDLE Handle)107 WsProcGetAsyncHelper(IN PWSPROCESS Process,
108 OUT PHANDLE Handle)
109 {
110 /* Check if we have it already set up */
111 if (Process->ApcHelper)
112 {
113 /* Just return it */
114 *Handle = Process->ApcHelper;
115 return ERROR_SUCCESS;
116 }
117 else
118 {
119 /* Open it for the first time */
120 return WsProcOpenAsyncHelperDevice(Process, Handle);
121 }
122 }
123
124 INT
125 WSAAPI
WsProcStartup(VOID)126 WsProcStartup(VOID)
127 {
128 INT ErrorCode = WSAEFAULT;
129
130 /* Create a new process */
131 CurrentWsProcess = WsProcAllocate();
132
133 /* Initialize it */
134 if (CurrentWsProcess)
135 {
136 /* Initialize the process */
137 ErrorCode = WsProcInitialize(CurrentWsProcess);
138 }
139 else
140 {
141 /* No memory for the process object */
142 ErrorCode = WSA_NOT_ENOUGH_MEMORY;
143 }
144
145 return ErrorCode;
146 }
147
148 PTCATALOG
149 WSAAPI
WsProcGetTCatalog(IN PWSPROCESS Process)150 WsProcGetTCatalog(IN PWSPROCESS Process)
151 {
152 /* Check if the catalogs have been modified */
153 if (WsCheckCatalogState(Process->ProtocolCatalogEvent))
154 {
155 /* Modification happened, reload them */
156 WsTcRefreshFromRegistry(Process->ProtocolCatalog,
157 Process->ProtocolCatalogEvent);
158 }
159
160 /* Return it */
161 return Process->ProtocolCatalog;
162 }
163
164 PNSCATALOG
165 WSAAPI
WsProcGetNsCatalog(IN PWSPROCESS Process)166 WsProcGetNsCatalog(IN PWSPROCESS Process)
167 {
168 /* Check if the catalogs have been modified */
169 if (WsCheckCatalogState(Process->NamespaceCatalogEvent))
170 {
171 /* Modification happened, reload them */
172 WsNcRefreshFromRegistry(Process->NamespaceCatalog,
173 Process->NamespaceCatalogEvent);
174 }
175
176 /* Return it */
177 return Process->NamespaceCatalog;
178 }
179
180 BOOL
181 WSAAPI
WsProcDetachSocket(IN PWSPROCESS Process,IN PWAH_HANDLE Handle)182 WsProcDetachSocket(IN PWSPROCESS Process,
183 IN PWAH_HANDLE Handle)
184 {
185 PWSSOCKET Socket = (PWSSOCKET)Handle;
186
187 /* Disassociate this socket from the table */
188 WahRemoveHandleContext(WsSockHandleTable, Handle);
189
190 /* If this is isn't an IFS socket */
191 if (!Socket->Provider)
192 {
193 /* Check if we have an active handle helper */
194 if (Process->HandleHelper)
195 {
196 /* Close it */
197 WahCloseSocketHandle(Process->HandleHelper, (SOCKET)Socket->Handle);
198 }
199 }
200
201 /* Remove a reference and return */
202 WsSockDereference(Socket);
203 return TRUE;
204 }
205
206 BOOL
207 WSAAPI
CleanupNamespaceProviders(IN PVOID Callback,IN PNSCATALOG_ENTRY Entry)208 CleanupNamespaceProviders(IN PVOID Callback,
209 IN PNSCATALOG_ENTRY Entry)
210 {
211 PNS_PROVIDER Provider;
212
213 /* Get the provider */
214 Provider = Entry->Provider;
215 if (Provider)
216 {
217 /* Do cleanup */
218 WsNpNSPCleanup(Provider);
219 }
220
221 /* Return success */
222 return TRUE;
223 }
224
225 BOOL
226 WSAAPI
CleanupProtocolProviders(IN PVOID Callback,IN PTCATALOG_ENTRY Entry)227 CleanupProtocolProviders(IN PVOID Callback,
228 IN PTCATALOG_ENTRY Entry)
229 {
230 PTPROVIDER Provider;
231 INT ErrorCode;
232
233 /* Get the provider */
234 Provider = Entry->Provider;
235 if (Provider)
236 {
237 /* Do cleanup */
238 WsTpWSPCleanup(Provider, &ErrorCode);
239 }
240
241 /* Return success */
242 return TRUE;
243 }
244
245 VOID
246 WSAAPI
WsProcDelete(IN PWSPROCESS Process)247 WsProcDelete(IN PWSPROCESS Process)
248 {
249 /* Check if we didn't even initialize yet */
250 if (!Process->LockReady) return;
251
252 /* No more current process */
253 CurrentWsProcess = NULL;
254
255 /* If we have a socket table */
256 if (WsSockHandleTable)
257 {
258 /* Enumerate the sockets with a delete callback */
259 WahEnumerateHandleContexts(WsSockHandleTable,
260 WsSockDeleteSockets,
261 Process);
262 }
263
264 /* Close APC Helper */
265 if (Process->ApcHelper) WahCloseApcHelper(Process->ApcHelper);
266
267 /* Close handle helper */
268 if (Process->HandleHelper) WahCloseHandleHelper(Process->HandleHelper);
269
270 /* Check for notification helper */
271 if (Process->NotificationHelper)
272 {
273 /* Close notification helper */
274 WahCloseNotificationHandleHelper(Process->NotificationHelper);
275 }
276
277 /* Check if we have a protocol catalog*/
278 if (Process->ProtocolCatalog)
279 {
280 /* Enumerate it to clean it up */
281 WsTcEnumerateCatalogItems(Process->ProtocolCatalog,
282 CleanupProtocolProviders,
283 NULL);
284
285 /* Delete it */
286 WsTcDelete(Process->ProtocolCatalog);
287 Process->ProtocolCatalog = NULL;
288 }
289
290 /* Check if we have a namespace catalog*/
291 if (Process->NamespaceCatalog)
292 {
293 /* Enumerate it to clean it up */
294 WsNcEnumerateCatalogItems(Process->NamespaceCatalog,
295 CleanupNamespaceProviders,
296 NULL);
297
298 /* Delete it */
299 WsNcDelete(Process->NamespaceCatalog);
300 Process->NamespaceCatalog = NULL;
301 }
302
303 /* Delete the thread lock */
304 DeleteCriticalSection(&Process->ThreadLock);
305
306 /* Delete us */
307 HeapFree(WsSockHeap, 0, Process);
308 }
309
310 VOID
311 WSAAPI
WsProcSetVersion(IN PWSPROCESS Process,IN WORD VersionRequested)312 WsProcSetVersion(IN PWSPROCESS Process,
313 IN WORD VersionRequested)
314 {
315 WORD Major, Minor;
316 WORD OldMajor, OldMinor;
317
318 /* Get the version data */
319 Major = LOBYTE(VersionRequested);
320 Minor = HIBYTE(VersionRequested);
321 OldMajor = LOBYTE(Process->Version);
322 OldMinor = HIBYTE(Process->Version);
323
324 /* Check if we're going lower */
325 if ((Major < OldMajor) || ((Major == OldMajor) && (Minor < OldMinor)))
326 {
327 /* Set the new version */
328 Process->Version = VersionRequested;
329 }
330 }
331