/* * @implemented */ HBRUSH WINAPI CreateDIBPatternBrush( HGLOBAL hglbDIBPacked, UINT fuColorSpec) { PVOID lpPackedDIB; HBRUSH hBrush = NULL; PBITMAPINFO pConvertedInfo; UINT ConvertedInfoSize; lpPackedDIB = GlobalLock(hglbDIBPacked); if (lpPackedDIB == NULL) return 0; pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, fuColorSpec, &ConvertedInfoSize, TRUE); if (pConvertedInfo) { hBrush = NtGdiCreateDIBBrush(pConvertedInfo, fuColorSpec, ConvertedInfoSize, FALSE, FALSE, lpPackedDIB); if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); } GlobalUnlock(hglbDIBPacked); return hBrush; }
/* * @implemented */ HBITMAP WINAPI CreateDIBSection( HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset) { PBITMAPINFO pConvertedInfo; UINT ConvertedInfoSize; HBITMAP hBitmap = NULL; PVOID bmBits = NULL; pConvertedInfo = ConvertBitmapInfo(BitmapInfo, Usage, &ConvertedInfoSize, FALSE); if (pConvertedInfo) { // Verify header due to converted may == info. if (pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) { if (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } } bmBits = Bits; hBitmap = NtGdiCreateDIBSection(hDC, hSection, dwOffset, pConvertedInfo, Usage, ConvertedInfoSize, 0, // fl 0, // dwColorSpace &bmBits); if (BitmapInfo != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); if (!hBitmap) { bmBits = NULL; } } if (Bits) *Bits = bmBits; return hBitmap; }
/* * @implemented */ HBRUSH WINAPI CreateDIBPatternBrushPt( CONST VOID *lpPackedDIB, UINT fuColorSpec) { HBRUSH hBrush = NULL; PBITMAPINFO pConvertedInfo; UINT ConvertedInfoSize; if (lpPackedDIB == NULL) return 0; pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, fuColorSpec, &ConvertedInfoSize, TRUE); if (pConvertedInfo) { hBrush = NtGdiCreateDIBBrush(pConvertedInfo, fuColorSpec, ConvertedInfoSize, FALSE, FALSE, (PVOID)lpPackedDIB); if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); } return hBrush; }
/* * @unimplemented */ int WINAPI StretchDIBits( HDC hdc, int XDest, int YDest, int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth, int nSrcHeight, CONST VOID *lpBits, CONST BITMAPINFO *lpBitsInfo, UINT iUsage, DWORD dwRop) { PDC_ATTR pDc_Attr; PBITMAPINFO pConvertedInfo = NULL; UINT ConvertedInfoSize = 0; INT LinesCopied = 0; UINT cjBmpScanSize = 0; PVOID pvSafeBits = NULL; BOOL Hit = FALSE; DPRINT("StretchDIBits %p : %p : %u\n", lpBits, lpBitsInfo, iUsage); #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) { if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC) return MFDRV_StretchBlt( hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, lpBits, lpBitsInfo, iUsage, dwRop); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return 0; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_StretchBlt(hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, lpBits, lpBitsInfo, iUsage, dwRop); } return 0; } } #endif pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage, &ConvertedInfoSize, FALSE); if (!pConvertedInfo) { return 0; } cjBmpScanSize = GdiGetBitmapBitsSize((BITMAPINFO *) pConvertedInfo); if (lpBits) { pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); if (pvSafeBits) { _SEH2_TRY { RtlCopyMemory(pvSafeBits, lpBits, cjBmpScanSize); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Hit = TRUE; } _SEH2_END if (Hit) { // We don't die, we continue on with a allocated safe pointer to kernel // space..... DPRINT1("StretchDIBits fail to read BitMapInfo: %p or Bits: %p & Size: %u\n", pConvertedInfo, lpBits, cjBmpScanSize); } DPRINT("StretchDIBits Allocate Bits %u!!!\n", cjBmpScanSize); } } if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr)) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } /* if ( !pDc_Attr || iUsage == DIB_PAL_COLORS || ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiStretchDIBitsInternal(hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, pvSafeBits, pConvertedInfo, (DWORD) iUsage, dwRop, ConvertedInfoSize, cjBmpScanSize, NULL); } if (pvSafeBits) RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); if (lpBitsInfo != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); return LinesCopied; }
/* * @implemented * */ INT WINAPI SetDIBitsToDevice( HDC hdc, int XDest, int YDest, DWORD Width, DWORD Height, int XSrc, int YSrc, UINT StartScan, UINT ScanLines, CONST VOID *Bits, CONST BITMAPINFO *lpbmi, UINT ColorUse) { PDC_ATTR pDc_Attr; PBITMAPINFO pConvertedInfo; UINT ConvertedInfoSize; INT LinesCopied = 0; UINT cjBmpScanSize = 0; BOOL Hit = FALSE; PVOID pvSafeBits = (PVOID) Bits; if (!ScanLines || !lpbmi || !Bits) return 0; if (ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS + 1) return 0; pConvertedInfo = ConvertBitmapInfo(lpbmi, ColorUse, &ConvertedInfoSize, FALSE); if (!pConvertedInfo) return 0; #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) { if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC) return MFDRV_SetDIBitsToDevice( hdc, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines, Bits, lpbmi, ColorUse); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return 0; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_SetDIBitsToDevice(hdc, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines, Bits, lpbmi, ColorUse); } return 0; } } #endif if ((pConvertedInfo->bmiHeader.biCompression == BI_RLE8) || (pConvertedInfo->bmiHeader.biCompression == BI_RLE4)) { /* For compressed data, we must set the whole thing */ StartScan = 0; ScanLines = pConvertedInfo->bmiHeader.biHeight; } cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, ScanLines); pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); if (pvSafeBits) { _SEH2_TRY { RtlCopyMemory(pvSafeBits, Bits, cjBmpScanSize); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Hit = TRUE; } _SEH2_END if (Hit) { // We don't die, we continue on with a allocated safe pointer to kernel // space..... DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u\n", pConvertedInfo, Bits, cjBmpScanSize); } DPRINT("SetDIBitsToDevice Allocate Bits %u!!!\n", cjBmpScanSize); } if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr)) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } /* if ( !pDc_Attr || // DC is Public ColorUse == DIB_PAL_COLORS || ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiSetDIBitsToDeviceInternal(hdc, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines, (LPBYTE) pvSafeBits, (LPBITMAPINFO) pConvertedInfo, ColorUse, cjBmpScanSize, ConvertedInfoSize, TRUE, NULL); } if (Bits != pvSafeBits) RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); if (lpbmi != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); return LinesCopied; }
/* * @implemented */ HPEN APIENTRY ExtCreatePen(DWORD dwPenStyle, DWORD dwWidth, CONST LOGBRUSH *lplb, DWORD dwStyleCount, CONST DWORD *lpStyle) { PVOID lpPackedDIB = NULL; HPEN hPen = NULL; PBITMAPINFO pConvertedInfo = NULL; UINT ConvertedInfoSize = 0, lbStyle; BOOL Hit = FALSE; if ((dwPenStyle & PS_STYLE_MASK) == PS_USERSTYLE) { if(!lpStyle) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } // This is an enhancement and prevents a call to kernel space. else if ((dwPenStyle & PS_STYLE_MASK) == PS_INSIDEFRAME && (dwPenStyle & PS_TYPE_MASK) != PS_GEOMETRIC) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } else if ((dwPenStyle & PS_STYLE_MASK) == PS_ALTERNATE && (dwPenStyle & PS_TYPE_MASK) != PS_COSMETIC) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } else { if (dwStyleCount || lpStyle) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } lbStyle = lplb->lbStyle; if (lplb->lbStyle > BS_HATCHED) { if (lplb->lbStyle == BS_PATTERN) { pConvertedInfo = (PBITMAPINFO)lplb->lbHatch; if (!pConvertedInfo) return 0; } else { if ((lplb->lbStyle == BS_DIBPATTERN) || (lplb->lbStyle == BS_DIBPATTERNPT)) { if (lplb->lbStyle == BS_DIBPATTERN) { lbStyle = BS_DIBPATTERNPT; lpPackedDIB = GlobalLock((HGLOBAL)lplb->lbHatch); if (lpPackedDIB == NULL) return 0; } pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, lplb->lbColor, &ConvertedInfoSize, TRUE); Hit = TRUE; // We converted DIB. } else pConvertedInfo = (PBITMAPINFO)lpStyle; } } else pConvertedInfo = (PBITMAPINFO)lplb->lbHatch; hPen = NtGdiExtCreatePen(dwPenStyle, dwWidth, lbStyle, lplb->lbColor, lplb->lbHatch, (ULONG_PTR)pConvertedInfo, dwStyleCount, (PULONG)lpStyle, ConvertedInfoSize, FALSE, NULL); if (lplb->lbStyle == BS_DIBPATTERN) GlobalUnlock((HGLOBAL)lplb->lbHatch); if (Hit) { if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); } return hPen; }