Check for failed allocations and fix some resource leaks.
[reactos.git] / reactos / lib / user32 / windows / bitmap.c
index 166dbfa..16b03fb 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: bitmap.c,v 1.31 2004/07/14 20:52:13 navaraf Exp $
+/* $Id$
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/input.c
 
 /* INCLUDES ******************************************************************/
 
-#include <string.h>
-#include <windows.h>
 #include <user32.h>
-#include <debug.h>
-#include <stdlib.h>
-#define NTOS_MODE_USER
-#include <ntos.h>
 
 /*forward declerations... actualy in user32\windows\icon.c but usful here****/
 HICON ICON_CreateCursorFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot);
@@ -60,7 +54,7 @@ LoadImageA(HINSTANCE hinst,
   UNICODE_STRING NameString;
 
   if (HIWORD(lpszName))
-    {      
+    {
       RtlCreateUnicodeStringFromAsciiz(&NameString, (LPSTR)lpszName);
       lpszWName = NameString.Buffer;
       Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
@@ -76,7 +70,7 @@ LoadImageA(HINSTANCE hinst,
 }
 
 
-HANDLE STATIC
+static HANDLE
 LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
 {
    HANDLE hResource;
@@ -96,7 +90,7 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
    INT id;
    ICONIMAGE *ResIcon;
    UINT ColorBits;
-  
+
    if (!(fuLoad & LR_LOADFROMFILE))
    {
       if (hinst == NULL)
@@ -108,7 +102,7 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
       {
          return NULL;
       }
-         
+
       if (fuLoad & LR_SHARED)
       {
          /* FIXME - pass size! */
@@ -152,111 +146,122 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
       hIcon = (HANDLE)CreateIconFromResourceEx((PBYTE)ResIcon,
          SizeofResource(hinst, h2Resource), FALSE, 0x00030000,
          32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
-      if (hIcon)
+      if (hIcon && 0 != (fuLoad & LR_SHARED))
       {
-         NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes, 
+         NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
                                  (HRSRC)NULL);
       }
 
       return hIcon;
    }
-   else
+
+   if (fuLoad & LR_SHARED)
    {
-      if (fuLoad & LR_SHARED)
-      {
-         DbgPrint("FIXME: need LR_SHARED support loading cursor images from files\n");
-      }
-      
-      hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
-         OPEN_EXISTING, 0, NULL);
-      if (hFile == NULL)
-      {
-         return NULL;
-      }
+      DbgPrint("FIXME: need LR_SHARED support loading cursor images from files\n");
+   }
 
-      hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
-      CloseHandle(hFile);
-      if (hSection == NULL)
-      {
-         return NULL;
-      }
+   hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
+      OPEN_EXISTING, 0, NULL);
+   if (hFile == NULL)
+   {
+      return NULL;
+   }
 
-      IconDIR = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
-      CloseHandle(hSection);
-      if (IconDIR == NULL)
-      {
-         return NULL;
-      }
+   hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+   CloseHandle(hFile);
+   if (hSection == NULL)
+   {
+      return NULL;
+   }
 
-      /* 
-       * Get a handle to the screen dc, the icon we create is going to be
-       * compatable with it.
-       */
-      hScreenDc = CreateCompatibleDC(0);
-      if (hScreenDc == NULL)
-      {
-         UnmapViewOfFile(IconDIR);
-         return NULL;
-      }
+   IconDIR = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
+   CloseHandle(hSection);
+   if (IconDIR == NULL)
+   {
+      return NULL;
+   }
 
-      if (fuLoad & LR_MONOCHROME)
-      {
-         ColorBits = 1;
-      }
-      else
-      {
-         ColorBits = GetDeviceCaps(hScreenDc, BITSPIXEL);
-         /*
-          * FIXME:
-          * Remove this after proper support for alpha icons will be finished.
-          */
-         if (ColorBits > 8)
-            ColorBits = 8;
-      }
+   if (0 != IconDIR->idReserved ||
+       (IMAGE_ICON != IconDIR->idType && IMAGE_CURSOR != IconDIR->idType))
+   {
+      UnmapViewOfFile(IconDIR);
+      return NULL;
+   }
 
-      /* Pick the best size. */
-      dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, 32, 32, ColorBits);
-      if (!dirEntry)
-      {
-         UnmapViewOfFile(IconDIR);
-         return(NULL);
-      }
+   /*
+    * Get a handle to the screen dc, the icon we create is going to be
+    * compatable with it.
+    */
+   hScreenDc = CreateCompatibleDC(0);
+   if (hScreenDc == NULL)
+   {
+      UnmapViewOfFile(IconDIR);
+      return NULL;
+   }
 
-      SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes); 
-      memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
+   if (fuLoad & LR_MONOCHROME)
+   {
+      ColorBits = 1;
+   }
+   else
+   {
+      ColorBits = GetDeviceCaps(hScreenDc, BITSPIXEL);
+      /*
+       * FIXME:
+       * Remove this after proper support for alpha icons will be finished.
+       */
+      if (ColorBits > 8)
+         ColorBits = 8;
    }
 
-  //at this point we have a copy of the icon image to play with
+   /* Pick the best size. */
+   dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, 32, 32, ColorBits);
+   if (!dirEntry)
+   {
+      UnmapViewOfFile(IconDIR);
+      return NULL;
+   }
 
