Initial version of the whole thing.
[wincetools.git] / virtual-query-imager.py
1 import fileinput
2 import Image, ImageDraw, ImageFont, ImageOps
3
4
5 # Pagesize
6 psize = 4096
7
8 # A column is 32MB
9 p_per_col = 32*1024*1024/psize
10 # 4 GB address space.
11 slots = 2*1024*1024*1024/psize/p_per_col
12
13 slotwidth = 60
14 pheight = 1
15
16 # colors:
17
18 size = p_per_col * pheight, slotwidth * slots
19
20 im = Image.new ("RGB", size)
21
22 draw = ImageDraw.Draw(im)
23 draw.rectangle ((0,0) + im.size, fill="#ffffff")
24
25
26 def getcolor (state, prot, prot_, type):
27     if state == "free":
28         return "#cccccc"
29     if state == "reserve":
30         if type == "image":
31             return "#88ff88"
32         if type == "private":
33             return "#ff8888"
34         if type == "mapped":
35             return "#8888ff"
36         return "#ffff00"
37     if state == "commit":
38         if type == "image":
39             return "#44dd44"
40         if type == "private":
41             return "#dd4444"
42         if type == "mapped":
43             return "#4444dd"
44         return "#ffff00"
45     return "#ffff00"
46
47     # alc-base   alc-prot address    size       state    protect  type     
48     # 0x00000000 --- ---  0x00001000 0x0000f000 free     --- ---  unknown  
49     # 0x00010000 --- ---  0x00014000 0x0000a000 reserve  --- ---  image    
50     # 0x00000000 --- ---  0x0001e000 0x017a2000 free     --- ---  unknown  
51     # 0x017c0000 --- ---  0x017c0000 0x000fe000 reserve  --- ---  private  
52     # 0x017c0000 --- ---  0x018be000 0x00002000 commit   rw- ---  private  
53     # 0x018c0000 --- ---  0x018c0000 0x00002000 commit   rw- -n-  private  
54
55
56 def upperleft (col, row):
57     col = slots - col - 1
58     return (row * pheight, col * slotwidth)
59
60 def lowerright (col, row):
61     col = slots - col - 1
62     return ((row + 1) * pheight - 1, (col + 1) * slotwidth - 1)
63
64
65 def drawit_ (draw, pstart, pstop, state, prot, prot_, type):
66     col = pstart / p_per_col
67     pstart = pstart - col * p_per_col
68     # inclusive now
69     pstop = (pstop - col * p_per_col) - 1
70
71     # Same col for pstop, ensured by drawit
72     color = getcolor (state, prot, prot_, type)
73     draw.rectangle (upperleft(col, pstop) + lowerright (col, pstart),
74                     color)
75    
76
77 def drawit (draw, addr, size, state, prot, prot_, type):
78     if addr >= 2*1024*1024*1024:
79         return
80     
81     end = addr + size
82     while addr < end:
83         next = ((addr + p_per_col) / p_per_col) * p_per_col
84         if next > end:
85             next = end
86         drawit_ (draw, addr, next, state, prot, prot_, type)
87         addr = next
88
89 for line in fileinput.input():
90     if line[0] != '0':
91         continue
92     # alc-base   alc-prot address    size       state    protect  type     
93     # 0x00000000 --- ---  0x00001000 0x0000f000 free     --- ---  unknown  
94     # 0x00010000 --- ---  0x00014000 0x0000a000 reserve  --- ---  image    
95     # 0x00000000 --- ---  0x0001e000 0x017a2000 free     --- ---  unknown  
96     # 0x017c0000 --- ---  0x017c0000 0x000fe000 reserve  --- ---  private  
97     # 0x017c0000 --- ---  0x018be000 0x00002000 commit   rw- ---  private  
98     # 0x018c0000 --- ---  0x018c0000 0x00002000 commit   rw- -n-  private  
99
100     fields = line.split()
101     addr, size, state, prot, prot_, type = fields[3:]
102     addr = int(addr, 16) / 4096
103     size = int(size, 16) / 4096
104
105     drawit (draw, addr, size, state, prot, prot_, type)
106
107
108 # Create grid.
109 for col in xrange(slots):
110     draw.line ((0, col*slotwidth) + (im.size[0], col*slotwidth), fill="#666666")
111 for col in xrange(3):
112     draw.rectangle ((0, (col+1)*(slots/4)*slotwidth - slotwidth/16)
113                     + (im.size[0], (col+1)*(slots/4)*slotwidth + slotwidth/16), fill="#666666")
114 for row in xrange(31):
115     draw.line (((row+1)*(p_per_col/32)*pheight, 0) + (((row+1)*(p_per_col/32))*pheight, im.size[1]), fill="#666666")
116
117 del draw
118
119 # Compose documented image.
120 fsize = (im.size[0] + 30 * slotwidth, im.size[1] + 6 * slotwidth)
121 ulpaste = (28*slotwidth, 3*slotwidth)
122 fim = Image.new ("RGB", fsize)
123 draw = ImageDraw.Draw(fim)
124
125 draw.rectangle ((0,0) + fim.size, fill="#ffffff")
126 draw.rectangle ((ulpaste[0]-2, ulpaste[1]-2) + (ulpaste[0] + im.size[0] + 2, ulpaste[1] + im.size[1] + 2), fill="#000000")
127 fim.paste (im, ulpaste)
128
129 fs = int (slotwidth * 2 / 3)
130 dpf = ImageFont.truetype ("datapro.ttf", int(fs * 1.5))
131 draw.text((slotwidth/2,slotwidth), "Virtual Memory Map of Windows CE", fill="#000000", font=dpf)
132
133 dpf = ImageFont.truetype ("datapro.ttf", fs)
134
135 def getrow(i):
136     return 5 + ulpaste[1] + im.size[1] - slotwidth * (i + 1)
137
138 for i in xrange(slots):
139     draw.text ((ulpaste[0] - 6 * slotwidth, getrow(i) ),
140                "0x%08x" % (i * 0x02000000), fill="#444444", font=dpf)
141
142 for row in xrange(32):
143     txt=Image.new("L", (600,60))
144     d = ImageDraw.Draw(txt)
145     d.text ((0,0), "0x%08x" % (row * 0x00100000), fill=255, font=dpf)
146     del d
147     rtxt = txt.rotate (17.5, expand=1)
148     fim.paste (ImageOps.colorize(rtxt, "#ffffff", "#444444"),
149                (ulpaste[0] + (row*(p_per_col/32)*pheight), ulpaste[1] - 4*slotwidth), rtxt)
150     del txt
151     del rtxt
152
153 #draw.text ((ulpaste[0] + 0x00011000 * p_per_col*pheight / (32*1024*1024), ulpaste[1] + 65*slotwidth),
154 #           "Code/Data", fill="#000000", font=dpf)
155 #draw.text ((ulpaste[0] + 0x018C0000 * p_per_col*pheight / (32*1024*1024), ulpaste[1] + 65*slotwidth),
156 #           "Stack/Heap", fill="#000000", font=dpf)
157
158               
159 def writerow(i, str):
160     draw.text ((10 * slotwidth, getrow(i) ), str, fill="#000000", font=dpf)
161
162 writerow (0, "Slot  0: Active Process")
163 writerow (1, "Slot  1: ROM Image")
164 for i in xrange (31):
165     writerow (2 + i, "Slot %2i: Process %i" % (i + 2, i))
166 for i in xrange (26):
167     writerow (33 + i, "Slot %2i: Shared Area" % (33 + i))
168 writerow (59, "Slot 59: Driver Stacks")
169 writerow (60, "Slot 60: Large DLLs")
170 writerow (61, "Slot 61: Large DLLs")
171 writerow (62, "Slot 62: Shared Heaps")
172 writerow (63, "Slot 63: Resource DLLs")
173
174 def writelegend(i, col, str):
175     draw.rectangle ((1 * slotwidth, getrow(63-i), 2 * slotwidth - 10, getrow(63-i - 1) - 10), fill=col)
176     draw.rectangle ((1 * slotwidth, getrow(63-i), 2 * slotwidth - 10, getrow(63-i - 1) - 10), outline="#444444")
177     draw.text ((2 * slotwidth, getrow(63-i) ), str, fill="#000000", font=dpf)
178
179 writelegend(0, "#ffffff", "unused")
180 writelegend(1, getcolor("free", 0, 0, ""), "free")
181 writelegend(2, getcolor("reserve", 0, 0, "image"), "image")
182 writelegend(3, getcolor("commit", 0, 0, "image"), "... committed")
183 writelegend(4, getcolor("reserve", 0, 0, "private"), "private")
184 writelegend(5, getcolor("commit", 0, 0, "private"), "... committed")
185 writelegend(6, getcolor("reserve", 0, 0, "mapped"), "mapped")
186 writelegend(7, getcolor("commit", 0, 0, "mapped"), "... committed")
187
188 def writeextra(i, str):
189     draw.text ((1 * slotwidth, getrow(63-i) ), str, fill="#000000", font=dpf)
190 writeextra(9, "1px = 4 KB")
191
192
193 del draw 
194 fim.save("output.png", "PNG")