mirror of
https://github.com/reactos/reactos.git
synced 2025-05-08 19:27:00 +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;
|
HANDLE CsrPortHeap;
|
||||||
ULONG_PTR CsrPortMemoryDelta;
|
ULONG_PTR CsrPortMemoryDelta;
|
||||||
BOOLEAN InsideCsrProcess = FALSE;
|
BOOLEAN InsideCsrProcess = FALSE;
|
||||||
BOOLEAN UsingOldCsr = TRUE;
|
|
||||||
|
|
||||||
typedef NTSTATUS
|
typedef NTSTATUS
|
||||||
(NTAPI *PCSR_SERVER_API_ROUTINE)(IN PPORT_MESSAGE Request,
|
(NTAPI *PCSR_SERVER_API_ROUTINE)(IN PPORT_MESSAGE Request,
|
||||||
|
@ -151,7 +150,7 @@ CsrClientCallServer(PCSR_API_MESSAGE ApiMessage,
|
||||||
else
|
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 */
|
||||||
DbgBreakPoint();
|
DPRINT1("Next gen server-to-server call\n");
|
||||||
ApiMessage->Header.ClientId = NtCurrentTeb()->ClientId;
|
ApiMessage->Header.ClientId = NtCurrentTeb()->ClientId;
|
||||||
Status = CsrServerApiRoutine(&ApiMessage->Header,
|
Status = CsrServerApiRoutine(&ApiMessage->Header,
|
||||||
&ApiMessage->Header);
|
&ApiMessage->Header);
|
||||||
|
@ -366,10 +365,10 @@ CsrClientConnectToServer(PWSTR ObjectDirectory,
|
||||||
InsideCsrProcess = (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE);
|
InsideCsrProcess = (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE);
|
||||||
|
|
||||||
/* Now we can check if we are inside or not */
|
/* Now we can check if we are inside or not */
|
||||||
if (InsideCsrProcess && !UsingOldCsr)
|
if (InsideCsrProcess)
|
||||||
{
|
{
|
||||||
/* We're inside, so let's find csrsrv */
|
/* We're inside, so let's find csrsrv */
|
||||||
DbgBreakPoint();
|
DPRINT1("Next-GEN CSRSS support\n");
|
||||||
RtlInitUnicodeString(&CsrSrvName, L"csrsrv");
|
RtlInitUnicodeString(&CsrSrvName, L"csrsrv");
|
||||||
Status = LdrGetDllHandle(NULL,
|
Status = LdrGetDllHandle(NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -513,7 +513,7 @@ BasepNotifyCsrOfCreation(ULONG dwCreationFlags,
|
||||||
sizeof(CSR_API_MESSAGE));
|
sizeof(CSR_API_MESSAGE));
|
||||||
if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
|
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;
|
return CsrRequest.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1074,7 +1074,7 @@ CsrLockProcessByClientId(IN HANDLE Pid,
|
||||||
{
|
{
|
||||||
PLIST_ENTRY NextEntry;
|
PLIST_ENTRY NextEntry;
|
||||||
PCSR_PROCESS CurrentProcess = NULL;
|
PCSR_PROCESS CurrentProcess = NULL;
|
||||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Acquire the lock */
|
/* Acquire the lock */
|
||||||
CsrAcquireProcessLock();
|
CsrAcquireProcessLock();
|
||||||
|
@ -1084,31 +1084,37 @@ CsrLockProcessByClientId(IN HANDLE Pid,
|
||||||
*CsrProcess = NULL;
|
*CsrProcess = NULL;
|
||||||
|
|
||||||
/* Setup the List Pointers */
|
/* Setup the List Pointers */
|
||||||
NextEntry = CsrRootProcess->ListLink.Flink;
|
NextEntry = &CsrRootProcess->ListLink;
|
||||||
while (NextEntry != &CsrRootProcess->ListLink)
|
do
|
||||||
{
|
{
|
||||||
/* Get the Process */
|
/* Get the Process */
|
||||||
CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
|
CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
|
||||||
|
|
||||||
/* Check for PID Match */
|
/* Check for PID Match */
|
||||||
if (CurrentProcess->ClientId.UniqueProcess == Pid) break;
|
if (CurrentProcess->ClientId.UniqueProcess == Pid)
|
||||||
|
{
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Next entry */
|
/* Next entry */
|
||||||
NextEntry = NextEntry->Flink;
|
NextEntry = NextEntry->Flink;
|
||||||
}
|
} while (NextEntry != &CsrRootProcess->ListLink);
|
||||||
|
|
||||||
/* Check if we didn't find it in the list */
|
/* Check if we didn't find it in the list */
|
||||||
if (NextEntry == &CsrRootProcess->ListLink)
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Nothing found, release the lock */
|
/* Nothing found, release the lock */
|
||||||
CsrReleaseProcessLock();
|
CsrReleaseProcessLock();
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Lock the found process and return it */
|
{
|
||||||
Status = STATUS_SUCCESS;
|
/* Lock the found process and return it */
|
||||||
CurrentProcess->ReferenceCount++;
|
CsrLockedReferenceProcess(CurrentProcess);
|
||||||
*CsrProcess = CurrentProcess;
|
*CsrProcess = CurrentProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,128 @@ CsrHandleHardError(IN PCSR_THREAD ThreadData,
|
||||||
CallHardError(ThreadData, Message);
|
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
|
* @name CsrApiPortInitialize
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@ stdcall CsrAddStaticServerThread(ptr ptr long)
|
@ stdcall CsrAddStaticServerThread(ptr ptr long)
|
||||||
;@ stdcall CsrCallServerFromServer(ptr ptr)
|
@ stdcall CsrCallServerFromServer(ptr ptr)
|
||||||
;@ stdcall CsrConnectToUser()
|
;@ stdcall CsrConnectToUser()
|
||||||
;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
|
;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
|
||||||
;@ stdcall CsrCreateRemoteThread(ptr ptr)
|
;@ stdcall CsrCreateRemoteThread(ptr ptr)
|
||||||
|
|
|
@ -810,6 +810,7 @@ CsrLockProcessByClientId(IN HANDLE Pid,
|
||||||
{
|
{
|
||||||
PLIST_ENTRY NextEntry;
|
PLIST_ENTRY NextEntry;
|
||||||
PCSR_PROCESS CurrentProcess = NULL;
|
PCSR_PROCESS CurrentProcess = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Acquire the lock */
|
/* Acquire the lock */
|
||||||
CsrAcquireProcessLock();
|
CsrAcquireProcessLock();
|
||||||
|
@ -819,31 +820,38 @@ CsrLockProcessByClientId(IN HANDLE Pid,
|
||||||
*CsrProcess = NULL;
|
*CsrProcess = NULL;
|
||||||
|
|
||||||
/* Setup the List Pointers */
|
/* Setup the List Pointers */
|
||||||
NextEntry = CsrRootProcess->ListLink.Flink;
|
NextEntry = &CsrRootProcess->ListLink;
|
||||||
while (NextEntry != &CsrRootProcess->ListLink)
|
do
|
||||||
{
|
{
|
||||||
/* Get the Process */
|
/* Get the Process */
|
||||||
CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
|
CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
|
||||||
|
|
||||||
/* Check for PID Match */
|
/* Check for PID Match */
|
||||||
if (CurrentProcess->ClientId.UniqueProcess == Pid) break;
|
if (CurrentProcess->ClientId.UniqueProcess == Pid)
|
||||||
|
{
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Next entry */
|
/* Next entry */
|
||||||
NextEntry = NextEntry->Flink;
|
NextEntry = NextEntry->Flink;
|
||||||
}
|
} while (NextEntry != &CsrRootProcess->ListLink);
|
||||||
|
|
||||||
/* Check if we didn't find it in the list */
|
/* Check if we didn't find it in the list */
|
||||||
if (NextEntry == &CsrRootProcess->ListLink)
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Nothing found, release the lock */
|
/* Nothing found, release the lock */
|
||||||
CsrReleaseProcessLock();
|
CsrReleaseProcessLock();
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Lock the found process and return it */
|
{
|
||||||
CsrLockedReferenceProcess(CurrentProcess);
|
/* Lock the found process and return it */
|
||||||
*CsrProcess = CurrentProcess;
|
CsrLockedReferenceProcess(CurrentProcess);
|
||||||
return STATUS_SUCCESS;
|
*CsrProcess = CurrentProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue