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)
14 HANDLE DllHandle
= NULL
;
15 HANDLE BaseApiPort
= NULL
;
17 extern LIST_ENTRY DosDeviceHistory
;
18 extern RTL_CRITICAL_SECTION BaseDefineDosDeviceCritSec
;
20 // Windows NT 4 tables, adapted from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_NT
21 // It is for testing purposes. After that I will update it to 2k3 version and add stubs.
22 // Some names are also deduced from the subsystems/win32/csrss/csrsrv/server.c ones.
23 PCSR_API_ROUTINE BaseServerApiDispatchTable
[BasepMaxApiNumber
] =
29 // BaseSrvDebugProcess,
31 BaseSrvUpdateVDMEntry
,
32 // BaseSrvGetNextVDMCommand,
35 BaseSrvGetVDMExitCode
,
36 // BaseSrvSetReenterCount,
37 BaseSrvSetProcessShutdownParam
,
38 BaseSrvGetProcessShutdownParam
,
39 // BaseSrvNlsSetUserInfo,
40 // BaseSrvNlsSetMultipleUserInfo,
41 // BaseSrvNlsCreateSortSection,
42 // BaseSrvNlsPreserveSection,
43 // BaseSrvSetVDMCurDirs,
44 // BaseSrvGetVDMCurDirs,
45 // BaseSrvBatNotification,
46 // BaseSrvRegisterWowExec,
47 BaseSrvSoundSentryNotification
,
48 // BaseSrvRefreshIniFileMapping,
49 BaseSrvDefineDosDevice
52 BOOLEAN BaseServerApiServerValidTable
[BasepMaxApiNumber
] =
54 TRUE
, // SrvCreateProcess,
55 TRUE
, // SrvCreateThread,
56 TRUE
, // SrvGetTempFile,
57 FALSE
, // SrvExitProcess,
58 // FALSE, // SrvDebugProcess,
60 TRUE
, // SrvUpdateVDMEntry
61 // TRUE, // SrvGetNextVDMCommand
62 // TRUE, // SrvExitVDM
63 // TRUE, // SrvIsFirstVDM
64 TRUE
, // SrvGetVDMExitCode
65 // TRUE, // SrvSetReenterCount
66 TRUE
, // SrvSetProcessShutdownParam
67 TRUE
, // SrvGetProcessShutdownParam
68 // TRUE, // SrvNlsSetUserInfo
69 // TRUE, // SrvNlsSetMultipleUserInfo
70 // TRUE, // SrvNlsCreateSortSection
71 // TRUE, // SrvNlsPreserveSection
72 // TRUE, // SrvSetVDMCurDirs
73 // TRUE, // SrvGetVDMCurDirs
74 // TRUE, // SrvBatNotification
75 // TRUE, // SrvRegisterWowExec
76 TRUE
, // SrvSoundSentryNotification
77 // TRUE, // SrvRefreshIniFileMapping
78 TRUE
, // SrvDefineDosDevice
82 PCHAR BaseServerApiNameTable
[BasepMaxApiNumber
] =
88 // "BaseDebugProcess",
91 // "BaseGetNextVDMCommand",
95 // "BaseSetReenterCount",
96 "BaseSetProcessShutdownParam",
97 "BaseGetProcessShutdownParam",
98 // "BaseNlsSetUserInfo",
99 // "BaseNlsSetMultipleUserInfo",
100 // "BaseNlsCreateSortSection",
101 // "BaseNlsPreserveSection",
102 // "BaseSetVDMCurDirs",
103 // "BaseGetVDMCurDirs",
104 // "BaseBatNotification",
105 // "BaseRegisterWowExec",
106 "BaseSoundSentryNotification",
107 // "BaseSrvRefreshIniFileMapping"
108 "BaseDefineDosDevice",
113 /* FUNCTIONS ******************************************************************/
117 BasepFakeStaticServerData(VOID
)
120 WCHAR Buffer
[MAX_PATH
];
122 UNICODE_STRING SystemRootString
;
123 UNICODE_STRING UnexpandedSystemRootString
= RTL_CONSTANT_STRING(L
"%SystemRoot%");
124 UNICODE_STRING BaseSrvCSDString
;
125 UNICODE_STRING BaseSrvWindowsDirectory
;
126 UNICODE_STRING BaseSrvWindowsSystemDirectory
;
127 UNICODE_STRING BnoString
;
128 OBJECT_ATTRIBUTES ObjectAttributes
;
130 HANDLE BaseSrvNamedObjectDirectory
;
131 HANDLE BaseSrvRestrictedObjectDirectory
;
132 PACL BnoDacl
, BnoRestrictedDacl
;
133 PSECURITY_DESCRIPTOR BnoSd
;
135 UNICODE_STRING DirectoryName
, SymlinkName
;
137 RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable
[2] =
141 RTL_QUERY_REGISTRY_DIRECT
,
150 /* Get the session ID */
151 SessionId
= NtCurrentPeb()->SessionId
;
153 /* Get the Windows directory */
154 RtlInitEmptyUnicodeString(&SystemRootString
, Buffer
, sizeof(Buffer
));
155 Status
= RtlExpandEnvironmentStrings_U(NULL
,
156 &UnexpandedSystemRootString
,
159 ASSERT(NT_SUCCESS(Status
));
161 /* Create the base directory */
162 Buffer
[SystemRootString
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
163 Status
= RtlCreateUnicodeString(&BaseSrvWindowsDirectory
,
164 SystemRootString
.Buffer
);
165 ASSERT(NT_SUCCESS(Status
));
167 /* Create the system directory */
168 wcscat(SystemRootString
.Buffer
, L
"\\System32");
169 Status
= RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory
,
170 SystemRootString
.Buffer
);
171 ASSERT(NT_SUCCESS(Status
));
173 /* FIXME: Check Session ID */
174 wcscpy(Buffer
, L
"\\BaseNamedObjects");
175 RtlInitUnicodeString(&BnoString
, Buffer
);
177 /* Allocate the server data */
178 BaseStaticServerData
= RtlAllocateHeap(CsrSrvSharedSectionHeap
,
180 sizeof(BASE_STATIC_SERVER_DATA
));
181 ASSERT(BaseStaticServerData
!= NULL
);
183 /* Process timezone information */
184 BaseStaticServerData
->TermsrvClientTimeZoneId
= TIME_ZONE_ID_INVALID
;
185 BaseStaticServerData
->TermsrvClientTimeZoneChangeNum
= 0;
186 Status
= NtQuerySystemInformation(SystemTimeOfDayInformation
,
187 &BaseStaticServerData
->TimeOfDay
,
188 sizeof(BaseStaticServerData
->TimeOfDay
),
190 ASSERT(NT_SUCCESS(Status
));
192 /* Make a shared heap copy of the Windows directory */
193 BaseStaticServerData
->WindowsDirectory
= BaseSrvWindowsDirectory
;
194 HeapBuffer
= RtlAllocateHeap(CsrSrvSharedSectionHeap
,
196 BaseSrvWindowsDirectory
.MaximumLength
);
198 RtlCopyMemory(HeapBuffer
,
199 BaseStaticServerData
->WindowsDirectory
.Buffer
,
200 BaseSrvWindowsDirectory
.MaximumLength
);
201 BaseStaticServerData
->WindowsDirectory
.Buffer
= HeapBuffer
;
203 /* Make a shared heap copy of the System directory */
204 BaseStaticServerData
->WindowsSystemDirectory
= BaseSrvWindowsSystemDirectory
;
205 HeapBuffer
= RtlAllocateHeap(CsrSrvSharedSectionHeap
,
207 BaseSrvWindowsSystemDirectory
.MaximumLength
);
209 RtlCopyMemory(HeapBuffer
,
210 BaseStaticServerData
->WindowsSystemDirectory
.Buffer
,
211 BaseSrvWindowsSystemDirectory
.MaximumLength
);
212 BaseStaticServerData
->WindowsSystemDirectory
.Buffer
= HeapBuffer
;
214 /* This string is not used */
215 RtlInitEmptyUnicodeString(&BaseStaticServerData
->WindowsSys32x86Directory
,
219 /* Make a shared heap copy of the BNO directory */
220 BaseStaticServerData
->NamedObjectDirectory
= BnoString
;
221 BaseStaticServerData
->NamedObjectDirectory
.MaximumLength
= BnoString
.Length
+
222 sizeof(UNICODE_NULL
);
223 HeapBuffer
= RtlAllocateHeap(CsrSrvSharedSectionHeap
,
225 BaseStaticServerData
->NamedObjectDirectory
.MaximumLength
);
227 RtlCopyMemory(HeapBuffer
,
228 BaseStaticServerData
->NamedObjectDirectory
.Buffer
,
229 BaseStaticServerData
->NamedObjectDirectory
.MaximumLength
);
230 BaseStaticServerData
->NamedObjectDirectory
.Buffer
= HeapBuffer
;
233 * Confirmed that in Windows, CSDNumber and RCNumber are actually Length
234 * and MaximumLength of the CSD String, since the same UNICODE_STRING is
235 * being queried twice, the first time as a ULONG!
237 * Somehow, in Windows this doesn't cause a buffer overflow, but it might
238 * in ReactOS, so this code is disabled until someone figures out WTF.
240 BaseStaticServerData
->CSDNumber
= 0;
241 BaseStaticServerData
->RCNumber
= 0;
243 /* Initialize the CSD string and query its value from the registry */
244 RtlInitEmptyUnicodeString(&BaseSrvCSDString
, Buffer
, sizeof(Buffer
));
245 Status
= RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT
,
247 BaseServerRegistryConfigurationTable
,
250 if (NT_SUCCESS(Status
))
252 /* Copy into the shared buffer */
253 wcsncpy(BaseStaticServerData
->CSDVersion
,
254 BaseSrvCSDString
.Buffer
,
255 BaseSrvCSDString
.Length
/ sizeof(WCHAR
));
259 /* NULL-terminate to indicate nothing is there */
260 BaseStaticServerData
->CSDVersion
[0] = UNICODE_NULL
;
263 /* Cache the system information */
264 Status
= NtQuerySystemInformation(SystemBasicInformation
,
265 &BaseStaticServerData
->SysInfo
,
266 sizeof(BaseStaticServerData
->SysInfo
),
268 ASSERT(NT_SUCCESS(Status
));
270 /* FIXME: Should query the registry for these */
271 BaseStaticServerData
->DefaultSeparateVDM
= FALSE
;
272 BaseStaticServerData
->IsWowTaskReady
= FALSE
;
274 /* Allocate a security descriptor and create it */
275 BnoSd
= RtlAllocateHeap(CsrHeap
, 0, 1024);
277 Status
= RtlCreateSecurityDescriptor(BnoSd
, SECURITY_DESCRIPTOR_REVISION
);
278 ASSERT(NT_SUCCESS(Status
));
280 /* Create the BNO and \Restricted DACLs */
281 Status
= CreateBaseAcls(&BnoDacl
, &BnoRestrictedDacl
);
282 ASSERT(NT_SUCCESS(Status
));
284 /* Set the BNO DACL as active for now */
285 Status
= RtlSetDaclSecurityDescriptor(BnoSd
, TRUE
, BnoDacl
, FALSE
);
286 ASSERT(NT_SUCCESS(Status
));
288 /* Create the BNO directory */
289 RtlInitUnicodeString(&BnoString
, L
"\\BaseNamedObjects");
290 InitializeObjectAttributes(&ObjectAttributes
,
292 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
295 Status
= NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory
,
296 DIRECTORY_ALL_ACCESS
,
298 ASSERT(NT_SUCCESS(Status
));
300 /* Check if we are session 0 */
303 /* Mark this as a session 0 directory */
304 Status
= NtSetInformationObject(BaseSrvNamedObjectDirectory
,
305 ObjectSessionInformation
,
308 ASSERT(NT_SUCCESS(Status
));
311 /* Check if LUID device maps are enabled */
312 Status
= NtQueryInformationProcess(NtCurrentProcess(),
313 ProcessLUIDDeviceMapsEnabled
,
317 ASSERT(NT_SUCCESS(Status
));
318 BaseStaticServerData
->LUIDDeviceMapsEnabled
= LuidEnabled
;
319 if (!BaseStaticServerData
->LUIDDeviceMapsEnabled
)
321 /* Make Global point back to BNO */
322 RtlInitUnicodeString(&DirectoryName
, L
"Global");
323 RtlInitUnicodeString(&SymlinkName
, L
"\\BaseNamedObjects");
324 InitializeObjectAttributes(&ObjectAttributes
,
326 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
327 BaseSrvNamedObjectDirectory
,
329 Status
= NtCreateSymbolicLinkObject(&SymHandle
,
330 SYMBOLIC_LINK_ALL_ACCESS
,
333 if ((NT_SUCCESS(Status
)) && SessionId
== 0) NtClose(SymHandle
);
335 /* Make local point back to \Sessions\x\BNO */
336 RtlInitUnicodeString(&DirectoryName
, L
"Local");
337 ASSERT(SessionId
== 0);
338 InitializeObjectAttributes(&ObjectAttributes
,
340 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
341 BaseSrvNamedObjectDirectory
,
343 Status
= NtCreateSymbolicLinkObject(&SymHandle
,
344 SYMBOLIC_LINK_ALL_ACCESS
,
347 if ((NT_SUCCESS(Status
)) && SessionId
== 0) NtClose(SymHandle
);
349 /* Make Session point back to BNOLINKS */
350 RtlInitUnicodeString(&DirectoryName
, L
"Session");
351 RtlInitUnicodeString(&SymlinkName
, L
"\\Sessions\\BNOLINKS");
352 InitializeObjectAttributes(&ObjectAttributes
,
354 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
355 BaseSrvNamedObjectDirectory
,
357 Status
= NtCreateSymbolicLinkObject(&SymHandle
,
358 SYMBOLIC_LINK_ALL_ACCESS
,
361 if ((NT_SUCCESS(Status
)) && SessionId
== 0) NtClose(SymHandle
);
363 /* Create the BNO\Restricted directory and set the restricted DACL */
364 RtlInitUnicodeString(&DirectoryName
, L
"Restricted");
365 Status
= RtlSetDaclSecurityDescriptor(BnoSd
, TRUE
, BnoRestrictedDacl
, FALSE
);
366 ASSERT(NT_SUCCESS(Status
));
367 InitializeObjectAttributes(&ObjectAttributes
,
369 OBJ_OPENIF
| OBJ_PERMANENT
| OBJ_CASE_INSENSITIVE
,
370 BaseSrvNamedObjectDirectory
,
372 Status
= NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory
,
373 DIRECTORY_ALL_ACCESS
,
375 ASSERT(NT_SUCCESS(Status
));
378 /* Finally, set the pointer */
379 CsrSrvSharedStaticServerData
[CSR_CONSOLE
] = BaseStaticServerData
;
383 VOID WINAPI
BaseStaticServerThread(PVOID x
)
385 NTSTATUS Status
= STATUS_SUCCESS
;
386 PPORT_MESSAGE Request
= (PPORT_MESSAGE
)x
;
387 PPORT_MESSAGE Reply
= NULL
;
388 ULONG MessageType
= 0;
390 DPRINT("BASESRV: %s called\n", __FUNCTION__
);
392 MessageType
= Request
->u2
.s2
.Type
;
393 DPRINT("BASESRV: %s received a message (Type=%d)\n",
394 __FUNCTION__
, MessageType
);
399 Status
= NtReplyPort(BaseApiPort
, Reply
);
405 CSR_SERVER_DLL_INIT(ServerDllInitialization
)
407 // NTSTATUS Status = STATUS_SUCCESS;
410 DPRINT("BASSRV: %s(%ld,...) called\n", __FUNCTION__, ArgumentCount);
412 BaseApiPort = CsrQueryApiPort ();
413 Status = CsrAddStaticServerThread(BaseStaticServerThread);
414 if (NT_SUCCESS(Status))
416 //TODO initialize the BASE server
418 return STATUS_SUCCESS;
421 /* Setup the DLL Object */
422 LoadedServerDll
->ApiBase
= BASESRV_FIRST_API_NUMBER
; // ApiNumberBase
423 LoadedServerDll
->HighestApiSupported
= BasepMaxApiNumber
; // MaxApiNumber
424 LoadedServerDll
->DispatchTable
= BaseServerApiDispatchTable
;
425 LoadedServerDll
->ValidTable
= BaseServerApiServerValidTable
;
426 LoadedServerDll
->NameTable
= BaseServerApiNameTable
;
427 LoadedServerDll
->SizeOfProcessData
= 0;
428 LoadedServerDll
->ConnectCallback
= NULL
;
429 LoadedServerDll
->DisconnectCallback
= NULL
;
431 BasepFakeStaticServerData();
433 RtlInitializeCriticalSection(&BaseDefineDosDeviceCritSec
);
434 InitializeListHead(&DosDeviceHistory
);
437 return STATUS_SUCCESS
;
442 DllMain(IN HANDLE hDll
,
444 IN LPVOID lpReserved
)
446 UNREFERENCED_PARAMETER(dwReason
);
447 UNREFERENCED_PARAMETER(lpReserved
);
449 if (DLL_PROCESS_ATTACH
== dwReason
)
453 else if (DLL_PROCESS_DETACH
== dwReason
)
455 BaseCleanupDefineDosDevice();