diff --git a/rostests/winetests/shell32/shelllink.c b/rostests/winetests/shell32/shelllink.c index 9e792fdfa76..3ab37668159 100755 --- a/rostests/winetests/shell32/shelllink.c +++ b/rostests/winetests/shell32/shelllink.c @@ -40,10 +40,12 @@ typedef void (WINAPI *fnILFree)(LPITEMIDLIST); typedef BOOL (WINAPI *fnILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST); typedef HRESULT (WINAPI *fnSHILCreateFromPath)(LPCWSTR, LPITEMIDLIST *,DWORD*); +typedef HRESULT (WINAPI *fnSHDefExtractIconA)(LPCSTR, int, UINT, HICON*, HICON*, UINT); static fnILFree pILFree; static fnILIsEqual pILIsEqual; static fnSHILCreateFromPath pSHILCreateFromPath; +static fnSHDefExtractIconA pSHDefExtractIconA; static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR, LPSTR, DWORD); @@ -708,6 +710,34 @@ static void test_datalink(void) IShellLinkW_Release( sl ); } +static void test_shdefextracticon(void) +{ + HICON hiconlarge=NULL, hiconsmall=NULL; + HRESULT res; + + if (!pSHDefExtractIconA) + { + win_skip("SHDefExtractIconA is unavailable\n"); + return; + } + + res = pSHDefExtractIconA("shell32.dll", 0, 0, &hiconlarge, &hiconsmall, MAKELONG(16,24)); + ok(SUCCEEDED(res), "SHDefExtractIconA failed, res=%x\n", res); + ok(hiconlarge != NULL, "got null hiconlarge\n"); + ok(hiconsmall != NULL, "got null hiconsmall\n"); + DestroyIcon(hiconlarge); + DestroyIcon(hiconsmall); + + hiconsmall = NULL; + res = pSHDefExtractIconA("shell32.dll", 0, 0, NULL, &hiconsmall, MAKELONG(16,24)); + ok(SUCCEEDED(res), "SHDefExtractIconA failed, res=%x\n", res); + ok(hiconsmall != NULL, "got null hiconsmall\n"); + DestroyIcon(hiconsmall); + + res = pSHDefExtractIconA("shell32.dll", 0, 0, NULL, NULL, MAKELONG(16,24)); + ok(SUCCEEDED(res), "SHDefExtractIconA failed, res=%x\n", res); +} + START_TEST(shelllink) { HRESULT r; @@ -717,6 +747,7 @@ START_TEST(shelllink) pILFree = (fnILFree) GetProcAddress(hmod, (LPSTR)155); pILIsEqual = (fnILIsEqual) GetProcAddress(hmod, (LPSTR)21); pSHILCreateFromPath = (fnSHILCreateFromPath) GetProcAddress(hmod, (LPSTR)28); + pSHDefExtractIconA = (fnSHDefExtractIconA) GetProcAddress(hmod, "SHDefExtractIconA"); pGetLongPathNameA = (void *)GetProcAddress(hkernel32, "GetLongPathNameA"); @@ -728,6 +759,7 @@ START_TEST(shelllink) test_get_set(); test_load_save(); test_datalink(); + test_shdefextracticon(); CoUninitialize(); } diff --git a/rostests/winetests/shell32/shlexec.c b/rostests/winetests/shell32/shlexec.c index 863cea16120..6edc9263618 100755 --- a/rostests/winetests/shell32/shlexec.c +++ b/rostests/winetests/shell32/shlexec.c @@ -333,11 +333,11 @@ static void create_test_verb_dde(const char* extension, const char* verb, } else { - cmd=malloc(strlen(argv0)+10+strlen(child_file)+2+strlen(cmdtail)+1); + cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+10+strlen(child_file)+2+strlen(cmdtail)+1); sprintf(cmd,"%s shlexec \"%s\" %s", argv0, child_file, cmdtail); rc=RegSetValueEx(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmd, strlen(cmd)+1); assert(rc==ERROR_SUCCESS); - free(cmd); + HeapFree(GetProcessHeap(), 0, cmd); } if (ddeexec) @@ -677,6 +677,8 @@ static void test_filename(void) test=filename_tests; while (test->basename) { + BOOL quotedfile = FALSE; + sprintf(filename, test->basename, tmpdir); if (strchr(filename, '/')) { @@ -695,6 +697,8 @@ static void test_filename(void) else { char quoted[MAX_PATH + 2]; + + quotedfile = TRUE; sprintf(quoted, "\"%s\"", filename); rc=shell_execute(test->verb, quoted, NULL, NULL); } @@ -702,7 +706,9 @@ static void test_filename(void) rc=33; if ((test->todo & 0x1)==0) { - ok(rc==test->rc, "%s failed: rc=%d err=%d\n", shell_call, + ok(rc==test->rc || + broken(quotedfile && rc == 2), /* NT4 */ + "%s failed: rc=%d err=%d\n", shell_call, rc, GetLastError()); } else todo_wine @@ -858,7 +864,8 @@ static void test_find_executable(void) ok(rc == SE_ERR_NOASSOC /* >= win2000 */ || rc > 32 /* win98, nt4 */, "FindExecutable(NULL) returned %ld\n", rc); ok(strcmp(command, "your word") != 0, "FindExecutable(NULL) returned command=[%s]\n", command); - sprintf(filename, "%s\\test file.sfe", tmpdir); + /* Win95 can't cope with double backslashes in FindExecutableA (tmpdir has a trailing backslash) */ + sprintf(filename, "%stest file.sfe", tmpdir); rc=(INT_PTR)FindExecutableA(filename, NULL, command); ok(rc > 32, "FindExecutable(%s) returned %ld\n", filename, rc); /* Depending on the platform, command could be '%1' or 'test file.sfe' */ @@ -904,6 +911,10 @@ static void test_find_executable(void) test=filename_tests; while (test->basename) { + /* Win95 can't cope with double slashes/backslashes in FindExecutableA */ + if (tmpdir[strlen(tmpdir) - 1] == '\\') + tmpdir[strlen(tmpdir) - 1] = 0; + sprintf(filename, test->basename, tmpdir); if (strchr(filename, '/')) { @@ -1591,6 +1602,8 @@ static void cleanup_test(void) while (*testfile) { sprintf(filename, *testfile, tmpdir); + /* Make sure we can delete the files ('test file.noassoc' is read-only now) */ + SetFileAttributes(filename, FILE_ATTRIBUTE_NORMAL); DeleteFile(filename); testfile++; } diff --git a/rostests/winetests/shell32/shlfolder.c b/rostests/winetests/shell32/shlfolder.c index 0536d2e2863..790096682e9 100644 --- a/rostests/winetests/shell32/shlfolder.c +++ b/rostests/winetests/shell32/shlfolder.c @@ -52,6 +52,9 @@ static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT); static LPITEMIDLIST (WINAPI *pILFindLastID)(LPCITEMIDLIST); static void (WINAPI *pILFree)(LPITEMIDLIST); static BOOL (WINAPI *pILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST); +static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**); +static LPITEMIDLIST (WINAPI *pILCombine)(LPCITEMIDLIST,LPCITEMIDLIST); + static void init_function_pointers(void) { @@ -68,6 +71,8 @@ static void init_function_pointers(void) pILFindLastID = (void *)GetProcAddress(hmod, (LPCSTR)16); pILFree = (void*)GetProcAddress(hmod, (LPSTR)155); pILIsEqual = (void*)GetProcAddress(hmod, (LPSTR)21); + pSHCreateShellItem = (void*)GetProcAddress(hmod, "SHCreateShellItem"); + pILCombine = (void*)GetProcAddress(hmod, (LPSTR)25); hmod = GetModuleHandleA("shlwapi.dll"); pStrRetToBufW = (void*)GetProcAddress(hmod, "StrRetToBufW"); @@ -1740,6 +1745,163 @@ cleanup: RemoveDirectoryA(".\\testfolder"); } +static void test_SHCreateShellItem(void) +{ + IShellItem *shellitem, *shellitem2; + IPersistIDList *persistidl; + LPITEMIDLIST pidl_cwd=NULL, pidl_testfile, pidl_abstestfile, pidl_test; + HRESULT ret; + char curdirA[MAX_PATH]; + WCHAR curdirW[MAX_PATH]; + IShellFolder *desktopfolder=NULL, *currentfolder=NULL; + static WCHAR testfileW[] = {'t','e','s','t','f','i','l','e',0}; + + GetCurrentDirectoryA(MAX_PATH, curdirA); + + if (!lstrlenA(curdirA)) + { + win_skip("GetCurrentDirectoryA returned empty string, skipping test_SHCreateShellItem\n"); + return; + } + + MultiByteToWideChar(CP_ACP, 0, curdirA, -1, curdirW, MAX_PATH); + + ret = SHGetDesktopFolder(&desktopfolder); + ok(SUCCEEDED(ret), "SHGetShellFolder returned %x\n", ret); + + ret = IShellFolder_ParseDisplayName(desktopfolder, NULL, NULL, curdirW, NULL, &pidl_cwd, NULL); + ok(SUCCEEDED(ret), "ParseDisplayName returned %x\n", ret); + + ret = IShellFolder_BindToObject(desktopfolder, pidl_cwd, NULL, &IID_IShellFolder, (void**)¤tfolder); + ok(SUCCEEDED(ret), "BindToObject returned %x\n", ret); + + CreateTestFile(".\\testfile"); + + ret = IShellFolder_ParseDisplayName(currentfolder, NULL, NULL, testfileW, NULL, &pidl_testfile, NULL); + ok(SUCCEEDED(ret), "ParseDisplayName returned %x\n", ret); + + pidl_abstestfile = pILCombine(pidl_cwd, pidl_testfile); + + ret = pSHCreateShellItem(NULL, NULL, NULL, &shellitem); + ok(ret == E_INVALIDARG, "SHCreateShellItem returned %x\n", ret); + + if (0) /* crashes on Windows XP */ + { + pSHCreateShellItem(NULL, NULL, pidl_cwd, NULL); + pSHCreateShellItem(pidl_cwd, NULL, NULL, &shellitem); + pSHCreateShellItem(NULL, currentfolder, NULL, &shellitem); + pSHCreateShellItem(pidl_cwd, currentfolder, NULL, &shellitem); + } + + ret = pSHCreateShellItem(NULL, NULL, pidl_cwd, &shellitem); + ok(SUCCEEDED(ret), "SHCreateShellItem returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IShellItem_QueryInterface(shellitem, &IID_IPersistIDList, (void**)&persistidl); + ok(SUCCEEDED(ret), "QueryInterface returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IPersistIDList_GetIDList(persistidl, &pidl_test); + ok(SUCCEEDED(ret), "GetIDList returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ok(ILIsEqual(pidl_cwd, pidl_test), "id lists are not equal\n"); + pILFree(pidl_test); + } + IPersistIDList_Release(persistidl); + } + IShellItem_Release(shellitem); + } + + ret = pSHCreateShellItem(pidl_cwd, NULL, pidl_testfile, &shellitem); + ok(SUCCEEDED(ret), "SHCreateShellItem returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IShellItem_QueryInterface(shellitem, &IID_IPersistIDList, (void**)&persistidl); + ok(SUCCEEDED(ret), "QueryInterface returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IPersistIDList_GetIDList(persistidl, &pidl_test); + ok(SUCCEEDED(ret), "GetIDList returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ok(ILIsEqual(pidl_abstestfile, pidl_test), "id lists are not equal\n"); + pILFree(pidl_test); + } + IPersistIDList_Release(persistidl); + } + + ret = IShellItem_GetParent(shellitem, &shellitem2); + ok(SUCCEEDED(ret), "GetParent returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IShellItem_QueryInterface(shellitem2, &IID_IPersistIDList, (void**)&persistidl); + ok(SUCCEEDED(ret), "QueryInterface returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IPersistIDList_GetIDList(persistidl, &pidl_test); + ok(SUCCEEDED(ret), "GetIDList returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ok(ILIsEqual(pidl_cwd, pidl_test), "id lists are not equal\n"); + pILFree(pidl_test); + } + IPersistIDList_Release(persistidl); + } + IShellItem_Release(shellitem2); + } + + IShellItem_Release(shellitem); + } + + ret = pSHCreateShellItem(NULL, currentfolder, pidl_testfile, &shellitem); + ok(SUCCEEDED(ret), "SHCreateShellItem returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IShellItem_QueryInterface(shellitem, &IID_IPersistIDList, (void**)&persistidl); + ok(SUCCEEDED(ret), "QueryInterface returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IPersistIDList_GetIDList(persistidl, &pidl_test); + ok(SUCCEEDED(ret), "GetIDList returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ok(ILIsEqual(pidl_abstestfile, pidl_test), "id lists are not equal\n"); + pILFree(pidl_test); + } + IPersistIDList_Release(persistidl); + } + IShellItem_Release(shellitem); + } + + /* if a parent pidl and shellfolder are specified, the shellfolder is ignored */ + ret = pSHCreateShellItem(pidl_cwd, desktopfolder, pidl_testfile, &shellitem); + ok(SUCCEEDED(ret), "SHCreateShellItem returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IShellItem_QueryInterface(shellitem, &IID_IPersistIDList, (void**)&persistidl); + ok(SUCCEEDED(ret), "QueryInterface returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ret = IPersistIDList_GetIDList(persistidl, &pidl_test); + ok(SUCCEEDED(ret), "GetIDList returned %x\n", ret); + if (SUCCEEDED(ret)) + { + ok(ILIsEqual(pidl_abstestfile, pidl_test), "id lists are not equal\n"); + pILFree(pidl_test); + } + IPersistIDList_Release(persistidl); + } + IShellItem_Release(shellitem); + } + + DeleteFileA(".\\testfile"); + pILFree(pidl_abstestfile); + pILFree(pidl_testfile); + pILFree(pidl_cwd); + IShellFolder_Release(currentfolder); + IShellFolder_Release(desktopfolder); +} START_TEST(shlfolder) { @@ -1762,6 +1924,10 @@ START_TEST(shlfolder) else skip("SHGetFolderPathAndSubDirA not present\n"); test_LocalizedNames(); + if(pSHCreateShellItem) + test_SHCreateShellItem(); + else + win_skip("test_SHCreateShellItem not present\n"); OleUninitialize(); }