Alexandre Julliard : kernel32/tests: Add tests for the global flag and its influence on the heap flags.
Alexandre Julliard
julliard at winehq.org
Fri Jan 22 08:26:53 CST 2010
Module: wine
Branch: master
Commit: dabda7e3ee6e7710ddb7dca1db94ce7d5fd3fcf1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=dabda7e3ee6e7710ddb7dca1db94ce7d5fd3fcf1
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Jan 22 12:33:24 2010 +0100
kernel32/tests: Add tests for the global flag and its influence on the heap flags.
---
dlls/kernel32/tests/heap.c | 151 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 151 insertions(+), 0 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 56f9744..b213339 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -21,14 +21,25 @@
#include <stdarg.h>
#include <stdlib.h>
+#include <stdio.h>
#include "windef.h"
#include "winbase.h"
+#include "winreg.h"
+#include "winternl.h"
#include "wine/test.h"
#define MAGIC_DEAD 0xdeadbeef
static BOOL (WINAPI *pHeapQueryInformation)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T);
+static ULONG (WINAPI *pRtlGetNtGlobalFlags)(void);
+
+struct heap_layout
+{
+ DWORD unknown[3];
+ DWORD flags;
+ DWORD force_flags;
+};
static SIZE_T resize_9x(SIZE_T size)
{
@@ -467,8 +478,132 @@ static void test_HeapQueryInformation(void)
ok(info == 0 || info == 1 || info == 2, "expected 0, 1 or 2, got %u\n", info);
}
+static void test_debug_heap( const char *argv0, DWORD flags )
+{
+ char keyname[MAX_PATH];
+ char buffer[MAX_PATH];
+ PROCESS_INFORMATION info;
+ STARTUPINFOA startup;
+ BOOL ret;
+ DWORD err;
+ HKEY hkey;
+ const char *basename;
+
+ if ((basename = strrchr( argv0, '\\' ))) basename++;
+ else basename = argv0;
+
+ sprintf( keyname, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%s",
+ basename );
+ if (!strcmp( keyname + strlen(keyname) - 3, ".so" )) keyname[strlen(keyname) - 3] = 0;
+
+ err = RegCreateKeyA( HKEY_LOCAL_MACHINE, keyname, &hkey );
+ ok( !err, "failed to create '%s' error %u\n", keyname, err );
+ if (err) return;
+
+ if (flags == 0xdeadbeef) /* magic value for unsetting it */
+ RegDeleteValueA( hkey, "GlobalFlag" );
+ else
+ RegSetValueExA( hkey, "GlobalFlag", 0, REG_DWORD, (BYTE *)&flags, sizeof(flags) );
+
+ memset( &startup, 0, sizeof(startup) );
+ startup.cb = sizeof(startup);
+
+ sprintf( buffer, "%s heap.c 0x%x", argv0, flags );
+ ret = CreateProcessA( NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info );
+ ok( ret, "failed to create child process error %u\n", GetLastError() );
+ if (ret)
+ {
+ winetest_wait_child_process( info.hProcess );
+ CloseHandle( info.hThread );
+ CloseHandle( info.hProcess );
+ }
+ RegDeleteValueA( hkey, "GlobalFlag" );
+ RegCloseKey( hkey );
+ RegDeleteKeyA( HKEY_LOCAL_MACHINE, keyname );
+}
+
+static DWORD heap_flags_from_global_flag( DWORD flag )
+{
+ DWORD ret = 0;
+
+ if (flag & FLG_HEAP_ENABLE_TAIL_CHECK)
+ ret |= HEAP_TAIL_CHECKING_ENABLED;
+ if (flag & FLG_HEAP_ENABLE_FREE_CHECK)
+ ret |= HEAP_FREE_CHECKING_ENABLED;
+ if (flag & FLG_HEAP_VALIDATE_PARAMETERS)
+ ret |= 0x50000000 | HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED;
+ if (flag & FLG_HEAP_VALIDATE_ALL)
+ ret |= 0x30000000 | HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED;
+ if (flag & FLG_HEAP_DISABLE_COALESCING)
+ ret |= HEAP_DISABLE_COALESCE_ON_FREE;
+ if (flag & FLG_HEAP_PAGE_ALLOCS)
+ ret |= 0x01000000 | HEAP_GROWABLE;
+ return ret;
+}
+
+static void test_child_heap( const char *arg )
+{
+ struct heap_layout *heap = GetProcessHeap();
+ DWORD expected = strtoul( arg, 0, 16 );
+
+ if (expected == 0xdeadbeef) /* expected value comes from Session Manager global flags */
+ {
+ HKEY hkey;
+ expected = 0;
+ if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager", &hkey ))
+ {
+ char buffer[32];
+ DWORD type, size = sizeof(buffer);
+
+ if (!RegQueryValueExA( hkey, "GlobalFlag", 0, &type, (BYTE *)buffer, &size ))
+ {
+ if (type == REG_DWORD) expected = *(DWORD *)buffer;
+ else if (type == REG_SZ) expected = strtoul( buffer, 0, 16 );
+ }
+ RegCloseKey( hkey );
+ }
+ }
+ if (expected && !pRtlGetNtGlobalFlags()) /* not working on NT4 */
+ {
+ win_skip( "global flags not set\n" );
+ return;
+ }
+
+ ok( pRtlGetNtGlobalFlags() == expected,
+ "%s: got global flags %08x expected %08x\n", arg, pRtlGetNtGlobalFlags(), expected );
+
+ if (!(heap->flags & HEAP_GROWABLE) || heap->flags == 0xeeeeeeee) /* vista layout */
+ {
+ if (expected & FLG_HEAP_PAGE_ALLOCS)
+ ok( heap->flags == 0xeeeeeeee, "%s: got heap flags %08x expected 0xeeeeeeee\n",
+ arg, heap->flags );
+ else
+ ok( heap->flags == 0, "%s: got heap flags %08x expected 0\n", arg, heap->flags );
+ }
+ else
+ {
+ expected = heap_flags_from_global_flag( expected );
+ ok( heap->flags == (expected | HEAP_GROWABLE),
+ "%s: got heap flags %08x expected %08x\n", arg, heap->flags, expected );
+ ok( heap->force_flags == (expected & ~0x18000080),
+ "%s: got heap force flags %08x expected %08x\n", arg, heap->force_flags, expected );
+ }
+}
+
START_TEST(heap)
{
+ int argc;
+ char **argv;
+
+ pRtlGetNtGlobalFlags = (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"), "RtlGetNtGlobalFlags" );
+
+ argc = winetest_get_mainargs( &argv );
+ if (argc >= 3)
+ {
+ test_child_heap( argv[2] );
+ return;
+ }
+
test_heap();
test_obsolete_flags();
@@ -480,4 +615,20 @@ START_TEST(heap)
test_sized_HeapReAlloc((1 << 20), (2 << 20));
test_sized_HeapReAlloc((1 << 20), 1);
test_HeapQueryInformation();
+
+ if (pRtlGetNtGlobalFlags)
+ {
+ test_debug_heap( argv[0], 0 );
+ test_debug_heap( argv[0], FLG_HEAP_ENABLE_TAIL_CHECK );
+ test_debug_heap( argv[0], FLG_HEAP_ENABLE_FREE_CHECK );
+ test_debug_heap( argv[0], FLG_HEAP_VALIDATE_PARAMETERS );
+ test_debug_heap( argv[0], FLG_HEAP_VALIDATE_ALL );
+ test_debug_heap( argv[0], FLG_POOL_ENABLE_TAGGING );
+ test_debug_heap( argv[0], FLG_HEAP_ENABLE_TAGGING );
+ test_debug_heap( argv[0], FLG_HEAP_ENABLE_TAG_BY_DLL );
+ test_debug_heap( argv[0], FLG_HEAP_DISABLE_COALESCING );
+ test_debug_heap( argv[0], FLG_HEAP_PAGE_ALLOCS );
+ test_debug_heap( argv[0], 0xdeadbeef );
+ }
+ else win_skip( "RtlGetNtGlobalFlags not found, skipping heap debug tests\n" );
}
More information about the wine-cvs
mailing list