mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[USER32] Support loading icons from data file module (#6065)
GetModuleFileName() fails on LOAD_LIBRARY_AS_DATAFILE causing LoadImage to fail. Use a fake filename for LR_SHARED (with same format as Windows). This may not be a good design, but it does match Windows' behaviour. + Added test.
This commit is contained in:
parent
8f349ab3c2
commit
82c07abf1a
2 changed files with 62 additions and 1 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue