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

📄 process.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
                CsrImpersonateClient(CsrThread);
                Status = CsrGetProcessLuid(NULL, &ProcessLuid);
                CsrRevertToSelf();
            }
        }

        if (!NT_SUCCESS(Status))
        {
            /* We didn't have access, so skip it */
            CsrProcess->Flags |= CsrProcessSkipShutdown;
            continue;
        }

        /* Check if this is the System LUID */
        if ((IsSystemLuid = RtlEqualLuid(&ProcessLuid, &SystemLuid)))
        {
            /* Mark this process */
            CsrProcess->ShutdownFlags |= CsrShutdownSystem;
        }
        else if (!(IsOurLuid = RtlEqualLuid(&ProcessLuid, CallerLuid)))
        {
            /* Our LUID doesn't match with the caller's */
            CsrProcess->ShutdownFlags |= CsrShutdownOther;
        }

        /* Check if we're past the previous level */
        if (CsrProcess->ShutdownLevel > Level)
        {
            /* Update the level */
            Level = CsrProcess->ShutdownLevel;

            /* Set the final process */
            ReturnCsrProcess = CsrProcess;
        }
    }

    /* Check if we found a process */
    if (ReturnCsrProcess)
    {
        /* Skip this one next time */
        ReturnCsrProcess->Flags |= CsrProcessSkipShutdown;
    }

    return ReturnCsrProcess;
}

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

/*++
 * @name CsrCreateProcess
 * @implemented NT4
 *
 * Do nothing for 500ms.
 *
 * @param ArgumentCount
 *        Description of the parameter. Wrapped to more lines on ~70th
 *        column.
 *
 * @param Arguments
 *        Description of the parameter. Wrapped to more lines on ~70th
 *        column.     
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrCreateProcess(IN HANDLE hProcess,
                 IN HANDLE hThread,
                 IN PCLIENT_ID ClientId,
                 IN PCSR_NT_SESSION NtSession,
                 IN ULONG Flags,
                 IN PCLIENT_ID DebugCid)
{
    PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
    CLIENT_ID CurrentCid;
    PCSR_PROCESS CurrentProcess;
    PVOID ProcessData;
    ULONG i;
    PCSR_PROCESS CsrProcess;
    NTSTATUS Status;
    PCSR_THREAD CsrThread;
    KERNEL_USER_TIMES KernelTimes;

    /* Get the current CID and lock Processes */
    CurrentCid = CurrentThread->ClientId;
    CsrAcquireProcessLock();

    /* Get the current CSR Thread */
    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
    if (!CurrentThread)
    {
        /* We've failed to locate the thread */
        CsrReleaseProcessLock();
        return STATUS_THREAD_IS_TERMINATING;
    }

    /* Allocate a new Process Object */
    if (!(CsrProcess = CsrAllocateProcess()))
    {
        /* Couldn't allocate Process */
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Setup Process Data */
    CsrProcess->ClientId = *ClientId;
    CsrProcess->ProcessHandle = hProcess;
    CsrProcess->ShutdownLevel = 0x280;

    /* Inherit the Process Data */
    ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX];
    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
    {
        /* Check if the DLL is Loaded and has Per Process Data */
        if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
        {
            /* Set the pointer */
            CsrProcess->ServerData[i] = ProcessData;

            /* Copy the Data */
            RtlMoveMemory(ProcessData,
                          CurrentProcess->ServerData[i],
                          CsrLoadedServerDll[i]->SizeOfProcessData);

            /* Update next data pointer */
            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
                                  CsrLoadedServerDll[i]->SizeOfProcessData);
        }
        else 
        {
            /* No data for this Server */
            CsrProcess->ServerData[i] = NULL;
        }
    }

    /* Set the Exception port to us */
    Status = NtSetInformationProcess(hProcess,
                                     ProcessExceptionPort,
                                     &CsrApiPort,
                                     sizeof(HANDLE));
    if (!NT_SUCCESS(Status))
    {
        /* Failed */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* If Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
    if (!(Flags & CsrProcessCreateNewGroup))
    {
        /* Create new data */
        CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess);
        CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber;
    }
    else
    {
        /* Copy it from the current process */
        CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId;
        CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence;
    }

    /* Check if this is a console process */
    if(Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp;

    /* Mask out non-debug flags */
    Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup);

    /* Check if every process will be debugged */
    if (!Flags && CurrentProcess->DebugFlags & CsrDebugProcessChildren)
    {
        /* Pass it on to the current process */
        CsrProcess->DebugFlags = CsrDebugProcessChildren;
        CsrProcess->DebugCid = CurrentProcess->DebugCid;
    }

    /* Check if Debugging was used on this process */
    if (Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren))
    {
        /* Save the debug flag used */
        CsrProcess->DebugFlags = Flags;

        /* Save the CID */
        if (DebugCid) CsrProcess->DebugCid = *DebugCid;
    }

    /* Check if we debugging is enabled */
    if (CsrProcess->DebugFlags)
    {
        /* Set the Debug Port to us */
        Status = NtSetInformationProcess(hProcess,
                                         ProcessDebugPort,
                                         &CsrApiPort,
                                         sizeof(HANDLE));
        if (!NT_SUCCESS(Status))
        {
            /* Failed */
            CsrDeallocateProcess(CsrProcess);
            CsrReleaseProcessLock();
            return STATUS_NO_MEMORY;
        }
    }

    /* Get the Thread Create Time */
    Status = NtQueryInformationThread(hThread,
                                      ThreadTimes,
                                      (PVOID)&KernelTimes,
                                      sizeof(KernelTimes),
                                      NULL);

    /* Allocate a CSR Thread Structure */
    CsrThread = CsrAllocateThread(CsrProcess);
    if (CsrThread == NULL)
    {
        /* Failed */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Save the data we have */
    CsrThread->CreateTime = KernelTimes.CreateTime;
    CsrThread->ClientId = *ClientId;
    CsrThread->ThreadHandle = hThread;
    CsrThread->Flags = 0;

    /* Insert the Thread into the Process */
    CsrInsertThread(CsrProcess, CsrThread);

    /* Reference the session */
    CsrReferenceNtSession(NtSession);
    CsrProcess->NtSession = NtSession;

    /* Set the Priority to Background */
    CsrSetBackgroundPriority(CsrProcess);

    /* Insert the Process */
    CsrInsertProcess(NULL, CurrentProcess, CsrProcess);

    /* Release lock and return */
    CsrReleaseProcessLock();
    return Status;
}

