Clean up warning for SafeIconImage might be uninitialized in LoadImageW.
[reactos.git] / reactos / lib / user32 / windows / bitmap.c
index 07f132a..d471aa7 100644 (file)
@@ -66,13 +66,19 @@ LoadImageA(HINSTANCE hinst,
       Handle = LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired,
                          cyDesired, fuLoad);
    }
+
    return Handle;
 }
 
 
 static HANDLE
-LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
+LoadCursorIconImage(
+   HINSTANCE hinst,
+   LPCWSTR lpszName,
+   INT width,
+   INT height,
+   UINT fuLoad,
+   ULONG uType)
 {
    HANDLE hResource;
    HANDLE h2Resource;
@@ -81,30 +87,31 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
    HANDLE hSection;
    CURSORICONDIR *IconDIR;
    HDC hScreenDc;
-   HANDLE hIcon;
+   HICON hIcon;
    ULONG HeaderSize;
    ULONG ColorCount;
+   ULONG ColorBits;
    PVOID Data;
    CURSORICONDIRENTRY* dirEntry;
-   ICONIMAGE* SafeIconImage;
+   ICONIMAGE* SafeIconImage = NULL;
    GRPCURSORICONDIR* IconResDir;
    INT id;
    ICONIMAGE *ResIcon;
-   UINT ColorBits;
+   BOOL Icon = (uType == IMAGE_ICON);
 
    if (!(fuLoad & LR_LOADFROMFILE))
    {
       if (hinst == NULL)
          hinst = User32Instance;
 
-      hResource = hfRes = FindResourceW(hinst, lpszName, RT_GROUP_CURSOR);
+      hResource = hfRes = FindResourceW(hinst, lpszName,
+                                        Icon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
       if (hResource == NULL)
          return NULL;
 
       if (fuLoad & LR_SHARED)
       {
-         /* FIXME - pass size! */
-         hIcon = (HANDLE)NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, 0, 0);
+         hIcon = NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, width, height);
          if (hIcon)
             return hIcon;
       }
@@ -117,12 +124,18 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
       if (IconResDir == NULL)
          return NULL;
 
-      /* Find the best fitting in the IconResDir for this resolution. */
-      id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, TRUE,
-         32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+      /*
+       * Find the best fitting in the IconResDir for this resolution
+       */
+
+      id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, Icon, width, height,
+                                       fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
 
       h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id),
-         MAKEINTRESOURCEW(RT_CURSOR));
+                                 Icon ? MAKEINTRESOURCEW(RT_ICON) :
+                                 MAKEINTRESOURCEW(RT_CURSOR));
+      if (h2Resource == NULL)
+         return NULL;
 
       hResource = LoadResource(hinst, h2Resource);
       if (hResource == NULL)
@@ -132,9 +145,10 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
       if (ResIcon == NULL)
          return NULL;
 
-      hIcon = (HANDLE)CreateIconFromResourceEx((PBYTE)ResIcon,
-         SizeofResource(hinst, h2Resource), FALSE, 0x00030000,
-         32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
+      hIcon = CreateIconFromResourceEx((PBYTE)ResIcon,
+                                       SizeofResource(hinst, h2Resource),
+                                       Icon, 0x00030000, width, height,
+                                       fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
       if (hIcon && 0 != (fuLoad & LR_SHARED))
       {
          NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
@@ -144,14 +158,22 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
       return hIcon;
    }
 
+   /*
+    * 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
+    * and passing that to CURSORICON_FindBestIcon.
+    */
+
    if (fuLoad & LR_SHARED)
    {
-      DbgPrint("FIXME: need LR_SHARED support loading cursor images from files\n");
+      DbgPrint("FIXME: need LR_SHARED support for loading icon images from files\n");
    }
 
    hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
                        OPEN_EXISTING, 0, NULL);
-   if (hFile == NULL)
+   if (hFile == INVALID_HANDLE_VALUE)
       return NULL;
 
    hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
@@ -171,14 +193,13 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
       return NULL;
    }
 
-   /*
-    * Get a handle to the screen dc, the icon we create is going to be
-    * compatable with it.
-    */
-   hScreenDc = CreateCompatibleDC(NULL);
+   /* Get a handle to the screen dc, the icon we create is going to be
+    * compatable with this. */
+   hScreenDc = CreateDCW(NULL, NULL, NULL, NULL);
    if (hScreenDc == NULL)
    {
       UnmapViewOfFile(IconDIR);
+      RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
       return NULL;
    }
 
@@ -198,9 +219,10 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
    }
 
    /* Pick the best size. */
-   dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, 32, 32, ColorBits);
+   dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, width, height, ColorBits);
    if (!dirEntry)
    {
+      DeleteDC(hScreenDc);
       UnmapViewOfFile(IconDIR);
       return NULL;
    }
@@ -208,164 +230,10 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
    SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
    if (SafeIconImage == NULL)
    {
+      DeleteDC(hScreenDc);
       UnmapViewOfFile(IconDIR);
       return NULL;
    }
-   memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
-   UnmapViewOfFile(IconDIR);
-
-   /* 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
-   {
-      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;
-}
-
-
-static HANDLE
-LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuLoad)
-{
-   HANDLE hResource;
-   HANDLE h2Resource;
-   HANDLE hfRes;
-   HANDLE hFile;
-   HANDLE hSection;
-   CURSORICONDIR* IconDIR;
-   HDC hScreenDc;
-   HICON hIcon;
-   ULONG HeaderSize;
-   ULONG ColorCount;
-   PVOID Data;
-   CURSORICONDIRENTRY* dirEntry;
-   ICONIMAGE* SafeIconImage;
-   GRPCURSORICONDIR* IconResDir;
-   INT id;
-   ICONIMAGE *ResIcon;
-
-   if (!(fuLoad & LR_LOADFROMFILE))
-   {
-      if (hinst == NULL)
-         hinst = User32Instance;
-
-      hResource = hfRes = FindResourceW(hinst, lpszName, RT_GROUP_ICON);
-      if (hResource == NULL)
-         return NULL;
-
-      if (fuLoad & LR_SHARED)
-      {
-         hIcon = NtUserFindExistingCursorIcon(hinst, (HRSRC)hfRes, width, height);
-         if (hIcon)
-            return hIcon;
-      }
-
-      hResource = LoadResource(hinst, hResource);
-      if (hResource == NULL)
-         return NULL;
-
-      IconResDir = LockResource(hResource);
-      if (IconResDir == NULL)
-         return NULL;
-
-      /*
-       * Find the best fitting in the IconResDir for this resolution
-       */
-
-      id = LookupIconIdFromDirectoryEx((PBYTE)IconResDir, TRUE, width, height,
-                                       fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
-
-      h2Resource = FindResourceW(hinst, MAKEINTRESOURCEW(id), MAKEINTRESOURCEW(RT_ICON));
-
-      hResource = LoadResource(hinst, h2Resource);
-      if (hResource == NULL)
-         return NULL;
-
-      ResIcon = LockResource(hResource);
-      if (ResIcon == NULL)
-         return NULL;
-
-      hIcon = CreateIconFromResourceEx((PBYTE)ResIcon,
-                                       SizeofResource(hinst, h2Resource),
-                                       TRUE, 0x00030000, width, height,
-                                       fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
-      if (hIcon && 0 != (fuLoad & LR_SHARED))
-      {
-         NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
-                                 (HRSRC)NULL);
-      }
-
-      return hIcon;
-   }
-
-   /*
-    * 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
-    * and passing that to CURSORICON_FindBestIcon.
-    */
-
-   if (fuLoad & LR_SHARED)
-   {
-     DbgPrint("FIXME: need LR_SHARED support for loading icon images from files\n");
-   }
-
-   hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
-                       OPEN_EXISTING, 0, NULL);
-   if (hFile == NULL)
-       return NULL;
-
-   hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
-   CloseHandle(hFile);
-   if (hSection == NULL)
-       return NULL;
-
-   IconDIR = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
-   CloseHandle(hSection);
-   if (IconDIR == 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)
-   {
-       UnmapViewOfFile(IconDIR);
-       return NULL;
-   }
-
-   SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
-   if (SafeIconImage == NULL)
-   {
-       UnmapViewOfFile(IconDIR);
-       return NULL;
-   }
 
    memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
    UnmapViewOfFile(IconDIR);
@@ -391,18 +259,9 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
    /* Make data point to the start of the XOR image data. */
    Data = (PBYTE)SafeIconImage + HeaderSize;
 
-   /* Get a handle to the screen dc, the icon we create is going to be
-    * compatable with this. */
-   hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
-   if (hScreenDc == NULL)
-   {
-      if (fuLoad & LR_LOADFROMFILE)
-         RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-      return NULL;
-   }
-
    hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2);
    RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
+   DeleteDC(hScreenDc);
 
    return hIcon;
 }
@@ -441,7 +300,7 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
    {
       hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
                           OPEN_EXISTING, 0, NULL);
-      if (hFile == NULL)
+      if (hFile == INVALID_HANDLE_VALUE)
          return NULL;
 
       hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
@@ -548,13 +407,13 @@ LoadImageW(
       case IMAGE_BITMAP:
          return LoadBitmapImage(hinst, lpszName, fuLoad);
       case IMAGE_CURSOR:
-         return LoadCursorImage(hinst, lpszName, fuLoad);
       case IMAGE_ICON:
-         return LoadIconImage(hinst, lpszName, cxDesired, cyDesired, fuLoad);
+         return LoadCursorIconImage(hinst, lpszName, cxDesired, cyDesired,
+                                    fuLoad, uType);
       default:
          break;
    }
+
    return NULL;
 }
 
@@ -644,6 +503,6 @@ CopyImage(
             return CopyCursor(hnd);
          }
    }
-   
+
    return NULL;
 }