kernel32: Implement HeapQueryInformation, add some basic tests for it.

Dmitry Timoshkov dmitry at codeweavers.com
Mon Oct 12 03:20:57 CDT 2009


---
 dlls/kernel32/heap.c        |    8 ++++++
 dlls/kernel32/kernel32.spec |    2 +-
 dlls/kernel32/tests/heap.c  |   55 +++++++++++++++++++++++++++++++++++++++++++
 dlls/ntdll/heap.c           |   23 ++++++++++++++++++
 dlls/ntdll/ntdll.spec       |    2 +-
 include/winternl.h          |    1 +
 6 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index 93cf545..e85ccc3 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -291,6 +291,14 @@ SIZE_T WINAPI HeapSize( HANDLE heap, DWORD flags, LPCVOID ptr )
     return RtlSizeHeap( heap, flags, ptr );
 }
 
+BOOL WINAPI HeapQueryInformation( HANDLE heap, HEAP_INFORMATION_CLASS info_class,
+                                  PVOID info, SIZE_T size_in, PSIZE_T size_out)
+{
+    NTSTATUS ret = RtlQueryHeapInformation( heap, info_class, info, size_in, size_out );
+    if (ret) SetLastError( RtlNtStatusToDosError(ret) );
+    return !ret;
+}
+
 BOOL WINAPI HeapSetInformation( HANDLE heap, HEAP_INFORMATION_CLASS infoclass, PVOID info, SIZE_T size)
 {
     FIXME("%p %d %p %ld\n", heap, infoclass, info, size );
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index c97aa28..f5df031 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -707,7 +707,7 @@
 @ stub HeapExtend
 @ stdcall HeapFree(long long long) ntdll.RtlFreeHeap
 @ stdcall HeapLock(long)
-# @ stub HeapQueryInformation
+@ stdcall HeapQueryInformation(long long ptr long ptr)
 @ stub HeapQueryTagW
 @ stdcall HeapReAlloc(long long ptr long) ntdll.RtlReAllocateHeap
 @ stub HeapSetFlags
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 19b4106..c59d304 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -28,6 +28,8 @@
 
 #define MAGIC_DEAD 0xdeadbeef
 
+static BOOL (WINAPI *pHeapQueryInformation)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T);
+
 static SIZE_T resize_9x(SIZE_T size)
 {
     DWORD dwSizeAligned = (size + 3) & ~3;
@@ -410,6 +412,58 @@ static void test_obsolete_flags(void)
     }
 }
 
+static void test_HeapQueryInformation(void)
+{
+    ULONG info;
+    SIZE_T size;
+    BOOL ret;
+
+    pHeapQueryInformation = (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "HeapQueryInformation");
+    if (!pHeapQueryInformation)
+    {
+        win_skip("HeapQueryInformation is not available\n");
+        return;
+    }
+
+    if (0) /* crashes under XP */
+    {
+        size = 0;
+        ret = pHeapQueryInformation(0,
+                                HeapCompatibilityInformation,
+                                &info, sizeof(info), &size);
+        size = 0;
+        ret = pHeapQueryInformation(GetProcessHeap(),
+                                HeapCompatibilityInformation,
+                                NULL, sizeof(info), &size);
+    }
+
+    size = 0;
+    SetLastError(0xdeadbeef);
+    ret = pHeapQueryInformation(GetProcessHeap(),
+                                HeapCompatibilityInformation,
+                                NULL, 0, &size);
+    ok(!ret, "HeapQueryInformation should fail\n");
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "expected ERROR_INSUFFICIENT_BUFFER got %u\n", GetLastError());
+    ok(size == sizeof(ULONG), "expected 4, got %lu\n", size);
+
+    SetLastError(0xdeadbeef);
+    ret = pHeapQueryInformation(GetProcessHeap(),
+                                HeapCompatibilityInformation,
+                                NULL, 0, NULL);
+    ok(!ret, "HeapQueryInformation should fail\n");
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "expected ERROR_INSUFFICIENT_BUFFER got %u\n", GetLastError());
+
+    info = 0xdeadbeaf;
+    SetLastError(0xdeadbeef);
+    ret = pHeapQueryInformation(GetProcessHeap(),
+                                HeapCompatibilityInformation,
+                                &info, sizeof(info) + 1, NULL);
+    ok(ret, "HeapQueryInformation error %u\n", GetLastError());
+    ok(info == 0 || info == 1 || info == 2, "expected 0, 1 or 2, got %u\n", info);
+}
+
 START_TEST(heap)
 {
     test_heap();
@@ -422,4 +476,5 @@ START_TEST(heap)
     test_sized_HeapReAlloc(1, (1 << 20));
     test_sized_HeapReAlloc((1 << 20), (2 << 20));
     test_sized_HeapReAlloc((1 << 20), 1);
+    test_HeapQueryInformation();
 }
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 14cac32..adaf693 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -1961,3 +1961,26 @@ ULONG WINAPI RtlGetProcessHeaps( ULONG count, HANDLE *heaps )
     RtlLeaveCriticalSection( &processHeap->critSection );
     return total;
 }