/*++
 * @name CsrDebugProcess
 * @implemented NT4
 *
 * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is
 * exported only for compatibility with older CSR Server DLLs.
 *
 * @param CsrProcess
 *        Deprecated.  
 *
 * @return Deprecated
 *
 * @remarks Deprecated.
 *
 *--*/
NTSTATUS
NTAPI
CsrDebugProcess(PCSR_PROCESS CsrProcess)
{
    /* CSR does not handle debugging anymore */
    DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
    return STATUS_UNSUCCESSFUL;
}

/*++
 * @name CsrServerInitialization
 * @implemented NT4
 *
 * The CsrDebugProcessStop routine is deprecated in NT 5.1 and higher. It is
 * exported only for compatibility with older CSR Server DLLs.
 *
 * @param CsrProcess
 *        Deprecated.  
 *
 * @return Deprecated
 *
 * @remarks Deprecated.
 *
 *--*/
NTSTATUS
NTAPI
CsrDebugProcessStop(PCSR_PROCESS CsrProcess)
{
    /* CSR does not handle debugging anymore */
    DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
    return STATUS_UNSUCCESSFUL;
}

/*++
 * @name CsrDereferenceProcess
 * @implemented NT4
 *
 * The CsrDereferenceProcess routine removes a reference from a CSR Process.
 *
 * @param CsrThread
 *        Pointer to the CSR Process to dereference.
 *
 * @return None.
 *
 * @remarks If the reference count has reached zero (ie: the CSR Process has
 *          no more active references), it will be deleted.
 *
 *--*/
VOID
NTAPI
CsrDereferenceProcess(PCSR_PROCESS CsrProcess)
{
    /* Acquire process lock */
    CsrAcquireProcessLock();

    /* Decrease reference count */
    if (!(--CsrProcess->ReferenceCount))
    {
        /* Call the generic cleanup code */
        CsrProcessRefcountZero(CsrProcess);
    }
    else
    {
        /* Just release the lock */
        CsrReleaseProcessLock();
    }
}

/*++
 * @name CsrDestroyProcess
 * @implemented NT4
 *
 * The CsrDestroyProcess routine destroys the CSR Process corresponding to 
 * a given Client ID.
 *
 * @param Cid
 *        Pointer to the Client ID Structure corresponding to the CSR
 *        Process which is about to be destroyed. 
 *
 * @param ExitStatus
 *        Unused.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
 *         if the CSR Process is already terminating.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrDestroyProcess(IN PCLIENT_ID Cid,
                  IN NTSTATUS ExitStatus)
{
    PCSR_THREAD CsrThread;
    PCSR_PROCESS CsrProcess;
    CLIENT_ID ClientId = *Cid;
    PLIST_ENTRY ListHead, NextEntry;

    /* Acquire lock */
    CsrAcquireProcessLock();

    /* Find the thread */
    CsrThread = CsrLocateThreadByClientId(&CsrProcess,
                                          &ClientId);

    /* Make sure we got one back, and that it's not already gone */
    if (!CsrThread || CsrProcess->Flags & CsrProcessTerminating)
    {
        /* Release the lock and return failure */
        CsrReleaseProcessLock();
        return STATUS_THREAD_IS_TERMINATING;
    }

    /* Set the terminated flag */
    CsrProcess->Flags |= CsrProcessTerminating;

    /* Get the List Pointers */
    ListHead = &CsrProcess->ThreadList;
    NextEntry = ListHead->Flink;

    /* Loop the list */
    while (NextEntry != ListHead)
    {
        /* Get the current thread entry */
        CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);

        /* Move to the next entry */
        NextEntry = NextEntry->Flink;

        /* Make sure the thread isn't already dead */
        if (CsrThread->Flags & CsrThreadTerminated) continue;

        /* Set the Terminated flag */
        CsrThread->Flags |= CsrThreadTerminated;

        /* Acquire the Wait Lock */
        CsrAcquireWaitLock();

        /* Do we have an active wait block? */
        if (CsrThread->WaitBlock)
        {
            /* Notify waiters of termination */
            CsrNotifyWaitBlock(CsrThread->WaitBlock,
                               NULL,
                               NULL,
                               NULL,
                               CsrProcessTerminating,

⌨️ 快捷键说明

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