-  SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
+   SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
+   if (SafeIconImage == NULL)
+   {
+      UnmapViewOfFile(IconDIR);
+      return NULL;
+   }
+   memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
+   UnmapViewOfFile(IconDIR);
 
-  if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
-    {
+   /* at this point we have a copy of the icon image to play with */
+
+   SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
+
+   if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
+   {
       BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
       ColorCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
       HeaderSize = sizeof(BITMAPCOREHEADER) + ColorCount * sizeof(RGBTRIPLE);
-    }
-  else
-    {
+   }
+   else
+   {
       ColorCount = SafeIconImage->icHeader.biClrUsed;
       if (ColorCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
        {
          ColorCount = 1 << SafeIconImage->icHeader.biBitCount;
        }
       HeaderSize = sizeof(BITMAPINFOHEADER) + ColorCount * sizeof(RGBQUAD);
-    }
-  
-  //make data point to the start of the XOR image data
-  Data = (PBYTE)SafeIconImage + HeaderSize;
+   }
 
-  hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, 32, 32, dirEntry->Info.cursor.wXHotspot, dirEntry->Info.cursor.wYHotspot);
-  DeleteDC(hScreenDc);
-  RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-  return hIcon;
+   /* make data point to the start of the XOR image data */
+   Data = (PBYTE)SafeIconImage + HeaderSize;
+
+   hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, 32, 32, dirEntry->Info.cursor.wXHotspot, dirEntry->Info.cursor.wYHotspot);
+   DeleteDC(hScreenDc);
+   RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
+   return hIcon;
 }
 
 
