https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1c55924045facde76d9f7…
commit 1c55924045facde76d9f7c855f0760e16365b778
Author: Doug Lyons <douglyons(a)douglyons.com>
AuthorDate: Tue Dec 24 17:51:31 2024 -0600
Commit: GitHub <noreply(a)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.mz(a)gmail.com>
+* Copyright 2024 Doug Lyons <douglyons(a)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: