⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -