c++ - 如何通过 HANDLE 判断一个堆是否被序列化?

标签 c++ windows multithreading winapi heap-memory

比如说,如果我调用 GetProcessHeaps在我获取它使用的堆列表的过程中。有一个堆 HANDLE 我怎么知道这样的堆是否是用 HEAP_NO_SERIALIZE flag 创建的还是不是?

最佳答案

虽然没有确定的答案,您可以调用HeapQueryInformation(HeapCompatibilityInformation)如果它返回 2 则它被序列化,因为 MSDN 对 HEAP_NO_SERIALIZE 说:

The low-fragmentation heap (LFH) cannot be enabled for a heap created with this option

我不知道是否有未记录的 API 来获取标志,但出于调试目的,您可以直接访问内部堆结构:

void DumpHeapType_Win8_x86(HANDLE hHeap)
{
    typedef struct {
        UINT32 Unknown1[2];
        UINT32 Sig;
        UINT32 Unknown2[1];
        void*Unknown3[2]; //LIST_ENTRY?
        void*Unknown4[1+1+1+1+2];
        UINT32 Unknown5[1+1+1+1];
        UINT32 Flags;
    } HEAP_HDR;
    typedef struct {
        UINT32 Unknown1[2];
        UINT32 Sig;
        UINT32 Unknown2[1];
        void*Unknown3[2]; //LIST_ENTRY?
        HEAP_HDR*pHdr;
    } HEAP_THING;
    HEAP_THING *pThing = (HEAP_THING*) hHeap;
    if (hHeap && pThing->Sig == 0xffeeffee)
    {
        HEAP_HDR *pHdr = (HEAP_HDR*) pThing->pHdr;
        if (pHdr->Sig == 0xffeeffee)
        {
            printf("Flags=%#x Serialized=%d\n", pHdr->Flags, !(pHdr->Flags & HEAP_NO_SERIALIZE));
        }
    }
}

void playwithheaps()
{
    HANDLE hHeap;
    DumpHeapType_Win8_x86(hHeap = GetProcessHeap());
    DumpHeapType_Win8_x86(hHeap = HeapCreate(0, 0, 0)); if (hHeap) HeapDestroy(hHeap);
    DumpHeapType_Win8_x86(hHeap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0)); if (hHeap) HeapDestroy(hHeap);
    DumpHeapType_Win8_x86(hHeap = HeapCreate(HEAP_NO_SERIALIZE|HEAP_GENERATE_EXCEPTIONS, 0, 0)); if (hHeap) HeapDestroy(hHeap);
}

在我的 Windows 8 机器上,这给了我以下输出:

Flags=0x2 Serialized=1
Flags=0x1002 Serialized=1
Flags=0x1003 Serialized=0
Flags=0x1007 Serialized=0

但是堆结构布局在其他版本上可能会有所不同,所以你只需要仔细测试......

关于c++ - 如何通过 HANDLE 判断一个堆是否被序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44339368/

相关文章:

c++ - Qt 框架 : How to display a QGraphicsView in a layout?

windows - 作为 Windows 服务的媒体播放器

c++ - 右值引用是否像左值引用一样工作?

c++ - 如何在c++中设计一个大类的头文件?

c++ - 如何判断是使用 '->'还是 '.'

java - 将唯一引用设置为 null 是否意味着它及其子线程被垃圾收集?

java - unlockCanvasAndPost 中的 IllegalArgumentException(安卓动态壁纸)

java - 线程限制/swingworkers

c++ - 相对标题 XCode 4

windows - 文本编辑器打开大(巨大的,巨大的,大的)文本文件