[WIN32K]
authorJérôme Gardou <jerome.gardou@reactos.org>
Wed, 9 Jun 2010 00:08:50 +0000 (00:08 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Wed, 9 Jun 2010 00:08:50 +0000 (00:08 +0000)
  - More BITMAPV5INFO fun
  - Probe max size we are asked for when converting to V5 Info
[USER32] [WIN32K]
  - CreateDIBitmap : Move safety handling to win32k, where it belongs. More code cleanness!

svn path=/branches/reactos-yarotows/; revision=47701

dll/win32/gdi32/objects/bitmap.c
subsystems/win32/win32k/include/bitmaps.h
subsystems/win32/win32k/misc/file.c
subsystems/win32/win32k/objects/dibobj.c

index 2c7d4ce..1b5f66f 100644 (file)
@@ -43,16 +43,16 @@ DIB_BitmapBitsSize( PBITMAPINFO Info )
   if ( Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
   {
      PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
-     Ret = Core->bcHeight * 
+     Ret = Core->bcHeight *
           ((Core->bcWidth * Core->bcPlanes * Core->bcBitCount  + 31) & ~31 ) / 8;
   }
   else /* assume BITMAPINFOHEADER */
   {
-     if ((Info->bmiHeader.biCompression) && 
+     if ((Info->bmiHeader.biCompression) &&
          (Info->bmiHeader.biCompression != BI_BITFIELDS))
          return Info->bmiHeader.biSizeImage;
         // Make Height positive always....
-     Ret = abs(Info->bmiHeader.biHeight) * 
+     Ret = abs(Info->bmiHeader.biHeight) *
           ((Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes * Info->bmiHeader.biBitCount + 31) & ~31 ) / 8;
   }
   return Ret;
@@ -132,12 +132,12 @@ WINAPI
 GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
 {
     int retSize;
-    
+
     if (lpbmi->bmiHeader.biSize == FIELD_OFFSET(BITMAPINFOHEADER, biPlanes))
     {
         /* Calc the bits Size and align it*/
-        retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) * 
-                  LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31) 
+        retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) *
+                  LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31)
                   & -32) / 8;
     }
     else
@@ -148,13 +148,13 @@ GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
             if (lpbmi->bmiHeader.biHeight >=0 )
             {
                 /* Calc the bits Size and align it*/
-                retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth * 
+                retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth *
                           lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
             }
             else
             {
                 /* Make height postiive if it negitve then calc the bits Size and align it*/
-                retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth * 
+                retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth *
                           lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
             }
         }
@@ -189,7 +189,7 @@ CreateDIBSection(
    {  // Verify header due to converted may == info.
       if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
       {
-         if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG || 
+         if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
               pConvertedInfo->bmiHeader.biCompression  == BI_PNG )
          {
             SetLastError(ERROR_INVALID_PARAMETER);
@@ -319,7 +319,7 @@ CreateBitmapIndirect(const BITMAP *pbm)
         (!(pbm->bmWidthBytes & 1)) )
 
    {
-        
+
       bitmap = CreateBitmap(pbm->bmWidth,
                             pbm->bmHeight,
                             pbm->bmPlanes,
@@ -409,7 +409,7 @@ GetDIBits(
      {
         if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
         {
-           if ( lpbmi->bmiHeader.biCompression == BI_JPEG || 
+           if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
                 lpbmi->bmiHeader.biCompression == BI_PNG )
            {
               SetLastError(ERROR_INVALID_PARAMETER);
@@ -461,78 +461,40 @@ CreateDIBitmap( HDC hDC,
   LONG width, height, compr, dibsize;
   WORD planes, bpp;
 //  PDC_ATTR pDc_Attr;
-  PBITMAPINFO pConvertedInfo;
   UINT ConvertedInfoSize;
   UINT cjBmpScanSize;
-  PVOID pvSafeBits = NULL;
   HBITMAP hBmp;
 
   if (!Header) return 0;
 
-  pConvertedInfo = ConvertBitmapInfo(Data, ColorUse,
-                                          &ConvertedInfoSize, FALSE);
-
   if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1)
   {
      GdiSetLastError(ERROR_INVALID_PARAMETER);
      return NULL;
   }
 
-  if ( pConvertedInfo )
-  {
-     if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
-     {
-        if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG || 
-             pConvertedInfo->bmiHeader.biCompression == BI_PNG )
-        {
-           hBmp = NULL;
-           goto Exit;
-        }
-     }
-  }
-  
 // For Icm support.
 // GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
 
-  cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
-  DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", pConvertedInfo,bpp,dibsize,ConvertedInfoSize,cjBmpScanSize);
+  cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)Header);
+  DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", Data,bpp,dibsize,ConvertedInfoSize,cjBmpScanSize);
 
   if ( !width || !height )
      hBmp = GetStockObject(DEFAULT_BITMAP);
   else
   {
-     if ( Bits && Init == CBM_INIT )
-     {
-        pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
-        if (pvSafeBits == NULL)
-        {
-            hBmp = NULL;
-            goto Exit;
-        }
-        else
-        {
-           RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize);
-        }
-     }
-
      hBmp = NtGdiCreateDIBitmapInternal(hDC,
                                         width,
                                         height,
                                         Init,
-                                        (LPBYTE)pvSafeBits,
-                                        (PBITMAPINFO)pConvertedInfo,
+                                        (LPBYTE)Bits,
+                                        (LPBITMAPINFO)Data,
                                         ColorUse,
                                         ConvertedInfoSize,
                                         cjBmpScanSize,
                                         0,
                                         0);
-
-     if ( Bits && Init == CBM_INIT )
-        RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
   }
-Exit:
-  if (Data != pConvertedInfo)
-     RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
   return hBmp;
 }
 
@@ -588,7 +550,7 @@ SetDIBits(HDC hDC,
 
  if ( hOldBitmap )
  {
-    if ( hDC )    
+    if ( hDC )
       hPal = SelectPalette(SavehDC, (HPALETTE)GetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE), FALSE);
 
     if ( lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
@@ -782,7 +744,7 @@ SetDIBitsToDevice(
 /*
   if ( !pDc_Attr ||
        ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
-       (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || 
+       (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
         pConvertedInfo->bmiHeader.biCompression  == BI_PNG )) )*/
   {
     LinesCopied = NtGdiSetDIBitsToDeviceInternal( hdc,
@@ -806,7 +768,7 @@ SetDIBitsToDevice(
      RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
   if (lpbmi != pConvertedInfo)
      RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
-         
+
   return LinesCopied;
 }
 
@@ -933,7 +895,7 @@ StretchDIBits(HDC hdc,
 /*
   if ( !pDc_Attr ||
        ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
-       (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || 
+       (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
         pConvertedInfo->bmiHeader.biCompression  == BI_PNG )) )*/
   {
      LinesCopied = NtGdiStretchDIBitsInternal( hdc,
index cc3b47b..383322c 100644 (file)
@@ -13,7 +13,7 @@ HBITMAP FASTCALL IntCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format,
 HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP  hBitmap);
 UINT    FASTCALL BITMAP_GetRealBitsPixel(UINT nBitsPixel);
 INT     FASTCALL BITMAP_GetWidthBytes (INT bmWidth, INT bpp);
-NTSTATUS FASTCALL ProbeAndConvertToBitmapV5Info( OUT PBITMAPV5INFO pbmiDst, IN CONST BITMAPINFO* pbmiUnsafe, IN DWORD dwUse);
+NTSTATUS FASTCALL ProbeAndConvertToBitmapV5Info( OUT PBITMAPV5INFO pbmiDst, IN CONST BITMAPINFO* pbmiUnsafe, IN DWORD dwUse, UINT MaxSize);
 VOID FASTCALL GetBMIFromBitmapV5Info(IN PBITMAPV5INFO pbmiSrc, OUT PBITMAPINFO pbmiDst, IN DWORD dwUse);
 
 HBITMAP
index f8b9325..365b099 100644 (file)
@@ -199,7 +199,8 @@ UserLoadImage(PCWSTR pwszName)
     {
         Status = ProbeAndConvertToBitmapV5Info(&bmiLocal,
                                                pbmi,
-                                               DIB_RGB_COLORS);
+                                               DIB_RGB_COLORS,
+                                               0);
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
index c7e34f1..7c7cfed 100644 (file)
@@ -354,7 +354,8 @@ NtGdiSetDIBits(
 
     _SEH2_TRY
     {
-        Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse);
+        Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, 0);
+        /* Don't check Bits and hope we won't die */
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -427,7 +428,8 @@ NtGdiSetDIBitsToDeviceInternal(
 
     _SEH2_TRY
     {
-        Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse);
+        Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, cjMaxInfo);
+        ProbeForRead(Bits, cjMaxBits, 1);
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -595,7 +597,7 @@ NtGdiGetDIBitsInternal(
 
     _SEH2_TRY
     {
-        Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, Info, Usage);
+        Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, Info, Usage, MaxInfo);
         if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -842,7 +844,7 @@ NtGdiGetDIBitsInternal(
                                               bmiLocal.bmiHeader.bV5BitCount) * DestSize.cy;
 
             hDestBitmap = EngCreateBitmap(DestSize,
-                                          DIB_GetDIBWidthBytes(DestSize.cx, 
+                                          DIB_GetDIBWidthBytes(DestSize.cx,
                                                                bmiLocal.bmiHeader.bV5BitCount),
                                           BitmapFormat(bmiLocal.bmiHeader.bV5BitCount,
                                                        bmiLocal.bmiHeader.bV5Compression),
@@ -942,7 +944,8 @@ NtGdiStretchDIBitsInternal(
     HDC hdcMem;
     HPALETTE hPal = NULL;
     PDC pDC;
-    BOOL Hit = FALSE;
+    NTSTATUS Status;
+    BITMAPV5INFO bmiLocal ;
 
     if (!Bits || !BitsInfo)
     {
@@ -952,16 +955,16 @@ NtGdiStretchDIBitsInternal(
 
     _SEH2_TRY
     {
-        ProbeForRead(BitsInfo, cjMaxInfo, 1);
+        Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, BitsInfo, Usage, cjMaxInfo);
         ProbeForRead(Bits, cjMaxBits, 1);
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        Hit = TRUE;
+        Status = _SEH2_GetExceptionCode();
     }
     _SEH2_END
 
-    if (Hit)
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits);
         return 0;
@@ -975,8 +978,8 @@ NtGdiStretchDIBitsInternal(
     }
 
     hBitmap = NtGdiCreateCompatibleBitmap(hDC,
-                                          abs(BitsInfo->bmiHeader.biWidth),
-                                          abs(BitsInfo->bmiHeader.biHeight));
+                                          abs(bmiLocal.bmiHeader.bV5Width),
+                                          abs(bmiLocal.bmiHeader.bV5Height));
     if (hBitmap == NULL)
     {
         DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n");
@@ -995,15 +998,15 @@ NtGdiStretchDIBitsInternal(
         hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
     }
 
-    if (BitsInfo->bmiHeader.biCompression == BI_RLE4 ||
-            BitsInfo->bmiHeader.biCompression == BI_RLE8)
+    if (bmiLocal.bmiHeader.bV5Compression == BI_RLE4 ||
+            bmiLocal.bmiHeader.bV5Compression == BI_RLE8)
     {
         /* copy existing bitmap from destination dc */
         if (SrcWidth == DestWidth && SrcHeight == DestHeight)
-            NtGdiBitBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
+            NtGdiBitBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
                         SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
         else
-            NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
+            NtGdiStretchBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
                             SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
                             ROP, 0);
     }
@@ -1015,8 +1018,8 @@ NtGdiStretchDIBitsInternal(
          * if it negitve we getting to many scanline for scanline is UINT not
          * a INT, so we need make the negtive value to positve and that make the
          * count correct for negtive bitmap, TODO : we need testcase for this api */
-        IntSetDIBits(pDC, hBitmap, 0, abs(BitsInfo->bmiHeader.biHeight), Bits,
-                     BitsInfo, Usage);
+        IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits,
+                     (PBITMAPINFO)&bmiLocal, Usage);
 
         DC_UnlockDc(pDC);
     }
@@ -1026,11 +1029,11 @@ NtGdiStretchDIBitsInternal(
        left (negative biHeight) */
     if (SrcWidth == DestWidth && SrcHeight == DestHeight)
         NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight,
-                    hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
+                    hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
                     ROP, 0, 0);
     else
         NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
-                        hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
+                        hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
                         SrcWidth, SrcHeight, ROP, 0);
 
     /* cleanup */
@@ -1057,7 +1060,7 @@ IntCreateDIBitmap(
     UINT bpp,
     DWORD init,
     LPBYTE bits,
-    PBITMAPINFO data,
+    PBITMAPV5INFO data,
     DWORD coloruse)
 {
     HBITMAP handle;
@@ -1070,40 +1073,19 @@ IntCreateDIBitmap(
     else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
     else
     {
-        if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
-        {
-            const RGBQUAD *rgb = data->bmiColors;
-            DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
-
-            // Check if the first color of the colormap is black
-            if ((col == RGB(0, 0, 0)))
-            {
-                rgb++;
-                col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
+        const RGBQUAD *rgb = data->bmiColors;
+        DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
 
-                // If the second color is white, create a monochrome bitmap
-                fColor = (col != RGB(0xff,0xff,0xff));
-            }
-            else fColor = TRUE;
-        }
-        else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+        // Check if the first color of the colormap is black
+        if ((col == RGB(0, 0, 0)))
         {
-            RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
-            DWORD col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
+            rgb++;
+            col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
 
-            if ((col == RGB(0,0,0)))
-            {
-                rgb++;
-                col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
-                fColor = (col != RGB(0xff,0xff,0xff));
-            }
-            else fColor = TRUE;
-        }
-        else
-        {
-            DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize);
-            return 0;
+            // If the second color is white, create a monochrome bitmap
+            fColor = (col != RGB(0xff,0xff,0xff));
         }
+        else fColor = TRUE;
     }
 
     // Now create the bitmap
@@ -1125,7 +1107,7 @@ IntCreateDIBitmap(
 
     if (NULL != handle && CBM_INIT == init)
     {
-        IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
+        IntSetDIBits(Dc, handle, 0, height, bits, (BITMAPINFO*)data, coloruse);
     }
 
     return handle;
@@ -1151,6 +1133,25 @@ NtGdiCreateDIBitmapInternal(
     PDC Dc;
     HBITMAP Bmp;
     UINT bpp;
+    BITMAPV5INFO bmiLocal ;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    _SEH2_TRY
+    {
+        if(pbmi) Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, pbmi, iUsage, cjMaxInitInfo);
+        if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END
+
+    if(!NT_SUCCESS(Status))
+    {
+        SetLastNtError(Status);
+        return NULL;
+    }
 
     if (!hDc) // CreateBitmap
     {  // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
@@ -1169,7 +1170,7 @@ NtGdiCreateDIBitmapInternal(
             return NULL;
         }
         bpp = 1;
-        Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+        Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi ? &bmiLocal : NULL, iUsage);
 
         DC_UnlockDc(Dc);
         NtGdiDeleteObjectApp(hDc);
@@ -1187,7 +1188,7 @@ NtGdiCreateDIBitmapInternal(
            should match that of the hdc and not that supplied in bmih.
          */
         if (pbmi)
-            bpp = pbmi->bmiHeader.biBitCount;
+            bpp = bmiLocal.bmiHeader.bV5BitCount;
         else
         {
             if (Dc->dctype != DC_TYPE_MEMORY)
@@ -1211,7 +1212,7 @@ NtGdiCreateDIBitmapInternal(
                 }
             }
         }
-        Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+        Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi ? &bmiLocal : NULL, iUsage);
         DC_UnlockDc(Dc);
     }
     return Bmp;
@@ -1760,7 +1761,8 @@ FASTCALL
 ProbeAndConvertToBitmapV5Info(
     OUT PBITMAPV5INFO pbmiDst,
     IN CONST BITMAPINFO* pbmiUnsafe,
-    IN DWORD dwColorUse)
+    IN DWORD dwColorUse,
+    IN UINT MaxSize)
 {
     DWORD dwSize;
     ULONG ulWidthBytes;
@@ -1769,7 +1771,8 @@ ProbeAndConvertToBitmapV5Info(
     /* Get the size and probe */
     ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
     dwSize = pbmiUnsafe->bmiHeader.biSize;
-    ProbeForRead(pbmiUnsafe, dwSize, 1);
+    /* At least dwSize bytes must be valids */
+    ProbeForRead(pbmiUnsafe, max(dwSize, MaxSize), 1);
 
     /* Check the size */
     // FIXME: are intermediate sizes allowed? As what are they interpreted?