Author: tkreuzer
Date: Sat May 5 22:50:47 2012
New Revision: 56521
URL: http://svn.reactos.org/svn/reactos?rev=56521&view=rev
Log:
[WIN32K]
Fix regression of gdi32_winetest palette
Modified:
trunk/reactos/win32ss/gdi/ntgdi/dibobj.c
Modified: trunk/reactos/win32ss/gdi/ntgdi/dibobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dibobj.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] Sat May 5 22:50:47 2012
@@ -148,9 +148,12 @@
/* Loop all color indices in the DIB */
for (i = 0; i < cColors; i++)
{
- /* Get the RGB value from the DC palette, indexed by the DIB
- color table value */
- crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, pwColors[i]);
+ /* Get the palette index and handle wraparound when exceeding
+ the number of colors in the DC palette */
+ WORD wIndex = pwColors[i] % ppalDC->NumColors;
+
+ /* USe the RGB value from the DC palette */
+ crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, wIndex);
PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
}
}
Author: tkreuzer
Date: Sat May 5 22:06:15 2012
New Revision: 56520
URL: http://svn.reactos.org/svn/reactos?rev=56520&view=rev
Log:
[WIN32K]
Someone passes iUsage == 2, so don't assert in that case, but ignore it as long as it's not supported.
Modified:
trunk/reactos/win32ss/gdi/ntgdi/dibobj.c
Modified: trunk/reactos/win32ss/gdi/ntgdi/dibobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dibobj.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] Sat May 5 22:06:15 2012
@@ -171,11 +171,11 @@
/* Mark the palette as a brush hack palette */
ppal->flFlags |= PAL_BRUSHHACK;
}
- else if (iUsage == 2)
- {
+// else if (iUsage == 2)
+// {
// FIXME: this one is undocumented
- ASSERT(FALSE);
- }
+// ASSERT(FALSE);
+// }
else // if (iUsage == DIB_RGB_COLORS)
{
/* The colors are an array of RGBQUAD values */
Author: tkreuzer
Date: Sat May 5 21:09:08 2012
New Revision: 56517
URL: http://svn.reactos.org/svn/reactos?rev=56517&view=rev
Log:
[WIN32K]
When dereferencing an object without a handle, don't check for the ready-to-die flag
Modified:
trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] Sat May 5 21:09:08 2012
@@ -479,6 +479,8 @@
/* Must not be exclusively locked */
ASSERT(pobj->cExclusiveLock == 0);
+ DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
+
/* Check if the object has a handle */
if (GDI_HANDLE_GET_INDEX(pobj->hHmgr))
{
@@ -492,6 +494,9 @@
/* Check if we reached 0 and handle bit is not set */
if (cRefs == 0)
{
+ /* Make sure it's ok to delete the object */
+ ASSERT(pobj->BaseFlags & BASEFLAG_READY_TO_DIE);
+
/* Check if the handle was process owned */
if (gpentHmgr[ulIndex].ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC &&
gpentHmgr[ulIndex].ObjectOwner.ulObj != GDI_OBJ_HMGR_NONE)
@@ -504,6 +509,9 @@
/* Push entry to the free list */
ENTRY_vPushFreeEntry(&gpentHmgr[ulIndex]);
+
+ /* Free the object */
+ GDIOBJ_vFreeObject(pobj);
}
}
else
@@ -511,18 +519,13 @@
/* Decrement the objects reference count */
ASSERT(pobj->ulShareCount > 0);
cRefs = InterlockedDecrement((LONG*)&pobj->ulShareCount);
- }
-
- DBG_LOGEVENT(&pobj->slhLog, EVENT_DEREFERENCE, cRefs);
-
- /* Check if we reached 0 */
- if (cRefs == 0)
- {
- /* Make sure it's ok to delete the object */
- ASSERT(pobj->BaseFlags & BASEFLAG_READY_TO_DIE);
-
- /* Free the object */
- GDIOBJ_vFreeObject(pobj);
+
+ /* Check if we reached 0 */
+ if (cRefs == 0)
+ {
+ /* Free the object */
+ GDIOBJ_vFreeObject(pobj);
+ }
}
}
Author: sir_richard
Date: Sat May 5 19:37:34 2012
New Revision: 56516
URL: http://svn.reactos.org/svn/reactos?rev=56516&view=rev
Log:
[NTOS]: Cleanup MiQueryAddressState.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Sat May 5 19:37:34 2012
@@ -1308,7 +1308,7 @@
PMMPDE PointerPde;
MMPTE TempPte;
BOOLEAN DemandZeroPte = TRUE, ValidPte = FALSE;
- ULONG State = MEM_RESERVE, Protect = 0, LockChange;
+ ULONG State = MEM_RESERVE, Protect = 0;
ASSERT((Vad->StartingVpn <= ((ULONG_PTR)Va >> PAGE_SHIFT)) &&
(Vad->EndingVpn >= ((ULONG_PTR)Va >> PAGE_SHIFT)));
@@ -1322,31 +1322,23 @@
/* Return the next range */
*NextVa = (PVOID)((ULONG_PTR)Va + PAGE_SIZE);
- /* Loop to make sure the PDE is valid */
- do
- {
- /* Try again */
- LockChange = 0;
-
- /* Is the PDE empty? */
- if (!PointerPde->u.Long)
- {
- /* No address in this range used yet, move to the next PDE range */
- *NextVa = MiPdeToAddress(PointerPde + 1);
- break;
- }
-
- /* The PDE is not empty, but is it faulted in? */
- if (!PointerPde->u.Hard.Valid)
- {
- /* It isn't, go ahead and do the fault */
- LockChange = MiMakeSystemAddressValid(MiPdeToPte(PointerPde),
- TargetProcess);
- }
-
- /* Check if the PDE was faulted in, making the PTE readable */
- if (!LockChange) ValidPte = TRUE;
- } while (LockChange);
+ /* Is the PDE demand-zero? */
+ if (PointerPde->u.Long != 0)
+ {
+ /* It is not. Is it valid? */
+ if (PointerPde->u.Hard.Valid == 0)
+ {
+ /* Is isn't, fault it in */
+ PointerPte = MiPteToAddress(PointerPde);
+ MiMakeSystemAddressValid(PointerPte, TargetProcess);
+ ValidPte = TRUE;
+ }
+ }
+ else
+ {
+ /* It is, skip it and move to the next PDE */
+ *NextVa = MiPdeToAddress(PointerPde + 1);
+ }
/* Is it safe to try reading the PTE? */
if (ValidPte)
@@ -1355,36 +1347,52 @@
/* Capture the PTE */
TempPte = *PointerPte;
- if (TempPte.u.Long)
+ if (TempPte.u.Long != 0)
{
/* The PTE is valid, so it's not zeroed out */
DemandZeroPte = FALSE;
- /* Check if it's valid or has a valid protection mask */
- ASSERT(TempPte.u.Soft.Prototype == 0);
- if ((TempPte.u.Soft.Protection != MM_DECOMMIT) ||
- (TempPte.u.Hard.Valid == 1))
- {
- /* This means it's committed */
- State = MEM_COMMIT;
-
- /* Get protection state of this page */
- Protect = MiGetPageProtection(PointerPte);
- }
- else
+ /* Is it a decommited, invalid, or faulted PTE? */
+ if ((TempPte.u.Soft.Protection == MM_DECOMMIT) &&
+ (TempPte.u.Hard.Valid == 0) &&
+ ((TempPte.u.Soft.Prototype == 0) ||
+ (TempPte.u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED)))
{
/* Otherwise our defaults should hold */
ASSERT(Protect == 0);
ASSERT(State == MEM_RESERVE);
}
+ else
+ {
+ /* This means it's committed */
+ State = MEM_COMMIT;
+
+ /* Get protection state of this page */
+ Protect = MiGetPageProtection(PointerPte);
+
+ /* Check if this is an image-backed VAD */
+ if ((TempPte.u.Soft.Valid == 0) &&
+ (TempPte.u.Soft.Prototype == 1) &&
+ (Vad->u.VadFlags.PrivateMemory == 0) &&
+ (Vad->ControlArea))
+ {
+ DPRINT1("Not supported\n");
+ ASSERT(FALSE);
+ }
+ }
}
}
/* Check if this was a demand-zero PTE, since we need to find the state */
if (DemandZeroPte)
{
- /* Check if the VAD is for committed memory */
- if (Vad->u.VadFlags.MemCommit)
+ /* Check if this is private commited memory, or an image-backed VAD */
+ if ((Vad->u.VadFlags.PrivateMemory == 0) && (Vad->ControlArea))
+ {
+ DPRINT1("Not supported\n");
+ ASSERT(FALSE);
+ }
+ else if (Vad->u.VadFlags.MemCommit)
{
/* This is committed memory */
State = MEM_COMMIT;
Author: sir_richard
Date: Sat May 5 19:26:21 2012
New Revision: 56515
URL: http://svn.reactos.org/svn/reactos?rev=56515&view=rev
Log:
[NTOS]: Attempt to hackfix MiGetPageProtection to support the case seen in OllyDBG.
[NTOS]: Implement Case C of NtFreeVirtualMemory, which is sometimes seen in some heap logs. The hard part is figuring out the right amount of committed/decommitted pages. Only supports 2-level paging for now as the algorithm is already messy enough.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Sat May 5 19:26:21 2012
@@ -27,6 +27,168 @@
OUT PULONG OldAccessProtection OPTIONAL);
/* PRIVATE FUNCTIONS **********************************************************/
+
+ULONG
+NTAPI
+MiCalculatePageCommitment(IN ULONG_PTR StartingAddress,
+ IN ULONG_PTR EndingAddress,
+ IN PMMVAD Vad,
+ IN PEPROCESS Process)
+{
+ PMMPTE PointerPte, LastPte, PointerPde;
+ ULONG CommittedPages;
+
+ /* Compute starting and ending PTE and PDE addresses */
+ PointerPde = MiAddressToPde(StartingAddress);
+ PointerPte = MiAddressToPte(StartingAddress);
+ LastPte = MiAddressToPte(EndingAddress);
+
+ /* Handle commited pages first */
+ if (Vad->u.VadFlags.MemCommit == 1)
+ {
+ /* This is a committed VAD, so Assume the whole range is committed */
+ CommittedPages = BYTES_TO_PAGES(EndingAddress - StartingAddress);
+
+ /* Is the PDE demand-zero? */
+ PointerPde = MiAddressToPte(PointerPte);
+ if (PointerPde->u.Long != 0)
+ {
+ /* It is not. Is it valid? */
+ if (PointerPde->u.Hard.Valid == 0)
+ {
+ /* Fault it in */
+ PointerPte = MiPteToAddress(PointerPde);
+ MiMakeSystemAddressValid(PointerPte, Process);
+ }
+ }
+ else
+ {
+ /* It is, skip it and move to the next PDE, unless we're done */
+ PointerPde++;
+ PointerPte = MiPteToAddress(PointerPde);
+ if (PointerPte > LastPte) return CommittedPages;
+ }
+
+ /* Now loop all the PTEs in the range */
+ while (PointerPte <= LastPte)
+ {
+ /* Have we crossed a PDE boundary? */
+ if (MiIsPteOnPdeBoundary(PointerPte))
+ {
+ /* Is this PDE demand zero? */
+ PointerPde = MiAddressToPte(PointerPte);
+ if (PointerPde->u.Long != 0)
+ {
+ /* It isn't -- is it valid? */
+ if (PointerPde->u.Hard.Valid == 0)
+ {
+ /* Nope, fault it in */
+ PointerPte = MiPteToAddress(PointerPde);
+ MiMakeSystemAddressValid(PointerPte, Process);
+ }
+ }
+ else
+ {
+ /* It is, skip it and move to the next PDE */
+ PointerPde++;
+ PointerPte = MiPteToAddress(PointerPde);
+ continue;
+ }
+ }
+
+ /* Is this PTE demand zero? */
+ if (PointerPte->u.Long != 0)
+ {
+ /* It isn't -- is it a decommited, invalid, or faulted PTE? */
+ if ((PointerPte->u.Soft.Protection == MM_DECOMMIT) &&
+ (PointerPte->u.Hard.Valid == 0) &&
+ ((PointerPte->u.Soft.Prototype == 0) ||
+ (PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED)))
+ {
+ /* It is, so remove it from the count of commited pages */
+ CommittedPages--;
+ }
+ }
+
+ /* Move to the next PTE */
+ PointerPte++;
+ }
+
+ /* Return how many committed pages there still are */
+ return CommittedPages;
+ }
+
+ /* This is a non-commited VAD, so assume none of it is committed */
+ CommittedPages = 0;
+
+ /* Is the PDE demand-zero? */
+ PointerPde = MiAddressToPte(PointerPte);
+ if (PointerPde->u.Long != 0)
+ {
+ /* It isn't -- is it invalid? */
+ if (PointerPde->u.Hard.Valid == 0)
+ {
+ /* It is, so page it in */
+ PointerPte = MiPteToAddress(PointerPde);
+ MiMakeSystemAddressValid(PointerPte, Process);
+ }
+ }
+ else
+ {
+ /* It is, so skip it and move to the next PDE */
+ PointerPde++;
+ PointerPte = MiPteToAddress(PointerPde);
+ if (PointerPte > LastPte) return CommittedPages;
+ }
+
+ /* Loop all the PTEs in this PDE */
+ while (PointerPte <= LastPte)
+ {
+ /* Have we crossed a PDE boundary? */
+ if (MiIsPteOnPdeBoundary(PointerPte))
+ {
+ /* Is this new PDE demand-zero? */
+ PointerPde = MiAddressToPte(PointerPte);
+ if (PointerPde->u.Long != 0)
+ {
+ /* It isn't. Is it valid? */
+ if (PointerPde->u.Hard.Valid == 0)
+ {
+ /* It isn't, so make it valid */
+ PointerPte = MiPteToAddress(PointerPde);
+ MiMakeSystemAddressValid(PointerPte, Process);
+ }
+ }
+ else
+ {
+ /* It is, so skip it and move to the next one */
+ PointerPde++;
+ PointerPte = MiPteToAddress(PointerPde);
+ continue;
+ }
+ }
+
+ /* Is this PTE demand-zero? */
+ if (PointerPte->u.Long != 0)
+ {
+ /* Nope. Is it a valid, non-decommited, non-paged out PTE? */
+ if ((PointerPte->u.Soft.Protection != MM_DECOMMIT) ||
+ (PointerPte->u.Hard.Valid == 1) ||
+ ((PointerPte->u.Soft.Prototype == 1) &&
+ (PointerPte->u.Soft.PageFileHigh != MI_PTE_LOOKUP_NEEDED)))
+ {
+ /* It is! So we'll treat this as a committed page */
+ CommittedPages++;
+ }
+ }
+
+ /* Move to the next PTE */
+ PointerPte++;
+ }
+
+ /* Return how many committed pages we found in this VAD */
+ return CommittedPages;
+}
ULONG
NTAPI
@@ -1118,18 +1280,19 @@
/* If we get here, the PTE is valid, so look up the page in PFN database */
Pfn = MiGetPfnEntry(TempPte.u.Hard.PageFrameNumber);
-
if (!Pfn->u3.e1.PrototypePte)
{
/* Return protection of the original pte */
+ ASSERT(Pfn->u4.AweAllocation == 0);
return MmProtectToValue[Pfn->OriginalPte.u.Soft.Protection];
}
- /* This is hardware PTE */
- UNIMPLEMENTED;
- ASSERT(FALSE);
-
- return PAGE_NOACCESS;
+ /* This is software PTE */
+ DPRINT1("Prototype PTE: %lx %p\n", TempPte.u.Hard.PageFrameNumber, Pfn);
+ DPRINT1("VA: %p\n", MiPteToAddress(&TempPte));
+ DPRINT1("Mask: %lx\n", TempPte.u.Soft.Protection);
+ DPRINT1("Mask2: %lx\n", Pfn->OriginalPte.u.Soft.Protection);
+ return MmProtectToValue[TempPte.u.Soft.Protection];
}
ULONG
@@ -4049,11 +4212,13 @@
// and then change the ending address of the VAD to be a bit
// smaller.
//
- // NOT YET IMPLEMENTED IN ARM3.
- //
- DPRINT1("Case C not handled\n");
- Status = STATUS_FREE_VM_NOT_AT_BASE;
- goto FailPath;
+ MiLockWorkingSet(CurrentThread, AddressSpace);
+ CommitReduction = MiCalculatePageCommitment(StartingAddress,
+ EndingAddress,
+ Vad,
+ Process);
+ Vad->u.VadFlags.CommitCharge -= CommitReduction;
+ Vad->EndingVpn = ((ULONG_PTR)StartingAddress - 1) >> PAGE_SHIFT;
}
else
{