[KERNEL32] Initial implementation for BaseCheckRunApp, calling into apphelp to check...
[reactos.git] / reactos / dll / win32 / kernel32 / client / dllmain.c
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 == TRUE)
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 */