xref: /reactos/dll/win32/ws2_32/src/dprocess.c (revision 50cf16b3)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS WinSock 2 API
4  * FILE:        dll/win32/ws2_32_new/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
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
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
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
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
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
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
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
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
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
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
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
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