[BASESRV-CONSRV-WINSRV]
[reactos.git] / 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 // UCHAR KeyValueBuffer[0x40];
142 // PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
143 // UNICODE_STRING KeyName;
144 // ULONG ProtectionMode = 0;
145 ULONG AclLength; // , ResultLength;
146 // HANDLE hKey;
147 // OBJECT_ATTRIBUTES ObjectAttributes;
148
149 /* Open the Session Manager Key */
150 /*
151 RtlInitUnicodeString(&KeyName, SM_REG_KEY);
152 InitializeObjectAttributes(&ObjectAttributes,
153 &KeyName,
154 OBJ_CASE_INSENSITIVE,
155 NULL,
156 NULL);
157 Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
158 if (NT_SUCCESS(Status))
159 {
160 /\* Read the key value *\/
161 RtlInitUnicodeString(&KeyName, L"ProtectionMode");
162 Status = NtQueryValueKey(hKey,
163 &KeyName,
164 KeyValuePartialInformation,
165 KeyValueBuffer,
166 sizeof(KeyValueBuffer),
167 &ResultLength);
168
169 /\* Make sure it's what we expect it to be *\/
170 KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
171 if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
172 (*(PULONG)KeyValuePartialInfo->Data))
173 {
174 /\* Save the Protection Mode *\/
175 // ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
176 }
177
178 /\* Close the handle *\/
179 NtClose(hKey);
180 }
181 */
182
183 /* Allocate the System SID */
184 Status = RtlAllocateAndInitializeSid(&NtAuthority,
185 1, SECURITY_LOCAL_SYSTEM_RID,
186 0, 0, 0, 0, 0, 0, 0,
187 &SystemSid);
188 ASSERT(NT_SUCCESS(Status));
189
190 /* Allocate the World SID */
191 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
192 1, SECURITY_WORLD_RID,
193 0, 0, 0, 0, 0, 0, 0,
194 &WorldSid);
195 ASSERT(NT_SUCCESS(Status));
196
197 /* Allocate the restricted SID */
198 Status = RtlAllocateAndInitializeSid(&NtAuthority,
199 1, SECURITY_RESTRICTED_CODE_RID,
200 0, 0, 0, 0, 0, 0, 0,
201 &RestrictedSid);
202 ASSERT(NT_SUCCESS(Status));
203
204 /* Allocate one ACL with 3 ACEs each for one SID */
205 AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
206 RtlLengthSid(SystemSid) +
207 RtlLengthSid(WorldSid) +
208 RtlLengthSid(RestrictedSid);
209 *Dacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
210 ASSERT(*Dacl != NULL);
211
212 /* Set the correct header fields */
213 Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2);
214 ASSERT(NT_SUCCESS(Status));
215
216 /* Give the appropriate rights to each SID */
217 /* FIXME: Should check SessionId/ProtectionMode */
218 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
219 ASSERT(NT_SUCCESS(Status));
220 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
221 ASSERT(NT_SUCCESS(Status));
222 Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
223 ASSERT(NT_SUCCESS(Status));
224
225 /* Now allocate the restricted DACL */
226 *RestrictedDacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
227 ASSERT(*RestrictedDacl != NULL);
228
229 /* Initialize it */
230 Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2);
231 ASSERT(NT_SUCCESS(Status));
232
233 /* And add the same ACEs as before */
234 /* FIXME: Not really fully correct */
235 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
236 ASSERT(NT_SUCCESS(Status));
237 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
238 ASSERT(NT_SUCCESS(Status));
239 Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
240 ASSERT(NT_SUCCESS(Status));
241
242 /* The SIDs are captured, can free them now */
243 RtlFreeSid(RestrictedSid);
244 RtlFreeSid(WorldSid);
245 RtlFreeSid(SystemSid);
246 return Status;
247 }
248
249 VOID
250 NTAPI
251 BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll)
252 {
253 NTSTATUS Status;
254 WCHAR Buffer[MAX_PATH];
255 PWCHAR HeapBuffer;
256 UNICODE_STRING SystemRootString;
257 UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
258 UNICODE_STRING BaseSrvCSDString;
259 UNICODE_STRING BaseSrvWindowsDirectory;
260 UNICODE_STRING BaseSrvWindowsSystemDirectory;
261 UNICODE_STRING BnoString;
262 OBJECT_ATTRIBUTES ObjectAttributes;
263 ULONG SessionId;
264 HANDLE BaseSrvNamedObjectDirectory;
265 HANDLE BaseSrvRestrictedObjectDirectory;
266 PACL BnoDacl, BnoRestrictedDacl;
267 PSECURITY_DESCRIPTOR BnoSd;
268 HANDLE SymHandle;
269 UNICODE_STRING DirectoryName, SymlinkName;
270 ULONG LuidEnabled;
271 RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] =
272 {
273 {
274 NULL,
275 RTL_QUERY_REGISTRY_DIRECT,
276 L"CSDVersion",
277 &BaseSrvCSDString,
278 REG_NONE, NULL, 0
279 },
280
281 {0}
282 };
283
284 /* Initialize the memory */
285 BaseSrvHeap = RtlGetProcessHeap(); // Initialize our own heap.
286 BaseSrvSharedHeap = LoadedServerDll->SharedSection; // Get the CSR shared heap.
287
288 /* Get the session ID */
289 SessionId = NtCurrentPeb()->SessionId;
290
291 /* Get the Windows directory */
292 RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer));
293 Status = RtlExpandEnvironmentStrings_U(NULL,
294 &UnexpandedSystemRootString,
295 &SystemRootString,
296 NULL);
297 ASSERT(NT_SUCCESS(Status));
298
299 /* Create the base directory */
300 Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL;
301 Status = RtlCreateUnicodeString(&BaseSrvWindowsDirectory,
302 SystemRootString.Buffer);
303 ASSERT(NT_SUCCESS(Status));
304
305 /* Create the system directory */
306 wcscat(SystemRootString.Buffer, L"\\System32");
307 Status = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory,
308 SystemRootString.Buffer);
309 ASSERT(NT_SUCCESS(Status));
310
311 /* FIXME: Check Session ID */
312 wcscpy(Buffer, L"\\BaseNamedObjects");
313 RtlInitUnicodeString(&BnoString, Buffer);
314
315 /* Allocate the server data */
316 BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap,
317 HEAP_ZERO_MEMORY,
318 sizeof(BASE_STATIC_SERVER_DATA));
319 ASSERT(BaseStaticServerData != NULL);
320
321 /* Process timezone information */
322 BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
323 BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
324 Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
325 &BaseStaticServerData->TimeOfDay,
326 sizeof(BaseStaticServerData->TimeOfDay),
327 NULL);
328 ASSERT(NT_SUCCESS(Status));
329
330 /* Make a shared heap copy of the Windows directory */
331 BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
332 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
333 0,
334 BaseSrvWindowsDirectory.MaximumLength);
335 ASSERT(HeapBuffer);
336 RtlCopyMemory(HeapBuffer,
337 BaseStaticServerData->WindowsDirectory.Buffer,
338 BaseSrvWindowsDirectory.MaximumLength);
339 BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;
340
341 /* Make a shared heap copy of the System directory */
342 BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
343 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
344 0,
345 BaseSrvWindowsSystemDirectory.MaximumLength);
346 ASSERT(HeapBuffer);
347 RtlCopyMemory(HeapBuffer,
348 BaseStaticServerData->WindowsSystemDirectory.Buffer,
349 BaseSrvWindowsSystemDirectory.MaximumLength);
350 BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;
351
352 /* This string is not used */
353 RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
354 NULL,
355 0);
356
357 /* Make a shared heap copy of the BNO directory */
358 BaseStaticServerData->NamedObjectDirectory = BnoString;
359 BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
360 sizeof(UNICODE_NULL);
361 HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
362 0,
363 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
364 ASSERT(HeapBuffer);
365 RtlCopyMemory(HeapBuffer,
366 BaseStaticServerData->NamedObjectDirectory.Buffer,
367 BaseStaticServerData->NamedObjectDirectory.MaximumLength);
368 BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;
369
370 /*
371 * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
372 * and MaximumLength of the CSD String, since the same UNICODE_STRING is
373 * being queried twice, the first time as a ULONG!
374 *
375 * Somehow, in Windows this doesn't cause a buffer overflow, but it might
376 * in ReactOS, so this code is disabled until someone figures out WTF.
377 */
378 BaseStaticServerData->CSDNumber = 0;
379 BaseStaticServerData->RCNumber = 0;
380
381 /* Initialize the CSD string and query its value from the registry */
382 RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
383 Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
384 L"",
385 BaseServerRegistryConfigurationTable,
386 NULL,
387 NULL);
388 if (NT_SUCCESS(Status))
389 {
390 /* Copy into the shared buffer */
391 wcsncpy(BaseStaticServerData->CSDVersion,
392 BaseSrvCSDString.Buffer,
393 BaseSrvCSDString.Length / sizeof(WCHAR));
394 }
395 else
396 {
397 /* NULL-terminate to indicate nothing is there */
398 BaseStaticServerData->CSDVersion[0] = UNICODE_NULL;
399 }
400
401 /* Cache the system information */
402 Status = NtQuerySystemInformation(SystemBasicInformation,
403 &BaseStaticServerData->SysInfo,
404 sizeof(BaseStaticServerData->SysInfo),
405 NULL);
406 ASSERT(NT_SUCCESS(Status));
407
408 /* FIXME: Should query the registry for these */
409 BaseStaticServerData->DefaultSeparateVDM = FALSE;
410 BaseStaticServerData->IsWowTaskReady = FALSE;
411
412 /* Allocate a security descriptor and create it */
413 BnoSd = RtlAllocateHeap(BaseSrvHeap, 0, 1024);
414 ASSERT(BnoSd);
415 Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION);
416 ASSERT(NT_SUCCESS(Status));
417
418 /* Create the BNO and \Restricted DACLs */
419 Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl);
420 ASSERT(NT_SUCCESS(Status));
421
422 /* Set the BNO DACL as active for now */
423 Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE);
424 ASSERT(NT_SUCCESS(Status));
425
426 /* Create the BNO directory */
427 RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
428 InitializeObjectAttributes(&ObjectAttributes,
429 &BnoString,
430 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
431 NULL,
432 BnoSd);
433 Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory,
434 DIRECTORY_ALL_ACCESS,
435 &ObjectAttributes);
436 ASSERT(NT_SUCCESS(Status));
437
438 /* Check if we are session 0 */
439 if (SessionId == 0)
440 {
441 /* Mark this as a session 0 directory */
442 Status = NtSetInformationObject(BaseSrvNamedObjectDirectory,
443 ObjectSessionInformation,
444 NULL,
445 0);
446 ASSERT(NT_SUCCESS(Status));
447 }
448
449 /* Check if LUID device maps are enabled */
450 Status = NtQueryInformationProcess(NtCurrentProcess(),
451 ProcessLUIDDeviceMapsEnabled,
452 &LuidEnabled,
453 sizeof(LuidEnabled),
454 NULL);
455 ASSERT(NT_SUCCESS(Status));
456 BaseStaticServerData->LUIDDeviceMapsEnabled = LuidEnabled;
457 if (!BaseStaticServerData->LUIDDeviceMapsEnabled)
458 {
459 /* Make Global point back to BNO */
460 RtlInitUnicodeString(&DirectoryName, L"Global");
461 RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects");
462 InitializeObjectAttributes(&ObjectAttributes,
463 &DirectoryName,
464 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
465 BaseSrvNamedObjectDirectory,
466 BnoSd);
467 Status = NtCreateSymbolicLinkObject(&SymHandle,
468 SYMBOLIC_LINK_ALL_ACCESS,
469 &ObjectAttributes,
470 &SymlinkName);
471 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
472
473 /* Make local point back to \Sessions\x\BNO */
474 RtlInitUnicodeString(&DirectoryName, L"Local");
475 ASSERT(SessionId == 0);
476 InitializeObjectAttributes(&ObjectAttributes,
477 &DirectoryName,
478 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
479 BaseSrvNamedObjectDirectory,
480 BnoSd);
481 Status = NtCreateSymbolicLinkObject(&SymHandle,
482 SYMBOLIC_LINK_ALL_ACCESS,
483 &ObjectAttributes,
484 &SymlinkName);
485 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
486
487 /* Make Session point back to BNOLINKS */
488 RtlInitUnicodeString(&DirectoryName, L"Session");
489 RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS");
490 InitializeObjectAttributes(&ObjectAttributes,
491 &DirectoryName,
492 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
493 BaseSrvNamedObjectDirectory,
494 BnoSd);
495 Status = NtCreateSymbolicLinkObject(&SymHandle,
496 SYMBOLIC_LINK_ALL_ACCESS,
497 &ObjectAttributes,
498 &SymlinkName);
499 if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
500
501 /* Create the BNO\Restricted directory and set the restricted DACL */
502 RtlInitUnicodeString(&DirectoryName, L"Restricted");
503 Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE);
504 ASSERT(NT_SUCCESS(Status));
505 InitializeObjectAttributes(&ObjectAttributes,
506 &DirectoryName,
507 OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
508 BaseSrvNamedObjectDirectory,
509 BnoSd);
510 Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory,
511 DIRECTORY_ALL_ACCESS,
512 &ObjectAttributes);
513 ASSERT(NT_SUCCESS(Status));
514 }
515
516 /* Finally, set the pointer */
517 LoadedServerDll->SharedSection = BaseStaticServerData;
518 }
519
520 CSR_SERVER_DLL_INIT(ServerDllInitialization)
521 {
522 /* Setup the DLL Object */
523 LoadedServerDll->ApiBase = BASESRV_FIRST_API_NUMBER; // ApiNumberBase
524 LoadedServerDll->HighestApiSupported = BasepMaxApiNumber; // MaxApiNumber
525 LoadedServerDll->DispatchTable = BaseServerApiDispatchTable;
526 LoadedServerDll->ValidTable = BaseServerApiServerValidTable;
527 LoadedServerDll->NameTable = BaseServerApiNameTable;
528 LoadedServerDll->SizeOfProcessData = 0;
529 LoadedServerDll->ConnectCallback = NULL;
530 LoadedServerDll->DisconnectCallback = NULL;
531 LoadedServerDll->ShutdownProcessCallback = NULL;
532
533 BaseSrvDllInstance = LoadedServerDll->ServerHandle;
534
535 BaseInitializeStaticServerData(LoadedServerDll);
536
537 /* Initialize DOS devices management */
538 BaseInitDefineDosDevice();
539
540 /* All done */
541 return STATUS_SUCCESS;
542 }
543
544 BOOL
545 NTAPI
546 DllMain(IN HINSTANCE hInstanceDll,
547 IN DWORD dwReason,
548 IN LPVOID lpReserved)
549 {
550 UNREFERENCED_PARAMETER(hInstanceDll);
551 UNREFERENCED_PARAMETER(dwReason);
552 UNREFERENCED_PARAMETER(lpReserved);
553
554 if (DLL_PROCESS_DETACH == dwReason)
555 {
556 BaseCleanupDefineDosDevice();
557 }
558
559 return TRUE;
560 }
561
562 /* EOF */