2012-10-13 20:32:44 +00:00
|
|
|
/*
|
2011-07-25 05:54:37 +00:00
|
|
|
* subsystems/win32/csrss/csrsrv/api/wapi.c
|
1999-12-22 14:48:30 +00:00
|
|
|
*
|
2012-10-20 21:03:32 +00:00
|
|
|
* "\windows\ApiPort" port process management functions
|
2005-02-26 15:06:19 +00:00
|
|
|
* CSRSS port message processing
|
1999-12-22 14:48:30 +00:00
|
|
|
*
|
|
|
|
* ReactOS Operating System
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2010-03-10 04:59:39 +00:00
|
|
|
#include <srv.h>
|
2005-03-20 22:55:05 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
2002-09-07 15:13:13 +00:00
|
|
|
#include <debug.h>
|
|
|
|
|
1999-12-30 01:51:42 +00:00
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
static unsigned ApiDefinitionsCount = 0;
|
|
|
|
static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
|
2012-02-16 16:40:15 +00:00
|
|
|
UNICODE_STRING CsrApiPortName;
|
2012-02-19 06:32:17 +00:00
|
|
|
volatile LONG CsrpStaticThreadCount;
|
|
|
|
volatile LONG CsrpDynamicThreadTotal;
|
2012-09-05 21:38:02 +00:00
|
|
|
extern ULONG CsrMaxApiRequestThreads;
|
2003-12-02 11:38:47 +00:00
|
|
|
|
1999-12-22 14:48:30 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2012-10-20 21:03:32 +00:00
|
|
|
#if 0
|
2003-12-02 11:38:47 +00:00
|
|
|
NTSTATUS FASTCALL
|
|
|
|
CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
|
1999-12-22 14:48:30 +00:00
|
|
|
{
|
2003-12-02 11:38:47 +00:00
|
|
|
unsigned NewCount;
|
|
|
|
PCSRSS_API_DEFINITION Scan;
|
|
|
|
PCSRSS_API_DEFINITION New;
|
|
|
|
|
2007-06-14 16:47:24 +00:00
|
|
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
2005-03-20 22:55:05 +00:00
|
|
|
|
2003-12-02 11:38:47 +00:00
|
|
|
NewCount = 0;
|
|
|
|
for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
|
|
|
|
{
|
|
|
|
NewCount++;
|
|
|
|
}
|
|
|
|
|
2012-02-15 19:53:31 +00:00
|
|
|
New = RtlAllocateHeap(CsrHeap, 0,
|
2003-12-02 11:38:47 +00:00
|
|
|
(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));
|
2012-02-15 19:53:31 +00:00
|
|
|
RtlFreeHeap(CsrHeap, 0, ApiDefinitions);
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
|
|
|
|
NewCount * sizeof(CSRSS_API_DEFINITION));
|
|
|
|
ApiDefinitions = New;
|
|
|
|
ApiDefinitionsCount += NewCount;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2012-10-20 21:03:32 +00:00
|
|
|
#endif
|
2003-12-02 11:38:47 +00:00
|
|
|
|
2012-10-17 23:10:40 +00:00
|
|
|
/*
|
2007-10-19 23:21:45 +00:00
|
|
|
VOID
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
FASTCALL
|
2012-02-15 20:29:08 +00:00
|
|
|
CsrApiCallHandler(PCSR_PROCESS ProcessData,
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
PCSR_API_MESSAGE Request)
|
2012-10-17 23:10:40 +00:00
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
CsrApiCallHandler(
|
|
|
|
IN OUT PCSR_API_MESSAGE ApiMessage,
|
|
|
|
OUT PULONG Reply
|
|
|
|
)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
|
|
|
unsigned DefIndex;
|
2012-10-17 23:10:40 +00:00
|
|
|
ULONG ApiId;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2012-10-17 23:10:40 +00:00
|
|
|
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));
|
2003-12-02 11:38:47 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
/* FIXME: Extract DefIndex instead of looping */
|
2008-08-02 22:09:22 +00:00
|
|
|
for (DefIndex = 0; DefIndex < ApiDefinitionsCount; DefIndex++)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2012-10-17 23:10:40 +00:00
|
|
|
if (ApiDefinitions[DefIndex].ApiID == ApiId)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2012-10-17 23:10:40 +00:00
|
|
|
if (ApiMessage->Header.u1.s1.DataLength < ApiDefinitions[DefIndex].MinRequestSize)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2012-10-17 23:10:40 +00:00
|
|
|
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;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-10-17 23:10:40 +00:00
|
|
|
ApiMessage->Status = (ApiDefinitions[DefIndex].Handler)(ApiMessage, Reply);
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2008-08-02 22:09:22 +00:00
|
|
|
return;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
}
|
2012-10-17 23:10:40 +00:00
|
|
|
DPRINT1("CSR: Unknown request ApiNumber 0x%x\n", ApiMessage->ApiNumber);
|
|
|
|
ApiMessage->Status = STATUS_INVALID_SYSTEM_SERVICE;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
|
|
|
|
2012-02-17 05:15:13 +00:00
|
|
|
VOID
|
|
|
|
CallHardError(IN PCSR_THREAD ThreadData,
|
2007-12-22 17:18:32 +00:00
|
|
|
IN PHARDERROR_MSG HardErrorMessage);
|
2006-10-30 14:20:45 +00:00
|
|
|
|
|
|
|
static
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2012-02-17 05:15:13 +00:00
|
|
|
CsrHandleHardError(IN PCSR_THREAD ThreadData,
|
2006-10-30 14:20:45 +00:00
|
|
|
IN OUT PHARDERROR_MSG Message)
|
|
|
|
{
|
|
|
|
DPRINT1("CSR: received hard error %lx\n", Message->Status);
|
|
|
|
|
|
|
|
/* Call the hard error handler in win32csr */
|
2012-02-17 05:15:13 +00:00
|
|
|
CallHardError(ThreadData, Message);
|
2006-10-30 14:20:45 +00:00
|
|
|
}
|
|
|
|
|
2012-02-18 01:27:50 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrCallServerFromServer
|
|
|
|
* @implemented NT4
|
|
|
|
*
|
|
|
|
* The CsrCallServerFromServer routine calls a CSR API from within a server.
|
|
|
|
* It avoids using LPC messages since the request isn't coming from a client.
|
|
|
|
*
|
|
|
|
* @param ReceiveMsg
|
|
|
|
* Pointer to the CSR API Message to send to the server.
|
|
|
|
*
|
|
|
|
* @param ReplyMsg
|
|
|
|
* Pointer to the CSR API Message to receive from the server.
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_ILLEGAL_FUNCTION
|
2012-10-17 23:10:40 +00:00
|
|
|
* if the ApiNumber is invalid, or STATUS_ACCESS_VIOLATION if there
|
2012-02-18 01:27:50 +00:00
|
|
|
* was a problem executing the API.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg,
|
|
|
|
PCSR_API_MESSAGE ReplyMsg)
|
|
|
|
{
|
2012-10-20 21:03:32 +00:00
|
|
|
#if 1 // Real code
|
2012-02-18 01:27:50 +00:00
|
|
|
ULONG ServerId;
|
|
|
|
PCSR_SERVER_DLL ServerDll;
|
|
|
|
ULONG ApiId;
|
|
|
|
ULONG Reply;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Get the Server ID */
|
2012-10-17 23:10:40 +00:00
|
|
|
ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg->ApiNumber);
|
2012-02-18 01:27:50 +00:00
|
|
|
|
|
|
|
/* Make sure that the ID is within limits, and the Server DLL loaded */
|
|
|
|
if ((ServerId >= CSR_SERVER_DLL_MAX) ||
|
|
|
|
(!(ServerDll = CsrLoadedServerDll[ServerId])))
|
|
|
|
{
|
|
|
|
/* We are beyond the Maximum Server ID */
|
|
|
|
DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", ServerId, ServerDll);
|
|
|
|
ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
|
|
|
|
return STATUS_ILLEGAL_FUNCTION;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Get the API ID */
|
2012-10-17 23:10:40 +00:00
|
|
|
ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg->ApiNumber);
|
2012-02-18 01:27:50 +00:00
|
|
|
|
|
|
|
/* Normalize it with our Base ID */
|
|
|
|
ApiId -= ServerDll->ApiBase;
|
|
|
|
|
|
|
|
/* Make sure that the ID is within limits, and the entry exists */
|
|
|
|
if ((ApiId >= ServerDll->HighestApiSupported) ||
|
|
|
|
((ServerDll->ValidTable) && !(ServerDll->ValidTable[ApiId])))
|
|
|
|
{
|
|
|
|
/* We are beyond the Maximum API ID, or it doesn't exist */
|
|
|
|
DPRINT1("CSRSS: %lx (%s) is invalid ApiTableIndex for %Z or is an "
|
|
|
|
"invalid API to call from the server.\n",
|
|
|
|
ServerDll->ValidTable[ApiId],
|
|
|
|
((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ?
|
|
|
|
ServerDll->NameTable[ApiId] : "*** UNKNOWN ***", &ServerDll->Name);
|
|
|
|
DbgBreakPoint();
|
|
|
|
ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
|
|
|
|
return STATUS_ILLEGAL_FUNCTION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CsrDebug & 2)
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: %s Api Request received from server process\n",
|
|
|
|
ServerDll->NameTable[ApiId]);
|
|
|
|
}
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-18 01:27:50 +00:00
|
|
|
/* Validation complete, start SEH */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
/* Call the API and get the result */
|
2012-10-20 21:03:32 +00:00
|
|
|
/// CsrApiCallHandler(ReplyMsg, /*ProcessData*/ &ReplyCode); ///
|
2012-02-18 01:27:50 +00:00
|
|
|
Status = (ServerDll->DispatchTable[ApiId])(ReceiveMsg, &Reply);
|
|
|
|
|
|
|
|
/* Return the result, no matter what it is */
|
|
|
|
ReplyMsg->Status = Status;
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
/* If we got an exception, return access violation */
|
|
|
|
ReplyMsg->Status = STATUS_ACCESS_VIOLATION;
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
/* Return success */
|
|
|
|
return STATUS_SUCCESS;
|
2012-10-13 20:32:44 +00:00
|
|
|
|
2012-02-18 01:27:50 +00:00
|
|
|
#else // Hacky reactos code
|
2012-10-13 20:32:44 +00:00
|
|
|
|
2012-02-18 01:27:50 +00:00
|
|
|
PCSR_PROCESS ProcessData;
|
2012-10-17 23:10:40 +00:00
|
|
|
ULONG ReplyCode;
|
2012-02-19 19:40:28 +00:00
|
|
|
|
2012-02-18 01:27:50 +00:00
|
|
|
/* Get the Process Data */
|
2012-02-19 19:40:28 +00:00
|
|
|
CsrLockProcessByClientId(&ReceiveMsg->Header.ClientId.UniqueProcess, &ProcessData);
|
2012-02-18 01:27:50 +00:00
|
|
|
if (!ProcessData)
|
|
|
|
{
|
|
|
|
DPRINT1("Message: Unable to find data for process 0x%x\n",
|
|
|
|
ReceiveMsg->Header.ClientId.UniqueProcess);
|
|
|
|
return STATUS_NOT_SUPPORTED;
|
|
|
|
}
|
2012-02-19 19:40:28 +00:00
|
|
|
|
2012-02-18 01:27:50 +00:00
|
|
|
/* Validation complete, start SEH */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
/* Call the API and get the result */
|
2012-10-17 23:10:40 +00:00
|
|
|
CsrApiCallHandler(ReplyMsg, /*ProcessData*/ &ReplyCode);
|
2012-02-18 01:27:50 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
/* If we got an exception, return access violation */
|
|
|
|
ReplyMsg->Status = STATUS_ACCESS_VIOLATION;
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Release the process reference */
|
|
|
|
CsrUnlockProcess(ProcessData);
|
|
|
|
|
2012-02-18 01:27:50 +00:00
|
|
|
/* Return success */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-02-16 16:40:15 +00:00
|
|
|
/*++
|
|
|
|
* @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
|
2012-10-13 20:32:44 +00:00
|
|
|
* otherwise.
|
2012-02-16 16:40:15 +00:00
|
|
|
*
|
|
|
|
* @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 */
|
2012-02-19 06:32:17 +00:00
|
|
|
Status = NtCreatePort(&CsrApiPort,
|
2012-02-16 16:40:15 +00:00
|
|
|
&ObjectAttributes,
|
2012-10-13 20:32:44 +00:00
|
|
|
LPC_MAX_DATA_LENGTH, // hack ; sizeof(CSR_CONNECTION_INFO),
|
|
|
|
LPC_MAX_MESSAGE_LENGTH, // hack ; sizeof(CSR_API_MESSAGE),
|
2012-02-16 16:40:15 +00:00
|
|
|
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 Request Thread */
|
|
|
|
Status = RtlCreateUserThread(NtCurrentProcess(),
|
|
|
|
NULL,
|
|
|
|
TRUE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
(PVOID)ClientConnectionThread,//CsrApiRequestThread,
|
|
|
|
(PVOID)hRequestEvent,
|
|
|
|
&hThread,
|
|
|
|
&ClientId);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Add this as a static thread to CSRSRV */
|
|
|
|
CsrAddStaticServerThread(hThread, &ClientId, CsrThreadIsServerThread);
|
|
|
|
|
|
|
|
/* Get the Thread List Pointers */
|
|
|
|
ListHead = &CsrRootProcess->ThreadList;
|
|
|
|
NextEntry = ListHead->Flink;
|
|
|
|
|
|
|
|
/* Start looping the list */
|
|
|
|
while (NextEntry != ListHead)
|
|
|
|
{
|
|
|
|
/* Get the Thread */
|
|
|
|
ServerThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
|
|
|
|
|
|
|
|
/* Start it up */
|
|
|
|
Status = NtResumeThread(ServerThread->ThreadHandle, NULL);
|
|
|
|
|
|
|
|
/* Is this a Server Thread? */
|
|
|
|
if (ServerThread->Flags & CsrThreadIsServerThread)
|
|
|
|
{
|
|
|
|
/* If so, then wait for it to initialize */
|
|
|
|
Status = NtWaitForSingleObject(hRequestEvent, FALSE, NULL);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Next thread */
|
|
|
|
NextEntry = NextEntry->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We don't need this anymore */
|
|
|
|
NtClose(hRequestEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2011-08-03 03:09:02 +00:00
|
|
|
PBASE_STATIC_SERVER_DATA BaseStaticServerData;
|
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CreateBaseAcls(OUT PACL* Dacl,
|
|
|
|
OUT PACL* RestrictedDacl)
|
|
|
|
{
|
|
|
|
PSID SystemSid, WorldSid, RestrictedSid;
|
|
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
|
|
|
|
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
|
|
|
|
NTSTATUS Status;
|
|
|
|
UCHAR KeyValueBuffer[0x40];
|
|
|
|
PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
|
|
|
|
UNICODE_STRING KeyName;
|
|
|
|
ULONG ProtectionMode = 0;
|
|
|
|
ULONG AclLength, ResultLength;
|
|
|
|
HANDLE hKey;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
|
|
|
|
/* Open the Session Manager Key */
|
|
|
|
RtlInitUnicodeString(&KeyName, SM_REG_KEY);
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&KeyName,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Read the key value */
|
|
|
|
RtlInitUnicodeString(&KeyName, L"ProtectionMode");
|
|
|
|
Status = NtQueryValueKey(hKey,
|
|
|
|
&KeyName,
|
|
|
|
KeyValuePartialInformation,
|
|
|
|
KeyValueBuffer,
|
|
|
|
sizeof(KeyValueBuffer),
|
|
|
|
&ResultLength);
|
|
|
|
|
|
|
|
/* Make sure it's what we expect it to be */
|
|
|
|
KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
|
|
|
|
if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
|
|
|
|
(*(PULONG)KeyValuePartialInfo->Data))
|
|
|
|
{
|
|
|
|
/* Save the Protection Mode */
|
|
|
|
ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close the handle */
|
|
|
|
NtClose(hKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate the System SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1, SECURITY_LOCAL_SYSTEM_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&SystemSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Allocate the World SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&WorldAuthority,
|
|
|
|
1, SECURITY_WORLD_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&WorldSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Allocate the restricted SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1, SECURITY_RESTRICTED_CODE_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&RestrictedSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/* Allocate one ACL with 3 ACEs each for one SID */
|
|
|
|
AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
|
|
|
|
RtlLengthSid(SystemSid) +
|
|
|
|
RtlLengthSid(RestrictedSid) +
|
|
|
|
RtlLengthSid(WorldSid);
|
|
|
|
*Dacl = RtlAllocateHeap(CsrHeap, 0, AclLength);
|
|
|
|
ASSERT(*Dacl != NULL);
|
|
|
|
|
|
|
|
/* Set the correct header fields */
|
|
|
|
Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Give the appropriate rights to each SID */
|
|
|
|
/* FIXME: Should check SessionId/ProtectionMode */
|
|
|
|
Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Now allocate the restricted DACL */
|
|
|
|
*RestrictedDacl = RtlAllocateHeap(CsrHeap, 0, AclLength);
|
|
|
|
ASSERT(*RestrictedDacl != NULL);
|
|
|
|
|
|
|
|
/* Initialize it */
|
|
|
|
Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* And add the same ACEs as before */
|
|
|
|
/* FIXME: Not really fully correct */
|
|
|
|
Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-15 16:11:12 +00:00
|
|
|
/* The SIDs are captured, can free them now */
|
|
|
|
RtlFreeHeap(CsrHeap, 0, SystemSid);
|
|
|
|
RtlFreeHeap(CsrHeap, 0, WorldSid);
|
|
|
|
RtlFreeHeap(CsrHeap, 0, RestrictedSid);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
NTSTATUS WINAPI
|
2012-10-13 20:32:44 +00:00
|
|
|
CsrpHandleConnectionRequest(PPORT_MESSAGE Request)
|
2006-10-30 18:45:22 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2012-02-19 06:32:17 +00:00
|
|
|
HANDLE ServerPort = NULL;//, ServerThread = NULL;
|
2012-02-15 20:29:08 +00:00
|
|
|
PCSR_PROCESS ProcessData = NULL;
|
2012-02-19 04:18:33 +00:00
|
|
|
REMOTE_PORT_VIEW RemotePortView;
|
2012-02-19 06:32:17 +00:00
|
|
|
// CLIENT_ID ClientId;
|
2011-08-03 03:09:02 +00:00
|
|
|
BOOLEAN AllowConnection = FALSE;
|
2011-07-25 18:39:56 +00:00
|
|
|
PCSR_CONNECTION_INFO ConnectInfo;
|
2006-10-30 18:45:22 +00:00
|
|
|
ServerPort = NULL;
|
|
|
|
|
- Fix SleepEx.
- Put volatile statements in EX_RUNDOWN_REF, IRP, DEVICE_OBJECT, ERESOURCE, FILE_OBJECT, IO_REMOVE_LOCK, WORK_QUEUE_ITEM where required (thanks to Microsoft's changes in the WDK to mark the fields properly).
- Update FILE_OBJECT definition.
- Add some asserts to some I/O functions.
- Add stub support for File Objects created by XP+ Drivers which have File Object Extensions.
- Add some fixes to IopDeleteFile, including proper reference counting for the DO and VPB, as well as cleanup when the file is closed without a handle.
- Fix a bug in IopSecurityFile.
- Queue and unqueue IRPs in all I/O functions.
- Fully support IRP cancellation now.
- Fix critical bugs in NtDeviceIoControlFile and NtDeviceFsControlFile which were causing double queueing of IRPs and freeing of invalid memory, as well as invalid paramter checking for user-mode buffers.
- Add exhaustive validation checks to IoCreateFile, add more failure cases, and validate the EA buffer. Also support IO_ATTACH_DEVICE_API flag.
- Implement IoCreateStreamFileObjectEx and IoCreateStreamFileObjectLite and fix several bugs in the original implementation of IoCreateStreamFileObject.
- Fix a bug in RtlRaiseException.
- Update Io*ShareAccess routines to support XP+ style semantics related to special File Object flags which disable their use.
- Add validation to all Query/Set routines so that information clasess, lengths, buffers and alignment are properly checked.
- Also add an array for the proper acess rights that each query/set operation requires.
- Check backup/restore privileges during I/O File operations.
- Check traverse access during I/O File Operations.
- Check access privileges to the device during I/O file operations.
- Rename IopReferenceDeviceObject and also verify if an exclusive DO is trying to be invalidly opened.
- Support various extra security checks during I/O File/Device Parse Routine.
- Fix a bug during IopCleanupIrp so that we don't dereference the File OBject if this was a create operation.
- Fix some bogus asserts in IofCompleteRequest, and save the IRP Flags before signalling it's event, since the driver might've freed it behind our back.
- Fix a large bug in ObInsertObject which affected the insert of unnamed objects with forced security options (Such as process/threads).
- Fix the creation of the Process/Thread/Job Obejct Types to that security information is forced.
- Remove "Fix PS!!!" messages since the bug is now fixed and these objects now get proper security descriptors.
- Fix another bug in ObInsertObjet which wasn't properly validating user-mode objects and always assumed kernel mode.
- Silence multiple trace/checkpoint messages that have accumulated throughout time for various debugging purposes.
svn path=/trunk/; revision=25118
2006-12-10 18:40:30 +00:00
|
|
|
DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
|
2006-10-30 18:45:22 +00:00
|
|
|
|
2011-07-25 18:39:56 +00:00
|
|
|
ConnectInfo = (PCSR_CONNECTION_INFO)(Request + 1);
|
2012-02-15 16:11:12 +00:00
|
|
|
|
2011-07-25 18:39:56 +00:00
|
|
|
/* Save the process ID */
|
|
|
|
RtlZeroMemory(ConnectInfo, sizeof(CSR_CONNECTION_INFO));
|
2012-02-15 16:11:12 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
CsrLockProcessByClientId(Request->ClientId.UniqueProcess, &ProcessData);
|
2012-02-19 04:18:33 +00:00
|
|
|
if (!ProcessData)
|
2006-10-30 18:45:22 +00:00
|
|
|
{
|
2012-02-19 04:18:33 +00:00
|
|
|
DPRINT1("CSRSRV: Unknown process: %lx. Will be rejecting connection\n",
|
|
|
|
Request->ClientId.UniqueProcess);
|
2011-08-03 03:57:30 +00:00
|
|
|
}
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 00:04:05 +00:00
|
|
|
if ((ProcessData) && (ProcessData != CsrRootProcess))
|
2011-08-03 03:57:30 +00:00
|
|
|
{
|
|
|
|
/* Attach the Shared Section */
|
|
|
|
Status = CsrSrvAttachSharedSection(ProcessData, ConnectInfo);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2011-09-08 08:28:41 +00:00
|
|
|
DPRINT("Connection ok\n");
|
2011-08-03 03:57:30 +00:00
|
|
|
AllowConnection = TRUE;
|
|
|
|
}
|
2011-08-03 03:09:02 +00:00
|
|
|
else
|
|
|
|
{
|
2011-08-03 03:57:30 +00:00
|
|
|
DPRINT1("Shared section map failed: %lx\n", Status);
|
2011-08-03 03:09:02 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-19 00:04:05 +00:00
|
|
|
else if (ProcessData == CsrRootProcess)
|
|
|
|
{
|
|
|
|
AllowConnection = TRUE;
|
|
|
|
}
|
2012-02-15 16:11:12 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Release the process */
|
|
|
|
if (ProcessData) CsrUnlockProcess(ProcessData);
|
2012-02-19 04:18:33 +00:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
2011-08-03 03:09:02 +00:00
|
|
|
Status = NtAcceptConnectPort(&ServerPort,
|
2012-02-19 04:18:33 +00:00
|
|
|
AllowConnection ? UlongToPtr(ProcessData->SequenceNumber) : 0,
|
2011-08-03 03:09:02 +00:00
|
|
|
Request,
|
|
|
|
AllowConnection,
|
2012-02-19 04:18:33 +00:00
|
|
|
NULL,
|
|
|
|
&RemotePortView);
|
2011-08-03 03:09:02 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2012-02-19 04:18:33 +00:00
|
|
|
DPRINT1("CSRSS: NtAcceptConnectPort - failed. Status == %X\n", Status);
|
2006-10-30 18:45:22 +00:00
|
|
|
}
|
2012-02-19 04:18:33 +00:00
|
|
|
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);
|
|
|
|
}
|
2006-10-30 18:45:22 +00:00
|
|
|
|
2012-02-19 04:18:33 +00:00
|
|
|
/* 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);
|
2006-10-30 18:45:22 +00:00
|
|
|
|
2012-02-19 04:18:33 +00:00
|
|
|
/* Complete the connection */
|
|
|
|
Status = NtCompleteConnectPort(ServerPort);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2006-10-30 18:45:22 +00:00
|
|
|
{
|
2012-02-19 04:18:33 +00:00
|
|
|
DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
|
|
|
|
Request->ClientId.UniqueProcess,
|
|
|
|
Request->ClientId.UniqueThread);
|
2006-10-30 18:45:22 +00:00
|
|
|
}
|
2012-02-15 16:11:12 +00:00
|
|
|
|
2006-10-30 18:45:22 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2012-10-13 20:32:44 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrConnectToUser
|
|
|
|
* @implemented NT4
|
|
|
|
*
|
|
|
|
* The CsrConnectToUser connects to the User subsystem.
|
|
|
|
*
|
|
|
|
* @param None
|
|
|
|
*
|
|
|
|
* @return A pointer to the CSR Thread
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
2010-03-09 20:23:22 +00:00
|
|
|
PCSR_THREAD
|
|
|
|
NTAPI
|
|
|
|
CsrConnectToUser(VOID)
|
|
|
|
{
|
|
|
|
PTEB Teb = NtCurrentTeb();
|
|
|
|
PCSR_THREAD CsrThread;
|
|
|
|
#if 0
|
|
|
|
NTSTATUS Status;
|
|
|
|
ANSI_STRING DllName;
|
|
|
|
UNICODE_STRING TempName;
|
|
|
|
HANDLE hUser32;
|
|
|
|
STRING StartupName;
|
|
|
|
|
|
|
|
/* Check if we didn't already find it */
|
|
|
|
if (!CsrClientThreadSetup)
|
|
|
|
{
|
|
|
|
/* Get the DLL Handle for user32.dll */
|
|
|
|
RtlInitAnsiString(&DllName, "user32");
|
|
|
|
RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE);
|
|
|
|
Status = LdrGetDllHandle(NULL,
|
|
|
|
NULL,
|
|
|
|
&TempName,
|
|
|
|
&hUser32);
|
|
|
|
RtlFreeUnicodeString(&TempName);
|
|
|
|
|
|
|
|
/* If we got teh handle, get the Client Thread Startup Entrypoint */
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
RtlInitAnsiString(&StartupName,"ClientThreadSetup");
|
|
|
|
Status = LdrGetProcedureAddress(hUser32,
|
|
|
|
&StartupName,
|
|
|
|
0,
|
|
|
|
(PVOID)&CsrClientThreadSetup);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Connect to user32 */
|
|
|
|
CsrClientThreadSetup();
|
|
|
|
#endif
|
|
|
|
/* Save pointer to this thread in TEB */
|
|
|
|
CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
|
|
|
|
if (CsrThread) Teb->CsrClientThread = CsrThread;
|
|
|
|
|
|
|
|
/* Return it */
|
|
|
|
return CsrThread;
|
|
|
|
}
|
|
|
|
|
2012-02-19 06:32:17 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrpCheckRequestThreads
|
|
|
|
*
|
|
|
|
* The CsrpCheckRequestThreads routine checks if there are no more threads
|
|
|
|
* to handle CSR API Requests, and creates a new thread if possible, to
|
|
|
|
* avoid starvation.
|
|
|
|
*
|
|
|
|
* @param None.
|
|
|
|
*
|
|
|
|
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
|
|
|
* if a new thread couldn't be created.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CsrpCheckRequestThreads(VOID)
|
|
|
|
{
|
|
|
|
HANDLE hThread;
|
|
|
|
CLIENT_ID ClientId;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Decrease the count, and see if we're out */
|
|
|
|
if (!(_InterlockedDecrement(&CsrpStaticThreadCount)))
|
|
|
|
{
|
|
|
|
/* Check if we've still got space for a Dynamic Thread */
|
|
|
|
if (CsrpDynamicThreadTotal < CsrMaxApiRequestThreads)
|
|
|
|
{
|
|
|
|
/* Create a new dynamic thread */
|
|
|
|
Status = RtlCreateUserThread(NtCurrentProcess(),
|
|
|
|
NULL,
|
|
|
|
TRUE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
(PVOID)ClientConnectionThread,//CsrApiRequestThread,
|
|
|
|
NULL,
|
|
|
|
&hThread,
|
|
|
|
&ClientId);
|
|
|
|
/* Check success */
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Increase the thread counts */
|
|
|
|
_InterlockedIncrement(&CsrpStaticThreadCount);
|
|
|
|
_InterlockedIncrement(&CsrpDynamicThreadTotal);
|
|
|
|
|
|
|
|
/* Add a new server thread */
|
|
|
|
if (CsrAddStaticServerThread(hThread,
|
|
|
|
&ClientId,
|
|
|
|
CsrThreadIsServerThread))
|
|
|
|
{
|
|
|
|
/* Activate it */
|
|
|
|
NtResumeThread(hThread, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Failed to create a new static thread */
|
|
|
|
_InterlockedDecrement(&CsrpStaticThreadCount);
|
|
|
|
_InterlockedDecrement(&CsrpDynamicThreadTotal);
|
|
|
|
|
|
|
|
/* Terminate it */
|
|
|
|
DPRINT1("Failing\n");
|
|
|
|
NtTerminateThread(hThread, 0);
|
|
|
|
NtClose(hThread);
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Success */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
VOID
|
2008-11-29 22:48:58 +00:00
|
|
|
WINAPI
|
2012-02-16 16:40:15 +00:00
|
|
|
ClientConnectionThread(IN PVOID Parameter)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2012-02-16 16:40:15 +00:00
|
|
|
PTEB Teb = NtCurrentTeb();
|
|
|
|
LARGE_INTEGER TimeOut;
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
NTSTATUS Status;
|
2005-08-28 12:03:25 +00:00
|
|
|
BYTE RawRequest[LPC_MAX_DATA_LENGTH];
|
|
|
|
PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
PCSR_API_MESSAGE Reply;
|
2012-02-19 19:40:28 +00:00
|
|
|
PCSR_PROCESS CsrProcess;
|
|
|
|
PCSR_THREAD ServerThread, CsrThread;
|
2012-02-16 16:40:15 +00:00
|
|
|
ULONG MessageType;
|
2012-02-19 06:32:17 +00:00
|
|
|
HANDLE ReplyPort;
|
2012-02-19 18:05:49 +00:00
|
|
|
PDBGKM_MSG DebugMessage;
|
2012-02-19 19:40:28 +00:00
|
|
|
PHARDERROR_MSG HardErrorMsg;
|
|
|
|
PCLIENT_DIED_MSG ClientDiedMsg;
|
2007-06-14 16:47:24 +00:00
|
|
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
2012-02-15 16:11:12 +00:00
|
|
|
|
2012-02-16 16:40:15 +00:00
|
|
|
/* Setup LPC loop port and message */
|
|
|
|
Reply = NULL;
|
2012-02-19 06:32:17 +00:00
|
|
|
ReplyPort = CsrApiPort;
|
2012-02-16 16:40:15 +00:00
|
|
|
|
2010-03-09 20:23:22 +00:00
|
|
|
/* Connect to user32 */
|
|
|
|
while (!CsrConnectToUser())
|
|
|
|
{
|
2012-02-16 16:40:15 +00:00
|
|
|
/* Set up the timeout for the connect (30 seconds) */
|
|
|
|
TimeOut.QuadPart = -30 * 1000 * 1000 * 10;
|
|
|
|
|
2010-03-09 20:23:22 +00:00
|
|
|
/* Keep trying until we get a response */
|
2012-02-16 16:40:15 +00:00
|
|
|
Teb->Win32ClientInfo[0] = 0;
|
|
|
|
NtDelayExecution(FALSE, &TimeOut);
|
2010-03-09 20:23:22 +00:00
|
|
|
}
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
|
2012-02-16 16:40:15 +00:00
|
|
|
/* 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));
|
|
|
|
|
|
|
|
/* Increase the Thread Counts */
|
2012-02-19 06:32:17 +00:00
|
|
|
_InterlockedIncrement(&CsrpStaticThreadCount);
|
|
|
|
_InterlockedIncrement(&CsrpDynamicThreadTotal);
|
2012-02-16 16:40:15 +00:00
|
|
|
}
|
2005-06-22 17:43:59 +00:00
|
|
|
|
2012-02-16 16:40:15 +00:00
|
|
|
/* Now start the loop */
|
|
|
|
while (TRUE)
|
2003-12-02 11:38:47 +00:00
|
|
|
{
|
2012-02-16 16:40:15 +00:00
|
|
|
/* 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",
|
2012-02-19 20:16:36 +00:00
|
|
|
Request, Reply);
|
2012-02-16 16:40:15 +00:00
|
|
|
DbgBreakPoint();
|
|
|
|
}
|
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
/* Send the reply and wait for a new request */
|
2012-02-19 06:32:17 +00:00
|
|
|
DPRINT("Replying to: %lx (%lx)\n", ReplyPort, CsrApiPort);
|
|
|
|
Status = NtReplyWaitReceivePort(ReplyPort,
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
0,
|
|
|
|
&Reply->Header,
|
2005-08-28 12:03:25 +00:00
|
|
|
&Request->Header);
|
2012-02-16 16:40:15 +00:00
|
|
|
/* Check if we didn't get success */
|
|
|
|
if (Status != STATUS_SUCCESS)
|
2007-06-15 19:14:15 +00:00
|
|
|
{
|
2012-02-16 16:40:15 +00:00
|
|
|
/* Was it a failure or another success code? */
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Check for specific status cases */
|
|
|
|
if ((Status != STATUS_INVALID_CID) &&
|
2012-02-19 06:32:17 +00:00
|
|
|
(Status != STATUS_UNSUCCESSFUL) &&
|
|
|
|
((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
|
2012-02-16 16:40:15 +00:00
|
|
|
{
|
|
|
|
/* Notify the debugger */
|
|
|
|
DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
|
2012-02-19 06:32:17 +00:00
|
|
|
DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort);
|
2012-02-16 16:40:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We failed big time, so start out fresh */
|
|
|
|
Reply = NULL;
|
2012-02-19 06:32:17 +00:00
|
|
|
ReplyPort = CsrApiPort;
|
|
|
|
DPRINT1("failed: %lx\n", Status);
|
2012-02-16 16:40:15 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* A bizare "success" code, just try again */
|
|
|
|
DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status);
|
|
|
|
continue;
|
|
|
|
}
|
2007-06-15 19:14:15 +00:00
|
|
|
}
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-16 16:40:15 +00:00
|
|
|
/* Use whatever Client ID we got */
|
|
|
|
Teb->RealClientId = Request->Header.ClientId;
|
2007-06-15 19:14:15 +00:00
|
|
|
|
2012-02-16 16:40:15 +00:00
|
|
|
/* Get the Message Type */
|
|
|
|
MessageType = Request->Header.u2.s2.Type;
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Handle connection requests */
|
2012-02-16 16:40:15 +00:00
|
|
|
if (MessageType == LPC_CONNECTION_REQUEST)
|
2006-10-30 18:45:22 +00:00
|
|
|
{
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Handle the Connection Request */
|
2012-02-19 06:32:17 +00:00
|
|
|
DPRINT("Accepting new connection\n");
|
2012-02-16 16:40:15 +00:00
|
|
|
CsrpHandleConnectionRequest((PPORT_MESSAGE)Request);
|
2006-10-30 18:45:22 +00:00
|
|
|
Reply = NULL;
|
2012-02-19 06:32:17 +00:00
|
|
|
ReplyPort = CsrApiPort;
|
2006-10-30 18:45:22 +00:00
|
|
|
continue;
|
|
|
|
}
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* It's some other kind of request. Get the lock for the lookup */
|
|
|
|
CsrAcquireProcessLock();
|
2006-10-30 18:45:22 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Now do the lookup to get the CSR_THREAD */
|
|
|
|
CsrThread = CsrLocateThreadByClientId(&CsrProcess,
|
|
|
|
&Request->Header.ClientId);
|
2004-07-03 17:15:02 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Did we find a thread? */
|
|
|
|
if (!CsrThread)
|
2012-02-19 18:05:49 +00:00
|
|
|
{
|
2012-02-19 19:40:28 +00:00
|
|
|
/* This wasn't a CSR Thread, release lock */
|
|
|
|
CsrReleaseProcessLock();
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* 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 */
|
2012-09-15 16:33:30 +00:00
|
|
|
DPRINT("Death from unknown thread, just continue\n");
|
2012-02-19 19:40:28 +00:00
|
|
|
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;
|
2012-02-19 18:05:49 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Default it to unhandled */
|
|
|
|
HardErrorMsg->Response = ResponseNotHandled;
|
2012-02-15 16:11:12 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Check if there are free api threads */
|
2012-02-19 06:32:17 +00:00
|
|
|
CsrpCheckRequestThreads();
|
2012-02-19 19:40:28 +00:00
|
|
|
if (CsrpStaticThreadCount)
|
2012-02-19 06:32:17 +00:00
|
|
|
{
|
2012-02-19 19:40:28 +00:00
|
|
|
CsrHandleHardError(CsrThread, (PHARDERROR_MSG)Request);
|
2012-02-19 06:32:17 +00:00
|
|
|
}
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* If the response was 0xFFFFFFFF, we'll ignore it */
|
|
|
|
if (HardErrorMsg->Response == 0xFFFFFFFF)
|
2012-02-19 06:32:17 +00:00
|
|
|
{
|
2012-02-19 19:40:28 +00:00
|
|
|
Reply = NULL;
|
|
|
|
ReplyPort = CsrApiPort;
|
2012-02-19 06:32:17 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-02-19 19:40:28 +00:00
|
|
|
if (CsrThread) CsrDereferenceThread(CsrThread);
|
|
|
|
Reply = Request;
|
|
|
|
ReplyPort = CsrApiPort;
|
2012-02-19 06:32:17 +00:00
|
|
|
}
|
2012-02-19 19:40:28 +00:00
|
|
|
}
|
|
|
|
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",
|
2012-10-17 23:10:40 +00:00
|
|
|
Request->ApiNumber & 0xFFFF,
|
2012-02-19 19:40:28 +00:00
|
|
|
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;
|
|
|
|
}
|
2012-02-19 06:32:17 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Keep going */
|
|
|
|
continue;
|
|
|
|
}
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* 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)
|
2012-02-19 06:32:17 +00:00
|
|
|
{
|
2012-02-19 19:40:28 +00:00
|
|
|
/* 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);
|
2012-02-19 06:32:17 +00:00
|
|
|
}
|
2012-02-19 19:40:28 +00:00
|
|
|
|
|
|
|
/* Release the lock and keep looping */
|
|
|
|
CsrReleaseProcessLock();
|
|
|
|
Reply = NULL;
|
|
|
|
ReplyPort = CsrApiPort;
|
|
|
|
continue;
|
2012-02-19 06:32:17 +00:00
|
|
|
}
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Reference the thread and release the lock */
|
|
|
|
CsrLockedReferenceThread(CsrThread);
|
|
|
|
CsrReleaseProcessLock();
|
|
|
|
|
|
|
|
/* If this was an exception, handle it */
|
|
|
|
if (MessageType == LPC_EXCEPTION)
|
2012-02-19 06:32:17 +00:00
|
|
|
{
|
2012-02-19 19:40:28 +00:00
|
|
|
/* 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 */
|
2012-02-19 20:13:07 +00:00
|
|
|
DebugMessage = (PDBGKM_MSG)Request;
|
2012-02-19 19:40:28 +00:00
|
|
|
DebugMessage->ReturnedStatus = DBG_CONTINUE;
|
|
|
|
Reply = Request;
|
2012-02-19 06:32:17 +00:00
|
|
|
ReplyPort = CsrApiPort;
|
2012-02-19 20:13:07 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Remove our extra reference */
|
|
|
|
CsrDereferenceThread(CsrThread);
|
2012-02-19 06:32:17 +00:00
|
|
|
}
|
2012-02-19 19:40:28 +00:00
|
|
|
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;
|
2006-10-30 14:20:45 +00:00
|
|
|
}
|
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* We got an API Request */
|
|
|
|
CsrLockedReferenceThread(CsrThread);
|
|
|
|
CsrReleaseProcessLock();
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Assume success */
|
2005-08-28 12:03:25 +00:00
|
|
|
Reply = Request;
|
2012-02-19 19:40:28 +00:00
|
|
|
Request->Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
/* Now we reply to a particular client */
|
|
|
|
ReplyPort = CsrThread->Process->ClientPort;
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
|
2012-10-17 23:10:40 +00:00
|
|
|
Request->ApiNumber,
|
2012-02-19 19:40:28 +00:00
|
|
|
Request->Header.ClientId.UniqueThread);
|
|
|
|
|
|
|
|
/* Validation complete, start SEH */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2012-10-17 23:10:40 +00:00
|
|
|
ULONG ReplyCode;
|
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Make sure we have enough threads */
|
|
|
|
CsrpCheckRequestThreads();
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Set the client thread pointer */
|
|
|
|
NtCurrentTeb()->CsrClientThread = CsrThread;
|
|
|
|
|
|
|
|
/* Call the Handler */
|
2012-10-17 23:10:40 +00:00
|
|
|
CsrApiCallHandler(Request, &ReplyCode);
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Increase the static thread count */
|
|
|
|
_InterlockedIncrement(&CsrpStaticThreadCount);
|
|
|
|
|
|
|
|
/* Restore the server thread */
|
|
|
|
NtCurrentTeb()->CsrClientThread = ServerThread;
|
2012-09-15 16:33:30 +00:00
|
|
|
|
2012-02-19 19:40:28 +00:00
|
|
|
/* Check if this is a dead client now */
|
2012-10-17 23:10:40 +00:00
|
|
|
if (Request->ApiNumber == 0xBABE)
|
2012-02-19 19:40:28 +00:00
|
|
|
{
|
|
|
|
/* 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;
|
2003-12-02 11:38:47 +00:00
|
|
|
}
|
2006-11-05 20:31:35 +00:00
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
/* Close the port and exit the thread */
|
2007-06-14 19:09:32 +00:00
|
|
|
// NtClose(ServerPort);
|
2007-06-14 16:47:24 +00:00
|
|
|
|
2012-02-19 06:32:17 +00:00
|
|
|
DPRINT1("CSR: %s done\n", __FUNCTION__);
|
2012-02-16 16:40:15 +00:00
|
|
|
/* We're out of the loop for some reason, terminate! */
|
|
|
|
NtTerminateThread(NtCurrentThread(), Status);
|
|
|
|
//return Status;
|
1999-12-22 14:48:30 +00:00
|
|
|
}
|
|
|
|
|
2012-02-16 06:57:27 +00:00
|
|
|
/*++
|
|
|
|
* @name CsrReleaseCapturedArguments
|
|
|
|
* @implemented NT5.1
|
|
|
|
*
|
|
|
|
* The CsrReleaseCapturedArguments routine releases a Capture Buffer
|
|
|
|
* that was previously captured with CsrCaptureArguments.
|
|
|
|
*
|
|
|
|
* @param ApiMessage
|
|
|
|
* Pointer to the CSR API Message containing the Capture Buffer
|
|
|
|
* that needs to be released.
|
|
|
|
*
|
|
|
|
* @return None.
|
|
|
|
*
|
|
|
|
* @remarks None.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
|
|
|
|
{
|
|
|
|
PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer;
|
|
|
|
SIZE_T BufferDistance;
|
|
|
|
ULONG PointerCount;
|
|
|
|
ULONG_PTR **PointerOffsets, *CurrentPointer;
|
|
|
|
|
|
|
|
/* Get the capture buffers */
|
|
|
|
RemoteCaptureBuffer = ApiMessage->CsrCaptureData;
|
|
|
|
LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer;
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
/* Start the loop */
|
|
|
|
while (PointerCount)
|
|
|
|
{
|
|
|
|
/* Get the current pointer */
|
|
|
|
CurrentPointer = *PointerOffsets++;
|
|
|
|
if (CurrentPointer)
|
|
|
|
{
|
|
|
|
/* Add it to the CSR Message structure */
|
|
|
|
CurrentPointer += (ULONG_PTR)ApiMessage;
|
|
|
|
|
|
|
|
/* Modify the pointer to take into account its new position */
|
|
|
|
*CurrentPointer += BufferDistance;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move to the next Pointer */
|
|
|
|
PointerCount--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy the data back */
|
|
|
|
RtlMoveMemory(LocalCaptureBuffer, RemoteCaptureBuffer, RemoteCaptureBuffer->Size);
|
|
|
|
|
|
|
|
/* Free our allocated buffer */
|
|
|
|
RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
|
|
|
|
}
|
|
|
|
|
2001-08-14 12:57:16 +00:00
|
|
|
/* EOF */
|