diff --git a/modules/rostests/apitests/user32/CMakeLists.txt b/modules/rostests/apitests/user32/CMakeLists.txt index 7dd1be59361..3e696def280 100644 --- a/modules/rostests/apitests/user32/CMakeLists.txt +++ b/modules/rostests/apitests/user32/CMakeLists.txt @@ -5,6 +5,7 @@ list(APPEND SOURCE ../include/msgtrace.c CharFuncs.c CloseWindow.c + CopyImage.c CreateDialog.c CreateIconFromResourceEx.c CreateWindowEx.c diff --git a/modules/rostests/apitests/user32/CopyImage.c b/modules/rostests/apitests/user32/CopyImage.c new file mode 100644 index 00000000000..bad7c472f4f --- /dev/null +++ b/modules/rostests/apitests/user32/CopyImage.c @@ -0,0 +1,84 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+) + * PURPOSE: Test for SetFocus/GetFocus/GetGUIThreadInfo + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include "precomp.h" +#include + +#define COPYIMAGE_VALID_FLAGS ( \ + LR_SHARED | LR_COPYFROMRESOURCE | LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS | 0x800 | \ + LR_VGACOLOR | LR_LOADREALSIZE | LR_DEFAULTSIZE | LR_LOADTRANSPARENT | LR_LOADFROMFILE | \ + LR_COPYDELETEORG | LR_COPYRETURNORG | LR_COLOR | LR_MONOCHROME \ +) + +#define LR_UNKNOWN_0x10000 0x10000 + +static HANDLE CreateTestImage(UINT uType) +{ + HANDLE hImage; + switch (uType) + { + case IMAGE_BITMAP: + { + HDC hDC = CreateCompatibleDC(NULL); + hImage = (HANDLE)CreateCompatibleBitmap(hDC, 10, 10); + DeleteDC(hDC); + break; + } + case IMAGE_CURSOR: + hImage = (HANDLE)LoadCursor(NULL, IDC_ARROW); + break; + case IMAGE_ICON: + hImage = (HANDLE)LoadIcon(NULL, IDI_APPLICATION); + break; + } + return hImage; +} + +static VOID +Test_CopyImage_Flags(UINT uType) +{ + UINT iBit, uBit, uValidFlags = COPYIMAGE_VALID_FLAGS; + HANDLE hImage, hCopiedImage; + + if (IsWindowsVistaOrGreater()) + uValidFlags |= LR_UNKNOWN_0x10000; + + hImage = CreateTestImage(uType); + for (iBit = 0; iBit < sizeof(UINT) * CHAR_BIT; ++iBit) + { + uBit = (1 << iBit); + + SetLastError(0xDEADFACE); + hCopiedImage = CopyImage(hImage, uType, 0, 0, uBit); + + if (uValidFlags & uBit) // Valid flag? + { + ok(hCopiedImage != NULL, "iBit %u: uType %u: hCopiedImage was NULL\n", iBit, uType); + } + else + { + ok(hCopiedImage == NULL, "iBit %u: uType %u: hCopiedImage was %p\n", iBit, uType, hCopiedImage); + ok_err(ERROR_INVALID_PARAMETER); + } + + if (hCopiedImage) + DeleteObject(hCopiedImage); + + /* If the original image was deleted, re-create it */ + if (uBit & LR_COPYDELETEORG) + hImage = CreateTestImage(uType); + } + + DeleteObject(hImage); +} + +START_TEST(CopyImage) +{ + Test_CopyImage_Flags(IMAGE_BITMAP); + Test_CopyImage_Flags(IMAGE_CURSOR); + Test_CopyImage_Flags(IMAGE_ICON); +} diff --git a/modules/rostests/apitests/user32/testlist.c b/modules/rostests/apitests/user32/testlist.c index 24e66096de1..5186c71c5d1 100644 --- a/modules/rostests/apitests/user32/testlist.c +++ b/modules/rostests/apitests/user32/testlist.c @@ -6,6 +6,7 @@ extern void func_AttachThreadInput(void); extern void func_CharFuncs(void); extern void func_CloseWindow(void); +extern void func_CopyImage(void); extern void func_CreateDialog(void); extern void func_CreateIconFromResourceEx(void); extern void func_CreateWindowEx(void); @@ -67,6 +68,7 @@ const struct test winetest_testlist[] = { "AttachThreadInput", func_AttachThreadInput }, { "CharFuncs", func_CharFuncs }, { "CloseWindow", func_CloseWindow }, + { "CopyImage", func_CopyImage }, { "CreateDialog", func_CreateDialog }, { "CreateIconFromResourceEx", func_CreateIconFromResourceEx }, { "CreateWindowEx", func_CreateWindowEx }, diff --git a/win32ss/user/user32/windows/cursoricon.c b/win32ss/user/user32/windows/cursoricon.c index 531c29abe57..586deb7a728 100644 --- a/win32ss/user/user32/windows/cursoricon.c +++ b/win32ss/user/user32/windows/cursoricon.c @@ -2015,6 +2015,12 @@ User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength) /************* PUBLIC FUNCTIONS *******************/ +#define COPYIMAGE_VALID_FLAGS ( \ + LR_SHARED | LR_COPYFROMRESOURCE | LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS | 0x800 | \ + LR_VGACOLOR | LR_LOADREALSIZE | LR_DEFAULTSIZE | LR_LOADTRANSPARENT | LR_LOADFROMFILE | \ + LR_COPYDELETEORG | LR_COPYRETURNORG | LR_COLOR | LR_MONOCHROME \ +) + HANDLE WINAPI CopyImage( _In_ HANDLE hImage, _In_ UINT uType, @@ -2025,6 +2031,13 @@ HANDLE WINAPI CopyImage( { TRACE("hImage=%p, uType=%u, cxDesired=%d, cyDesired=%d, fuFlags=%x\n", hImage, uType, cxDesired, cyDesired, fuFlags); + + if (fuFlags & ~COPYIMAGE_VALID_FLAGS) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + switch(uType) { case IMAGE_BITMAP: