Author: jgardou Date: Thu Jul 29 18:01:14 2010 New Revision: 48364
URL: http://svn.reactos.org/svn/reactos?rev=48364&view=rev Log: [WIN32K] - rewrite UserLoadImage so that it uses information from the BITMAPFILEHEADER and probes the right buffer.
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h [iso-8859-1] Thu Jul 29 18:01:14 2010 @@ -18,3 +18,6 @@
HPALETTE FASTCALL BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType); + +BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage); +VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c [iso-8859-1] Thu Jul 29 18:01:14 2010 @@ -157,14 +157,12 @@ NTAPI UserLoadImage(PCWSTR pwszName) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; HANDLE hFile, hSection; BITMAPFILEHEADER *pbmfh; LPBITMAPINFO pbmi; - ULONG cjInfoSize; PVOID pvBits; HBITMAP hbmp = 0; - BITMAPV5INFO bmiLocal;
DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
@@ -194,40 +192,58 @@ /* Get a pointer to the BITMAPINFO */ pbmi = (LPBITMAPINFO)(pbmfh + 1);
- /* Create a normalized local BITMAPINFO */ - _SEH2_TRY - { - Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, - pbmi, - DIB_RGB_COLORS, - 0); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END - - if (NT_SUCCESS(Status)) - { - cjInfoSize = bmiLocal.bmiHeader.bV5Size + - bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD); - pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize); + _SEH2_TRY + { + ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1); + ProbeForRead(pbmfh, pbmfh->bfSize, 1); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END + + if(!NT_SUCCESS(Status)) + { + DPRINT1("Bad File?\n"); + goto leave; + } + + if (pbmfh->bfType == 0x4D42 /* 'BM' */) + { + /* Could be BITMAPCOREINFO */ + BITMAPINFO* pConvertedInfo; + + pvBits = (PVOID)((PCHAR)pbmi + pbmfh->bfOffBits); + + pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS); + if(!pConvertedInfo) + { + DPRINT1("Unable to convert the bitmap Info\n"); + goto leave; + }
// FIXME: use Gre... so that the BITMAPINFO doesn't get probed hbmp = NtGdiCreateDIBitmapInternal(NULL, - bmiLocal.bmiHeader.bV5Width, - bmiLocal.bmiHeader.bV5Height, + pConvertedInfo->bmiHeader.biWidth, + pConvertedInfo->bmiHeader.biHeight, CBM_INIT, pvBits, pbmi, DIB_RGB_COLORS, - bmiLocal.bmiHeader.bV5Size, - bmiLocal.bmiHeader.bV5SizeImage, + pConvertedInfo->bmiHeader.biSize, + pConvertedInfo->bmiHeader.biSizeImage, 0, 0); - } - + + DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi); + } + else + { + DPRINT1("Unknown file type!\n"); + } + +leave: /* Unmap our section, we don't need it anymore */ ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] Thu Jul 29 18:01:14 2010 @@ -674,18 +674,12 @@ /* We need a BITMAPINFO to create a DIB, but we have to fill * the BITMAPCOREINFO we're provided */ pbmci = (BITMAPCOREINFO*)Info; - Info = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), TAG_DIB); + Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage); if(Info == NULL) { - DPRINT1("Error, could not allocate another BITMAPINFO!\n"); + DPRINT1("Error, could not convert the BITMAPCOREINFO!\n"); return 0; } - RtlZeroMemory(Info, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); - Info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - Info->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount; - Info->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes; - Info->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth; - Info->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight; rgbQuads = Info->bmiColors; }
@@ -1050,7 +1044,7 @@
if(pDC) DC_UnlockDc(pDC); if(psurf) SURFACE_UnlockSurface(psurf); - if(pbmci) ExFreePoolWithTag(Info, TAG_DIB); + if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
return ScanLines; } @@ -2077,4 +2071,82 @@ return STATUS_SUCCESS; }
+/* Converts a BITMAPCOREINFO to a BITMAPINFO structure, + * or does nothing if it's already a BITMAPINFO (or V4 or V5) */ +BITMAPINFO* +FASTCALL +DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage) +{ + CONST BITMAPCOREINFO* pbmci = (BITMAPCOREINFO*)pbmi; + BITMAPINFO* pNewBmi ; + UINT numColors = 0, ColorsSize = 0; + + if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi; + if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL; + + if(pbmci->bmciHeader.bcBitCount <= 8) + { + numColors = 1 << pbmci->bmciHeader.bcBitCount; + if(Usage == DIB_PAL_COLORS) + { + ColorsSize = numColors * sizeof(WORD); + } + else + { + ColorsSize = numColors * sizeof(RGBQUAD); + } + } + else if (Usage == DIB_PAL_COLORS) + { + /* Invalid at high Res */ + return NULL; + } + + pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB); + if(!pNewBmi) return NULL; + + RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize); + + pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount; + pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth; + pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight; + pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes; + pNewBmi->bmiHeader.biCompression = BI_RGB ; + pNewBmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth, + pNewBmi->bmiHeader.biHeight, + pNewBmi->bmiHeader.biBitCount); + + if(Usage == DIB_PAL_COLORS) + { + RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize); + } + else + { + UINT i; + for(i=0; i<numColors; i++) + { + pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed; + pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen; + pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue; + } + } + + return pNewBmi ; +} + +/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */ +VOID +FASTCALL +DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig) +{ + if(converted != orig) + ExFreePoolWithTag(converted, TAG_DIB); +} + + + + + + /* EOF */