2b0e9aedb29c6f4833e61cc0b237763788c04586
[reactos.git] / subsystems / win / basesrv / init.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS/Win32 Base enviroment Subsystem Server
4 * FILE: subsystems/win/basesrv/init.c
5 * PURPOSE: Initialization
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "basesrv.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* GLOBALS ********************************************************************/
17
18 HANDLE BaseSrvDllInstance = NULL;
19
20 /* Memory */
21 HANDLE BaseSrvHeap = NULL; // Our own heap.
22 HANDLE BaseSrvSharedHeap = NULL; // Shared heap with CSR. (CsrSrvSharedSectionHeap)
23 PBASE_STATIC_SERVER_DATA BaseStaticServerData = NULL; // Data that we can share amongst processes. Initialized inside BaseSrvSharedHeap.
24
25 // Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
26 PCSR_API_ROUTINE BaseServerApiDispatchTable[BasepMaxApiNumber] =
27 {
28 BaseSrvCreateProcess,
29 BaseSrvCreateThread,
30 BaseSrvGetTempFile,
31 BaseSrvExitProcess,
32 // BaseSrvDebugProcess,
33 // BaseSrvCheckVDM,
34 // BaseSrvUpdateVDMEntry,
35 // BaseSrvGetNextVDMCommand,
36 // BaseSrvExitVDM,
37 // BaseSrvIsFirstVDM,
38 // BaseSrvGetVDMExitCode,
39 // BaseSrvSetReenterCount,
40 BaseSrvSetProcessShutdownParam,
41 BaseSrvGetProcessShutdownParam,
42 // BaseSrvNlsSetUserInfo,
43 // BaseSrvNlsSetMultipleUserInfo,
44 // BaseSrvNlsCreateSection,
45 // BaseSrvSetVDMCurDirs,
46 // BaseSrvGetVDMCurDirs,
47 // BaseSrvBatNotification,
48 // BaseSrvRegisterWowExec,
49 BaseSrvSoundSentryNotification,
50 // BaseSrvRefreshIniFileMapping,
51 BaseSrvDefineDosDevice,
52 // BaseSrvSetTermsrvAppInstallMode,
53 // BaseSrvNlsUpdateCacheCount,
54 // BaseSrvSetTermsrvClientTimeZone,
55 // BaseSrvSxsCreateActivationContext,
56 // BaseSrvRegisterThread,
57 // BaseSrvNlsGetUserInfo,
58 };
59
60 BOOLEAN BaseServerApiServerValidTable[BasepMaxApiNumber] =
61 {
62 TRUE, // BaseSrvCreateProcess
63 TRUE, // BaseSrvCreateThread
64 TRUE, // BaseSrvGetTempFile
65 FALSE, // BaseSrvExitProcess
66 // FALSE, // BaseSrvDebugProcess
67 // TRUE, // BaseSrvCheckVDM
68 // TRUE, // BaseSrvUpdateVDMEntry
69 // TRUE, // BaseSrvGetNextVDMCommand
70 // TRUE, // BaseSrvExitVDM
71 // TRUE, // BaseSrvIsFirstVDM
72 // TRUE, // BaseSrvGetVDMExitCode
73 // TRUE, // BaseSrvSetReenterCount
74 TRUE, // BaseSrvSetProcessShutdownParam
75 TRUE, // BaseSrvGetProcessShutdownParam
76 // TRUE, // BaseSrvNlsSetUserInfo
77 // TRUE, // BaseSrvNlsSetMultipleUserInfo
78 // TRUE, // BaseSrvNlsCreateSection
79 // TRUE, // BaseSrvSetVDMCurDirs
80 // TRUE, // BaseSrvGetVDMCurDirs
81 // TRUE, // BaseSrvBatNotification
82 // TRUE, // BaseSrvRegisterWowExec
83 TRUE, // BaseSrvSoundSentryNotification
84 // TRUE, // BaseSrvRefreshIniFileMapping
85 TRUE, // BaseSrvDefineDosDevice
86 // FALSE, // BaseSrvSetTermsrvAppInstallMode
87 // FALSE, // BaseSrvNlsUpdateCacheCount
88 // FALSE, // BaseSrvSetTermsrvClientTimeZone
89 // FALSE, // BaseSrvSxsCreateActivationContext
90 // FALSE, // BaseSrvRegisterThread
91 // FALSE, // BaseSrvNlsGetUserInfo
92 };
93
94 PCHAR BaseServerApiNameTable[BasepMaxApiNumber] =
95 {
96 "BaseCreateProcess",
97 "BaseCreateThread",
98 "BaseGetTempFile",
99 "BaseExitProcess",
100 // "BaseDebugProcess",
101 // "BaseCheckVDM",
102 // "BaseUpdateVDMEntry",
103 // "BaseGetNextVDMCommand",
104 // "BaseExitVDM",
105 // "BaseIsFirstVDM",
106 // "BaseGetVDMExitCode",
107 // "BaseSetReenterCount",
108 "BaseSetProcessShutdownParam",
109 "BaseGetProcessShutdownParam",
110 // "BaseNlsSetUserInfo",
111 // "BaseNlsSetMultipleUserInfo",
112 // "BaseNlsCreateSection",
113 // "BaseSetVDMCurDirs",
114 // "BaseGetVDMCurDirs",
115 // "BaseBatNotification",
116 // "BaseRegisterWowExec",
117 "BaseSoundSentryNotification",
118 // "BaseRefreshIniFileMapping",
119 "BaseDefineDosDevice",
120 // "BaseSetTermsrvAppInstallMode",
121 // "BaseNlsUpdateCacheCount",
122 // "BaseSetTermsrvClientTimeZone",
123 // "BaseSxsCreateActivationContext",
124 // "BaseRegisterThread",
125 // "BaseNlsGetUserInfo",
126 };
127
128
129 /* FUNCTIONS ******************************************************************/
130
131 NTSTATUS
132 NTAPI
133 CreateBaseAcls(OUT PACL* Dacl,
134 OUT PACL* RestrictedDacl)
135 {
136 PSID SystemSid, WorldSid, RestrictedSid;
137 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
138 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
139 NTSTATUS Status;
140 // UCHAR KeyValueBuffer[0x40];
141 // PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
142 // UNICODE_STRING KeyName;
143 // ULONG ProtectionMode = 0;
144 ULONG AclLength; // , ResultLength;
145 // HANDLE hKey;
146 // OBJECT_ATTRIBUTES ObjectAttributes;
147
148 /* Open the Session Manager Key */
149 /*
150 RtlInitUnicodeString(&KeyName, SM_REG_KEY);
151 InitializeObjectAttributes(&ObjectAttributes,
152 &KeyName,
153 OBJ_CASE_INSENSITIVE,
154 NULL,
155 NULL);
156 Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
157 if (NT_SUCCESS(Status))
158 {
159 /\* Read the key value *\/
160 RtlInitUnicodeString(&KeyName, L"ProtectionMode");
161 Status = NtQueryValueKey(hKey,
162 &KeyName,
163 KeyValuePartialInformation,
164 KeyValueBuffer,
165 sizeof(KeyValueBuffer),
166 &ResultLength);
167
168 /\* Make sure it's what we expect it to be *\/
169 KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
170 if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
171 (*(PULONG)KeyValuePartialInfo->Data))
172 {
173 /\* Save the Protection Mode *\/
174 // ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
175 }
176
177 /\* Close the handle *\/
178 NtClose(hKey);
179 }
180 */
181
182 /* Allocate the System SID */
183 Status = RtlAllocateAndInitializeSid(&NtAuthority,
184 1, SECURITY_LOCAL_SYSTEM_RID,
185 0, 0, 0, 0, 0, 0, 0,
186 &SystemSid);
187 ASSERT(NT_SUCCESS(Status));
188
189 /* Allocate the World SID */
190 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
191 1, SECURITY_WORLD_RID,
192 0, 0, 0, 0, 0, 0, 0,
193 &WorldSid);
194 ASSERT(NT_SUCCESS(Status));
195
196 /* Allocate the restricted SID */
197 Status = RtlAllocateAndInitializeSid(&NtAuthority,
198 1, SECURITY_RESTRICTED_CODE_RID,
199 0, 0, 0, 0, 0, 0, 0,
200 &RestrictedSid);
201 ASSERT(NT_SUCCESS(Status));
202
203 /* Allocate one ACL with 3 ACEs each for one SID */
204 AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
205 RtlLengthSid(SystemSid) +
206 RtlLengthSid(RestrictedSid) +
207 RtlLengthSid(WorldSid);
208 *Dacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
209 ASSERT(*Dacl != NULL);
210
211 /* Set the correct header fields */
212 Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2);
213 ASSERT(NT_SUCCESS(Status));
214
215 /* Give the appropriate rights to each SID */
216 /* FIXME: Should check SessionId/ProtectionMode */
217 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
218 ASSERT(NT_SUCCESS(Status));
219 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
220 ASSERT(NT_SUCCESS(Status));
221 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
222 ASSERT(NT_SUCCESS(Status));
223
224 /* Now allocate the restricted DACL */
225 *RestrictedDacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
226 ASSERT(*RestrictedDacl != NULL);
227
228 /* Initialize it */
229 Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2);
230 ASSERT(NT_SUCCESS(Status));
231
232 /* And add the same ACEs as before */
233 /* FIXME: Not really fully correct */
234 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
235 ASSERT(NT_SUCCESS(Status));
236 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
237 ASSERT(NT_SUCCESS(Status));
238 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
239 ASSERT(NT_SUCCESS(Status));
240
241 /* The SIDs are captured, can free them now */
242 RtlFreeHeap(BaseSrvHeap, 0, SystemSid);
243 RtlFreeHeap(BaseSrvHeap, 0, WorldSid);
244 RtlFreeHeap(BaseSrvHeap, 0, RestrictedSid);
245 return Status;
246 }
247
248 VOID
249 NTAPI
250 BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll)
251 {
252 NTSTATUS Status;
253 WCHAR Buffer[MAX_PATH];
254 PWCHAR HeapBuffer;
255 UNICODE_STRING SystemRootString;
256 UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
257 UNICODE_STRING BaseSrvCSDString;
258 UNICODE_STRING BaseSrvWindowsDirectory;
259 UNICODE_STRING BaseSrvWindowsSystemDirectory;
260 UNICODE_STRING BnoString;
261 OBJECT_ATTRIBUTES ObjectAttributes;
262 ULONG SessionId;
263 HANDLE BaseSrvNamedObjectDirectory;
264 HANDLE BaseSrvRestrictedObjectDirectory;
265 PACL BnoDacl, BnoRestrictedDacl;
266 PSECURITY_DESCRIPTOR BnoSd;
267 HANDLE SymHandle;
268 UNICODE_STRING DirectoryName, SymlinkName;
269 ULONG LuidEnabled;
270 RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] =
271 {
272 {
273 NULL,
274 RTL_QUERY_REGISTRY_DIRECT,
275 L"CSDVersion",
276 &BaseSrvCSDString,
277 REG_NONE, NULL, 0
278 },
279
280 {0}
281 };
282
283 /* Initialize the memory */
284 BaseSrvHeap = RtlGetProcessHeap(); // Initialize our own heap.
285 BaseSrvSharedHeap = LoadedServerDll->SharedSection; // Get the CSR shared heap.
286
287 /* Get the session ID */
288 SessionId = NtCurrentPeb()->SessionId;
289
290 /* Get the Windows directory */
291 RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer));
292 Status = RtlExpandEnvironmentStrings_U(NULL,
293 &UnexpandedSystemRootString,
294 &SystemRootString,
295 NULL);
296 ASSERT(NT_SUCCESS(Status));
297
298 /* Create the base directory */
299 Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL;
300 Status = RtlCreateUnicodeString(&BaseSrvWindowsDirectory,
301 SystemRootString.Buffer);
302 ASSERT(NT_SUCCESS(Status));
303
304 /* Create the system directory */
305 wcscat(SystemRootString.Buffer, L"\\System32");
306 Status = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory,
307 SystemRootString.Buffer);
308 ASSERT(NT_SUCCESS(Status));
309
310 /* FIXME: Check Session ID */
311 wcscpy(Buffer, L"\\BaseNamedObjects");
312 RtlInitUnicodeString(&BnoString, Buffer);
313
314 /* Allocate the server data */
315 BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap,
316 HEAP_ZERO_MEMORY,
317 sizeof(BASE_STATIC_SERVER_DATA));
318 ASSERT(BaseStaticServerData != NULL);
319
320 /* Process timezone information */
321 BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
322 BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
323 Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
324 &BaseStaticServerData->TimeOfDay,
325 sizeof(BaseStaticServerData->TimeOfDay),
326 NULL);
327 ASSERT(NT_SUCCESS(Status));
328
329 /* Make a shared heap copy of the Windows directory */
330 BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
331 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
332 0,
333 BaseSrvWindowsDirectory.MaximumLength);
334 ASSERT(HeapBuffer);
335 RtlCopyMemory(HeapBuffer,
336 BaseStaticServerData->WindowsDirectory.Buffer,
337 BaseSrvWindowsDirectory.MaximumLength);
338 BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;
339
340 /* Make a shared heap copy of the System directory */
341 BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
342 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
343 0,
344 BaseSrvWindowsSystemDirectory.MaximumLength);
345 ASSERT(HeapBuffer);
346 RtlCopyMemory(HeapBuffer,
347 BaseStaticServerData->WindowsSystemDirectory.Buffer,
348 BaseSrvWindowsSystemDirectory.MaximumLength);
349 BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;
350
351 /* This string is not used */
352 RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
353 NULL,
354 0);
355
356 /* Make a shared heap copy of the BNO directory */
357 BaseStaticServerData->NamedObjectDirectory = BnoString;
358 BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
359 sizeof(UNICODE_NULL);
360 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
361 0,
362 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
363 ASSERT(HeapBuffer);
364 RtlCopyMemory(HeapBuffer,
365 BaseStaticServerData->NamedObjectDirectory.Buffer,
366 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
367 BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;
368
369 /*
370 * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
371 * and MaximumLength of the CSD String, since the same UNICODE_STRING is
372 * being queried twice, the first time as a ULONG!
373 *
374 * Somehow, in Windows this doesn't cause a buffer overflow, but it might
375 * in ReactOS, so this code is disabled until someone figures out WTF.
376 */
377 BaseStaticServerData->CSDNumber = 0;
378 BaseStaticServerData->RCNumber = 0;
379
380 /* Initialize the CSD string and query its value from the registry */
381 RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
382 Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
383 L"",
384 BaseServerRegistryConfigurationTable,
385 NULL,
386 NULL);
387 if (NT_SUCCESS(Status))
388 {
389 /* Copy into the shared buffer */
390 wcsncpy(BaseStaticServerData->CSDVersion,
391 BaseSrvCSDString.Buffer,
392 BaseSrvCSDString.Length / sizeof(WCHAR));
393 }
394 else
395 {
396 /* NULL-terminate to indicate nothing is there */
397 BaseStaticServerData->CSDVersion[0] = UNICODE_NULL;
398 }
399
400 /* Cache the system information */
401 Status = NtQuerySystemInformation(SystemBasicInformation,
402 &BaseStaticServerData->SysInfo,
403 sizeof(BaseStaticServerData->SysInfo),
404 NULL);
405 ASSERT(NT_SUCCESS(Status));
406
407 /* FIXME: Should query the registry for these */
408 BaseStaticServerData->DefaultSeparateVDM = FALSE;
409 BaseStaticServerData->IsWowTaskReady = FALSE;
410
411 /* Allocate a security descriptor and create it */
412 BnoSd = RtlAllocateHeap(BaseSrvHeap, 0, 1024);
413 ASSERT(BnoSd);
414 Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION);
415 ASSERT(NT_SUCCESS(Status));
416
417 /* Create the BNO and \Restricted DACLs */
418 Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl);
419 ASSERT(NT_SUCCESS(Status));
420
421 /* Set the BNO DACL as active for now */
422 Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE);
423 ASSERT(NT_SUCCESS(Status));
424
425 /* Create the BNO directory */
426 RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
427 InitializeObjectAttributes(&ObjectAttributes,
428 &BnoString,
429 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
430 NULL,
431 BnoSd);
432 Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory,
433 DIRECTORY_ALL_ACCESS,
434 &ObjectAttributes);
435 ASSERT(NT_SUCCESS(Status));
436
437 /* Check if we are session 0 */
438 if (SessionId == 0)
439 {
440 /* Mark this as a session 0 directory */
441 Status = NtSetInformationObject(BaseSrvNamedObjectDirectory,
442 ObjectSessionInformation,
443 NULL,
444 0);
445 ASSERT(NT_SUCCESS(Status));
446 }
447
448 /* Check if LUID device maps are enabled */
449 Status = NtQueryInformationProcess(NtCurrentProcess(),
450 ProcessLUIDDeviceMapsEnabled,
451 &LuidEnabled,
452 sizeof(LuidEnabled),
453 NULL);
454 ASSERT(NT_SUCCESS(Status));
455 BaseStaticServerData->LUIDDeviceMapsEnabled = LuidEnabled;
456 if (!BaseStaticServerData->LUIDDeviceMapsEnabled)
457 {
458 /* Make Global point back to BNO */
459 RtlInitUnicodeString(&DirectoryName, L"Global");
460 RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects");
461 InitializeObjectAttributes(&ObjectAttributes,
462 &DirectoryName,
463 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
464 BaseSrvNamedObjectDirectory,
465 BnoSd);
466 Status = NtCreateSymbolicLinkObject(&SymHandle,
467 SYMBOLIC_LINK_ALL_ACCESS,
468 &ObjectAttributes,
469 &SymlinkName);
470 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
471
472 /* Make local point back to \Sessions\x\BNO */
473 RtlInitUnicodeString(&DirectoryName, L"Local");
474 ASSERT(SessionId == 0);
475 InitializeObjectAttributes(&ObjectAttributes,
476 &DirectoryName,
477 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
478 BaseSrvNamedObjectDirectory,
479 BnoSd);
480 Status = NtCreateSymbolicLinkObject(&SymHandle,
481 SYMBOLIC_LINK_ALL_ACCESS,
482 &ObjectAttributes,
483 &SymlinkName);
484 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
485
486 /* Make Session point back to BNOLINKS */
487 RtlInitUnicodeString(&DirectoryName, L"Session");
488 RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS");
489 InitializeObjectAttributes(&ObjectAttributes,
490 &DirectoryName,
491 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
492 BaseSrvNamedObjectDirectory,
493 BnoSd);
494 Status = NtCreateSymbolicLinkObject(&SymHandle,
495 SYMBOLIC_LINK_ALL_ACCESS,
496 &ObjectAttributes,
497 &SymlinkName);
498 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
499
500 /* Create the BNO\Restricted directory and set the restricted DACL */
501 RtlInitUnicodeString(&DirectoryName, L"Restricted");
502 Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE);
503 ASSERT(NT_SUCCESS(Status));
504 InitializeObjectAttributes(&ObjectAttributes,
505 &DirectoryName,
506 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
507 BaseSrvNamedObjectDirectory,
508 BnoSd);
509 Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory,
510 DIRECTORY_ALL_ACCESS,
511 &ObjectAttributes);
512 ASSERT(NT_SUCCESS(Status));
513 }
514
515 /* Finally, set the pointer */
516 LoadedServerDll->SharedSection = BaseStaticServerData;
517 }
518
519 CSR_SERVER_DLL_INIT(ServerDllInitialization)
520 {
521 /* Setup the DLL Object */
522 LoadedServerDll->ApiBase = BASESRV_FIRST_API_NUMBER; // ApiNumberBase
523 LoadedServerDll->HighestApiSupported = BasepMaxApiNumber; // MaxApiNumber
524 LoadedServerDll->DispatchTable = BaseServerApiDispatchTable;
525 LoadedServerDll->ValidTable = BaseServerApiServerValidTable;
526 LoadedServerDll->NameTable = BaseServerApiNameTable;
527 LoadedServerDll->SizeOfProcessData = 0;
528 LoadedServerDll->ConnectCallback = NULL;
529 LoadedServerDll->DisconnectCallback = NULL;
530 LoadedServerDll->ShutdownProcessCallback = NULL;
531
532 BaseSrvDllInstance = LoadedServerDll->ServerHandle;
533
534 BaseInitializeStaticServerData(LoadedServerDll);
535
536 /* Initialize DOS devices management */
537 BaseInitDefineDosDevice();
538
539 /* All done */
540 return STATUS_SUCCESS;
541 }
542
543 BOOL
544 NTAPI
545 DllMain(IN HINSTANCE hInstanceDll,
546 IN DWORD dwReason,
547 IN LPVOID lpReserved)
548 {
549 UNREFERENCED_PARAMETER(hInstanceDll);
550 UNREFERENCED_PARAMETER(dwReason);
551 UNREFERENCED_PARAMETER(lpReserved);
552
553 if (DLL_PROCESS_DETACH == dwReason)
554 {
555 BaseCleanupDefineDosDevice();
556 }
557
558 return TRUE;
559 }
560
561 /* EOF */