2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS CSR Sub System
4 * FILE: subsystems/win32/csrss/csrsrv/init.c
5 * PURPOSE: CSR Server DLL Initialization
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * ReactOS Portable Systems Group
10 /* INCLUDES *******************************************************************/
16 /* DATA ***********************************************************************/
18 HANDLE CsrHeap
= (HANDLE
) 0;
19 HANDLE CsrObjectDirectory
= (HANDLE
) 0;
20 UNICODE_STRING CsrDirectoryName
;
21 UNICODE_STRING CsrSbApiPortName
;
22 HANDLE CsrSbApiPort
= 0;
23 PCSR_THREAD CsrSbApiRequestThreadPtr
;
25 HANDLE hSbApiPort
= (HANDLE
) 0;
26 HANDLE CsrApiPort
= (HANDLE
) 0;
27 ULONG CsrDebug
= 0;//0xFFFFFFFF;
28 ULONG CsrMaxApiRequestThreads
;
29 ULONG CsrTotalPerProcessDataLength
;
31 HANDLE BNOLinksDirectory
;
32 HANDLE SessionObjectDirectory
;
33 HANDLE DosDevicesDirectory
;
34 HANDLE CsrInitializationEvent
;
35 SYSTEM_BASIC_INFORMATION CsrNtSysInfo
;
37 /* PRIVATE FUNCTIONS **********************************************************/
40 CallHardError(IN PCSR_THREAD ThreadData
,
41 IN PHARDERROR_MSG HardErrorMessage
)
44 PCSR_SERVER_DLL ServerDll
;
46 DPRINT("CSR: %s called\n", __FUNCTION__
);
48 /* Notify the Server DLLs */
49 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
51 /* Get the current Server DLL */
52 ServerDll
= CsrLoadedServerDll
[i
];
54 /* Make sure it's valid and that it has callback */
55 if ((ServerDll
) && (ServerDll
->HardErrorCallback
))
57 ServerDll
->HardErrorCallback(ThreadData
, HardErrorMessage
);
63 CallProcessCreated(IN PCSR_PROCESS SourceProcessData
,
64 IN PCSR_PROCESS TargetProcessData
)
66 NTSTATUS Status
= STATUS_SUCCESS
;
68 PCSR_SERVER_DLL ServerDll
;
70 DPRINT("CSR: %s called\n", __FUNCTION__
);
72 /* Notify the Server DLLs */
73 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
75 /* Get the current Server DLL */
76 ServerDll
= CsrLoadedServerDll
[i
];
78 /* Make sure it's valid and that it has callback */
79 if ((ServerDll
) && (ServerDll
->NewProcessCallback
))
81 Status
= ServerDll
->NewProcessCallback(SourceProcessData
, TargetProcessData
);
88 CSRSS_API_DEFINITION NativeDefinitions
[] =
90 CSRSS_DEFINE_API(CREATE_PROCESS
, CsrSrvCreateProcess
),
91 CSRSS_DEFINE_API(CREATE_THREAD
, CsrSrvCreateThread
),
92 CSRSS_DEFINE_API(TERMINATE_PROCESS
, CsrTerminateProcess
),
93 CSRSS_DEFINE_API(CONNECT_PROCESS
, CsrConnectProcess
),
94 CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS
, CsrRegisterServicesProcess
),
95 CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS
, CsrGetShutdownParameters
),
96 CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS
, CsrSetShutdownParameters
),
100 /* === INIT ROUTINES === */
104 BasepFakeStaticServerData(VOID
);
107 * @name CsrSetProcessSecurity
109 * The CsrSetProcessSecurity routine protects access to the CSRSS process
110 * from unauthorized tampering.
114 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
122 CsrSetProcessSecurity(VOID
)
125 HANDLE hToken
, hProcess
= NtCurrentProcess();
127 PTOKEN_USER TokenInfo
= NULL
;
128 PSECURITY_DESCRIPTOR ProcSd
= NULL
;
133 Status
= NtOpenProcessToken(hProcess
, TOKEN_QUERY
, &hToken
);
134 if (!NT_SUCCESS(Status
)) goto Quickie
;
136 /* Get the Token User Length */
137 NtQueryInformationToken(hToken
, TokenUser
, NULL
, 0, &Length
);
139 /* Allocate space for it */
140 TokenInfo
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, Length
);
143 Status
= STATUS_NO_MEMORY
;
147 /* Now query the data */
148 Status
= NtQueryInformationToken(hToken
, TokenUser
, TokenInfo
, Length
, &Length
);
150 if (!NT_SUCCESS(Status
)) goto Quickie
;
152 /* Now check the SID Length */
153 UserSid
= TokenInfo
->User
.Sid
;
154 Length
= RtlLengthSid(UserSid
) + sizeof(ACL
) + sizeof(ACCESS_ALLOWED_ACE
);
156 /* Allocate a buffer for the Security Descriptor, with SID and DACL */
157 ProcSd
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, SECURITY_DESCRIPTOR_MIN_LENGTH
+ Length
);
160 Status
= STATUS_NO_MEMORY
;
164 /* Set the pointer to the DACL */
165 Dacl
= (PACL
)((ULONG_PTR
)ProcSd
+ SECURITY_DESCRIPTOR_MIN_LENGTH
);
167 /* Now create the SD itself */
168 Status
= RtlCreateSecurityDescriptor(ProcSd
, SECURITY_DESCRIPTOR_REVISION
);
169 if (!NT_SUCCESS(Status
))
171 DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status
);
175 /* Create the DACL for it*/
176 Status
= RtlCreateAcl(Dacl
, Length
, ACL_REVISION2
);
177 if (!NT_SUCCESS(Status
))
179 DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status
);
184 Status
= RtlAddAccessAllowedAce(Dacl
,
186 PROCESS_VM_READ
| PROCESS_VM_WRITE
|
187 PROCESS_VM_OPERATION
| PROCESS_DUP_HANDLE
|
188 PROCESS_TERMINATE
| PROCESS_SUSPEND_RESUME
|
189 PROCESS_QUERY_INFORMATION
| READ_CONTROL
,
191 if (!NT_SUCCESS(Status
))
193 DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status
);
197 /* Clear the DACL in the SD */
198 Status
= RtlSetDaclSecurityDescriptor(ProcSd
, TRUE
, Dacl
, FALSE
);
199 if (!NT_SUCCESS(Status
))
201 DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status
);
205 /* Write the SD into the Process */
206 Status
= NtSetSecurityObject(hProcess
, DACL_SECURITY_INFORMATION
, ProcSd
);
207 if (!NT_SUCCESS(Status
))
209 DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status
);
213 /* Free the memory and return */
215 if (ProcSd
) RtlFreeHeap(CsrHeap
, 0, ProcSd
);
216 RtlFreeHeap(CsrHeap
, 0, TokenInfo
);
221 * @name CsrSetDirectorySecurity
223 * The CsrSetDirectorySecurity routine sets the security descriptor for the
224 * specified Object Directory.
226 * @param ObjectDirectory
227 * Handle fo the Object Directory to protect.
229 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
237 CsrSetDirectorySecurity(IN HANDLE ObjectDirectory
)
239 /* FIXME: Implement */
240 return STATUS_SUCCESS
;
244 * @name GetDosDevicesProtection
246 * The GetDosDevicesProtection creates a security descriptor for the DOS Devices
249 * @param DosDevicesSd
250 * Pointer to the Security Descriptor to return.
252 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
255 * @remarks Depending on the DOS Devices Protection Mode (set in the registry),
256 * regular users may or may not have full access to the directory.
261 GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd
)
263 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
264 SID_IDENTIFIER_AUTHORITY CreatorAuthority
= {SECURITY_CREATOR_SID_AUTHORITY
};
265 SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
266 PSID WorldSid
, CreatorSid
, AdminSid
, SystemSid
;
267 UCHAR KeyValueBuffer
[0x40];
268 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
269 UNICODE_STRING KeyName
;
270 ULONG ProtectionMode
= 0;
271 OBJECT_ATTRIBUTES ObjectAttributes
;
273 PACCESS_ALLOWED_ACE Ace
;
276 ULONG ResultLength
, SidLength
, AclLength
;
279 Status
= RtlCreateSecurityDescriptor(DosDevicesSd
, SECURITY_DESCRIPTOR_REVISION
);
280 ASSERT(NT_SUCCESS(Status
));
282 /* Initialize the System SID */
283 Status
= RtlAllocateAndInitializeSid(&NtSidAuthority
, 1,
284 SECURITY_LOCAL_SYSTEM_RID
,
287 ASSERT(NT_SUCCESS(Status
));
289 /* Initialize the World SID */
290 Status
= RtlAllocateAndInitializeSid(&WorldAuthority
, 1,
294 ASSERT(NT_SUCCESS(Status
));
296 /* Initialize the Admin SID */
297 Status
= RtlAllocateAndInitializeSid(&NtSidAuthority
, 2,
298 SECURITY_BUILTIN_DOMAIN_RID
,
299 DOMAIN_ALIAS_RID_ADMINS
,
302 ASSERT(NT_SUCCESS(Status
));
304 /* Initialize the Creator SID */
305 Status
= RtlAllocateAndInitializeSid(&CreatorAuthority
, 1,
306 SECURITY_CREATOR_OWNER_RID
,
309 ASSERT(NT_SUCCESS(Status
));
311 /* Open the Session Manager Key */
312 RtlInitUnicodeString(&KeyName
, SM_REG_KEY
);
313 InitializeObjectAttributes(&ObjectAttributes
,
315 OBJ_CASE_INSENSITIVE
,
318 Status
= NtOpenKey(&hKey
, KEY_READ
, &ObjectAttributes
);
319 if (NT_SUCCESS(Status
))
321 /* Read the key value */
322 RtlInitUnicodeString(&KeyName
, L
"ProtectionMode");
323 Status
= NtQueryValueKey(hKey
,
325 KeyValuePartialInformation
,
327 sizeof(KeyValueBuffer
),
330 /* Make sure it's what we expect it to be */
331 KeyValuePartialInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)KeyValueBuffer
;
332 if ((NT_SUCCESS(Status
)) && (KeyValuePartialInfo
->Type
== REG_DWORD
) &&
333 (*(PULONG
)KeyValuePartialInfo
->Data
))
335 /* Save the Protection Mode */
336 ProtectionMode
= *(PULONG
)KeyValuePartialInfo
->Data
;
339 /* Close the handle */
343 /* Check the Protection Mode */
344 if (ProtectionMode
& 3)
346 /* Calculate SID Lengths */
347 SidLength
= RtlLengthSid(CreatorSid
) + RtlLengthSid(SystemSid
) +
348 RtlLengthSid(AdminSid
);
349 AclLength
= sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) + SidLength
;
351 /* Allocate memory for the DACL */
352 Dacl
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, AclLength
);
353 ASSERT(Dacl
!= NULL
);
355 /* Build the ACL and add 3 ACEs */
356 Status
= RtlCreateAcl(Dacl
, AclLength
, ACL_REVISION2
);
357 ASSERT(NT_SUCCESS(Status
));
358 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, SystemSid
);
359 ASSERT(NT_SUCCESS(Status
));
360 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, AdminSid
);
361 ASSERT(NT_SUCCESS(Status
));
362 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, CreatorSid
);
363 ASSERT(NT_SUCCESS(Status
));
365 /* Edit the ACEs to make them inheritable */
366 Status
= RtlGetAce(Dacl
, 0, (PVOID
*)&Ace
);
367 ASSERT(NT_SUCCESS(Status
));
368 Ace
->Header
.AceFlags
|= OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
;
369 Status
= RtlGetAce(Dacl
, 1, (PVOID
*)&Ace
);
370 ASSERT(NT_SUCCESS(Status
));
371 Ace
->Header
.AceFlags
|= OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
;
372 Status
= RtlGetAce(Dacl
, 2, (PVOID
*)&Ace
);
373 ASSERT(NT_SUCCESS(Status
));
374 Ace
->Header
.AceFlags
|= OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
| INHERIT_ONLY_ACE
;
376 /* Set this DACL with the SD */
377 Status
= RtlSetDaclSecurityDescriptor(DosDevicesSd
, TRUE
, Dacl
, FALSE
);
378 ASSERT(NT_SUCCESS(Status
));
383 /* Calculate SID Lengths */
384 SidLength
= RtlLengthSid(WorldSid
) + RtlLengthSid(SystemSid
);
385 AclLength
= sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) + SidLength
;
387 /* Allocate memory for the DACL */
388 Dacl
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, AclLength
);
389 ASSERT(Dacl
!= NULL
);
391 /* Build the ACL and add 3 ACEs */
392 Status
= RtlCreateAcl(Dacl
, AclLength
, ACL_REVISION2
);
393 ASSERT(NT_SUCCESS(Status
));
394 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_READ
| GENERIC_WRITE
| GENERIC_EXECUTE
, WorldSid
);
395 ASSERT(NT_SUCCESS(Status
));
396 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, SystemSid
);
397 ASSERT(NT_SUCCESS(Status
));
398 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, WorldSid
);
399 ASSERT(NT_SUCCESS(Status
));
401 /* Edit the last ACE to make it inheritable */
402 Status
= RtlGetAce(Dacl
, 2, (PVOID
*)&Ace
);
403 ASSERT(NT_SUCCESS(Status
));
404 Ace
->Header
.AceFlags
|= OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
| INHERIT_ONLY_ACE
;
406 /* Set this DACL with the SD */
407 Status
= RtlSetDaclSecurityDescriptor(DosDevicesSd
, TRUE
, Dacl
, FALSE
);
408 ASSERT(NT_SUCCESS(Status
));
412 /* FIXME: failure cases! Fail: */
413 /* Free the memory */
414 RtlFreeHeap(CsrHeap
, 0, Dacl
);
416 /* FIXME: semi-failure cases! Quickie: */
419 RtlFreeSid(SystemSid
);
420 RtlFreeSid(WorldSid
);
421 RtlFreeSid(AdminSid
);
422 RtlFreeSid(CreatorSid
);
429 * @name FreeDosDevicesProtection
431 * The FreeDosDevicesProtection frees the security descriptor that was created
432 * by GetDosDevicesProtection
434 * @param DosDevicesSd
435 * Pointer to the security descriptor to free.
444 FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd
)
447 BOOLEAN Present
, Default
;
450 /* Get the DACL corresponding to this SD */
451 Status
= RtlGetDaclSecurityDescriptor(DosDevicesSd
, &Present
, &Dacl
, &Default
);
452 ASSERT(NT_SUCCESS(Status
));
454 ASSERT(Dacl
!= NULL
);
457 if ((NT_SUCCESS(Status
)) && (Dacl
)) RtlFreeHeap(CsrHeap
, 0, Dacl
);
461 * @name CsrCreateSessionObjectDirectory
463 * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects,
464 * Session and Dos Devices directories for the specified session.
467 * Session ID for which to create the directories.
469 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
477 CsrCreateSessionObjectDirectory(IN ULONG Session
)
479 WCHAR SessionBuffer
[512], BnoBuffer
[512];
480 UNICODE_STRING SessionString
, BnoString
;
481 OBJECT_ATTRIBUTES ObjectAttributes
;
483 SECURITY_DESCRIPTOR DosDevicesSd
;
486 /* Generate the Session BNOLINKS Directory name */
487 swprintf(SessionBuffer
, L
"%ws\\BNOLINKS", SESSION_ROOT
);
488 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
491 InitializeObjectAttributes(&ObjectAttributes
,
493 OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
496 Status
= NtCreateDirectoryObject(&BNOLinksDirectory
,
497 DIRECTORY_ALL_ACCESS
,
499 if (!NT_SUCCESS(Status
))
501 DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
502 "CsrCreateSessionObjectDirectory - status = %lx\n", Status
);
506 /* Now add the Session ID */
507 swprintf(SessionBuffer
, L
"%ld", Session
);
508 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
510 /* Check if this is the first Session */
513 /* Not the first, so the name will be slighly more complex */
514 swprintf(BnoBuffer
, L
"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT
, Session
);
515 RtlInitUnicodeString(&BnoString
, BnoBuffer
);
519 /* Use the direct name */
520 RtlInitUnicodeString(&BnoString
, L
"\\BaseNamedObjects");
523 /* Create the symlink */
524 InitializeObjectAttributes(&ObjectAttributes
,
526 OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
529 Status
= NtCreateSymbolicLinkObject(&BnoHandle
,
530 SYMBOLIC_LINK_ALL_ACCESS
,
533 if (!NT_SUCCESS(Status
))
535 DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in "
536 "CsrCreateSessionObjectDirectory - status = %lx\n", Status
);
540 /* Create the \DosDevices Security Descriptor */
541 Status
= GetDosDevicesProtection(&DosDevicesSd
);
542 if (!NT_SUCCESS(Status
)) return Status
;
544 /* Now create a directory for this session */
545 swprintf(SessionBuffer
, L
"%ws\\%ld", SESSION_ROOT
, Session
);
546 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
548 /* Create the directory */
549 InitializeObjectAttributes(&ObjectAttributes
,
551 OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
554 Status
= NtCreateDirectoryObject(&SessionObjectDirectory
,
555 DIRECTORY_ALL_ACCESS
,
557 if (!NT_SUCCESS(Status
))
559 DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
560 "CsrCreateSessionObjectDirectory - status = %lx\n", Status
);
561 FreeDosDevicesProtection(&DosDevicesSd
);
565 /* Next, create a directory for this session's DOS Devices */
566 RtlInitUnicodeString(&SessionString
, L
"DosDevices");
567 InitializeObjectAttributes(&ObjectAttributes
,
569 OBJ_CASE_INSENSITIVE
,
570 SessionObjectDirectory
,
572 Status
= NtCreateDirectoryObject(&DosDevicesDirectory
,
573 DIRECTORY_ALL_ACCESS
,
575 if (!NT_SUCCESS(Status
))
577 DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
578 "CsrCreateSessionObjectDirectory - status = %lx\n", Status
);
581 /* Release the Security Descriptor */
582 FreeDosDevicesProtection(&DosDevicesSd
);
589 * @name CsrParseServerCommandLine
591 * The CsrParseServerCommandLine routine parses the CSRSS command-line in the
592 * registry and performs operations for each entry found.
594 * @param ArgumentCount
595 * Number of arguments on the command line.
598 * Array of arguments.
600 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
608 CsrParseServerCommandLine(IN ULONG ArgumentCount
,
609 IN PCHAR Arguments
[])
612 PCHAR ParameterName
= NULL
, ParameterValue
= NULL
, EntryPoint
, ServerString
;
614 ANSI_STRING AnsiString
;
615 OBJECT_ATTRIBUTES ObjectAttributes
;
617 /* Set the Defaults */
618 CsrTotalPerProcessDataLength
= 0;
619 CsrObjectDirectory
= NULL
;
620 CsrMaxApiRequestThreads
= 16;
622 /* Save our Session ID, and create a Directory for it */
623 SessionId
= NtCurrentPeb()->SessionId
;
624 Status
= CsrCreateSessionObjectDirectory(SessionId
);
625 if (!NT_SUCCESS(Status
))
627 DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
630 /* It's not fatal if the session ID isn't zero */
631 if (SessionId
) return Status
;
632 ASSERT(NT_SUCCESS(Status
));
635 /* Loop through every argument */
636 for (i
= 1; i
< ArgumentCount
; i
++)
638 /* Split Name and Value */
639 ParameterName
= Arguments
[i
];
640 ParameterValue
= NULL
;
641 ParameterValue
= strchr(ParameterName
, '=');
642 if (ParameterValue
) *ParameterValue
++ = ANSI_NULL
;
644 /* Check for Object Directory */
645 if (!_stricmp(ParameterName
, "ObjectDirectory"))
647 /* Check if a session ID is specified */
650 DPRINT1("Sessions not yet implemented\n");
654 /* Initialize the directory name */
655 RtlInitAnsiString(&AnsiString
, ParameterValue
);
656 Status
= RtlAnsiStringToUnicodeString(&CsrDirectoryName
,
659 ASSERT(NT_SUCCESS(Status
) || SessionId
!= 0);
660 if (!NT_SUCCESS(Status
)) return Status
;
663 InitializeObjectAttributes(&ObjectAttributes
,
665 OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
668 Status
= NtCreateDirectoryObject(&CsrObjectDirectory
,
669 DIRECTORY_ALL_ACCESS
,
671 if (!NT_SUCCESS(Status
)) return Status
;
674 Status
= CsrSetDirectorySecurity(CsrObjectDirectory
);
675 if (!NT_SUCCESS(Status
)) return Status
;
677 else if (!_stricmp(ParameterName
, "SubSystemType"))
681 else if (!_stricmp(ParameterName
, "MaxRequestThreads"))
683 Status
= RtlCharToInteger(ParameterValue
,
685 &CsrMaxApiRequestThreads
);
687 else if (!_stricmp(ParameterName
, "RequestThreads"))
690 Status
= STATUS_SUCCESS
;
692 else if (!_stricmp(ParameterName
, "ProfileControl"))
696 else if (!_stricmp(ParameterName
, "SharedSection"))
698 /* Create the Section */
699 Status
= CsrSrvCreateSharedSection(ParameterValue
);
700 if (!NT_SUCCESS(Status
))
702 DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
703 ParameterName
, ParameterValue
, Status
);
708 Status
= CsrLoadServerDll("CSRSS", NULL
, CSR_SRV_SERVER
);
710 else if (!_stricmp(ParameterName
, "ServerDLL"))
712 /* Loop the command line */
714 Status
= STATUS_INVALID_PARAMETER
;
715 ServerString
= ParameterValue
;
716 while (*ServerString
)
718 /* Check for the Entry Point */
719 if ((*ServerString
== ':') && (!EntryPoint
))
721 /* Found it. Add a nullchar and save it */
722 *ServerString
++ = ANSI_NULL
;
723 EntryPoint
= ServerString
;
726 /* Check for the Dll Index */
727 if (*ServerString
++ == ',') break;
730 /* Did we find something to load? */
733 DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
734 ParameterValue
, Status
);
738 /* Convert it to a ULONG */
739 Status
= RtlCharToInteger(ServerString
, 10, &DllIndex
);
741 /* Add a null char if it was valid */
742 if (NT_SUCCESS(Status
)) ServerString
[-1] = ANSI_NULL
;
745 if (CsrDebug
& 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue
, EntryPoint
);
747 /* Hackito ergo sum */
748 Status
= STATUS_SUCCESS
;
749 if (strstr(ParameterValue
, "basesrv"))
751 DPRINT1("Fake basesrv init\n");
752 BasepFakeStaticServerData();
756 // Status = CsrLoadServerDll(ParameterValue, EntryPoint, 2);
758 // Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex);
759 if (!NT_SUCCESS(Status
))
761 DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
762 ParameterValue
, Status
);
766 else if (!_stricmp(ParameterName
, "Windows"))
772 /* Invalid parameter on the command line */
773 Status
= STATUS_INVALID_PARAMETER
;
782 * @name CsrCreateLocalSystemSD
784 * The CsrCreateLocalSystemSD routine creates a Security Descriptor for
785 * the local account with PORT_ALL_ACCESS.
787 * @param LocalSystemSd
788 * Pointer to a pointer to the security descriptor to create.
790 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
798 CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR
*LocalSystemSd
)
800 SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
803 PSECURITY_DESCRIPTOR SystemSd
;
807 /* Initialize the System SID */
808 RtlAllocateAndInitializeSid(&NtSidAuthority
, 1,
809 SECURITY_LOCAL_SYSTEM_RID
,
813 /* Get the length of the SID */
814 Length
= RtlLengthSid(SystemSid
) + sizeof(ACL
) + sizeof(ACCESS_ALLOWED_ACE
);
816 /* Allocate a buffer for the Security Descriptor, with SID and DACL */
817 SystemSd
= RtlAllocateHeap(CsrHeap
, 0, SECURITY_DESCRIPTOR_MIN_LENGTH
+ Length
);
819 /* Set the pointer to the DACL */
820 Dacl
= (PACL
)((ULONG_PTR
)SystemSd
+ SECURITY_DESCRIPTOR_MIN_LENGTH
);
822 /* Now create the SD itself */
823 Status
= RtlCreateSecurityDescriptor(SystemSd
, SECURITY_DESCRIPTOR_REVISION
);
824 if (!NT_SUCCESS(Status
))
827 RtlFreeHeap(CsrHeap
, 0, SystemSd
);
831 /* Create the DACL for it */
832 RtlCreateAcl(Dacl
, Length
, ACL_REVISION2
);
835 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, PORT_ALL_ACCESS
, SystemSid
);
836 if (!NT_SUCCESS(Status
))
839 RtlFreeHeap(CsrHeap
, 0, SystemSd
);
843 /* Clear the DACL in the SD */
844 Status
= RtlSetDaclSecurityDescriptor(SystemSd
, TRUE
, Dacl
, FALSE
);
845 if (!NT_SUCCESS(Status
))
848 RtlFreeHeap(CsrHeap
, 0, SystemSd
);
852 /* Free the SID and return*/
853 RtlFreeSid(SystemSid
);
854 *LocalSystemSd
= SystemSd
;
859 * @name CsrSbApiPortInitialize
861 * The CsrSbApiPortInitialize routine initializes the LPC Port used for
862 * communications with the Session Manager (SM) and initializes the static
863 * thread that will handle connection requests and APIs.
867 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
875 CsrSbApiPortInitialize(VOID
)
878 PSECURITY_DESCRIPTOR PortSd
;
879 OBJECT_ATTRIBUTES ObjectAttributes
;
881 HANDLE hRequestThread
;
884 /* Calculate how much space we'll need for the Port Name */
885 Size
= CsrDirectoryName
.Length
+ sizeof(SB_PORT_NAME
) + sizeof(WCHAR
);
887 /* Create the buffer for it */
888 CsrSbApiPortName
.Buffer
= RtlAllocateHeap(CsrHeap
, 0, Size
);
889 if (!CsrSbApiPortName
.Buffer
) return STATUS_NO_MEMORY
;
891 /* Setup the rest of the empty string */
892 CsrSbApiPortName
.Length
= 0;
893 CsrSbApiPortName
.MaximumLength
= (USHORT
)Size
;
895 /* Now append the full port name */
896 RtlAppendUnicodeStringToString(&CsrSbApiPortName
, &CsrDirectoryName
);
897 RtlAppendUnicodeToString(&CsrSbApiPortName
, UNICODE_PATH_SEP
);
898 RtlAppendUnicodeToString(&CsrSbApiPortName
, SB_PORT_NAME
);
899 if (CsrDebug
& 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName
);
901 /* Create Security Descriptor for this Port */
902 Status
= CsrCreateLocalSystemSD(&PortSd
);
903 if (!NT_SUCCESS(Status
)) return Status
;
905 /* Initialize the Attributes */
906 InitializeObjectAttributes(&ObjectAttributes
,
912 /* Create the Port Object */
913 Status
= NtCreatePort(&CsrSbApiPort
,
915 sizeof(SB_CONNECTION_INFO
),
917 32 * sizeof(SB_API_MSG
));
918 if (PortSd
) RtlFreeHeap(CsrHeap
, 0, PortSd
);
920 if (NT_SUCCESS(Status
))
922 /* Create the Thread to handle the API Requests */
923 Status
= RtlCreateUserThread(NtCurrentProcess(),
929 (PVOID
)CsrSbApiRequestThread
,
933 if (NT_SUCCESS(Status
))
935 /* Add it as a Static Server Thread */
936 CsrSbApiRequestThreadPtr
= CsrAddStaticServerThread(hRequestThread
,
941 Status
= NtResumeThread(hRequestThread
, NULL
);
948 /* PUBLIC FUNCTIONS ***********************************************************/
951 * @name CsrServerInitialization
954 * The CsrServerInitialization routine is the native (not Server) entrypoint
955 * of this Server DLL. It serves as the entrypoint for csrss.
957 * @param ArgumentCount
958 * Number of arguments on the command line.
961 * Array of arguments from the command line.
963 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
971 CsrServerInitialization(IN ULONG ArgumentCount
,
972 IN PCHAR Arguments
[])
974 NTSTATUS Status
= STATUS_SUCCESS
;
975 DPRINT("CSRSRV: %s called\n", __FUNCTION__
);
977 /* Create the Init Event */
978 Status
= NtCreateEvent(&CsrInitializationEvent
,
981 SynchronizationEvent
,
983 if (!NT_SUCCESS(Status
))
985 DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
986 __FUNCTION__
, Status
);
990 /* Cache System Basic Information so we don't always request it */
991 Status
= NtQuerySystemInformation(SystemBasicInformation
,
993 sizeof(SYSTEM_BASIC_INFORMATION
),
995 if (!NT_SUCCESS(Status
))
997 DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
998 __FUNCTION__
, Status
);
1003 CsrHeap
= RtlGetProcessHeap();
1005 /* Set our Security Descriptor to protect the process */
1006 Status
= CsrSetProcessSecurity();
1007 if (!NT_SUCCESS(Status
))
1009 DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
1010 __FUNCTION__
, Status
);
1014 /* Set up Session Support */
1015 Status
= CsrInitializeNtSessionList();
1016 if (!NT_SUCCESS(Status
))
1018 DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
1019 __FUNCTION__
, Status
);
1023 /* Set up Process Support */
1024 Status
= CsrInitializeProcessStructure();
1025 if (!NT_SUCCESS(Status
))
1027 DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
1028 __FUNCTION__
, Status
);
1032 /* Parse the command line */
1033 Status
= CsrParseServerCommandLine(ArgumentCount
, Arguments
);
1034 if (!NT_SUCCESS(Status
))
1036 DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
1037 __FUNCTION__
, Status
);
1041 Status
= CsrApiRegisterDefinitions(NativeDefinitions
);
1042 if (!NT_SUCCESS(Status
))
1044 DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrApiRegisterDefinitions", Status
);
1047 /* Now initialize our API Port */
1048 Status
= CsrApiPortInitialize();
1049 if (!NT_SUCCESS(Status
))
1051 DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
1052 __FUNCTION__
, Status
);
1056 /* Initialize Win32csr */
1057 Status
= CsrLoadServerDll("win32csr", "Win32CsrInitialization", 2);
1058 if (!NT_SUCCESS(Status
))
1060 DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrLoadServerDll", Status
);
1063 /* Initialize the API Port for SM communication */
1064 Status
= CsrSbApiPortInitialize();
1065 if (!NT_SUCCESS(Status
))
1067 DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
1068 __FUNCTION__
, Status
);
1072 /* We're all set! Connect to SM! */
1073 Status
= SmConnectToSm(&CsrSbApiPortName
,
1075 IMAGE_SUBSYSTEM_WINDOWS_GUI
,
1077 if (!NT_SUCCESS(Status
))
1079 DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
1080 __FUNCTION__
, Status
);
1084 /* Finito! Signal the event */
1085 Status
= NtSetEvent(CsrInitializationEvent
, NULL
);
1086 if (!NT_SUCCESS(Status
))
1088 DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
1089 __FUNCTION__
, Status
);
1093 /* Close the event handle now */
1094 NtClose(CsrInitializationEvent
);
1096 /* Have us handle Hard Errors */
1097 Status
= NtSetDefaultHardErrorPort(CsrApiPort
);
1098 if (!NT_SUCCESS(Status
))
1100 DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
1101 __FUNCTION__
, Status
);
1110 * @name CsrPopulateDosDevices
1111 * @unimplemented NT5.1
1113 * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
1114 * to populate the Dos Devices Object Directory for the session.
1125 CsrPopulateDosDevices(VOID
)
1127 DPRINT1("Deprecated API\n");
1133 DllMain(IN HANDLE hDll
,
1135 IN LPVOID lpReserved
)
1137 /* We don't do much */
1138 UNREFERENCED_PARAMETER(hDll
);
1139 UNREFERENCED_PARAMETER(dwReason
);
1140 UNREFERENCED_PARAMETER(lpReserved
);