https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1c55924045facde76d9f7c855f0760e16365b778

commit 1c55924045facde76d9f7c855f0760e16365b778
Author:     Doug Lyons <dougly...@douglyons.com>
AuthorDate: Tue Dec 24 17:51:31 2024 -0600
Commit:     GitHub <nore...@github.com>
CommitDate: Tue Dec 24 17:51:31 2024 -0600

    [USER32_APTEST][USER32] CopyImage improve regression test and function. 
(#7524)
    
    CORE-19806 and CORE-17902.
    
    * Follow-up of PR #6886 and commit d3ec7cd to remove hack.
---
 modules/rostests/apitests/user32/CopyImage.c | 53 ++++++++++++++++++++++++++++
 win32ss/user/user32/windows/cursoricon.c     | 46 ++++++++++++++++++++----
 2 files changed, 93 insertions(+), 6 deletions(-)

diff --git a/modules/rostests/apitests/user32/CopyImage.c 
b/modules/rostests/apitests/user32/CopyImage.c
index bad7c472f4f..2280b20a6ba 100644
--- a/modules/rostests/apitests/user32/CopyImage.c
+++ b/modules/rostests/apitests/user32/CopyImage.c
@@ -3,6 +3,7 @@
  * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
  * PURPOSE:     Test for SetFocus/GetFocus/GetGUIThreadInfo
  * COPYRIGHT:   Copyright 2024 Katayama Hirofumi MZ 
<katayama.hirofumi...@gmail.com>
+*               Copyright 2024 Doug Lyons <dougly...@douglyons.com>
  */
 
 #include "precomp.h"
@@ -76,9 +77,61 @@ Test_CopyImage_Flags(UINT uType)
     DeleteObject(hImage);
 }
 
+static VOID
+Test_CopyImage_hImage_NULL(void)
+{
+    HANDLE hImg;
+    DWORD LastError;
+
+    /* Test NULL HANDLE return and GetLastError return. */
+    SetLastError(0xdeadbeef);
+    hImg = CopyImage(NULL, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE);
+    LastError = GetLastError();
+    ok(LastError == ERROR_INVALID_CURSOR_HANDLE, "Wrong error 0x%08lx 
returned\n", LastError);
+    ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg);
+
+    SetLastError(0xdeadbeef);
+    hImg = CopyImage(NULL, IMAGE_BITMAP, 16, 16, LR_COPYFROMRESOURCE);
+    LastError = GetLastError();
+    ok(LastError == ERROR_INVALID_HANDLE, "Wrong error 0x%08lx returned\n", 
LastError);
+    ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg);
+
+
+    SetLastError(0xdeadbeef);
+    hImg = CopyImage(NULL, IMAGE_CURSOR, 16, 16, LR_COPYFROMRESOURCE);
+    LastError = GetLastError();
+    ok(LastError == ERROR_INVALID_CURSOR_HANDLE, "Wrong error 0x%08lx 
returned\n", LastError);
+    ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg);
+
+    /* Test bad Flags for Invalid Parameter return */
+    SetLastError(0xdeadbeef);
+    /* 0x80000000 is an invalid flag value */
+    hImg = CopyImage(NULL, IMAGE_BITMAP, 16, 16, 0x80000000);
+    LastError = GetLastError();
+    ok(LastError == ERROR_INVALID_PARAMETER, "Wrong error 0x%08lx returned\n", 
LastError);
+    ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg);
+
+    /* Test bad Type (5) GetLastError return value. Not Icon, Cursor, or 
Bitmap. */
+    SetLastError(0xdeadbeef);
+    hImg = CopyImage(NULL, 5, 16, 16, LR_COPYFROMRESOURCE);
+    LastError = GetLastError();
+    ok(LastError == ERROR_INVALID_PARAMETER, "Wrong error 0x%08lx returned\n", 
LastError);
+    ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg);
+
+    /* Test bad type (5) GetLastError return value with good HANDLE */
+    hImg = CreateTestImage(IMAGE_ICON);
+    SetLastError(0xdeadbeef);
+    hImg = CopyImage(hImg, 5, 16, 16, LR_COPYFROMRESOURCE);
+    LastError = GetLastError();
+    ok(LastError == ERROR_INVALID_PARAMETER, "Wrong error 0x%08lx returned\n", 
LastError);
+    ok(!hImg, "Image returned should have been NULL, hImg was %p\n", hImg);
+    DeleteObject(hImg);
+}
+
 START_TEST(CopyImage)
 {
     Test_CopyImage_Flags(IMAGE_BITMAP);
     Test_CopyImage_Flags(IMAGE_CURSOR);
     Test_CopyImage_Flags(IMAGE_ICON);
+    Test_CopyImage_hImage_NULL();
 }
diff --git a/win32ss/user/user32/windows/cursoricon.c 
b/win32ss/user/user32/windows/cursoricon.c
index 53c98456e81..b1d8bc7e69a 100644
--- a/win32ss/user/user32/windows/cursoricon.c
+++ b/win32ss/user/user32/windows/cursoricon.c
@@ -2041,16 +2041,50 @@ HANDLE WINAPI CopyImage(
     switch(uType)
     {
         case IMAGE_BITMAP:
+            if (!hImage)
+            {
+                SetLastError(ERROR_INVALID_HANDLE);
+                break;
+            }
             return BITMAP_CopyImage(hImage, cxDesired, cyDesired, fuFlags);
         case IMAGE_CURSOR:
         case IMAGE_ICON:
-        /* HACK: Copying bitmaps with LR_COPYFROMRESOURCE flag fails. 
CORE-17902.
-         * This is a way to return the original bit map if we need
-         * the icons to show up. We need a simpler test. */
         {
-            HANDLE handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, 
cxDesired, cyDesired, fuFlags);
-            if (!handle && (fuFlags & (LR_COPYFROMRESOURCE|LR_COPYRETURNORG)))
-                handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, 
cxDesired, cyDesired, (fuFlags & ~LR_COPYFROMRESOURCE));
+            HANDLE handle;
+            if (!hImage)
+            {
+                SetLastError(ERROR_INVALID_CURSOR_HANDLE);
+                break;
+            }
+            handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, 
cxDesired, cyDesired, fuFlags);
+            if (!handle && (fuFlags & LR_COPYFROMRESOURCE))
+            {
+                /* Test if the hImage is the same size as what we want by 
getting
+                 * its BITMAP and comparing its dimensions to the desired 
size. */
+                BITMAP bm;
+
+                ICONINFO iconinfo = { 0 };
+                if (!GetIconInfo(hImage, &iconinfo))
+                {
+                    ERR("GetIconInfo Failed. hImage %p\n", hImage);
+                    return NULL;
+                }
+                if (!GetObject(iconinfo.hbmColor, sizeof(bm), &bm))
+                {
+                    ERR("GetObject Failed. iconinfo %p\n", iconinfo);
+                    return NULL;
+                }
+
+                DeleteObject(iconinfo.hbmMask);
+                DeleteObject(iconinfo.hbmColor);
+
+                /* If the images are the same size remove LF_COPYFROMRESOURCE 
and try again */
+                if (cxDesired == bm.bmWidth && cyDesired == bm.bmHeight)
+                {
+                    handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, 
cxDesired,
+                                                  cyDesired, (fuFlags & 
~LR_COPYFROMRESOURCE));
+                }
+            }
             return handle;
         }
         default:

Reply via email to