On May 12 20:42, Corinna Vinschen wrote:
> I created a test application with several heaps [...]

Btw., here's my test app.  It's ugly but it's just for testing the
results anyway.


Corinna

#include <stdio.h>
#define _WIN32_WINNT 0x0601
#include <windows.h>
#include <ddk/ntddk.h>
#include <ddk/ntapi.h>

typedef struct _MODULES
{
  ULONG count;
  DEBUG_MODULE_INFORMATION dmi[1];
} MODULES, *PMODULES;

typedef struct _HEAPS
{
  ULONG count;
  DEBUG_HEAP_INFORMATION dhi[1];
} HEAPS, *PHEAPS;

typedef struct _HEAP_BLOCK
{
  ULONG size;
  ULONG flags;
  ULONG unknown;
  ULONG addr;
} HEAP_BLOCK, *PHEAP_BLOCK;

#define HEAP_CREATE_ENABLE_EXECUTE 0x40000
int
main ()
{
  PDEBUG_BUFFER buf;
  NTSTATUS status;
  int i;
  HMODULE modules[100];
  DWORD needed = sizeof modules;

  HANDLE h0 = HeapCreate (0, 0, 0);
  ULONG lowfrag = 2;
  if (!HeapSetInformation (h0, HeapCompatibilityInformation,
                           &lowfrag, sizeof lowfrag))
    fprintf (stderr, "HeapSet: %lu\n", GetLastError ());
  printf ("alloc h0: %p %p\n", h0, HeapAlloc (h0, 0, 32));
  HANDLE h1 = HeapCreate (0, 0, 0);
  printf ("alloc h1: %p %p\n", h1, HeapAlloc (h1, 0, 32));
  HANDLE h1b = HeapCreate (0, 0, 65536);
  printf ("alloc h1b: %p %p\n", h1b, HeapAlloc (h1b, 0, 32));
  HANDLE h2 = HeapCreate (HEAP_NO_SERIALIZE, 4096, 4 * 65536);
  printf ("alloc h2: %p %p\n", h2, HeapAlloc (h2, 0, 32));
  HANDLE h3 = HeapCreate (HEAP_GENERATE_EXCEPTIONS, 4096, 8 * 65536);
  printf ("alloc h3: %p %p\n", h3, HeapAlloc (h3, 0, 32));
  HANDLE h4 = HeapCreate (HEAP_CREATE_ENABLE_EXECUTE, 4096, 0);
  printf ("alloc h4: %p %p\n", h4, HeapAlloc (h4, 0, 200000));
  HANDLE h5 = HeapCreate (0, 4096, 0);
  printf ("alloc h5: %p %p\n", h5, HeapAlloc (h5, 0, 2000000));
  buf = RtlCreateQueryDebugBuffer (0, FALSE);
  if (!buf)
    {
      fprintf (stderr, "RtlCreateQueryDebugBuffer returned NULL\n");
      return 1;
    }
  status = RtlQueryProcessDebugInformation (GetCurrentProcessId (),
                                            PDI_MODULES | PDI_HEAPS
                                            | PDI_HEAP_BLOCKS, buf);
  if (!NT_SUCCESS (status))
    {
      fprintf (stderr, "RtlQueryProcessDebugInformation returned 0x%08lx\n", 
status);
      return 1;
    }
#if 0
  PMODULES mods = (PMODULES) buf->ModuleInformation;
  if (!mods)
    fprintf (stderr, "mods is NULL\n");
  else
    {
      for (i = 0; i < mods->count; ++i)
        printf ("%40s Base 0x%08lx, Size %8lu U 0x%08lx\n",
                mods->dmi[i].ImageName,
                mods->dmi[i].Base,
                mods->dmi[i].Size,
                mods->dmi[i].Unknown);
    }
#endif
  PHEAPS heaps = (PHEAPS) buf->HeapInformation;
  if (!heaps)
    fprintf (stderr, "heaps is NULL\n");
  else
    {
      for (i = 0; i < heaps->count; ++i)
        {
          int r;

#if 1
          printf ("%3d: base 0x%08lx, flags 0x%08lx, granularity %5hu, unknown 
%5hu\n"
                  "     allocated %8lu, committed %8lu, block count %lu\n"
                  "     reserved",
                  i,
                  heaps->dhi[i].Base,
                  heaps->dhi[i].Flags,
                  heaps->dhi[i].Granularity,
                  heaps->dhi[i].Unknown,
                  heaps->dhi[i].Allocated,
                  heaps->dhi[i].Committed,
                  heaps->dhi[i].BlockCount);
          for (r = 0; r < 7; ++r)
            printf (" %lu",
                    heaps->dhi[i].Reserved[r],
                    heaps->dhi[i].Reserved[r]);
          puts ("");
#else
          printf ("%3d: base 0x%08lx, flags 0x%08lx\n",
                  i,
                  heaps->dhi[i].Base,
                  heaps->dhi[i].Flags);
#endif
          PHEAP_BLOCK blocks = (PHEAP_BLOCK) heaps->dhi[i].Blocks;
          if (!blocks)
            fprintf (stderr, "blocks is NULL\n");
          else
            {
              uintptr_t addr = 0;
              char flags[32];
              printf ("     Blocks:\n");
              for (r = 0; r < heaps->dhi[i].BlockCount; ++r)
                {
                  flags[0] = '\0';
                  if (blocks[r].flags & 2)
                    {
                      addr = blocks[r].addr;
                      strcpy (flags, "start");
                    }
                  else if (blocks[r].flags & 0x2f1) 
                    strcpy (flags, "fixed");
                  else if (blocks[r].flags & 0x20)
                    strcpy (flags, "moveable");
                  else if (blocks[r].flags & 0x100)
                    strcpy (flags, "free");
                  if (blocks[r].flags & 2)
                    printf ("     %3d: addr 0x%08lx, size %8lu, flags 0x%08lx, "
                            "unknown 0x%08lx\n",
                            r,
                            addr,
                            blocks[r].size,
                            blocks[r].flags,
                            blocks[r].unknown);
#if 0
                  else
                    printf ("     %3d: addr 0x%08lx, size %8lu, "
                            "flags 0x%08x %8s\n",
                            r,
                            addr,
                            blocks[r].size,
                            blocks[r].flags,
                            flags);
#endif
                  if (blocks[r].flags & 2)
                    addr += heaps->dhi[i].Granularity;
                  else
                    addr += blocks[r].size;
                }
            }
        }
    }
  RtlDestroyQueryDebugBuffer (buf);
  getchar ();
  return 0;
}

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Reply via email to