[ros-diffs] [tkreuzer] 28110: NtGdiGetSetBitmapBits: - use SEH and probe the user mode buffers - SetLastWin32Error on invalid handle - move the copying to IntGetSetBitmapBits - only use IntGetSetBitmapBits from inside win32k - move NtGdiGetBitmapBits to bitmap.c - allow copying a number of bytes not matching one entire line, like on windows I think that was all changes.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Fri Aug 3 00:14:32 CEST 2007


Author: tkreuzer
Date: Fri Aug  3 02:14:32 2007
New Revision: 28110

URL: http://svn.reactos.org/svn/reactos?rev=28110&view=rev
Log:
NtGdiGetSetBitmapBits:
- use SEH and probe the user mode buffers
- SetLastWin32Error on invalid handle
- move the copying to IntGetSetBitmapBits
- only use IntGetSetBitmapBits from inside win32k
- move NtGdiGetBitmapBits to bitmap.c
- allow copying a number of bytes not matching one entire line, like on windows
I think that was all changes.

Modified:
    trunk/reactos/subsystems/win32/win32k/include/intgdi.h
    trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
    trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c
    trunk/reactos/subsystems/win32/win32k/objects/dibobj.c

Modified: trunk/reactos/subsystems/win32/win32k/include/intgdi.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/intgdi.h?rev=28110&r1=28109&r2=28110&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/intgdi.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/intgdi.h Fri Aug  3 02:14:32 2007
@@ -259,5 +259,9 @@
 
 VOID STDCALL IntGdiSetDCState ( HDC hDC, HDC hDCSave );
 
+LONG STDCALL IntSetBitmapBits(PBITMAPOBJ bmp, DWORD  Bytes, IN PBYTE Bits);
+
+LONG STDCALL IntGetBitmapBits(PBITMAPOBJ bmp, DWORD Bytes, OUT PBYTE Bits);
+
 #endif /* _WIN32K_INTGDI_H */
 

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c?rev=28110&r1=28109&r2=28110&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c Fri Aug  3 02:14:32 2007
@@ -1552,7 +1552,7 @@
             }
 
             /* get icon bits */
-            NtGdiGetBitmapBits(hbmOff, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
+            IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
 
             /* premultiply with the alpha channel value */
             for (i = 0; i < cyHeight; i++)
@@ -1581,7 +1581,7 @@
             }
 
             /* set icon bits */
-            NtGdiSetBitmapBits(hbmOff, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
+            IntSetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
             ExFreePool(pBits);
 
             GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);

Modified: trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c?rev=28110&r1=28109&r2=28110&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c Fri Aug  3 02:14:32 2007
@@ -406,7 +406,7 @@
     INT  Height,
     UINT  Planes,
     UINT  BitsPixel,
-    IN OPTIONAL LPBYTE Bits)
+    IN OPTIONAL LPBYTE pUnsafeBits)
 {
    PBITMAPOBJ bmp;
    HBITMAP hBitmap;
@@ -432,7 +432,7 @@
    hBitmap = IntCreateBitmap(Size, WidthBytes,
                              BitmapFormat(BitsPixel, BI_RGB),
                              (Height < 0 ? BMF_TOPDOWN : 0) |
-                             (NULL == Bits ? 0 : BMF_NOZEROINIT), NULL);
+                             (NULL == pUnsafeBits ? 0 : BMF_NOZEROINIT), NULL);
    if (!hBitmap)
    {
       DPRINT("NtGdiCreateBitmap: returned 0\n");
@@ -450,18 +450,21 @@
    }
    
    bmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
+
+   if (NULL != pUnsafeBits)
+   {
+      _SEH_TRY
+      {
+         ProbeForRead(pUnsafeBits, bmp->SurfObj.cjBits, 1);
+         IntSetBitmapBits(bmp, bmp->SurfObj.cjBits, pUnsafeBits);
+      }
+      _SEH_HANDLE
+      {
+      }
+      _SEH_END
+   }
+
    BITMAPOBJ_UnlockBitmap( bmp );
-
-   /*
-    * NOTE: It's ugly practice, but we are using the object even
-    * after unlocking. Since the handle is currently known only
-    * to us it should be safe.
-    */
-
-   if (NULL != Bits)
-   {
-      NtGdiSetBitmapBits(hBitmap, bmp->SurfObj.cjBits, Bits);
-   }
 
    return hBitmap;
 }
@@ -911,64 +914,160 @@
 	return FALSE;
 }
 
