📄 init.c
字号:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsys/csr/csrsrv/init.c
* PURPOSE: CSR Server DLL Initialization
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
HANDLE CsrObjectDirectory;
ULONG SessionId;
BOOLEAN CsrProfileControl;
UNICODE_STRING CsrDirectoryName;
HANDLE CsrHeap;
HANDLE BNOLinksDirectory;
HANDLE SessionObjectDirectory;
HANDLE DosDevicesDirectory;
HANDLE CsrInitializationEvent;
SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
/* PRIVATE FUNCTIONS *********************************************************/
/*++
* @name CsrPopulateDosDevicesDirectory
*
* The CsrPopulateDosDevicesDirectory routine uses the DOS Device Map from the
* Kernel to populate the Dos Devices Object Directory for the session.
*
* @param TODO.
*
* @return TODO.
*
* @remarks TODO.
*
*--*/
NTSTATUS
NTAPI
CsrPopulateDosDevicesDirectory(IN HANDLE hDosDevicesDirectory,
IN PPROCESS_DEVICEMAP_INFORMATION DeviceMap)
{
WCHAR SymLinkBuffer[0x1000];
UNICODE_STRING GlobalString;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hDirectory = 0;
NTSTATUS Status;
ULONG ReturnLength = 0;
ULONG BufferLength = 0x4000;
ULONG Context;
POBJECT_DIRECTORY_INFORMATION QueryBuffer;
HANDLE hSymLink;
UNICODE_STRING LinkTarget;
/* Initialize the Global String */
RtlInitUnicodeString(&GlobalString, GLOBAL_ROOT);
/* Initialize the Object Attributes */
InitializeObjectAttributes(&ObjectAttributes,
&GlobalString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Open the directory */
Status = NtOpenDirectoryObject(&hDirectory,
DIRECTORY_QUERY,
&ObjectAttributes);
if (!NT_SUCCESS(Status)) return Status;
/* Allocate memory */
QueryBuffer = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, 0x4000);
if (!QueryBuffer) return STATUS_NO_MEMORY;
/* Start query loop */
while (TRUE)
{
/* Query the Directory */
Status = NtQueryDirectoryObject(hDirectory,
QueryBuffer,
BufferLength,
FALSE,
FALSE,
&Context,
&ReturnLength);
/* Check for the status */
if (NT_SUCCESS(Status))
{
/* Make sure it has a name */
if (!QueryBuffer->Name.Buffer[0]) continue;
/* Check if it's actually a symbolic link */
if (wcscmp(QueryBuffer->TypeName.Buffer, SYMLINK_NAME))
{
/* It is, open it */
InitializeObjectAttributes(&ObjectAttributes,
&QueryBuffer->Name,
OBJ_CASE_INSENSITIVE,
NULL,
hDirectory);
Status = NtOpenSymbolicLinkObject(&hSymLink,
SYMBOLIC_LINK_QUERY,
&ObjectAttributes);
if (NT_SUCCESS(Status))
{
/* Setup the Target String */
LinkTarget.Length = 0;
LinkTarget.MaximumLength = sizeof(SymLinkBuffer);
LinkTarget.Buffer = SymLinkBuffer;
/* Query the target */
Status = NtQuerySymbolicLinkObject(hSymLink,
&LinkTarget,
&ReturnLength);
/* Close the handle */
NtClose(hSymLink);
}
}
}
}
}
/*++
* @name CsrLoadServerDllFromCommandLine
*
* The CsrLoadServerDllFromCommandLine routine loads a Server DLL from the
* CSRSS command-line in the registry.
*
* @param KeyValue
* Pointer to the specially formatted string for this Server DLL.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrLoadServerDllFromCommandLine(PCHAR KeyValue)
{
PCHAR EntryPoint = NULL;
ULONG DllIndex = 0;
PCHAR ServerString = KeyValue;
NTSTATUS Status;
/* Loop the command line */
while (*ServerString)
{
/* Check for the Entry Point */
if ((*ServerString == ':') && (!EntryPoint))
{
/* Found it. Add a nullchar and save it */
*ServerString++ = '\0';
EntryPoint = ServerString;
}
/* Check for the Dll Index */
if (*ServerString++ == ',')
{
/* Convert it to a ULONG */
Status = RtlCharToInteger(ServerString, 10, &DllIndex);
/* Add a null char if it was valid */
if (NT_SUCCESS(Status)) ServerString[-1] = '\0';
/* We're done here */
break;
}
}
/* We've got the name, entrypoint and index, load it */
return CsrLoadServerDll(KeyValue, EntryPoint, DllIndex);
}
/*++
* @name CsrpParseCommandLine
*
* The CsrpParseCommandLine routine parses the CSRSS command-line in the
* registry and performs operations for each entry found.
*
* @param ArgumentCount
* Number of arguments on the command line.
*
* @param Arguments
* Array of arguments.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
FASTCALL
CsrpParseCommandLine(IN ULONG ArgumentCount,
IN PCHAR Arguments[])
{
NTSTATUS Status;
PCHAR ParameterName = NULL;
PCHAR ParameterValue = NULL;
ULONG i;
/* Set the Defaults */
CsrTotalPerProcessDataLength = 0;
CsrObjectDirectory = 0;
CsrMaxApiRequestThreads = 16;
/* Save our Session ID, and create a Directory for it */
SessionId = NtCurrentPeb()->SessionId;
Status = CsrCreateSessionObjectDirectory(SessionId);
if (NT_SUCCESS(Status))
{
DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
Status);
/* It's not fatal if the SID is 0 */
if (SessionId != 0) return Status;
}
/* Loop through every argument */
for (i = 1; i < ArgumentCount; i++)
{
/* Split Name and Value */
ParameterName = Arguments[i];
ParameterValue = strchr(ParameterName, L'=');
*ParameterValue++ = '\0';
DPRINT("Name=%S, Value=%S\n", ParameterName, ParameterValue);
/* Check for Object Directory */
if (!_stricmp(ParameterName, "ObjectDirectory"))
{
CsrCreateObjectDirectory(ParameterValue);
}
else if(!_stricmp(ParameterName, "SubSystemType"))
{
/* Ignored */
Status = STATUS_SUCCESS;
}
else if (!_stricmp(ParameterName, "MaxRequestThreads"))
{
Status = RtlCharToInteger(ParameterValue,
0,
&CsrMaxApiRequestThreads);
}
else if (!_stricmp(ParameterName, "RequestThreads"))
{
/* Ignored */
Status = STATUS_SUCCESS;
}
else if (!_stricmp(ParameterName, "ProfileControl"))
{
CsrProfileControl = (!_stricmp(ParameterValue, "On")) ? TRUE : FALSE;
}
else if (!_stricmp(ParameterName, "SharedSection"))
{
/* Craete the Section */
Status = CsrSrvCreateSharedSection(ParameterValue);
/* Load us */
Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER);
}
else if (!_stricmp(ParameterName, "ServerDLL"))
{
/* Parse the Command-Line and load this DLL */
Status = CsrLoadServerDllFromCommandLine(ParameterValue);
}
else if (!_stricmp(ParameterName, "Windows"))
{
/* Ignored */
Status = STATUS_SUCCESS;
}
else
{
/* Invalid parameter on the command line */
Status = STATUS_INVALID_PARAMETER;
}
}
/* Return status */
return Status;
}
/*++
* @name CsrCreateObjectDirectory
*
* The CsrCreateObjectDirectory creates the Object Directory on the CSRSS
* command-line from the registry.
*
* @param ObjectDirectory
* Pointer to the name of the Object Directory to create.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCreateObjectDirectory(IN PCHAR ObjectDirectory)
{
NTSTATUS Status = STATUS_SUCCESS;
ANSI_STRING TempString;
OBJECT_ATTRIBUTES DirectoryAttributes;
DPRINT("CSRSRV:%s(%s) called\n", __FUNCTION__, ObjectDirectory);
/* Convert the parameter to our Global Unicode name */
RtlInitAnsiString(&TempString, ObjectDirectory);
Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, &TempString, TRUE);
/* Initialize the attributes for the Directory */
InitializeObjectAttributes(&DirectoryAttributes,
&CsrDirectoryName,
OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Create it */
Status = NtCreateDirectoryObject(&CsrObjectDirectory,
DIRECTORY_ALL_ACCESS,
&DirectoryAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
}
/* Set the Security */
Status = CsrSetDirectorySecurity(CsrObjectDirectory);
/* Return */
return Status;
}
/*++
* @name CsrCreateLocalSystemSD
*
* The CsrCreateLocalSystemSD routine creates a Security Descriptor for
* the local account with PORT_ALL_ACCESS.
*
* @param LocalSystemSd
* Pointer to a pointer to the security descriptor to create.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
{
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
PSID SystemSid;
ULONG SidLength;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PACL Dacl;
NTSTATUS Status;
/* Initialize the System SID */
RtlAllocateAndInitializeSid(&NtSidAuthority,
1,
SECURITY_LOCAL_SYSTEM_RID,
0,
0,
0,
0,
0,
0,
0,
&SystemSid);
/* Get the length of the SID */
SidLength = RtlLengthSid(SystemSid);
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
SecurityDescriptor = RtlAllocateHeap(CsrHeap,
0,
SECURITY_DESCRIPTOR_MIN_LENGTH +
sizeof(ACL) + SidLength +
sizeof(ACCESS_ALLOWED_ACE));
/* Set the pointer to the DACL */
Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
/* Now create the SD itself */
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
return Status;
}
/* Create the DACL for it*/
RtlCreateAcl(Dacl,
sizeof(ACL) + SidLength + sizeof(ACCESS_ALLOWED_ACE),
ACL_REVISION2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -