1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2009-2014, Mario Vilas 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are met: 9# 10# * Redistributions of source code must retain the above copyright notice, 11# this list of conditions and the following disclaimer. 12# * Redistributions in binary form must reproduce the above copyright 13# notice,this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# * Neither the name of the copyright holder nor the names of its 16# contributors may be used to endorse or promote products derived from 17# this software without specific prior written permission. 18# 19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29# POSSIBILITY OF SUCH DAMAGE. 30 31""" 32Wrapper for gdi32.dll in ctypes. 33""" 34 35__revision__ = "$Id$" 36 37from winappdbg.win32.defines import * 38from winappdbg.win32.kernel32 import GetLastError, SetLastError 39 40#============================================================================== 41# This is used later on to calculate the list of exported symbols. 42_all = None 43_all = set(vars().keys()) 44#============================================================================== 45 46#--- Helpers ------------------------------------------------------------------ 47 48#--- Types -------------------------------------------------------------------- 49 50#--- Constants ---------------------------------------------------------------- 51 52# GDI object types 53OBJ_PEN = 1 54OBJ_BRUSH = 2 55OBJ_DC = 3 56OBJ_METADC = 4 57OBJ_PAL = 5 58OBJ_FONT = 6 59OBJ_BITMAP = 7 60OBJ_REGION = 8 61OBJ_METAFILE = 9 62OBJ_MEMDC = 10 63OBJ_EXTPEN = 11 64OBJ_ENHMETADC = 12 65OBJ_ENHMETAFILE = 13 66OBJ_COLORSPACE = 14 67GDI_OBJ_LAST = OBJ_COLORSPACE 68 69# Ternary raster operations 70SRCCOPY = 0x00CC0020 # dest = source 71SRCPAINT = 0x00EE0086 # dest = source OR dest 72SRCAND = 0x008800C6 # dest = source AND dest 73SRCINVERT = 0x00660046 # dest = source XOR dest 74SRCERASE = 0x00440328 # dest = source AND (NOT dest) 75NOTSRCCOPY = 0x00330008 # dest = (NOT source) 76NOTSRCERASE = 0x001100A6 # dest = (NOT src) AND (NOT dest) 77MERGECOPY = 0x00C000CA # dest = (source AND pattern) 78MERGEPAINT = 0x00BB0226 # dest = (NOT source) OR dest 79PATCOPY = 0x00F00021 # dest = pattern 80PATPAINT = 0x00FB0A09 # dest = DPSnoo 81PATINVERT = 0x005A0049 # dest = pattern XOR dest 82DSTINVERT = 0x00550009 # dest = (NOT dest) 83BLACKNESS = 0x00000042 # dest = BLACK 84WHITENESS = 0x00FF0062 # dest = WHITE 85NOMIRRORBITMAP = 0x80000000 # Do not Mirror the bitmap in this call 86CAPTUREBLT = 0x40000000 # Include layered windows 87 88# Region flags 89ERROR = 0 90NULLREGION = 1 91SIMPLEREGION = 2 92COMPLEXREGION = 3 93RGN_ERROR = ERROR 94 95# CombineRgn() styles 96RGN_AND = 1 97RGN_OR = 2 98RGN_XOR = 3 99RGN_DIFF = 4 100RGN_COPY = 5 101RGN_MIN = RGN_AND 102RGN_MAX = RGN_COPY 103 104# StretchBlt() modes 105BLACKONWHITE = 1 106WHITEONBLACK = 2 107COLORONCOLOR = 3 108HALFTONE = 4 109MAXSTRETCHBLTMODE = 4 110STRETCH_ANDSCANS = BLACKONWHITE 111STRETCH_ORSCANS = WHITEONBLACK 112STRETCH_DELETESCANS = COLORONCOLOR 113STRETCH_HALFTONE = HALFTONE 114 115# PolyFill() modes 116ALTERNATE = 1 117WINDING = 2 118POLYFILL_LAST = 2 119 120# Layout orientation options 121LAYOUT_RTL = 0x00000001 # Right to left 122LAYOUT_BTT = 0x00000002 # Bottom to top 123LAYOUT_VBH = 0x00000004 # Vertical before horizontal 124LAYOUT_ORIENTATIONMASK = LAYOUT_RTL + LAYOUT_BTT + LAYOUT_VBH 125LAYOUT_BITMAPORIENTATIONPRESERVED = 0x00000008 126 127# Stock objects 128WHITE_BRUSH = 0 129LTGRAY_BRUSH = 1 130GRAY_BRUSH = 2 131DKGRAY_BRUSH = 3 132BLACK_BRUSH = 4 133NULL_BRUSH = 5 134HOLLOW_BRUSH = NULL_BRUSH 135WHITE_PEN = 6 136BLACK_PEN = 7 137NULL_PEN = 8 138OEM_FIXED_FONT = 10 139ANSI_FIXED_FONT = 11 140ANSI_VAR_FONT = 12 141SYSTEM_FONT = 13 142DEVICE_DEFAULT_FONT = 14 143DEFAULT_PALETTE = 15 144SYSTEM_FIXED_FONT = 16 145 146# Metafile functions 147META_SETBKCOLOR = 0x0201 148META_SETBKMODE = 0x0102 149META_SETMAPMODE = 0x0103 150META_SETROP2 = 0x0104 151META_SETRELABS = 0x0105 152META_SETPOLYFILLMODE = 0x0106 153META_SETSTRETCHBLTMODE = 0x0107 154META_SETTEXTCHAREXTRA = 0x0108 155META_SETTEXTCOLOR = 0x0209 156META_SETTEXTJUSTIFICATION = 0x020A 157META_SETWINDOWORG = 0x020B 158META_SETWINDOWEXT = 0x020C 159META_SETVIEWPORTORG = 0x020D 160META_SETVIEWPORTEXT = 0x020E 161META_OFFSETWINDOWORG = 0x020F 162META_SCALEWINDOWEXT = 0x0410 163META_OFFSETVIEWPORTORG = 0x0211 164META_SCALEVIEWPORTEXT = 0x0412 165META_LINETO = 0x0213 166META_MOVETO = 0x0214 167META_EXCLUDECLIPRECT = 0x0415 168META_INTERSECTCLIPRECT = 0x0416 169META_ARC = 0x0817 170META_ELLIPSE = 0x0418 171META_FLOODFILL = 0x0419 172META_PIE = 0x081A 173META_RECTANGLE = 0x041B 174META_ROUNDRECT = 0x061C 175META_PATBLT = 0x061D 176META_SAVEDC = 0x001E 177META_SETPIXEL = 0x041F 178META_OFFSETCLIPRGN = 0x0220 179META_TEXTOUT = 0x0521 180META_BITBLT = 0x0922 181META_STRETCHBLT = 0x0B23 182META_POLYGON = 0x0324 183META_POLYLINE = 0x0325 184META_ESCAPE = 0x0626 185META_RESTOREDC = 0x0127 186META_FILLREGION = 0x0228 187META_FRAMEREGION = 0x0429 188META_INVERTREGION = 0x012A 189META_PAINTREGION = 0x012B 190META_SELECTCLIPREGION = 0x012C 191META_SELECTOBJECT = 0x012D 192META_SETTEXTALIGN = 0x012E 193META_CHORD = 0x0830 194META_SETMAPPERFLAGS = 0x0231 195META_EXTTEXTOUT = 0x0a32 196META_SETDIBTODEV = 0x0d33 197META_SELECTPALETTE = 0x0234 198META_REALIZEPALETTE = 0x0035 199META_ANIMATEPALETTE = 0x0436 200META_SETPALENTRIES = 0x0037 201META_POLYPOLYGON = 0x0538 202META_RESIZEPALETTE = 0x0139 203META_DIBBITBLT = 0x0940 204META_DIBSTRETCHBLT = 0x0b41 205META_DIBCREATEPATTERNBRUSH = 0x0142 206META_STRETCHDIB = 0x0f43 207META_EXTFLOODFILL = 0x0548 208META_SETLAYOUT = 0x0149 209META_DELETEOBJECT = 0x01f0 210META_CREATEPALETTE = 0x00f7 211META_CREATEPATTERNBRUSH = 0x01F9 212META_CREATEPENINDIRECT = 0x02FA 213META_CREATEFONTINDIRECT = 0x02FB 214META_CREATEBRUSHINDIRECT = 0x02FC 215META_CREATEREGION = 0x06FF 216 217# Metafile escape codes 218NEWFRAME = 1 219ABORTDOC = 2 220NEXTBAND = 3 221SETCOLORTABLE = 4 222GETCOLORTABLE = 5 223FLUSHOUTPUT = 6 224DRAFTMODE = 7 225QUERYESCSUPPORT = 8 226SETABORTPROC = 9 227STARTDOC = 10 228ENDDOC = 11 229GETPHYSPAGESIZE = 12 230GETPRINTINGOFFSET = 13 231GETSCALINGFACTOR = 14 232MFCOMMENT = 15 233GETPENWIDTH = 16 234SETCOPYCOUNT = 17 235SELECTPAPERSOURCE = 18 236DEVICEDATA = 19 237PASSTHROUGH = 19 238GETTECHNOLGY = 20 239GETTECHNOLOGY = 20 240SETLINECAP = 21 241SETLINEJOIN = 22 242SETMITERLIMIT = 23 243BANDINFO = 24 244DRAWPATTERNRECT = 25 245GETVECTORPENSIZE = 26 246GETVECTORBRUSHSIZE = 27 247ENABLEDUPLEX = 28 248GETSETPAPERBINS = 29 249GETSETPRINTORIENT = 30 250ENUMPAPERBINS = 31 251SETDIBSCALING = 32 252EPSPRINTING = 33 253ENUMPAPERMETRICS = 34 254GETSETPAPERMETRICS = 35 255POSTSCRIPT_DATA = 37 256POSTSCRIPT_IGNORE = 38 257MOUSETRAILS = 39 258GETDEVICEUNITS = 42 259GETEXTENDEDTEXTMETRICS = 256 260GETEXTENTTABLE = 257 261GETPAIRKERNTABLE = 258 262GETTRACKKERNTABLE = 259 263EXTTEXTOUT = 512 264GETFACENAME = 513 265DOWNLOADFACE = 514 266ENABLERELATIVEWIDTHS = 768 267ENABLEPAIRKERNING = 769 268SETKERNTRACK = 770 269SETALLJUSTVALUES = 771 270SETCHARSET = 772 271STRETCHBLT = 2048 272METAFILE_DRIVER = 2049 273GETSETSCREENPARAMS = 3072 274QUERYDIBSUPPORT = 3073 275BEGIN_PATH = 4096 276CLIP_TO_PATH = 4097 277END_PATH = 4098 278EXT_DEVICE_CAPS = 4099 279RESTORE_CTM = 4100 280SAVE_CTM = 4101 281SET_ARC_DIRECTION = 4102 282SET_BACKGROUND_COLOR = 4103 283SET_POLY_MODE = 4104 284SET_SCREEN_ANGLE = 4105 285SET_SPREAD = 4106 286TRANSFORM_CTM = 4107 287SET_CLIP_BOX = 4108 288SET_BOUNDS = 4109 289SET_MIRROR_MODE = 4110 290OPENCHANNEL = 4110 291DOWNLOADHEADER = 4111 292CLOSECHANNEL = 4112 293POSTSCRIPT_PASSTHROUGH = 4115 294ENCAPSULATED_POSTSCRIPT = 4116 295POSTSCRIPT_IDENTIFY = 4117 296POSTSCRIPT_INJECTION = 4118 297CHECKJPEGFORMAT = 4119 298CHECKPNGFORMAT = 4120 299GET_PS_FEATURESETTING = 4121 300GDIPLUS_TS_QUERYVER = 4122 301GDIPLUS_TS_RECORD = 4123 302SPCLPASSTHROUGH2 = 4568 303 304#--- Structures --------------------------------------------------------------- 305 306# typedef struct _RECT { 307# LONG left; 308# LONG top; 309# LONG right; 310# LONG bottom; 311# }RECT, *PRECT; 312class RECT(Structure): 313 _fields_ = [ 314 ('left', LONG), 315 ('top', LONG), 316 ('right', LONG), 317 ('bottom', LONG), 318 ] 319PRECT = POINTER(RECT) 320LPRECT = PRECT 321 322# typedef struct tagPOINT { 323# LONG x; 324# LONG y; 325# } POINT; 326class POINT(Structure): 327 _fields_ = [ 328 ('x', LONG), 329 ('y', LONG), 330 ] 331PPOINT = POINTER(POINT) 332LPPOINT = PPOINT 333 334# typedef struct tagBITMAP { 335# LONG bmType; 336# LONG bmWidth; 337# LONG bmHeight; 338# LONG bmWidthBytes; 339# WORD bmPlanes; 340# WORD bmBitsPixel; 341# LPVOID bmBits; 342# } BITMAP, *PBITMAP; 343class BITMAP(Structure): 344 _fields_ = [ 345 ("bmType", LONG), 346 ("bmWidth", LONG), 347 ("bmHeight", LONG), 348 ("bmWidthBytes", LONG), 349 ("bmPlanes", WORD), 350 ("bmBitsPixel", WORD), 351 ("bmBits", LPVOID), 352 ] 353PBITMAP = POINTER(BITMAP) 354LPBITMAP = PBITMAP 355 356#--- High level classes ------------------------------------------------------- 357 358#--- gdi32.dll ---------------------------------------------------------------- 359 360# HDC GetDC( 361# __in HWND hWnd 362# ); 363def GetDC(hWnd): 364 _GetDC = windll.gdi32.GetDC 365 _GetDC.argtypes = [HWND] 366 _GetDC.restype = HDC 367 _GetDC.errcheck = RaiseIfZero 368 return _GetDC(hWnd) 369 370# HDC GetWindowDC( 371# __in HWND hWnd 372# ); 373def GetWindowDC(hWnd): 374 _GetWindowDC = windll.gdi32.GetWindowDC 375 _GetWindowDC.argtypes = [HWND] 376 _GetWindowDC.restype = HDC 377 _GetWindowDC.errcheck = RaiseIfZero 378 return _GetWindowDC(hWnd) 379 380# int ReleaseDC( 381# __in HWND hWnd, 382# __in HDC hDC 383# ); 384def ReleaseDC(hWnd, hDC): 385 _ReleaseDC = windll.gdi32.ReleaseDC 386 _ReleaseDC.argtypes = [HWND, HDC] 387 _ReleaseDC.restype = ctypes.c_int 388 _ReleaseDC.errcheck = RaiseIfZero 389 _ReleaseDC(hWnd, hDC) 390 391# HGDIOBJ SelectObject( 392# __in HDC hdc, 393# __in HGDIOBJ hgdiobj 394# ); 395def SelectObject(hdc, hgdiobj): 396 _SelectObject = windll.gdi32.SelectObject 397 _SelectObject.argtypes = [HDC, HGDIOBJ] 398 _SelectObject.restype = HGDIOBJ 399 _SelectObject.errcheck = RaiseIfZero 400 return _SelectObject(hdc, hgdiobj) 401 402# HGDIOBJ GetStockObject( 403# __in int fnObject 404# ); 405def GetStockObject(fnObject): 406 _GetStockObject = windll.gdi32.GetStockObject 407 _GetStockObject.argtypes = [ctypes.c_int] 408 _GetStockObject.restype = HGDIOBJ 409 _GetStockObject.errcheck = RaiseIfZero 410 return _GetStockObject(fnObject) 411 412# DWORD GetObjectType( 413# __in HGDIOBJ h 414# ); 415def GetObjectType(h): 416 _GetObjectType = windll.gdi32.GetObjectType 417 _GetObjectType.argtypes = [HGDIOBJ] 418 _GetObjectType.restype = DWORD 419 _GetObjectType.errcheck = RaiseIfZero 420 return _GetObjectType(h) 421 422# int GetObject( 423# __in HGDIOBJ hgdiobj, 424# __in int cbBuffer, 425# __out LPVOID lpvObject 426# ); 427def GetObject(hgdiobj, cbBuffer = None, lpvObject = None): 428 _GetObject = windll.gdi32.GetObject 429 _GetObject.argtypes = [HGDIOBJ, ctypes.c_int, LPVOID] 430 _GetObject.restype = ctypes.c_int 431 _GetObject.errcheck = RaiseIfZero 432 433 # Both cbBuffer and lpvObject can be omitted, the correct 434 # size and structure to return are automatically deduced. 435 # If lpvObject is given it must be a ctypes object, not a pointer. 436 # Always returns a ctypes object. 437 438 if cbBuffer is not None: 439 if lpvObject is None: 440 lpvObject = ctypes.create_string_buffer("", cbBuffer) 441 elif lpvObject is not None: 442 cbBuffer = sizeof(lpvObject) 443 else: # most likely case, both are None 444 t = GetObjectType(hgdiobj) 445 if t == OBJ_PEN: 446 cbBuffer = sizeof(LOGPEN) 447 lpvObject = LOGPEN() 448 elif t == OBJ_BRUSH: 449 cbBuffer = sizeof(LOGBRUSH) 450 lpvObject = LOGBRUSH() 451 elif t == OBJ_PAL: 452 cbBuffer = _GetObject(hgdiobj, 0, None) 453 lpvObject = (WORD * (cbBuffer // sizeof(WORD)))() 454 elif t == OBJ_FONT: 455 cbBuffer = sizeof(LOGFONT) 456 lpvObject = LOGFONT() 457 elif t == OBJ_BITMAP: # try the two possible types of bitmap 458 cbBuffer = sizeof(DIBSECTION) 459 lpvObject = DIBSECTION() 460 try: 461 _GetObject(hgdiobj, cbBuffer, byref(lpvObject)) 462 return lpvObject 463 except WindowsError: 464 cbBuffer = sizeof(BITMAP) 465 lpvObject = BITMAP() 466 elif t == OBJ_EXTPEN: 467 cbBuffer = sizeof(LOGEXTPEN) 468 lpvObject = LOGEXTPEN() 469 else: 470 cbBuffer = _GetObject(hgdiobj, 0, None) 471 lpvObject = ctypes.create_string_buffer("", cbBuffer) 472 _GetObject(hgdiobj, cbBuffer, byref(lpvObject)) 473 return lpvObject 474 475# LONG GetBitmapBits( 476# __in HBITMAP hbmp, 477# __in LONG cbBuffer, 478# __out LPVOID lpvBits 479# ); 480def GetBitmapBits(hbmp): 481 _GetBitmapBits = windll.gdi32.GetBitmapBits 482 _GetBitmapBits.argtypes = [HBITMAP, LONG, LPVOID] 483 _GetBitmapBits.restype = LONG 484 _GetBitmapBits.errcheck = RaiseIfZero 485 486 bitmap = GetObject(hbmp, lpvObject = BITMAP()) 487 cbBuffer = bitmap.bmWidthBytes * bitmap.bmHeight 488 lpvBits = ctypes.create_string_buffer("", cbBuffer) 489 _GetBitmapBits(hbmp, cbBuffer, byref(lpvBits)) 490 return lpvBits.raw 491 492# HBITMAP CreateBitmapIndirect( 493# __in const BITMAP *lpbm 494# ); 495def CreateBitmapIndirect(lpbm): 496 _CreateBitmapIndirect = windll.gdi32.CreateBitmapIndirect 497 _CreateBitmapIndirect.argtypes = [PBITMAP] 498 _CreateBitmapIndirect.restype = HBITMAP 499 _CreateBitmapIndirect.errcheck = RaiseIfZero 500 return _CreateBitmapIndirect(lpbm) 501 502#============================================================================== 503# This calculates the list of exported symbols. 504_all = set(vars().keys()).difference(_all) 505__all__ = [_x for _x in _all if not _x.startswith('_')] 506__all__.sort() 507#============================================================================== 508