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

📄 process.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
                               TRUE);
        }

        /* Release the Wait Lock */
        CsrReleaseWaitLock();

        /* Dereference the thread */
        CsrLockedDereferenceThread(CsrThread);
    }

    /* Release the Process Lock and return success */
    CsrReleaseProcessLock();
    return STATUS_SUCCESS;
}

/*++
 * @name CsrGetProcessLuid
 * @implemented NT4
 *
 * Do nothing for 500ms.
 *
 * @param hProcess
 *        Optional handle to the process whose LUID should be returned.
 *
 * @param Luid
 *        Pointer to a LUID Pointer which will receive the CSR Process' LUID    
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks If hProcess is not supplied, then the current thread's token will
 *          be used. If that too is missing, then the current process' token
 *          will be used.
 *
 *--*/
NTSTATUS
NTAPI
CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
                  PLUID Luid)
{
    HANDLE hToken = NULL;
    NTSTATUS Status;
    ULONG Length;
    PTOKEN_STATISTICS TokenStats;

    /* Check if we have a handle to a CSR Process */
    if (!hProcess)
    {
        /* We don't, so try opening the Thread's Token */
        Status = NtOpenThreadToken(NtCurrentThread(),
                                   TOKEN_QUERY,
                                   FALSE,
                                   &hToken);

        /* Check for success */
        if (!NT_SUCCESS(Status))
        {
            /* If we got some other failure, then return and quit */
            if (Status != STATUS_NO_TOKEN) return Status;

            /* We don't have a Thread Token, use a Process Token */
            hProcess = NtCurrentProcess();
            hToken = NULL;
        }
    }

    /* Check if we have a token by now */
    if (!hToken)
    {
        /* No token yet, so open the Process Token */
        Status = NtOpenProcessToken(hProcess,
                                    TOKEN_QUERY,
                                    &hToken);
        if (!NT_SUCCESS(Status))
        {
            /* Still no token, return the error */
            return Status;
        }
    }

    /* Now get the size we'll need for the Token Information */
    Status = NtQueryInformationToken(hToken,
                                     TokenStatistics,
                                     NULL,
                                     0,
                                     &Length);

    /* Allocate memory for the Token Info */
    if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length)))
    {
        /* Fail and close the token */
        NtClose(hToken);
        return STATUS_NO_MEMORY;
    }

    /* Now query the information */
    Status = NtQueryInformationToken(hToken,
                                     TokenStatistics,
                                     &TokenStats,
                                     Length,
                                     &Length);

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

    /* Check for success */
    if (NT_SUCCESS(Status))
    {
        /* Return the LUID */
        *Luid = TokenStats->AuthenticationId;
    }

    /* Free the query information */
    RtlFreeHeap(CsrHeap, 0, TokenStats);

    /* Return the Status */
    return Status;
}

/*++
 * @name CsrLockProcessByClientId
 * @implemented NT4
 *
 * The CsrLockProcessByClientId routine locks the CSR Process corresponding
 * to the given Process ID and optionally returns it.
 *
 * @param Pid
 *        Process ID corresponding to the CSR Process which will be locked.
 *
 * @param CsrProcess
 *        Optional pointer to a CSR Process pointer which will hold the
 *        CSR Process corresponding to the given Process ID.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks Locking a CSR Process is defined as acquiring an extra
 *          reference to it and returning with the Process Lock held.
 *
 *--*/
NTSTATUS
NTAPI
CsrLockProcessByClientId(IN HANDLE Pid,
                         OUT PCSR_PROCESS *CsrProcess OPTIONAL)
{
    PLIST_ENTRY ListHead, NextEntry;
    PCSR_PROCESS CurrentProcess = NULL;
    NTSTATUS Status = STATUS_UNSUCCESSFUL;

    /* Acquire the lock */
    CsrAcquireProcessLock();

    /* Setup the List Pointers */
    ListHead = &CsrRootProcess->ListLink;
    NextEntry = ListHead;

    /* Start Loop */
    while (NextEntry != ListHead)
    {
        /* Get the Process */
        CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);

        /* Check for PID Match */
        if (CurrentProcess->ClientId.UniqueProcess == Pid)
        {
            /* Get out of here with success */
            Status = STATUS_SUCCESS;
            break;
        }

        /* Next entry */
        NextEntry = NextEntry->Flink;
    }

    /* Did the loop find something? */
    if (NT_SUCCESS(Status))
    {
        /* Lock the found process */
        CurrentProcess->ReferenceCount++;
    }
    else
    {
        /* Nothing found, release the lock */
        CsrReleaseProcessLock();
    }

    /* Return the status and process */
    if (CsrProcess) *CsrProcess = CurrentProcess;
    return Status;
}

/*++
 * @name CsrSetForegroundPriority
 * @implemented NT4
 *
 * The CsrSetForegroundPriority routine sets the priority for the given CSR
 * Process as a Foreground priority.
 *
 * @param CsrProcess
 *        Pointer to the CSR Process whose priority will be modified.
 *
 * @return None.
 *
 * @remarks None.
 *
 *--*/
VOID
NTAPI
CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
{
    PROCESS_PRIORITY_CLASS PriorityClass;

    /* Set the Foreground bit on */
    PriorityClass.Foreground = TRUE;

    /* Set the new Priority */
    NtSetInformationProcess(CsrProcess->ProcessHandle,
                            ProcessPriorityClass,
                            &PriorityClass,
                            sizeof(PriorityClass));
}

/*++
 * @name CsrSetBackgroundPriority
 * @implemented NT4
 *
 * The CsrSetBackgroundPriority routine sets the priority for the given CSR
 * Process as a Background priority.
 *
 * @param CsrProcess
 *        Pointer to the CSR Process whose priority will be modified.
 *
 * @return None.
 *
 * @remarks None.
 *
 *--*/
VOID
NTAPI
CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
{
    PROCESS_PRIORITY_CLASS PriorityClass;

    /* Set the Foreground bit off */
    PriorityClass.Foreground = FALSE;

    /* Set the new Priority */
    NtSetInformationProcess(CsrProcess->ProcessHandle,
                            ProcessPriorityClass,
                            &PriorityClass,
                            sizeof(PriorityClass));
}

/*++
 * @name CsrShutdownProcesses
 * @implemented NT4
 *
 * The CsrShutdownProcesses routine shuts down every CSR Process possible
 * and calls each Server DLL's shutdown notification.
 *
 * @param CallerLuid
 *        Pointer to the LUID of the CSR Process that is ordering the
 *        shutdown.
 *
 * @param Flags
 *        Flags to send to the shutdown notification routine.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrShutdownProcesses(PLUID CallerLuid,
                     ULONG Flags)
{
    PLIST_ENTRY ListHead, NextEntry;
    PCSR_PROCESS CsrProcess = NULL;
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    BOOLEAN FirstTry = TRUE;
    ULONG i = 0;
    PCSR_SERVER_DLL ServerDll = NULL;
    ULONG Result = 0;

    /* Acquire process lock */
    CsrAcquireProcessLock();

    /* Add shutdown flag */
    CsrRootProcess->ShutdownFlags |= CsrShutdownSystem;

    /* Get the list pointers */
    ListHead = &CsrRootProcess->ListLink;
    NextEntry = ListHead->Flink;

    /* Start the loop */
    while (NextEntry != ListHead)
    {
        /* Get the Process */
        CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);

        /* Remove the skip flag, set shutdown flags to 0*/
        CsrProcess->Flags &= ~CsrProcessSkipShutdown;
        CsrProcess->ShutdownFlags = 0;

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

    /* Set shudown Priority */
    CsrSetToShutdownPriority();

    /* Start looping */
    while (TRUE)
    {
        /* Find the next process to shutdown */
        if (!(CsrProcess = FindProcessForShutdown(CallerLuid)))
        {
            /* Done, quit */
            CsrReleaseProcessLock();
            Status = STATUS_SUCCESS;
            goto Quickie;
         }

        /* Increase reference to process */
        CsrProcess->ReferenceCount++;

LoopAgain:
        /* Loop all the servers */
        for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
        {
            /* Get the current server */
            ServerDll = CsrLoadedServerDll[i];
            if (ServerDll && ServerDll->ShutdownProcessCallback)
            {
                /* Release the lock, make the callback, and acquire it back */
                CsrReleaseProcessLock();
                Result = (*ServerDll->ShutdownProcessCallback)(CsrProcess,
                                                               Flags,
                                                               FirstTry);
                CsrAcquireProcessLock();

                /* Check the result */
                if (Result == CsrShutdownCsrProcess)
                {
                    /* The callback unlocked the process */
                    break;
                }
                else if (Result == CsrShutdownNonCsrProcess)
                {
                    /* A non-CSR process, the callback didn't touch it */
                    continue;
                }
                else if (Result == CsrShutdownCancelled)
                {
                    /* Shutdown was cancelled, unlock and exit */
                    CsrReleaseProcessLock();
                    Status = STATUS_CANCELLED;
                    goto Quickie;
                }
            }
        }

        /* No matches during the first try, so loop again */
        if (FirstTry && Result == CsrShutdownNonCsrProcess)
        {
            FirstTry = FALSE;
            goto LoopAgain;
        }

        /* We've reached the final loop here, so dereference */
        if (i == CSR_SERVER_DLL_MAX) CsrLockedDereferenceProcess(CsrProcess);
    }

Quickie:
    /* Return to normal priority */
    CsrSetToNormalPriority();
    return Status;
}

/*++
 * @name CsrUnlockProcess
 * @implemented NT4
 *
 * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation.
 *
 * @param CsrProcess
 *        Pointer to a previously locked CSR Process. 
 *
 * @return STATUS_SUCCESS.
 *
 * @remarks This routine must be called with the Process Lock held.
 *
 *--*/
NTSTATUS
NTAPI
CsrUnlockProcess(PCSR_PROCESS CsrProcess)
{
    /* Dereference the process */
    CsrLockedDereferenceProcess(CsrProcess);

    /* Release the lock and return */
    CsrReleaseProcessLock();
    return STATUS_SUCCESS;
}

/* EOF */

⌨️ 快捷键说明

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