RT2301: GetDIBits, not GetBitmapBits in rand_win
authorJake Goulding <goulding@vivisimo.com>
Fri, 5 Sep 2014 15:13:23 +0000 (11:13 -0400)
committerRich Salz <rsalz@openssl.org>
Thu, 18 Sep 2014 20:41:31 +0000 (16:41 -0400)
GetDIBits has been around since Windows2000 and
BitBitmapBits is an old Win16 compatibility function
that is much slower.

Reviewed-by: Tim Hudson <tjh@openssl.org>
crypto/rand/rand_win.c

index 73f261f122b2d2a99d8ab35bda243c96c6194d93..e5195118ca8c022a0f2fb2a60a7100103f3b2082 100644 (file)
@@ -741,9 +741,7 @@ static void readscreen(void)
 {
 #if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN)
   HDC          hScrDC;         /* screen DC */
-  HDC          hMemDC;         /* memory DC */
   HBITMAP      hBitmap;        /* handle for our bitmap */
-  HBITMAP      hOldBitmap;     /* handle for previous bitmap */
   BITMAP       bm;             /* bitmap properties */
   unsigned int size;           /* size of bitmap */
   char         *bmbits;        /* contents of bitmap */
@@ -751,13 +749,13 @@ static void readscreen(void)
   int          h;              /* screen height */
   int          y;              /* y-coordinate of screen lines to grab */
   int          n = 16;         /* number of screen lines to grab at a time */
+  BITMAPINFOHEADER bi;         /* info about the bitmap */
 
   if (check_winnt() && OPENSSL_isservice()>0)
     return;
 
-  /* Create a screen DC and a memory DC compatible to screen DC */
-  hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
-  hMemDC = CreateCompatibleDC(hScrDC);
+  /* Get a reference to the screen DC */
+  hScrDC = GetDC(NULL);
 
   /* Get screen resolution */
   w = GetDeviceCaps(hScrDC, HORZRES);
@@ -766,13 +764,22 @@ static void readscreen(void)
   /* Create a bitmap compatible with the screen DC */
   hBitmap = CreateCompatibleBitmap(hScrDC, w, n);
 
-  /* Select new bitmap into memory DC */
-  hOldBitmap = SelectObject(hMemDC, hBitmap);
-
   /* Get bitmap properties */
   GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
   size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes;
 
+  bi.biSize = sizeof(BITMAPINFOHEADER);
+  bi.biWidth = bm.bmWidth;
+  bi.biHeight = bm.bmHeight;
+  bi.biPlanes = bm.bmPlanes;
+  bi.biBitCount = bm.bmBitsPixel;
+  bi.biCompression = BI_RGB;
+  bi.biSizeImage = 0;
+  bi.biXPelsPerMeter = 0;
+  bi.biYPelsPerMeter = 0;
+  bi.biClrUsed = 0;
+  bi.biClrImportant = 0;
+
   bmbits = OPENSSL_malloc(size);
   if (bmbits) {
     /* Now go through the whole screen, repeatedly grabbing n lines */
@@ -780,11 +787,9 @@ static void readscreen(void)
        {
        unsigned char md[MD_DIGEST_LENGTH];
 
-       /* Bitblt screen DC to memory DC */
-       BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY);
-
-       /* Copy bitmap bits from memory DC to bmbits */
-       GetBitmapBits(hBitmap, size, bmbits);
+       /* Copy the bits of the current line range into the buffer */
+       GetDIBits(hScrDC, hBitmap, y, n,
+                 bmbits, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
 
        /* Get the hash of the bitmap */
        MD(bmbits,size,md);
@@ -796,13 +801,9 @@ static void readscreen(void)
     OPENSSL_free(bmbits);
   }
 
-  /* Select old bitmap back into memory DC */
-  hBitmap = SelectObject(hMemDC, hOldBitmap);
-
   /* Clean up */
   DeleteObject(hBitmap);
-  DeleteDC(hMemDC);
-  DeleteDC(hScrDC);
+  ReleaseDC(NULL, hScrDC);
 #endif /* !OPENSSL_SYS_WINCE */
 }