Do not print a skip message for every page.
[wincetools.git] / dump-active-process.c
1 #include <stdio.h>
2 #include <windows.h>
3 #include <ctype.h>
4
5 void
6 dump_mbi_header ()
7 {
8   printf ("alc-base   alc-prot address    size       state    protect  type     \n");
9
10
11
12 int
13 dump_protect_flags (DWORD flags)
14 {
15   DWORD pr = flags & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE
16                       | PAGE_EXECUTE_WRITECOPY | PAGE_READONLY
17                       | PAGE_READWRITE | PAGE_WRITECOPY);
18   DWORD pw = flags & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY
19                       | PAGE_READWRITE | PAGE_WRITECOPY);
20   DWORD pc = flags & (PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY);
21   DWORD px = flags & (PAGE_EXECUTE | PAGE_EXECUTE_READ
22                       | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
23   
24   printf ("%c%c%c %c%c%c  ",
25           pr ? 'r' : '-', pc ? 'c' : (pw ? 'w' : '-'), px ? 'x' : '-',
26           (flags & PAGE_GUARD) ? 'g' : '-',
27           (flags & PAGE_NOCACHE) ? 'n' : '-',
28 #ifdef PAGE_PHYSICAL
29           (flags & PAGE_PHYSICAL) ? 'p' : 
30 #endif
31           '-');
32   return pr;
33 }
34
35
36 void
37 dump_state (DWORD state)
38 {
39   switch (state)
40     {
41     case MEM_COMMIT:
42       printf ("commit   ");
43       return;
44     case MEM_FREE:
45       printf ("free     ");
46       return;
47     case MEM_RESERVE:
48       printf ("reserve  ");
49       return;
50     default:
51       printf ("unknown  ");
52     }
53 }
54
55
56 void
57 dump_type (DWORD mtype)
58 {
59   switch (mtype)
60     {
61     case MEM_IMAGE:
62       printf ("image    ");
63       return;
64     case MEM_MAPPED:
65       printf ("mapped   ");
66       return;
67     case MEM_PRIVATE:
68       printf ("private  ");
69       return;
70     default:
71       printf ("unknown  ");
72     }
73 }
74
75
76 void
77 dump_region (unsigned char *base, unsigned int size)
78 {
79   int i;
80   int in_nulls = 0;
81  
82   /* Base and size are page-aligned.  */
83   while (size != 0)
84     {
85       for (i = 0; i < 16; i++)
86         if (base[i])
87           break;
88       if (i == 16)
89         {
90           /* Only zeroes.  */
91           if (! in_nulls)
92             {
93               printf ("*\n");
94               in_nulls = 1;
95             }
96           goto next;
97         }
98       in_nulls = 0;
99       printf ("0x%08x:", base);
100       for (i = 0; i < 16; i++)
101         {
102           if (i == 8)
103             printf (" ");
104           printf (" %02x", base[i]);
105         }
106       printf ("  ");
107       for (i = 0; i < 16; i++)
108         {
109           if (i == 8)
110             printf (" ");
111           printf ("%c", isprint(base[i]) ? base[i] : '.');
112         }
113       printf ("\n");
114     next:
115       base += 16;
116       size -= 16;
117     }
118 }
119
120
121 void
122 dump_mbi (PMEMORY_BASIC_INFORMATION mbi)
123 {
124   int pr;
125   printf ("0x%08x ", mbi->AllocationBase);
126   dump_protect_flags (mbi->AllocationProtect);
127   printf ("0x%08x ", mbi->BaseAddress);
128   printf ("0x%08x ", mbi->RegionSize);
129   dump_state (mbi->State);
130   pr = dump_protect_flags (mbi->Protect);
131   dump_type (mbi->Type);
132   printf ("\n");
133   if (pr)
134     dump_region (mbi->BaseAddress, mbi->RegionSize);
135 }
136
137
138 int
139 main (int argc, char* argv[])
140 {
141   MEMORY_BASIC_INFORMATION mbi;
142   SYSTEM_INFO si;
143   void *addr;
144   
145   memset (&si, '\0', sizeof (si));
146   GetSystemInfo (&si);
147   dump_mbi_header ();
148
149   addr = 0;
150   do
151     {
152       DWORD res;
153       void *new_addr;
154
155       memset (&mbi, '\0', sizeof (mbi));
156       res = VirtualQuery (addr, &mbi, sizeof (mbi));
157       if (res == 0)
158         {
159           printf ("Skipping over %p\n", addr);
160           new_addr = addr + si.dwPageSize;
161           if (new_addr < addr)
162             break;
163           addr = new_addr;
164           continue;
165         }
166       if (res != sizeof (mbi))
167         {
168           printf ("Unexpected return size: %i (expected %i)\n",
169                   res, sizeof (mbi));
170         }
171       dump_mbi (&mbi);
172       /* Check for overflow.  */
173       new_addr = addr + mbi.RegionSize;
174       if (new_addr < addr)
175         break;
176       addr = new_addr;
177     }
178   while (1);
179
180   /* Give ssh time to flush buffers.  */
181   fflush (stdout);
182   Sleep (300);
183   return 0;
184 }