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 Status = RtlStringCbPrintfW(BaseDefaultPathBuffer, 176 sizeof(BaseDefaultPathBuffer), 177 L".;%wZ;%wZ\\system;%wZ;", 178 &BaseWindowsSystemDirectory, 179 &BaseWindowsDirectory, 180 &BaseWindowsDirectory); 181 if (!NT_SUCCESS(Status)) 182 { 183 DPRINT1("NLS Init failed\n"); 184 return FALSE; 185 } 186 187 BaseDefaultPath.Buffer = BaseDefaultPathBuffer; 188 BaseDefaultPath.Length = (USHORT)wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR); 189 BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer); 190 191 /* Use remaining part of the default path buffer for the append path */ 192 BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length); 193 BaseDefaultPathAppend.Length = 0; 194 BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length; 195 196 /* Initialize command line */ 197 InitCommandLines(); 198 199 /* Initialize the DLL critical section */ 200 RtlInitializeCriticalSection(&BaseDllDirectoryLock); 201 202 /* Initialize the National Language Support routines */ 203 if (!NlsInit()) 204 { 205 DPRINT1("NLS Init failed\n"); 206 return FALSE; 207 } 208 209 /* Initialize Console Support */ 210 if (!ConDllInitialize(dwReason, SessionDir)) 211 { 212 DPRINT1("Failed to set up console\n"); 213 return FALSE; 214 } 215 216 /* Initialize application certification globals */ 217 InitializeListHead(&BasepAppCertDllsList); 218 RtlInitializeCriticalSection(&gcsAppCert); 219 220 /* Insert more dll attach stuff here! */ 221 DllInitialized = TRUE; 222 break; 223 } 224 225 case DLL_PROCESS_DETACH: 226 { 227 if (DllInitialized != FALSE) 228 { 229 /* Uninitialize console support */ 230 ConDllInitialize(dwReason, NULL); 231 232 /* Insert more dll detach stuff here! */ 233 NlsUninit(); 234 235 /* Delete DLL critical section */ 236 RtlDeleteCriticalSection(&BaseDllDirectoryLock); 237 } 238 break; 239 } 240 241 case DLL_THREAD_ATTACH: 242 { 243 /* ConDllInitialize sets the current console locale for the new thread */ 244 return ConDllInitialize(dwReason, NULL); 245 } 246 247 default: 248 break; 249 } 250 251 return TRUE; 252 } 253 254 /* EOF */ 255