+
+LONG STDCALL
+IntGetBitmapBits(
+	PBITMAPOBJ bmp,
+	DWORD Bytes,
+	OUT PBYTE Bits)
+{
+	LONG ret;
+
+	ASSERT(Bits);
+
+	/* Don't copy more bytes than the buffer has */
+	Bytes = min(Bytes, bmp->SurfObj.cjBits);
+
+#if 0
+	/* FIXME: Call DDI CopyBits here if available  */
+	if(bmp->DDBitmap)
+	{
+		DPRINT("Calling device specific BitmapBits\n");
+		if(bmp->DDBitmap->funcs->pBitmapBits)
+		{
+			ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count, DDB_GET);
+		}
+		else
+		{
+			ERR_(bitmap)("BitmapBits == NULL??\n");
+			ret = 0;
+		}
+	}
+	else
+#endif
+	{
+		RtlCopyMemory(Bits, bmp->SurfObj.pvBits, Bytes);
+		ret = Bytes;
+	}
+	return ret;
+}
+
+LONG STDCALL
+NtGdiGetBitmapBits(HBITMAP  hBitmap,
+                   ULONG  Bytes,
+                   OUT OPTIONAL PBYTE pUnsafeBits)
+{
+	PBITMAPOBJ  bmp;
+	LONG  ret;
+
+	if (pUnsafeBits != NULL && Bytes == 0)
+	{
+		return 0;
+	}
+
+	bmp = BITMAPOBJ_LockBitmap (hBitmap);
+	if (!bmp)
+	{
+		SetLastWin32Error(ERROR_INVALID_HANDLE);
+		return 0;
+	}
+
+	/* If the bits vector is null, the function should return the read size */
+	if (pUnsafeBits == NULL)
+	{
+		ret = bmp->SurfObj.cjBits;
+		BITMAPOBJ_UnlockBitmap (bmp);
+		return ret;
+	}
+
+	/* Don't copy more bytes than the buffer has */
+	Bytes = min(Bytes, bmp->SurfObj.cjBits);
+
+	_SEH_TRY
+	{
+		ProbeForWrite(pUnsafeBits, Bytes, 1);
+		ret = IntGetBitmapBits(bmp, Bytes, pUnsafeBits);
+	}
+	_SEH_HANDLE
+	{
+		ret = 0;
+	}
+	_SEH_END
+
+	BITMAPOBJ_UnlockBitmap (bmp);
+
+	return  ret;
+}
+
+
+LONG STDCALL
+IntSetBitmapBits(
+	PBITMAPOBJ bmp,
+	DWORD  Bytes,
+	IN PBYTE Bits)
+{
+	LONG ret;
+
+	/* Don't copy more bytes than the buffer has */
+	Bytes = min(Bytes, bmp->SurfObj.cjBits);
+
+#if 0
+	/* FIXME: call DDI specific function here if available  */
+	if(bmp->DDBitmap)
+	{
+		DPRINT ("Calling device specific BitmapBits\n");
+		if (bmp->DDBitmap->funcs->pBitmapBits)
+		{
+			ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
+		}
+		else
+		{
+			DPRINT ("BitmapBits == NULL??\n");
+			ret = 0;
+		}
+	}
+	else
+#endif
+	{
+		RtlCopyMemory(bmp->SurfObj.pvBits, Bits, Bytes);
+		ret = Bytes;
+	}
+
+	return ret;
+}
+
+
 LONG STDCALL
 NtGdiSetBitmapBits(
 	HBITMAP  hBitmap,
 	DWORD  Bytes,
-	IN PBYTE Bits)
-{
-	LONG height, ret;
+	IN PBYTE pUnsafeBits)
+{
+	LONG ret;
 	PBITMAPOBJ bmp;
 
+	if (pUnsafeBits == NULL || Bytes == 0)
+	{
+		return 0;
+	}
+
 	bmp = BITMAPOBJ_LockBitmap(hBitmap);
-	if (bmp == NULL || Bits == NULL)
-	{
+	if (bmp == NULL)
+	{
+		SetLastWin32Error(ERROR_INVALID_HANDLE);
 		return 0;
 	}
 
-	if (Bytes < 0)
-	{
-		DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
-		Bytes = -Bytes;
-	}
-
-	/* Only get entire lines */
-	height = Bytes / abs(bmp->SurfObj.lDelta);
-	if (height > bmp->SurfObj.sizlBitmap.cy)
-	{
-		height = bmp->SurfObj.sizlBitmap.cy;
-	}
-	Bytes = height * abs(bmp->SurfObj.lDelta);
-	DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
-		hBitmap,
-		Bytes,
-		Bits,
-		bmp->SurfObj.sizlBitmap.cx,
-		bmp->SurfObj.sizlBitmap.cy,
-		1 << BitsPerFormat(bmp->SurfObj.iBitmapFormat),
-		height);
-
-#if 0
-	/* FIXME: call DDI specific function here if available  */
-	if(bmp->DDBitmap)
-	{
-		DPRINT ("Calling device specific BitmapBits\n");
-		if (bmp->DDBitmap->funcs->pBitmapBits)
-		{
-			ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
-		}
-		else
-		{
-			DPRINT ("BitmapBits == NULL??\n");
-			ret = 0;
-		}
-	}
-	else
-#endif
-	{
-		memcpy(bmp->SurfObj.pvBits, Bits, Bytes);
-		ret = Bytes;
-	}
+	_SEH_TRY
+	{
+		ProbeForRead(pUnsafeBits, Bytes, 1);
+		ret = IntSetBitmapBits(bmp, Bytes, pUnsafeBits);
+	}
+	_SEH_HANDLE
+	{
+		ret = 0;
+	}
+	_SEH_END
 
 	BITMAPOBJ_UnlockBitmap(bmp);
 
@@ -1464,7 +1563,7 @@
 {
 	HBITMAP  res;
 	BITMAP  bm;
-	BITMAPOBJ *Bitmap;
+	BITMAPOBJ *Bitmap, *resBitmap;
 
 	if (hBitmap == NULL)
 	{
@@ -1491,10 +1590,15 @@
 	{
 		PBYTE buf;
 
-		buf = ExAllocatePoolWithTag (PagedPool, bm.bmWidthBytes * abs(bm.bmHeight), TAG_BITMAP);
-		NtGdiGetBitmapBits (hBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
-		NtGdiSetBitmapBits (res, bm.bmWidthBytes * abs(bm.bmHeight), buf);
-		ExFreePool (buf);
+		resBitmap = GDIOBJ_LockObj(GdiHandleTable, res, GDI_OBJECT_TYPE_BITMAP);
+		if (resBitmap)
+		{
+			buf = ExAllocatePoolWithTag (PagedPool, bm.bmWidthBytes * abs(bm.bmHeight), TAG_BITMAP);
+			IntGetBitmapBits (Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
+			IntSetBitmapBits (resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
+			ExFreePool (buf);
+			GDIOBJ_UnlockObjByPtr(GdiHandleTable, resBitmap);
+		}
 	}
 
 	GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);

Modified: trunk/reactos/subsystems/win32/win32k/objects/dibobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/dibobj.c?rev=28110&r1=28109&r2=28110&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/dibobj.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/dibobj.c Fri Aug  3 02:14:32 2007
@@ -631,78 +631,6 @@
    return SrcHeight;
 }
 
-LONG STDCALL NtGdiGetBitmapBits(HBITMAP  hBitmap,
-                        ULONG  Count,
-                        OUT OPTIONAL PBYTE Bits)
-{
-  PBITMAPOBJ  bmp;
-  LONG  height, ret;
-
-  bmp = BITMAPOBJ_LockBitmap (hBitmap);
-  if (!bmp)
-  {
-    return 0;
-  }
-
-  /* If the bits vector is null, the function should return the read size */
-  if (Bits == NULL)
-  {
-    ret = bmp->SurfObj.cjBits;
-    BITMAPOBJ_UnlockBitmap (bmp);
-    return ret;
-  }
-
-  if (Count < 0)
-  {
-    DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
-    Count = -Count;
-  }
-
-  /* Only get entire lines */
-  height = Count / abs(bmp->SurfObj.lDelta);
-  if (height > bmp->SurfObj.sizlBitmap.cy)
-  {
-    height = bmp->SurfObj.sizlBitmap.cy;
-  }
-  Count = height * abs(bmp->SurfObj.lDelta);
-  if (Count == 0)
-  {
-    DPRINT("Less then one entire line requested\n");
-    BITMAPOBJ_UnlockBitmap (bmp);
-    return  0;
-  }
-
-  DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
-         hBitmap, Count, Bits, bmp->SurfObj.sizlBitmap.cx,
-         bmp->SurfObj.sizlBitmap.cy,
-         1 << BitsPerFormat(bmp->SurfObj.iBitmapFormat), height );
-#if 0
-  /* FIXME: Call DDI CopyBits here if available  */
-  if(bmp->DDBitmap)
-  {
-    DPRINT("Calling device specific BitmapBits\n");
-    if(bmp->DDBitmap->funcs->pBitmapBits)
-    {
-      ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
-                                              DDB_GET);
-    }
-    else
-    {
-      ERR_(bitmap)("BitmapBits == NULL??\n");
-      ret = 0;
-    }
-  }
-  else
-#endif
-  {
-    memcpy(Bits, bmp->SurfObj.pvBits, Count);
-    ret = Count;
-  }
-
-  BITMAPOBJ_UnlockBitmap (bmp);
-
-  return  ret;
-}
 
 HBITMAP FASTCALL
 IntCreateDIBitmap(PDC Dc, const BITMAPINFOHEADER *header,




More information about the Ros-diffs mailing list