Author: tkreuzer
Date: Tue Feb 22 17:29:32 2011
New Revision: 50866
URL: http://svn.reactos.org/svn/reactos?rev=50866&view=rev
Log:
[CRT]
Fix special behaviour of wsprintf: when used with # flag, the "0x" prefix does not count into the field width, so we have to add additional 2 characters here. Fixes Opera installer.
See issue #5900 for more details.
Modified:
trunk/reactos/lib/sdk/crt/printf/streamout.c
Modified: trunk/reactos/lib/sdk/crt/printf/streamout.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/printf/streamo…
==============================================================================
--- trunk/reactos/lib/sdk/crt/printf/streamout.c [iso-8859-1] (original)
+++ trunk/reactos/lib/sdk/crt/printf/streamout.c [iso-8859-1] Tue Feb 22 17:29:32 2011
@@ -587,6 +587,9 @@
if (flags & FLAG_SPECIAL)
{
prefix = &digits[16];
+#ifdef _USER32_WSPRINTF
+ fieldwidth += 2;
+#endif
}
case _T('u'):
Author: akhaldi
Date: Tue Feb 22 11:28:00 2011
New Revision: 50865
URL: http://svn.reactos.org/svn/reactos?rev=50865&view=rev
Log:
[NEWCC]
- Add config.rbuild with NEWCC enabled by default.
Added:
branches/arty-newcc/config.rbuild (with props)
Added: branches/arty-newcc/config.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/config.rbuild?rev=50…
==============================================================================
--- branches/arty-newcc/config.rbuild (added)
+++ branches/arty-newcc/config.rbuild [iso-8859-1] Tue Feb 22 11:28:00 2011
@@ -1,0 +1,107 @@
+<?xml version="1.0"?>
+<!DOCTYPE group SYSTEM "tools/rbuild/project.dtd">
+<group>
+
+<!--
+ This file is a template used as a starting point for compile-time
+ configuration of ReactOS. Make a copy of this file and name it config.rbuild.
+ Then change the options in config.rbuild. If you don't have a config.rbuild file,
+ then the defaults in this file, config.template.rbuild, will be used instead.
+
+ Boolean options can obtain the values 0 (disabled) or 1 (enabled). String
+ options can obtain any value specified in the comment before it.
+-->
+
+
+<!--
+ Sub-architecture to build for. Specify one of:
+ xbox
+-->
+<property name="SARCH" value="" />
+
+
+<!--
+ Generate instructions for this CPU type. Specify one of:
+ native, i386, i486, pentium, pentium-mmx, pentiumpro, i686,
+ pentium2, pentium3, pentium-m, pentium4, prescott, nocona,
+ core2, k6, k6-2, athlon, athlon-xp, opteron, opteron-sse3,
+ barcelona, winchip-c6, winchip2, c3, c3-2, geode
+
+ See GCC manual for more CPU names.
+-->
+<property name="OARCH" value="pentium" />
+
+
+<!--
+ Which CPU ReactOS should be optimized for. Specify one of the above
+ CPUs or generic. When this option is not used, GCC will optimize for
+ the processor specified by OARCH.
+-->
+<property name="TUNE" value="i686" />
+
+
+<!--
+ What level of optimisation to use.
+ 0 = off
+ 1 = Default option, optimize for size (-Os) with some additional options
+ 2 = -Os
+ 3 = -O1
+ 4 = -O2
+ 5 = -O3
+-->
+<property name="OPTIMIZE" value="1" />
+
+
+<!--
+ Whether to compile in the integrated kernel debugger.
+-->
+<property name="KDBG" value="1" />
+
+
+<!--
+ Whether to compile for debugging.
+-->
+<property name="DBG" value="1" />
+
+
+<!--
+ Whether to compile for debugging with GDB. If you don't use GDB, don't
+ enable this.
+-->
+<property name="GDB" value="0" />
+
+
+<!--
+ Whether to compile apps/libs with features covered software patents or not.
+ If you live in a country where software patents are valid/apply, don't
+ enable this (except they/you purchased a license from the patent owner).
+ This settings is disabled (0) by default.
+-->
+<property name="NSWPAT" value="0" />
+
+<!--
+ Whether to compile with the KD protocol. This will disable support for KDBG
+ as well as rossym and symbol lookups, and allow WinDBG to connect to ReactOS.
+ This is currently not fully working, and requires kdcom from Windows 2003 or
+ TinyKRNL. Booting into debug mode with this flag enabled will result in a
+ failure to enter GUI mode. Do not enable unless you know what you're doing.
+-->
+<property name="_WINKD_" value="0" />
+
+<!--
+ Whether to compile support for ELF files. Do not enable unless you know what
+ you're doing.
+-->
+<property name="_ELF_" value="0" />
+
+<!--
+ Whether to compile the multi processor versions for ntoskrnl and hal.
+-->
+<property name="BUILD_MP" value="1" />
+
+<!--
+ Whether to compile the new cache manager
+-->
+<property name="NEWCC" value="1" />
+
+</group>
Propchange: branches/arty-newcc/config.rbuild
------------------------------------------------------------------------------
svn:eol-style = native
Author: arty
Date: Tue Feb 22 04:39:26 2011
New Revision: 50863
URL: http://svn.reactos.org/svn/reactos?rev=50863&view=rev
Log:
[NEWCC] Reenable post-unmap flush. It seems to fix the regtest cd.
Modified:
branches/arty-newcc/ntoskrnl/cache/pinsup.c
Modified: branches/arty-newcc/ntoskrnl/cache/pinsup.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/cache/pinsu…
==============================================================================
--- branches/arty-newcc/ntoskrnl/cache/pinsup.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/cache/pinsup.c [iso-8859-1] Tue Feb 22 04:39:26 2011
@@ -767,12 +767,7 @@
CcpUnlock();
if (!Released) {
- // Note: I thought this flush was needed based on the unwritten pages I had
- // seen post-install, but realized that the installer is using sections to
- // write files and we weren't pushing section pages.
- // I corrected that seperately and this probably isn't needed anymore.
- //if (RealBcb->Dirty)
- //MiFlushMappedSection(RealBcb->BaseAddress, &RealBcb->FileOffset, &RealBcb->Map->FileSizes.FileSize, RealBcb->Dirty);
+ MiFlushMappedSection(RealBcb->BaseAddress, &RealBcb->FileOffset, &RealBcb->Map->FileSizes.FileSize, RealBcb->Dirty);
CcpLock();
CcpUnpinData(RealBcb, TRUE);
CcpUnlock();
Author: fireball
Date: Mon Feb 21 22:42:21 2011
New Revision: 50860
URL: http://svn.reactos.org/svn/reactos?rev=50860&view=rev
Log:
[RTL/DPH]
- Implement heap free operation using already implemented busy/free/available/unused lists support and other base routines.
- Implement missing place to free list and remove from busy list routines.
- Implement find busy block routine (using AVL tree).
- Fix a bug in RtlpDphCoalesceNodeIntoAvailable() which resulted in unwanted attempt to merge the only node with itself (which failed anyway).
- Fix a bug in RtlpDphCoalesceNodeIntoAvailable() which incorrectly removed a node from available list (which is implemented as a standard NT double-linked list, compared to unused and free lists which are implemented as single-linked custom lists and busy list which is an AVL tree). Result of that bug was an infinite loop at the next attempt to traverse the list of available nodes.
- In RtlpDphCoalesceFreeIntoAvailable() break when FreeAllocations becomes less than LeaveOnFreeList (before it would break 1 size too early).
- Fix list traversal in RtlpDphSearchAvailableMemoryListForBestFit(). If it couldn't find a node, it would return the last node in the list instead of NULL.
- In RtlpDphFindAvailableMemory(), a new smaller size should be 4 times smaller, not just 2.
- Add a #if0-ed section in RtlpDphRemoveFromAvailableList which checks if a request to remove node not in the list performed. Used only for debugging.
- Add a trace dprint to every type of list insert/removal operation for easier tracking.
- Add break on NULL ptr freeing support.
- RtlpDphSetProtectionAfterUse() is stubbed and protection is set directly in RtlpDphHeapFree(). To be moved into this function.
Modified:
trunk/reactos/lib/rtl/heappage.c
Modified: trunk/reactos/lib/rtl/heappage.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heappage.c?rev=508…
==============================================================================
--- trunk/reactos/lib/rtl/heappage.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/heappage.c [iso-8859-1] Mon Feb 21 22:42:21 2011
@@ -137,20 +137,22 @@
#define DPH_BREAK_ON_RELEASE_FAIL 0x04
#define DPH_BREAK_ON_FREE_FAIL 0x08
#define DPH_BREAK_ON_PROTECT_FAIL 0x10
+#define DPH_BREAK_ON_NULL_FREE 0x80
/* RtlpDphDebugOptions */
#define DPH_DEBUG_INTERNAL_VALIDATE 0x01
#define DPH_DEBUG_VERBOSE 0x04
/* DPH ExtraFlags */
-#define DPH_EXTRA_CHECK_UNDERRUN 0x10
-#define DPH_LOG_STACK_TRACES 0x0 //FIXME: Get correct value
+#define DPH_EXTRA_LOG_STACK_TRACES 0x02
+#define DPH_EXTRA_CHECK_UNDERRUN 0x10
/* Fillers */
#define DPH_FILL 0xEEEEEEEE
#define DPH_FILL_START_STAMP_1 0xABCDBBBB
#define DPH_FILL_START_STAMP_2 0xABCDBBBA
#define DPH_FILL_END_STAMP_1 0xDCBABBBB
+#define DPH_FILL_END_STAMP_2 0xDCBABBBA
#define DPH_FILL_SUFFIX 0xD0
#define DPH_FILL_INFIX 0xC0
@@ -453,9 +455,31 @@
}
VOID NTAPI
+RtlpDphPlaceOnFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
+{
+ DPRINT("RtlpDphPlaceOnFreeList(%p %p)\n", DphRoot, Node);
+
+ /* Node is being added to the tail of the list */
+ Node->pNextAlloc = NULL;
+
+ /* Add it to the tail of the linked list */
+ if (DphRoot->pFreeAllocationListTail)
+ DphRoot->pFreeAllocationListTail->pNextAlloc = Node;
+ else
+ DphRoot->pFreeAllocationListHead = Node;
+ DphRoot->pFreeAllocationListTail = Node;
+
+ /* Update byte counts taking in account this new node */
+ DphRoot->nFreeAllocations++;
+ DphRoot->nFreeAllocationBytesCommitted += Node->nVirtualBlockSize;
+}
+
+VOID NTAPI
RtlpDphPlaceOnPoolList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
{
- /* DphNode is being added to the tail of the list */
+ DPRINT("RtlpDphPlaceOnPoolList(%p %p)\n", DphRoot, Node);
+
+ /* Node is being added to the tail of the list */
Node->pNextAlloc = NULL;
/* Add it to the tail of the linked list */
@@ -473,6 +497,8 @@
VOID NTAPI
RtlpDphPlaceOnVirtualList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
{
+ DPRINT("RtlpDphPlaceOnVirtualList(%p %p)\n", DphRoot, Node);
+
/* Add it to the head of the virtual list */
Node->pNextAlloc = DphRoot->pVirtualStorageListHead;
if (!DphRoot->pVirtualStorageListHead)
@@ -490,6 +516,8 @@
PDPH_HEAP_BLOCK Node = DphRoot->pUnusedNodeListHead;
PDPH_HEAP_BLOCK Next;
+ DPRINT("RtlpDphTakeNodeFromUnusedList(%p), ret %p\n", DphRoot, Node);
+
/* Take the first entry */
if (!Node) return NULL;
@@ -508,6 +536,8 @@
RtlpDphReturnNodeToUnusedList(PDPH_HEAP_ROOT DphRoot,
PDPH_HEAP_BLOCK Node)
{
+ DPRINT("RtlpDphReturnNodeToUnusedList(%p, %p)\n", DphRoot, Node);
+
/* Add it back to the head of the unused list */
Node->pNextAlloc = DphRoot->pUnusedNodeListHead;
if (!DphRoot->pUnusedNodeListHead)
@@ -528,6 +558,37 @@
DPRINT("RtlpDphRemoveFromAvailableList(%p %p)\n", DphRoot, Node);
+ /* Check if it is in the list */
+#if 0
+ {
+ PLIST_ENTRY CurEntry;
+ PDPH_HEAP_BLOCK NodeEntry;
+ BOOLEAN Found = FALSE;
+
+ /* Find where to put this node according to its virtual address */
+ CurEntry = DphRoot->AvailableAllocationHead.Flink;
+
+ while (CurEntry != &DphRoot->AvailableAllocationHead)
+ {
+ NodeEntry = CONTAINING_RECORD(CurEntry, DPH_HEAP_BLOCK, AvailableEntry);
+
+ if (NodeEntry == Node)
+ {
+ Found = TRUE;
+ break;
+ }
+
+ CurEntry = CurEntry->Flink;
+ }
+
+ if (!Found)
+ {
+ DPRINT1("Trying to remove non-existing in availlist node!\n");
+ DbgBreakPoint();
+ }
+ }
+#endif
+
/* Remove it from the list */
RemoveEntryList(&Node->AvailableEntry);
@@ -541,11 +602,31 @@
}
VOID NTAPI
+RtlpDphRemoveFromBusyList(PDPH_HEAP_ROOT DphRoot,
+ PDPH_HEAP_BLOCK Node)
+{
+ BOOLEAN ElementPresent;
+
+ DPRINT("RtlpDphRemoveFromBusyList(%p %p)\n", DphRoot, Node);
+
+ /* Delete it from busy nodes table */
+ ElementPresent = RtlDeleteElementGenericTableAvl(&DphRoot->BusyNodesTable, &Node->pUserAllocation);
+ ASSERT(ElementPresent == TRUE);
+
+ /* Update counters */
+ DphRoot->nBusyAllocations--;
+ DphRoot->nBusyAllocationBytesCommitted -= Node->nVirtualBlockSize;
+ DphRoot->nBusyAllocationBytesAccessible -= Node->nVirtualAccessSize;
+}
+
+VOID NTAPI
RtlpDphRemoveFromFreeList(PDPH_HEAP_ROOT DphRoot,
PDPH_HEAP_BLOCK Node,
PDPH_HEAP_BLOCK Prev)
{
PDPH_HEAP_BLOCK Next;
+
+ DPRINT("RtlpDphRemoveFromFreeList(%p %p %p)\n", DphRoot, Node, Prev);
/* Detach it from the list */
Next = Node->pNextAlloc;
@@ -578,12 +659,13 @@
/* Find where to put this node according to its virtual address */
AvailListHead = &DphRoot->AvailableAllocationHead;
+
+ /* Find a point where to insert an available node */
CurEntry = AvailListHead->Flink;
while (CurEntry != AvailListHead)
{
NodeEntry = CONTAINING_RECORD(CurEntry, DPH_HEAP_BLOCK, AvailableEntry);
-
if (NodeEntry->pVirtualBlock >= Node->pVirtualBlock)
{
PrevNode = NodeEntry;
@@ -592,10 +674,9 @@
CurEntry = CurEntry->Flink;
}
- /* Did we find a node to insert our one after? */
if (!PrevNode)
{
- /* No, just add to the head of the list then */
+ /* That means either this list is empty, or we should add to the head of it */
InsertHeadList(AvailListHead, &Node->AvailableEntry);
}
else
@@ -615,20 +696,22 @@
/* Insert after PrevNode */
InsertTailList(&PrevNode->AvailableEntry, &Node->AvailableEntry);
}
- }
-
- /* Now check the next entry after our one */
- if (Node->AvailableEntry.Flink != AvailListHead)
- {
- NextNode = CONTAINING_RECORD(Node->AvailableEntry.Flink, DPH_HEAP_BLOCK, AvailableEntry);;
- /* Node is not at the tail of the list, check if it's adjacent */
- if (Node->pVirtualBlock + Node->nVirtualBlockSize == NextNode->pVirtualBlock)
- {
- /* They are adjacent - merge! */
- Node->nVirtualBlockSize += NextNode->nVirtualBlockSize;
- Node->pNextAlloc = NextNode->pNextAlloc;
- RtlpDphReturnNodeToUnusedList(DphRoot, NextNode);
- DphRoot->nAvailableAllocations--;
+
+ /* Now check the next entry after our one */
+ if (Node->AvailableEntry.Flink != AvailListHead)
+ {
+ NextNode = CONTAINING_RECORD(Node->AvailableEntry.Flink, DPH_HEAP_BLOCK, AvailableEntry);
+ /* Node is not at the tail of the list, check if it's adjacent */
+ if (Node->pVirtualBlock + Node->nVirtualBlockSize == NextNode->pVirtualBlock)
+ {
+ /* They are adjacent - merge! */
+ Node->nVirtualBlockSize += NextNode->nVirtualBlockSize;
+
+ /* Remove next entry from the list and put it into unused entries list */
+ RemoveEntryList(&NextNode->AvailableEntry);
+ RtlpDphReturnNodeToUnusedList(DphRoot, NextNode);
+ DphRoot->nAvailableAllocations--;
+ }
}
}
}
@@ -643,10 +726,12 @@
/* Make sure requested size is not too big */
ASSERT(FreeAllocations >= LeaveOnFreeList);
+ DPRINT("RtlpDphCoalesceFreeIntoAvailable(%p %d)\n", DphRoot, LeaveOnFreeList);
+
while (Node)
{
FreeAllocations--;
- if (FreeAllocations <= LeaveOnFreeList) break;
+ if (FreeAllocations < LeaveOnFreeList) break;
/* Get the next pointer, because it may be changed after following two calls */
Next = Node->pNextAlloc;
@@ -657,6 +742,7 @@
/* And put into the available */
RtlpDphCoalesceNodeIntoAvailable(DphRoot, Node);
+ /* Go to the next node */
Node = Next;
}
}
@@ -713,20 +799,21 @@
SIZE_T Size)
{
PLIST_ENTRY CurEntry;
- PDPH_HEAP_BLOCK Node;
+ PDPH_HEAP_BLOCK Node, NodeFound = NULL;
CurEntry = DphRoot->AvailableAllocationHead.Flink;
- while (TRUE)
- {
- /* If we reached end of the list - return right away */
- if (CurEntry == &DphRoot->AvailableAllocationHead) return NULL;
-
+ while (CurEntry != &DphRoot->AvailableAllocationHead)
+ {
/* Get the current available node */
Node = CONTAINING_RECORD(CurEntry, DPH_HEAP_BLOCK, AvailableEntry);
/* Check its size */
- if (Node->nVirtualBlockSize >= Size) break;
+ if (Node->nVirtualBlockSize >= Size)
+ {
+ NodeFound = Node;
+ break;
+ }
/* Move to the next available entry */
CurEntry = CurEntry->Flink;
@@ -736,7 +823,7 @@
//ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Flink));
//ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Blink));
- return Node;
+ return NodeFound;
}
PDPH_HEAP_BLOCK NTAPI
@@ -757,7 +844,7 @@
if (DphRoot->nFreeAllocations <= DPH_FREE_LIST_MINIMUM) break;
/* Calculate a new free list size */
- NewSize = DphRoot->nFreeAllocations >> 1;
+ NewSize = DphRoot->nFreeAllocations >> 2;
if (NewSize < DPH_FREE_LIST_MINIMUM) NewSize = DPH_FREE_LIST_MINIMUM;
/* Coalesce free into available */
@@ -795,6 +882,23 @@
return Node;
}
+PDPH_HEAP_BLOCK NTAPI
+RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot,
+ PVOID pUserMem)
+{
+ PDPH_HEAP_BLOCK Node;
+ PVOID Ptr;
+
+ /* Lookup busy block in AVL */
+ Ptr = RtlLookupElementGenericTableAvl(&DphRoot->BusyNodesTable, &pUserMem);
+ if (!Ptr) return NULL;
+
+ /* Restore pointer to the heap block */
+ Node = CONTAINING_RECORD(Ptr, DPH_HEAP_BLOCK, pUserAllocation);
+ ASSERT(Node->pUserAllocation == pUserMem);
+ return Node;
+}
+
NTSTATUS NTAPI
RtlpDphSetProtectionBeforeUse(PDPH_HEAP_ROOT DphRoot, PUCHAR VirtualBlock, ULONG UserSize)
{
@@ -815,6 +919,20 @@
Protection = PAGE_READWRITE;
return RtlpDphProtectVm(Base, UserSize, Protection);
+}
+
+NTSTATUS NTAPI
+RtlpDphSetProtectionAfterUse(PDPH_HEAP_ROOT DphRoot, /*PUCHAR VirtualBlock*/PDPH_HEAP_BLOCK Node)
+{
+ // FIXME: Bring stuff here
+ if (DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN)
+ {
+ }
+ else
+ {
+ }
+
+ return STATUS_SUCCESS;
}
PDPH_HEAP_BLOCK NTAPI
@@ -1685,8 +1803,91 @@
ULONG Flags,
PVOID Ptr)
{
- UNIMPLEMENTED;
- return FALSE;
+ PDPH_HEAP_ROOT DphRoot;
+ PDPH_HEAP_BLOCK Node;
+ ULONG ValidationInfo;
+ PDPH_BLOCK_INFORMATION Info;
+
+ /* Check for a NULL pointer freeing */
+ if (!HeapPtr)
+ {
+ if (RtlpDphBreakOptions & DPH_BREAK_ON_NULL_FREE)
+ {
+ DPRINT1("Page heap: freeing a null pointer \n");
+ DbgBreakPoint();
+ }
+ return TRUE;
+ }
+
+ /* Get a pointer to the heap root */
+ DphRoot = RtlpDphPointerFromHandle(HeapPtr);
+ if (!DphRoot) return FALSE;
+
+ /* Acquire the heap lock */
+ RtlpDphPreProcessing(DphRoot, Flags);
+
+ /* Perform internal validation if specified by flags */
+ if (RtlpDphDebugOptions & DPH_DEBUG_INTERNAL_VALIDATE)
+ RtlpDphInternalValidatePageHeap(DphRoot, NULL, 0);
+
+ /* Add heap flags */
+ Flags |= DphRoot->HeapFlags;
+
+ /* Find busy memory */
+ Node = RtlpDphFindBusyMemory(DphRoot, Ptr);
+
+ if (!Node)
+ {
+ /* This block was not found in page heap, try a normal heap instead */
+ //RtlpDphNormalHeapFree();
+ ASSERT(FALSE);
+ }
+
+ if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
+ {
+ /* Check and report corrupted block */
+ if (!RtlpDphIsPageHeapBlock(DphRoot, Ptr, &ValidationInfo, TRUE))
+ {
+ RtlpDphReportCorruptedBlock(DphRoot, 1, Ptr, ValidationInfo);
+ }
+
+ // FIXME: Should go inside RtlpDphSetProtectionAfterUse
+ if (Node->nVirtualAccessSize != 0)
+ {
+ /* Set stamps */
+ Info = (PDPH_BLOCK_INFORMATION)Node->pUserAllocation - 1;
+ Info->StartStamp = DPH_FILL_START_STAMP_2;
+ Info->EndStamp = DPH_FILL_END_STAMP_2;
+
+ RtlpDphProtectVm(Node->pVirtualBlock, Node->nVirtualAccessSize, PAGE_NOACCESS);
+ }
+ }
+ else
+ {
+ // FIXME: Should go inside RtlpDphSetProtectionAfterUse
+ if (Node->nVirtualAccessSize != 0)
+ RtlpDphProtectVm(Node->pVirtualBlock + PAGE_SIZE, Node->nVirtualAccessSize, PAGE_NOACCESS);
+ }
+
+ /* Set new protection */
+ RtlpDphSetProtectionAfterUse(DphRoot, Node);
+
+ /* Remove it from the list of busy nodes */
+ RtlpDphRemoveFromBusyList(DphRoot, Node);
+
+ /* And put it into the list of free nodes */
+ RtlpDphPlaceOnFreeList(DphRoot, Node);
+
+ //if (DphRoot->ExtraFlags & DPH_EXTRA_LOG_STACK_TRACES)
+ // Node->StackTrace = RtlpDphLogStackTrace(3);
+ //else
+ Node->StackTrace = NULL;
+
+ /* Leave the heap lock */
+ RtlpDphPostProcessing(DphRoot);
+
+ /* Return success */
+ return TRUE;
}
PVOID NTAPI