Author: ion
Date: Sat Feb 18 01:27:50 2012
New Revision: 55677
URL: http://svn.reactos.org/svn/reactos?rev=55677&view=rev
Log:
[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++.
Modified:
trunk/reactos/dll/ntdll/csr/connect.c
trunk/reactos/dll/win32/kernel32/client/proc.c
trunk/reactos/subsystems/csr/csrsrv/process.c
trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c
trunk/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec
trunk/reactos/subsystems/win32/csrss/csrsrv/procsup.c
Modified: trunk/reactos/dll/ntdll/csr/connect.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/csr/connect.c?re…
==============================================================================
--- trunk/reactos/dll/ntdll/csr/connect.c [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/csr/connect.c [iso-8859-1] Sat Feb 18 01:27:50 2012
@@ -19,7 +19,6 @@
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 @@
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 @@
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,
Modified: trunk/reactos/dll/win32/kernel32/client/proc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] Sat Feb 18 01:27:50 2012
@@ -513,7 +513,7 @@
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;
}
Modified: trunk/reactos/subsystems/csr/csrsrv/process.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/csr/csrsrv/proc…
==============================================================================
--- trunk/reactos/subsystems/csr/csrsrv/process.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/csr/csrsrv/process.c [iso-8859-1] Sat Feb 18 01:27:50 2012
@@ -1074,7 +1074,7 @@
{
PLIST_ENTRY NextEntry;
PCSR_PROCESS CurrentProcess = NULL;
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ NTSTATUS Status;
/* Acquire the lock */
CsrAcquireProcessLock();
@@ -1084,31 +1084,37 @@
*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;
}
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] Sat Feb 18 01:27:50 2012
@@ -111,6 +111,128 @@
/* Call the hard error handler in win32csr */
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
}
/*++
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec [iso-8859-1] Sat Feb 18 01:27:50 2012
@@ -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)
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/procsup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/procsup.c [iso-8859-1] Sat Feb 18 01:27:50 2012
@@ -810,6 +810,7 @@
{
PLIST_ENTRY NextEntry;
PCSR_PROCESS CurrentProcess = NULL;
+ NTSTATUS Status;
/* Acquire the lock */
CsrAcquireProcessLock();
@@ -819,31 +820,38 @@
*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 */
Author: tkreuzer
Date: Fri Feb 17 15:51:13 2012
New Revision: 55671
URL: http://svn.reactos.org/svn/reactos?rev=55671&view=rev
Log:
[WIN32K]
Fix another bug in NtGdiSelectBitmap, where selecting the same bitmap a second time, would release the bitmap
Modified:
trunk/reactos/subsystems/win32/win32k/objects/dcobjs.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/dcobjs.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/dcobjs.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/dcobjs.c [iso-8859-1] Fri Feb 17 15:51:13 2012
@@ -261,11 +261,9 @@
IN HBITMAP hbmp)
{
PDC pdc;
- PDC_ATTR pdcattr;
HBITMAP hbmpOld;
PSURFACE psurfNew, psurfOld;
HRGN hVisRgn;
- SIZEL sizlBitmap = {1, 1};
HDC hdcOld;
ASSERT_NOGDILOCKS();
@@ -278,7 +276,6 @@
{
return NULL;
}
- pdcattr = pdc->pdcattr;
/* Must be a memory dc to select a bitmap */
if (pdc->dctype != DC_TYPE_MEMORY)
@@ -290,10 +287,34 @@
/* Save the old bitmap */
psurfOld = pdc->dclevel.pSurface;
+ /* Check if there is a bitmap selected */
+ if (psurfOld)
+ {
+ /* Get the old bitmap's handle */
+ hbmpOld = psurfOld->BaseObject.hHmgr;
+ }
+ else
+ {
+ /* Use the default bitmap */
+ hbmpOld = StockObjects[DEFAULT_BITMAP];
+ }
+
+ /* Check if the new bitmap is already selected */
+ if (hbmp == hbmpOld)
+ {
+ /* Unlock the DC and return the old bitmap */
+ DC_UnlockDc(pdc);
+ return hbmpOld;
+ }
+
/* Check if the default bitmap was passed */
if (hbmp == StockObjects[DEFAULT_BITMAP])
{
psurfNew = NULL;
+
+ /* Default bitmap is 1x1 pixel */
+ pdc->dclevel.sizl.cx = 1;
+ pdc->dclevel.sizl.cy = 1;
// HACK
psurfNew = SURFACE_ShareLockSurface(hbmp);
@@ -308,28 +329,32 @@
return NULL;
}
- /* Set the bitmp's hdc */
+ /* Set the bitmap's hdc and check if it was set before */
hdcOld = InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc, 0);
- if (hdcOld != NULL && hdcOld != hdc)
- {
- /* The bitmap is already selected, fail */
+ if (hdcOld != NULL)
+ {
+ /* The bitmap is already selected into a different DC */
+ ASSERT(hdcOld != hdc);
+
+ /* Dereference the bitmap, unlock the DC and fail. */
SURFACE_ShareUnlockSurface(psurfNew);
DC_UnlockDc(pdc);
return NULL;
}
- /* Get the bitmap size */
- sizlBitmap = psurfNew->SurfObj.sizlBitmap;
+ /* Copy the bitmap size */
+ pdc->dclevel.sizl = psurfNew->SurfObj.sizlBitmap;
/* Check if the bitmap is a dibsection */
if(psurfNew->hSecure)
{
/* Set DIBSECTION attribute */
- pdcattr->ulDirty_ |= DC_DIBSECTION;
+ pdc->pdcattr->ulDirty_ |= DC_DIBSECTION;
}
else
{
- pdcattr->ulDirty_ &= ~DC_DIBSECTION;
+ /* Remove DIBSECTION attribute */
+ pdc->pdcattr->ulDirty_ &= ~DC_DIBSECTION;
}
}
@@ -339,37 +364,30 @@
/* Check if there was a bitmap selected before */
if (psurfOld)
{
- /* Get the old bitmap's handle */
- hbmpOld = psurfOld->BaseObject.hHmgr;
-
- /* Reset hdc of the old bitmap,it isn't selected anymore */
+ /* Reset hdc of the old bitmap, it isn't selected anymore */
psurfOld->hdc = NULL;
/* Dereference the old bitmap */
SURFACE_ShareUnlockSurface(psurfOld);
}
- else
- {
- /* Return default bitmap */
- hbmpOld = StockObjects[DEFAULT_BITMAP];
- }
/* Mark the dc brushes invalid */
- pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
-
- /* Unlock the DC */
- DC_UnlockDc(pdc);
+ pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
/* FIXME: Improve by using a region without a handle and selecting it */
hVisRgn = IntSysCreateRectRgn( 0,
0,
- sizlBitmap.cx,
- sizlBitmap.cy);
+ pdc->dclevel.sizl.cx,
+ pdc->dclevel.sizl.cy);
+
if (hVisRgn)
{
GdiSelectVisRgn(hdc, hVisRgn);
GreDeleteObject(hVisRgn);
}
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
/* Return the old bitmap handle */
return hbmpOld;