Fabian Maurer : user32: LoadImage should not only search in the working directory.

Alexandre Julliard julliard at winehq.org
Fri Nov 30 14:34:42 CST 2018


Module: wine
Branch: master
Commit: 400dd1596ab7946e68278b3f8dc7c87b898c7e9f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=400dd1596ab7946e68278b3f8dc7c87b898c7e9f

Author: Fabian Maurer <dark.shadow4 at web.de>
Date:   Wed Nov 28 22:39:49 2018 +0100

user32: LoadImage should not only search in the working directory.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46186
Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/cursoricon.c       |  8 +++-
 dlls/user32/tests/cursoricon.c | 89 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index f11f5e4..539fc7c 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -3039,11 +3039,17 @@ HANDLE WINAPI LoadImageW( HINSTANCE hinst, LPCWSTR name, UINT type,
                 INT desiredx, INT desiredy, UINT loadflags )
 {
     int depth;
+    WCHAR path[MAX_PATH];
 
     TRACE_(resource)("(%p,%s,%d,%d,%d,0x%08x)\n",
                      hinst,debugstr_w(name),type,desiredx,desiredy,loadflags);
 
-    if (loadflags & LR_LOADFROMFILE) loadflags &= ~LR_SHARED;
+    if (loadflags & LR_LOADFROMFILE)
+    {
+        loadflags &= ~LR_SHARED;
+        /* relative paths are not only relative to the current working directory */
+        if (SearchPathW(NULL, name, NULL, ARRAY_SIZE(path), path, NULL)) name = path;
+    }
     switch (type) {
     case IMAGE_BITMAP:
         return BITMAP_Load( hinst, name, desiredx, desiredy, loadflags );
diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 8404ee7..405856c 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -1203,6 +1203,92 @@ static void create_ico_file(const char *filename, const test_icon_entries_t *tes
     HeapFree(GetProcessHeap(), 0, buf);
 }
 
+void test_LoadImage_working_directory_run(char *path)
+{
+    DWORD bytes_written;
+    HANDLE handle;
+    BOOL ret;
+    char path_icon[MAX_PATH];
+    char path_image[MAX_PATH];
+    static const test_icon_entries_t icon_desc = {32, 32};
+
+    sprintf(path_icon, "%s\\icon.ico", path);
+    sprintf(path_image,  "%s\\test.bmp", path);
+
+    /* Create Files */
+    create_ico_file(path_icon, &icon_desc, 1);
+
+    handle = CreateFileA(path_image, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+    ok(handle != INVALID_HANDLE_VALUE, "run %s: CreateFileA failed. %u\n", path, GetLastError());
+    ret = WriteFile(handle, bmpimage, sizeof(bmpimage), &bytes_written, NULL);
+    ok(ret && bytes_written == sizeof(bmpimage), "run %s: Test file created improperly.\n", path);
+    CloseHandle(handle);
+
+    /* Test cursor */
+    handle = LoadImageA(NULL, "icon.ico", IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
+    ok(handle != NULL, "run %s: LoadImage() failed.\n", path);
+
+    ret = DestroyIcon(handle);
+    ok(ret, "run %s: DestroyIcon failed: %d\n", path, GetLastError());
+
+    /* Test image */
+    handle = LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+    ok(handle != NULL, "run %s: LoadImageA failed.\n", path);
+
+    ret = DeleteObject(handle);
+    ok(ret, "run %s: DeleteObject failed: %d\n", path, GetLastError());
+
+    /* Cleanup */
+    ret = DeleteFileA(path_image);
+    ok(ret, "run %s: DeleteFileA failed: %d\n", path, GetLastError());
+    ret = DeleteFileA(path_icon);
+    ok(ret, "run %s: DeleteFileA failed: %d\n", path, GetLastError());
+}
+
+static void test_LoadImage_working_directory(void)
+{
+    char old_working_dir[MAX_PATH];
+    char temp_dir_current[MAX_PATH];
+    char temp_dir_PATH[MAX_PATH];
+    char executable_path[MAX_PATH];
+    int pos_slash;
+    char old_PATH[10000];
+    char new_PATH[10000];
+    BOOL ret;
+
+    GetCurrentDirectoryA(ARRAY_SIZE(old_working_dir), old_working_dir);
+
+    GetTempPathA(ARRAY_SIZE(temp_dir_current), temp_dir_current);
+    strcat(temp_dir_current, "wine-test-dir-current\\");
+    GetTempPathA(ARRAY_SIZE(temp_dir_PATH), temp_dir_PATH);
+    strcat(temp_dir_PATH,    "wine-test-dir-path\\");
+
+    GetModuleFileNameA(NULL, executable_path, ARRAY_SIZE(executable_path));
+    pos_slash = strrchr(executable_path, '\\') - executable_path;
+    executable_path[pos_slash + 1] = 0;
+
+    CreateDirectoryA(temp_dir_current, NULL);
+    CreateDirectoryA(temp_dir_PATH, NULL);
+
+    SetCurrentDirectoryA(temp_dir_current);
+
+    GetEnvironmentVariableA("PATH", old_PATH, ARRAY_SIZE(old_PATH));
+    sprintf(new_PATH, "%s;%s", old_PATH, temp_dir_PATH);
+    SetEnvironmentVariableA("PATH", new_PATH);
+
+    test_LoadImage_working_directory_run(temp_dir_current);
+    test_LoadImage_working_directory_run(executable_path);
+    test_LoadImage_working_directory_run(temp_dir_PATH);
+
+    SetCurrentDirectoryA(old_working_dir);
+    SetEnvironmentVariableA("PATH", old_PATH);
+
+    ret = RemoveDirectoryA(temp_dir_current);
+    ok(ret, "RemoveDirectoryA failed: %d\n", GetLastError());
+    ret = RemoveDirectoryA(temp_dir_PATH);
+    ok(ret, "RemoveDirectoryA failed: %d\n", GetLastError());
+}
+
 static void test_LoadImage(void)
 {
     HANDLE handle;
@@ -1326,6 +1412,9 @@ static void test_LoadImage(void)
     bitmap_header->biSize = sizeof(BITMAPINFOHEADER);
 
     test_LoadImageFile("Cursor (invalid dwDIBOffset)", invalid_dwDIBOffset, sizeof(invalid_dwDIBOffset), "cur", 0);
+
+    /* Test in which paths images with a relative path can be found */
+    test_LoadImage_working_directory();
 }
 
 static void test_CreateIconFromResource(void)




More information about the wine-cvs mailing list