Formatting fix only.
[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 */