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
8 /* INCLUDES ******************************************************************/
11 /* DATA **********************************************************************/
13 BOOL SockProcessTerminating
;
14 LONG SockProcessPendingAPCCount
;
15 HINSTANCE SockModuleHandle
;
17 /* FUNCTIONS *****************************************************************/
21 MSWSOCK_Initialize(VOID
)
23 SYSTEM_INFO SystemInfo
;
25 /* If our heap is already initialized, we can skip everything */
26 if (SockAllocateHeapRoutine
) return TRUE
;
28 /* Make sure nobody thinks we're terminating */
29 SockProcessTerminating
= FALSE
;
31 /* Get the system information */
32 GetSystemInfo(&SystemInfo
);
34 /* Check if this is an MP machine */
35 if (SystemInfo
.dwNumberOfProcessors
> 1)
37 /* Use our own heap on MP, to reduce locks */
38 SockAllocateHeapRoutine
= SockInitializeHeap
;
39 SockPrivateHeap
= NULL
;
43 /* Use process heap */
44 SockAllocateHeapRoutine
= RtlAllocateHeap
;
45 SockPrivateHeap
= RtlGetProcessHeap();
48 /* Initialize WSM data */
49 gWSM_NSPStartupRef
= -1;
52 /* Initialize the helper listhead */
53 InitializeListHead(&SockHelperDllListHead
);
55 /* Initialize the global lock */
56 SockInitializeRwLockAndSpinCount(&SocketGlobalLock
, 1000);
58 /* Initialize the socket lock */
59 InitializeCriticalSection(&MSWSOCK_SocketLock
);
61 /* Initialize RnR locks and other RnR data */
70 DllMain(HANDLE hModule
,
74 OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
;
75 PWINSOCK_TEB_DATA ThreadData
;
77 /* Check what's going on */
80 /* Process attaching */
81 case DLL_PROCESS_ATTACH
:
83 /* Save module handles */
84 SockModuleHandle
= hModule
;
85 NlsMsgSourcemModuleHandle
= hModule
;
92 case DLL_PROCESS_DETACH
:
94 /* Did we initialize yet? */
95 if (!SockAllocateHeapRoutine
) break;
97 /* Fail all future calls */
98 SockProcessTerminating
= TRUE
;
100 /* Is this a FreeLibrary? */
104 Rnr_ProcessCleanup();
106 /* Delete the socket lock */
107 DeleteCriticalSection(&MSWSOCK_SocketLock
);
109 /* Check if we have an Async Queue Port */
110 if (SockAsyncQueuePort
)
112 /* Unprotect the handle */
113 HandleInfo
.ProtectFromClose
= FALSE
;
114 HandleInfo
.Inherit
= FALSE
;
115 NtSetInformationObject(SockAsyncQueuePort
,
116 ObjectHandleFlagInformation
,
120 /* Close it, and clear the port */
121 NtClose(SockAsyncQueuePort
);
122 SockAsyncQueuePort
= NULL
;
125 /* Check if we have a context table */
126 if (SockContextTable
)
129 WahDestroyHandleContextTable(SockContextTable
);
130 SockContextTable
= NULL
;
133 /* Delete the global lock as well */
134 SockDeleteRwLock(&SocketGlobalLock
);
136 /* Check if we have a buffer keytable */
137 if (SockBufferKeyTable
)
140 VirtualFree(SockBufferKeyTable
, 0, MEM_RELEASE
);
144 /* Check if we have to a SAN cleanup event */
145 if (SockSanCleanUpCompleteEvent
)
147 /* Close the event handle */
148 CloseHandle(SockSanCleanUpCompleteEvent
);
151 /* Thread detaching */
152 case DLL_THREAD_DETACH
:
154 /* Set the context to NULL for thread detach */
155 if (dwReason
== DLL_THREAD_DETACH
) lpReserved
= NULL
;
157 /* Check if this is a normal thread detach */
160 /* Do RnR Thread cleanup */
163 /* Get thread data */
164 ThreadData
= NtCurrentTeb()->WinSockData
;
167 /* Check if any APCs are pending */
168 if (ThreadData
->PendingAPCs
)
171 InterlockedExchangeAdd(&SockProcessPendingAPCCount
,
172 -(ThreadData
->PendingAPCs
));
174 /* Close the evnet handle */
175 NtClose(ThreadData
->EventHandle
);
177 /* Free the thread data and set it to null */
178 RtlFreeHeap(GetProcessHeap(), 0, (PVOID
)ThreadData
);
179 NtCurrentTeb()->WinSockData
= NULL
;
184 /* Check if this is a process detach fallthrough */
185 if (dwReason
== DLL_PROCESS_DETACH
&& !lpReserved
)
187 /* Check if we're using a private heap */
188 if (SockPrivateHeap
!= RtlGetProcessHeap())
191 RtlDestroyHeap(SockPrivateHeap
);
193 SockAllocateHeapRoutine
= NULL
;
197 case DLL_THREAD_ATTACH
: