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

📄 server.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * COPYRIGHT:       See COPYING in the top level directory
 * PROJECT:         ReactOS CSR Sub System
 * FILE:            subsys/csr/csrsrv/server.c
 * PURPOSE:         CSR Server DLL Server Functions
 * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
 */

/* INCLUDES ******************************************************************/
#include "srv.h"

#define NDEBUG
#include <debug.h>

/* DATA **********************************************************************/

PCSR_API_ROUTINE CsrServerApiDispatchTable[5] =
{
    CsrSrvClientConnect,
    CsrSrvUnusedFunction,
    CsrSrvUnusedFunction,
    CsrSrvIdentifyAlertableThread,
    CsrSrvSetPriorityClass
};

BOOLEAN CsrServerApiServerValidTable[5] =
{
    TRUE,
    FALSE,
    TRUE,
    TRUE,
    TRUE
};

PCHAR CsrServerApiNameTable[5] =
{
    "ClientConnect",
    "ThreadConnect",
    "ProfileControl",
    "IdentifyAlertableThread",
    "SetPriorityClass"
};

PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
PVOID CsrSrvSharedSectionHeap;
PVOID CsrSrvSharedSectionBase;
PVOID *CsrSrvSharedStaticServerData;
ULONG CsrSrvSharedSectionSize;
HANDLE CsrSrvSharedSection;

/* PRIVATE FUNCTIONS**********************************************************/

/*++
 * @name CsrLoadServerDll
 * @implemented NT4
 *
 * The CsrLoadServerDll routine loads a CSR Server DLL and calls its entrypoint
 *
 * @param DllString
 *        Pointer to the CSR Server DLL to load and call.
 *
 * @param EntryPoint
 *        Pointer to the name of the server's initialization function. If
 *        this parameter is NULL, the default ServerDllInitialize will be
 *        assumed.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrLoadServerDll(IN PCHAR DllString,
                 IN PCHAR EntryPoint OPTIONAL,
                 IN ULONG ServerId)
{
    NTSTATUS Status;
    ANSI_STRING DllName;
    UNICODE_STRING TempString;
    HANDLE hServerDll = NULL;
    ULONG Size;
    PCSR_SERVER_DLL ServerDll;
    STRING EntryPointString;
    PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure;

    /* Check if it's beyond the maximum we support */
    if (ServerId >= CSR_SERVER_DLL_MAX) return(STATUS_TOO_MANY_NAMES);

    /* Check if it's already been loaded */
    if (CsrLoadedServerDll[ServerId]) return(STATUS_INVALID_PARAMETER);

    /* Convert the name to Unicode */
    RtlInitAnsiString(&DllName, DllString);
    Status = RtlAnsiStringToUnicodeString(&TempString, &DllName, TRUE);

    /* If we are loading ourselves, don't actually load us */
    if (ServerId != CSR_SRV_SERVER)
    {
        /* Load the DLL */
        Status = LdrLoadDll(NULL, 0, &TempString, &hServerDll);

        /* Get rid of the string */
        RtlFreeUnicodeString(&TempString);
        if (!NT_SUCCESS(Status))
        {
            return Status;
        }
    }

    /* Allocate a CSR DLL Object */
    Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength;
    if (!(ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size)))
    {
        if (hServerDll) LdrUnloadDll(hServerDll);
        return STATUS_NO_MEMORY;
    }

    /* Set up the Object */
    ServerDll->Length = Size;
    ServerDll->SharedSection = CsrSrvSharedSectionHeap;
    ServerDll->Event = CsrInitializationEvent;
    ServerDll->Name.Length = DllName.Length;
    ServerDll->Name.MaximumLength = DllName.MaximumLength;
    ServerDll->Name.Buffer = (PCHAR)(ServerDll + 1);
    if (DllName.Length)
    {
        strncpy(ServerDll->Name.Buffer, DllName.Buffer, DllName.Length);
    }
    ServerDll->ServerId = ServerId;
    ServerDll->ServerHandle = hServerDll;

    /* Now get the entrypoint */
    if (hServerDll)
    {
        /* Initialize a string for the entrypoint, or use the default */
        RtlInitAnsiString(&EntryPointString, 
                          !(EntryPoint) ? "ServerDllInitialization" :
                                          EntryPoint);

        /* Get a pointer to it */
        Status = LdrGetProcedureAddress(hServerDll,
                                        &EntryPointString,
                                        0,
                                        (PVOID)&ServerDllInitProcedure);
    }
    else
    {
        /* No handle, so we are loading ourselves */
        ServerDllInitProcedure = CsrServerDllInitialization;
        Status = STATUS_SUCCESS;
    }

    /* Check if we got the pointer, and call it */
    if (NT_SUCCESS(Status))
    {
        /* Get the result from the Server DLL */
        Status = (*ServerDllInitProcedure)(ServerDll);

        /* Check for Success */
        if (NT_SUCCESS(Status))
        {
            /*
             * Add this Server's Per-Process Data Size to the total that each
             * process will need.
             */
            CsrTotalPerProcessDataLength += ServerDll->SizeOfProcessData;

            /* Save the pointer in our list */
            CsrLoadedServerDll[ServerDll->ServerId] = ServerDll;

            /* Does it use our generic heap? */
            if (ServerDll->SharedSection != CsrSrvSharedSectionHeap)
            {
                /* No, save the pointer to its shared section in our list */
                CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection;
            }
        }
        else
        {
            /* Use shared failure code */
            goto LoadFailed;
        }
    }
    else
    {
LoadFailed:
        /* Server Init failed, unload it */
        if (hServerDll) LdrUnloadDll(hServerDll);

        /* Delete the Object */
        RtlFreeHeap(CsrHeap, 0, ServerDll);
    }

    /* Return to caller */
    return Status;
}

/*++
 * @name CsrServerDllInitialization
 * @implemented NT4
 *
 * The CsrServerDllInitialization is the initialization routine for
 * the this Server DLL.
 *
 * @param LoadedServerDll
 *        Pointer to the CSR Server DLL structure representing this Server DLL.
 *
 * @return STATUS_SUCCESS.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll)
{
    /* Setup the DLL Object */
    LoadedServerDll->ApiBase = 0;
    LoadedServerDll->HighestApiSupported = 5;
    LoadedServerDll->DispatchTable = CsrServerApiDispatchTable;
    LoadedServerDll->ValidTable = CsrServerApiServerValidTable;
    LoadedServerDll->NameTable = CsrServerApiNameTable;
    LoadedServerDll->SizeOfProcessData = 0;
    LoadedServerDll->ConnectCallback = NULL;
    LoadedServerDll->DisconnectCallback = NULL;

    /* All done */
    return STATUS_SUCCESS;
}

/*++
 * @name CsrSrvClientConnect
 *
 * The CsrSrvClientConnect CSR API handles a new connection to a server DLL.
 *
 * @param ApiMessage
 *        Pointer to the CSR API Message for this request.
 *
 * @param Reply
 *        Optional reply to this request.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_INVALID_PARAMETER
 *         or STATUS_TOO_MANY_NAMES in case of failure.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
                    IN OUT PULONG Reply OPTIONAL)
{
    NTSTATUS Status;
    PCSR_CLIENT_CONNECT ClientConnect;
    PCSR_SERVER_DLL ServerDll;

    /* Load the Message, set default reply */
    ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect;
    *Reply = 0;

    /* Validate the ServerID */
    if (ClientConnect->ServerId >= CSR_SERVER_DLL_MAX)
    {
        return STATUS_TOO_MANY_NAMES;
    }
    else if (!(CsrLoadedServerDll[ClientConnect->ServerId]))
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Validate the Message Buffer */
    if (!(CsrValidateMessageBuffer(ApiMessage,
                                   ClientConnect->ConnectionInfo,
                                   ClientConnect->ConnectionInfoSize,
                                   1)))
    {
        /* Fail due to buffer overflow or other invalid buffer */
        return STATUS_INVALID_PARAMETER;
    }

    /* Load the Server DLL */
    ServerDll = CsrLoadedServerDll[ClientConnect->ServerId];

    /* Check if it has a Connect Callback */
    if (ServerDll->ConnectCallback)
    {
        /* Call the callback */
        Status = (ServerDll->ConnectCallback)(((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process,
                                              ClientConnect->ConnectionInfo,
                                              &ClientConnect->ConnectionInfoSize);
    }
    else
    {
        /* Assume success */
        Status = STATUS_SUCCESS;
    }

    /* Return status */
    return Status;
}

/*++
 * @name CsrSrvCreateSharedSection
 *
 * The CsrSrvCreateSharedSection creates the Shared Section that all CSR Server
 * DLLs and Clients can use to share data.
 *
 * @param ParameterValue
 *        Specially formatted string from our registry command-line which
 *        specifies various arguments for the shared section.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
 *         othwerwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
{
    PCHAR SizeValue = ParameterValue;
    ULONG Size;
    NTSTATUS Status;
    LARGE_INTEGER SectionSize;
    ULONG ViewSize = 0;
    PPEB Peb = NtCurrentPeb();

    /* Find the first comma, and null terminate */
    while (*SizeValue)
    {
        if (*SizeValue == ',')

⌨️ 快捷键说明

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