+
+/***********************************************************************
+ *           RtlQueryHeapInformation    (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlQueryHeapInformation( HANDLE heap, HEAP_INFORMATION_CLASS info_class,
+                                         PVOID info, SIZE_T size_in, PSIZE_T size_out)
+{
+    switch (info_class)
+    {
+    case HeapCompatibilityInformation:
+        if (size_out) *size_out = sizeof(ULONG);
+
+        if (size_in < sizeof(ULONG))
+            return STATUS_BUFFER_TOO_SMALL;
+
+        *(ULONG *)info = 0; /* standard heap */
+        return STATUS_SUCCESS;
+
+    default:
+        FIXME("Unknown heap information class %u\n", info_class);
+        return STATUS_INVALID_INFO_CLASS;
+    }
+}
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 8787611..70647d2 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -768,7 +768,7 @@
 @ stdcall RtlQueryAtomInAtomTable(ptr long ptr ptr ptr ptr)
 @ stdcall RtlQueryDepthSList(ptr)
 @ stdcall RtlQueryEnvironmentVariable_U(ptr ptr ptr)
-@ stub RtlQueryHeapInformation
+@ stdcall RtlQueryHeapInformation(long long ptr long ptr)
 @ stdcall RtlQueryInformationAcl(ptr ptr long long)
 @ stdcall RtlQueryInformationActivationContext(long long ptr long ptr long ptr)
 @ stub RtlQueryInformationActiveActivationContext
diff --git a/include/winternl.h b/include/winternl.h
index a6fea7d..a78e9e5 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2412,6 +2412,7 @@ NTSYSAPI BOOLEAN   WINAPI RtlPrefixString(const STRING*,const STRING*,BOOLEAN);
 NTSYSAPI BOOLEAN   WINAPI RtlPrefixUnicodeString(const UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);
 NTSYSAPI NTSTATUS  WINAPI RtlQueryAtomInAtomTable(RTL_ATOM_TABLE,RTL_ATOM,ULONG*,ULONG*,WCHAR*,ULONG*);
 NTSYSAPI NTSTATUS  WINAPI RtlQueryEnvironmentVariable_U(PWSTR,PUNICODE_STRING,PUNICODE_STRING);
+NTSYSAPI NTSTATUS  WINAPI RtlQueryHeapInformation(HANDLE,HEAP_INFORMATION_CLASS,PVOID,SIZE_T,PSIZE_T);
 NTSYSAPI NTSTATUS  WINAPI RtlQueryInformationAcl(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
 NTSYSAPI NTSTATUS  WINAPI RtlQueryInformationActivationContext(ULONG,HANDLE,PVOID,ULONG,PVOID,SIZE_T,SIZE_T*);
 NTSYSAPI NTSTATUS  WINAPI RtlQueryProcessDebugInformation(ULONG,ULONG,PDEBUG_BUFFER);
-- 
1.6.4.2




More information about the wine-patches mailing list