mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
[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:
parent
87a966228c
commit
e5f337a82b
6 changed files with 164 additions and 29 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue