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)
9 /* INCLUDES *******************************************************************/
21 /* GLOBALS ********************************************************************/
23 HANDLE BaseSrvDllInstance
= NULL
;
24 extern UNICODE_STRING BaseSrvKernel32DllPath
;
27 HANDLE BaseSrvHeap
= NULL
; // Our own heap.
28 HANDLE BaseSrvSharedHeap
= NULL
; // Shared heap with CSR. (CsrSrvSharedSectionHeap)
29 PBASE_STATIC_SERVER_DATA BaseStaticServerData
= NULL
; // Data that we can share amongst processes. Initialized inside BaseSrvSharedHeap.
31 PINIFILE_MAPPING BaseSrvIniFileMapping
;
33 // Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
34 PCSR_API_ROUTINE BaseServerApiDispatchTable
[BasepMaxApiNumber
- BASESRV_FIRST_API_NUMBER
] =
42 BaseSrvUpdateVDMEntry
,
43 BaseSrvGetNextVDMCommand
,
46 BaseSrvGetVDMExitCode
,
47 BaseSrvSetReenterCount
,
48 BaseSrvSetProcessShutdownParam
,
49 BaseSrvGetProcessShutdownParam
,
50 BaseSrvNlsSetUserInfo
,
51 BaseSrvNlsSetMultipleUserInfo
,
52 BaseSrvNlsCreateSection
,
55 BaseSrvBatNotification
,
56 BaseSrvRegisterWowExec
,
57 BaseSrvSoundSentryNotification
,
58 BaseSrvRefreshIniFileMapping
,
59 BaseSrvDefineDosDevice
,
60 BaseSrvSetTermsrvAppInstallMode
,
61 BaseSrvNlsUpdateCacheCount
,
62 BaseSrvSetTermsrvClientTimeZone
,
63 BaseSrvSxsCreateActivationContext
,
65 BaseSrvRegisterThread
,
66 BaseSrvNlsGetUserInfo
,
69 BOOLEAN BaseServerApiServerValidTable
[BasepMaxApiNumber
- BASESRV_FIRST_API_NUMBER
] =
71 TRUE
, // BaseSrvCreateProcess
72 TRUE
, // BaseSrvCreateThread
73 TRUE
, // BaseSrvGetTempFile
74 FALSE
, // BaseSrvExitProcess
75 FALSE
, // BaseSrvDebugProcess
76 TRUE
, // BaseSrvCheckVDM
77 TRUE
, // BaseSrvUpdateVDMEntry
78 TRUE
, // BaseSrvGetNextVDMCommand
79 TRUE
, // BaseSrvExitVDM
80 TRUE
, // BaseSrvIsFirstVDM
81 TRUE
, // BaseSrvGetVDMExitCode
82 TRUE
, // BaseSrvSetReenterCount
83 TRUE
, // BaseSrvSetProcessShutdownParam
84 TRUE
, // BaseSrvGetProcessShutdownParam
85 TRUE
, // BaseSrvNlsSetUserInfo
86 TRUE
, // BaseSrvNlsSetMultipleUserInfo
87 TRUE
, // BaseSrvNlsCreateSection
88 TRUE
, // BaseSrvSetVDMCurDirs
89 TRUE
, // BaseSrvGetVDMCurDirs
90 TRUE
, // BaseSrvBatNotification
91 TRUE
, // BaseSrvRegisterWowExec
92 TRUE
, // BaseSrvSoundSentryNotification
93 TRUE
, // BaseSrvRefreshIniFileMapping
94 TRUE
, // BaseSrvDefineDosDevice
95 TRUE
, // BaseSrvSetTermsrvAppInstallMode
96 TRUE
, // BaseSrvNlsUpdateCacheCount
97 TRUE
, // BaseSrvSetTermsrvClientTimeZone
98 TRUE
, // BaseSrvSxsCreateActivationContext
99 TRUE
, // BaseSrvUnknown
100 TRUE
, // BaseSrvRegisterThread
101 TRUE
, // BaseSrvNlsGetUserInfo
105 * On Windows Server 2003, CSR Servers contain
106 * the API Names Table only in Debug Builds.
109 PCHAR BaseServerApiNameTable
[BasepMaxApiNumber
- BASESRV_FIRST_API_NUMBER
] =
117 "BaseUpdateVDMEntry",
118 "BaseGetNextVDMCommand",
121 "BaseGetVDMExitCode",
122 "BaseSetReenterCount",
123 "BaseSetProcessShutdownParam",
124 "BaseGetProcessShutdownParam",
125 "BaseNlsSetUserInfo",
126 "BaseNlsSetMultipleUserInfo",
127 "BaseNlsCreateSection",
130 "BaseBatNotification",
131 "BaseRegisterWowExec",
132 "BaseSoundSentryNotification",
133 "BaseRefreshIniFileMapping",
134 "BaseDefineDosDevice",
135 "BaseSetTermsrvAppInstallMode",
136 "BaseNlsUpdateCacheCount",
137 "BaseSetTermsrvClientTimeZone",
138 "BaseSxsCreateActivationContext",
140 "BaseRegisterThread",
141 "BaseNlsGetUserInfo",
145 /* FUNCTIONS ******************************************************************/
149 BaseSrvInitializeIniFileMappings(IN PBASE_STATIC_SERVER_DATA StaticServerData
)
151 /* Allocate the mapping blob */
152 BaseSrvIniFileMapping
= RtlAllocateHeap(BaseSrvSharedHeap
,
154 sizeof(*BaseSrvIniFileMapping
));
155 if (BaseSrvIniFileMapping
== NULL
)
157 DPRINT1("BASESRV: Unable to allocate memory in shared heap for IniFileMapping\n");
158 return STATUS_NO_MEMORY
;
162 StaticServerData
->IniFileMapping
= BaseSrvIniFileMapping
;
164 /* FIXME: Do the work to initialize the mappings */
165 return STATUS_SUCCESS
;
170 CreateBaseAcls(OUT PACL
* Dacl
,
171 OUT PACL
* RestrictedDacl
)
173 PSID SystemSid
, WorldSid
, RestrictedSid
;
174 SID_IDENTIFIER_AUTHORITY NtAuthority
= {SECURITY_NT_AUTHORITY
};
175 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
178 UCHAR KeyValueBuffer
[0x40];
179 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
180 UNICODE_STRING KeyName
;
181 ULONG ProtectionMode
= 0;
187 OBJECT_ATTRIBUTES ObjectAttributes
;
189 /* Open the Session Manager Key */
190 RtlInitUnicodeString(&KeyName
, SM_REG_KEY
);
191 InitializeObjectAttributes(&ObjectAttributes
,
193 OBJ_CASE_INSENSITIVE
,
196 Status
= NtOpenKey(&hKey
, KEY_READ
, &ObjectAttributes
);
197 if (NT_SUCCESS(Status
))
199 /* Read the key value */
200 RtlInitUnicodeString(&KeyName
, L
"ProtectionMode");
201 Status
= NtQueryValueKey(hKey
,
203 KeyValuePartialInformation
,
205 sizeof(KeyValueBuffer
),
208 /* Make sure it's what we expect it to be */
209 KeyValuePartialInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)KeyValueBuffer
;
210 if ((NT_SUCCESS(Status
)) && (KeyValuePartialInfo
->Type
== REG_DWORD
) &&
211 (*(PULONG
)KeyValuePartialInfo
->Data
))
213 /* Save the Protection Mode */
214 ProtectionMode
= *(PULONG
)KeyValuePartialInfo
->Data
;
217 /* Close the handle */
222 /* Allocate the System SID */
223 Status
= RtlAllocateAndInitializeSid(&NtAuthority
,
224 1, SECURITY_LOCAL_SYSTEM_RID
,
227 ASSERT(NT_SUCCESS(Status
));
229 /* Allocate the World SID */
230 Status
= RtlAllocateAndInitializeSid(&WorldAuthority
,
231 1, SECURITY_WORLD_RID
,
234 ASSERT(NT_SUCCESS(Status
));
236 /* Allocate the restricted SID */
237 Status
= RtlAllocateAndInitializeSid(&NtAuthority
,
238 1, SECURITY_RESTRICTED_CODE_RID
,
241 ASSERT(NT_SUCCESS(Status
));
243 /* Allocate one ACL with 3 ACEs each for one SID */
244 AclLength
= sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) +
245 RtlLengthSid(SystemSid
) +
246 RtlLengthSid(WorldSid
) +
247 RtlLengthSid(RestrictedSid
);
248 *Dacl
= RtlAllocateHeap(BaseSrvHeap
, 0, AclLength
);
249 ASSERT(*Dacl
!= NULL
);
251 /* Set the correct header fields */
252 Status
= RtlCreateAcl(*Dacl
, AclLength
, ACL_REVISION2
);
253 ASSERT(NT_SUCCESS(Status
));
255 /* Give the appropriate rights to each SID */
256 /* FIXME: Should check SessionId/ProtectionMode */
257 Status
= RtlAddAccessAllowedAce(*Dacl
, ACL_REVISION2
, DIRECTORY_QUERY
| DIRECTORY_TRAVERSE
| DIRECTORY_CREATE_OBJECT
| DIRECTORY_CREATE_SUBDIRECTORY
| READ_CONTROL
, WorldSid
);
258 ASSERT(NT_SUCCESS(Status
));
259 Status
= RtlAddAccessAllowedAce(*Dacl
, ACL_REVISION2
, DIRECTORY_ALL_ACCESS
, SystemSid
);
260 ASSERT(NT_SUCCESS(Status
));
261 Status
= RtlAddAccessAllowedAce(*Dacl
, ACL_REVISION2
, DIRECTORY_TRAVERSE
, RestrictedSid
);
262 ASSERT(NT_SUCCESS(Status
));
264 /* Now allocate the restricted DACL */
265 *RestrictedDacl
= RtlAllocateHeap(BaseSrvHeap
, 0, AclLength
);
266 ASSERT(*RestrictedDacl
!= NULL
);
269 Status
= RtlCreateAcl(*RestrictedDacl
, AclLength
, ACL_REVISION2
);
270 ASSERT(NT_SUCCESS(Status
));
272 /* And add the same ACEs as before */
273 /* FIXME: Not really fully correct */
274 Status
= RtlAddAccessAllowedAce(*RestrictedDacl
, ACL_REVISION2
, DIRECTORY_QUERY
| DIRECTORY_TRAVERSE
| DIRECTORY_CREATE_OBJECT
| DIRECTORY_CREATE_SUBDIRECTORY
| READ_CONTROL
, WorldSid
);
275 ASSERT(NT_SUCCESS(Status
));
276 Status
= RtlAddAccessAllowedAce(*RestrictedDacl
, ACL_REVISION2
, DIRECTORY_ALL_ACCESS
, SystemSid
);
277 ASSERT(NT_SUCCESS(Status
));
278 Status
= RtlAddAccessAllowedAce(*RestrictedDacl
, ACL_REVISION2
, DIRECTORY_TRAVERSE
, RestrictedSid
);
279 ASSERT(NT_SUCCESS(Status
));
281 /* The SIDs are captured, can free them now */
282 RtlFreeSid(RestrictedSid
);
283 RtlFreeSid(WorldSid
);
284 RtlFreeSid(SystemSid
);
290 BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll
)
294 WCHAR Buffer
[MAX_PATH
];
296 UNICODE_STRING SystemRootString
;
297 UNICODE_STRING UnexpandedSystemRootString
= RTL_CONSTANT_STRING(L
"%SystemRoot%");
298 UNICODE_STRING BaseSrvCSDString
;
299 UNICODE_STRING BaseSrvWindowsDirectory
;
300 UNICODE_STRING BaseSrvWindowsSystemDirectory
;
301 UNICODE_STRING BnoString
;
302 OBJECT_ATTRIBUTES ObjectAttributes
;
304 HANDLE BaseSrvNamedObjectDirectory
;
305 HANDLE BaseSrvRestrictedObjectDirectory
;
306 PACL BnoDacl
, BnoRestrictedDacl
;
307 PSECURITY_DESCRIPTOR BnoSd
;
309 UNICODE_STRING DirectoryName
, SymlinkName
;
311 RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable
[2] =
315 RTL_QUERY_REGISTRY_DIRECT
,
324 /* Initialize the memory */
325 BaseSrvHeap
= RtlGetProcessHeap(); // Initialize our own heap.
326 BaseSrvSharedHeap
= LoadedServerDll
->SharedSection
; // Get the CSR shared heap.
328 /* Get the session ID */
329 SessionId
= NtCurrentPeb()->SessionId
;
331 /* Get the Windows directory */
332 RtlInitEmptyUnicodeString(&SystemRootString
, Buffer
, sizeof(Buffer
));
333 Status
= RtlExpandEnvironmentStrings_U(NULL
,
334 &UnexpandedSystemRootString
,
337 ASSERT(NT_SUCCESS(Status
));
339 /* Create the base directory */
340 Buffer
[SystemRootString
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
341 Success
= RtlCreateUnicodeString(&BaseSrvWindowsDirectory
,
342 SystemRootString
.Buffer
);
345 /* Create the system directory */
346 wcscat(SystemRootString
.Buffer
, L
"\\System32");
347 Success
= RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory
,
348 SystemRootString
.Buffer
);
351 /* Create the kernel32 path */
352 wcscat(SystemRootString
.Buffer
, L
"\\kernel32.dll");
353 Success
= RtlCreateUnicodeString(&BaseSrvKernel32DllPath
,
354 SystemRootString
.Buffer
);
357 /* FIXME: Check Session ID */
358 wcscpy(Buffer
, L
"\\BaseNamedObjects");
359 RtlInitUnicodeString(&BnoString
, Buffer
);
361 /* Allocate the server data */
362 BaseStaticServerData
= RtlAllocateHeap(BaseSrvSharedHeap
,
364 sizeof(BASE_STATIC_SERVER_DATA
));
365 ASSERT(BaseStaticServerData
!= NULL
);
367 /* Process timezone information */
368 BaseStaticServerData
->TermsrvClientTimeZoneId
= TIME_ZONE_ID_INVALID
;
369 BaseStaticServerData
->TermsrvClientTimeZoneChangeNum
= 0;
370 Status
= NtQuerySystemInformation(SystemTimeOfDayInformation
,
371 &BaseStaticServerData
->TimeOfDay
,
372 sizeof(BaseStaticServerData
->TimeOfDay
),
374 ASSERT(NT_SUCCESS(Status
));
376 /* Make a shared heap copy of the Windows directory */
377 BaseStaticServerData
->WindowsDirectory
= BaseSrvWindowsDirectory
;
378 HeapBuffer
= RtlAllocateHeap(BaseSrvSharedHeap
,
380 BaseSrvWindowsDirectory
.MaximumLength
);
382 RtlCopyMemory(HeapBuffer
,
383 BaseStaticServerData
->WindowsDirectory
.Buffer
,
384 BaseSrvWindowsDirectory
.MaximumLength
);
385 BaseStaticServerData
->WindowsDirectory
.Buffer
= HeapBuffer
;
387 /* Make a shared heap copy of the System directory */
388 BaseStaticServerData
->WindowsSystemDirectory
= BaseSrvWindowsSystemDirectory
;
389 HeapBuffer
= RtlAllocateHeap(BaseSrvSharedHeap
,
391 BaseSrvWindowsSystemDirectory
.MaximumLength
);
393 RtlCopyMemory(HeapBuffer
,
394 BaseStaticServerData
->WindowsSystemDirectory
.Buffer
,
395 BaseSrvWindowsSystemDirectory
.MaximumLength
);
396 BaseStaticServerData
->WindowsSystemDirectory
.Buffer
= HeapBuffer
;
398 /* This string is not used */
399 RtlInitEmptyUnicodeString(&BaseStaticServerData
->WindowsSys32x86Directory
,
403 /* Make a shared heap copy of the BNO directory */
404 BaseStaticServerData
->NamedObjectDirectory
= BnoString
;
405 BaseStaticServerData
->NamedObjectDirectory
.MaximumLength
= BnoString
.Length
+
406 sizeof(UNICODE_NULL
);
407 HeapBuffer
= RtlAllocateHeap(BaseSrvSharedHeap
,
409 BaseStaticServerData
->NamedObjectDirectory
.MaximumLength
);
411 RtlCopyMemory(HeapBuffer
,
412 BaseStaticServerData
->NamedObjectDirectory
.Buffer
,
413 BaseStaticServerData
->NamedObjectDirectory
.MaximumLength
);
414 BaseStaticServerData
->NamedObjectDirectory
.Buffer
= HeapBuffer
;
417 * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
418 * and MaximumLength of the CSD String, since the same UNICODE_STRING is
419 * being queried twice, the first time as a ULONG!
421 * Somehow, in Windows this doesn't cause a buffer overflow, but it might
422 * in ReactOS, so this code is disabled until someone figures out WTF.
424 BaseStaticServerData
->CSDNumber
= 0;
425 BaseStaticServerData
->RCNumber
= 0;
427 /* Initialize the CSD string and query its value from the registry */
428 RtlInitEmptyUnicodeString(&BaseSrvCSDString
, Buffer
, sizeof(Buffer
));
429 Status
= RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT
,
431 BaseServerRegistryConfigurationTable
,
434 if (NT_SUCCESS(Status
))
436 /* Copy into the shared buffer */
437 wcsncpy(BaseStaticServerData
->CSDVersion
,
438 BaseSrvCSDString
.Buffer
,
439 BaseSrvCSDString
.Length
/ sizeof(WCHAR
));
443 /* NULL-terminate to indicate nothing is there */
444 BaseStaticServerData
->CSDVersion
[0] = UNICODE_NULL
;
447 /* Cache the system information */
448 Status
= NtQuerySystemInformation(SystemBasicInformation
,
449 &BaseStaticServerData
->SysInfo
,
450 sizeof(BaseStaticServerData
->SysInfo
),
452 ASSERT(NT_SUCCESS(Status
));
454 /* Setup the ini file mappings */
455 Status
= BaseSrvInitializeIniFileMappings(BaseStaticServerData
);
456 ASSERT(NT_SUCCESS(Status
));
458 /* FIXME: Should query the registry for these */
459 BaseStaticServerData
->DefaultSeparateVDM
= FALSE
;
460 BaseStaticServerData
->IsWowTaskReady
= FALSE
;
462 /* Allocate a security descriptor and create it */
463 BnoSd
= RtlAllocateHeap(BaseSrvHeap
, 0, 1024);
465 Status
= RtlCreateSecurityDescriptor(BnoSd
, SECURITY_DESCRIPTOR_REVISION
);
466 ASSERT(NT_SUCCESS(Status
));
468 /* Create the BNO and \Restricted DACLs */
469 Status
= CreateBaseAcls(&BnoDacl
, &BnoRestrictedDacl
);
470 ASSERT(NT_SUCCESS(Status
));
472 /* Set the BNO DACL as active for now */
473 Status
= RtlSetDaclSecurityDescriptor(BnoSd
, TRUE
, BnoDacl
, FALSE
);
474 ASSERT(NT_SUCCESS(Status
));
476 /* Create the BNO directory */
477 RtlInitUnicodeString(&BnoString
, L
"\\BaseNamedObjects");
478 InitializeObjectAttributes(&ObjectAttributes
,
480 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
483 Status
= NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory
,
484 DIRECTORY_ALL_ACCESS
,
486 ASSERT(NT_SUCCESS(Status
));
488 /* Check if we are session 0 */
491 /* Mark this as a session 0 directory */
492 Status
= NtSetInformationObject(BaseSrvNamedObjectDirectory
,
493 ObjectSessionInformation
,
496 ASSERT(NT_SUCCESS(Status
));
499 /* Check if LUID device maps are enabled */
500 Status
= NtQueryInformationProcess(NtCurrentProcess(),
501 ProcessLUIDDeviceMapsEnabled
,
505 ASSERT(NT_SUCCESS(Status
));
506 BaseStaticServerData
->LUIDDeviceMapsEnabled
= (BOOLEAN
)LuidEnabled
;
507 if (!BaseStaticServerData
->LUIDDeviceMapsEnabled
)
509 /* Make Global point back to BNO */
510 RtlInitUnicodeString(&DirectoryName
, L
"Global");
511 RtlInitUnicodeString(&SymlinkName
, L
"\\BaseNamedObjects");
512 InitializeObjectAttributes(&ObjectAttributes
,
514 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
515 BaseSrvNamedObjectDirectory
,
517 Status
= NtCreateSymbolicLinkObject(&SymHandle
,
518 SYMBOLIC_LINK_ALL_ACCESS
,
521 if ((NT_SUCCESS(Status
)) && SessionId
== 0) NtClose(SymHandle
);
523 /* Make local point back to \Sessions\x\BNO */
524 RtlInitUnicodeString(&DirectoryName
, L
"Local");
525 ASSERT(SessionId
== 0);
526 InitializeObjectAttributes(&ObjectAttributes
,
528 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
529 BaseSrvNamedObjectDirectory
,
531 Status
= NtCreateSymbolicLinkObject(&SymHandle
,
532 SYMBOLIC_LINK_ALL_ACCESS
,
535 if ((NT_SUCCESS(Status
)) && SessionId
== 0) NtClose(SymHandle
);
537 /* Make Session point back to BNOLINKS */
538 RtlInitUnicodeString(&DirectoryName
, L
"Session");
539 RtlInitUnicodeString(&SymlinkName
, L
"\\Sessions\\BNOLINKS");
540 InitializeObjectAttributes(&ObjectAttributes
,
542 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
543 BaseSrvNamedObjectDirectory
,
545 Status
= NtCreateSymbolicLinkObject(&SymHandle
,
546 SYMBOLIC_LINK_ALL_ACCESS
,
549 if ((NT_SUCCESS(Status
)) && SessionId
== 0) NtClose(SymHandle
);
551 /* Create the BNO\Restricted directory and set the restricted DACL */
552 RtlInitUnicodeString(&DirectoryName
, L
"Restricted");
553 Status
= RtlSetDaclSecurityDescriptor(BnoSd
, TRUE
, BnoRestrictedDacl
, FALSE
);
554 ASSERT(NT_SUCCESS(Status
));
555 InitializeObjectAttributes(&ObjectAttributes
,
557 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
558 BaseSrvNamedObjectDirectory
,
560 Status
= NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory
,
561 DIRECTORY_ALL_ACCESS
,
563 ASSERT(NT_SUCCESS(Status
));
567 BaseSrvNLSInit(BaseStaticServerData
);
569 /* Finally, set the pointer */
570 LoadedServerDll
->SharedSection
= BaseStaticServerData
;
575 BaseSrvDisconnect(PCSR_PROCESS Process
)
577 /* Cleanup the VDM console records */
578 BaseSrvCleanupVdmRecords(HandleToUlong(Process
->ClientId
.UniqueProcess
));
581 CSR_SERVER_DLL_INIT(ServerDllInitialization
)
583 /* Setup the DLL Object */
584 LoadedServerDll
->ApiBase
= BASESRV_FIRST_API_NUMBER
;
585 LoadedServerDll
->HighestApiSupported
= BasepMaxApiNumber
;
586 LoadedServerDll
->DispatchTable
= BaseServerApiDispatchTable
;
587 LoadedServerDll
->ValidTable
= BaseServerApiServerValidTable
;
589 LoadedServerDll
->NameTable
= BaseServerApiNameTable
;
591 LoadedServerDll
->SizeOfProcessData
= 0;
592 LoadedServerDll
->ConnectCallback
= NULL
;
593 LoadedServerDll
->DisconnectCallback
= BaseSrvDisconnect
;
594 LoadedServerDll
->ShutdownProcessCallback
= NULL
;
596 BaseSrvDllInstance
= LoadedServerDll
->ServerHandle
;
598 BaseInitializeStaticServerData(LoadedServerDll
);
600 /* Initialize DOS devices management */
601 BaseInitDefineDosDevice();
603 /* Initialize VDM support */
607 return STATUS_SUCCESS
;
612 DllMain(IN HINSTANCE hInstanceDll
,
614 IN LPVOID lpReserved
)
616 UNREFERENCED_PARAMETER(hInstanceDll
);
617 UNREFERENCED_PARAMETER(dwReason
);
618 UNREFERENCED_PARAMETER(lpReserved
);
620 if (DLL_PROCESS_DETACH
== dwReason
)
622 BaseCleanupDefineDosDevice();