[ros-diffs] [jgardou] 48364: [WIN32K] - rewrite UserLoadImage so that it uses information from the BITMAPFILEHEADER and probes the right buffer.

jgardou at svn.reactos.org jgardou at svn.reactos.org
Thu Jul 29 18:01:15 UTC 2010


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/win32/win32k/include/dib.h?rev=48364&r1=48363&r2=48364&view=diff
==============================================================================
--- 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/win32/win32k/misc/file.c?rev=48364&r1=48363&r2=48364&view=diff
==============================================================================
--- 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/win32/win32k/objects/dibobj.c?rev=48364&r1=48363&r2=48364&view=diff
==============================================================================
--- 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 */




More information about the Ros-diffs mailing list