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

📄 init.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
                               OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
                               0,
                               &DosDevicesSd);

    /* Create it */
    Status = NtCreateDirectoryObject(&SessionObjectDirectory,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
                __FUNCTION__, Status);
        /* Release the Security Descriptor */
        CsrFreeDosDevicesSd(&DosDevicesSd);
        return Status;
    }

    /* Next, create a directory for this session's DOS Devices */
    /* Now create a directory for this session */
    RtlInitUnicodeString(&SessionString, L"DosDevices");

    /* Initialize the attributes for the Directory */
    InitializeObjectAttributes(&ObjectAttributes,
                               &SessionString,
                               OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
                               0,
                               &DosDevicesSd);

    /* Create it */
    Status = NtCreateDirectoryObject(&DosDevicesDirectory,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
                __FUNCTION__, Status);
    }

    /* Release the Security Descriptor */
    CsrFreeDosDevicesSd(&DosDevicesSd);

    /* Return */
    return Status;
}

/*++
 * @name CsrSetProcessSecurity
 *
 * The CsrSetProcessSecurity routine protects access to the CSRSS process
 * from unauthorized tampering.
 *
 * @param None.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrSetProcessSecurity(VOID)
{
    NTSTATUS Status;
    HANDLE hToken;
    ULONG ReturnLength;
    PTOKEN_USER TokenUserInformation;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    PACL Dacl;

    /* Open our token */
    Status = NtOpenProcessToken(NtCurrentProcess(),
                                TOKEN_QUERY,
                                &hToken);
    if (!NT_SUCCESS(Status)) return Status;

    /* Get the Token User Length */
    NtQueryInformationToken(hToken,
                            TokenUser,
                            NULL,
                            0,
                            &ReturnLength);

    /* Allocate space for it */
    TokenUserInformation = RtlAllocateHeap(CsrHeap,
                                           HEAP_ZERO_MEMORY,
                                           ReturnLength);

    /* Now query the data */
    Status = NtQueryInformationToken(hToken,
                                     TokenUser,
                                     TokenUserInformation,
                                     ReturnLength,
                                     &ReturnLength);

    /* Close the handle */
    NtClose(hToken);

    /* Make sure that we got the data */
    if (!NT_SUCCESS(Status))
    {
        /* FAil */
        RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
        return Status;
    }

    /* Now check the SID Length */
    ReturnLength = RtlLengthSid(TokenUserInformation->User.Sid);

    /* Allocate a buffer for the Security Descriptor, with SID and DACL */
    SecurityDescriptor = RtlAllocateHeap(CsrHeap,
                                         HEAP_ZERO_MEMORY,
                                         SECURITY_DESCRIPTOR_MIN_LENGTH +
                                         sizeof(ACL) + ReturnLength +
                                         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);
        RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
        return Status;
    }

    /* Create the DACL for it*/
    RtlCreateAcl(Dacl,
                 sizeof(ACL) + ReturnLength + sizeof(ACCESS_ALLOWED_ACE),
                 ACL_REVISION2);

    /* Create the ACE */
    Status = RtlAddAccessAllowedAce(Dacl,
                                    ACL_REVISION,
                                    PROCESS_VM_READ | PROCESS_VM_WRITE |
                                    PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
                                    PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
                                    PROCESS_QUERY_INFORMATION | READ_CONTROL,
                                    TokenUserInformation->User.Sid);
    if (!NT_SUCCESS(Status))
    {
        /* Fail */
        RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
        RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
        return Status;
    }

    /* Clear the DACL in the SD */
    Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
                                          TRUE,
                                          Dacl,
                                          FALSE);
    if (!NT_SUCCESS(Status))
    {
        /* Fail */
        RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
        RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
        return Status;
    }

    /* Write the SD into the Process */
    Status = NtSetSecurityObject(NtCurrentProcess(),
                                 DACL_SECURITY_INFORMATION,
                                 SecurityDescriptor);

    /* Free the memory and return */
    RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
    RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
    return Status;
}

/*++
 * @name CsrSetDirectorySecurity
 *
 * The CsrSetDirectorySecurity routine sets the security descriptor for the
 * specified Object Directory.
 *
 * @param ObjectDirectory
 *        Handle fo the Object Directory to protect.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrSetDirectorySecurity(IN HANDLE ObjectDirectory)
{
    /* FIXME: Implement */
    return STATUS_SUCCESS;
}

/* PUBLIC FUNCTIONS **********************************************************/

