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