2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS CSR Sub System
4 * FILE: subsys/csr/csrsrv/init.c
5 * PURPOSE: CSR Server DLL Initialization
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES ******************************************************************/
16 /* DATA **********************************************************************/
18 HANDLE CsrObjectDirectory
;
20 BOOLEAN CsrProfileControl
;
21 UNICODE_STRING CsrDirectoryName
;
23 HANDLE BNOLinksDirectory
;
24 HANDLE SessionObjectDirectory
;
25 HANDLE DosDevicesDirectory
;
26 HANDLE CsrInitializationEvent
;
27 SYSTEM_BASIC_INFORMATION CsrNtSysInfo
;
30 /* PRIVATE FUNCTIONS *********************************************************/
33 * @name CsrParseServerCommandLine
35 * The CsrParseServerCommandLine routine parses the CSRSS command-line in the
36 * registry and performs operations for each entry found.
38 * @param ArgumentCount
39 * Number of arguments on the command line.
44 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
52 CsrParseServerCommandLine(IN ULONG ArgumentCount
,
56 PCHAR ParameterName
= NULL
, ParameterValue
= NULL
, EntryPoint
, ServerString
;
58 ANSI_STRING AnsiString
;
59 OBJECT_ATTRIBUTES ObjectAttributes
;
61 /* Set the Defaults */
62 CsrTotalPerProcessDataLength
= 0;
63 CsrObjectDirectory
= 0;
64 CsrMaxApiRequestThreads
= 16;
66 /* Save our Session ID, and create a Directory for it */
67 SessionId
= NtCurrentPeb()->SessionId
;
68 Status
= CsrCreateSessionObjectDirectory(SessionId
);
69 if (!NT_SUCCESS(Status
))
71 DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
74 /* It's not fatal if the session ID isn't zero */
75 if (SessionId
) return Status
;
76 ASSERT(NT_SUCCESS(Status
));
79 /* Loop through every argument */
80 for (i
= 1; i
< ArgumentCount
; i
++)
82 /* Split Name and Value */
83 ParameterName
= Arguments
[i
];
84 ParameterValue
= NULL
;
85 ParameterValue
= strchr(ParameterName
, '=');
86 if (ParameterValue
) *ParameterValue
++ = ANSI_NULL
;
87 DPRINT1("Name=%s, Value=%s\n", ParameterName
, ParameterValue
);
89 /* Check for Object Directory */
90 if (!_stricmp(ParameterName
, "ObjectDirectory"))
92 /* Check if a session ID is specified */
95 DPRINT1("Sessions not yet implemented\n");
99 /* Initialize the directory name */
100 RtlInitAnsiString(&AnsiString
, ParameterValue
);
101 Status
= RtlAnsiStringToUnicodeString(&CsrDirectoryName
,
104 ASSERT(NT_SUCCESS(Status
) || SessionId
!= 0);
105 if (!NT_SUCCESS(Status
)) return Status
;
108 InitializeObjectAttributes(&ObjectAttributes
,
110 OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
| OBJ_PERMANENT
,
113 Status
= NtCreateDirectoryObject(&CsrObjectDirectory
,
114 DIRECTORY_ALL_ACCESS
,
116 if (!NT_SUCCESS(Status
)) return Status
;
119 Status
= CsrSetDirectorySecurity(CsrObjectDirectory
);
120 if (!NT_SUCCESS(Status
)) return Status
;
122 else if (!_stricmp(ParameterName
, "SubSystemType"))
126 else if (!_stricmp(ParameterName
, "MaxRequestThreads"))
128 Status
= RtlCharToInteger(ParameterValue
,
130 &CsrMaxApiRequestThreads
);
132 else if (!_stricmp(ParameterName
, "RequestThreads"))
135 Status
= STATUS_SUCCESS
;
137 else if (!_stricmp(ParameterName
, "ProfileControl"))
141 else if (!_stricmp(ParameterName
, "SharedSection"))
143 /* Craete the Section */
144 Status
= CsrSrvCreateSharedSection(ParameterValue
);
145 if (!NT_SUCCESS(Status
))
147 DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
148 ParameterName
, ParameterValue
, Status
);
153 Status
= CsrLoadServerDll("CSRSS", NULL
, CSR_SRV_SERVER
);
155 else if (!_stricmp(ParameterName
, "ServerDLL"))
157 /* Loop the command line */
159 Status
= STATUS_INVALID_PARAMETER
;
160 ServerString
= ParameterValue
;
161 while (*ServerString
)
163 /* Check for the Entry Point */
164 if ((*ServerString
== ':') && (!EntryPoint
))
166 /* Found it. Add a nullchar and save it */
167 *ServerString
++ = ANSI_NULL
;
168 EntryPoint
= ServerString
;
171 /* Check for the Dll Index */
172 if (*ServerString
++ == ',') break;
175 /* Did we find something to load? */
178 DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
179 ParameterValue
, Status
);
183 /* Convert it to a ULONG */
184 Status
= RtlCharToInteger(ServerString
, 10, &DllIndex
);
186 /* Add a null char if it was valid */
187 if (NT_SUCCESS(Status
)) ServerString
[-1] = ANSI_NULL
;
190 if (CsrDebug
& 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue
, EntryPoint
);
191 Status
= CsrLoadServerDll(ParameterValue
, EntryPoint
, DllIndex
);
192 if (!NT_SUCCESS(Status
))
194 DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
195 ParameterValue
, Status
);
199 else if (!_stricmp(ParameterName
, "Windows"))
205 /* Invalid parameter on the command line */
206 Status
= STATUS_INVALID_PARAMETER
;
215 * @name CsrCreateLocalSystemSD
217 * The CsrCreateLocalSystemSD routine creates a Security Descriptor for
218 * the local account with PORT_ALL_ACCESS.
220 * @param LocalSystemSd
221 * Pointer to a pointer to the security descriptor to create.
223 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
231 CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR
*LocalSystemSd
)
233 SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
236 PSECURITY_DESCRIPTOR SystemSd
;
240 /* Initialize the System SID */
241 RtlAllocateAndInitializeSid(&NtSidAuthority
, 1,
242 SECURITY_LOCAL_SYSTEM_RID
,
246 /* Get the length of the SID */
247 Length
= RtlLengthSid(SystemSid
) + sizeof(ACL
) + sizeof(ACCESS_ALLOWED_ACE
);
249 /* Allocate a buffer for the Security Descriptor, with SID and DACL */
250 SystemSd
= RtlAllocateHeap(CsrHeap
, 0, SECURITY_DESCRIPTOR_MIN_LENGTH
+ Length
);
252 /* Set the pointer to the DACL */
253 Dacl
= (PACL
)((ULONG_PTR
)SystemSd
+ SECURITY_DESCRIPTOR_MIN_LENGTH
);
255 /* Now create the SD itself */
256 Status
= RtlCreateSecurityDescriptor(SystemSd
, SECURITY_DESCRIPTOR_REVISION
);
257 if (!NT_SUCCESS(Status
))
260 RtlFreeHeap(CsrHeap
, 0, SystemSd
);
264 /* Create the DACL for it*/
265 RtlCreateAcl(Dacl
, Length
, ACL_REVISION2
);
268 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, PORT_ALL_ACCESS
, SystemSid
);
269 if (!NT_SUCCESS(Status
))
272 RtlFreeHeap(CsrHeap
, 0, SystemSd
);
276 /* Clear the DACL in the SD */
277 Status
= RtlSetDaclSecurityDescriptor(SystemSd
, TRUE
, Dacl
, FALSE
);
278 if (!NT_SUCCESS(Status
))
281 RtlFreeHeap(CsrHeap
, 0, SystemSd
);
285 /* Free the SID and return*/
286 RtlFreeSid(SystemSid
);
287 *LocalSystemSd
= SystemSd
;
292 * @name GetDosDevicesProtection
294 * The GetDosDevicesProtection creates a security descriptor for the DOS Devices
297 * @param DosDevicesSd
298 * Pointer to the Security Descriptor to return.
300 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
303 * @remarks Depending on the DOS Devices Protection Mode (set in the registry),
304 * regular users may or may not have full access to the directory.
309 GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd
)
311 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
312 SID_IDENTIFIER_AUTHORITY CreatorAuthority
= {SECURITY_CREATOR_SID_AUTHORITY
};
313 SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
314 PSID WorldSid
, CreatorSid
, AdminSid
, SystemSid
;
315 UCHAR KeyValueBuffer
[0x40];
316 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
317 UNICODE_STRING KeyName
;
318 ULONG ProtectionMode
= 0;
319 OBJECT_ATTRIBUTES ObjectAttributes
;
321 PACCESS_ALLOWED_ACE Ace
;
324 ULONG ResultLength
, SidLength
, AclLength
;
327 Status
= RtlCreateSecurityDescriptor(DosDevicesSd
, SECURITY_DESCRIPTOR_REVISION
);
328 ASSERT(NT_SUCCESS(Status
));
330 /* Initialize the System SID */
331 Status
= RtlAllocateAndInitializeSid(&NtSidAuthority
, 1,
332 SECURITY_LOCAL_SYSTEM_RID
,
335 ASSERT(NT_SUCCESS(Status
));
337 /* Initialize the World SID */
338 Status
= RtlAllocateAndInitializeSid(&WorldAuthority
, 1,
342 ASSERT(NT_SUCCESS(Status
));
344 /* Initialize the Admin SID */
345 Status
= RtlAllocateAndInitializeSid(&NtSidAuthority
, 2,
346 SECURITY_BUILTIN_DOMAIN_RID
,
347 DOMAIN_ALIAS_RID_ADMINS
,
350 ASSERT(NT_SUCCESS(Status
));
352 /* Initialize the Creator SID */
353 Status
= RtlAllocateAndInitializeSid(&CreatorAuthority
, 1,
354 SECURITY_CREATOR_OWNER_RID
,
357 ASSERT(NT_SUCCESS(Status
));
359 /* Open the Session Manager Key */
360 RtlInitUnicodeString(&KeyName
, SM_REG_KEY
);
361 InitializeObjectAttributes(&ObjectAttributes
,
363 OBJ_CASE_INSENSITIVE
,
366 Status
= NtOpenKey(&hKey
, KEY_READ
, &ObjectAttributes
);
367 if (NT_SUCCESS(Status
))
369 /* Read the key value */
370 RtlInitUnicodeString(&KeyName
, L
"ProtectionMode");
371 Status
= NtQueryValueKey(hKey
,
373 KeyValuePartialInformation
,
375 sizeof(KeyValueBuffer
),
378 /* Make sure it's what we expect it to be */
379 KeyValuePartialInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)KeyValueBuffer
;
380 if ((NT_SUCCESS(Status
)) && (KeyValuePartialInfo
->Type
== REG_DWORD
) &&
381 (*(PULONG
)KeyValuePartialInfo
->Data
))
383 /* Save the Protection Mode */
384 ProtectionMode
= *(PULONG
)KeyValuePartialInfo
->Data
;
387 /* Close the handle */
391 /* Check the Protection Mode */
392 if (ProtectionMode
& 3)
394 /* Calculate SID Lengths */
395 SidLength
= RtlLengthSid(CreatorSid
) + RtlLengthSid(SystemSid
) +
396 RtlLengthSid(AdminSid
);
397 AclLength
= sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) + SidLength
;
399 /* Allocate memory for the DACL */
400 Dacl
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, AclLength
);
401 ASSERT(Dacl
!= NULL
);
403 /* Build the ACL and add 3 ACEs */
404 Status
= RtlCreateAcl(Dacl
, AclLength
, ACL_REVISION2
);
405 ASSERT(NT_SUCCESS(Status
));
406 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, SystemSid
);
407 ASSERT(NT_SUCCESS(Status
));
408 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, AdminSid
);
409 ASSERT(NT_SUCCESS(Status
));
410 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, CreatorSid
);
411 ASSERT(NT_SUCCESS(Status
));
413 /* Edit the ACEs to make them inheritable */
414 Status
= RtlGetAce(Dacl
, 0, (PVOID
*)&Ace
);
415 ASSERT(NT_SUCCESS(Status
));
416 Ace
->Header
.AceFlags
|= OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
;
417 Status
= RtlGetAce(Dacl
, 1, (PVOID
*)&Ace
);
418 ASSERT(NT_SUCCESS(Status
));
419 Ace
->Header
.AceFlags
|= OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
;
420 Status
= RtlGetAce(Dacl
, 2, (PVOID
*)&Ace
);
421 ASSERT(NT_SUCCESS(Status
));
422 Ace
->Header
.AceFlags
|= OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
| INHERIT_ONLY_ACE
;
424 /* Set this DACL with the SD */
425 Status
= RtlSetDaclSecurityDescriptor(DosDevicesSd
, TRUE
, Dacl
, FALSE
);
426 ASSERT(NT_SUCCESS(Status
));
431 /* Calculate SID Lengths */
432 SidLength
= RtlLengthSid(WorldSid
) + RtlLengthSid(SystemSid
);
433 AclLength
= sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) + SidLength
;
435 /* Allocate memory for the DACL */
436 Dacl
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, AclLength
);
437 ASSERT(Dacl
!= NULL
);
439 /* Build the ACL and add 3 ACEs */
440 Status
= RtlCreateAcl(Dacl
, AclLength
, ACL_REVISION2
);
441 ASSERT(NT_SUCCESS(Status
));
442 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_READ
| GENERIC_WRITE
| GENERIC_EXECUTE
, WorldSid
);
443 ASSERT(NT_SUCCESS(Status
));
444 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, SystemSid
);
445 ASSERT(NT_SUCCESS(Status
));
446 Status
= RtlAddAccessAllowedAce(Dacl
, ACL_REVISION
, GENERIC_ALL
, WorldSid
);
447 ASSERT(NT_SUCCESS(Status
));
449 /* Edit the last ACE to make it inheritable */
450 Status
= RtlGetAce(Dacl
, 2, (PVOID
*)&Ace
);
451 ASSERT(NT_SUCCESS(Status
));
452 Ace
->Header
.AceFlags
|= OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
| INHERIT_ONLY_ACE
;
454 /* Set this DACL with the SD */
455 Status
= RtlSetDaclSecurityDescriptor(DosDevicesSd
, TRUE
, Dacl
, FALSE
);
456 ASSERT(NT_SUCCESS(Status
));
460 /* FIXME: failure cases! Fail: */
461 /* Free the memory */
462 RtlFreeHeap(CsrHeap
, 0, Dacl
);
464 /* FIXME: semi-failure cases! Quickie: */
467 RtlFreeSid(SystemSid
);
468 RtlFreeSid(WorldSid
);
469 RtlFreeSid(AdminSid
);
470 RtlFreeSid(CreatorSid
);
477 * @name FreeDosDevicesProtection
479 * The FreeDosDevicesProtection frees the security descriptor that was created
480 * by GetDosDevicesProtection
482 * @param DosDevicesSd
483 * Pointer to the security descriptor to free.
492 FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd
)
495 BOOLEAN Present
, Default
;
498 /* Get the DACL corresponding to this SD */
499 Status
= RtlGetDaclSecurityDescriptor(DosDevicesSd
, &Present
, &Dacl
, &Default
);
500 ASSERT(NT_SUCCESS(Status
));
502 ASSERT(Dacl
!= NULL
);
505 if ((NT_SUCCESS(Status
)) && (Dacl
)) RtlFreeHeap(CsrHeap
, 0, Dacl
);
509 * @name CsrCreateSessionObjectDirectory
511 * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects,
512 * Session and Dos Devices directories for the specified session.
515 * Session ID for which to create the directories.
517 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
525 CsrCreateSessionObjectDirectory(IN ULONG Session
)
527 WCHAR SessionBuffer
[512], BnoBuffer
[512];
528 UNICODE_STRING SessionString
, BnoString
;
529 OBJECT_ATTRIBUTES ObjectAttributes
;
531 SECURITY_DESCRIPTOR DosDevicesSd
;
534 /* Generate the Session BNOLINKS Directory name */
535 swprintf(SessionBuffer
, L
"%ws\\BNOLINKS", SESSION_ROOT
);
536 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
539 InitializeObjectAttributes(&ObjectAttributes
,
541 OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
544 Status
= NtCreateDirectoryObject(&BNOLinksDirectory
,
545 DIRECTORY_ALL_ACCESS
,
547 if (!NT_SUCCESS(Status
))
549 DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
550 "CsrCreateSessionObjectDirectory - status = %lx\n", Status
);
554 /* Now add the Session ID */
555 swprintf(SessionBuffer
, L
"%ld", Session
);
556 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
558 /* Check if this is the first Session */
561 /* Not the first, so the name will be slighly more complex */
562 swprintf(BnoBuffer
, L
"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT
, Session
);
563 RtlInitUnicodeString(&BnoString
, BnoBuffer
);
567 /* Use the direct name */
568 RtlInitUnicodeString(&BnoString
, L
"\\BaseNamedObjects");
571 /* Create the symlink */
572 InitializeObjectAttributes(&ObjectAttributes
,
574 OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
577 Status
= NtCreateSymbolicLinkObject(&BnoHandle
,
578 SYMBOLIC_LINK_ALL_ACCESS
,
581 if (!NT_SUCCESS(Status
))
583 DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in "
584 "CsrCreateSessionObjectDirectory - status = %lx\n", Status
);
588 /* Create the \DosDevices Security Descriptor */
589 Status
= GetDosDevicesProtection(&DosDevicesSd
);
590 if (!NT_SUCCESS(Status
)) return Status
;
592 /* Now create a directory for this session */
593 swprintf(SessionBuffer
, L
"%ws\\%ld", SESSION_ROOT
, Session
);
594 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
596 /* Create the directory */
597 InitializeObjectAttributes(&ObjectAttributes
,
599 OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
602 Status
= NtCreateDirectoryObject(&SessionObjectDirectory
,
603 DIRECTORY_ALL_ACCESS
,
605 if (!NT_SUCCESS(Status
))
607 DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
608 "CsrCreateSessionObjectDirectory - status = %lx\n", Status
);
609 FreeDosDevicesProtection(&DosDevicesSd
);
613 /* Next, create a directory for this session's DOS Devices */
614 RtlInitUnicodeString(&SessionString
, L
"DosDevices");
615 InitializeObjectAttributes(&ObjectAttributes
,
617 OBJ_CASE_INSENSITIVE
,
618 SessionObjectDirectory
,
620 Status
= NtCreateDirectoryObject(&DosDevicesDirectory
,
621 DIRECTORY_ALL_ACCESS
,
623 if (!NT_SUCCESS(Status
))
625 DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
626 "CsrCreateSessionObjectDirectory - status = %lx\n", Status
);
629 /* Release the Security Descriptor */
630 FreeDosDevicesProtection(&DosDevicesSd
);
637 * @name CsrSetProcessSecurity
639 * The CsrSetProcessSecurity routine protects access to the CSRSS process
640 * from unauthorized tampering.
644 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
652 CsrSetProcessSecurity(VOID
)
655 HANDLE hToken
, hProcess
= NtCurrentProcess();
656 ULONG ReturnLength
, Length
;
657 PTOKEN_USER TokenInfo
= NULL
;
658 PSECURITY_DESCRIPTOR ProcSd
= NULL
;
663 Status
= NtOpenProcessToken(hProcess
, TOKEN_QUERY
, &hToken
);
664 if (!NT_SUCCESS(Status
)) goto Quickie
;
666 /* Get the Token User Length */
667 NtQueryInformationToken(hToken
, TokenUser
, NULL
, 0, &Length
);
669 /* Allocate space for it */
670 TokenInfo
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, Length
);
673 Status
= STATUS_NO_MEMORY
;
677 /* Now query the data */
678 Status
= NtQueryInformationToken(hToken
, TokenUser
, TokenInfo
, Length
, &Length
);
680 if (!NT_SUCCESS(Status
)) goto Quickie
;
682 /* Now check the SID Length */
683 UserSid
= TokenInfo
->User
.Sid
;
684 ReturnLength
= RtlLengthSid(UserSid
) + sizeof(ACL
) + sizeof(ACCESS_ALLOWED_ACE
);
686 /* Allocate a buffer for the Security Descriptor, with SID and DACL */
687 ProcSd
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, SECURITY_DESCRIPTOR_MIN_LENGTH
+ Length
);
690 Status
= STATUS_NO_MEMORY
;
694 /* Set the pointer to the DACL */
695 Dacl
= (PACL
)((ULONG_PTR
)ProcSd
+ SECURITY_DESCRIPTOR_MIN_LENGTH
);
697 /* Now create the SD itself */
698 Status
= RtlCreateSecurityDescriptor(ProcSd
, SECURITY_DESCRIPTOR_REVISION
);
699 if (!NT_SUCCESS(Status
)) goto Quickie
;
701 /* Create the DACL for it*/
702 RtlCreateAcl(Dacl
, Length
, ACL_REVISION2
);
705 Status
= RtlAddAccessAllowedAce(Dacl
,
707 PROCESS_VM_READ
| PROCESS_VM_WRITE
|
708 PROCESS_VM_OPERATION
| PROCESS_DUP_HANDLE
|
709 PROCESS_TERMINATE
| PROCESS_SUSPEND_RESUME
|
710 PROCESS_QUERY_INFORMATION
| READ_CONTROL
,
712 if (!NT_SUCCESS(Status
)) goto Quickie
;
714 /* Clear the DACL in the SD */
715 Status
= RtlSetDaclSecurityDescriptor(ProcSd
, TRUE
, Dacl
, FALSE
);
716 if (!NT_SUCCESS(Status
)) goto Quickie
;
718 /* Write the SD into the Process */
719 Status
= NtSetSecurityObject(hProcess
, DACL_SECURITY_INFORMATION
, ProcSd
);
721 /* Free the memory and return */
723 if (ProcSd
) RtlFreeHeap(CsrHeap
, 0, ProcSd
);
724 RtlFreeHeap(CsrHeap
, 0, TokenInfo
);
729 * @name CsrSetDirectorySecurity
731 * The CsrSetDirectorySecurity routine sets the security descriptor for the
732 * specified Object Directory.
734 * @param ObjectDirectory
735 * Handle fo the Object Directory to protect.
737 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
745 CsrSetDirectorySecurity(IN HANDLE ObjectDirectory
)
747 /* FIXME: Implement */
748 return STATUS_SUCCESS
;
751 /* PUBLIC FUNCTIONS **********************************************************/
754 * @name CsrServerInitialization
757 * The CsrServerInitialization routine is the native (not Server) entrypoint
758 * of this Server DLL. It serves as the entrypoint for csrss.
760 * @param ArgumentCount
761 * Number of arguments on the command line.
764 * Array of arguments from the command line.
766 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
774 CsrServerInitialization(IN ULONG ArgumentCount
,
775 IN PCHAR Arguments
[])
777 NTSTATUS Status
= STATUS_SUCCESS
;
780 PCSR_SERVER_DLL ServerDll
;
781 DPRINT("CSRSRV: %s called\n", __FUNCTION__
);
783 /* Create the Init Event */
784 Status
= NtCreateEvent(&CsrInitializationEvent
,
787 SynchronizationEvent
,
789 if (!NT_SUCCESS(Status
))
791 DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
792 __FUNCTION__
, Status
);
796 /* Cache System Basic Information so we don't always request it */
797 Status
= NtQuerySystemInformation(SystemBasicInformation
,
799 sizeof(SYSTEM_BASIC_INFORMATION
),
801 if (!NT_SUCCESS(Status
))
803 DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
804 __FUNCTION__
, Status
);
809 CsrHeap
= RtlGetProcessHeap();
811 /* Set our Security Descriptor to protect the process */
812 Status
= CsrSetProcessSecurity();
813 if (!NT_SUCCESS(Status
))
815 DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
816 __FUNCTION__
, Status
);
820 /* Set up Session Support */
821 Status
= CsrInitializeNtSessionList();
822 if (!NT_SUCCESS(Status
))
824 DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
825 __FUNCTION__
, Status
);
829 /* Set up Process Support */
830 Status
= CsrInitializeProcessStructure();
831 if (!NT_SUCCESS(Status
))
833 DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
834 __FUNCTION__
, Status
);
838 /* Parse the command line */
839 Status
= CsrParseServerCommandLine(ArgumentCount
, Arguments
);
840 if (!NT_SUCCESS(Status
))
842 DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
843 __FUNCTION__
, Status
);
847 /* All Server DLLs are now loaded, allocate a heap for the Root Process */
848 ProcessData
= RtlAllocateHeap(CsrHeap
,
850 CsrTotalPerProcessDataLength
);
853 DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n",
854 __FUNCTION__
, STATUS_NO_MEMORY
);
855 return STATUS_NO_MEMORY
;
859 * Our Root Process was never officially initalized, so write the data
860 * for each Server DLL manually.
862 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
864 /* Get the current Server */
865 ServerDll
= CsrLoadedServerDll
[i
];
867 /* Is it loaded, and does it have per process data? */
868 if ((ServerDll
) && (ServerDll
->SizeOfProcessData
))
870 /* It does, give it part of our allocated heap */
871 CsrRootProcess
->ServerData
[i
] = ProcessData
;
873 /* Move to the next heap position */
874 ProcessData
= (PVOID
)((ULONG_PTR
)ProcessData
+
875 ServerDll
->SizeOfProcessData
);
879 /* Nothing for this Server DLL */
880 CsrRootProcess
->ServerData
[i
] = NULL
;
884 /* Now initialize the Root Process manually as well */
885 for (i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
887 /* Get the current Server */
888 ServerDll
= CsrLoadedServerDll
[i
];
890 /* Is it loaded, and does it a callback for new processes? */
891 if ((ServerDll
) && (ServerDll
->NewProcessCallback
))
893 /* Call the callback */
894 ServerDll
->NewProcessCallback(NULL
, CsrRootProcess
);
898 /* Now initialize our API Port */
899 Status
= CsrApiPortInitialize();
900 if (!NT_SUCCESS(Status
))
902 DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
903 __FUNCTION__
, Status
);
907 /* Initialize the API Port for SM communication */
908 Status
= CsrSbApiPortInitialize();
909 if (!NT_SUCCESS(Status
))
911 DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
912 __FUNCTION__
, Status
);
916 /* We're all set! Connect to SM! */
917 Status
= SmConnectToSm(&CsrSbApiPortName
,
919 IMAGE_SUBSYSTEM_WINDOWS_GUI
,
921 if (!NT_SUCCESS(Status
))
923 DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
924 __FUNCTION__
, Status
);
928 /* Finito! Signal the event */
929 Status
= NtSetEvent(CsrInitializationEvent
, NULL
);
930 if (!NT_SUCCESS(Status
))
932 DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
933 __FUNCTION__
, Status
);
937 /* Close the event handle now */
938 NtClose(CsrInitializationEvent
);
940 /* Have us handle Hard Errors */
941 Status
= NtSetDefaultHardErrorPort(CsrApiPort
);
942 if (!NT_SUCCESS(Status
))
944 DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
945 __FUNCTION__
, Status
);
954 * @name CsrPopulateDosDevices
955 * @unimplemented NT5.1
957 * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
958 * to populate the Dos Devices Object Directory for the session.
969 CsrPopulateDosDevices(VOID
)
971 DPRINT1("Deprecated API\n");
977 DllMain(IN HANDLE hDll
,
979 IN LPVOID lpReserved
)
981 /* We don't do much */
982 UNREFERENCED_PARAMETER(hDll
);
983 UNREFERENCED_PARAMETER(dwReason
);
984 UNREFERENCED_PARAMETER(lpReserved
);