From d736f0b91452308be9b85a58250b045d84c85092 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 5 Nov 2012 00:23:58 +0000 Subject: [PATCH] [NTDLL] - Add parameter annotations. - Improve CSR buffer allocation with 4-byte align. - Simplify the capture-buffer pointers settings. [CSRSRV] - Remove last console structure from csrsrv.h (in next commits it will be placed in a proper header). - Enable global CSR debugging (for debugging purposes... ;-) ). - api.c: Enable debugging. - api.c/.h: Remove old code and deprecated unused definitions. - Use the Win2k3-compliant version of CsrCreateThread (code from subsystems/csr/csrsrv) (TODO: correct its usage in basesrv:BaseSrvCreateThread). - init.c: Implement a helper routine, CsrInitCsrRootProcess, in order to initialize the per-process server data (see CSR_PROCESS structure) in the Root CSR process. New process inherit it from this Root process. - server.c - Add a DPRINT. Remove a hack. Correct a parameter passing. - session.c - Remove a hack (it will go to the new process initialization in consrv) - Disable the code of CsrConnectToUser while user32:ClientThreadSetup doesn't work. - Correct the implementation of CsrValidateMessageBuffer. - Basic implementation of CsrValidateMessageString using CsrValidateMessageBuffer. TODO: - Compare CsrpHandleConnectionRequest with the other one function in api.c. - Compare CsrValidateMessageBuffer with Win32CsrValidateBuffer ? svn path=/branches/ros-csrss/; revision=57673 --- dll/ntdll/csr/api.c | 4 +- dll/ntdll/csr/capture.c | 71 +- dll/ntdll/csr/connect.c | 133 ++-- include/reactos/subsys/csr/csr.h | 29 +- include/reactos/subsys/csr/csrmsg.h | 4 +- include/reactos/subsys/csr/csrsrv.h | 38 +- subsystems/win32/csrsrv/api.c | 1032 +++++++------------------ subsystems/win32/csrsrv/csrsrv.spec | 2 +- subsystems/win32/csrsrv/include/api.h | 48 -- subsystems/win32/csrsrv/init.c | 99 ++- subsystems/win32/csrsrv/procsup.c | 10 +- subsystems/win32/csrsrv/server.c | 22 +- subsystems/win32/csrsrv/session.c | 3 - subsystems/win32/csrsrv/thredsup.c | 63 +- 14 files changed, 542 insertions(+), 1016 deletions(-) diff --git a/dll/ntdll/csr/api.c b/dll/ntdll/csr/api.c index 26fec9c1569..76de9c7b657 100644 --- a/dll/ntdll/csr/api.c +++ b/dll/ntdll/csr/api.c @@ -50,7 +50,7 @@ CsrSetPriorityClass(HANDLE hProcess, NULL, CSR_CREATE_API_NUMBER(CSRSRV_SERVERDLL_INDEX, CsrpSetPriorityClass), sizeof(CSR_SET_PRIORITY_CLASS)); - + /* Return what we got, if requested */ if (*PriorityClass) *PriorityClass = SetPriorityClass->PriorityClass; @@ -68,7 +68,7 @@ CsrIdentifyAlertableThread(VOID) NTSTATUS Status; CSR_API_MESSAGE ApiMessage; PCSR_IDENTIFY_ALTERTABLE_THREAD IdentifyAlertableThread; - + /* Set up the data for CSR */ DbgBreakPoint(); IdentifyAlertableThread = &ApiMessage.Data.IdentifyAlertableThread; diff --git a/dll/ntdll/csr/capture.c b/dll/ntdll/csr/capture.c index 97215d7a422..71fa4414bf3 100644 --- a/dll/ntdll/csr/capture.c +++ b/dll/ntdll/csr/capture.c @@ -82,10 +82,10 @@ CsrProbeForWrite(IN PVOID Address, /* * @implemented */ -PVOID +PCSR_CAPTURE_BUFFER NTAPI -CsrAllocateCaptureBuffer(ULONG ArgumentCount, - ULONG BufferSize) +CsrAllocateCaptureBuffer(IN ULONG ArgumentCount, + IN ULONG BufferSize) { PCSR_CAPTURE_BUFFER CaptureBuffer; @@ -93,10 +93,13 @@ CsrAllocateCaptureBuffer(ULONG ArgumentCount, if (BufferSize >= MAXLONG) return NULL; /* Add the size of the header and for each pointer to the pointers */ - BufferSize += sizeof(CSR_CAPTURE_BUFFER) + (ArgumentCount * sizeof(PVOID)); + BufferSize += FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) + (ArgumentCount * sizeof(ULONG_PTR)); + + /* Align it to a 4-byte boundary */ + BufferSize = (BufferSize + 3) & ~3; /* Allocate memory from the port heap */ - CaptureBuffer = RtlAllocateHeap(CsrPortHeap, 0, BufferSize); + CaptureBuffer = RtlAllocateHeap(CsrPortHeap, HEAP_ZERO_MEMORY, BufferSize); if (CaptureBuffer == NULL) return NULL; /* Initialize the header */ @@ -104,12 +107,12 @@ CsrAllocateCaptureBuffer(ULONG ArgumentCount, CaptureBuffer->PointerCount = 0; /* Initialize all the pointers */ - RtlZeroMemory(CaptureBuffer->PointerArray, + RtlZeroMemory(CaptureBuffer->PointerOffsetsArray, ArgumentCount * sizeof(ULONG_PTR)); - /* Point the start of the free buffer */ - CaptureBuffer->BufferEnd = (ULONG_PTR)CaptureBuffer->PointerArray + - ArgumentCount * sizeof(ULONG_PTR); + /* Point to the start of the free buffer */ + CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->PointerOffsetsArray + + ArgumentCount * sizeof(ULONG_PTR)); /* Return the address of the buffer */ return CaptureBuffer; @@ -120,20 +123,19 @@ CsrAllocateCaptureBuffer(ULONG ArgumentCount, */ ULONG NTAPI -CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer, - ULONG MessageLength, - PVOID *CaptureData) +CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, + IN ULONG MessageLength, + OUT PVOID *CapturedData) { - /* If there's no data, our job is easy. */ if (MessageLength == 0) { - *CaptureData = NULL; - CaptureData = NULL; + *CapturedData = NULL; + CapturedData = NULL; } else { /* Set the capture data at our current available buffer */ - *CaptureData = (PVOID)CaptureBuffer->BufferEnd; + *CapturedData = CaptureBuffer->BufferEnd; /* Validate the size */ if (MessageLength >= MAXLONG) return 0; @@ -142,14 +144,11 @@ CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer, MessageLength = (MessageLength + 3) & ~3; /* Move our available buffer beyond this space */ - CaptureBuffer->BufferEnd += MessageLength; + CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->BufferEnd + MessageLength); } - /* Write down this pointer in the array */ - CaptureBuffer->PointerArray[CaptureBuffer->PointerCount] = (ULONG_PTR)CaptureData; - - /* Increase the pointer count */ - CaptureBuffer->PointerCount++; + /* Write down this pointer in the array and increase the count */ + CaptureBuffer->PointerOffsetsArray[CaptureBuffer->PointerCount++] = (ULONG_PTR)CapturedData; /* Return the aligned length */ return MessageLength; @@ -160,19 +159,19 @@ CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer, */ VOID NTAPI -CsrCaptureMessageBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer, - PVOID MessageString, - ULONG StringLength, - PVOID *CapturedData) +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, StringLength, CapturedData); + CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData); /* Check if there was any data */ - if (!MessageString || !StringLength) return; + if (!MessageBuffer || !MessageLength) return; /* Copy the data into the buffer */ - RtlMoveMemory(*CapturedData, MessageString, StringLength); + RtlMoveMemory(*CapturedData, MessageBuffer, MessageLength); } /* @@ -180,14 +179,14 @@ CsrCaptureMessageBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer, */ VOID NTAPI -CsrFreeCaptureBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer) +CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer) { /* Free it from the heap */ RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer); } /* - * @implemented + * @unimplemented */ NTSTATUS NTAPI @@ -206,8 +205,8 @@ CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER *CaptureBuffe */ VOID NTAPI -CsrCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer, - LPSTR String, +CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, + IN LPSTR String OPTIONAL, IN ULONG StringLength, IN ULONG MaximumLength, OUT PANSI_STRING CapturedString) @@ -256,14 +255,14 @@ CsrCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer, */ PLARGE_INTEGER NTAPI -CsrCaptureTimeout(LONG Milliseconds, - PLARGE_INTEGER Timeout) +CsrCaptureTimeout(IN ULONG Milliseconds, + OUT PLARGE_INTEGER Timeout) { /* Validate the time */ if (Milliseconds == -1) return NULL; /* Convert to relative ticks */ - Timeout->QuadPart = Milliseconds * -100000; + Timeout->QuadPart = Int32x32To64(Milliseconds, -100000); return Timeout; } diff --git a/dll/ntdll/csr/connect.c b/dll/ntdll/csr/connect.c index 27fbb743b17..b142e16f3f8 100644 --- a/dll/ntdll/csr/connect.c +++ b/dll/ntdll/csr/connect.c @@ -51,120 +51,113 @@ CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN ULONG DataLength) { NTSTATUS Status; - ULONG PointerCount; - PULONG_PTR Pointers; - ULONG_PTR CurrentPointer; - DPRINT("CsrClientCallServer\n"); + ULONG i; - /* Fill out the Port Message Header */ + /* Fill out the Port Message Header. */ ApiMessage->Header.u2.ZeroInit = 0; ApiMessage->Header.u1.s1.TotalLength = FIELD_OFFSET(CSR_API_MESSAGE, Data) + DataLength; - /* FIELD_OFFSET(CSR_API_MESSAGE, Data) <= sizeof(CSR_API_MESSAGE) - sizeof(ApiMessage->Data) */ ApiMessage->Header.u1.s1.DataLength = ApiMessage->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - /* Fill out the CSR Header */ + /* Fill out the CSR Header. */ ApiMessage->ApiNumber = ApiNumber; ApiMessage->CsrCaptureData = NULL; - DPRINT("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n", + 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 */ + /* Check if we are already inside a CSR Server. */ if (!InsideCsrProcess) { - /* Check if we got a a Capture Buffer */ + /* Check if we got 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--) + /* + * 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. + */ + for (i = 0 ; i < CaptureBuffer->PointerCount ; ++i) { - /* 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++)) + if (CaptureBuffer->PointerOffsetsArray[i] != 0) { - /* 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); + *(PULONG_PTR)CaptureBuffer->PointerOffsetsArray[i] += CsrPortMemoryDelta; + CaptureBuffer->PointerOffsetsArray[i] -= (ULONG_PTR)ApiMessage; } } } - /* Send the LPC Message */ + /* Send the LPC Message. */ Status = NtRequestWaitReplyPort(CsrApiPort, &ApiMessage->Header, &ApiMessage->Header); - /* Check if we got a a Capture Buffer */ + /* Check if we got a Capture Buffer. */ if (CaptureBuffer) { - /* We have to convert back from the remote view to our local 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--) + /* + * 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. + */ + for (i = 0 ; i < CaptureBuffer->PointerCount ; ++i) { - /* Get this pointer and check if it's valid */ - if ((CurrentPointer = *Pointers++)) + if (CaptureBuffer->PointerOffsetsArray[i] != 0) { - /* Update it */ - CurrentPointer += (ULONG_PTR)ApiMessage; - Pointers[-1] = CurrentPointer; - *(PULONG_PTR)CurrentPointer -= CsrPortMemoryDelta; + CaptureBuffer->PointerOffsetsArray[i] += (ULONG_PTR)ApiMessage; + *(PULONG_PTR)CaptureBuffer->PointerOffsetsArray[i] -= CsrPortMemoryDelta; } } } - /* Check for success */ + /* Check for success. */ if (!NT_SUCCESS(Status)) { - /* We failed. Overwrite the return value with the failure */ + /* 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 */ + /* This is a server-to-server call. Save our CID and do a direct call. */ DPRINT1("Next gen server-to-server call\n"); + + /* We check this equality inside CsrValidateMessageBuffer. */ ApiMessage->Header.ClientId = NtCurrentTeb()->ClientId; + Status = CsrServerApiRoutine(&ApiMessage->Header, &ApiMessage->Header); - - /* Check for success */ + + /* Check for success. */ if (!NT_SUCCESS(Status)) { - /* We failed. Overwrite the return value with the failure */ + /* We failed. Overwrite the return value with the failure. */ ApiMessage->Status = Status; } } - /* Return the CSR Result */ + /* Return the CSR Result. */ DPRINT("Got back: 0x%lx\n", ApiMessage->Status); return ApiMessage->Status; } @@ -203,7 +196,7 @@ CsrpConnectToServer(IN PWSTR ObjectDirectory) PortName.MaximumLength = PortNameLength; /* Allocate a buffer for it */ - PortName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, PortNameLength); + PortName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, PortNameLength); if (PortName.Buffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; @@ -307,6 +300,8 @@ CsrpConnectToServer(IN PWSTR ObjectDirectory) 0); if (CsrPortHeap == NULL) { + /* Failure */ + DPRINT1("Couldn't create heap for CSR port\n"); NtClose(CsrApiPort); CsrApiPort = NULL; return STATUS_INSUFFICIENT_RESOURCES; @@ -332,9 +327,9 @@ CsrClientConnectToServer(IN PWSTR ObjectDirectory, UNICODE_STRING CsrSrvName; HANDLE hCsrSrv; ANSI_STRING CsrServerRoutineName; - PCSR_CAPTURE_BUFFER CaptureBuffer; CSR_API_MESSAGE ApiMessage; PCSR_CLIENT_CONNECT ClientConnect = &ApiMessage.Data.CsrClientConnect; + PCSR_CAPTURE_BUFFER CaptureBuffer; /* Validate the Connection Info */ DPRINT("CsrClientConnectToServer: %lx %p\n", ServerId, ConnectionInfo); @@ -419,15 +414,11 @@ CsrClientConnectToServer(IN PWSTR ObjectDirectory, return STATUS_INSUFFICIENT_RESOURCES; } - /* Allocate a pointer for the connection info*/ - CsrAllocateMessagePointer(CaptureBuffer, - ClientConnect->ConnectionInfoSize, - &ClientConnect->ConnectionInfo); - - /* Copy the data into the buffer */ - RtlMoveMemory(ClientConnect->ConnectionInfo, - ConnectionInfo, - ClientConnect->ConnectionInfoSize); + /* Capture the connection info data */ + CsrCaptureMessageBuffer(CaptureBuffer, + ConnectionInfo, + ClientConnect->ConnectionInfoSize, + &ClientConnect->ConnectionInfo); /* Return the allocated length */ *ConnectionInfoSize = ClientConnect->ConnectionInfoSize; diff --git a/include/reactos/subsys/csr/csr.h b/include/reactos/subsys/csr/csr.h index 7586c3917df..1516860fd33 100644 --- a/include/reactos/subsys/csr/csr.h +++ b/include/reactos/subsys/csr/csr.h @@ -38,27 +38,40 @@ CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength); -PVOID +PCSR_CAPTURE_BUFFER NTAPI CsrAllocateCaptureBuffer(IN ULONG ArgumentCount, IN ULONG BufferSize); -VOID -NTAPI -CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer); - ULONG NTAPI CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN ULONG MessageLength, - OUT PVOID* CaptureData); + OUT PVOID *CapturedData); VOID NTAPI CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, - IN PVOID MessageString, + IN PVOID MessageBuffer OPTIONAL, + IN ULONG MessageLength, + OUT PVOID *CapturedData); + +VOID +NTAPI +CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, + IN LPSTR String OPTIONAL, IN ULONG StringLength, - OUT PVOID* CapturedData); + IN ULONG MaximumLength, + OUT PANSI_STRING CapturedString); + +VOID +NTAPI +CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer); + +PLARGE_INTEGER +NTAPI +CsrCaptureTimeout(IN ULONG Milliseconds, + OUT PLARGE_INTEGER Timeout); VOID NTAPI diff --git a/include/reactos/subsys/csr/csrmsg.h b/include/reactos/subsys/csr/csrmsg.h index c6d129b6a72..a64bfff236c 100644 --- a/include/reactos/subsys/csr/csrmsg.h +++ b/include/reactos/subsys/csr/csrmsg.h @@ -93,8 +93,8 @@ typedef struct _CSR_CAPTURE_BUFFER ULONG Size; struct _CSR_CAPTURE_BUFFER *PreviousCaptureBuffer; ULONG PointerCount; - ULONG_PTR BufferEnd; - ULONG_PTR PointerArray[1]; + PVOID BufferEnd; + ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]; } CSR_CAPTURE_BUFFER, *PCSR_CAPTURE_BUFFER; /* Keep in sync with definition below. */ diff --git a/include/reactos/subsys/csr/csrsrv.h b/include/reactos/subsys/csr/csrsrv.h index 22c1941dbc2..ae0db7d149d 100644 --- a/include/reactos/subsys/csr/csrsrv.h +++ b/include/reactos/subsys/csr/csrsrv.h @@ -24,7 +24,7 @@ /* TYPES **********************************************************************/ // Used in ntdll/csr/connect.c -#define CSR_CSRSS_SECTION_SIZE (65536) +#define CSR_CSRSS_SECTION_SIZE 65536 typedef struct _CSR_NT_SESSION { @@ -33,21 +33,6 @@ typedef struct _CSR_NT_SESSION ULONG SessionId; } CSR_NT_SESSION, *PCSR_NT_SESSION; -/*** old thingie, remove it later... (put it in winsrv -- console) ***/ -#include -typedef struct _CSRSS_CON_PROCESS_DATA -{ - HANDLE ConsoleEvent; - struct tagCSRSS_CONSOLE *Console; - struct tagCSRSS_CONSOLE *ParentConsole; - BOOL bInheritHandles; - RTL_CRITICAL_SECTION HandleTableLock; - ULONG HandleTableSize; - struct _CSRSS_HANDLE *HandleTable; - PCONTROLDISPATCHER CtrlDispatcher; - LIST_ENTRY ConsoleLink; -} CSRSS_CON_PROCESS_DATA, *PCSRSS_CON_PROCESS_DATA; -/*********************************************************************/ typedef struct _CSR_PROCESS { CLIENT_ID ClientId; @@ -73,8 +58,7 @@ typedef struct _CSR_PROCESS ULONG Reserved; ULONG ShutdownLevel; ULONG ShutdownFlags; - PVOID ServerData[ANYSIZE_ARRAY]; // ServerDllPerProcessData // One structure per CSR server. - CSRSS_CON_PROCESS_DATA; //// FIXME: Remove it after we activate the previous member. + PVOID ServerData[ANYSIZE_ARRAY]; // One structure per CSR server. } CSR_PROCESS, *PCSR_PROCESS; typedef struct _CSR_THREAD @@ -181,10 +165,10 @@ NTSTATUS OUT PULONG Reply ); -#define CSR_API(n) NTSTATUS NTAPI n( \ - IN OUT PCSR_API_MESSAGE ApiMessage, \ - OUT PULONG Reply) - // IN OUT PCSR_REPLY_STATUS ReplyStatus) +#define CSR_API(n) \ + NTSTATUS NTAPI n(IN OUT PCSR_API_MESSAGE ApiMessage, \ + OUT PULONG Reply) + // IN OUT PCSR_REPLY_STATUS ReplyStatus) typedef NTSTATUS @@ -250,7 +234,8 @@ typedef NTSTATUS (NTAPI *PCSR_SERVER_DLL_INIT_CALLBACK)(IN PCSR_SERVER_DLL LoadedServerDll); -#define CSR_SERVER_DLL_INIT(n) NTSTATUS NTAPI n(IN PCSR_SERVER_DLL LoadedServerDll) +#define CSR_SERVER_DLL_INIT(n) \ + NTSTATUS NTAPI n(IN PCSR_SERVER_DLL LoadedServerDll) /* PROTOTYPES ****************************************************************/ @@ -306,7 +291,8 @@ NTSTATUS NTAPI CsrCreateThread(IN PCSR_PROCESS CsrProcess, IN HANDLE hThread, - IN PCLIENT_ID ClientId); + IN PCLIENT_ID ClientId, + IN BOOLEAN HaveClient); BOOLEAN NTAPI @@ -431,8 +417,8 @@ BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, - IN ULONG ArgumentSize, - IN ULONG ArgumentCount); + IN ULONG ElementCount, + IN ULONG ElementSize); BOOLEAN NTAPI diff --git a/subsystems/win32/csrsrv/api.c b/subsystems/win32/csrsrv/api.c index 111cf89d334..854a26e37d9 100644 --- a/subsystems/win32/csrsrv/api.c +++ b/subsystems/win32/csrsrv/api.c @@ -11,14 +11,11 @@ #include "srv.h" -#define NDEBUG +//#define NDEBUG #include /* GLOBALS ********************************************************************/ -static unsigned ApiDefinitionsCount = 0; -static PCSRSS_API_DEFINITION ApiDefinitions = NULL; - BOOLEAN (*CsrClientThreadSetup)(VOID) = NULL; UNICODE_STRING CsrApiPortName; volatile LONG CsrpStaticThreadCount; @@ -27,88 +24,6 @@ extern ULONG CsrMaxApiRequestThreads; /* FUNCTIONS ******************************************************************/ -#if 0 -NTSTATUS FASTCALL -CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions) -{ - unsigned NewCount; - PCSRSS_API_DEFINITION Scan; - PCSRSS_API_DEFINITION New; - - DPRINT("CSR: %s called\n", __FUNCTION__); - - NewCount = 0; - for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++) - { - NewCount++; - } - - New = RtlAllocateHeap(CsrHeap, 0, - (ApiDefinitionsCount + NewCount) - * sizeof(CSRSS_API_DEFINITION)); - if (NULL == New) - { - DPRINT1("Unable to allocate memory\n"); - return STATUS_NO_MEMORY; - } - if (0 != ApiDefinitionsCount) - { - RtlCopyMemory(New, ApiDefinitions, - ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION)); - RtlFreeHeap(CsrHeap, 0, ApiDefinitions); - } - RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions, - NewCount * sizeof(CSRSS_API_DEFINITION)); - ApiDefinitions = New; - ApiDefinitionsCount += NewCount; - - return STATUS_SUCCESS; -} -#endif - -/* -VOID -FASTCALL -CsrApiCallHandler(PCSR_PROCESS ProcessData, - PCSR_API_MESSAGE Request) -*/ -VOID -FASTCALL -CsrApiCallHandler( - IN OUT PCSR_API_MESSAGE ApiMessage, - OUT PULONG Reply -) -{ - unsigned DefIndex; - ULONG ApiId; - - DPRINT("CSR: Calling handler for ApiNumber: %x.\n", ApiMessage->ApiNumber); - ApiId = CSR_API_NUMBER_TO_API_ID(ApiMessage->ApiNumber); - DPRINT("CSR: ApiID: %x ServerID: %x\n", ApiId, CSR_API_NUMBER_TO_SERVER_ID(ApiMessage->ApiNumber)); - - /* FIXME: Extract DefIndex instead of looping */ - for (DefIndex = 0; DefIndex < ApiDefinitionsCount; DefIndex++) - { - if (ApiDefinitions[DefIndex].ApiID == ApiId) - { - if (ApiMessage->Header.u1.s1.DataLength < ApiDefinitions[DefIndex].MinRequestSize) - { - DPRINT1("Request ApiID %d min request size %d actual %d\n", - ApiId, ApiDefinitions[DefIndex].MinRequestSize, - ApiMessage->Header.u1.s1.DataLength); - ApiMessage->Status = STATUS_INVALID_PARAMETER; - } - else - { - ApiMessage->Status = (ApiDefinitions[DefIndex].Handler)(ApiMessage, Reply); - } - return; - } - } - DPRINT1("CSR: Unknown request ApiNumber 0x%x\n", ApiMessage->ApiNumber); - ApiMessage->Status = STATUS_INVALID_SYSTEM_SERVICE; -} - VOID CallHardError(IN PCSR_THREAD ThreadData, IN PHARDERROR_MSG HardErrorMessage); @@ -152,7 +67,6 @@ NTAPI CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, IN OUT PCSR_API_MESSAGE ReplyMsg) { -#if 1 // Real code ULONG ServerId; PCSR_SERVER_DLL ServerDll; ULONG ApiId; @@ -173,11 +87,8 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, } else { - /* Get the API ID */ - ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg->ApiNumber); - - /* Normalize it with our Base ID */ - ApiId -= ServerDll->ApiBase; + /* Get the API ID, normalized with our Base ID */ + ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg->ApiNumber) - ServerDll->ApiBase; /* Make sure that the ID is within limits, and the entry exists */ if ((ApiId >= ServerDll->HighestApiSupported) || @@ -220,40 +131,6 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, /* Return success */ return STATUS_SUCCESS; - -#else // Hacky reactos code - - PCSR_PROCESS ProcessData; - ULONG ReplyCode; - - /* Get the Process Data */ - CsrLockProcessByClientId(&ReceiveMsg->Header.ClientId.UniqueProcess, &ProcessData); - if (!ProcessData) - { - DPRINT1("Message: Unable to find data for process 0x%x\n", - ReceiveMsg->Header.ClientId.UniqueProcess); - return STATUS_NOT_SUPPORTED; - } - - /* Validation complete, start SEH */ - _SEH2_TRY - { - /* Call the API and get the result */ - CsrApiCallHandler(ReplyMsg, /*ProcessData*/ &ReplyCode); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* If we got an exception, return access violation */ - ReplyMsg->Status = STATUS_ACCESS_VIOLATION; - } - _SEH2_END; - - /* Release the process reference */ - CsrUnlockProcess(ProcessData); - - /* Return success */ - return STATUS_SUCCESS; -#endif } /*++ @@ -391,6 +268,107 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage) return Status; } +// TODO: See CsrApiHandleConnectionRequest +NTSTATUS WINAPI +CsrpHandleConnectionRequest(PPORT_MESSAGE Request) +{ + NTSTATUS Status; + HANDLE ServerPort = NULL;//, ServerThread = NULL; + PCSR_PROCESS ProcessData = NULL; + REMOTE_PORT_VIEW RemotePortView; +// CLIENT_ID ClientId; + BOOLEAN AllowConnection = FALSE; + PCSR_CONNECTION_INFO ConnectInfo; + ServerPort = NULL; + + DPRINT1("CSR: %s: Handling: %p\n", __FUNCTION__, Request); + + ConnectInfo = (PCSR_CONNECTION_INFO)(Request + 1); + + /* Save the process ID */ + RtlZeroMemory(ConnectInfo, sizeof(CSR_CONNECTION_INFO)); + + CsrLockProcessByClientId(Request->ClientId.UniqueProcess, &ProcessData); + if (!ProcessData) + { + DPRINT1("CSRSRV: Unknown process: %lx. Will be rejecting connection\n", + Request->ClientId.UniqueProcess); + } + + if ((ProcessData) && (ProcessData != CsrRootProcess)) + { + /* Attach the Shared Section */ + Status = CsrSrvAttachSharedSection(ProcessData, ConnectInfo); + if (NT_SUCCESS(Status)) + { + DPRINT1("Connection ok\n"); + AllowConnection = TRUE; + } + else + { + DPRINT1("Shared section map failed: %lx\n", Status); + } + } + else if (ProcessData == CsrRootProcess) + { + AllowConnection = TRUE; + } + + /* Release the process */ + if (ProcessData) CsrUnlockProcess(ProcessData); + + /* Setup the Port View Structure */ + RemotePortView.Length = sizeof(REMOTE_PORT_VIEW); + RemotePortView.ViewSize = 0; + RemotePortView.ViewBase = NULL; + + /* Save the Process ID */ + ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess; + + Status = NtAcceptConnectPort(&ServerPort, + AllowConnection ? UlongToPtr(ProcessData->SequenceNumber) : 0, + Request, + AllowConnection, + NULL, + &RemotePortView); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: NtAcceptConnectPort - failed. Status == %X\n", Status); + } + else if (AllowConnection) + { + if (CsrDebug & 2) + { + DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n", + Request->ClientId.UniqueProcess, + Request->ClientId.UniqueThread, + RemotePortView.ViewBase, + RemotePortView.ViewSize); + } + + /* Set some Port Data in the Process */ + ProcessData->ClientPort = ServerPort; + ProcessData->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase; + ProcessData->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase + + (ULONG_PTR)RemotePortView.ViewSize); + + /* Complete the connection */ + Status = NtCompleteConnectPort(ServerPort); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status); + } + } + else + { + DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n", + Request->ClientId.UniqueProcess, + Request->ClientId.UniqueThread); + } + + return Status; +} + /*++ * @name CsrpCheckRequestThreads * @@ -486,7 +464,6 @@ CsrpCheckRequestThreads(VOID) NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter) -#if 1 { PTEB Teb = NtCurrentTeb(); LARGE_INTEGER TimeOut; @@ -649,7 +626,7 @@ CsrApiRequestThread(IN PVOID Parameter) if ((ServerDll) && (ServerDll->HardErrorCallback)) { /* Call it */ - ServerDll->HardErrorCallback(NULL, HardErrorMsg); + ServerDll->HardErrorCallback(NULL /* CsrThread */, HardErrorMsg); /* If it's handled, get out of here */ if (HardErrorMsg->Response != ResponseNotHandled) break; @@ -697,11 +674,8 @@ CsrApiRequestThread(IN PVOID Parameter) continue; } - /* Get the API ID */ - ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber); - - /* Normalize it with our Base ID */ - ApiId -= ServerDll->ApiBase; + /* Get the API ID, normalized with our Base ID */ + ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase; /* Make sure that the ID is within limits, and the entry exists */ if (ApiId >= ServerDll->HighestApiSupported) @@ -897,11 +871,8 @@ CsrApiRequestThread(IN PVOID Parameter) continue; } - /* Get the API ID */ - ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber); - - /* Normalize it with our Base ID */ - ApiId -= ServerDll->ApiBase; + /* Get the API ID, normalized with our Base ID */ + ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase; /* Make sure that the ID is within limits, and the entry exists */ if (ApiId >= ServerDll->HighestApiSupported) @@ -1007,429 +978,78 @@ CsrApiRequestThread(IN PVOID Parameter) NtTerminateThread(NtCurrentThread(), Status); return Status; } -#else + +/*++ + * @name CsrApiPortInitialize + * + * The CsrApiPortInitialize routine initializes the LPC Port used for + * communications with the Client/Server Runtime (CSR) and initializes the + * static thread that will handle connection requests and APIs. + * + * @param None + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * otherwise. + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +CsrApiPortInitialize(VOID) { - PTEB Teb = NtCurrentTeb(); - LARGE_INTEGER TimeOut; + ULONG Size; + OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; - BYTE RawRequest[LPC_MAX_DATA_LENGTH]; - PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest; - PCSR_API_MESSAGE Reply; - PCSR_PROCESS CsrProcess; - PCSR_THREAD ServerThread, CsrThread; - ULONG MessageType; - HANDLE ReplyPort; - PDBGKM_MSG DebugMessage; - PHARDERROR_MSG HardErrorMsg; - PCLIENT_DIED_MSG ClientDiedMsg; - DPRINT("CSR: %s called\n", __FUNCTION__); + HANDLE hRequestEvent, hThread; + CLIENT_ID ClientId; + PLIST_ENTRY ListHead, NextEntry; + PCSR_THREAD ServerThread; - /* Setup LPC loop port and message */ - Reply = NULL; - ReplyPort = CsrApiPort; + /* Calculate how much space we'll need for the Port Name */ + Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR); - /* Connect to user32 */ - while (!CsrConnectToUser()) - { - /* Set up the timeout for the connect (30 seconds) */ - TimeOut.QuadPart = -30 * 1000 * 1000 * 10; + /* Create the buffer for it */ + CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size); + if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY; - /* Keep trying until we get a response */ - Teb->Win32ClientInfo[0] = 0; - NtDelayExecution(FALSE, &TimeOut); + /* Setup the rest of the empty string */ + CsrApiPortName.Length = 0; + CsrApiPortName.MaximumLength = (USHORT)Size; + RtlAppendUnicodeStringToString(&CsrApiPortName, &CsrDirectoryName); + RtlAppendUnicodeToString(&CsrApiPortName, UNICODE_PATH_SEP); + RtlAppendUnicodeToString(&CsrApiPortName, CSR_PORT_NAME); + if (CsrDebug & 1) + { + DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName); + DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) == %ld\n", + sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE)); } - /* Get our thread */ - ServerThread = Teb->CsrClientThread; - - /* If we got an event... */ - if (Parameter) - { - /* Set it, to let stuff waiting on us load */ - Status = NtSetEvent((HANDLE)Parameter, NULL); - ASSERT(NT_SUCCESS(Status)); + /* FIXME: Create a Security Descriptor */ - /* Increase the Thread Counts */ - _InterlockedIncrement(&CsrpStaticThreadCount); - _InterlockedIncrement(&CsrpDynamicThreadTotal); - } + /* Initialize the Attributes */ + InitializeObjectAttributes(&ObjectAttributes, + &CsrApiPortName, + 0, + NULL, + NULL /* FIXME*/); - /* Now start the loop */ - while (TRUE) + /* Create the Port Object */ + Status = NtCreatePort(&CsrApiPort, + &ObjectAttributes, + LPC_MAX_DATA_LENGTH, // HACK: the real value is: sizeof(CSR_CONNECTION_INFO), + LPC_MAX_MESSAGE_LENGTH, // HACK: the real value is: sizeof(CSR_API_MESSAGE), + 16 * PAGE_SIZE); + if (NT_SUCCESS(Status)) { - /* Make sure the real CID is set */ - Teb->RealClientId = Teb->ClientId; - - /* Debug check */ - if (Teb->CountOfOwnedCriticalSections) - { - DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu critical sections\n", - Teb->CountOfOwnedCriticalSections); - DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n", - Request, Reply); - DbgBreakPoint(); - } - - /* Send the reply and wait for a new request */ - DPRINT("Replying to: %lx (%lx)\n", ReplyPort, CsrApiPort); - Status = NtReplyWaitReceivePort(ReplyPort, - 0, - &Reply->Header, - &Request->Header); - /* Check if we didn't get success */ - if (Status != STATUS_SUCCESS) - { - /* Was it a failure or another success code? */ - if (!NT_SUCCESS(Status)) - { - /* Check for specific status cases */ - if ((Status != STATUS_INVALID_CID) && - (Status != STATUS_UNSUCCESSFUL) && - ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort))) - { - /* Notify the debugger */ - DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status); - DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort); - } - - /* We failed big time, so start out fresh */ - Reply = NULL; - ReplyPort = CsrApiPort; - DPRINT1("failed: %lx\n", Status); - continue; - } - else - { - /* A bizare "success" code, just try again */ - DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status); - continue; - } - } - - /* Use whatever Client ID we got */ - Teb->RealClientId = Request->Header.ClientId; - - /* Get the Message Type */ - MessageType = Request->Header.u2.s2.Type; - - /* Handle connection requests */ - if (MessageType == LPC_CONNECTION_REQUEST) - { - /* Handle the Connection Request */ - DPRINT("Accepting new connection\n"); - CsrpHandleConnectionRequest((PPORT_MESSAGE)Request); - Reply = NULL; - ReplyPort = CsrApiPort; - continue; - } - - /* It's some other kind of request. Get the lock for the lookup */ - CsrAcquireProcessLock(); - - /* Now do the lookup to get the CSR_THREAD */ - CsrThread = CsrLocateThreadByClientId(&CsrProcess, - &Request->Header.ClientId); - - /* Did we find a thread? */ - if (!CsrThread) - { - /* This wasn't a CSR Thread, release lock */ - CsrReleaseProcessLock(); - - /* If this was an exception, handle it */ - if (MessageType == LPC_EXCEPTION) - { - DPRINT1("Exception from unknown thread, just continue\n"); - Reply = Request; - ReplyPort = CsrApiPort; - Reply->Status = DBG_CONTINUE; - } - else if (MessageType == LPC_PORT_CLOSED || - MessageType == LPC_CLIENT_DIED) - { - /* The Client or Port are gone, loop again */ - DPRINT("Death from unknown thread, just continue\n"); - Reply = NULL; - ReplyPort = CsrApiPort; - } - else if (MessageType == LPC_ERROR_EVENT) - { - /* If it's a hard error, handle this too */ - DPRINT1("Hard error from unknown thread, call handlers\n"); -HandleHardError: - HardErrorMsg = (PHARDERROR_MSG)Request; - - /* Default it to unhandled */ - HardErrorMsg->Response = ResponseNotHandled; - - /* Check if there are free api threads */ - CsrpCheckRequestThreads(); - if (CsrpStaticThreadCount) - { - CsrHandleHardError(CsrThread, (PHARDERROR_MSG)Request); - } - - /* If the response was 0xFFFFFFFF, we'll ignore it */ - if (HardErrorMsg->Response == 0xFFFFFFFF) - { - Reply = NULL; - ReplyPort = CsrApiPort; - } - else - { - if (CsrThread) CsrDereferenceThread(CsrThread); - Reply = Request; - ReplyPort = CsrApiPort; - } - } - else if (MessageType == LPC_REQUEST) - { - /* This is an API Message coming from a non-CSR Thread */ - DPRINT1("No thread found for request %lx and clientID %lx.%lx\n", - Request->ApiNumber & 0xFFFF, - Request->Header.ClientId.UniqueProcess, - Request->Header.ClientId.UniqueThread); - Reply = Request; - ReplyPort = CsrApiPort; - Reply->Status = STATUS_ILLEGAL_FUNCTION; - } - else if (MessageType == LPC_DATAGRAM) - { - DPRINT1("Kernel datagram: not yet supported\n"); - Reply = NULL; - ReplyPort = CsrApiPort; - } - else - { - /* Some other ignored message type */ - Reply = NULL; - ReplyPort = CsrApiPort; - } - - /* Keep going */ - continue; - } - - /* We have a valid thread, was this an LPC Request? */ - if (MessageType != LPC_REQUEST) - { - /* It's not an API, check if the client died */ - if (MessageType == LPC_CLIENT_DIED) - { - /* Get the information and check if it matches our thread */ - ClientDiedMsg = (PCLIENT_DIED_MSG)Request; - if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart) - { - /* Reference the thread */ - CsrLockedReferenceThread(CsrThread); - - /* Destroy the thread in the API Message */ - CsrDestroyThread(&Request->Header.ClientId); - - /* Check if the thread was actually ourselves */ - if (CsrProcess->ThreadCount == 1) - { - /* Kill the process manually here */ - DPRINT1("Last thread\n"); - CsrDestroyProcess(&CsrThread->ClientId, 0); - } - - /* Remove our extra reference */ - CsrLockedDereferenceThread(CsrThread); - } - - /* Release the lock and keep looping */ - CsrReleaseProcessLock(); - Reply = NULL; - ReplyPort = CsrApiPort; - continue; - } - - /* Reference the thread and release the lock */ - CsrLockedReferenceThread(CsrThread); - CsrReleaseProcessLock(); - - /* If this was an exception, handle it */ - if (MessageType == LPC_EXCEPTION) - { - /* Kill the process */ - DPRINT1("Exception in %lx.%lx. Killing...\n", - Request->Header.ClientId.UniqueProcess, - Request->Header.ClientId.UniqueThread); - NtTerminateProcess(CsrProcess->ProcessHandle, STATUS_ABANDONED); - - /* Destroy it from CSR */ - CsrDestroyProcess(&Request->Header.ClientId, STATUS_ABANDONED); - - /* Return a Debug Message */ - DebugMessage = (PDBGKM_MSG)Request; - DebugMessage->ReturnedStatus = DBG_CONTINUE; - Reply = Request; - ReplyPort = CsrApiPort; - - /* Remove our extra reference */ - CsrDereferenceThread(CsrThread); - } - else if (MessageType == LPC_ERROR_EVENT) - { - DPRINT1("Hard error from known CSR thread... handling\n"); - goto HandleHardError; - } - else - { - /* Something else */ - DPRINT1("Unhandled message type: %lx\n", MessageType); - CsrDereferenceThread(CsrThread); - Reply = NULL; - } - - /* Keep looping */ - continue; - } - - /* We got an API Request */ - CsrLockedReferenceThread(CsrThread); - CsrReleaseProcessLock(); - - /* Assume success */ - Reply = Request; - Request->Status = STATUS_SUCCESS; - - /* Now we reply to a particular client */ - ReplyPort = CsrThread->Process->ClientPort; - - DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n", - Request->ApiNumber, - Request->Header.ClientId.UniqueThread); - - /* Validation complete, start SEH */ - _SEH2_TRY - { - ULONG ReplyCode; - - /* Make sure we have enough threads */ - CsrpCheckRequestThreads(); - - /* Set the client thread pointer */ - NtCurrentTeb()->CsrClientThread = CsrThread; - - /* Call the Handler */ - CsrApiCallHandler(Request, &ReplyCode); - - /* Increase the static thread count */ - _InterlockedIncrement(&CsrpStaticThreadCount); - - /* Restore the server thread */ - NtCurrentTeb()->CsrClientThread = ServerThread; - - /* Check if this is a dead client now */ - if (Request->ApiNumber == 0xBABE) - { - /* Reply to the death message */ - NtReplyPort(ReplyPort, &Reply->Header); - - /* Reply back to the API port now */ - ReplyPort = CsrApiPort; - Reply = NULL; - - /* Drop the reference */ - CsrDereferenceThread(CsrThread); - } - else - { - /* Drop the reference */ - CsrDereferenceThread(CsrThread); - } - } - _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation())) - { - Reply = NULL; - ReplyPort = CsrApiPort; - } - _SEH2_END; - } - - /* Close the port and exit the thread */ - // NtClose(ServerPort); - - DPRINT1("CSR: %s done\n", __FUNCTION__); - /* We're out of the loop for some reason, terminate! */ - NtTerminateThread(NtCurrentThread(), Status); - //return Status; -} -#endif - -/*++ - * @name CsrApiPortInitialize - * - * The CsrApiPortInitialize routine initializes the LPC Port used for - * communications with the Client/Server Runtime (CSR) and initializes the - * static thread that will handle connection requests and APIs. - * - * @param None - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * otherwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrApiPortInitialize(VOID) -{ - ULONG Size; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS Status; - HANDLE hRequestEvent, hThread; - CLIENT_ID ClientId; - PLIST_ENTRY ListHead, NextEntry; - PCSR_THREAD ServerThread; - - /* Calculate how much space we'll need for the Port Name */ - Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR); - - /* Create the buffer for it */ - CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size); - if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY; - - /* Setup the rest of the empty string */ - CsrApiPortName.Length = 0; - CsrApiPortName.MaximumLength = (USHORT)Size; - RtlAppendUnicodeStringToString(&CsrApiPortName, &CsrDirectoryName); - RtlAppendUnicodeToString(&CsrApiPortName, UNICODE_PATH_SEP); - RtlAppendUnicodeToString(&CsrApiPortName, CSR_PORT_NAME); - if (CsrDebug & 1) - { - DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName); - DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) == %ld\n", - sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE)); - } - - /* FIXME: Create a Security Descriptor */ - - /* Initialize the Attributes */ - InitializeObjectAttributes(&ObjectAttributes, - &CsrApiPortName, - 0, - NULL, - NULL /* FIXME*/); - - /* Create the Port Object */ - Status = NtCreatePort(&CsrApiPort, - &ObjectAttributes, - LPC_MAX_DATA_LENGTH, // hack ; sizeof(CSR_CONNECTION_INFO), - LPC_MAX_MESSAGE_LENGTH, // hack ; sizeof(CSR_API_MESSAGE), - 16 * PAGE_SIZE); - if (NT_SUCCESS(Status)) - { - /* Create the event the Port Thread will use */ - Status = NtCreateEvent(&hRequestEvent, - EVENT_ALL_ACCESS, - NULL, - SynchronizationEvent, - FALSE); - if (NT_SUCCESS(Status)) + /* Create the event the Port Thread will use */ + Status = NtCreateEvent(&hRequestEvent, + EVENT_ALL_ACCESS, + NULL, + SynchronizationEvent, + FALSE); + if (NT_SUCCESS(Status)) { /* Create the Request Thread */ Status = RtlCreateUserThread(NtCurrentProcess(), @@ -1482,106 +1102,6 @@ CsrApiPortInitialize(VOID) return Status; } -NTSTATUS WINAPI -CsrpHandleConnectionRequest(PPORT_MESSAGE Request) -{ - NTSTATUS Status; - HANDLE ServerPort = NULL;//, ServerThread = NULL; - PCSR_PROCESS ProcessData = NULL; - REMOTE_PORT_VIEW RemotePortView; -// CLIENT_ID ClientId; - BOOLEAN AllowConnection = FALSE; - PCSR_CONNECTION_INFO ConnectInfo; - ServerPort = NULL; - - DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__, Request); - - ConnectInfo = (PCSR_CONNECTION_INFO)(Request + 1); - - /* Save the process ID */ - RtlZeroMemory(ConnectInfo, sizeof(CSR_CONNECTION_INFO)); - - CsrLockProcessByClientId(Request->ClientId.UniqueProcess, &ProcessData); - if (!ProcessData) - { - DPRINT1("CSRSRV: Unknown process: %lx. Will be rejecting connection\n", - Request->ClientId.UniqueProcess); - } - - if ((ProcessData) && (ProcessData != CsrRootProcess)) - { - /* Attach the Shared Section */ - Status = CsrSrvAttachSharedSection(ProcessData, ConnectInfo); - if (NT_SUCCESS(Status)) - { - DPRINT("Connection ok\n"); - AllowConnection = TRUE; - } - else - { - DPRINT1("Shared section map failed: %lx\n", Status); - } - } - else if (ProcessData == CsrRootProcess) - { - AllowConnection = TRUE; - } - - /* Release the process */ - if (ProcessData) CsrUnlockProcess(ProcessData); - - /* Setup the Port View Structure */ - RemotePortView.Length = sizeof(REMOTE_PORT_VIEW); - RemotePortView.ViewSize = 0; - RemotePortView.ViewBase = NULL; - - /* Save the Process ID */ - ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess; - - Status = NtAcceptConnectPort(&ServerPort, - AllowConnection ? UlongToPtr(ProcessData->SequenceNumber) : 0, - Request, - AllowConnection, - NULL, - &RemotePortView); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: NtAcceptConnectPort - failed. Status == %X\n", Status); - } - else if (AllowConnection) - { - if (CsrDebug & 2) - { - DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n", - Request->ClientId.UniqueProcess, - Request->ClientId.UniqueThread, - RemotePortView.ViewBase, - RemotePortView.ViewSize); - } - - /* Set some Port Data in the Process */ - ProcessData->ClientPort = ServerPort; - ProcessData->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase; - ProcessData->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase + - (ULONG_PTR)RemotePortView.ViewSize); - - /* Complete the connection */ - Status = NtCompleteConnectPort(ServerPort); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status); - } - } - else - { - DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n", - Request->ClientId.UniqueProcess, - Request->ClientId.UniqueThread); - } - - return Status; -} - /*++ * @name CsrConnectToUser * @implemented NT4 @@ -1599,6 +1119,7 @@ PCSR_THREAD NTAPI CsrConnectToUser(VOID) { +#if 0 // This code is OK, however it is ClientThreadSetup which sucks. NTSTATUS Status; ANSI_STRING DllName; UNICODE_STRING TempName; @@ -1655,6 +1176,19 @@ CsrConnectToUser(VOID) /* Return it */ return CsrThread; + +#else + + PTEB Teb = NtCurrentTeb(); + PCSR_THREAD CsrThread; + + /* Save pointer to this thread in TEB */ + CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId); + if (CsrThread) Teb->CsrClientThread = CsrThread; + + /* Return it */ + return CsrThread; +#endif } /*++ @@ -1703,20 +1237,20 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread, IN PCSR_API_MESSAGE ApiMessage) { PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL, RemoteCaptureBuffer = NULL; - ULONG LocalLength = 0, PointerCount = 0; - SIZE_T BufferDistance = 0; - ULONG_PTR **PointerOffsets = NULL, *CurrentPointer = NULL; + SIZE_T BufferDistance; + ULONG Length = 0; + ULONG i; /* Use SEH to make sure this is valid */ _SEH2_TRY { /* Get the buffer we got from whoever called NTDLL */ LocalCaptureBuffer = ApiMessage->CsrCaptureData; - LocalLength = LocalCaptureBuffer->Size; + Length = LocalCaptureBuffer->Size; /* Now check if the buffer is inside our mapped section */ if (((ULONG_PTR)LocalCaptureBuffer < CsrThread->Process->ClientViewBase) || - (((ULONG_PTR)LocalCaptureBuffer + LocalLength) >= CsrThread->Process->ClientViewBounds)) + (((ULONG_PTR)LocalCaptureBuffer + Length) >= CsrThread->Process->ClientViewBounds)) { /* Return failure */ DPRINT1("*** CSRSS: CaptureBuffer outside of ClientView\n"); @@ -1725,8 +1259,9 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread, } /* Check if the Length is valid */ - if (((LocalCaptureBuffer->PointerCount * 4 + sizeof(CSR_CAPTURE_BUFFER)) > - LocalLength) ||(LocalLength > MAXWORD)) + if ((FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) + + (LocalCaptureBuffer->PointerCount * sizeof(PVOID)) > Length) || + (Length > MAXWORD)) { /* Return failure */ DPRINT1("*** CSRSS: CaptureBuffer %p has bad length\n", LocalCaptureBuffer); @@ -1743,7 +1278,7 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread, } _SEH2_END; /* We validated the incoming buffer, now allocate the remote one */ - RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, 0, LocalLength); + RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, 0, Length); if (!RemoteCaptureBuffer) { /* We're out of memory */ @@ -1752,33 +1287,27 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread, } /* Copy the client's buffer */ - RtlMoveMemory(RemoteCaptureBuffer, LocalCaptureBuffer, LocalLength); - - /* Copy the length */ - RemoteCaptureBuffer->Size = LocalLength; + RtlMoveMemory(RemoteCaptureBuffer, LocalCaptureBuffer, Length); /* Calculate the difference between our buffer and the client's */ BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer; - /* Save the pointer count and offset pointer */ - PointerCount = RemoteCaptureBuffer->PointerCount; - PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1); - - /* Start the loop */ - while (PointerCount) + /* + * Convert all the pointer offsets into real pointers, and make + * them point to the remote data buffer instead of the local one. + */ + for (i = 0 ; i < RemoteCaptureBuffer->PointerCount ; ++i) { - /* Get the current pointer */ - if ((CurrentPointer = *PointerOffsets++)) + if (RemoteCaptureBuffer->PointerOffsetsArray[i] != 0) { - /* Add it to the CSR Message structure */ - CurrentPointer += (ULONG_PTR)ApiMessage; + RemoteCaptureBuffer->PointerOffsetsArray[i] += (ULONG_PTR)ApiMessage; /* Validate the bounds of the current pointer */ - if ((*CurrentPointer >= CsrThread->Process->ClientViewBase) && - (*CurrentPointer < CsrThread->Process->ClientViewBounds)) + if ((*(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] >= CsrThread->Process->ClientViewBase) && + (*(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] < CsrThread->Process->ClientViewBounds)) { /* Modify the pointer to take into account its new position */ - *CurrentPointer += BufferDistance; + *(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] += BufferDistance; } else { @@ -1788,9 +1317,6 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread, ApiMessage->Status = STATUS_INVALID_PARAMETER; } } - - /* Move to the next Pointer */ - PointerCount--; } /* Check if we got success */ @@ -1833,39 +1359,33 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage) { PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer; SIZE_T BufferDistance; - ULONG PointerCount; - ULONG_PTR **PointerOffsets, *CurrentPointer; + ULONG i; /* Get the capture buffers */ RemoteCaptureBuffer = ApiMessage->CsrCaptureData; LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer; + /* Do not continue if there is no captured buffer */ + if (!RemoteCaptureBuffer) return; + /* Free the previous one */ RemoteCaptureBuffer->PreviousCaptureBuffer = NULL; - /* Find out the difference between the two buffers */ - BufferDistance = (ULONG_PTR)LocalCaptureBuffer - (ULONG_PTR)RemoteCaptureBuffer; - - /* Save the pointer count and offset pointer */ - PointerCount = RemoteCaptureBuffer->PointerCount; - PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1); + /* Calculate the difference between our buffer and the client's */ + BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer; - /* Start the loop */ - while (PointerCount) + /* + * Convert back all the pointers into pointer offsets, and make them + * point to the local data buffer instead of the remote one (revert + * the logic of CsrCaptureArguments). + */ + for (i = 0 ; i < RemoteCaptureBuffer->PointerCount ; ++i) { - /* Get the current pointer */ - CurrentPointer = *PointerOffsets++; - if (CurrentPointer) + if (RemoteCaptureBuffer->PointerOffsetsArray[i] != 0) { - /* Add it to the CSR Message structure */ - CurrentPointer += (ULONG_PTR)ApiMessage; - - /* Modify the pointer to take into account its new position */ - *CurrentPointer += BufferDistance; + *(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] -= BufferDistance; + RemoteCaptureBuffer->PointerOffsetsArray[i] -= (ULONG_PTR)ApiMessage; } - - /* Move to the next Pointer */ - PointerCount--; } /* Copy the data back */ @@ -1889,11 +1409,11 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage) * @param Buffer * Pointer to the message buffer to validate. * - * @param ArgumentSize - * Size of the message to check. + * @param ElementCount + * Number of elements contained in the message buffer. * - * @param ArgumentCount - * Number of messages to check. + * @param ElementSize + * Size of each element. * * @return TRUE if validation suceeded, FALSE otherwise. * @@ -1904,62 +1424,97 @@ BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, - IN ULONG ArgumentSize, - IN ULONG ArgumentCount) + IN ULONG ElementCount, + IN ULONG ElementSize) { PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData; - SIZE_T BufferDistance; - ULONG PointerCount, i; - ULONG_PTR **PointerOffsets, *CurrentPointer; - - /* Make sure there are some arguments */ - if (!ArgumentCount) return FALSE; + // SIZE_T BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage; + ULONG i; + + /* + * Check whether we have a valid buffer pointer, elements + * of non-trivial size and that we don't overflow. + */ + if (!Buffer || ElementSize == 0 || + (ULONGLONG)ElementCount * ElementSize > (ULONGLONG)0xFFFFFFFF) + { + return FALSE; + } /* Check if didn't get a buffer and there aren't any arguments to check */ - if (!(*Buffer) && (!(ArgumentCount * ArgumentSize))) return TRUE; + // if (!*Buffer && (ElementCount * ElementSize == 0)) + if (!*Buffer && ElementCount == 0) // Here ElementSize != 0 therefore only ElementCount can be == 0 + return TRUE; /* Check if we have no capture buffer */ if (!CaptureBuffer) { - /* In this case, check only the Process ID */ + /* + * In this case, check only the Process ID + * and if there is a match, we succeed. + */ if (NtCurrentTeb()->ClientId.UniqueProcess == ApiMessage->Header.ClientId.UniqueProcess) { - /* There is a match, validation succeeded */ return TRUE; } } else { /* Make sure that there is still space left in the buffer */ - if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) < - (ArgumentCount * ArgumentSize)) + if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) >= + (ElementCount * ElementSize)) { - /* Find out the difference between the two buffers */ - BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage; - - /* Save the pointer count */ - PointerCount = CaptureBuffer->PointerCount; - PointerOffsets = (ULONG_PTR**)(CaptureBuffer + 1); - - /* Start the loop */ - for (i = 0; i < PointerCount; i++) + for (i = 0 ; i < CaptureBuffer->PointerCount ; ++i) { - /* Get the current pointer */ - CurrentPointer = *PointerOffsets++; - - /* Check if its' equal to the difference */ - if (*CurrentPointer == BufferDistance) return TRUE; + /* + * If the pointer offset is in fact equal to the + * real address of the buffer then it's OK. + */ + if (CaptureBuffer->PointerOffsetsArray[i] == (ULONG_PTR)Buffer /* BufferDistance + (ULONG_PTR)ApiMessage */) + { + return TRUE; + } } } } /* Failure */ - DbgPrint("CSRSRV: Bad message buffer %p\n", ApiMessage); + DPRINT1("CSRSRV: Bad message buffer %p\n", ApiMessage); DbgBreakPoint(); return FALSE; } +/*** This is what we have in consrv/server.c *** + +/\* Ensure that a captured buffer is safe to access *\/ +BOOL FASTCALL +Win32CsrValidateBuffer(PCSR_PROCESS ProcessData, PVOID Buffer, + SIZE_T NumElements, SIZE_T ElementSize) +{ + /\* Check that the following conditions are true: + * 1. The start of the buffer is somewhere within the process's + * shared memory section view. + * 2. The remaining space in the view is at least as large as the buffer. + * (NB: Please don't try to "optimize" this by using multiplication + * instead of division; remember that 2147483648 * 2 = 0.) + * 3. The buffer is DWORD-aligned. + *\/ + ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->ClientViewBase; + if (Offset >= ProcessData->ClientViewBounds + || NumElements > (ProcessData->ClientViewBounds - Offset) / ElementSize + || (Offset & (sizeof(DWORD) - 1)) != 0) + { + DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n", + Buffer, NumElements, ElementSize, + ProcessData->ClientViewBase, ProcessData->ClientViewBounds); + return FALSE; + } + return TRUE; +} + +***********************************************/ + /*++ * @name CsrValidateMessageString * @implemented NT5.1 @@ -1983,8 +1538,17 @@ NTAPI CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage, IN LPWSTR *MessageString) { - DPRINT1("CSRSRV: %s called\n", __FUNCTION__); - return FALSE; + if (MessageString) + { + return CsrValidateMessageBuffer(ApiMessage, + (PVOID*)MessageString, + wcslen(*MessageString) + 1, + sizeof(WCHAR)); + } + else + { + return FALSE; + } } /* EOF */ diff --git a/subsystems/win32/csrsrv/csrsrv.spec b/subsystems/win32/csrsrv/csrsrv.spec index b2244491a05..b84f92e8878 100644 --- a/subsystems/win32/csrsrv/csrsrv.spec +++ b/subsystems/win32/csrsrv/csrsrv.spec @@ -3,7 +3,7 @@ @ stdcall CsrConnectToUser() @ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr) @ stdcall CsrCreateRemoteThread(ptr ptr) -@ stdcall CsrCreateThread(ptr ptr ptr) ;;; @ stdcall CsrCreateThread(ptr ptr ptr long) ?? +@ stdcall CsrCreateThread(ptr ptr ptr long) @ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr) @ stdcall CsrDebugProcess(ptr) @ stdcall CsrDebugProcessStop(ptr) diff --git a/subsystems/win32/csrsrv/include/api.h b/subsystems/win32/csrsrv/include/api.h index f6ffb1ad8e5..7124dbc2f7b 100644 --- a/subsystems/win32/csrsrv/include/api.h +++ b/subsystems/win32/csrsrv/include/api.h @@ -41,37 +41,6 @@ extern RTL_CRITICAL_SECTION CsrProcessLock, CsrWaitListsLock; #define CSR_SERVER_DLL_MAX 4 -/*** - *** Old structure. Deprecated. - ***/ -typedef struct _CSRSS_API_DEFINITION -{ - ULONG ApiID; - ULONG MinRequestSize; - PCSR_API_ROUTINE Handler; -} CSRSS_API_DEFINITION, *PCSRSS_API_DEFINITION; - -#define CSRSS_DEFINE_API(Func, Handler) \ - { Func, sizeof(CSRSS_##Func), Handler } - - - - -typedef struct _CSRSS_LISTEN_DATA -{ - HANDLE ApiPortHandle; - ULONG ApiDefinitionsCount; - PCSRSS_API_DEFINITION *ApiDefinitions; -} CSRSS_LISTEN_DATA, *PCSRSS_LISTEN_DATA; - - - - -/****************************************************************************** - ****************************************************************************** - ******************************************************************************/ - - extern HANDLE hBootstrapOk; extern HANDLE CsrApiPort; extern HANDLE CsrSmApiPort; @@ -154,13 +123,6 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, IN PCSR_PROCESS CurrentProcess OPTIONAL, IN PCSR_PROCESS CsrProcess); - -#if 0 -NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions); -#endif - -VOID FASTCALL CsrApiCallHandler(IN OUT PCSR_API_MESSAGE ApiMessage, OUT PULONG Reply); - NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter); // HANDLE ServerPort ?? @@ -209,16 +171,6 @@ NTAPI CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, IN PCLIENT_ID ClientId); -// HACK -VOID -NTAPI -CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess); - -// HACK -VOID -NTAPI -CsrThreadRefcountZero(IN PCSR_THREAD CsrThread); - NTSTATUS NTAPI CsrInitializeNtSessionList(VOID); diff --git a/subsystems/win32/csrsrv/init.c b/subsystems/win32/csrsrv/init.c index 7ab776553ef..2c123b64b95 100644 --- a/subsystems/win32/csrsrv/init.c +++ b/subsystems/win32/csrsrv/init.c @@ -25,7 +25,7 @@ PCSR_THREAD CsrSbApiRequestThreadPtr; HANDLE CsrSmApiPort = NULL; HANDLE hSbApiPort = NULL; HANDLE CsrApiPort = NULL; -ULONG CsrDebug = 0;//0xFFFFFFFF; +ULONG CsrDebug = 0xFFFFFFFF; // 0; ULONG CsrMaxApiRequestThreads; ULONG CsrTotalPerProcessDataLength; ULONG SessionId; @@ -564,7 +564,7 @@ CsrCreateSessionObjectDirectory(IN ULONG Session) * *--*/ NTSTATUS -FASTCALL +NTAPI CsrParseServerCommandLine(IN ULONG ArgumentCount, IN PCHAR Arguments[]) { @@ -668,7 +668,7 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, /* Load us */ Status = CsrLoadServerDll("CSRSS" /* "CSRSRV" */, NULL, CSRSRV_SERVERDLL_INDEX); } - else if (_stricmp(ParameterName, "ServerDLL") == 0) + else if (_stricmp(ParameterName, "ServerDll") == 0) { /* Loop the command line */ EntryPoint = NULL; @@ -728,6 +728,84 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, return Status; } +/*++ + * @name CsrInitCsrRootProcess + * + * The CsrInitCsrRootProcess routine further initializes the CSR Root Process + * created by CsrInitializeProcessStructure, by allocating and initializing + * per-process data for each Server DLL. + * + * @param None. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * otherwise. + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +CsrInitCsrRootProcess(VOID) +{ + PVOID ProcessData; + PCSR_SERVER_DLL ServerDll; + ULONG i = 0; + + /* All Server DLLs are now loaded, allocate a heap for the Root Process */ + ProcessData = RtlAllocateHeap(CsrHeap, + HEAP_ZERO_MEMORY, + CsrTotalPerProcessDataLength); + if (!ProcessData) + { + DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n", + __FUNCTION__, STATUS_NO_MEMORY); + return STATUS_NO_MEMORY; + } + + /* + * Our Root Process was never officially initalized, so write the data + * for each Server DLL manually. + */ + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) + { + /* Get the current Server */ + ServerDll = CsrLoadedServerDll[i]; + + /* Is it loaded, and does it have per process data? */ + if (ServerDll && ServerDll->SizeOfProcessData) + { + /* It does, give it part of our allocated heap */ + CsrRootProcess->ServerData[i] = ProcessData; + + /* Move to the next heap position */ + ProcessData = (PVOID)((ULONG_PTR)ProcessData + + ServerDll->SizeOfProcessData); + } + else + { + /* Nothing for this Server DLL */ + CsrRootProcess->ServerData[i] = NULL; + } + } + + /* Now initialize the Root Process manually as well */ + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) + { + /* Get the current Server */ + ServerDll = CsrLoadedServerDll[i]; + + /* Is it loaded, and does it a callback for new processes? */ + if (ServerDll && ServerDll->NewProcessCallback) + { + /* Call the callback */ + DPRINT1("Call NewProcessCallback(NULL, 0x%p) called\n", CsrRootProcess); + ServerDll->NewProcessCallback(NULL, CsrRootProcess); + } + } + + return STATUS_SUCCESS; +} + /*++ * @name CsrCreateLocalSystemSD * @@ -971,7 +1049,7 @@ CsrServerInitialization(IN ULONG ArgumentCount, return Status; } - /* Set up Process Support */ + /* Set up Process Support and allocate the CSR Root Process */ Status = CsrInitializeProcessStructure(); if (!NT_SUCCESS(Status)) { @@ -989,6 +1067,15 @@ CsrServerInitialization(IN ULONG ArgumentCount, return Status; } + /* Finish to initialize the CSR Root Process */ + Status = CsrInitCsrRootProcess(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: CsrInitCsrRootProcess failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } + /* Now initialize our API Port */ Status = CsrApiPortInitialize(); if (!NT_SUCCESS(Status)) @@ -1068,12 +1155,12 @@ CsrPopulateDosDevices(VOID) BOOL NTAPI -DllMain(IN HANDLE hDll, +DllMain(IN HINSTANCE hInstanceDll, IN DWORD dwReason, IN LPVOID lpReserved) { /* We don't do much */ - UNREFERENCED_PARAMETER(hDll); + UNREFERENCED_PARAMETER(hInstanceDll); UNREFERENCED_PARAMETER(dwReason); UNREFERENCED_PARAMETER(lpReserved); diff --git a/subsystems/win32/csrsrv/procsup.c b/subsystems/win32/csrsrv/procsup.c index 2976af01fc6..25e37db5f0f 100644 --- a/subsystems/win32/csrsrv/procsup.c +++ b/subsystems/win32/csrsrv/procsup.c @@ -341,7 +341,7 @@ CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess) * @implemented NT4 * * The CsrInitializeProcessStructure routine sets up support for CSR Processes - * and CSR Threads. + * and CSR Threads by initializing our own CSR Root Process. * * @param None. * @@ -467,9 +467,9 @@ CsrRemoveProcess(IN PCSR_PROCESS CsrProcess) *--*/ VOID NTAPI -CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, - IN PCSR_PROCESS CurrentProcess OPTIONAL, - IN PCSR_PROCESS CsrProcess) +CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, // ParentProcess + IN PCSR_PROCESS CurrentProcess OPTIONAL, // CallingProcess + IN PCSR_PROCESS CsrProcess) // Process { PCSR_SERVER_DLL ServerDll; ULONG i; @@ -488,7 +488,7 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, ServerDll = CsrLoadedServerDll[i]; /* Make sure it's valid and that it has callback */ - if ((ServerDll) && (ServerDll->NewProcessCallback)) + if (ServerDll && ServerDll->NewProcessCallback) { ServerDll->NewProcessCallback(CurrentProcess, CsrProcess); } diff --git a/subsystems/win32/csrsrv/server.c b/subsystems/win32/csrsrv/server.c index 57592aad747..91a254591b3 100644 --- a/subsystems/win32/csrsrv/server.c +++ b/subsystems/win32/csrsrv/server.c @@ -119,6 +119,8 @@ CsrLoadServerDll(IN PCHAR DllString, PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure; ULONG Response; + DPRINT1("CsrLoadServerDll(%s, 0x%p, %lu)\n", DllString, EntryPoint, ServerId); + /* Check if it's beyond the maximum we support */ if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES; @@ -222,14 +224,6 @@ CsrLoadServerDll(IN PCHAR DllString, /* No, save the pointer to its shared section in our list */ CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection; } - -#if 0 /* HACK: ReactOS Specific hax. REMOVE IT. */ - if (ServerDll->HighestApiSupported == 0xDEADBABE) - { - // CSRSS_API_DEFINITIONS == Old structure. - Status = CsrApiRegisterDefinitions((PVOID)ServerDll->DispatchTable); - } -#endif } else { @@ -274,12 +268,11 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PULONG Reply OPTIONAL) { NTSTATUS Status; - PCSR_CLIENT_CONNECT ClientConnect; + PCSR_CLIENT_CONNECT ClientConnect = &ApiMessage->Data.CsrClientConnect; PCSR_SERVER_DLL ServerDll; PCSR_PROCESS CurrentProcess = CsrGetClientThread()->Process; - /* Load the Message, set default reply */ - ClientConnect = &ApiMessage->Data.CsrClientConnect; + /* Set default reply */ *Reply = 0; /* Validate the ServerID */ @@ -294,9 +287,9 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage, /* Validate the Message Buffer */ if (!(CsrValidateMessageBuffer(ApiMessage, - ClientConnect->ConnectionInfo, + &ClientConnect->ConnectionInfo, ClientConnect->ConnectionInfoSize, - 1))) + sizeof(BYTE)))) { /* Fail due to buffer overflow or other invalid buffer */ return STATUS_INVALID_PARAMETER; @@ -429,8 +422,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue) /* Now allocate space from the heap for the Shared Data */ CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap, 0, - CSR_SERVER_DLL_MAX * - sizeof(PVOID)); + CSR_SERVER_DLL_MAX * sizeof(PVOID)); if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY; /* Write the values to the PEB */ diff --git a/subsystems/win32/csrsrv/session.c b/subsystems/win32/csrsrv/session.c index ad53c79a762..7df34576089 100644 --- a/subsystems/win32/csrsrv/session.c +++ b/subsystems/win32/csrsrv/session.c @@ -326,9 +326,6 @@ CsrSbCreateSession(IN PSB_API_MSG ApiMessage) } } - /* HACK: FIXME: should go in BaseSrv part of CreateCallback done in Insert below */ - // RtlInitializeCriticalSection(&CsrProcess->HandleTableLock); - /* Insert the Process */ CsrInsertProcess(NULL, NULL, CsrProcess); diff --git a/subsystems/win32/csrsrv/thredsup.c b/subsystems/win32/csrsrv/thredsup.c index 91e10835989..90b3bdad9bd 100644 --- a/subsystems/win32/csrsrv/thredsup.c +++ b/subsystems/win32/csrsrv/thredsup.c @@ -659,7 +659,6 @@ CsrCreateRemoteThread(IN HANDLE hThread, *--*/ NTSTATUS NTAPI -#if 0 CsrCreateThread(IN PCSR_PROCESS CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId, @@ -670,12 +669,13 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, PCSR_PROCESS CurrentProcess; CLIENT_ID CurrentCid; KERNEL_USER_TIMES KernelTimes; + DPRINT("CSRSRV: %s called\n", __FUNCTION__); if (HaveClient) { /* Get the current thread and CID */ - CurrentThread = NtCurrentTeb()->CsrClientThread; + CurrentThread = CsrGetClientThread(); CurrentCid = CurrentThread->ClientId; /* Acquire the Process Lock */ @@ -683,6 +683,8 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, /* Get the current Process and make sure the Thread is valid with this CID */ CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid); + + /* Something is wrong if we get an empty thread back */ if (!CurrentThread) { DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__); @@ -729,66 +731,9 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, /* Release the lock and return */ CsrReleaseProcessLock(); - return STATUS_SUCCESS; -} -#else -CsrCreateThread(IN PCSR_PROCESS CsrProcess, - IN HANDLE hThread, - IN PCLIENT_ID ClientId) -{ - PCSR_THREAD CsrThread; - PCSR_PROCESS CurrentProcess; - PCSR_THREAD CurrentThread = CsrGetClientThread(); - CLIENT_ID CurrentCid; - KERNEL_USER_TIMES KernelTimes; - - /* Get the current thread and CID */ - CurrentCid = CurrentThread->ClientId; - - /* Acquire the Process Lock */ - CsrAcquireProcessLock(); - - /* Get the current Process and make sure the Thread is valid with this CID */ - CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, - &CurrentCid); - - /* Something is wrong if we get an empty thread back */ - if (!CurrentThread) - { - DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__); - CsrReleaseProcessLock(); - return STATUS_THREAD_IS_TERMINATING; - } - /* Get the Thread Create Time */ - NtQueryInformationThread(hThread, - ThreadTimes, - (PVOID)&KernelTimes, - sizeof(KernelTimes), - NULL); - - /* Allocate a CSR Thread Structure */ - if (!(CsrThread = CsrAllocateThread(CsrProcess))) - { - DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); - CsrReleaseProcessLock(); - return STATUS_NO_MEMORY; - } - - /* Save the data we have */ - CsrThread->CreateTime = KernelTimes.CreateTime; - CsrThread->ClientId = *ClientId; - CsrThread->ThreadHandle = hThread; - CsrThread->Flags = 0; - - /* Insert the Thread into the Process */ - CsrInsertThread(CsrProcess, CsrThread); - - /* Release the lock and return */ - CsrReleaseProcessLock(); return STATUS_SUCCESS; } -#endif /*++ * @name CsrDereferenceThread -- 2.17.1