📄 server.c
字号:
/*
* 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 + -