-HANDLE STATIC
+static HANDLE
 LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuLoad)
 {
   HANDLE hResource;
@@ -275,7 +280,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
   GRPCURSORICONDIR* IconResDir;
   INT id;
   ICONIMAGE *ResIcon;
-  
+
   if (!(fuLoad & LR_LOADFROMFILE))
   {
       if (hinst == NULL)
@@ -287,7 +292,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
          {
            return(NULL);
          }
-         
+
       if (fuLoad & LR_SHARED)
           {
             hIcon = NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, width, height);
@@ -328,9 +333,9 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
       hIcon = (HANDLE)CreateIconFromResourceEx((PBYTE) ResIcon,
                         SizeofResource(hinst, h2Resource), TRUE, 0x00030000,
                         width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
-      if(hIcon)
+      if (hIcon && 0 != (fuLoad & LR_SHARED))
       {
-        NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes, 
+        NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
                                 (HRSRC)NULL);
       }
       return hIcon;
@@ -338,7 +343,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
   else
   {
       /*
-       * FIXME: This code is incorrect and is likely to crash in many cases. 
+       * FIXME: This code is incorrect and is likely to crash in many cases.
        * In the file the cursor/icon directory records are stored like
        * CURSORICONFILEDIR, but we treat them like CURSORICONDIR. In Wine
        * this is solved by creating a fake cursor/icon directory in memory
@@ -349,7 +354,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
       {
         DbgPrint("FIXME: need LR_SHARED support for loading icon images from files\n");
       }
-      
+
       hFile = CreateFileW(lpszName,
                         GENERIC_READ,
                         FILE_SHARE_READ,
@@ -358,9 +363,9 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
                         0,
                         NULL);
       if (hFile == NULL)
-         {
-           return(NULL);
-         }
+      {
+          return NULL;
+      }
 
       hSection = CreateFileMappingW(hFile,
                                   NULL,
@@ -369,42 +374,42 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
                                   0,
                                   NULL);
 
+      CloseHandle(hFile);
       if (hSection == NULL)
-         {
-           CloseHandle(hFile);
-           return(NULL);
-         }
+      {
+          return NULL;
+      }
+
       IconDIR = MapViewOfFile(hSection,
                                 FILE_MAP_READ,
                                 0,
                                 0,
                                 0);
-
+      CloseHandle(hSection);
       if (IconDIR == NULL)
-         {
-           CloseHandle(hFile);
-           CloseHandle(hSection);
-           return(NULL);
-         }
+      {
+          return NULL;
+      }
+      
+      if (0 != IconDIR->idReserved ||
+          (IMAGE_ICON != IconDIR->idType && IMAGE_CURSOR != IconDIR->idType))
+      {
+          UnmapViewOfFile(IconDIR);
+          return NULL;
+      }
 
       //pick the best size.
       dirEntry = (CURSORICONDIRENTRY *)  CURSORICON_FindBestIcon( IconDIR, width, height, 1);
-
-
       if (!dirEntry)
-         {
-              CloseHandle(hFile);
-              CloseHandle(hSection);
-              UnmapViewOfFile(IconDIR);
-              return(NULL);
-         }
+      {
+          UnmapViewOfFile(IconDIR);
+          return NULL;
+      }
 
-      SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes); 
+      SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
 
       memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
-
-      CloseHandle(hFile);
-      CloseHandle(hSection);
+      UnmapViewOfFile(IconDIR);
   }
 
   //at this point we have a copy of the icon image to play with
@@ -426,7 +431,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
        }
       HeaderSize = sizeof(BITMAPINFOHEADER) + ColorCount * sizeof(RGBQUAD);
     }
-  
+
   //make data point to the start of the XOR image data
   Data = (PBYTE)SafeIconImage + HeaderSize;
 
@@ -436,10 +441,9 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
   if (hScreenDc == NULL)
   {
       if (fuLoad & LR_LOADFROMFILE)
-         {
-               RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-        UnmapViewOfFile(IconDIR);
-         }
+      {
+         RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
+      }
       return(NULL);
   }
 
@@ -449,7 +453,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
 }
 
 
-HANDLE STATIC
+static HANDLE
 LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
 {
   HANDLE hResource;
@@ -506,7 +510,7 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
                                   NULL);
       CloseHandle(hFile);
       if (hSection == NULL)
-       {               
+       {
          return(NULL);
        }
       BitmapInfo = MapViewOfFile(hSection,
@@ -540,7 +544,7 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
        }
       HeaderSize = sizeof(BITMAPINFOHEADER) + ColorCount * sizeof(RGBQUAD);
     }
-  Data = (PVOID)BitmapInfo + HeaderSize;
+  Data = (PVOID)((ULONG_PTR)BitmapInfo + HeaderSize);
 
   PrivateInfo = RtlAllocateHeap(GetProcessHeap(), 0, HeaderSize);
   if (PrivateInfo == NULL)
@@ -555,7 +559,7 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
 
   /* FIXME: Handle color conversion and transparency. */
 
-  hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
+  hScreenDc = CreateCompatibleDC(NULL);
   if (hScreenDc == NULL)
     {
       RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
@@ -570,7 +574,7 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
     {
       DIBSECTION Dib;
 
-      hBitmap = CreateDIBSection(hScreenDc, PrivateInfo, DIB_RGB_COLORS, NULL, 
+      hBitmap = CreateDIBSection(hScreenDc, PrivateInfo, DIB_RGB_COLORS, NULL,
                                 0, 0);
       GetObjectA(hBitmap, sizeof(DIBSECTION), &Dib);
       SetDIBits(hScreenDc, hBitmap, 0, Dib.dsBm.bmHeight, Data, BitmapInfo,
@@ -583,7 +587,7 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
     }
 
   RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
-  /*DeleteDC(hScreenDc);*/
+  DeleteDC(hScreenDc);
   if (fuLoad & LR_LOADFROMFILE)
     {
       UnmapViewOfFile(BitmapInfo);
@@ -598,7 +602,7 @@ LoadImageW(HINSTANCE hinst,
           int cxDesired,
           int cyDesired,
           UINT fuLoad)
-{  
+{
   if (fuLoad & LR_DEFAULTSIZE)
     {
       if (uType == IMAGE_ICON)
@@ -673,6 +677,9 @@ LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)
 HANDLE WINAPI
 CopyImage(HANDLE hnd, UINT type, INT desiredx, INT desiredy, UINT flags)
 {
+    HBITMAP res;
+    BITMAP bm;
+
        switch (type)
        {
         case IMAGE_BITMAP:
@@ -681,21 +688,24 @@ CopyImage(HANDLE hnd, UINT type, INT desiredx, INT desiredy, UINT flags)
                        /* FIXME:  support flags LR_COPYDELETEORG, LR_COPYFROMRESOURCE,
                                                                 LR_COPYRETURNORG, LR_CREATEDIBSECTION,
                                                                 and LR_MONOCHROME; */
-                               HBITMAP res;
-                               BITMAP bm;
 
                                if (!GetObjectW(hnd, sizeof(bm), &bm)) return 0;
                                bm.bmBits = NULL;
                                if ((res = CreateBitmapIndirect(&bm)))
                                {
                     char *buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight);
+                                       if (buf == NULL)
+                                       {
+                                               DeleteObject(res);
+                                               return NULL;
+                                       }
                                        GetBitmapBits(hnd, bm.bmWidthBytes * bm.bmHeight, buf);
                                        SetBitmapBits(res, bm.bmWidthBytes * bm.bmHeight, buf);
                                        HeapFree(GetProcessHeap(), 0, buf);
                                }
                 return res;
                        }
-               case IMAGE_ICON: 
+               case IMAGE_ICON:
                        {
                                static BOOL IconMsgDisplayed = FALSE;
                                /* FIXME: support loading the image as shared from an instance */
@@ -705,7 +715,7 @@ CopyImage(HANDLE hnd, UINT type, INT desiredx, INT desiredy, UINT flags)
                                }
                        return CopyIcon(hnd);
                        }
-               case IMAGE_CURSOR: 
+               case IMAGE_CURSOR:
                        {
                                static BOOL IconMsgDisplayed = FALSE;
                                /* FIXME: support loading the image as shared from an instance */