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
;
29 /* PRIVATE FUNCTIONS *********************************************************/
32 * @name CsrPopulateDosDevicesDirectory
34 * The CsrPopulateDosDevicesDirectory routine uses the DOS Device Map from the
35 * Kernel to populate the Dos Devices Object Directory for the session.
46 CsrPopulateDosDevicesDirectory(IN HANDLE hDosDevicesDirectory
,
47 IN PPROCESS_DEVICEMAP_INFORMATION DeviceMap
)
49 WCHAR SymLinkBuffer
[0x1000];
50 UNICODE_STRING GlobalString
;
51 OBJECT_ATTRIBUTES ObjectAttributes
;
52 HANDLE hDirectory
= 0;
54 ULONG ReturnLength
= 0;
55 ULONG BufferLength
= 0x4000;
57 POBJECT_DIRECTORY_INFORMATION QueryBuffer
;
59 UNICODE_STRING LinkTarget
;
61 /* Initialize the Global String */
62 RtlInitUnicodeString(&GlobalString
, GLOBAL_ROOT
);
64 /* Initialize the Object Attributes */
65 InitializeObjectAttributes(&ObjectAttributes
,
71 /* Open the directory */
72 Status
= NtOpenDirectoryObject(&hDirectory
,
75 if (!NT_SUCCESS(Status
)) return Status
;
78 QueryBuffer
= RtlAllocateHeap(CsrHeap
, HEAP_ZERO_MEMORY
, 0x4000);
79 if (!QueryBuffer
) return STATUS_NO_MEMORY
;
81 /* Start query loop */
84 /* Query the Directory */
85 Status
= NtQueryDirectoryObject(hDirectory
,
93 /* Check for the status */
94 if (NT_SUCCESS(Status
))
96 /* Make sure it has a name */
97 if (!QueryBuffer
->Name
.Buffer
[0]) continue;
99 /* Check if it's actually a symbolic link */
100 if (wcscmp(QueryBuffer
->TypeName
.Buffer
, SYMLINK_NAME
))
103 InitializeObjectAttributes(&ObjectAttributes
,
105 OBJ_CASE_INSENSITIVE
,
108 Status
= NtOpenSymbolicLinkObject(&hSymLink
,
111 if (NT_SUCCESS(Status
))
113 /* Setup the Target String */
114 LinkTarget
.Length
= 0;
115 LinkTarget
.MaximumLength
= sizeof(SymLinkBuffer
);
116 LinkTarget
.Buffer
= SymLinkBuffer
;
118 /* Query the target */
119 Status
= NtQuerySymbolicLinkObject(hSymLink
,
123 /* Close the handle */
129 /* FIXME: Loop never ends! */
134 * @name CsrLoadServerDllFromCommandLine
136 * The CsrLoadServerDllFromCommandLine routine loads a Server DLL from the
137 * CSRSS command-line in the registry.
140 * Pointer to the specially formatted string for this Server DLL.
142 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
150 CsrLoadServerDllFromCommandLine(PCHAR KeyValue
)
152 PCHAR EntryPoint
= NULL
;
154 PCHAR ServerString
= KeyValue
;
157 /* Loop the command line */
158 while (*ServerString
)
160 /* Check for the Entry Point */
161 if ((*ServerString
== ':') && (!EntryPoint
))
163 /* Found it. Add a nullchar and save it */
164 *ServerString
++ = '\0';
165 EntryPoint
= ServerString
;
168 /* Check for the Dll Index */
169 if (*ServerString
++ == ',')
171 /* Convert it to a ULONG */
172 Status
= RtlCharToInteger(ServerString
, 10, &DllIndex
);
174 /* Add a null char if it was valid */
175 if (NT_SUCCESS(Status
)) ServerString
[-1] = '\0';
177 /* We're done here */
182 /* We've got the name, entrypoint and index, load it */
183 return CsrLoadServerDll(KeyValue
, EntryPoint
, DllIndex
);
187 * @name CsrpParseCommandLine
189 * The CsrpParseCommandLine routine parses the CSRSS command-line in the
190 * registry and performs operations for each entry found.
192 * @param ArgumentCount
193 * Number of arguments on the command line.
196 * Array of arguments.
198 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
206 CsrpParseCommandLine(IN ULONG ArgumentCount
,
207 IN PCHAR Arguments
[])
210 PCHAR ParameterName
= NULL
;
211 PCHAR ParameterValue
= NULL
;
214 /* Set the Defaults */
215 CsrTotalPerProcessDataLength
= 0;
216 CsrObjectDirectory
= 0;
217 CsrMaxApiRequestThreads
= 16;
219 /* Save our Session ID, and create a Directory for it */
220 SessionId
= NtCurrentPeb()->SessionId
;
221 Status
= CsrCreateSessionObjectDirectory(SessionId
);
222 if (NT_SUCCESS(Status
))
224 DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
227 /* It's not fatal if the SID is 0 */
228 if (SessionId
!= 0) return Status
;
231 /* Loop through every argument */
232 for (i
= 1; i
< ArgumentCount
; i
++)
234 /* Split Name and Value */
235 ParameterName
= Arguments
[i
];
236 ParameterValue
= strchr(ParameterName
, L
'=');
237 *ParameterValue
++ = '\0';
238 DPRINT("Name=%S, Value=%S\n", ParameterName
, ParameterValue
);
240 /* Check for Object Directory */
241 if (!_stricmp(ParameterName
, "ObjectDirectory"))
243 CsrCreateObjectDirectory(ParameterValue
);
245 else if(!_stricmp(ParameterName
, "SubSystemType"))
248 Status
= STATUS_SUCCESS
;
250 else if (!_stricmp(ParameterName
, "MaxRequestThreads"))
252 Status
= RtlCharToInteger(ParameterValue
,
254 &CsrMaxApiRequestThreads
);
256 else if (!_stricmp(ParameterName
, "RequestThreads"))
259 Status
= STATUS_SUCCESS
;
261 else if (!_stricmp(ParameterName
, "ProfileControl"))
263 CsrProfileControl
= (!_stricmp(ParameterValue
, "On")) ? TRUE
: FALSE
;
265 else if (!_stricmp(ParameterName
, "SharedSection"))
267 /* Craete the Section */
268 Status
= CsrSrvCreateSharedSection(ParameterValue
);
271 Status
= CsrLoadServerDll("CSRSS", NULL
, CSR_SRV_SERVER
);
273 else if (!_stricmp(ParameterName
, "ServerDLL"))
275 /* Parse the Command-Line and load this DLL */
276 Status
= CsrLoadServerDllFromCommandLine(ParameterValue
);
278 else if (!_stricmp(ParameterName
, "Windows"))
281 Status
= STATUS_SUCCESS
;
285 /* Invalid parameter on the command line */
286 Status
= STATUS_INVALID_PARAMETER
;
295 * @name CsrCreateObjectDirectory
297 * The CsrCreateObjectDirectory creates the Object Directory on the CSRSS
298 * command-line from the registry.
300 * @param ObjectDirectory
301 * Pointer to the name of the Object Directory to create.
303 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
311 CsrCreateObjectDirectory(IN PCHAR ObjectDirectory
)
313 NTSTATUS Status
= STATUS_SUCCESS
;
314 ANSI_STRING TempString
;
315 OBJECT_ATTRIBUTES DirectoryAttributes
;
317 DPRINT("CSRSRV:%s(%s) called\n", __FUNCTION__
, ObjectDirectory
);
319 /* Convert the parameter to our Global Unicode name */
320 RtlInitAnsiString(&TempString
, ObjectDirectory
);
321 Status
= RtlAnsiStringToUnicodeString(&CsrDirectoryName
, &TempString
, TRUE
);
323 /* Initialize the attributes for the Directory */
324 InitializeObjectAttributes(&DirectoryAttributes
,
326 OBJ_PERMANENT
| OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
331 Status
= NtCreateDirectoryObject(&CsrObjectDirectory
,
332 DIRECTORY_ALL_ACCESS
,
333 &DirectoryAttributes
);
334 if (!NT_SUCCESS(Status
))
336 DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
337 __FUNCTION__
, Status
);
340 /* Set the Security */
341 Status
= CsrSetDirectorySecurity(CsrObjectDirectory
);
348 * @name CsrCreateLocalSystemSD
350 * The CsrCreateLocalSystemSD routine creates a Security Descriptor for
351 * the local account with PORT_ALL_ACCESS.
353 * @param LocalSystemSd
354 * Pointer to a pointer to the security descriptor to create.
356 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
364 CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR
*LocalSystemSd
)
366 SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
369 PSECURITY_DESCRIPTOR SecurityDescriptor
;
373 /* Initialize the System SID */
374 RtlAllocateAndInitializeSid(&NtSidAuthority
,
376 SECURITY_LOCAL_SYSTEM_RID
,
386 /* Get the length of the SID */
387 SidLength
= RtlLengthSid(SystemSid
);
389 /* Allocate a buffer for the Security Descriptor, with SID and DACL */
390 SecurityDescriptor
= RtlAllocateHeap(CsrHeap
,
392 SECURITY_DESCRIPTOR_MIN_LENGTH
+
393 sizeof(ACL
) + SidLength
+
394 sizeof(ACCESS_ALLOWED_ACE
));
396 /* Set the pointer to the DACL */
397 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ SECURITY_DESCRIPTOR_MIN_LENGTH
);
399 /* Now create the SD itself */
400 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
401 SECURITY_DESCRIPTOR_REVISION
);
402 if (!NT_SUCCESS(Status
))
405 RtlFreeHeap(CsrHeap
, 0, SecurityDescriptor
);
409 /* Create the DACL for it*/
411 sizeof(ACL
) + SidLength
+ sizeof(ACCESS_ALLOWED_ACE
),
415 Status
= RtlAddAccessAllowedAce(Dacl
,
419 if (!NT_SUCCESS(Status
))
422 RtlFreeHeap(CsrHeap
, 0, SecurityDescriptor
);
426 /* Clear the DACL in the SD */
427 Status
= RtlSetDaclSecurityDescriptor(SecurityDescriptor
,
431 if (!NT_SUCCESS(Status
))
434 RtlFreeHeap(CsrHeap
, 0, SecurityDescriptor
);
438 /* Free the SID and return*/
439 RtlFreeSid(SystemSid
);
440 *LocalSystemSd
= SecurityDescriptor
;
445 * @name CsrGetDosDevicesSd
447 * The CsrGetDosDevicesSd creates a security descriptor for the DOS Devices
450 * @param DosDevicesSd
451 * Pointer to the Security Descriptor to return.
453 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
456 * @remarks Depending on the DOS Devices Protection Mode (set in the registry),
457 * regular users may or may not have full access to the directory.
462 CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd
)
464 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
465 SID_IDENTIFIER_AUTHORITY CreatorAuthority
= {SECURITY_CREATOR_SID_AUTHORITY
};
466 SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
467 PSID WorldSid
, CreatorSid
, AdminSid
, SystemSid
;
468 UCHAR KeyValueBuffer
[0x40];
469 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
470 UNICODE_STRING KeyName
;
471 ULONG ProtectionMode
= 0;
472 OBJECT_ATTRIBUTES ObjectAttributes
;
474 PACCESS_ALLOWED_ACE Ace
;
477 ULONG ResultLength
, SidLength
;
480 RtlCreateSecurityDescriptor(DosDevicesSd
, SECURITY_DESCRIPTOR_REVISION
);
482 /* Initialize the System SID */
483 RtlAllocateAndInitializeSid(&NtSidAuthority
,
485 SECURITY_LOCAL_SYSTEM_RID
,
495 /* Initialize the World SID */
496 RtlAllocateAndInitializeSid(&WorldAuthority
,
508 /* Initialize the Admin SID */
509 RtlAllocateAndInitializeSid(&NtSidAuthority
,
511 SECURITY_BUILTIN_DOMAIN_RID
,
512 DOMAIN_ALIAS_RID_ADMINS
,
521 /* Initialize the Creator SID */
522 RtlAllocateAndInitializeSid(&CreatorAuthority
,
524 SECURITY_CREATOR_OWNER_RID
,
534 /* Open the Session Manager Key */
535 RtlInitUnicodeString(&KeyName
, SM_REG_KEY
);
536 InitializeObjectAttributes(&ObjectAttributes
,
538 OBJ_CASE_INSENSITIVE
,
541 if (NT_SUCCESS(Status
= NtOpenKey(&hKey
,
545 /* Read the ProtectionMode. See http://support.microsoft.com/kb/q218473/ */
546 RtlInitUnicodeString(&KeyName
, L
"ProtectionMode");
547 Status
= NtQueryValueKey(hKey
,
549 KeyValuePartialInformation
,
551 sizeof(KeyValueBuffer
),
554 /* Make sure it's what we expect it to be */
555 KeyValuePartialInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)KeyValueBuffer
;
556 if ((KeyValuePartialInfo
->Type
== REG_DWORD
) &&
557 (*(PULONG
)KeyValuePartialInfo
->Data
!= 0))
559 /* Save the Protection Mode */
560 ProtectionMode
= *(PULONG
)KeyValuePartialInfo
->Data
;
563 /* Close the handle */
567 /* Check the Protection Mode */
568 if (ProtectionMode
& 3)
570 /* Calculate SID Lengths */
571 SidLength
= RtlLengthSid(CreatorSid
) + RtlLengthSid(SystemSid
) +
572 RtlLengthSid(AdminSid
);
574 /* Allocate memory for the DACL */
575 Dacl
= RtlAllocateHeap(CsrHeap
,
577 sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) +
581 Status
= RtlCreateAcl(Dacl
,
582 sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) +
586 /* Give full access to the System */
587 Status
= RtlAddAccessAllowedAce(Dacl
,
592 /* Get the ACE back */
593 Status
= RtlGetAce(Dacl
, 0, (PVOID
*)&Ace
);
595 /* Add some flags to it for the Admin SID */
596 Ace
->Header
.AceFlags
|= (OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
);
598 /* Add the ACE to the Admin SID */
599 Status
= RtlAddAccessAllowedAce(Dacl
,
604 /* Get the ACE back */
605 Status
= RtlGetAce(Dacl
, 1, (PVOID
*)&Ace
);
607 /* Add some flags to it for the Creator SID */
608 Ace
->Header
.AceFlags
|= (OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
);
610 /* Add the ACE to the Admin SID */
611 Status
= RtlAddAccessAllowedAce(Dacl
,
616 /* Get the ACE back */
617 Status
= RtlGetAce(Dacl
, 2, (PVOID
*)&Ace
);
619 /* Add some flags to it for the SD */
620 Ace
->Header
.AceFlags
|= (OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
|
623 /* Set this DACL with the SD */
624 Status
= RtlSetDaclSecurityDescriptor(DosDevicesSd
,
631 /* Calculate SID Lengths */
632 SidLength
= RtlLengthSid(WorldSid
) + RtlLengthSid(SystemSid
);
634 /* Allocate memory for the DACL */
635 Dacl
= RtlAllocateHeap(CsrHeap
,
637 sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) +
641 Status
= RtlCreateAcl(Dacl
,
642 sizeof(ACL
) + 3 * sizeof(ACCESS_ALLOWED_ACE
) +
646 /* Give RWE access to the World */
647 Status
= RtlAddAccessAllowedAce(Dacl
,
649 GENERIC_READ
| GENERIC_WRITE
|
653 /* Give full access to the System */
654 Status
= RtlAddAccessAllowedAce(Dacl
,
659 /* Give full access to the World */
660 Status
= RtlAddAccessAllowedAce(Dacl
,
665 /* Get the ACE back */
666 Status
= RtlGetAce(Dacl
, 2, (PVOID
*)&Ace
);
668 /* Add some flags to it for the SD */
669 Ace
->Header
.AceFlags
|= (OBJECT_INHERIT_ACE
| CONTAINER_INHERIT_ACE
|
672 /* Set this DACL with the SD */
673 Status
= RtlSetDaclSecurityDescriptor(DosDevicesSd
,
679 /* FIXME: failure cases! Fail: */
680 /* Free the memory */
681 RtlFreeHeap(CsrHeap
, 0, Dacl
);
683 /* FIXME: semi-failure cases! Quickie: */
685 RtlFreeSid(SystemSid
);
686 RtlFreeSid(WorldSid
);
687 RtlFreeSid(AdminSid
);
688 RtlFreeSid(CreatorSid
);
695 * @name CsrFreeDosDevicesSd
697 * The CsrFreeDosDevicesSd frees the security descriptor that was created
698 * by CsrGetDosDevicesSd
700 * @param DosDevicesSd
701 * Pointer to the security descriptor to free.
710 CsrFreeDosDevicesSd(IN PSECURITY_DESCRIPTOR DosDevicesSd
)
713 BOOLEAN Present
, Default
;
716 /* Get the DACL corresponding to this SD */
717 Status
= RtlGetDaclSecurityDescriptor(DosDevicesSd
,
723 if (NT_SUCCESS(Status
) && Dacl
) RtlFreeHeap(CsrHeap
, 0, Dacl
);
727 * @name CsrCreateSessionObjectDirectory
729 * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects,
730 * Session and Dos Devices directories for the specified session.
733 * Session ID for which to create the directories.
735 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
743 CsrCreateSessionObjectDirectory(IN ULONG Session
)
745 WCHAR SessionBuffer
[512];
746 WCHAR BnoBuffer
[512];
747 UNICODE_STRING SessionString
;
748 UNICODE_STRING BnoString
;
749 OBJECT_ATTRIBUTES ObjectAttributes
;
751 SECURITY_DESCRIPTOR DosDevicesSd
;
754 /* Generate the Session BNOLINKS Directory */
755 swprintf(SessionBuffer
, L
"%ws\\BNOLINKS", SESSION_ROOT
);
756 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
758 /* Initialize the attributes for the Directory */
759 InitializeObjectAttributes(&ObjectAttributes
,
761 OBJ_PERMANENT
| OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
766 Status
= NtCreateDirectoryObject(&BNOLinksDirectory
,
767 DIRECTORY_ALL_ACCESS
,
769 if (!NT_SUCCESS(Status
))
771 DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
772 __FUNCTION__
, Status
);
776 /* Now add the Session ID */
777 swprintf(SessionBuffer
, L
"%ld", Session
);
778 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
780 /* Check if this is the first Session */
783 /* Not the first, so the name will be slighly more complex */
784 swprintf(BnoBuffer
, L
"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT
, Session
);
788 /* Use the direct name */
789 RtlCopyMemory(BnoBuffer
, L
"\\BaseNamedObjects", 36);
792 /* Create the Unicode String for the BNO SymLink */
793 RtlInitUnicodeString(&BnoString
, BnoBuffer
);
795 /* Initialize the attributes for the SymLink */
796 InitializeObjectAttributes(&ObjectAttributes
,
798 OBJ_PERMANENT
| OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
803 Status
= NtCreateSymbolicLinkObject(&BnoHandle
,
804 SYMBOLIC_LINK_ALL_ACCESS
,
807 if (!NT_SUCCESS(Status
))
809 DPRINT1("CSRSRV:%s: fatal: NtCreateSymbolicLinkObject failed (Status=0x%08lx)\n",
810 __FUNCTION__
, Status
);
814 /* Create the \DosDevices Security Descriptor */
815 CsrGetDosDevicesSd(&DosDevicesSd
);
817 /* Now create a directory for this session */
818 swprintf(SessionBuffer
, L
"%ws\\%ld", SESSION_ROOT
, Session
);
819 RtlInitUnicodeString(&SessionString
, SessionBuffer
);
821 /* Initialize the attributes for the Directory */
822 InitializeObjectAttributes(&ObjectAttributes
,
824 OBJ_PERMANENT
| OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
829 Status
= NtCreateDirectoryObject(&SessionObjectDirectory
,
830 DIRECTORY_ALL_ACCESS
,
832 if (!NT_SUCCESS(Status
))
834 DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
835 __FUNCTION__
, Status
);
836 /* Release the Security Descriptor */
837 CsrFreeDosDevicesSd(&DosDevicesSd
);
841 /* Next, create a directory for this session's DOS Devices */
842 /* Now create a directory for this session */
843 RtlInitUnicodeString(&SessionString
, L
"DosDevices");
845 /* Initialize the attributes for the Directory */
846 InitializeObjectAttributes(&ObjectAttributes
,
848 OBJ_PERMANENT
| OBJ_OPENIF
| OBJ_CASE_INSENSITIVE
,
853 Status
= NtCreateDirectoryObject(&DosDevicesDirectory
,
854 DIRECTORY_ALL_ACCESS
,
856 if (!NT_SUCCESS(Status
))
858 DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
859 __FUNCTION__
, Status
);
862 /* Release the Security Descriptor */
863 CsrFreeDosDevicesSd(&DosDevicesSd
);
870 * @name CsrSetProcessSecurity
872 * The CsrSetProcessSecurity routine protects access to the CSRSS process
873 * from unauthorized tampering.
877 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
885 CsrSetProcessSecurity(VOID
)
890 PTOKEN_USER TokenUserInformation
;
891 PSECURITY_DESCRIPTOR SecurityDescriptor
;
895 Status
= NtOpenProcessToken(NtCurrentProcess(),
898 if (!NT_SUCCESS(Status
)) return Status
;
900 /* Get the Token User Length */
901 NtQueryInformationToken(hToken
,
907 /* Allocate space for it */
908 TokenUserInformation
= RtlAllocateHeap(CsrHeap
,
912 /* Now query the data */
913 Status
= NtQueryInformationToken(hToken
,
915 TokenUserInformation
,
919 /* Close the handle */
922 /* Make sure that we got the data */
923 if (!NT_SUCCESS(Status
))
926 RtlFreeHeap(CsrHeap
, 0, TokenUserInformation
);
930 /* Now check the SID Length */
931 ReturnLength
= RtlLengthSid(TokenUserInformation
->User
.Sid
);
933 /* Allocate a buffer for the Security Descriptor, with SID and DACL */
934 SecurityDescriptor
= RtlAllocateHeap(CsrHeap
,
936 SECURITY_DESCRIPTOR_MIN_LENGTH
+
937 sizeof(ACL
) + ReturnLength
+
938 sizeof(ACCESS_ALLOWED_ACE
));
940 /* Set the pointer to the DACL */
941 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ SECURITY_DESCRIPTOR_MIN_LENGTH
);
943 /* Now create the SD itself */
944 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
945 SECURITY_DESCRIPTOR_REVISION
);
946 if (!NT_SUCCESS(Status
))
949 RtlFreeHeap(CsrHeap
, 0, SecurityDescriptor
);
950 RtlFreeHeap(CsrHeap
, 0, TokenUserInformation
);
954 /* Create the DACL for it*/
956 sizeof(ACL
) + ReturnLength
+ sizeof(ACCESS_ALLOWED_ACE
),
960 Status
= RtlAddAccessAllowedAce(Dacl
,
962 PROCESS_VM_READ
| PROCESS_VM_WRITE
|
963 PROCESS_VM_OPERATION
| PROCESS_DUP_HANDLE
|
964 PROCESS_TERMINATE
| PROCESS_SUSPEND_RESUME
|
965 PROCESS_QUERY_INFORMATION
| READ_CONTROL
,
966 TokenUserInformation
->User
.Sid
);
967 if (!NT_SUCCESS(Status
))
970 RtlFreeHeap(CsrHeap
, 0, SecurityDescriptor
);
971 RtlFreeHeap(CsrHeap
, 0, TokenUserInformation
);
975 /* Clear the DACL in the SD */
976 Status
= RtlSetDaclSecurityDescriptor(SecurityDescriptor
,
980 if (!NT_SUCCESS(Status
))
983 RtlFreeHeap(CsrHeap
, 0, SecurityDescriptor
);
984 RtlFreeHeap(CsrHeap
, 0, TokenUserInformation
);
988 /* Write the SD into the Process */
989 Status
= NtSetSecurityObject(NtCurrentProcess(),
990 DACL_SECURITY_INFORMATION
,
993 /* Free the memory and return */
994 RtlFreeHeap(CsrHeap
, 0, SecurityDescriptor
);
995 RtlFreeHeap(CsrHeap
, 0, TokenUserInformation
);
1000 * @name CsrSetDirectorySecurity
1002 * The CsrSetDirectorySecurity routine sets the security descriptor for the
1003 * specified Object Directory.
1005 * @param ObjectDirectory
1006 * Handle fo the Object Directory to protect.
1008 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
1016 CsrSetDirectorySecurity(IN HANDLE ObjectDirectory
)
1018 /* FIXME: Implement */
1019 return STATUS_SUCCESS
;
1022 /* PUBLIC FUNCTIONS **********************************************************/
1025 * @name CsrServerInitialization
1028 * The CsrServerInitialization routine is the native (not Server) entrypoint
1029 * of this Server DLL. It serves as the entrypoint for csrss.
1031 * @param ArgumentCount
1032 * Number of arguments on the command line.
1035 * Array of arguments from the command line.
1037 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
1045 CsrServerInitialization(ULONG ArgumentCount
,
1048 NTSTATUS Status
= STATUS_SUCCESS
;
1051 PCSR_SERVER_DLL ServerDll
;
1053 DPRINT("CSRSRV: %s called\n", __FUNCTION__
);
1055 /* Create the Init Event */
1056 Status
= NtCreateEvent(&CsrInitializationEvent
,
1059 SynchronizationEvent
,
1062 /* Cache System Basic Information so we don't always request it */
1063 Status
= NtQuerySystemInformation(SystemBasicInformation
,
1065 sizeof(SYSTEM_BASIC_INFORMATION
),
1069 CsrHeap
= RtlGetProcessHeap();
1071 /* Set our Security Descriptor to protect the process */
1072 CsrSetProcessSecurity();
1074 /* Set up Session Support */
1075 Status
= CsrInitializeNtSessions();
1076 if(!NT_SUCCESS(Status
))
1078 DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
1079 __FUNCTION__
, Status
);
1083 /* Set up Process Support */
1084 Status
= CsrInitializeProcesses();
1085 if(!NT_SUCCESS(Status
))
1087 DPRINT1("CSRSRV:%s: CsrInitializeProcesses failed (Status=%08lx)\n",
1088 __FUNCTION__
, Status
);
1092 /* Parse the command line */
1093 CsrpParseCommandLine(ArgumentCount
, Arguments
);
1095 /* All Server DLLs are now loaded, allocate a heap for the Root Process */
1096 ProcessData
= RtlAllocateHeap(CsrHeap
,
1098 CsrTotalPerProcessDataLength
);
1101 * Our Root Process was never officially initalized, so write the data
1102 * for each Server DLL manually.
1104 for(i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
1106 /* Get the current Server */
1107 ServerDll
= CsrLoadedServerDll
[i
];
1109 /* Is it loaded, and does it have per process data? */
1110 if (ServerDll
&& ServerDll
->SizeOfProcessData
)
1112 /* It does, give it part of our allocated heap */
1113 CsrRootProcess
->ServerData
[i
] = ProcessData
;
1115 /* Move to the next heap position */
1116 ProcessData
= (PVOID
)((ULONG_PTR
)ProcessData
+
1117 ServerDll
->SizeOfProcessData
);
1121 /* Nothing for this Server DLL */
1122 CsrRootProcess
->ServerData
[i
] = NULL
;
1126 /* Now initialize the Root Process manually as well */
1127 for(i
= 0; i
< CSR_SERVER_DLL_MAX
; i
++)
1129 /* Get the current Server */
1130 ServerDll
= CsrLoadedServerDll
[i
];
1132 /* Is it loaded, and does it a callback for new processes? */
1133 if (ServerDll
&& ServerDll
->NewProcessCallback
)
1135 /* Call the callback */
1136 (*ServerDll
->NewProcessCallback
)(NULL
, CsrRootProcess
);
1140 /* Now initialize our API Port */
1141 Status
= CsrApiPortInitialize();
1142 if(!NT_SUCCESS(Status
))
1144 DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
1145 __FUNCTION__
, Status
);
1149 /* Initialize the API Port for SM communication */
1150 Status
= CsrSbApiPortInitialize();
1151 if(!NT_SUCCESS(Status
))
1153 DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
1154 __FUNCTION__
, Status
);
1158 /* We're all set! Connect to SM! */
1159 Status
= SmConnectToSm(&CsrSbApiPortName
,
1161 IMAGE_SUBSYSTEM_WINDOWS_GUI
,
1163 if(!NT_SUCCESS(Status
))
1165 DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
1166 __FUNCTION__
, Status
);
1170 /* Finito! Signal the event */
1171 NtSetEvent(CsrInitializationEvent
, NULL
);
1172 NtClose(CsrInitializationEvent
);
1174 /* Have us handle Hard Errors */
1175 NtSetDefaultHardErrorPort(CsrApiPort
);
1182 * @name CsrPopulateDosDevices
1183 * @implemented NT5.1
1185 * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
1186 * to populate the Dos Devices Object Directory for the session.
1197 CsrPopulateDosDevices(VOID
)
1200 PROCESS_DEVICEMAP_INFORMATION OldDeviceMap
;
1201 PROCESS_DEVICEMAP_INFORMATION NewDeviceMap
;
1203 /* Query the Device Map */
1204 Status
= NtQueryInformationProcess(NtCurrentProcess(),
1206 &OldDeviceMap
.Query
,
1207 sizeof(PROCESS_DEVICEMAP_INFORMATION
),
1209 if (!NT_SUCCESS(Status
)) return;
1211 /* Set the new one */
1212 NewDeviceMap
.Set
.DirectoryHandle
= DosDevicesDirectory
;
1213 Status
= NtSetInformationProcess(NtCurrentProcess(),
1217 if (!NT_SUCCESS(Status
)) return;
1219 /* Populate the Directory */
1220 CsrPopulateDosDevicesDirectory(DosDevicesDirectory
, &OldDeviceMap
);
1225 DllMainCRTStartup(HANDLE hDll
,
1229 /* We don't do much */
1230 UNREFERENCED_PARAMETER(hDll
);
1231 UNREFERENCED_PARAMETER(dwReason
);
1232 UNREFERENCED_PARAMETER(lpReserved
);