[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Full-disclosure] SOMEONE CAN HELP WITH THE Microsoft GDI WMF Parsing Heap Overflow Vulnerability ? IT´s a bit wired...
- To: <full-disclosure@xxxxxxxxxxxxxxxxx>
- Subject: [Full-disclosure] SOMEONE CAN HELP WITH THE Microsoft GDI WMF Parsing Heap Overflow Vulnerability ? IT´s a bit wired...
- From: "Nikolaos Rangos" <nikolaos.rangos@xxxxxxxxx>
- Date: Wed, 7 Jun 2028 15:35:30 +0200
Microsoft GDI WMF Parsing Heap Overflow Vulnerability - MAY SOMEONE HELP?
IT'S A MEAN BUG - OR AM I MAAAAAAAAAAAAAAD!? MAYBE !? SOME ONE PWN THAT
SHIT!
DISCLOSURE DAY 7 JUNE // MAYBE SOMEONE HELP THE GUYS WITH THE PATTERN BYTE?!
BILLY THE KID IS MADDER THAN THEO! PS SSSHSSHHSHSHSHSHSHSUTTTUPTEO
Affected Vendors
Microsoft *** MikeRoweSoft (BTW WHERES HIS XBOX?????)
Affected Products
Windows XP SP2
Windows 2003 SP1
Windows Vista
Windows 2000 SP4
Vulnerability Details
~+~~+~~+~~+~~+~~+~~+~
This vulnerability allows remote attackers to execute arbitrary code
on vulnerable installations of Microsoft Windows. User interaction is
required in that a user must open a malicious file or visit a malicious web
page.
The specific flaw exists within the parsing of malformed WMF files.
A vulnerability exists in the *GDI* funcion CreateDIBPatternBrushPt used
when processing WMF files.
Due to a mis-calculation of user data a heap chunk can be under-allocated
and later used resulting in a heap overflow. Successful exploitation can
result in system compromise under the credentials of the currently logged in
user.
Vendor Response
Microsoft has issued an update to correct this vulnerability. More details
can be found below (Look at the migization factors):
------
CURRENT WiNE TREE WaReZ:
/******************************************************************
* PlayMetaFileRecord (GDI32.@)
*
* Render a single metafile record specified by *mr in the DC hdc, while
* using the handle table *ht, of length handles,
* to store metafile objects.
*
* BUGS
* The following metafile records are unimplemented:
*
* DRAWTEXT, ANIMATEPALETTE, SETPALENTRIES,
* RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
* ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
*/
BOOL WINAPI PlayMetaFileRecord( HDC hdc, HANDLETABLE *ht, METARECORD *mr,
UINT handles )
{
short s1;
POINT *pt;
BITMAPINFOHEADER *infohdr;
TRACE("(%p %p %p %u) function %04x\n", hdc, ht, mr, handles,
mr->rdFunction);
switch (mr->rdFunction)
{
case META_EOF:
break;
case META_DELETEOBJECT:
DeleteObject(*(ht->objectHandle + mr->rdParm[0]));
*(ht->objectHandle + mr->rdParm[0]) = 0;
break;
case META_SETBKCOLOR:
SetBkColor(hdc, MAKELONG(mr->rdParm[0], mr->rdParm[1]));
break;
case META_SETBKMODE:
SetBkMode(hdc, mr->rdParm[0]);
break;
case META_SETMAPMODE:
SetMapMode(hdc, mr->rdParm[0]);
break;
case META_SETROP2:
SetROP2(hdc, mr->rdParm[0]);
break;
case META_SETRELABS:
SetRelAbs(hdc, mr->rdParm[0]);
break;
case META_SETPOLYFILLMODE:
SetPolyFillMode(hdc, mr->rdParm[0]);
break;
case META_SETSTRETCHBLTMODE:
SetStretchBltMode(hdc, mr->rdParm[0]);
break;
case META_SETTEXTCOLOR:
SetTextColor(hdc, MAKELONG(mr->rdParm[0], mr->rdParm[1]));
break;
case META_SETWINDOWORG:
SetWindowOrgEx(hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0],
NULL);
break;
case META_SETWINDOWEXT:
SetWindowExtEx(hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0],
NULL);
break;
case META_SETVIEWPORTORG:
SetViewportOrgEx(hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0],
NULL);
break;
case META_SETVIEWPORTEXT:
SetViewportExtEx(hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0],
NULL);
break;
case META_OFFSETWINDOWORG:
OffsetWindowOrgEx(hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0],
NULL);
break;
case META_SCALEWINDOWEXT:
ScaleWindowExtEx(hdc, (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0],
NULL);
break;
case META_OFFSETVIEWPORTORG:
OffsetViewportOrgEx(hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0],
NULL);
break;
case META_SCALEVIEWPORTEXT:
ScaleViewportExtEx(hdc, (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0],
NULL);
break;
case META_LINETO:
LineTo(hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]);
break;
case META_MOVETO:
MoveToEx(hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0], NULL);
break;
case META_EXCLUDECLIPRECT:
ExcludeClipRect( hdc, (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0] );
break;
case META_INTERSECTCLIPRECT:
IntersectClipRect( hdc, (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]
);
break;
case META_ARC:
Arc(hdc, (SHORT)mr->rdParm[7], (SHORT)mr->rdParm[6],
(SHORT)mr->rdParm[5], (SHORT)mr->rdParm[4],
(SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]);
break;
case META_ELLIPSE: ** YEAH CLOSE TO THAT, LOOK DOWN
Ellipse(hdc, (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]);
break;
case META_FLOODFILL:
FloodFill(hdc, (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
MAKELONG(mr->rdParm[0], mr->rdParm[1]));
break;
case META_PIE:
Pie(hdc, (SHORT)mr->rdParm[7], (SHORT)mr->rdParm[6],
(SHORT)mr->rdParm[5], (SHORT)mr->rdParm[4],
(SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]);
break;
case META_RECTANGLE:
Rectangle(hdc, (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]);
break;
case META_ROUNDRECT:
RoundRect(hdc, (SHORT)mr->rdParm[5], (SHORT)mr->rdParm[4],
(SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]);
break;
case META_PATBLT:
PatBlt(hdc, (SHORT)mr->rdParm[5], (SHORT)mr->rdParm[4],
(SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
MAKELONG(mr->rdParm[0], mr->rdParm[1]));
break;
case META_SAVEDC:
SaveDC(hdc);
break;
case META_SETPIXEL:
SetPixel(hdc, (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
MAKELONG(mr->rdParm[0], mr->rdParm[1]));
break;
case META_OFFSETCLIPRGN:
OffsetClipRgn( hdc, (SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0] );
break;
case META_TEXTOUT:
s1 = mr->rdParm[0];
TextOutA(hdc, (SHORT)mr->rdParm[((s1 + 1) >> 1) + 2],
(SHORT)mr->rdParm[((s1 + 1) >> 1) + 1],
(char *)(mr->rdParm + 1), s1);
break;
case META_POLYGON: ** BILLY CAN DRAW POLYGONS// WTF ABOUT CIRCLES?????
if ((pt = convert_points( mr->rdParm[0], (LPPOINT16)(mr->rdParm +
1))))
{
Polygon(hdc, pt, mr->rdParm[0]);
HeapFree( GetProcessHeap(), 0, pt );
}
break;
case META_POLYPOLYGON:
{
UINT i, total;
SHORT *counts = (SHORT *)(mr->rdParm + 1);
for (i = total = 0; i < mr->rdParm[0]; i++) total += counts[i];
pt = convert_points( total, (LPPOINT16)(counts + mr->rdParm[0])
);
if (pt)
{
INT *cnt32 = HeapAlloc( GetProcessHeap(), 0, mr->rdParm[0] *
sizeof(*cnt32) );
if (cnt32)
{
for (i = 0; i < mr->rdParm[0]; i++) cnt32[i] =
counts[i];
PolyPolygon( hdc, pt, cnt32, mr->rdParm[0]);
HeapFree( GetProcessHeap(), 0, cnt32 );
}
}
HeapFree( GetProcessHeap(), 0, pt );
}
break;
case META_POLYLINE:
if ((pt = convert_points( mr->rdParm[0], (LPPOINT16)(mr->rdParm +
1))))
{
Polyline( hdc, pt, mr->rdParm[0] );
HeapFree( GetProcessHeap(), 0, pt );
}
break;
case META_RESTOREDC:
RestoreDC(hdc, (SHORT)mr->rdParm[0]);
break;
case META_SELECTOBJECT:
SelectObject(hdc, *(ht->objectHandle + mr->rdParm[0]));
break;
case META_CHORD:
Chord(hdc, (SHORT)mr->rdParm[7], (SHORT)mr->rdParm[6],
(SHORT)mr->rdParm[5], (SHORT)mr->rdParm[4],
(SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]);
break;
case META_CREATEPATTERNBRUSH:
switch (mr->rdParm[0])
{
case BS_PATTERN:
infohdr = (BITMAPINFOHEADER *)(mr->rdParm + 2);
MF_AddHandle(ht, handles,
CreatePatternBrush(CreateBitmap(infohdr->biWidth,
infohdr->biHeight,
infohdr->biPlanes,
infohdr->biBitCount,
(LPSTR)(mr->rdParm +
(sizeof(BITMAPINFOHEADER) / 2) +
4))));
break;
case BS_DIBPATTERN:
infohdr = (BITMAPINFOHEADER *)(mr->rdParm + 2);
MF_AddHandle(ht, handles, CreateDIBPatternBrushPt( infohdr,
mr->rdParm[1] ));
break;
default:
ERR("META_CREATEPATTERNBRUSH: Unknown pattern type %d\n",
mr->rdParm[0]);
break;
}
break;
case META_CREATEPENINDIRECT:
{
LOGPEN pen;
pen.lopnStyle = mr->rdParm[0];
pen.lopnWidth.x = (SHORT)mr->rdParm[1];
pen.lopnWidth.y = (SHORT)mr->rdParm[2];
pen.lopnColor = MAKELONG( mr->rdParm[3], mr->rdParm[4] );
MF_AddHandle(ht, handles, CreatePenIndirect( &pen ));
}
break;
case META_CREATEFONTINDIRECT:
{
LOGFONTA font;
font.lfHeight = (SHORT)mr->rdParm[0];
font.lfWidth = (SHORT)mr->rdParm[1];
font.lfEscapement = (SHORT)mr->rdParm[2];
font.lfOrientation = (SHORT)mr->rdParm[3];
font.lfWeight = (SHORT)mr->rdParm[4];
font.lfItalic = LOBYTE(mr->rdParm[5]);
font.lfUnderline = HIBYTE(mr->rdParm[5]);
font.lfStrikeOut = LOBYTE(mr->rdParm[6]);
font.lfCharSet = HIBYTE(mr->rdParm[6]);
font.lfOutPrecision = LOBYTE(mr->rdParm[7]);
font.lfClipPrecision = HIBYTE(mr->rdParm[7]);
font.lfQuality = LOBYTE(mr->rdParm[8]);
font.lfPitchAndFamily = HIBYTE(mr->rdParm[8]);
memcpy( font.lfFaceName, mr->rdParm + 9, LF_FACESIZE );
MF_AddHandle(ht, handles, CreateFontIndirectA( &font ));
}
break;
case META_CREATEBRUSHINDIRECT:
{
LOGBRUSH brush;
brush.lbStyle = mr->rdParm[0];
brush.lbColor = MAKELONG( mr->rdParm[1], mr->rdParm[2] );
brush.lbHatch = mr->rdParm[3];
MF_AddHandle(ht, handles, CreateBrushIndirect( &brush ));
}
break;
case META_CREATEPALETTE:
MF_AddHandle(ht, handles, CreatePalette((LPLOGPALETTE)mr->rdParm));
break;
case META_SETTEXTALIGN:
SetTextAlign(hdc, mr->rdParm[0]);
break;
case META_SELECTPALETTE:
GDISelectPalette(hdc, *(ht->objectHandle + mr->rdParm[1]),
mr->rdParm[0]);
break;
case META_SETMAPPERFLAGS:
SetMapperFlags(hdc, MAKELONG(mr->rdParm[0],mr->rdParm[1]));
break;
case META_REALIZEPALETTE:
GDIRealizePalette(hdc);
break;
case META_ESCAPE:
Escape(hdc, mr->rdParm[0], mr->rdParm[1], (LPCSTR)&mr->rdParm[2],
NULL);
break;
case META_EXTTEXTOUT:
MF_Play_MetaExtTextOut( hdc, mr );
break;
case META_STRETCHDIB:
{
LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParm[11]);
LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParm[2]
);
StretchDIBits( hdc, (SHORT)mr->rdParm[10], (SHORT)mr->rdParm[9],
(SHORT)mr->rdParm[8],
(SHORT)mr->rdParm[7], (SHORT)mr->rdParm[6],
(SHORT)mr->rdParm[5],
(SHORT)mr->rdParm[4], (SHORT)mr->rdParm[3], bits,
info,
mr->rdParm[2],MAKELONG(mr->rdParm[0],mr->rdParm[1]));
}
break;
case META_DIBSTRETCHBLT:
{
LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParm[10]);
LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParm[2]
);
StretchDIBits( hdc, (SHORT)mr->rdParm[9], (SHORT)mr->rdParm[8],
(SHORT)mr->rdParm[7],
(SHORT)mr->rdParm[6], (SHORT)mr->rdParm[5],
(SHORT)mr->rdParm[4],
(SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2], bits,
info,
DIB_RGB_COLORS,MAKELONG(mr->rdParm[0],mr->rdParm[1]));
}
break;
case META_STRETCHBLT:
{
HDC hdcSrc = CreateCompatibleDC(hdc);
HBITMAP hbitmap = CreateBitmap(mr->rdParm[10], /*Width */
mr->rdParm[11], /*Height*/
mr->rdParm[13], /*Planes*/
mr->rdParm[14], /*BitsPixel*/
(LPSTR)&mr->rdParm[15]); /*bits*/
SelectObject(hdcSrc,hbitmap);
StretchBlt(hdc, (SHORT)mr->rdParm[9], (SHORT)mr->rdParm[8],
(SHORT)mr->rdParm[7], (SHORT)mr->rdParm[6],
hdcSrc, (SHORT)mr->rdParm[5], (SHORT)mr->rdParm[4],
(SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2],
MAKELONG(mr->rdParm[0],mr->rdParm[1]));
DeleteDC(hdcSrc);
}
break;
case META_BITBLT:
{
HDC hdcSrc = CreateCompatibleDC(hdc);
HBITMAP hbitmap = CreateBitmap(mr->rdParm[7]/*Width */,
mr->rdParm[8]/*Height*/,
mr->rdParm[10]/*Planes*/,
mr->rdParm[11]/*BitsPixel*/,
(LPSTR)&mr->rdParm[12]/*bits*/);
SelectObject(hdcSrc,hbitmap);
BitBlt(hdc,(SHORT)mr->rdParm[6],(SHORT)mr->rdParm[5],
(SHORT)mr->rdParm[4],(SHORT)mr->rdParm[3],
hdcSrc, (SHORT)mr->rdParm[2],(SHORT)mr->rdParm[1],
MAKELONG(0,mr->rdParm[0]));
DeleteDC(hdcSrc);
}
break;
case META_CREATEREGION:
{
HRGN hrgn = CreateRectRgn(0,0,0,0);
MF_Play_MetaCreateRegion(mr, hrgn);
MF_AddHandle(ht, handles, hrgn);
}
break;
case META_FILLREGION:
FillRgn(hdc, *(ht->objectHandle + mr->rdParm[1]),
*(ht->objectHandle + mr->rdParm[0]));
break;
case META_FRAMEREGION:
FrameRgn(hdc, *(ht->objectHandle + mr->rdParm[3]),
*(ht->objectHandle + mr->rdParm[2]),
(SHORT)mr->rdParm[1], (SHORT)mr->rdParm[0]);
break;
case META_INVERTREGION:
InvertRgn(hdc, *(ht->objectHandle + mr->rdParm[0]));
break;
case META_PAINTREGION:
PaintRgn(hdc, *(ht->objectHandle + mr->rdParm[0]));
break;
case META_SELECTCLIPREGION:
SelectClipRgn(hdc, *(ht->objectHandle + mr->rdParm[0]));
break;
************************************************************
~ DEFINE OF WHAT IS '' #define META_DIBCREATEPATTERNBRUSH 0x0142 ''
208 /******************************************************************
209 * MFDRV_CreateBrushIndirect
210 */
211
212 INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
213 {
214 DWORD size;
215 METARECORD *mr;
216 LOGBRUSH logbrush;
217 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
218 BOOL r;
219
220 if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;
221
222 switch(logbrush.lbStyle)
223 {
224 case BS_SOLID:
225 case BS_NULL:
226 case BS_HATCHED:
227 {
228 LOGBRUSH16 lb16;
229
230 lb16.lbStyle = logbrush.lbStyle;
231 lb16.lbColor = logbrush.lbColor;
232 lb16.lbHatch = logbrush.lbHatch;
233 size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2;
234 mr = HeapAlloc( GetProcessHeap(), 0, size );
235 mr->rdSize = size / 2;
236 mr->rdFunction = META_CREATEBRUSHINDIRECT;
237 memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
238 break;
239 }
240 case BS_PATTERN: ***** SWITCH CASE
241 {
242 BITMAP bm;
243 BITMAPINFO *info;
244 DWORD bmSize;
245 COLORREF cref;
246
247 GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
248 if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) {
249 FIXME("Trying to store a colour pattern brush\n");
250 goto done;
251 }
252
253 bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight,
DIB_PAL_COLORS);
254
255 size = sizeof(METARECORD) + sizeof(WORD) +
sizeof(BITMAPINFO) +
256 sizeof(RGBQUAD) + bmSize;
257
258 mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
259 if(!mr) goto done;
260 mr->rdFunction = META_DIBCREATEPATTERNBRUSH; **** PARAM 1
261 mr->rdSize = size / 2;
262 mr->rdParm[0] = BS_PATTERN;
263 mr->rdParm[1] = DIB_RGB_COLORS;
264 info = (BITMAPINFO *)(mr->rdParm + 2);
265
266 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
267 info->bmiHeader.biWidth = bm.bmWidth;
268 info->bmiHeader.biHeight = bm.bmHeight;
269 info->bmiHeader.biPlanes = 1;
270 info->bmiHeader.biBitCount = 1;
271 info->bmiHeader.biSizeImage = bmSize;
272
273 GetBitmapBits((HANDLE)logbrush.lbHatch,
274 bm.bmHeight * BITMAP_GetWidthBytes (bm.bmWidth,
bm.bmBitsPixel),
275 (LPBYTE)info + sizeof(BITMAPINFO) +
sizeof(RGBQUAD));
276
277 /* Change the padding to be DIB compatible if needed */
278 if(bm.bmWidth & 31)
279 MFDRV_PadTo32((LPBYTE)info + sizeof(BITMAPINFO) +
sizeof(RGBQUAD),
280 bm.bmWidth, bm.bmHeight);
281 /* BMP and DIB have opposite row order conventions */
282 MFDRV_Reverse((LPBYTE)info + sizeof(BITMAPINFO) +
sizeof(RGBQUAD),
283 bm.bmWidth, bm.bmHeight);
284
285 cref = GetTextColor(physDev->hdc);
286 info->bmiColors[0].rgbRed = GetRValue(cref);
287 info->bmiColors[0].rgbGreen = GetGValue(cref);
288 info->bmiColors[0].rgbBlue = GetBValue(cref);
289 info->bmiColors[0].rgbReserved = 0;
290 cref = GetBkColor(physDev->hdc);
291 info->bmiColors[1].rgbRed = GetRValue(cref);
292 info->bmiColors[1].rgbGreen = GetGValue(cref);
293 info->bmiColors[1].rgbBlue = GetBValue(cref);
294 info->bmiColors[1].rgbReserved = 0;
295 break;
296 }
297
298 case BS_DIBPATTERN:
299 {
300 BITMAPINFO *info;
301 DWORD bmSize, biSize;
302
303 info = GlobalLock16((HGLOBAL16)logbrush.lbHatch);
304 if (info->bmiHeader.biCompression)
305 bmSize = info->bmiHeader.biSizeImage;
306 else
307 bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
308
info->bmiHeader.biHeight,
309
info->bmiHeader.biBitCount);
310 biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor));
311 size = sizeof(METARECORD) + biSize + bmSize + 2;
312 mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
313 if(!mr) goto done;
314 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
315 mr->rdSize = size / 2;
316 *(mr->rdParm) = logbrush.lbStyle;
317 *(mr->rdParm + 1) = LOWORD(logbrush.lbColor);
318 memcpy(mr->rdParm + 2, info, biSize + bmSize);
319 break;
320 }
321 default:
322 FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
323 return 0;
324 }
325 r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
326 HeapFree(GetProcessHeap(), 0, mr);
327 if( !r )
328 return -1;
329 done:
330 return MFDRV_AddHandle( dev, hBrush );
331 }
************************************************************
case META_DIBCREATEPATTERNBRUSH: *
/* mr->rdParm[0] may be BS_PATTERN or BS_DIBPATTERN:
but there's no difference */
MF_AddHandle(ht, handles, *** CRASH FUNCTION ***
CreateDIBPatternBrushPt( mr->rdParm + 2, mr->rdParm[1] )); **
break;
case META_DIBBITBLT:
/* In practice I've found that there are two layouts for
META_DIBBITBLT, one (the first here) is the usual one when a src
dc is actually passed to it, the second occurs when the src dc is
passed in as NULL to the creating BitBlt. As the second case has
no dib, a size check will suffice to distinguish.
Caolan.McNamara@xxxxx */
if (mr->rdSize > 12) {
LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParm[8]);
LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize(info,
mr->rdParm[0]);
StretchDIBits(hdc, (SHORT)mr->rdParm[7], (SHORT)mr->rdParm[6],
(SHORT)mr->rdParm[5],
(SHORT)mr->rdParm[4], (SHORT)mr->rdParm[3],
(SHORT)mr->rdParm[2],
(SHORT)mr->rdParm[5], (SHORT)mr->rdParm[4], bits,
info,
DIB_RGB_COLORS, MAKELONG(mr->rdParm[0],
mr->rdParm[1]));
}
else /* equivalent to a PatBlt */
PatBlt(hdc, (SHORT)mr->rdParm[8], (SHORT)mr->rdParm[7],
(SHORT)mr->rdParm[6], (SHORT)mr->rdParm[5],
MAKELONG(mr->rdParm[0], mr->rdParm[1]));
break;
case META_SETTEXTCHAREXTRA:
SetTextCharacterExtra(hdc, (SHORT)mr->rdParm[0]);
break;
case META_SETTEXTJUSTIFICATION:
SetTextJustification(hdc, (SHORT)mr->rdParm[1],
(SHORT)mr->rdParm[0]);
break;
case META_EXTFLOODFILL:
ExtFloodFill(hdc, (SHORT)mr->rdParm[4], (SHORT)mr->rdParm[3],
MAKELONG(mr->rdParm[1], mr->rdParm[2]),
mr->rdParm[0]);
break;
case META_SETDIBTODEV:
{
BITMAPINFO *info = (BITMAPINFO *) &(mr->rdParm[9]);
char *bits = (char *)info + DIB_BitmapInfoSize( info,
mr->rdParm[0] );
SetDIBitsToDevice(hdc, (SHORT)mr->rdParm[8],
(SHORT)mr->rdParm[7],
(SHORT)mr->rdParm[6], (SHORT)mr->rdParm[5],
(SHORT)mr->rdParm[4], (SHORT)mr->rdParm[3],
mr->rdParm[2], mr->rdParm[1], bits, info,
mr->rdParm[0]);
break;
}
#define META_UNIMP(x) case x: \
FIXME("PlayMetaFileRecord:record type "#x" not implemented.\n"); \
break;
META_UNIMP(META_DRAWTEXT)
META_UNIMP(META_ANIMATEPALETTE)
META_UNIMP(META_SETPALENTRIES)
META_UNIMP(META_RESIZEPALETTE)
META_UNIMP(META_RESETDC)
META_UNIMP(META_STARTDOC)
META_UNIMP(META_STARTPAGE)
META_UNIMP(META_ENDPAGE)
META_UNIMP(META_ABORTDOC)
META_UNIMP(META_ENDDOC)
META_UNIMP(META_CREATEBRUSH)
META_UNIMP(META_CREATEBITMAPINDIRECT)
META_UNIMP(META_CREATEBITMAP)
#undef META_UNIMP
default:
WARN("PlayMetaFileRecord: Unknown record type %x\n",
mr->rdFunction);
return FALSE;
}
return TRUE;
}
* META_DIBCREATEPATTERNBRUSH - IS THiS THE PATTERN BYTE?
** 85 static int MF_AddHandle(HANDLETABLE *ht, UINT htlen, HGDIOBJ hobj)
86 {
87 int i;
88
89 for (i = 0; i < htlen; i++)
90 {
91 if (*(ht->objectHandle + i) == 0)
92 {
93 *(ht->objectHandle + i) = hobj;
94 return i;
95 }
96 }
97 return -1;
98 }
PlayMetaFileRecord gdi.dll
WTF HAPPEND WITH WINDOWS?
PlayMetaFile16
WINE CODE^^
/*******************************************************************
* MF_PlayMetaFile
*
* Helper for PlayMetaFile
*/
static BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh)
{
METARECORD *mr;
HANDLETABLE *ht;
unsigned int offset = 0;
WORD i;
HPEN hPen;
HBRUSH hBrush;
HFONT hFont;
BOOL loaded = FALSE;
if (!mh) return FALSE;
if(mh->mtType == METAFILE_DISK) { /* Create a memory-based copy */
mh = MF_LoadDiskBasedMetaFile(mh);
if(!mh) return FALSE;
loaded = TRUE;
}
/* save the current pen, brush and font */
hPen = GetCurrentObject(hdc, OBJ_PEN);
hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
hFont = GetCurrentObject(hdc, OBJ_FONT);
/* create the handle table */
ht = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(HANDLETABLE) * mh->mtNoObjects);
if(!ht) return FALSE;
/* loop through metafile playing records */
offset = mh->mtHeaderSize * 2;
while (offset < mh->mtSize * 2)
{
mr = (METARECORD *)((char *)mh + offset);
TRACE("offset=%04x,size=%08lx\n",
offset, mr->rdSize);
if (!mr->rdSize) {
TRACE(
"Entry got size 0 at offset %d, total mf length is %ld\n",
offset,mh->mtSize*2);
break; /* would loop endlessly otherwise */
}
offset += mr->rdSize * 2;
PlayMetaFileRecord( hdc, ht, mr, mh->mtNoObjects );
}
Signed,
Nikolaos Rangos nikolaos.rangos@xxxxxxxxx ---
Yours Sincerely,
ROOKIE // EMAIL CONCEALED
Omni glaubst du des? Die Chinesen RELEASEN deren CODE AUF GOOOOOOGLE
(COMPLETE KERNEL DUMPS HEHE)??!?!?!!
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/