mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 14:51:28 +00:00
ntdll: Rewrite RtlWalkHeap and enumerate large blocks.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1196b46b29
commit
074177b8b0
|
@ -526,7 +526,6 @@ static void test_HeapCreate(void)
|
|||
rtl_entry.lpData = NULL;
|
||||
SetLastError( 0xdeadbeef );
|
||||
while (!RtlWalkHeap( heap, &rtl_entry )) rtl_entries[count++] = rtl_entry;
|
||||
todo_wine
|
||||
ok( count == 3, "got count %lu\n", count );
|
||||
|
||||
count = 0;
|
||||
|
@ -536,16 +535,13 @@ static void test_HeapCreate(void)
|
|||
SetLastError( 0xdeadbeef );
|
||||
while ((ret = HeapWalk( heap, &entry ))) entries[count++] = entry;
|
||||
ok( GetLastError() == ERROR_NO_MORE_ITEMS, "got error %lu\n", GetLastError() );
|
||||
todo_wine
|
||||
ok( count == 3, "got count %lu\n", count );
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
winetest_push_context( "%Iu", i );
|
||||
ok( rtl_entries[i].lpData == entries[i].lpData, "got lpData %p\n", rtl_entries[i].lpData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbData == entries[i].cbData, "got cbData %#Ix\n", rtl_entries[i].cbData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbOverhead == entries[i].cbOverhead, "got cbOverhead %#x\n", rtl_entries[i].cbOverhead );
|
||||
ok( rtl_entries[i].iRegionIndex == entries[i].iRegionIndex, "got iRegionIndex %#x\n", rtl_entries[i].iRegionIndex );
|
||||
if (!entries[i].wFlags)
|
||||
|
@ -554,11 +550,8 @@ static void test_HeapCreate(void)
|
|||
ok( rtl_entries[i].wFlags == (RTL_HEAP_ENTRY_COMMITTED|RTL_HEAP_ENTRY_BLOCK|RTL_HEAP_ENTRY_BUSY) || broken(rtl_entries[i].wFlags == 0x411) /* win7 */,
|
||||
"got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
else if (entries[i].wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE)
|
||||
{
|
||||
todo_wine
|
||||
ok( rtl_entries[i].wFlags == RTL_HEAP_ENTRY_UNCOMMITTED || broken(rtl_entries[i].wFlags == 0x100) /* win7 */,
|
||||
"got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
}
|
||||
else if (entries[i].wFlags & PROCESS_HEAP_REGION)
|
||||
{
|
||||
ok( rtl_entries[i].wFlags == RTL_HEAP_ENTRY_REGION, "got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
|
@ -574,13 +567,9 @@ static void test_HeapCreate(void)
|
|||
winetest_pop_context();
|
||||
}
|
||||
|
||||
todo_wine
|
||||
ok( entries[0].wFlags == PROCESS_HEAP_REGION, "got wFlags %#x\n", entries[0].wFlags );
|
||||
todo_wine
|
||||
ok( entries[0].lpData == heap, "got lpData %p\n", entries[0].lpData );
|
||||
todo_wine
|
||||
ok( entries[0].cbData <= 0x1000 /* sizeof(*heap) */, "got cbData %#lx\n", entries[0].cbData );
|
||||
todo_wine
|
||||
ok( entries[0].cbOverhead == 0, "got cbOverhead %#x\n", entries[0].cbOverhead );
|
||||
ok( entries[0].iRegionIndex == 0, "got iRegionIndex %d\n", entries[0].iRegionIndex );
|
||||
todo_wine
|
||||
|
@ -594,27 +583,20 @@ static void test_HeapCreate(void)
|
|||
ok( (BYTE *)entries[0].Region.lpFirstBlock == (BYTE *)entries[0].lpData + entries[0].cbData + 2 * sizeof(void *) ||
|
||||
(BYTE *)entries[0].Region.lpFirstBlock == (BYTE *)entries[0].lpData + entries[0].cbData + 4 * sizeof(void *),
|
||||
"got Region.lpFirstBlock %p\n", entries[0].Region.lpFirstBlock );
|
||||
todo_wine
|
||||
ok( entries[0].Region.lpLastBlock == (BYTE *)entries[2].lpData + entries[2].cbData,
|
||||
"got Region.lpLastBlock %p\n", entries[0].Region.lpLastBlock );
|
||||
|
||||
ok( entries[1].wFlags == 0, "got wFlags %#x\n", entries[1].wFlags );
|
||||
todo_wine
|
||||
ok( entries[1].lpData != NULL, "got lpData %p\n", entries[1].lpData );
|
||||
todo_wine
|
||||
ok( entries[1].cbData != 0, "got cbData %#lx\n", entries[1].cbData );
|
||||
todo_wine
|
||||
ok( entries[1].cbOverhead == 4 * sizeof(void *), "got cbOverhead %#x\n", entries[1].cbOverhead );
|
||||
ok( entries[1].iRegionIndex == 0, "got iRegionIndex %d\n", entries[1].iRegionIndex );
|
||||
|
||||
todo_wine
|
||||
ok( entries[2].wFlags == PROCESS_HEAP_UNCOMMITTED_RANGE, "got wFlags %#x\n", entries[2].wFlags );
|
||||
todo_wine
|
||||
ok( entries[2].lpData == (BYTE *)entries[0].lpData + entries[0].Region.dwCommittedSize,
|
||||
"got lpData %p\n", entries[2].lpData );
|
||||
ok( entries[2].lpData == (BYTE *)entries[1].lpData + entries[1].cbData + 2 * entries[1].cbOverhead,
|
||||
"got lpData %p\n", entries[2].lpData );
|
||||
todo_wine
|
||||
ok( entries[2].cbData == entries[0].Region.dwUnCommittedSize - 0x1000 ||
|
||||
entries[2].cbData == entries[0].Region.dwUnCommittedSize /* win7 */,
|
||||
"got cbData %#lx\n", entries[2].cbData );
|
||||
|
@ -630,7 +612,6 @@ static void test_HeapCreate(void)
|
|||
rtl_entry.lpData = NULL;
|
||||
SetLastError( 0xdeadbeef );
|
||||
while (!RtlWalkHeap( heap, &rtl_entry )) rtl_entries[count++] = rtl_entry;
|
||||
todo_wine
|
||||
ok( count == 4, "got count %lu\n", count );
|
||||
|
||||
memmove( entries + 16, entries, 3 * sizeof(entry) );
|
||||
|
@ -640,7 +621,6 @@ static void test_HeapCreate(void)
|
|||
SetLastError( 0xdeadbeef );
|
||||
while ((ret = HeapWalk( heap, &entry ))) entries[count++] = entry;
|
||||
ok( GetLastError() == ERROR_NO_MORE_ITEMS, "got error %lu\n", GetLastError() );
|
||||
todo_wine
|
||||
ok( count == 4, "got count %lu\n", count );
|
||||
ok( !memcmp( entries + 16, entries, 3 * sizeof(entry) ), "entries differ\n" );
|
||||
|
||||
|
@ -648,9 +628,7 @@ static void test_HeapCreate(void)
|
|||
{
|
||||
winetest_push_context( "%Iu", i );
|
||||
ok( rtl_entries[i].lpData == entries[i].lpData, "got lpData %p\n", rtl_entries[i].lpData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbData == entries[i].cbData, "got cbData %#Ix\n", rtl_entries[i].cbData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbOverhead == entries[i].cbOverhead, "got cbOverhead %#x\n", rtl_entries[i].cbOverhead );
|
||||
ok( rtl_entries[i].iRegionIndex == entries[i].iRegionIndex, "got iRegionIndex %#x\n", rtl_entries[i].iRegionIndex );
|
||||
if (!entries[i].wFlags)
|
||||
|
@ -659,11 +637,8 @@ static void test_HeapCreate(void)
|
|||
ok( rtl_entries[i].wFlags == (RTL_HEAP_ENTRY_COMMITTED|RTL_HEAP_ENTRY_BLOCK|RTL_HEAP_ENTRY_BUSY) || broken(rtl_entries[i].wFlags == 0x411) /* win7 */,
|
||||
"got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
else if (entries[i].wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE)
|
||||
{
|
||||
todo_wine
|
||||
ok( rtl_entries[i].wFlags == RTL_HEAP_ENTRY_UNCOMMITTED || broken(rtl_entries[i].wFlags == 0x100) /* win7 */,
|
||||
"got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
}
|
||||
else if (entries[i].wFlags & PROCESS_HEAP_REGION)
|
||||
{
|
||||
ok( rtl_entries[i].wFlags == RTL_HEAP_ENTRY_REGION, "got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
|
@ -679,17 +654,13 @@ static void test_HeapCreate(void)
|
|||
winetest_pop_context();
|
||||
}
|
||||
|
||||
todo_wine
|
||||
ok( entries[3].wFlags == PROCESS_HEAP_ENTRY_BUSY ||
|
||||
broken(entries[3].wFlags == (PROCESS_HEAP_ENTRY_BUSY | PROCESS_HEAP_ENTRY_DDESHARE)) /* win7 */,
|
||||
"got wFlags %#x\n", entries[3].wFlags );
|
||||
todo_wine
|
||||
ok( entries[3].lpData == ptr, "got lpData %p\n", entries[3].lpData );
|
||||
todo_wine
|
||||
ok( entries[3].cbData == 5 * alloc_size, "got cbData %#lx\n", entries[3].cbData );
|
||||
ok( entries[3].cbOverhead == 0 || entries[3].cbOverhead == 8 * sizeof(void *) /* win7 */,
|
||||
"got cbOverhead %#x\n", entries[3].cbOverhead );
|
||||
todo_wine
|
||||
ok( entries[3].iRegionIndex == 64, "got iRegionIndex %d\n", entries[3].iRegionIndex );
|
||||
|
||||
ptr1 = HeapAlloc( heap, HEAP_ZERO_MEMORY, 5 * alloc_size );
|
||||
|
@ -701,7 +672,6 @@ static void test_HeapCreate(void)
|
|||
rtl_entry.lpData = NULL;
|
||||
SetLastError( 0xdeadbeef );
|
||||
while (!RtlWalkHeap( heap, &rtl_entry )) rtl_entries[count++] = rtl_entry;
|
||||
todo_wine
|
||||
ok( count == 5, "got count %lu\n", count );
|
||||
|
||||
memmove( entries + 16, entries, 4 * sizeof(entry) );
|
||||
|
@ -711,7 +681,6 @@ static void test_HeapCreate(void)
|
|||
SetLastError( 0xdeadbeef );
|
||||
while ((ret = HeapWalk( heap, &entry ))) entries[count++] = entry;
|
||||
ok( GetLastError() == ERROR_NO_MORE_ITEMS, "got error %lu\n", GetLastError() );
|
||||
todo_wine
|
||||
ok( count == 5, "got count %lu\n", count );
|
||||
ok( !memcmp( entries + 16, entries, 4 * sizeof(entry) ), "entries differ\n" );
|
||||
|
||||
|
@ -719,9 +688,7 @@ static void test_HeapCreate(void)
|
|||
{
|
||||
winetest_push_context( "%Iu", i );
|
||||
ok( rtl_entries[i].lpData == entries[i].lpData, "got lpData %p\n", rtl_entries[i].lpData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbData == entries[i].cbData, "got cbData %#Ix\n", rtl_entries[i].cbData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbOverhead == entries[i].cbOverhead, "got cbOverhead %#x\n", rtl_entries[i].cbOverhead );
|
||||
ok( rtl_entries[i].iRegionIndex == entries[i].iRegionIndex, "got iRegionIndex %#x\n", rtl_entries[i].iRegionIndex );
|
||||
if (!entries[i].wFlags)
|
||||
|
@ -730,11 +697,8 @@ static void test_HeapCreate(void)
|
|||
ok( rtl_entries[i].wFlags == (RTL_HEAP_ENTRY_COMMITTED|RTL_HEAP_ENTRY_BLOCK|RTL_HEAP_ENTRY_BUSY) || broken(rtl_entries[i].wFlags == 0x411) /* win7 */,
|
||||
"got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
else if (entries[i].wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE)
|
||||
{
|
||||
todo_wine
|
||||
ok( rtl_entries[i].wFlags == RTL_HEAP_ENTRY_UNCOMMITTED || broken(rtl_entries[i].wFlags == 0x100) /* win7 */,
|
||||
"got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
}
|
||||
else if (entries[i].wFlags & PROCESS_HEAP_REGION)
|
||||
{
|
||||
ok( rtl_entries[i].wFlags == RTL_HEAP_ENTRY_REGION, "got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
|
@ -750,17 +714,13 @@ static void test_HeapCreate(void)
|
|||
winetest_pop_context();
|
||||
}
|
||||
|
||||
todo_wine
|
||||
ok( entries[4].wFlags == PROCESS_HEAP_ENTRY_BUSY ||
|
||||
broken(entries[4].wFlags == (PROCESS_HEAP_ENTRY_BUSY | PROCESS_HEAP_ENTRY_DDESHARE)) /* win7 */,
|
||||
"got wFlags %#x\n", entries[4].wFlags );
|
||||
todo_wine
|
||||
ok( entries[4].lpData == ptr1, "got lpData %p\n", entries[4].lpData );
|
||||
todo_wine
|
||||
ok( entries[4].cbData == 5 * alloc_size, "got cbData %#lx\n", entries[4].cbData );
|
||||
ok( entries[4].cbOverhead == 0 || entries[4].cbOverhead == 8 * sizeof(void *) /* win7 */,
|
||||
"got cbOverhead %#x\n", entries[4].cbOverhead );
|
||||
todo_wine
|
||||
ok( entries[4].iRegionIndex == 64, "got iRegionIndex %d\n", entries[4].iRegionIndex );
|
||||
|
||||
ret = HeapFree( heap, 0, ptr1 );
|
||||
|
@ -775,7 +735,6 @@ static void test_HeapCreate(void)
|
|||
SetLastError( 0xdeadbeef );
|
||||
while ((ret = HeapWalk( heap, &entry ))) entries[count++] = entry;
|
||||
ok( GetLastError() == ERROR_NO_MORE_ITEMS, "got error %lu\n", GetLastError() );
|
||||
todo_wine
|
||||
ok( count == 3, "got count %lu\n", count );
|
||||
ok( !memcmp( entries + 16, entries, 3 * sizeof(entry) ), "entries differ\n" );
|
||||
|
||||
|
@ -789,40 +748,28 @@ static void test_HeapCreate(void)
|
|||
SetLastError( 0xdeadbeef );
|
||||
while ((ret = HeapWalk( heap, &entry ))) entries[count++] = entry;
|
||||
ok( GetLastError() == ERROR_NO_MORE_ITEMS, "got error %lu\n", GetLastError() );
|
||||
todo_wine
|
||||
ok( count == 4, "got count %lu\n", count );
|
||||
todo_wine
|
||||
ok( !memcmp( entries + 16, entries, 1 * sizeof(entry) ), "entries differ\n" );
|
||||
todo_wine
|
||||
ok( memcmp( entries + 17, entries + 2, 2 * sizeof(entry) ), "entries differ\n" );
|
||||
|
||||
todo_wine
|
||||
ok( entries[1].wFlags == PROCESS_HEAP_ENTRY_BUSY, "got wFlags %#x\n", entries[1].wFlags );
|
||||
todo_wine
|
||||
ok( entries[1].lpData == ptr, "got lpData %p\n", entries[1].lpData );
|
||||
todo_wine
|
||||
ok( entries[1].cbData == 123, "got cbData %#lx\n", entries[1].cbData );
|
||||
ok( entries[1].cbOverhead != 0, "got cbOverhead %#x\n", entries[1].cbOverhead );
|
||||
ok( entries[1].iRegionIndex == 0, "got iRegionIndex %d\n", entries[1].iRegionIndex );
|
||||
|
||||
ok( entries[2].wFlags == 0, "got wFlags %#x\n", entries[2].wFlags );
|
||||
todo_wine
|
||||
ok( entries[2].lpData == (BYTE *)entries[1].lpData + entries[1].cbData + entries[1].cbOverhead + 2 * sizeof(void *),
|
||||
"got lpData %p\n", entries[2].lpData );
|
||||
todo_wine
|
||||
ok( entries[2].cbData != 0, "got cbData %#lx\n", entries[2].cbData );
|
||||
todo_wine
|
||||
ok( entries[2].cbOverhead == 4 * sizeof(void *), "got cbOverhead %#x\n", entries[2].cbOverhead );
|
||||
ok( entries[2].iRegionIndex == 0, "got iRegionIndex %d\n", entries[2].iRegionIndex );
|
||||
|
||||
todo_wine
|
||||
ok( entries[3].wFlags == PROCESS_HEAP_UNCOMMITTED_RANGE, "got wFlags %#x\n", entries[3].wFlags );
|
||||
todo_wine
|
||||
ok( entries[3].lpData == (BYTE *)entries[0].lpData + entries[0].Region.dwCommittedSize,
|
||||
"got lpData %p\n", entries[3].lpData );
|
||||
ok( entries[3].lpData == (BYTE *)entries[2].lpData + entries[2].cbData + 2 * entries[2].cbOverhead,
|
||||
"got lpData %p\n", entries[3].lpData );
|
||||
todo_wine
|
||||
ok( entries[3].cbData == entries[0].Region.dwUnCommittedSize - 0x1000 ||
|
||||
entries[3].cbData == entries[0].Region.dwUnCommittedSize /* win7 */,
|
||||
"got cbData %#lx\n", entries[3].cbData );
|
||||
|
@ -839,40 +786,28 @@ static void test_HeapCreate(void)
|
|||
SetLastError( 0xdeadbeef );
|
||||
while ((ret = HeapWalk( heap, &entry ))) entries[count++] = entry;
|
||||
ok( GetLastError() == ERROR_NO_MORE_ITEMS, "got error %lu\n", GetLastError() );
|
||||
todo_wine
|
||||
ok( count == 5, "got count %lu\n", count );
|
||||
todo_wine
|
||||
ok( !memcmp( entries + 16, entries, 2 * sizeof(entry) ), "entries differ\n" );
|
||||
todo_wine
|
||||
ok( memcmp( entries + 18, entries + 3, 2 * sizeof(entry) ), "entries differ\n" );
|
||||
|
||||
todo_wine
|
||||
ok( entries[2].wFlags == PROCESS_HEAP_ENTRY_BUSY, "got wFlags %#x\n", entries[2].wFlags );
|
||||
todo_wine
|
||||
ok( entries[2].lpData == ptr1, "got lpData %p\n", entries[2].lpData );
|
||||
todo_wine
|
||||
ok( entries[2].cbData == 456, "got cbData %#lx\n", entries[2].cbData );
|
||||
ok( entries[2].cbOverhead != 0, "got cbOverhead %#x\n", entries[2].cbOverhead );
|
||||
ok( entries[2].iRegionIndex == 0, "got iRegionIndex %d\n", entries[2].iRegionIndex );
|
||||
|
||||
ok( entries[3].wFlags == 0, "got wFlags %#x\n", entries[3].wFlags );
|
||||
todo_wine
|
||||
ok( entries[3].lpData == (BYTE *)entries[2].lpData + entries[2].cbData + entries[2].cbOverhead + 2 * sizeof(void *),
|
||||
"got lpData %p\n", entries[3].lpData );
|
||||
todo_wine
|
||||
ok( entries[3].cbData != 0, "got cbData %#lx\n", entries[3].cbData );
|
||||
todo_wine
|
||||
ok( entries[3].cbOverhead == 4 * sizeof(void *), "got cbOverhead %#x\n", entries[3].cbOverhead );
|
||||
ok( entries[3].iRegionIndex == 0, "got iRegionIndex %d\n", entries[3].iRegionIndex );
|
||||
|
||||
todo_wine
|
||||
ok( entries[4].wFlags == PROCESS_HEAP_UNCOMMITTED_RANGE, "got wFlags %#x\n", entries[4].wFlags );
|
||||
todo_wine
|
||||
ok( entries[4].lpData == (BYTE *)entries[0].lpData + entries[0].Region.dwCommittedSize,
|
||||
"got lpData %p\n", entries[4].lpData );
|
||||
ok( entries[4].lpData == (BYTE *)entries[3].lpData + entries[3].cbData + 2 * entries[3].cbOverhead,
|
||||
"got lpData %p\n", entries[4].lpData );
|
||||
todo_wine
|
||||
ok( entries[4].cbData == entries[0].Region.dwUnCommittedSize - 0x1000 ||
|
||||
entries[4].cbData == entries[0].Region.dwUnCommittedSize /* win7 */,
|
||||
"got cbData %#lx\n", entries[4].cbData );
|
||||
|
@ -1004,21 +939,14 @@ static void test_HeapCreate(void)
|
|||
SetLastError( 0xdeadbeef );
|
||||
while ((ret = HeapWalk( heap, &entry ))) entries[count++] = entry;
|
||||
ok( GetLastError() == ERROR_NO_MORE_ITEMS, "got error %lu\n", GetLastError() );
|
||||
todo_wine
|
||||
ok( count == 3, "got count %lu\n", count );
|
||||
|
||||
todo_wine
|
||||
ok( entries[0].wFlags == PROCESS_HEAP_REGION, "got wFlags %#x\n", entries[0].wFlags );
|
||||
todo_wine
|
||||
ok( entries[0].lpData == heap, "got lpData %p\n", entries[0].lpData );
|
||||
todo_wine
|
||||
ok( entries[0].cbData <= 0x1000 /* sizeof(*heap) */, "got cbData %#lx\n", entries[0].cbData );
|
||||
todo_wine
|
||||
ok( entries[0].cbOverhead == 0, "got cbOverhead %#x\n", entries[0].cbOverhead );
|
||||
ok( entries[0].iRegionIndex == 0, "got iRegionIndex %d\n", entries[0].iRegionIndex );
|
||||
todo_wine
|
||||
ok( entries[1].wFlags == 0, "got wFlags %#x\n", entries[1].wFlags );
|
||||
todo_wine
|
||||
ok( entries[2].wFlags == PROCESS_HEAP_UNCOMMITTED_RANGE, "got wFlags %#x\n", entries[2].wFlags );
|
||||
|
||||
for (i = 0; i < 0x12; i++) ptrs[i] = pHeapAlloc( heap, 0, 24 + 2 * sizeof(void *) );
|
||||
|
@ -1035,16 +963,11 @@ static void test_HeapCreate(void)
|
|||
ok( count > 24, "got count %lu\n", count );
|
||||
if (count < 2) count = 2;
|
||||
|
||||
todo_wine
|
||||
ok( entries[0].wFlags == PROCESS_HEAP_REGION, "got wFlags %#x\n", entries[0].wFlags );
|
||||
todo_wine
|
||||
ok( entries[0].lpData == heap, "got lpData %p\n", entries[0].lpData );
|
||||
todo_wine
|
||||
ok( entries[0].cbData <= 0x1000 /* sizeof(*heap) */, "got cbData %#lx\n", entries[0].cbData );
|
||||
todo_wine
|
||||
ok( entries[0].cbOverhead == 0, "got cbOverhead %#x\n", entries[0].cbOverhead );
|
||||
ok( entries[0].iRegionIndex == 0, "got iRegionIndex %d\n", entries[0].iRegionIndex );
|
||||
todo_wine
|
||||
ok( entries[1].wFlags == 0, "got wFlags %#x\n", entries[1].wFlags );
|
||||
|
||||
for (i = 0; i < 0x12; i++)
|
||||
|
@ -1060,10 +983,7 @@ static void test_HeapCreate(void)
|
|||
if (entries[count - 1].wFlags == PROCESS_HEAP_REGION) /* > win7 */
|
||||
ok( entries[count - 2].wFlags == PROCESS_HEAP_UNCOMMITTED_RANGE, "got wFlags %#x\n", entries[count - 2].wFlags );
|
||||
else
|
||||
{
|
||||
todo_wine
|
||||
ok( entries[count - 1].wFlags == PROCESS_HEAP_UNCOMMITTED_RANGE, "got wFlags %#x\n", entries[count - 2].wFlags );
|
||||
}
|
||||
|
||||
count = 0;
|
||||
memset( &rtl_entries, 0, sizeof(rtl_entries) );
|
||||
|
@ -1079,9 +999,7 @@ static void test_HeapCreate(void)
|
|||
{
|
||||
winetest_push_context( "%Iu", i );
|
||||
ok( rtl_entries[i].lpData == entries[i].lpData, "got lpData %p\n", rtl_entries[i].lpData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbData == entries[i].cbData, "got cbData %#Ix\n", rtl_entries[i].cbData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbOverhead == entries[i].cbOverhead, "got cbOverhead %#x\n", rtl_entries[i].cbOverhead );
|
||||
ok( rtl_entries[i].iRegionIndex == entries[i].iRegionIndex, "got iRegionIndex %#x\n", rtl_entries[i].iRegionIndex );
|
||||
if (!entries[i].wFlags)
|
||||
|
@ -1120,12 +1038,9 @@ static void test_HeapCreate(void)
|
|||
ok( count > 24, "got count %lu\n", count );
|
||||
if (count < 2) count = 2;
|
||||
|
||||
todo_wine
|
||||
ok( entries[0].wFlags == PROCESS_HEAP_REGION, "got wFlags %#x\n", entries[0].wFlags );
|
||||
todo_wine
|
||||
ok( entries[0].lpData == heap, "got lpData %p\n", entries[0].lpData );
|
||||
ok( entries[0].cbData <= 0x1000 /* sizeof(*heap) */, "got cbData %#lx\n", entries[0].cbData );
|
||||
todo_wine
|
||||
ok( entries[0].cbOverhead == 0, "got cbOverhead %#x\n", entries[0].cbOverhead );
|
||||
ok( entries[0].iRegionIndex == 0, "got iRegionIndex %d\n", entries[0].iRegionIndex );
|
||||
ok( entries[1].wFlags == 0 || entries[1].wFlags == PROCESS_HEAP_ENTRY_BUSY /* win7 */, "got wFlags %#x\n", entries[1].wFlags );
|
||||
|
@ -1133,8 +1048,8 @@ static void test_HeapCreate(void)
|
|||
for (i = 1; i < count - 2; i++)
|
||||
{
|
||||
if (entries[i].wFlags != PROCESS_HEAP_ENTRY_BUSY) continue;
|
||||
todo_wine_if( sizeof(void *) == 8 )
|
||||
ok( entries[i].cbData == 0x18 + 2 * sizeof(void *), "got cbData %#lx\n", entries[i].cbData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( entries[i].cbOverhead == 0x8, "got cbOverhead %#x\n", entries[i].cbOverhead );
|
||||
}
|
||||
|
||||
|
@ -1157,9 +1072,7 @@ static void test_HeapCreate(void)
|
|||
{
|
||||
winetest_push_context( "%Iu", i );
|
||||
ok( rtl_entries[i].lpData == entries[i].lpData, "got lpData %p\n", rtl_entries[i].lpData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbData == entries[i].cbData, "got cbData %#Ix\n", rtl_entries[i].cbData );
|
||||
todo_wine_if(sizeof(void *) == 8)
|
||||
ok( rtl_entries[i].cbOverhead == entries[i].cbOverhead, "got cbOverhead %#x\n", rtl_entries[i].cbOverhead );
|
||||
ok( rtl_entries[i].iRegionIndex == entries[i].iRegionIndex, "got iRegionIndex %#x\n", rtl_entries[i].iRegionIndex );
|
||||
if (!entries[i].wFlags)
|
||||
|
@ -1171,11 +1084,8 @@ static void test_HeapCreate(void)
|
|||
"got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
}
|
||||
else if (entries[i].wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE)
|
||||
{
|
||||
todo_wine
|
||||
ok( rtl_entries[i].wFlags == RTL_HEAP_ENTRY_UNCOMMITTED || broken(rtl_entries[i].wFlags == 0x100) /* win7 */,
|
||||
"got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
}
|
||||
else if (entries[i].wFlags & PROCESS_HEAP_REGION)
|
||||
{
|
||||
ok( rtl_entries[i].wFlags == (RTL_HEAP_ENTRY_LFH|RTL_HEAP_ENTRY_REGION), "got wFlags %#x\n", rtl_entries[i].wFlags );
|
||||
|
|
|
@ -601,12 +601,67 @@ BOOL WINAPI DECLSPEC_HOTPATCH HeapValidate( HANDLE heap, DWORD flags, LPCVOID pt
|
|||
}
|
||||
|
||||
|
||||
/* undocumented RtlWalkHeap structure */
|
||||
|
||||
struct rtl_heap_entry
|
||||
{
|
||||
LPVOID lpData;
|
||||
SIZE_T cbData; /* differs from PROCESS_HEAP_ENTRY */
|
||||
BYTE cbOverhead;
|
||||
BYTE iRegionIndex;
|
||||
WORD wFlags; /* value differs from PROCESS_HEAP_ENTRY */
|
||||
union {
|
||||
struct {
|
||||
HANDLE hMem;
|
||||
DWORD dwReserved[3];
|
||||
} Block;
|
||||
struct {
|
||||
DWORD dwCommittedSize;
|
||||
DWORD dwUnCommittedSize;
|
||||
LPVOID lpFirstBlock;
|
||||
LPVOID lpLastBlock;
|
||||
} Region;
|
||||
};
|
||||
};
|
||||
|
||||
/* rtl_heap_entry flags, names made up */
|
||||
|
||||
#define RTL_HEAP_ENTRY_BUSY 0x0001
|
||||
#define RTL_HEAP_ENTRY_REGION 0x0002
|
||||
#define RTL_HEAP_ENTRY_BLOCK 0x0010
|
||||
#define RTL_HEAP_ENTRY_UNCOMMITTED 0x1000
|
||||
#define RTL_HEAP_ENTRY_COMMITTED 0x4000
|
||||
#define RTL_HEAP_ENTRY_LFH 0x8000
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* HeapWalk (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH HeapWalk( HANDLE heap, PROCESS_HEAP_ENTRY *entry )
|
||||
{
|
||||
return set_ntstatus( RtlWalkHeap( heap, entry ));
|
||||
struct rtl_heap_entry rtl_entry = {.lpData = entry->lpData};
|
||||
NTSTATUS status;
|
||||
|
||||
if (!(status = RtlWalkHeap( heap, &rtl_entry )))
|
||||
{
|
||||
entry->lpData = rtl_entry.lpData;
|
||||
entry->cbData = rtl_entry.cbData;
|
||||
entry->cbOverhead = rtl_entry.cbOverhead;
|
||||
entry->iRegionIndex = rtl_entry.iRegionIndex;
|
||||
|
||||
if (rtl_entry.wFlags & RTL_HEAP_ENTRY_BUSY)
|
||||
entry->wFlags = PROCESS_HEAP_ENTRY_BUSY;
|
||||
else if (rtl_entry.wFlags & RTL_HEAP_ENTRY_REGION)
|
||||
entry->wFlags = PROCESS_HEAP_REGION;
|
||||
else if (rtl_entry.wFlags & RTL_HEAP_ENTRY_UNCOMMITTED)
|
||||
entry->wFlags = PROCESS_HEAP_UNCOMMITTED_RANGE;
|
||||
else
|
||||
entry->wFlags = 0;
|
||||
|
||||
memcpy( &entry->u.Region, &rtl_entry.Region, sizeof(entry->u.Region) );
|
||||
}
|
||||
|
||||
return set_ntstatus( status );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,6 +39,39 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(heap);
|
||||
|
||||
/* undocumented RtlWalkHeap structure */
|
||||
|
||||
struct rtl_heap_entry
|
||||
{
|
||||
LPVOID lpData;
|
||||
SIZE_T cbData; /* differs from PROCESS_HEAP_ENTRY */
|
||||
BYTE cbOverhead;
|
||||
BYTE iRegionIndex;
|
||||
WORD wFlags; /* value differs from PROCESS_HEAP_ENTRY */
|
||||
union {
|
||||
struct {
|
||||
HANDLE hMem;
|
||||
DWORD dwReserved[3];
|
||||
} Block;
|
||||
struct {
|
||||
DWORD dwCommittedSize;
|
||||
DWORD dwUnCommittedSize;
|
||||
LPVOID lpFirstBlock;
|
||||
LPVOID lpLastBlock;
|
||||
} Region;
|
||||
};
|
||||
};
|
||||
|
||||
/* rtl_heap_entry flags, names made up */
|
||||
|
||||
#define RTL_HEAP_ENTRY_BUSY 0x0001
|
||||
#define RTL_HEAP_ENTRY_REGION 0x0002
|
||||
#define RTL_HEAP_ENTRY_BLOCK 0x0010
|
||||
#define RTL_HEAP_ENTRY_UNCOMMITTED 0x1000
|
||||
#define RTL_HEAP_ENTRY_COMMITTED 0x4000
|
||||
#define RTL_HEAP_ENTRY_LFH 0x8000
|
||||
|
||||
|
||||
/* header for heap blocks */
|
||||
|
||||
typedef struct block
|
||||
|
@ -517,46 +550,13 @@ static void heap_dump( const HEAP *heap )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void HEAP_DumpEntry( LPPROCESS_HEAP_ENTRY entry )
|
||||
static const char *debugstr_heap_entry( struct rtl_heap_entry *entry )
|
||||
{
|
||||
WORD rem_flags;
|
||||
TRACE( "Dumping entry %p\n", entry );
|
||||
TRACE( "lpData\t\t: %p\n", entry->lpData );
|
||||
TRACE( "cbData\t\t: %08x\n", entry->cbData);
|
||||
TRACE( "cbOverhead\t: %08x\n", entry->cbOverhead);
|
||||
TRACE( "iRegionIndex\t: %08x\n", entry->iRegionIndex);
|
||||
TRACE( "WFlags\t\t: ");
|
||||
if (entry->wFlags & PROCESS_HEAP_REGION)
|
||||
TRACE( "PROCESS_HEAP_REGION ");
|
||||
if (entry->wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE)
|
||||
TRACE( "PROCESS_HEAP_UNCOMMITTED_RANGE ");
|
||||
if (entry->wFlags & PROCESS_HEAP_ENTRY_BUSY)
|
||||
TRACE( "PROCESS_HEAP_ENTRY_BUSY ");
|
||||
if (entry->wFlags & PROCESS_HEAP_ENTRY_MOVEABLE)
|
||||
TRACE( "PROCESS_HEAP_ENTRY_MOVEABLE ");
|
||||
if (entry->wFlags & PROCESS_HEAP_ENTRY_DDESHARE)
|
||||
TRACE( "PROCESS_HEAP_ENTRY_DDESHARE ");
|
||||
rem_flags = entry->wFlags &
|
||||
~(PROCESS_HEAP_REGION | PROCESS_HEAP_UNCOMMITTED_RANGE |
|
||||
PROCESS_HEAP_ENTRY_BUSY | PROCESS_HEAP_ENTRY_MOVEABLE|
|
||||
PROCESS_HEAP_ENTRY_DDESHARE);
|
||||
if (rem_flags)
|
||||
TRACE( "Unknown %08x", rem_flags);
|
||||
TRACE( "\n");
|
||||
if ((entry->wFlags & PROCESS_HEAP_ENTRY_BUSY )
|
||||
&& (entry->wFlags & PROCESS_HEAP_ENTRY_MOVEABLE))
|
||||
{
|
||||
/* Treat as block */
|
||||
TRACE( "BLOCK->hMem\t\t:%p\n", entry->u.Block.hMem);
|
||||
}
|
||||
if (entry->wFlags & PROCESS_HEAP_REGION)
|
||||
{
|
||||
TRACE( "Region.dwCommittedSize\t:%08x\n",entry->u.Region.dwCommittedSize);
|
||||
TRACE( "Region.dwUnCommittedSize\t:%08x\n",entry->u.Region.dwUnCommittedSize);
|
||||
TRACE( "Region.lpFirstBlock\t:%p\n",entry->u.Region.lpFirstBlock);
|
||||
TRACE( "Region.lpLastBlock\t:%p\n",entry->u.Region.lpLastBlock);
|
||||
}
|
||||
const char *str = wine_dbg_sprintf( "data %p, size %#Ix, overhead %#x, region %#x, flags %#x", entry->lpData,
|
||||
entry->cbData, entry->cbOverhead, entry->iRegionIndex, entry->wFlags );
|
||||
if (!(entry->wFlags & RTL_HEAP_ENTRY_REGION)) return str;
|
||||
return wine_dbg_sprintf( "%s, commit %#x, uncommit %#x, first %p, last %p", str, entry->Region.dwCommittedSize,
|
||||
entry->Region.dwUnCommittedSize, entry->Region.lpFirstBlock, entry->Region.lpLastBlock );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -916,7 +916,7 @@ static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T siz
|
|||
/***********************************************************************
|
||||
* find_large_block
|
||||
*/
|
||||
static ARENA_LARGE *find_large_block( HEAP *heap, const void *ptr )
|
||||
static ARENA_LARGE *find_large_block( const HEAP *heap, const void *ptr )
|
||||
{
|
||||
ARENA_LARGE *arena;
|
||||
|
||||
|
@ -2120,131 +2120,123 @@ BOOLEAN WINAPI RtlValidateHeap( HANDLE heap, ULONG flags, const void *ptr )
|
|||
}
|
||||
|
||||
|
||||
static NTSTATUS heap_walk_blocks( const HEAP *heap, const SUBHEAP *subheap, struct rtl_heap_entry *entry )
|
||||
{
|
||||
const char *base = subheap_base( subheap ), *commit_end = subheap_commit_end( subheap ), *end = base + subheap_size( subheap );
|
||||
const struct block *block, *blocks = first_block( subheap );
|
||||
|
||||
if (entry->lpData == commit_end) return STATUS_NO_MORE_ENTRIES;
|
||||
|
||||
if (entry->lpData == base) block = blocks;
|
||||
else if (!(block = next_block( subheap, (struct block *)entry->lpData - 1 )))
|
||||
{
|
||||
entry->lpData = (void *)commit_end;
|
||||
entry->cbData = end - commit_end;
|
||||
entry->cbOverhead = 0;
|
||||
entry->iRegionIndex = 0;
|
||||
entry->wFlags = RTL_HEAP_ENTRY_UNCOMMITTED;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (block_get_flags( block ) & ARENA_FLAG_FREE)
|
||||
{
|
||||
entry->lpData = (char *)block + block_get_overhead( block );
|
||||
entry->cbData = block_get_size( block ) - block_get_overhead( block );
|
||||
/* FIXME: last free block should not include uncommitted range, which also has its own overhead */
|
||||
if (!contains( blocks, commit_end - (char *)blocks, block, block_get_size( block ) ))
|
||||
entry->cbData = commit_end - (char *)entry->lpData - 8 * sizeof(void *);
|
||||
entry->cbOverhead = 4 * sizeof(void *);
|
||||
entry->iRegionIndex = 0;
|
||||
entry->wFlags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->lpData = (void *)(block + 1);
|
||||
entry->cbData = block_get_size( block ) - block_get_overhead( block );
|
||||
entry->cbOverhead = block_get_overhead( block );
|
||||
entry->iRegionIndex = 0;
|
||||
entry->wFlags = RTL_HEAP_ENTRY_COMMITTED|RTL_HEAP_ENTRY_BLOCK|RTL_HEAP_ENTRY_BUSY;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS heap_walk( const HEAP *heap, struct rtl_heap_entry *entry )
|
||||
{
|
||||
const ARENA_LARGE *large;
|
||||
const struct list *next;
|
||||
const SUBHEAP *subheap;
|
||||
NTSTATUS status;
|
||||
char *base;
|
||||
|
||||
if ((large = find_large_block( heap, entry->lpData )))
|
||||
next = &large->entry;
|
||||
else if ((subheap = find_subheap( heap, entry->lpData )))
|
||||
{
|
||||
if (!(status = heap_walk_blocks( heap, subheap, entry ))) return STATUS_SUCCESS;
|
||||
else if (status != STATUS_NO_MORE_ENTRIES) return status;
|
||||
next = &subheap->entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entry->lpData) return STATUS_INVALID_PARAMETER;
|
||||
next = &heap->subheap_list;
|
||||
}
|
||||
|
||||
if (!large && (next = list_next( &heap->subheap_list, next )))
|
||||
{
|
||||
subheap = LIST_ENTRY( next, SUBHEAP, entry );
|
||||
base = subheap_base( subheap );
|
||||
entry->lpData = base;
|
||||
entry->cbData = (char *)first_block( subheap ) - base;
|
||||
entry->cbOverhead = 0;
|
||||
entry->iRegionIndex = 0;
|
||||
entry->wFlags = RTL_HEAP_ENTRY_REGION;
|
||||
entry->Region.dwCommittedSize = (char *)subheap_commit_end( subheap ) - base;
|
||||
entry->Region.dwUnCommittedSize = subheap_size( subheap ) - entry->Region.dwCommittedSize;
|
||||
entry->Region.lpFirstBlock = base + entry->cbData;
|
||||
entry->Region.lpLastBlock = base + subheap_size( subheap );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!next) next = &heap->large_list;
|
||||
if ((next = list_next( &heap->large_list, next )))
|
||||
{
|
||||
large = LIST_ENTRY( next, ARENA_LARGE, entry );
|
||||
entry->lpData = (void *)(large + 1);
|
||||
entry->cbData = large->data_size;
|
||||
entry->cbOverhead = 0;
|
||||
entry->iRegionIndex = 64;
|
||||
entry->wFlags = RTL_HEAP_ENTRY_COMMITTED|RTL_HEAP_ENTRY_BLOCK|RTL_HEAP_ENTRY_BUSY;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlWalkHeap (NTDLL.@)
|
||||
*
|
||||
* FIXME
|
||||
* The PROCESS_HEAP_ENTRY flag values seem different between this
|
||||
* function and HeapWalk(). To be checked.
|
||||
*/
|
||||
NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr )
|
||||
NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, void *entry_ptr )
|
||||
{
|
||||
LPPROCESS_HEAP_ENTRY entry = entry_ptr; /* FIXME */
|
||||
HEAP *heapPtr = HEAP_GetPtr(heap);
|
||||
SUBHEAP *sub, *currentheap = NULL;
|
||||
NTSTATUS ret;
|
||||
char *ptr;
|
||||
int region_index = 0;
|
||||
struct rtl_heap_entry *entry = entry_ptr;
|
||||
NTSTATUS status;
|
||||
HEAP *heapPtr;
|
||||
|
||||
if (!heapPtr || !entry) return STATUS_INVALID_PARAMETER;
|
||||
if (!entry) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
heap_lock( heapPtr, 0 );
|
||||
|
||||
/* FIXME: enumerate large blocks too */
|
||||
|
||||
/* set ptr to the next arena to be examined */
|
||||
|
||||
if (!entry->lpData) /* first call (init) ? */
|
||||
{
|
||||
TRACE("begin walking of heap %p.\n", heap);
|
||||
currentheap = &heapPtr->subheap;
|
||||
ptr = (char*)currentheap->base + currentheap->headerSize;
|
||||
}
|
||||
if (!(heapPtr = HEAP_GetPtr(heap)))
|
||||
status = STATUS_INVALID_HANDLE;
|
||||
else
|
||||
{
|
||||
ptr = entry->lpData;
|
||||
LIST_FOR_EACH_ENTRY( sub, &heapPtr->subheap_list, SUBHEAP, entry )
|
||||
{
|
||||
if ((ptr >= (char *)sub->base) &&
|
||||
(ptr < (char *)sub->base + sub->size))
|
||||
{
|
||||
currentheap = sub;
|
||||
break;
|
||||
}
|
||||
region_index++;
|
||||
}
|
||||
if (currentheap == NULL)
|
||||
{
|
||||
ERR("no matching subheap found, shouldn't happen !\n");
|
||||
ret = STATUS_NO_MORE_ENTRIES;
|
||||
goto HW_end;
|
||||
}
|
||||
|
||||
if (((ARENA_INUSE *)ptr - 1)->magic == ARENA_INUSE_MAGIC ||
|
||||
((ARENA_INUSE *)ptr - 1)->magic == ARENA_PENDING_MAGIC)
|
||||
{
|
||||
ARENA_INUSE *pArena = (ARENA_INUSE *)ptr - 1;
|
||||
ptr += pArena->size & ARENA_SIZE_MASK;
|
||||
}
|
||||
else if (((ARENA_FREE *)ptr - 1)->magic == ARENA_FREE_MAGIC)
|
||||
{
|
||||
ARENA_FREE *pArena = (ARENA_FREE *)ptr - 1;
|
||||
ptr += pArena->size & ARENA_SIZE_MASK;
|
||||
}
|
||||
else
|
||||
ptr += entry->cbData; /* point to next arena */
|
||||
|
||||
if (ptr > (char *)currentheap->base + currentheap->size - 1)
|
||||
{ /* proceed with next subheap */
|
||||
struct list *next = list_next( &heapPtr->subheap_list, ¤theap->entry );
|
||||
if (!next)
|
||||
{ /* successfully finished */
|
||||
TRACE("end reached.\n");
|
||||
ret = STATUS_NO_MORE_ENTRIES;
|
||||
goto HW_end;
|
||||
}
|
||||
currentheap = LIST_ENTRY( next, SUBHEAP, entry );
|
||||
ptr = (char *)currentheap->base + currentheap->headerSize;
|
||||
}
|
||||
heap_lock( heapPtr, 0 );
|
||||
status = heap_walk( heapPtr, entry );
|
||||
heap_unlock( heapPtr, 0 );
|
||||
}
|
||||
|
||||
entry->wFlags = 0;
|
||||
if (*(DWORD *)ptr & ARENA_FLAG_FREE)
|
||||
{
|
||||
ARENA_FREE *pArena = (ARENA_FREE *)ptr;
|
||||
|
||||
/*TRACE("free, magic: %04x\n", pArena->magic);*/
|
||||
|
||||
entry->lpData = pArena + 1;
|
||||
entry->cbData = pArena->size & ARENA_SIZE_MASK;
|
||||
entry->cbOverhead = sizeof(ARENA_FREE);
|
||||
entry->wFlags = PROCESS_HEAP_UNCOMMITTED_RANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ARENA_INUSE *pArena = (ARENA_INUSE *)ptr;
|
||||
|
||||
/*TRACE("busy, magic: %04x\n", pArena->magic);*/
|
||||
|
||||
entry->lpData = pArena + 1;
|
||||
entry->cbData = pArena->size & ARENA_SIZE_MASK;
|
||||
entry->cbOverhead = sizeof(ARENA_INUSE);
|
||||
entry->wFlags = (pArena->magic == ARENA_PENDING_MAGIC) ?
|
||||
PROCESS_HEAP_UNCOMMITTED_RANGE : PROCESS_HEAP_ENTRY_BUSY;
|
||||
/* FIXME: can't handle PROCESS_HEAP_ENTRY_MOVEABLE
|
||||
and PROCESS_HEAP_ENTRY_DDESHARE yet */
|
||||
}
|
||||
|
||||
entry->iRegionIndex = region_index;
|
||||
|
||||
/* first element of heap ? */
|
||||
if (ptr == (char *)currentheap->base + currentheap->headerSize)
|
||||
{
|
||||
entry->wFlags |= PROCESS_HEAP_REGION;
|
||||
entry->u.Region.dwCommittedSize = currentheap->commitSize;
|
||||
entry->u.Region.dwUnCommittedSize =
|
||||
currentheap->size - currentheap->commitSize;
|
||||
entry->u.Region.lpFirstBlock = /* first valid block */
|
||||
(char *)currentheap->base + currentheap->headerSize;
|
||||
entry->u.Region.lpLastBlock = /* first invalid block */
|
||||
(char *)currentheap->base + currentheap->size;
|
||||
}
|
||||
ret = STATUS_SUCCESS;
|
||||
if (TRACE_ON(heap)) HEAP_DumpEntry(entry);
|
||||
|
||||
HW_end:
|
||||
heap_unlock( heapPtr, 0 );
|
||||
return ret;
|
||||
TRACE( "heap %p, entry %p %s, return %#x\n", heap, entry,
|
||||
status ? "<empty>" : debugstr_heap_entry(entry), status );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue