diff --git a/modules/rostests/apitests/user32/LoadImage.c b/modules/rostests/apitests/user32/LoadImage.c index 64af37325d2..f46e4be7846 100644 --- a/modules/rostests/apitests/user32/LoadImage.c +++ b/modules/rostests/apitests/user32/LoadImage.c @@ -1,6 +1,50 @@ #include "precomp.h" +static void test_LoadImage_DataFile(void) +{ + static const struct + { + int result; + LPCWSTR file; + int res_id; + UINT lr; + BOOL same_handle; + BOOL after_unload; /* LR_SHARED stays valid */ + } + tests[] = + { + { 1, L"shell32.dll", 2, 0, 0, 0 }, + { 1, L"shell32.dll", 2, LR_SHARED, 1, 1 }, + { 0, L"shell32.dll", 0xfff0, 0, 1, 0 }, /* Icon should not exist */ + { 1, L"regedit.exe", 100, 0, 0, 0 }, + { 1, L"regedit.exe", 100, LR_SHARED, 1, 1 } + }; + + SIZE_T i; + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + HANDLE handle1, handle2; + HMODULE hMod = LoadLibraryExW(tests[i].file, NULL, LOAD_LIBRARY_AS_DATAFILE); + if (!((SIZE_T)hMod & 3)) + { + skip("Could not load library as datafile %ls\n", tests[i].file); + continue; + } + + handle1 = LoadImage(hMod, MAKEINTRESOURCE(tests[i].res_id), IMAGE_ICON, 0, 0, tests[i].lr); + ok(!!handle1 == !!tests[i].result, "Failed to load %ls,-%d from %p\n", tests[i].file, tests[i].res_id, hMod); + + handle2 = LoadImage(hMod, MAKEINTRESOURCE(tests[i].res_id), IMAGE_ICON, 0, 0, tests[i].lr); + ok(!!(handle1 == handle2) == !!tests[i].same_handle, "Shared handles don't match\n"); + + FreeLibrary(hMod); + + handle1 = LoadImage(hMod, MAKEINTRESOURCE(tests[i].res_id), IMAGE_ICON, 0, 0, tests[i].lr); + ok(!!handle1 == !!tests[i].after_unload, "LR_%x handle should %sload after FreeLibrary\n", tests[i].lr, tests[i].after_unload ? "" : "not "); + } +} + START_TEST(LoadImage) { char path[MAX_PATH]; @@ -77,6 +121,9 @@ START_TEST(LoadImage) DeleteObject(ii.hbmMask); if(ii.hbmColor) DeleteObject(ii.hbmColor); + /* LOAD_LIBRARY_AS_DATAFILE */ + test_LoadImage_DataFile(); + return; } diff --git a/win32ss/user/user32/windows/cursoricon.c b/win32ss/user/user32/windows/cursoricon.c index 1f6b71714aa..a3f8a48602e 100644 --- a/win32ss/user/user32/windows/cursoricon.c +++ b/win32ss/user/user32/windows/cursoricon.c @@ -1454,7 +1454,21 @@ CURSORICON_LoadImageW( RtlInitUnicodeString(&ustrRsrc, lpszName); } - if(hinst) + if(LDR_IS_RESOURCE(hinst)) + { + /* We don't have a real module for GetModuleFileName, construct a fake name instead. + * GetIconInfoEx reveals the name used by Windows. */ + LPCWSTR fakeNameFmt = sizeof(void*) > 4 ? L"\x01%016IX" : L"\x01%08IX"; + ustrModule.MaximumLength = 18 * sizeof(WCHAR); + ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength); + if (!ustrModule.Buffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + ustrModule.Length = wsprintfW(ustrModule.Buffer, fakeNameFmt, hinst) * sizeof(WCHAR); + } + else if(hinst) { DWORD size = MAX_PATH; /* Get the module name string */