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