mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[CSR][NTDLL] Move the CSR subsystem into its own "csr" sub-directory. (#4802)
Move CSRSS, CSRSRV there, as well as CSR client calls from NTDLL into a "CSRLIB" library.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
|
||||
add_subdirectory(csr)
|
||||
add_subdirectory(mvdm)
|
||||
add_subdirectory(win)
|
||||
add_subdirectory(win32)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
add_subdirectory(csrlib)
|
||||
add_subdirectory(csrsrv)
|
||||
add_subdirectory(csrss)
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
add_definitions(-D_NTSYSTEM_)
|
||||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/subsys/csr)
|
||||
|
||||
list(APPEND SOURCE
|
||||
api.c
|
||||
capture.c
|
||||
connect.c)
|
||||
|
||||
add_library(csrlib ${SOURCE})
|
||||
add_pch(csrlib csrlib.h SOURCE)
|
||||
add_dependencies(csrlib psdk)
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Client/Server Runtime SubSystem
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: CSR Client Library - API LPC Implementation
|
||||
* COPYRIGHT: Copyright 2005-2012 Alex Ionescu <[email protected]>
|
||||
* Copyright 2012-2022 Hermès Bélusca-Maïto <[email protected]>
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "csrlib.h"
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ndk/psfuncs.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrNewThread(VOID)
|
||||
{
|
||||
/* Register the termination port to CSR's */
|
||||
return NtRegisterThreadTerminatePort(CsrApiPort);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrIdentifyAlertableThread(VOID)
|
||||
{
|
||||
#if (NTDDI_VERSION < NTDDI_WS03)
|
||||
NTSTATUS Status;
|
||||
CSR_API_MESSAGE ApiMessage;
|
||||
PCSR_IDENTIFY_ALERTABLE_THREAD IdentifyAlertableThread;
|
||||
|
||||
/* Set up the data for CSR */
|
||||
IdentifyAlertableThread = &ApiMessage.Data.IdentifyAlertableThread;
|
||||
IdentifyAlertableThread->Cid = NtCurrentTeb()->ClientId;
|
||||
|
||||
/* Call it */
|
||||
Status = CsrClientCallServer(&ApiMessage,
|
||||
NULL,
|
||||
CSR_CREATE_API_NUMBER(CSRSRV_SERVERDLL_INDEX, CsrpIdentifyAlertableThread),
|
||||
sizeof(*IdentifyAlertableThread));
|
||||
|
||||
/* Return to caller */
|
||||
return Status;
|
||||
#else
|
||||
/* Deprecated */
|
||||
return STATUS_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrSetPriorityClass(IN HANDLE Process,
|
||||
IN OUT PULONG PriorityClass)
|
||||
{
|
||||
#if (NTDDI_VERSION < NTDDI_WS03)
|
||||
NTSTATUS Status;
|
||||
CSR_API_MESSAGE ApiMessage;
|
||||
PCSR_SET_PRIORITY_CLASS SetPriorityClass = &ApiMessage.Data.SetPriorityClass;
|
||||
|
||||
/* Set up the data for CSR */
|
||||
SetPriorityClass->hProcess = Process;
|
||||
SetPriorityClass->PriorityClass = *PriorityClass;
|
||||
|
||||
/* Call it */
|
||||
Status = CsrClientCallServer(&ApiMessage,
|
||||
NULL,
|
||||
CSR_CREATE_API_NUMBER(CSRSRV_SERVERDLL_INDEX, CsrpSetPriorityClass),
|
||||
sizeof(*SetPriorityClass));
|
||||
|
||||
/* Return what we got, if requested */
|
||||
if (*PriorityClass) *PriorityClass = SetPriorityClass->PriorityClass;
|
||||
|
||||
/* Return to caller */
|
||||
return Status;
|
||||
#else
|
||||
UNREFERENCED_PARAMETER(Process);
|
||||
UNREFERENCED_PARAMETER(PriorityClass);
|
||||
|
||||
/* Deprecated */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Client/Server Runtime SubSystem
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: CSR Client Library - CSR API Messages probing and capturing
|
||||
* COPYRIGHT: Copyright 2005 Alex Ionescu <[email protected]>
|
||||
* Copyright 2012-2022 Hermès Bélusca-Maïto <[email protected]>
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "csrlib.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrProbeForRead(IN PVOID Address,
|
||||
IN ULONG Length,
|
||||
IN ULONG Alignment)
|
||||
{
|
||||
volatile UCHAR *Pointer;
|
||||
UCHAR Data;
|
||||
|
||||
/* Validate length */
|
||||
if (Length == 0) return;
|
||||
|
||||
/* Validate alignment */
|
||||
if ((ULONG_PTR)Address & (Alignment - 1))
|
||||
{
|
||||
/* Raise exception if it doesn't match */
|
||||
RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
|
||||
}
|
||||
|
||||
/* Probe first byte */
|
||||
Pointer = Address;
|
||||
Data = *Pointer;
|
||||
|
||||
/* Probe last byte */
|
||||
Pointer = (PUCHAR)Address + Length - 1;
|
||||
Data = *Pointer;
|
||||
(void)Data;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrProbeForWrite(IN PVOID Address,
|
||||
IN ULONG Length,
|
||||
IN ULONG Alignment)
|
||||
{
|
||||
volatile UCHAR *Pointer;
|
||||
|
||||
/* Validate length */
|
||||
if (Length == 0) return;
|
||||
|
||||
/* Validate alignment */
|
||||
if ((ULONG_PTR)Address & (Alignment - 1))
|
||||
{
|
||||
/* Raise exception if it doesn't match */
|
||||
RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
|
||||
}
|
||||
|
||||
/* Probe first byte */
|
||||
Pointer = Address;
|
||||
*Pointer = *Pointer;
|
||||
|
||||
/* Probe last byte */
|
||||
Pointer = (PUCHAR)Address + Length - 1;
|
||||
*Pointer = *Pointer;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PCSR_CAPTURE_BUFFER
|
||||
NTAPI
|
||||
CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
|
||||
IN ULONG BufferSize)
|
||||
{
|
||||
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
||||
ULONG OffsetsArraySize;
|
||||
ULONG MaximumSize;
|
||||
|
||||
/* Validate the argument count. Note that on server side, CSRSRV
|
||||
* limits the count to MAXUSHORT; here we are a bit more lenient. */
|
||||
if (ArgumentCount > (MAXLONG / sizeof(ULONG_PTR)))
|
||||
return NULL;
|
||||
|
||||
OffsetsArraySize = ArgumentCount * sizeof(ULONG_PTR);
|
||||
|
||||
/*
|
||||
* Validate the total buffer size.
|
||||
* The total size of the header plus the pointer-offset array and the
|
||||
* provided buffer, together with the alignment padding for each argument,
|
||||
* must be less than MAXLONG aligned to 4-byte boundary.
|
||||
*/
|
||||
MaximumSize = (MAXLONG & ~3) - FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray);
|
||||
if (OffsetsArraySize >= MaximumSize)
|
||||
return NULL;
|
||||
MaximumSize -= OffsetsArraySize;
|
||||
if (BufferSize >= MaximumSize)
|
||||
return NULL;
|
||||
MaximumSize -= BufferSize;
|
||||
if ((ArgumentCount * 3) + 3 >= MaximumSize)
|
||||
return NULL;
|
||||
|
||||
/* Add the size of the header and of the pointer-offset array */
|
||||
BufferSize += FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) +
|
||||
OffsetsArraySize;
|
||||
|
||||
/* Add the size of the alignment padding for each argument */
|
||||
BufferSize += ArgumentCount * 3;
|
||||
|
||||
/* Align it to a 4-byte boundary */
|
||||
BufferSize = (BufferSize + 3) & ~3;
|
||||
|
||||
/* Allocate memory from the port heap */
|
||||
CaptureBuffer = RtlAllocateHeap(CsrPortHeap, HEAP_ZERO_MEMORY, BufferSize);
|
||||
if (CaptureBuffer == NULL) return NULL;
|
||||
|
||||
/* Initialize the header */
|
||||
CaptureBuffer->Size = BufferSize;
|
||||
CaptureBuffer->PointerCount = 0;
|
||||
|
||||
/* Initialize the pointer-offset array */
|
||||
RtlZeroMemory(CaptureBuffer->PointerOffsetsArray, OffsetsArraySize);
|
||||
|
||||
/* Point to the start of the free buffer */
|
||||
CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->PointerOffsetsArray +
|
||||
OffsetsArraySize);
|
||||
|
||||
/* Return the address of the buffer */
|
||||
return CaptureBuffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
|
||||
IN ULONG MessageLength,
|
||||
OUT PVOID* CapturedData)
|
||||
{
|
||||
if (MessageLength == 0)
|
||||
{
|
||||
*CapturedData = NULL;
|
||||
CapturedData = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the capture data at our current available buffer */
|
||||
*CapturedData = CaptureBuffer->BufferEnd;
|
||||
|
||||
/* Validate the size */
|
||||
if (MessageLength >= MAXLONG) return 0;
|
||||
|
||||
/* Align it to a 4-byte boundary */
|
||||
MessageLength = (MessageLength + 3) & ~3;
|
||||
|
||||
/* Move our available buffer beyond this space */
|
||||
CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->BufferEnd + MessageLength);
|
||||
}
|
||||
|
||||
/* Write down this pointer in the array and increase the count */
|
||||
CaptureBuffer->PointerOffsetsArray[CaptureBuffer->PointerCount++] = (ULONG_PTR)CapturedData;
|
||||
|
||||
/* Return the aligned length */
|
||||
return MessageLength;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
|
||||
IN PVOID MessageBuffer OPTIONAL,
|
||||
IN ULONG MessageLength,
|
||||
OUT PVOID* CapturedData)
|
||||
{
|
||||
/* Simply allocate a message pointer in the buffer */
|
||||
CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData);
|
||||
|
||||
/* Check if there was any data */
|
||||
if (!MessageBuffer || !MessageLength) return;
|
||||
|
||||
/* Copy the data into the buffer */
|
||||
RtlMoveMemory(*CapturedData, MessageBuffer, MessageLength);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
|
||||
{
|
||||
/* Free it from the heap */
|
||||
RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
|
||||
IN PCSTR String OPTIONAL,
|
||||
IN ULONG StringLength,
|
||||
IN ULONG MaximumLength,
|
||||
OUT PSTRING CapturedString)
|
||||
{
|
||||
ASSERT(CapturedString != NULL);
|
||||
|
||||
/*
|
||||
* If we don't have a string, initialize an empty one,
|
||||
* otherwise capture the given string.
|
||||
*/
|
||||
if (!String)
|
||||
{
|
||||
CapturedString->Length = 0;
|
||||
CapturedString->MaximumLength = (USHORT)MaximumLength;
|
||||
|
||||
/* Allocate a pointer for it */
|
||||
CsrAllocateMessagePointer(CaptureBuffer,
|
||||
MaximumLength,
|
||||
(PVOID*)&CapturedString->Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Cut-off the string length if needed */
|
||||
if (StringLength > MaximumLength)
|
||||
StringLength = MaximumLength;
|
||||
|
||||
CapturedString->Length = (USHORT)StringLength;
|
||||
|
||||
/* Allocate a buffer and get its size */
|
||||
CapturedString->MaximumLength =
|
||||
(USHORT)CsrAllocateMessagePointer(CaptureBuffer,
|
||||
MaximumLength,
|
||||
(PVOID*)&CapturedString->Buffer);
|
||||
|
||||
/* If the string has data, copy it into the buffer */
|
||||
if (StringLength)
|
||||
RtlMoveMemory(CapturedString->Buffer, String, StringLength);
|
||||
}
|
||||
|
||||
/* Null-terminate the string if we don't take up the whole space */
|
||||
if (CapturedString->Length < CapturedString->MaximumLength)
|
||||
CapturedString->Buffer[CapturedString->Length] = ANSI_NULL;
|
||||
}
|
||||
|
||||
static VOID
|
||||
CsrCaptureMessageUnicodeStringInPlace(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
|
||||
IN PUNICODE_STRING String)
|
||||
{
|
||||
ASSERT(String != NULL);
|
||||
|
||||
/* This is a way to capture the UNICODE string, since (Maximum)Length are also in bytes */
|
||||
CsrCaptureMessageString(CaptureBuffer,
|
||||
(PCSTR)String->Buffer,
|
||||
String->Length,
|
||||
String->MaximumLength,
|
||||
(PSTRING)String);
|
||||
|
||||
/* Null-terminate the string if we don't take up the whole space */
|
||||
if (String->Length + sizeof(WCHAR) <= String->MaximumLength)
|
||||
String->Buffer[String->Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrCaptureMessageMultiUnicodeStringsInPlace(OUT PCSR_CAPTURE_BUFFER* CaptureBuffer,
|
||||
IN ULONG StringsCount,
|
||||
IN PUNICODE_STRING* MessageStrings)
|
||||
{
|
||||
ULONG Count;
|
||||
|
||||
if (!CaptureBuffer) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Allocate a new capture buffer if we don't have one already */
|
||||
if (!*CaptureBuffer)
|
||||
{
|
||||
/* Compute the required size for the capture buffer */
|
||||
ULONG Size = 0;
|
||||
|
||||
Count = 0;
|
||||
while (Count < StringsCount)
|
||||
{
|
||||
if (MessageStrings[Count])
|
||||
Size += MessageStrings[Count]->MaximumLength;
|
||||
|
||||
++Count;
|
||||
}
|
||||
|
||||
/* Allocate the capture buffer */
|
||||
*CaptureBuffer = CsrAllocateCaptureBuffer(StringsCount, Size);
|
||||
if (!*CaptureBuffer) return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Now capture each UNICODE string */
|
||||
Count = 0;
|
||||
while (Count < StringsCount)
|
||||
{
|
||||
if (MessageStrings[Count])
|
||||
CsrCaptureMessageUnicodeStringInPlace(*CaptureBuffer, MessageStrings[Count]);
|
||||
|
||||
++Count;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PLARGE_INTEGER
|
||||
NTAPI
|
||||
CsrCaptureTimeout(IN ULONG Milliseconds,
|
||||
OUT PLARGE_INTEGER Timeout)
|
||||
{
|
||||
/* Validate the time */
|
||||
if (Milliseconds == -1) return NULL;
|
||||
|
||||
/* Convert to relative ticks */
|
||||
Timeout->QuadPart = Milliseconds * -10000LL;
|
||||
return Timeout;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Client/Server Runtime SubSystem
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: CSR Client Library - CSR connection and calling
|
||||
* COPYRIGHT: Copyright 2005-2013 Alex Ionescu <[email protected]>
|
||||
* Copyright 2012-2022 Hermès Bélusca-Maïto <[email protected]>
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "csrlib.h"
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ndk/ldrfuncs.h>
|
||||
#include <ndk/lpcfuncs.h>
|
||||
#include <ndk/mmfuncs.h>
|
||||
#include <ndk/obfuncs.h>
|
||||
#include <ndk/umfuncs.h>
|
||||
|
||||
#include <csrsrv.h> // For CSR_CSRSS_SECTION_SIZE
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
HANDLE CsrApiPort;
|
||||
HANDLE CsrProcessId;
|
||||
HANDLE CsrPortHeap;
|
||||
ULONG_PTR CsrPortMemoryDelta;
|
||||
BOOLEAN InsideCsrProcess = FALSE;
|
||||
|
||||
typedef NTSTATUS
|
||||
(NTAPI *PCSR_SERVER_API_ROUTINE)(IN PPORT_MESSAGE Request,
|
||||
IN PPORT_MESSAGE Reply);
|
||||
|
||||
PCSR_SERVER_API_ROUTINE CsrServerApiRoutine;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrpConnectToServer(IN PWSTR ObjectDirectory)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
SIZE_T PortNameLength;
|
||||
UNICODE_STRING PortName;
|
||||
LARGE_INTEGER CsrSectionViewSize;
|
||||
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_API_CONNECTINFO ConnectionInfo;
|
||||
ULONG ConnectionInfoLength = sizeof(ConnectionInfo);
|
||||
|
||||
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);
|
||||
if (PortNameLength > UNICODE_STRING_MAX_BYTES)
|
||||
{
|
||||
DPRINT1("PortNameLength too big: %Iu", PortNameLength);
|
||||
return STATUS_NAME_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Set the port name */
|
||||
PortName.Length = 0;
|
||||
PortName.MaximumLength = (USHORT)PortNameLength;
|
||||
|
||||
/* Allocate a buffer for it */
|
||||
PortName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, PortNameLength);
|
||||
if (PortName.Buffer == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Create the name */
|
||||
RtlAppendUnicodeToString(&PortName, ObjectDirectory);
|
||||
RtlAppendUnicodeToString(&PortName, L"\\");
|
||||
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_RESERVE,
|
||||
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 */
|
||||
LpcWrite.Length = sizeof(LpcWrite);
|
||||
LpcWrite.SectionHandle = CsrSectionHandle;
|
||||
LpcWrite.SectionOffset = 0;
|
||||
LpcWrite.ViewSize = CsrSectionViewSize.u.LowPart;
|
||||
LpcWrite.ViewBase = 0;
|
||||
LpcWrite.ViewRemoteBase = 0;
|
||||
LpcRead.Length = sizeof(LpcRead);
|
||||
LpcRead.ViewSize = 0;
|
||||
LpcRead.ViewBase = 0;
|
||||
|
||||
/* Setup the QoS */
|
||||
SecurityQos.ImpersonationLevel = SecurityImpersonation;
|
||||
SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
||||
SecurityQos.EffectiveOnly = TRUE;
|
||||
|
||||
/* Setup the connection info */
|
||||
ConnectionInfo.DebugFlags = 0;
|
||||
|
||||
/* Create a SID for us */
|
||||
Status = RtlAllocateAndInitializeSid(&NtSidAuthority,
|
||||
1,
|
||||
SECURITY_LOCAL_SYSTEM_RID,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&SystemSid);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Failure */
|
||||
DPRINT1("Couldn't allocate SID\n");
|
||||
NtClose(CsrSectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Connect to the port */
|
||||
Status = NtSecureConnectPort(&CsrApiPort,
|
||||
&PortName,
|
||||
&SecurityQos,
|
||||
&LpcWrite,
|
||||
SystemSid,
|
||||
&LpcRead,
|
||||
NULL,
|
||||
&ConnectionInfo,
|
||||
&ConnectionInfoLength);
|
||||
RtlFreeSid(SystemSid);
|
||||
NtClose(CsrSectionHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Failure */
|
||||
DPRINT1("Couldn't connect to CSR port\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Save the delta between the sections, for capture usage later */
|
||||
CsrPortMemoryDelta = (ULONG_PTR)LpcWrite.ViewRemoteBase -
|
||||
(ULONG_PTR)LpcWrite.ViewBase;
|
||||
|
||||
/* Save the Process */
|
||||
CsrProcessId = ConnectionInfo.ServerProcessId;
|
||||
|
||||
/* Save CSR Section data */
|
||||
NtCurrentPeb()->ReadOnlySharedMemoryBase = ConnectionInfo.SharedSectionBase;
|
||||
NtCurrentPeb()->ReadOnlySharedMemoryHeap = ConnectionInfo.SharedSectionHeap;
|
||||
NtCurrentPeb()->ReadOnlyStaticServerData = ConnectionInfo.SharedStaticServerData;
|
||||
|
||||
/* Create the port heap */
|
||||
CsrPortHeap = RtlCreateHeap(0,
|
||||
LpcWrite.ViewBase,
|
||||
LpcWrite.ViewSize,
|
||||
PAGE_SIZE,
|
||||
0,
|
||||
0);
|
||||
if (CsrPortHeap == NULL)
|
||||
{
|
||||
/* Failure */
|
||||
DPRINT1("Couldn't create heap for CSR port\n");
|
||||
NtClose(CsrApiPort);
|
||||
CsrApiPort = NULL;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrClientConnectToServer(IN PWSTR ObjectDirectory,
|
||||
IN ULONG ServerId,
|
||||
IN PVOID ConnectionInfo,
|
||||
IN OUT PULONG ConnectionInfoSize,
|
||||
OUT PBOOLEAN ServerToServerCall)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
|
||||
DPRINT("CsrClientConnectToServer: %lx %p\n", ServerId, ConnectionInfo);
|
||||
|
||||
/* Validate the Connection Info */
|
||||
if (ConnectionInfo && (!ConnectionInfoSize || !*ConnectionInfoSize))
|
||||
{
|
||||
DPRINT1("Connection info given, but no length\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check if we're inside a CSR Process */
|
||||
if (InsideCsrProcess)
|
||||
{
|
||||
/* Tell the client that we're already inside CSR */
|
||||
if (ServerToServerCall) *ServerToServerCall = TRUE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* We might be in a CSR Process but not know it, if this is the first call.
|
||||
* So let's find out.
|
||||
*/
|
||||
if (!(NtHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress)))
|
||||
{
|
||||
/* The image isn't valid */
|
||||
DPRINT1("Invalid image\n");
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
InsideCsrProcess = (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE);
|
||||
|
||||
/* Now we can check if we are inside or not */
|
||||
if (InsideCsrProcess)
|
||||
{
|
||||
UNICODE_STRING CsrSrvName;
|
||||
HANDLE hCsrSrv;
|
||||
ANSI_STRING CsrServerRoutineName;
|
||||
|
||||
/* We're inside, so let's find csrsrv */
|
||||
RtlInitUnicodeString(&CsrSrvName, L"csrsrv");
|
||||
Status = LdrGetDllHandle(NULL,
|
||||
NULL,
|
||||
&CsrSrvName,
|
||||
&hCsrSrv);
|
||||
|
||||
/* Now get the Server to Server routine */
|
||||
RtlInitAnsiString(&CsrServerRoutineName, "CsrCallServerFromServer");
|
||||
Status = LdrGetProcedureAddress(hCsrSrv,
|
||||
&CsrServerRoutineName,
|
||||
0L,
|
||||
(PVOID*)&CsrServerApiRoutine);
|
||||
|
||||
/* Use the local heap as port heap */
|
||||
CsrPortHeap = RtlGetProcessHeap();
|
||||
|
||||
/* Tell the caller we're inside the server */
|
||||
if (ServerToServerCall) *ServerToServerCall = InsideCsrProcess;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Now check if connection info is given */
|
||||
if (ConnectionInfo)
|
||||
{
|
||||
CSR_API_MESSAGE ApiMessage;
|
||||
PCSR_CLIENT_CONNECT ClientConnect = &ApiMessage.Data.CsrClientConnect;
|
||||
PCSR_CAPTURE_BUFFER CaptureBuffer;
|
||||
|
||||
/* Well, we're definitely in a client now */
|
||||
InsideCsrProcess = FALSE;
|
||||
|
||||
/* Do we have a connection to CSR yet? */
|
||||
if (!CsrApiPort)
|
||||
{
|
||||
/* No, set it up now */
|
||||
Status = CsrpConnectToServer(ObjectDirectory);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Failed */
|
||||
DPRINT1("Failure to connect to CSR\n");
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the connect message header */
|
||||
ClientConnect->ServerId = ServerId;
|
||||
ClientConnect->ConnectionInfoSize = *ConnectionInfoSize;
|
||||
|
||||
/* Setup a buffer for the connection info */
|
||||
CaptureBuffer = CsrAllocateCaptureBuffer(1, ClientConnect->ConnectionInfoSize);
|
||||
if (CaptureBuffer == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Capture the connection info data */
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
ConnectionInfo,
|
||||
ClientConnect->ConnectionInfoSize,
|
||||
&ClientConnect->ConnectionInfo);
|
||||
|
||||
/* Return the allocated length */
|
||||
*ConnectionInfoSize = ClientConnect->ConnectionInfoSize;
|
||||
|
||||
/* Call CSR */
|
||||
Status = CsrClientCallServer(&ApiMessage,
|
||||
CaptureBuffer,
|
||||
CSR_CREATE_API_NUMBER(CSRSRV_SERVERDLL_INDEX, CsrpClientConnect),
|
||||
sizeof(*ClientConnect));
|
||||
|
||||
/* Copy the updated connection info data back into the user buffer */
|
||||
RtlMoveMemory(ConnectionInfo,
|
||||
ClientConnect->ConnectionInfo,
|
||||
*ConnectionInfoSize);
|
||||
|
||||
/* Free the capture buffer */
|
||||
CsrFreeCaptureBuffer(CaptureBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No connection info, just return */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Let the caller know if this was server to server */
|
||||
DPRINT("Status was: 0x%lx. Are we in server: 0x%x\n", Status, InsideCsrProcess);
|
||||
if (ServerToServerCall) *ServerToServerCall = InsideCsrProcess;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Structures can be padded at the end, causing the size of the entire structure
|
||||
// minus the size of the last field, not to be equal to the offset of the last
|
||||
// field.
|
||||
//
|
||||
typedef struct _TEST_EMBEDDED
|
||||
{
|
||||
ULONG One;
|
||||
ULONG Two;
|
||||
ULONG Three;
|
||||
} TEST_EMBEDDED;
|
||||
|
||||
typedef struct _TEST
|
||||
{
|
||||
PORT_MESSAGE h;
|
||||
TEST_EMBEDDED Three;
|
||||
} TEST;
|
||||
|
||||
C_ASSERT(sizeof(PORT_MESSAGE) == 0x18);
|
||||
C_ASSERT(FIELD_OFFSET(TEST, Three) == 0x18);
|
||||
C_ASSERT(sizeof(TEST_EMBEDDED) == 0xC);
|
||||
|
||||
C_ASSERT(sizeof(TEST) != (sizeof(TEST_EMBEDDED) + sizeof(PORT_MESSAGE)));
|
||||
C_ASSERT((sizeof(TEST) - sizeof(TEST_EMBEDDED)) != FIELD_OFFSET(TEST, Three));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage,
|
||||
IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL,
|
||||
IN CSR_API_NUMBER ApiNumber,
|
||||
IN ULONG DataLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Make sure the length is valid */
|
||||
if (DataLength > (MAXSHORT - sizeof(CSR_API_MESSAGE)))
|
||||
{
|
||||
DPRINT1("DataLength too big: %lu", DataLength);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Fill out the Port Message Header */
|
||||
ApiMessage->Header.u2.ZeroInit = 0;
|
||||
ApiMessage->Header.u1.s1.TotalLength = (CSHORT)DataLength +
|
||||
sizeof(CSR_API_MESSAGE) - sizeof(ApiMessage->Data); // FIELD_OFFSET(CSR_API_MESSAGE, Data) + DataLength;
|
||||
ApiMessage->Header.u1.s1.DataLength = (CSHORT)DataLength +
|
||||
FIELD_OFFSET(CSR_API_MESSAGE, Data) - sizeof(ApiMessage->Header); // ApiMessage->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
|
||||
|
||||
/* Fill out the CSR Header */
|
||||
ApiMessage->ApiNumber = ApiNumber;
|
||||
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)
|
||||
{
|
||||
ULONG PointerCount;
|
||||
PULONG_PTR OffsetPointer;
|
||||
|
||||
/* Check if we got a Capture Buffer */
|
||||
if (CaptureBuffer)
|
||||
{
|
||||
/*
|
||||
* We have to convert from our local (client) view
|
||||
* to the remote (server) view.
|
||||
*/
|
||||
ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
|
||||
((ULONG_PTR)CaptureBuffer + CsrPortMemoryDelta);
|
||||
|
||||
/* Lock the buffer */
|
||||
CaptureBuffer->BufferEnd = NULL;
|
||||
|
||||
/*
|
||||
* Each client pointer inside the CSR message is converted into
|
||||
* a server pointer, and each pointer to these message pointers
|
||||
* is converted into an offset.
|
||||
*/
|
||||
PointerCount = CaptureBuffer->PointerCount;
|
||||
OffsetPointer = CaptureBuffer->PointerOffsetsArray;
|
||||
while (PointerCount--)
|
||||
{
|
||||
if (*OffsetPointer != 0)
|
||||
{
|
||||
*(PULONG_PTR)*OffsetPointer += CsrPortMemoryDelta;
|
||||
*OffsetPointer -= (ULONG_PTR)ApiMessage;
|
||||
}
|
||||
++OffsetPointer;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the LPC Message */
|
||||
Status = NtRequestWaitReplyPort(CsrApiPort,
|
||||
&ApiMessage->Header,
|
||||
&ApiMessage->Header);
|
||||
|
||||
/* Check if we got a Capture Buffer */
|
||||
if (CaptureBuffer)
|
||||
{
|
||||
/*
|
||||
* We have to convert back from the remote (server) view
|
||||
* to our local (client) view.
|
||||
*/
|
||||
ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
|
||||
((ULONG_PTR)ApiMessage->CsrCaptureData - CsrPortMemoryDelta);
|
||||
|
||||
/*
|
||||
* Convert back the offsets into pointers to CSR message
|
||||
* pointers, and convert back these message server pointers
|
||||
* into client pointers.
|
||||
*/
|
||||
PointerCount = CaptureBuffer->PointerCount;
|
||||
OffsetPointer = CaptureBuffer->PointerOffsetsArray;
|
||||
while (PointerCount--)
|
||||
{
|
||||
if (*OffsetPointer != 0)
|
||||
{
|
||||
*OffsetPointer += (ULONG_PTR)ApiMessage;
|
||||
*(PULONG_PTR)*OffsetPointer -= CsrPortMemoryDelta;
|
||||
}
|
||||
++OffsetPointer;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
DPRINT("Server-to-server call\n");
|
||||
|
||||
/* Save our CID; we check this equality inside CsrValidateMessageBuffer */
|
||||
ApiMessage->Header.ClientId = NtCurrentTeb()->ClientId;
|
||||
|
||||
/* Do a direct call */
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
NTAPI
|
||||
CsrGetProcessId(VOID)
|
||||
{
|
||||
return CsrProcessId;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,17 @@
|
||||
@ stdcall CsrAllocateCaptureBuffer(long long)
|
||||
@ stdcall CsrAllocateMessagePointer(ptr long ptr)
|
||||
@ stdcall CsrCaptureMessageBuffer(ptr ptr long ptr)
|
||||
@ stdcall CsrCaptureMessageMultiUnicodeStringsInPlace(ptr long ptr)
|
||||
@ stdcall CsrCaptureMessageString(ptr str long long ptr)
|
||||
@ stdcall CsrCaptureTimeout(long ptr)
|
||||
@ stdcall CsrClientCallServer(ptr ptr long long)
|
||||
@ stdcall CsrClientConnectToServer(str long ptr ptr ptr)
|
||||
@ stdcall CsrFreeCaptureBuffer(ptr)
|
||||
@ stdcall CsrGetProcessId()
|
||||
@ stdcall CsrIdentifyAlertableThread()
|
||||
@ stdcall -version=0x502 CsrNewThread()
|
||||
@ stdcall -version=0x502 CsrProbeForRead(ptr long long)
|
||||
@ stdcall -version=0x502 CsrProbeForWrite(ptr long long)
|
||||
@ stdcall CsrSetPriorityClass(ptr ptr)
|
||||
@ stdcall -stub -version=0x600+ CsrVerifyRegion(ptr long)
|
||||
@ stdcall -stub -version=0x600+ RtlRegisterThreadWithCsrss()
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Client/Server Runtime SubSystem
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: CSR Client Library - Main Header
|
||||
* COPYRIGHT: Copyright 2022 Hermès Bélusca-Maïto <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef _CSRLIB_H_
|
||||
#define _CSRLIB_H_
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
/* PSDK/NDK Headers */
|
||||
#define WIN32_NO_STATUS
|
||||
//#include <windef.h>
|
||||
#define NTOS_MODE_USER
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
/* CSRSS Headers */
|
||||
#include <csr.h>
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
extern HANDLE CsrApiPort;
|
||||
extern HANDLE CsrPortHeap;
|
||||
|
||||
#endif /* _CSRLIB_H_ */
|
||||
|
||||
/* EOF */
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include)
|
||||
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/subsys)
|
||||
|
||||
spec2def(csrsrv.dll csrsrv.spec ADD_IMPORTLIB)
|
||||
@@ -20,7 +19,7 @@ add_library(csrsrv MODULE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/csrsrv.def)
|
||||
|
||||
set_module_type(csrsrv nativedll)
|
||||
target_link_libraries(csrsrv ${PSEH_LIB} smlib)
|
||||
target_link_libraries(csrsrv smlib ${PSEH_LIB})
|
||||
add_importlibs(csrsrv ntdll)
|
||||
add_pch(csrsrv srv.h SOURCE)
|
||||
add_dependencies(csrsrv psdk bugcodes)
|
||||
Reference in New Issue
Block a user