📄 connect.c
字号:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/ntdll/csr/connect.c
* PURPOSE: Routines for connecting and calling CSR
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES *****************************************************************/
#include <ntdll.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
HANDLE CsrApiPort;
HANDLE CsrProcessId;
HANDLE CsrPortHeap;
ULONG_PTR CsrPortMemoryDelta;
BOOLEAN InsideCsrProcess = FALSE;
BOOLEAN UsingOldCsr = TRUE;
typedef NTSTATUS
(NTAPI *PCSR_SERVER_API_ROUTINE)(IN PPORT_MESSAGE Request,
IN PPORT_MESSAGE Reply);
PCSR_SERVER_API_ROUTINE CsrServerApiRoutine;
#define UNICODE_PATH_SEP L"\\"
#define CSR_PORT_NAME L"ApiPort"
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
HANDLE
NTAPI
CsrGetProcessId(VOID)
{
return CsrProcessId;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
CsrClientCallServer(PCSR_API_MESSAGE ApiMessage,
PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL,
CSR_API_NUMBER ApiNumber,
ULONG RequestLength)
{
NTSTATUS Status;
ULONG PointerCount;
PULONG_PTR Pointers;
ULONG_PTR CurrentPointer;
DPRINT("CsrClientCallServer\n");
/* Fill out the Port Message Header */
ApiMessage->Header.u2.ZeroInit = 0;
ApiMessage->Header.u1.s1.DataLength = RequestLength - sizeof(PORT_MESSAGE);
ApiMessage->Header.u1.s1.TotalLength = RequestLength;
/* Fill out the CSR Header */
ApiMessage->Type = ApiNumber;
//ApiMessage->Opcode = ApiNumber; <- Activate with new CSR
ApiMessage->CsrCaptureData = NULL;
DPRINT("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n",
ApiNumber,
ApiMessage->Header.u1.s1.DataLength,
ApiMessage->Header.u1.s1.TotalLength);
/* Check if we are already inside a CSR Server */
if (!InsideCsrProcess)
{
/* Check if we got a a Capture Buffer */
if (CaptureBuffer)
{
/* We have to convert from our local view to the remote view */
ApiMessage->CsrCaptureData = (PVOID)((ULONG_PTR)CaptureBuffer +
CsrPortMemoryDelta);
/* Lock the buffer */
CaptureBuffer->BufferEnd = 0;
/* Get the pointer information */
PointerCount = CaptureBuffer->PointerCount;
Pointers = CaptureBuffer->PointerArray;
/* Loop through every pointer and convert it */
DPRINT("PointerCount: %lx\n", PointerCount);
while (PointerCount--)
{
/* Get this pointer and check if it's valid */
DPRINT("Array Address: %p. This pointer: %p. Data: %lx\n",
&Pointers, Pointers, *Pointers);
if ((CurrentPointer = *Pointers++))
{
/* Update it */
DPRINT("CurrentPointer: %lx.\n", *(PULONG_PTR)CurrentPointer);
*(PULONG_PTR)CurrentPointer += CsrPortMemoryDelta;
Pointers[-1] = CurrentPointer - (ULONG_PTR)ApiMessage;
DPRINT("CurrentPointer: %lx.\n", *(PULONG_PTR)CurrentPointer);
}
}
}
/* Send the LPC Message */
Status = NtRequestWaitReplyPort(CsrApiPort,
&ApiMessage->Header,
&ApiMessage->Header);
/* Check if we got a a Capture Buffer */
if (CaptureBuffer)
{
/* We have to convert from the remote view to our remote view */
DPRINT("Reconverting CaptureBuffer\n");
ApiMessage->CsrCaptureData = (PVOID)((ULONG_PTR)
ApiMessage->CsrCaptureData -
CsrPortMemoryDelta);
/* Get the pointer information */
PointerCount = CaptureBuffer->PointerCount;
Pointers = CaptureBuffer->PointerArray;
/* Loop through every pointer and convert it */
while (PointerCount--)
{
/* Get this pointer and check if it's valid */
if ((CurrentPointer = *Pointers++))
{
/* Update it */
CurrentPointer += (ULONG_PTR)ApiMessage;
Pointers[-1] = CurrentPointer;
*(PULONG_PTR)CurrentPointer -= CsrPortMemoryDelta;
}
}
}
/* Check for success */
if (!NT_SUCCESS(Status))
{
/* We failed. Overwrite the return value with the failure */
DPRINT1("LPC Failed: %lx\n", Status);
ApiMessage->Status = Status;
}
}
else
{
/* This is a server-to-server call. Save our CID and do a direct call */
DbgBreakPoint();
ApiMessage->Header.ClientId = NtCurrentTeb()->Cid;
Status = CsrServerApiRoutine(&ApiMessage->Header,
&ApiMessage->Header);
/* Check for success */
if (!NT_SUCCESS(Status))
{
/* We failed. Overwrite the return value with the failure */
ApiMessage->Status = Status;
}
}
/* Return the CSR Result */
DPRINT("Got back: 0x%lx\n", ApiMessage->Status);
return ApiMessage->Status;
}
NTSTATUS
NTAPI
CsrConnectToServer(IN PWSTR ObjectDirectory)
{
ULONG PortNameLength;
UNICODE_STRING PortName;
LARGE_INTEGER CsrSectionViewSize;
NTSTATUS Status;
HANDLE CsrSectionHandle;
PORT_VIEW LpcWrite;
REMOTE_PORT_VIEW LpcRead;
SECURITY_QUALITY_OF_SERVICE SecurityQos;
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
PSID SystemSid = NULL;
CSR_CONNECTION_INFO ConnectionInfo;
ULONG ConnectionInfoLength = sizeof(CSR_CONNECTION_INFO);
DPRINT("%s(%S)\n", __FUNCTION__, ObjectDirectory);
/* Binary compatibility with MS KERNEL32 */
if (NULL == ObjectDirectory)
{
ObjectDirectory = L"\\Windows";
}
/* Calculate the total port name size */
PortNameLength = ((wcslen(ObjectDirectory) + 1) * sizeof(WCHAR)) +
sizeof(CSR_PORT_NAME);
/* Set the port name */
PortName.Length = 0;
PortName.MaximumLength = PortNameLength;
/* Allocate a buffer for it */
PortName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, PortNameLength);
if (PortName.Buffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Create the name */
RtlAppendUnicodeToString(&PortName, ObjectDirectory );
RtlAppendUnicodeToString(&PortName, UNICODE_PATH_SEP);
RtlAppendUnicodeToString(&PortName, CSR_PORT_NAME);
/* Create a section for the port memory */
CsrSectionViewSize.QuadPart = CSR_CSRSS_SECTION_SIZE;
Status = NtCreateSection(&CsrSectionHandle,
SECTION_ALL_ACCESS,
NULL,
&CsrSectionViewSize,
PAGE_READWRITE,
SEC_COMMIT,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failure allocating CSR Section\n");
return Status;
}
/* Set up the port view structures to match them with the section */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -