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