[CSRSRV]: Port CsrCallServerFromServer (and hackplement a reactos-compatible implememntation) from CSRSRV2.

[CSRSRV/CSRSRV2]: Fix CsrLockProcessByPid -- it was skipping the root process itself, so requests coming from a CSRSS-hosted DLL would fail (which is exactly what server-to-server depends on).
[NTDLL]: Enable support for server-to-server calls!
Server-to-server calls work now, and one of the multiple mapping hacks is gone. User32 and kernel32 still need a bit of fixes to get rid of the other hacks, though. Also, Perf++.

svn path=/trunk/; revision=55677
This commit is contained in:
Alex Ionescu 2012-02-18 01:27:50 +00:00
parent 87a966228c
commit e5f337a82b
6 changed files with 164 additions and 29 deletions

View file

@ -19,7 +19,6 @@ HANDLE CsrProcessId;
HANDLE CsrPortHeap;
ULONG_PTR CsrPortMemoryDelta;
BOOLEAN InsideCsrProcess = FALSE;
BOOLEAN UsingOldCsr = TRUE;
typedef NTSTATUS
(NTAPI *PCSR_SERVER_API_ROUTINE)(IN PPORT_MESSAGE Request,
@ -151,7 +150,7 @@ CsrClientCallServer(PCSR_API_MESSAGE ApiMessage,
else
{
/* This is a server-to-server call. Save our CID and do a direct call */
DbgBreakPoint();
DPRINT1("Next gen server-to-server call\n");
ApiMessage->Header.ClientId = NtCurrentTeb()->ClientId;
Status = CsrServerApiRoutine(&ApiMessage->Header,
&ApiMessage->Header);
@ -366,10 +365,10 @@ CsrClientConnectToServer(PWSTR ObjectDirectory,
InsideCsrProcess = (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE);
/* Now we can check if we are inside or not */
if (InsideCsrProcess && !UsingOldCsr)
if (InsideCsrProcess)
{
/* We're inside, so let's find csrsrv */
DbgBreakPoint();
DPRINT1("Next-GEN CSRSS support\n");
RtlInitUnicodeString(&CsrSrvName, L"csrsrv");
Status = LdrGetDllHandle(NULL,
NULL,

View file

@ -513,7 +513,7 @@ BasepNotifyCsrOfCreation(ULONG dwCreationFlags,
sizeof(CSR_API_MESSAGE));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
{
DPRINT1("Failed to tell csrss about new process\n");
DPRINT1("Failed to tell csrss about new process: %lx %lx\n", Status, CsrRequest.Status);
return CsrRequest.Status;
}

View file

@ -1074,7 +1074,7 @@ CsrLockProcessByClientId(IN HANDLE Pid,
{
PLIST_ENTRY NextEntry;
PCSR_PROCESS CurrentProcess = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
NTSTATUS Status;
/* Acquire the lock */
CsrAcquireProcessLock();
@ -1084,31 +1084,37 @@ CsrLockProcessByClientId(IN HANDLE Pid,
*CsrProcess = NULL;
/* Setup the List Pointers */
NextEntry = CsrRootProcess->ListLink.Flink;
while (NextEntry != &CsrRootProcess->ListLink)
NextEntry = &CsrRootProcess->ListLink;
do
{
/* Get the Process */
CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
/* Check for PID Match */
if (CurrentProcess->ClientId.UniqueProcess == Pid) break;
if (CurrentProcess->ClientId.UniqueProcess == Pid)
{
Status = STATUS_SUCCESS;
break;
}
/* Next entry */
NextEntry = NextEntry->Flink;
}
} while (NextEntry != &CsrRootProcess->ListLink);
/* Check if we didn't find it in the list */
if (NextEntry == &CsrRootProcess->ListLink)
if (!NT_SUCCESS(Status))
{
/* Nothing found, release the lock */
CsrReleaseProcessLock();
return Status;
}
/* Lock the found process and return it */
Status = STATUS_SUCCESS;
CurrentProcess->ReferenceCount++;
*CsrProcess = CurrentProcess;
else
{
/* Lock the found process and return it */
CsrLockedReferenceProcess(CurrentProcess);
*CsrProcess = CurrentProcess;
}
/* Return the result */
return Status;
}

View file

@ -113,6 +113,128 @@ CsrHandleHardError(IN PCSR_THREAD ThreadData,
CallHardError(ThreadData, Message);
}
/*++
* @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
* if the opcode is invalid, or STATUS_ACCESS_VIOLATION if there
* was a problem executing the API.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg,
PCSR_API_MESSAGE ReplyMsg)
{
#if 0 // real code
ULONG ServerId;
PCSR_SERVER_DLL ServerDll;
ULONG ApiId;
ULONG Reply;
NTSTATUS Status;
/* Get the Server ID */
ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg->Opcode);
/* 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 */
ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg->Opcode);
/* 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]);
}
/* Validation complete, start SEH */
_SEH2_TRY
{
/* Call the API and get the result */
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;
#else // Hacky reactos code
PCSR_PROCESS ProcessData;
/* Get the Process Data */
ProcessData = CsrGetProcessData(ReceiveMsg->Header.ClientId.UniqueProcess);
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(ProcessData, ReplyMsg);
}
_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;
#endif
}
/*++
* @name CsrApiPortInitialize
*

View file

@ -1,5 +1,5 @@
@ stdcall CsrAddStaticServerThread(ptr ptr long)
;@ stdcall CsrCallServerFromServer(ptr ptr)
@ stdcall CsrCallServerFromServer(ptr ptr)
;@ stdcall CsrConnectToUser()
;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
;@ stdcall CsrCreateRemoteThread(ptr ptr)

View file

@ -810,6 +810,7 @@ CsrLockProcessByClientId(IN HANDLE Pid,
{
PLIST_ENTRY NextEntry;
PCSR_PROCESS CurrentProcess = NULL;
NTSTATUS Status;
/* Acquire the lock */
CsrAcquireProcessLock();
@ -819,31 +820,38 @@ CsrLockProcessByClientId(IN HANDLE Pid,
*CsrProcess = NULL;
/* Setup the List Pointers */
NextEntry = CsrRootProcess->ListLink.Flink;
while (NextEntry != &CsrRootProcess->ListLink)
NextEntry = &CsrRootProcess->ListLink;
do
{
/* Get the Process */
CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
/* Check for PID Match */
if (CurrentProcess->ClientId.UniqueProcess == Pid) break;
if (CurrentProcess->ClientId.UniqueProcess == Pid)
{
Status = STATUS_SUCCESS;
break;
}
/* Next entry */
NextEntry = NextEntry->Flink;
}
} while (NextEntry != &CsrRootProcess->ListLink);
/* Check if we didn't find it in the list */
if (NextEntry == &CsrRootProcess->ListLink)
if (!NT_SUCCESS(Status))
{
/* Nothing found, release the lock */
CsrReleaseProcessLock();
return STATUS_UNSUCCESSFUL;
}
/* Lock the found process and return it */
CsrLockedReferenceProcess(CurrentProcess);
*CsrProcess = CurrentProcess;
return STATUS_SUCCESS;
else
{
/* Lock the found process and return it */
CsrLockedReferenceProcess(CurrentProcess);
*CsrProcess = CurrentProcess;
}
/* Return the result */
return Status;
}
/* EOF */