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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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 */