1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: dll/win32/kernel32/client/dllmain.c 5 * PURPOSE: Initialization 6 * PROGRAMMERS: Ariadne (ariadne@xs4all.nl) 7 * Aleksey Bragin (aleksey@reactos.org) 8 */ 9 10 /* INCLUDES ******************************************************************/ 11 12 #include <k32.h> 13 14 #define NDEBUG 15 #include <debug.h> 16 17 /* GLOBALS *******************************************************************/ 18 19 PBASE_STATIC_SERVER_DATA BaseStaticServerData; 20 BOOLEAN BaseRunningInServerProcess = FALSE; 21 22 WCHAR BaseDefaultPathBuffer[6140]; 23 24 HANDLE BaseNamedObjectDirectory; 25 HMODULE hCurrentModule = NULL; 26 HMODULE kernel32_handle = NULL; 27 PPEB Peb; 28 ULONG SessionId; 29 static BOOL DllInitialized = FALSE; 30 31 /* Critical section for various kernel32 data structures */ 32 RTL_CRITICAL_SECTION BaseDllDirectoryLock; 33 34 extern BOOL FASTCALL NlsInit(VOID); 35 extern VOID FASTCALL NlsUninit(VOID); 36 37 #define WIN_OBJ_DIR L"\\Windows" 38 #define SESSION_DIR L"\\Sessions" 39 40 /* FUNCTIONS *****************************************************************/ 41 42 NTSTATUS 43 NTAPI 44 BaseCreateThreadPoolThread(IN PTHREAD_START_ROUTINE Function, 45 IN PVOID Parameter, 46 OUT PHANDLE ThreadHandle) 47 { 48 NTSTATUS Status; 49 50 /* Create a Win32 thread */ 51 *ThreadHandle = CreateRemoteThread(NtCurrentProcess(), 52 NULL, 53 0, 54 Function, 55 Parameter, 56 CREATE_SUSPENDED, 57 NULL); 58 if (!(*ThreadHandle)) 59 { 60 /* Get the status value if we couldn't get a handle */ 61 Status = NtCurrentTeb()->LastStatusValue; 62 if (NT_SUCCESS(Status)) Status = STATUS_UNSUCCESSFUL; 63 } 64 else 65 { 66 /* Set success code */ 67 Status = STATUS_SUCCESS; 68 } 69 70 /* All done */ 71 return Status; 72 } 73 74 NTSTATUS 75 NTAPI 76 BaseExitThreadPoolThread(IN NTSTATUS ExitStatus) 77 { 78 /* Exit the thread */ 79 ExitThread(ExitStatus); 80 return STATUS_SUCCESS; 81 } 82 83 BOOL 84 WINAPI 85 DllMain(HANDLE hDll, 86 DWORD dwReason, 87 LPVOID lpReserved) 88 { 89 NTSTATUS Status; 90 BASESRV_API_CONNECTINFO ConnectInfo; 91 ULONG ConnectInfoSize = sizeof(ConnectInfo); 92 WCHAR SessionDir[256]; 93 94 DPRINT("DllMain(hInst %p, dwReason %lu)\n", 95 hDll, dwReason); 96 97 Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString; 98 99 /* Cache the PEB and Session ID */ 100 Peb = NtCurrentPeb(); 101 SessionId = Peb->SessionId; 102 103 switch (dwReason) 104 { 105 case DLL_PROCESS_ATTACH: 106 { 107 /* Set no filter initially */ 108 GlobalTopLevelExceptionFilter = RtlEncodePointer(NULL); 109 110 /* Enable the Rtl thread pool and timer queue to use proper Win32 thread */ 111 RtlSetThreadPoolStartFunc(BaseCreateThreadPoolThread, BaseExitThreadPoolThread); 112 113 /* Register the manifest prober routine */ 114 LdrSetDllManifestProber(BasepProbeForDllManifest); 115 116 /* Don't bother us for each thread */ 117 LdrDisableThreadCalloutsForDll((PVOID)hDll); 118 119 /* Initialize default path to NULL */ 120 RtlInitUnicodeString(&BaseDefaultPath, NULL); 121 122 /* Setup the Object Directory path */ 123 if (!SessionId) 124 { 125 /* Use the raw path */ 126 wcscpy(SessionDir, WIN_OBJ_DIR); 127 } 128 else 129 { 130 /* Use the session path */ 131 swprintf(SessionDir, 132 L"%ws\\%ld%ws", 133 SESSION_DIR, 134 SessionId, 135 WIN_OBJ_DIR); 136 } 137 138 /* Connect to the Base Server */ 139 Status = CsrClientConnectToServer(SessionDir, 140 BASESRV_SERVERDLL_INDEX, 141 &ConnectInfo, 142 &ConnectInfoSize, 143 &BaseRunningInServerProcess); 144 if (!NT_SUCCESS(Status)) 145 { 146 DPRINT1("Failed to connect to CSR (Status %lx)\n", Status); 147 NtTerminateProcess(NtCurrentProcess(), Status); 148 return FALSE; 149 } 150 151 /* Get the server data */ 152 ASSERT(Peb->ReadOnlyStaticServerData); 153 BaseStaticServerData = Peb->ReadOnlyStaticServerData[BASESRV_SERVERDLL_INDEX]; 154 ASSERT(BaseStaticServerData); 155 156 /* Check if we are running a CSR Server */ 157 if (!BaseRunningInServerProcess) 158 { 159 /* Set the termination port for the thread */ 160 DPRINT("Creating new thread for CSR\n"); 161 CsrNewThread(); 162 } 163 164 /* Initialize heap handle table */ 165 BaseDllInitializeMemoryManager(); 166 167 /* Set HMODULE for our DLL */ 168 kernel32_handle = hCurrentModule = hDll; 169 170 /* Set the directories */ 171 BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory; 172 BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory; 173 174 /* Construct the default path (using the static buffer) */ 175 _snwprintf(BaseDefaultPathBuffer, 176 sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR), 177 L".;%wZ;%wZ\\system;%wZ;", 178 &BaseWindowsSystemDirectory, 179 &BaseWindowsDirectory, 180 &BaseWindowsDirectory); 181 182 BaseDefaultPath.Buffer = BaseDefaultPathBuffer; 183 BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR); 184 BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer); 185 186 /* Use remaining part of the default path buffer for the append path */ 187 BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length); 188 BaseDefaultPathAppend.Length = 0; 189 BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length; 190 191 /* Initialize command line */ 192 InitCommandLines(); 193 194 /* Initialize the DLL critical section */ 195 RtlInitializeCriticalSection(&BaseDllDirectoryLock); 196 197 /* Initialize the National Language Support routines */ 198 if (!NlsInit()) 199 { 200 DPRINT1("NLS Init failed\n"); 201 return FALSE; 202 } 203 204 /* Initialize Console Support */ 205 if (!ConDllInitialize(dwReason, SessionDir)) 206 { 207 DPRINT1("Failed to set up console\n"); 208 return FALSE; 209 } 210 211 /* Initialize application certification globals */ 212 InitializeListHead(&BasepAppCertDllsList); 213 RtlInitializeCriticalSection(&gcsAppCert); 214 215 /* Insert more dll attach stuff here! */ 216 DllInitialized = TRUE; 217 break; 218 } 219 220 case DLL_PROCESS_DETACH: 221 { 222 if (DllInitialized != FALSE) 223 { 224 /* Uninitialize console support */ 225 ConDllInitialize(dwReason, NULL); 226 227 /* Insert more dll detach stuff here! */ 228 NlsUninit(); 229 230 /* Delete DLL critical section */ 231 RtlDeleteCriticalSection(&BaseDllDirectoryLock); 232 } 233 break; 234 } 235 236 case DLL_THREAD_ATTACH: 237 { 238 /* ConDllInitialize sets the current console locale for the new thread */ 239 return ConDllInitialize(dwReason, NULL); 240 } 241 242 default: 243 break; 244 } 245 246 return TRUE; 247 } 248 249 /* EOF */ 250