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