- Build fixes
[reactos.git] / dll / win32 / mswsock / mswsock / init.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winsock 2 SPI
4 * FILE: lib/mswsock/lib/init.c
5 * PURPOSE: DLL Initialization
6 */
7
8 /* INCLUDES ******************************************************************/
9 #include "msafd.h"
10
11 /* DATA **********************************************************************/
12
13 BOOL SockProcessTerminating;
14 LONG SockProcessPendingAPCCount;
15 HINSTANCE SockModuleHandle;
16
17 /* FUNCTIONS *****************************************************************/
18
19 BOOL
20 WSPAPI
21 MSWSOCK_Initialize(VOID)
22 {
23 SYSTEM_INFO SystemInfo;
24
25 /* If our heap is already initialized, we can skip everything */
26 if (SockAllocateHeapRoutine) return TRUE;
27
28 /* Make sure nobody thinks we're terminating */
29 SockProcessTerminating = FALSE;
30
31 /* Get the system information */
32 GetSystemInfo(&SystemInfo);
33
34 /* Check if this is an MP machine */
35 if (SystemInfo.dwNumberOfProcessors > 1)
36 {
37 /* Use our own heap on MP, to reduce locks */
38 SockAllocateHeapRoutine = SockInitializeHeap;
39 SockPrivateHeap = NULL;
40 }
41 else
42 {
43 /* Use process heap */
44 SockAllocateHeapRoutine = RtlAllocateHeap;
45 SockPrivateHeap = RtlGetProcessHeap();
46 }
47
48 /* Initialize WSM data */
49 gWSM_NSPStartupRef = -1;
50 gWSM_NSPCallRef = 0;
51
52 /* Initialize the helper listhead */
53 InitializeListHead(&SockHelperDllListHead);
54
55 /* Initialize the global lock */
56 SockInitializeRwLockAndSpinCount(&SocketGlobalLock, 1000);
57
58 /* Initialize the socket lock */
59 InitializeCriticalSection(&MSWSOCK_SocketLock);
60
61 /* Initialize RnR locks and other RnR data */
62 Rnr_ProcessInit();
63
64 /* Return success */
65 return TRUE;
66 }
67
68 BOOL
69 APIENTRY
70 DllMain(HANDLE hModule,
71 DWORD dwReason,
72 LPVOID lpReserved)
73 {
74 OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
75 PWINSOCK_TEB_DATA ThreadData;
76
77 /* Check what's going on */
78 switch (dwReason)
79 {
80 /* Process attaching */
81 case DLL_PROCESS_ATTACH:
82
83 /* Save module handles */
84 SockModuleHandle = hModule;
85 NlsMsgSourcemModuleHandle = hModule;
86
87 /* Initialize us */
88 MSWSOCK_Initialize();
89 break;
90
91 /* Detaching */
92 case DLL_PROCESS_DETACH:
93
94 /* Did we initialize yet? */
95 if (!SockAllocateHeapRoutine) break;
96
97 /* Fail all future calls */
98 SockProcessTerminating = TRUE;
99
100 /* Is this a FreeLibrary? */
101 if (!lpReserved)
102 {
103 /* Cleanup RNR */
104 Rnr_ProcessCleanup();
105
106 /* Delete the socket lock */
107 DeleteCriticalSection(&MSWSOCK_SocketLock);
108
109 /* Check if we have an Async Queue Port */
110 if (SockAsyncQueuePort)
111 {
112 /* Unprotect the handle */
113 HandleInfo.ProtectFromClose = FALSE;
114 HandleInfo.Inherit = FALSE;
115 NtSetInformationObject(SockAsyncQueuePort,
116 ObjectHandleFlagInformation,
117 &HandleInfo,
118 sizeof(HandleInfo));
119
120 /* Close it, and clear the port */
121 NtClose(SockAsyncQueuePort);
122 SockAsyncQueuePort = NULL;
123 }
124
125 /* Check if we have a context table */
126 if (SockContextTable)
127 {
128 /* Destroy it */
129 WahDestroyHandleContextTable(SockContextTable);
130 SockContextTable = NULL;
131 }
132
133 /* Delete the global lock as well */
134 SockDeleteRwLock(&SocketGlobalLock);
135
136 /* Check if we have a buffer keytable */
137 if (SockBufferKeyTable)
138 {
139 /* Free it */
140 VirtualFree(SockBufferKeyTable, 0, MEM_RELEASE);
141 }
142 }
143
144 /* Check if we have to a SAN cleanup event */
145 if (SockSanCleanUpCompleteEvent)
146 {
147 /* Close the event handle */
148 CloseHandle(SockSanCleanUpCompleteEvent);
149 }
150
151 /* Thread detaching */
152 case DLL_THREAD_DETACH:
153
154 /* Set the context to NULL for thread detach */
155 if (dwReason == DLL_THREAD_DETACH) lpReserved = NULL;
156
157 /* Check if this is a normal thread detach */
158 if (!lpReserved)
159 {
160 /* Do RnR Thread cleanup */
161 Rnr_ThreadCleanup();
162
163 /* Get thread data */
164 ThreadData = NtCurrentTeb()->WinSockData;
165 if (ThreadData)
166 {
167 /* Check if any APCs are pending */
168 if (ThreadData->PendingAPCs)
169 {
170 /* Save the value */
171 InterlockedExchangeAdd(&SockProcessPendingAPCCount,
172 -(ThreadData->PendingAPCs));
173
174 /* Close the evnet handle */
175 NtClose(ThreadData->EventHandle);
176
177 /* Free the thread data and set it to null */
178 RtlFreeHeap(GetProcessHeap(), 0, (PVOID)ThreadData);
179 NtCurrentTeb()->WinSockData = NULL;
180 }
181 }
182 }
183
184 /* Check if this is a process detach fallthrough */
185 if (dwReason == DLL_PROCESS_DETACH && !lpReserved)
186 {
187 /* Check if we're using a private heap */
188 if (SockPrivateHeap != RtlGetProcessHeap())
189 {
190 /* Destroy it */
191 RtlDestroyHeap(SockPrivateHeap);
192 }
193 SockAllocateHeapRoutine = NULL;
194 }
195 break;
196
197 case DLL_THREAD_ATTACH:
198 break;
199 }
200
201 /* Return */
202 return TRUE;
203 }
204