/*++
 * @name CsrServerInitialization
 * @implemented NT4
 *
 * The CsrServerInitialization routine is the native (not Server) entrypoint
 * of this Server DLL. It serves as the entrypoint for csrss.
 *
 * @param ArgumentCount
 *        Number of arguments on the command line.
 *
 * @param Arguments
 *        Array of arguments from the command line.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrServerInitialization(ULONG ArgumentCount,
                        PCHAR Arguments[])
{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG i = 0;
    PVOID ProcessData;
    PCSR_SERVER_DLL ServerDll;

    DPRINT("CSRSRV: %s called\n", __FUNCTION__);

    /* Create the Init Event */
    Status = NtCreateEvent(&CsrInitializationEvent,
                           EVENT_ALL_ACCESS,
                           NULL,
                           SynchronizationEvent,
                           FALSE);

    /* Cache System Basic Information so we don't always request it */
    Status = NtQuerySystemInformation(SystemBasicInformation,
                                      &CsrNtSysInfo,
                                      sizeof(SYSTEM_BASIC_INFORMATION),
                                      NULL);

    /* Save our Heap */
    CsrHeap = RtlGetProcessHeap();

    /* Set our Security Descriptor to protect the process */
    CsrSetProcessSecurity();

    /* Set up Session Support */
    Status = CsrInitializeNtSessions();
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Set up Process Support */
    Status = CsrInitializeProcesses();
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrInitializeProcesses failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Parse the command line */
    CsrpParseCommandLine(ArgumentCount, Arguments);

    /* All Server DLLs are now loaded, allocate a heap for the Root Process */
    ProcessData = RtlAllocateHeap(CsrHeap,
                                  HEAP_ZERO_MEMORY,
                                  CsrTotalPerProcessDataLength);

    /*
     * Our Root Process was never officially initalized, so write the data
     * for each Server DLL manually.
     */
    for(i = 0; i < CSR_SERVER_DLL_MAX; i++)
    {
        /* Get the current Server */
        ServerDll = CsrLoadedServerDll[i];

        /* Is it loaded, and does it have per process data? */
        if (ServerDll && ServerDll->SizeOfProcessData)
        {
            /* It does, give it part of our allocated heap */
            CsrRootProcess->ServerData[i] = ProcessData;

            /* Move to the next heap position */
            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
                                  ServerDll->SizeOfProcessData);
        }
        else
        {
            /* Nothing for this Server DLL */
            CsrRootProcess->ServerData[i] = NULL;
        }
    }

    /* Now initialize the Root Process manually as well */
    for(i = 0; i < CSR_SERVER_DLL_MAX; i++)
    {
        /* Get the current Server */
        ServerDll = CsrLoadedServerDll[i];

        /* Is it loaded, and does it a callback for new processes? */
        if (ServerDll && ServerDll->NewProcessCallback)
        {
            /* Call the callback */
            (*ServerDll->NewProcessCallback)(NULL, CsrRootProcess);
        }
    }

    /* Now initialize our API Port */
    Status = CsrApiPortInitialize();
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Initialize the API Port for SM communication */
    Status = CsrSbApiPortInitialize();
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* We're all set! Connect to SM! */
    Status = SmConnectToSm(&CsrSbApiPortName,
                           CsrSbApiPort,
                           IMAGE_SUBSYSTEM_WINDOWS_GUI,
                           &CsrSmApiPort);
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Finito! Signal the event */
    NtSetEvent(CsrInitializationEvent, NULL);
    NtClose(CsrInitializationEvent);

    /* Have us handle Hard Errors */
    NtSetDefaultHardErrorPort(CsrApiPort);
    
    /* Return status */
    return Status;
}

/*++
 * @name CsrPopulateDosDevices
 * @implemented NT5.1
 *
 * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
 * to populate the Dos Devices Object Directory for the session.
 *
 * @param None.
 *
 * @return None.
 *
 * @remarks None.
 *
 *--*/
VOID
NTAPI
CsrPopulateDosDevices(VOID)
{
    NTSTATUS Status;
    PROCESS_DEVICEMAP_INFORMATION OldDeviceMap;
    PROCESS_DEVICEMAP_INFORMATION NewDeviceMap;

    /* Query the Device Map */
    Status = NtQueryInformationProcess(NtCurrentProcess(),
                                       ProcessDeviceMap,
                                       &OldDeviceMap.Query,
                                       sizeof(PROCESS_DEVICEMAP_INFORMATION),
                                       NULL);
    if (!NT_SUCCESS(Status)) return;

    /* Set the new one */
    NewDeviceMap.Set.DirectoryHandle = DosDevicesDirectory;
    Status = NtSetInformationProcess(NtCurrentProcess(),
                                     ProcessDeviceMap,
                                     &NewDeviceMap,
                                     sizeof(ULONG));
    if (!NT_SUCCESS(Status)) return;

    /* Populate the Directory */
    CsrPopulateDosDevicesDirectory(DosDevicesDirectory, &OldDeviceMap);
}

BOOL
NTAPI
DllMain(HANDLE hDll,
        DWORD dwReason,
        LPVOID lpReserved)
{
    /* We don't do much */
    return TRUE;
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -