From e7264e00c587b76bf87e4bc75244864f3c74def8 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sun, 26 Apr 2015 11:27:59 +0000 Subject: [PATCH] [SHELL32_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246 svn path=/trunk/; revision=67432 --- rostests/winetests/shell32/assoc.c | 67 ++- rostests/winetests/shell32/ebrowser.c | 2 +- rostests/winetests/shell32/recyclebin.c | 25 +- rostests/winetests/shell32/shelllink.c | 38 +- rostests/winetests/shell32/shellpath.c | 89 +++- rostests/winetests/shell32/shlexec.c | 40 +- rostests/winetests/shell32/shlfileop.c | 20 +- rostests/winetests/shell32/shlfolder.c | 529 +++++++++++++++++++++++- rostests/winetests/shell32/shlview.c | 5 - 9 files changed, 739 insertions(+), 76 deletions(-) diff --git a/rostests/winetests/shell32/assoc.c b/rostests/winetests/shell32/assoc.c index ff999e98dc7..0092081db13 100644 --- a/rostests/winetests/shell32/assoc.c +++ b/rostests/winetests/shell32/assoc.c @@ -57,22 +57,12 @@ static void test_IQueryAssociations_QueryInterface(void) } -static void test_IApplicationAssociationRegistration_QueryInterface(void) +static void test_IApplicationAssociationRegistration_QueryInterface(IApplicationAssociationRegistration *appreg) { - IApplicationAssociationRegistration *appreg; IApplicationAssociationRegistration *appreg2; IUnknown *unk; HRESULT hr; - /* this works since Vista */ - hr = CoCreateInstance(&CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC_SERVER, - &IID_IApplicationAssociationRegistration, (LPVOID*)&appreg); - - if (FAILED(hr)) { - skip("IApplicationAssociationRegistration not created: 0x%x\n", hr); - return; - } - hr = IApplicationAssociationRegistration_QueryInterface(appreg, &IID_IApplicationAssociationRegistration, (void**)&appreg2); ok(hr == S_OK, "QueryInterface (IApplicationAssociationRegistration) returned 0x%x\n", hr); @@ -88,8 +78,6 @@ static void test_IApplicationAssociationRegistration_QueryInterface(void) hr = IApplicationAssociationRegistration_QueryInterface(appreg, &IID_IUnknown, NULL); ok(hr == E_POINTER, "got 0x%x (expected E_POINTER)\n", hr); - - IApplicationAssociationRegistration_Release(appreg); } struct assoc_getstring_test @@ -103,7 +91,6 @@ struct assoc_getstring_test }; static const WCHAR httpW[] = {'h','t','t','p',0}; -static const WCHAR httpsW[] = {'h','t','t','p','s',0}; static const WCHAR badW[] = {'b','a','d','b','a','d',0}; static struct assoc_getstring_test getstring_tests[] = @@ -190,9 +177,48 @@ static void test_IQueryAssociations_Init(void) IQueryAssociations_Release(assoc); } +static void test_IApplicationAssociationRegistration_QueryCurrentDefault(IApplicationAssociationRegistration *appreg) +{ + static const WCHAR emptyW[] = {0}; + static const WCHAR txtW[] = {'.','t','x','t',0}; + static const WCHAR spacetxtW[] = {' ','.','t','x','t',0}; + HRESULT hr; + LPWSTR assocprog = NULL; + + hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, emptyW, AT_URLPROTOCOL, AL_EFFECTIVE, &assocprog); + ok(hr == E_INVALIDARG, "got 0x%x\n", hr); + + hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, emptyW, AT_FILEEXTENSION, AL_EFFECTIVE, &assocprog); + ok(hr == E_INVALIDARG, "got 0x%x\n", hr); + + hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, spacetxtW, AT_FILEEXTENSION, AL_EFFECTIVE, &assocprog); + ok(hr == E_INVALIDARG || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /* Win8 */, "got 0x%x\n", hr); + + hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, httpW, AT_URLPROTOCOL, AL_EFFECTIVE, NULL); + ok(hr == E_INVALIDARG, "got 0x%x\n", hr); + + /* AT_FILEEXTENSION must start with a period */ + hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, txtW, AT_FILEEXTENSION, AL_EFFECTIVE, &assocprog); + ok(hr == S_OK, "got 0x%x\n", hr); + trace("%s\n", wine_dbgstr_w(assocprog)); + CoTaskMemFree(assocprog); + + hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, emptyW, AT_STARTMENUCLIENT, AL_EFFECTIVE, &assocprog); + ok(hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), "got 0x%x\n", hr); + + hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, emptyW, AT_MIMETYPE, AL_EFFECTIVE, &assocprog); + ok(hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), "got 0x%x\n", hr); + + hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, httpW, AT_URLPROTOCOL, AL_EFFECTIVE, &assocprog); + todo_wine ok(hr == S_OK, "got 0x%x\n", hr); + trace("%s\n", wine_dbgstr_w(assocprog)); + CoTaskMemFree(assocprog); +} + START_TEST(assoc) { IQueryAssociations *qa; + IApplicationAssociationRegistration *appreg; HRESULT hr; CoInitialize(NULL); @@ -210,7 +236,18 @@ START_TEST(assoc) else win_skip("IQueryAssociations not supported, 0x%x\n", hr); - test_IApplicationAssociationRegistration_QueryInterface(); + /* this works since Vista */ + hr = CoCreateInstance(&CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC_SERVER, + &IID_IApplicationAssociationRegistration, (LPVOID *)&appreg); + if (hr == S_OK) + { + test_IApplicationAssociationRegistration_QueryInterface(appreg); + test_IApplicationAssociationRegistration_QueryCurrentDefault(appreg); + + IApplicationAssociationRegistration_Release(appreg); + } + else + win_skip("IApplicationAssociationRegistration not supported: 0x%x\n", hr); CoUninitialize(); } diff --git a/rostests/winetests/shell32/ebrowser.c b/rostests/winetests/shell32/ebrowser.c index 1936cf9ec11..4c255a152b9 100644 --- a/rostests/winetests/shell32/ebrowser.c +++ b/rostests/winetests/shell32/ebrowser.c @@ -1381,7 +1381,7 @@ static void test_navigation(void) ok(pSHCreateShellItem != NULL, "pSHCreateShellItem unexpectedly missing.\n"); GetCurrentDirectoryW(MAX_PATH, current_path); - if(!lstrlenW(current_path)) + if(!current_path[0]) { skip("Failed to create test-directory.\n"); return; diff --git a/rostests/winetests/shell32/recyclebin.c b/rostests/winetests/shell32/recyclebin.c index d449b7e4f01..a5ac1dc68a6 100644 --- a/rostests/winetests/shell32/recyclebin.c +++ b/rostests/winetests/shell32/recyclebin.c @@ -55,8 +55,7 @@ static void test_query_recyclebin(void) HRESULT hr; HANDLE file; SHFILEOPSTRUCTA shfo; - const CHAR name[] = "test.txt"; - CHAR buf[MAX_PATH + sizeof(name) + 1]; + CHAR temp_path[MAX_PATH-14], buf[MAX_PATH+1]; if(!pSHQueryRecycleBinA) { skip("SHQueryRecycleBinA does not exist\n"); @@ -67,18 +66,17 @@ static void test_query_recyclebin(void) skip("SHFileOperationA does not exist\n"); return; } - GetCurrentDirectoryA(MAX_PATH, buf); - strcat(buf,"\\"); - strcat(buf,name); + ok(GetTempPathA(sizeof(temp_path), temp_path), "GetTempPath failed\n"); + ok(GetTempFileNameA(temp_path, "trash", 0, buf), "GetTempFileName failed\n"); buf[strlen(buf) + 1] = '\0'; hr = pSHQueryRecycleBinA(buf,&info1); ok(hr == S_OK, "SHQueryRecycleBinA failed with error 0x%x\n", hr); ok(info1.i64Size!=0xdeadbeef,"i64Size not set\n"); ok(info1.i64NumItems!=0xdeadbeef,"i64NumItems not set\n"); /*create and send a file to the recycle bin*/ - file = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); - ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n",name); - WriteFile(file,name,strlen(name),&written,NULL); + file = CreateFileA(buf,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); + ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n",buf); + WriteFile(file,buf,strlen(buf),&written,NULL); CloseHandle(file); shfo.hwnd = NULL; shfo.wFunc = FO_DELETE; @@ -89,14 +87,9 @@ static void test_query_recyclebin(void) shfo.lpszProgressTitle = NULL; ok(!pSHFileOperationA(&shfo), "Deletion was not successful\n"); hr = pSHQueryRecycleBinA(buf,&info2); - ok(hr == S_OK, "SHQueryRecycleBinW failed with error 0x%x\n", hr); - if(info2.i64Size!=info1.i64Size || info2.i64NumItems!=info1.i64NumItems) { - ok(info2.i64Size==info1.i64Size+written,"Expected recycle bin to have 0x%s bytes\n",str_from_int64(info1.i64Size+written)); - ok(info2.i64NumItems==info1.i64NumItems+1,"Expected recycle bin to have 0x%s items\n",str_from_int64(info1.i64NumItems+1)); - } else todo_wine { - ok(info2.i64Size==info1.i64Size+written,"Expected recycle bin to have 0x%s bytes\n",str_from_int64(info1.i64Size+written)); - ok(info2.i64NumItems==info1.i64NumItems+1,"Expected recycle bin to have 0x%s items\n",str_from_int64(info1.i64NumItems+1)); - } + ok(hr == S_OK, "SHQueryRecycleBinA failed with error 0x%x\n", hr); + ok(info2.i64Size==info1.i64Size+written,"Expected recycle bin to have 0x%s bytes\n",str_from_int64(info1.i64Size+written)); + ok(info2.i64NumItems==info1.i64NumItems+1,"Expected recycle bin to have 0x%s items\n",str_from_int64(info1.i64NumItems+1)); } diff --git a/rostests/winetests/shell32/shelllink.c b/rostests/winetests/shell32/shelllink.c index 0b2b7be226f..b2580526e3d 100755 --- a/rostests/winetests/shell32/shelllink.c +++ b/rostests/winetests/shell32/shelllink.c @@ -49,8 +49,6 @@ static const GUID _IID_IShellLinkDataList = { { 0xb9, 0x2f, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1 } }; -static const WCHAR notafile[]= { 'C',':','\\','n','o','n','e','x','i','s','t','e','n','t','\\','f','i','l','e',0 }; - /* For some reason SHILCreateFromPath does not work on Win98 and * SHSimpleIDListFromPathA does not work on NT4. But if we call both we @@ -1153,6 +1151,41 @@ static void test_SHExtractIcons(void) for (i = 0; i < ret; i++) DestroyIcon(icons[i]); } +static void test_propertystore(void) +{ + IShellLinkA *linkA; + IShellLinkW *linkW; + IPropertyStore *ps; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + &IID_IShellLinkA, (void**)&linkA); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IShellLinkA_QueryInterface(linkA, &IID_IShellLinkW, (void**)&linkW); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IShellLinkA_QueryInterface(linkA, &IID_IPropertyStore, (void**)&ps); + if (hr == S_OK) { + IPropertyStoreCache *pscache; + + IPropertyStore_Release(ps); + + hr = IShellLinkW_QueryInterface(linkW, &IID_IPropertyStore, (void**)&ps); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IPropertyStore_QueryInterface(ps, &IID_IPropertyStoreCache, (void**)&pscache); + ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); + + IPropertyStore_Release(ps); + } + else + win_skip("IShellLink doesn't support IPropertyStore.\n"); + + IShellLinkA_Release(linkA); + IShellLinkW_Release(linkW); +} + START_TEST(shelllink) { HRESULT r; @@ -1180,6 +1213,7 @@ START_TEST(shelllink) test_GetIconLocation(); test_SHGetStockIconInfo(); test_SHExtractIcons(); + test_propertystore(); CoUninitialize(); } diff --git a/rostests/winetests/shell32/shellpath.c b/rostests/winetests/shell32/shellpath.c index 7486fac4df9..64b7c0866ff 100644 --- a/rostests/winetests/shell32/shellpath.c +++ b/rostests/winetests/shell32/shellpath.c @@ -101,6 +101,7 @@ static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR,UINT); static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *); static HRESULT (WINAPI *pSHSetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR); static HRESULT (WINAPI *pSHGetFolderPathEx)(REFKNOWNFOLDERID, DWORD, HANDLE, LPWSTR, DWORD); +static BOOL (WINAPI *pPathYetAnotherMakeUniqueName)(PWSTR, PCWSTR, PCWSTR, PCWSTR); static DLLVERSIONINFO shellVersion = { 0 }; static LPMALLOC pMalloc; @@ -207,6 +208,7 @@ static void loadShell32(void) pILFindLastID = (void *)GetProcAddress(hShell32, (LPCSTR)16); GET_PROC(SHFileOperationA) GET_PROC(SHGetMalloc) + GET_PROC(PathYetAnotherMakeUniqueName) ok(pSHGetMalloc != NULL, "shell32 is missing SHGetMalloc\n"); if (pSHGetMalloc) @@ -859,6 +861,11 @@ if (0) { /* crashes */ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ok(path != NULL, "expected path != NULL\n"); + path = NULL; + hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_DEFAULT_PATH, NULL, &path); + ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); + ok(path != NULL, "expected path != NULL\n"); + hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH); ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); ok(!lstrcmpiW(path, buffer), "expected equal paths\n"); @@ -876,7 +883,7 @@ if (0) { /* crashes */ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr); } hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len); - ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "expected 0x8007007a, got 0x%08x\n", hr); + ok(hr == E_NOT_SUFFICIENT_BUFFER, "expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hr); hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1); ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); @@ -2631,6 +2638,85 @@ static void test_DoEnvironmentSubst(void) } } +static void test_PathYetAnotherMakeUniqueName(void) +{ + static const WCHAR shortW[] = {'f','i','l','e','.','t','s','t',0}; + static const WCHAR short2W[] = {'f','i','l','e',' ','(','2',')','.','t','s','t',0}; + static const WCHAR tmpW[] = {'t','m','p',0}; + static const WCHAR longW[] = {'n','a','m','e',0}; + static const WCHAR long2W[] = {'n','a','m','e',' ','(','2',')',0}; + WCHAR nameW[MAX_PATH], buffW[MAX_PATH], pathW[MAX_PATH]; + HANDLE file; + BOOL ret; + + if (!pPathYetAnotherMakeUniqueName) + { + win_skip("PathYetAnotherMakeUniqueName() is not available.\n"); + return; + } + +if (0) +{ + /* crashes on Windows */ + ret = pPathYetAnotherMakeUniqueName(NULL, NULL, NULL, NULL); + ok(!ret, "got %d\n", ret); + + ret = pPathYetAnotherMakeUniqueName(nameW, NULL, NULL, NULL); + ok(!ret, "got %d\n", ret); +} + + GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW); + + /* Using short name only first */ + nameW[0] = 0; + ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL); + ok(ret, "got %d\n", ret); + lstrcpyW(buffW, pathW); + lstrcatW(buffW, shortW); + ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW)); + + /* now create a file with this name and get next name */ + file = CreateFileW(nameW, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); + ok(file != NULL, "got %p\n", file); + + nameW[0] = 0; + ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL); + ok(ret, "got %d\n", ret); + lstrcpyW(buffW, pathW); + lstrcatW(buffW, short2W); + ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW)); + + CloseHandle(file); + + /* Using short and long */ + nameW[0] = 0; + ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW); + ok(ret, "got %d\n", ret); + lstrcpyW(buffW, pathW); + lstrcatW(buffW, longW); + ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW)); + + file = CreateFileW(nameW, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); + ok(file != NULL, "got %p\n", file); + + nameW[0] = 0; + ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW); + ok(ret, "got %d\n", ret); + lstrcpyW(buffW, pathW); + lstrcatW(buffW, long2W); + ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW)); + + CloseHandle(file); + + /* Using long only */ + nameW[0] = 0; + ret = pPathYetAnotherMakeUniqueName(nameW, pathW, NULL, longW); + ok(ret, "got %d\n", ret); + lstrcpyW(buffW, pathW); + lstrcatW(buffW, longW); + ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW)); +} + START_TEST(shellpath) { if (!init()) return; @@ -2659,5 +2745,6 @@ START_TEST(shellpath) test_SHGetFolderPathEx(); test_knownFolders(); test_DoEnvironmentSubst(); + test_PathYetAnotherMakeUniqueName(); } } diff --git a/rostests/winetests/shell32/shlexec.c b/rostests/winetests/shell32/shlexec.c index 9f4b1a385a8..2b3947e7c59 100755 --- a/rostests/winetests/shell32/shlexec.c +++ b/rostests/winetests/shell32/shlexec.c @@ -118,7 +118,7 @@ static INT_PTR shell_execute(LPCSTR verb, LPCSTR file, LPCSTR parameters, LPCSTR * association it displays the 'Open With' dialog and I could not find * a flag to prevent this. */ - rc=(INT_PTR)ShellExecuteA(NULL, verb, file, parameters, directory, SW_SHOWNORMAL); + rc=(INT_PTR)ShellExecuteA(NULL, verb, file, parameters, directory, SW_HIDE); if (rc > 32) { @@ -183,7 +183,7 @@ static INT_PTR shell_execute_ex(DWORD mask, LPCSTR verb, LPCSTR file, trace("%s\n", shell_call); sei.cbSize=sizeof(sei); - sei.fMask=SEE_MASK_NOCLOSEPROCESS | mask; + sei.fMask=SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE | mask; sei.hwnd=NULL; sei.lpVerb=verb; sei.lpFile=file; @@ -857,6 +857,7 @@ static const char* testfiles[]= "%s\\masked", "%s\\test file.sde", "%s\\test file.exe", + "%s\\test file two.exe", "%s\\test2.exe", "%s\\simple.shlexec", "%s\\drawback_file.noassoc", @@ -931,7 +932,7 @@ static void test_lpFile_parsed(void) /* existing "drawback_file.noassoc" prevents finding "drawback_file.noassoc foo.shlexec" on wine */ sprintf(fileA, "%s\\drawback_file.noassoc foo.shlexec", tmpdir); rc=shell_execute(NULL, fileA, NULL, NULL); - todo_wine ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc); + ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc); /* if quoted, existing "drawback_file.noassoc" not prevents finding "drawback_file.noassoc foo.shlexec" on wine */ sprintf(fileA, "\"%s\\drawback_file.noassoc foo.shlexec\"", tmpdir); @@ -1159,6 +1160,8 @@ static BOOL test_one_cmdline(const cmdline_tests_t* test) win_skip("CommandLineToArgvW not implemented, skipping\n"); return FALSE; } + ok(!argsW[cl2a_count] || broken(argsW[cl2a_count] != NULL) /* before Vista */, + "expected NULL-terminated list of commandline arguments\n"); count = 0; while (test->args[count]) @@ -1218,6 +1221,8 @@ static void test_commandline2argv(void) *strW = 0; args = CommandLineToArgvW(strW, &numargs); ok(numargs == 1, "expected 1 args, got %d\n", numargs); + ok(!args || (!args[numargs] || broken(args[numargs] != NULL) /* before Vista */), + "expected NULL-terminated list of commandline arguments\n"); if (numargs == 1) { GetModuleFileNameW(NULL, strW, sizeof(strW)/sizeof(*strW)); @@ -1543,7 +1548,7 @@ static void test_filename(void) "%s failed: rc=%ld err=%u\n", shell_call, rc, GetLastError()); } - else todo_wine + else { ok(rc==test->rc, "%s failed: rc=%ld err=%u\n", shell_call, rc, GetLastError()); @@ -2090,6 +2095,7 @@ static void test_exes(void) { char filename[MAX_PATH]; char params[1024]; + DWORD retval; INT_PTR rc; sprintf(params, "shlexec \"%s\" Exec", child_file); @@ -2116,6 +2122,32 @@ static void test_exes(void) { win_skip("Skipping shellexecute of file with unassociated extension\n"); } + + /* the directory with the test programs contain "test file.exe" + * and "test file two.exe". Check we do not start the first + * when we specify to start the second (see bug 19666) + */ + sprintf(filename, "%s\\test file.exe", tmpdir); + retval = CopyFileA(argv0, filename, FALSE); + ok(retval, "CopyFile(\"%s\",\"%s\",FALSE) failed\n", argv0, filename); + sprintf(filename, "%s\\test file two.exe", tmpdir); + retval = CopyFileA(argv0, filename, FALSE); + ok(retval, "CopyFile(\"%s\",\"%s\",FALSE) failed\n", argv0, filename); + rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename, params, NULL, NULL); + ok(rc > 32, "%s returned %lu\n", shell_call, rc); + okChildInt("argcA", 4); + okChildString("argvA0", filename); + okChildString("argvA3", "Exec"); + + /* check quoted filename */ + sprintf(filename, "\"%s\\test file two.exe\"", tmpdir); + rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename, params, NULL, NULL); + ok(rc > 32, "%s returned %lu\n", shell_call, rc); + okChildInt("argcA", 4); + /* strip the quotes for the compare */ + sprintf(filename, "%s\\test file two.exe", tmpdir); + okChildString("argvA0", filename); + okChildString("argvA3", "Exec"); } typedef struct diff --git a/rostests/winetests/shell32/shlfileop.c b/rostests/winetests/shell32/shlfileop.c index 64d0fbc9ea3..07e4ee24df0 100644 --- a/rostests/winetests/shell32/shlfileop.c +++ b/rostests/winetests/shell32/shlfileop.c @@ -251,7 +251,7 @@ static void test_get_file_info(void) ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent) should return 1, got 0x%x\n", rc); if (rc) { - ok(strcpy(shfi.szDisplayName, "dummy") != 0, "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n"); + ok(strcmp(shfi.szDisplayName, "dummy"), "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n"); ok(shfi.iIcon != 0xdeadbeef, "SHGetFileInfoA(c:\\nonexistent) iIcon is not set\n"); } @@ -622,7 +622,6 @@ static void test_delete(void) shfo.pFrom = "nonexistent.txt\0"; shfo.wFunc = FO_DELETE; ret = SHFileOperationA(&shfo); - todo_wine ok(ret == 1026 || ret == ERROR_FILE_NOT_FOUND || /* Vista */ broken(ret == ERROR_SUCCESS), /* NT4 */ @@ -651,7 +650,6 @@ static void test_delete(void) shfo.pFrom = "test1.txt\0nonexistent.txt\0test2.txt\0"; shfo.wFunc = FO_DELETE; ret = SHFileOperationA(&shfo); - todo_wine ok(ret == 1026 || ret == ERROR_FILE_NOT_FOUND || /* Vista */ broken(ret == ERROR_SUCCESS), /* NT4 */ @@ -664,14 +662,12 @@ static void test_delete(void) init_shfo_tests(); shfo.pFrom = "testdir2\\nonexistent.txt\0"; ret = SHFileOperationA(&shfo); - todo_wine ok(ret == ERROR_FILE_NOT_FOUND || /* Vista */ broken(ret == 0x402) || /* XP */ broken(ret == ERROR_SUCCESS), /* NT4 */ "Expected 0x402 or ERROR_FILE_NOT_FOUND, got %x\n", ret); shfo.pFrom = "nonexistent\\one.txt\0"; ret = SHFileOperationA(&shfo); - todo_wine ok(ret == DE_INVALIDFILES || /* Vista or later */ broken(ret == 0x402), /* XP */ "Expected 0x402 or DE_INVALIDFILES, got %x\n", ret); @@ -898,13 +894,13 @@ static void test_copy(void) DeleteFileA("test7.txt"); RemoveDirectoryA("test8.txt"); - /* number of sources do not correspond to number of targets */ + /* number of sources does not correspond to number of targets */ set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0"); set_curr_dir_path(to, "test6.txt\0test7.txt\0"); retval = SHFileOperationA(&shfo2); if (dir_exists("test6.txt")) { - /* Vista and W2K8 (broken or new behavior ?) */ + /* Vista and W2K8 (broken or new behavior?) */ ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %d\n", retval); ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files " "are specified as a target\n"); @@ -1871,7 +1867,7 @@ static void test_move(void) init_shfo_tests(); - /* number of sources do not correspond to number of targets, + /* number of sources does not correspond to number of targets, include directories */ set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0"); set_curr_dir_path(to, "test6.txt\0test7.txt\0"); @@ -1904,7 +1900,7 @@ static void test_move(void) } init_shfo_tests(); - /* number of sources do not correspond to number of targets, + /* number of sources does not correspond to number of targets, files only, from exceeds to */ set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0"); @@ -1939,7 +1935,7 @@ static void test_move(void) } init_shfo_tests(); - /* number of sources do not correspond to number of targets, + /* number of sources does not correspond to number of targets, files only, too exceeds from */ set_curr_dir_path(from, "test1.txt\0test2.txt\0"); @@ -1963,7 +1959,7 @@ static void test_move(void) } init_shfo_tests(); - /* number of sources do not correspond to number of targets, + /* number of sources does not correspond to number of targets, target directories */ set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0"); set_curr_dir_path(to, "test4.txt\0test5.txt\0"); @@ -1987,7 +1983,7 @@ static void test_move(void) init_shfo_tests(); - /* 0 incomming files */ + /* 0 incoming files */ set_curr_dir_path(from, "\0\0"); set_curr_dir_path(to, "test6.txt\0\0"); retval = SHFileOperationA(&shfo2); diff --git a/rostests/winetests/shell32/shlfolder.c b/rostests/winetests/shell32/shlfolder.c index f096476d3ff..1b457bbb558 100644 --- a/rostests/winetests/shell32/shlfolder.c +++ b/rostests/winetests/shell32/shlfolder.c @@ -60,6 +60,7 @@ static HRESULT (WINAPI *pSHCreateItemFromIDList)(PCIDLIST_ABSOLUTE pidl, REFIID static HRESULT (WINAPI *pSHCreateItemFromParsingName)(PCWSTR,IBindCtx*,REFIID,void**); static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**); static HRESULT (WINAPI *pSHCreateShellItemArray)(LPCITEMIDLIST,IShellFolder*,UINT,LPCITEMIDLIST*,IShellItemArray**); +static HRESULT (WINAPI *pSHCreateShellItemArrayFromIDLists)(UINT, PCIDLIST_ABSOLUTE*, IShellItemArray**); static HRESULT (WINAPI *pSHCreateShellItemArrayFromDataObject)(IDataObject*, REFIID, void **); static HRESULT (WINAPI *pSHCreateShellItemArrayFromShellItem)(IShellItem*, REFIID, void **); static LPITEMIDLIST (WINAPI *pILCombine)(LPCITEMIDLIST,LPCITEMIDLIST); @@ -80,7 +81,7 @@ static WCHAR *make_wstr(const char *str) WCHAR *ret; int len; - if(!str || strlen(str) == 0) + if (!str || !str[0]) return NULL; len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); @@ -116,6 +117,7 @@ static void init_function_pointers(void) MAKEFUNC(SHCreateItemFromParsingName); MAKEFUNC(SHCreateShellItem); MAKEFUNC(SHCreateShellItemArray); + MAKEFUNC(SHCreateShellItemArrayFromIDLists); MAKEFUNC(SHCreateShellItemArrayFromDataObject); MAKEFUNC(SHCreateShellItemArrayFromShellItem); MAKEFUNC(SHGetFolderPathA); @@ -533,12 +535,13 @@ if (0) IShellFolder_Release(psfSystemDir); - GetCurrentDirectoryA(MAX_PATH, buf); - if(!lstrlenA(buf)) + cChars = GetCurrentDirectoryA(MAX_PATH, buf); + if(!cChars) { skip("Failed to get current directory, skipping tests.\n"); return; } + if(buf[cChars-1] != '\\') lstrcatA(buf, "\\"); SHGetDesktopFolder(&psfDesktop); @@ -546,7 +549,6 @@ if (0) /* .html */ lstrcpyA(pathA, buf); - lstrcatA(pathA, "\\"); lstrcatA(pathA, filename_html); hfile = CreateFileA(pathA, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if(hfile != INVALID_HANDLE_VALUE) @@ -590,7 +592,6 @@ if (0) /* .txt */ lstrcpyA(pathA, buf); - lstrcatA(pathA, "\\"); lstrcatA(pathA, filename_txt); hfile = CreateFileA(pathA, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if(hfile != INVALID_HANDLE_VALUE) @@ -604,6 +605,7 @@ if (0) hr = IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (void**)&psfChild); ok(hr == E_FAIL || /* Vista+ */ hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || /* XP, W2K3 */ + hr == E_INVALIDARG || /* W2K item in top dir */ broken(hr == S_OK), /* Win9x, NT4, W2K */ "Got 0x%08x\n", hr); if(SUCCEEDED(hr)) IShellFolder_Release(psfChild); @@ -616,7 +618,6 @@ if (0) /* .foo */ lstrcpyA(pathA, buf); - lstrcatA(pathA, "\\"); lstrcatA(pathA, filename_foo); hfile = CreateFileA(pathA, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if(hfile != INVALID_HANDLE_VALUE) @@ -630,6 +631,7 @@ if (0) hr = IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (void**)&psfChild); ok(hr == E_FAIL || /* Vista+ */ hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || /* XP, W2K3 */ + hr == E_INVALIDARG || /* W2K item in top dir */ broken(hr == S_OK), /* Win9x, NT4, W2K */ "Got 0x%08x\n", hr); if(SUCCEEDED(hr)) IShellFolder_Release(psfChild); @@ -779,7 +781,8 @@ static void test_GetDisplayName(void) if (pidlLast->mkid.cb >= 76) { ok(!lstrcmpW((WCHAR*)&pidlLast->mkid.abID[46], wszFileName) || (pidlLast->mkid.cb >= 94 && !lstrcmpW((WCHAR*)&pidlLast->mkid.abID[64], wszFileName)) || /* Vista */ - (pidlLast->mkid.cb >= 98 && !lstrcmpW((WCHAR*)&pidlLast->mkid.abID[68], wszFileName)), /* Win7 */ + (pidlLast->mkid.cb >= 98 && !lstrcmpW((WCHAR*)&pidlLast->mkid.abID[68], wszFileName)) || /* Win7 */ + (pidlLast->mkid.cb >= 102 && !lstrcmpW((WCHAR*)&pidlLast->mkid.abID[72], wszFileName)), /* Win8 */ "Filename should be stored as wchar-string at this position!\n"); } @@ -1853,8 +1856,9 @@ static void test_ITEMIDLIST_format(void) { } ok (!lstrcmpW(wszFile[i], name) || - !lstrcmpW(wszFile[i], name + 9) || /* Vista */ - !lstrcmpW(wszFile[i], name + 11), /* Win7 */ + !lstrcmpW(wszFile[i], name + 9) || /* Vista */ + !lstrcmpW(wszFile[i], name + 11) || /* Win7 */ + !lstrcmpW(wszFile[i], name + 13), /* Win8 */ "The filename should be stored in unicode at this position!\n"); } } @@ -2199,7 +2203,7 @@ static void test_SHCreateShellItem(void) return; } - if (!lstrlenA(curdirA)) + if (!curdirA[0]) { win_skip("GetCurrentDirectoryA returned empty string, skipping test_SHCreateShellItem\n"); return; @@ -2234,8 +2238,10 @@ static void test_SHCreateShellItem(void) pidl_abstestfile = pILCombine(pidl_cwd, pidl_testfile); + shellitem = (void*)0xdeadbeef; ret = pSHCreateShellItem(NULL, NULL, NULL, &shellitem); ok(ret == E_INVALIDARG, "SHCreateShellItem returned %x\n", ret); + ok(shellitem == 0, "Got %p\n", shellitem); if (0) /* crashes on Windows XP */ { @@ -2774,7 +2780,7 @@ static void test_ShellItemCompare(void) } GetCurrentDirectoryW(MAX_PATH, curdirW); - if(!lstrlenW(curdirW)) + if (!curdirW[0]) { skip("Failed to get current directory, skipping.\n"); return; @@ -3538,11 +3544,344 @@ static void test_SHCreateShellItemArray(void) else skip("No SHCreateShellItemArrayFromDataObject.\n"); + if(pSHCreateShellItemArrayFromIDLists) + { + WCHAR test1W[] = {'t','e','s','t','1','.','t','x','t',0}; + WCHAR test1pathW[MAX_PATH]; + LPITEMIDLIST pidltest1; + LPCITEMIDLIST pidl_array[2]; + + if(0) + { + /* Crashes */ + hr = pSHCreateShellItemArrayFromIDLists(0, NULL, NULL); + } + + psia = (void*)0xdeadbeef; + hr = pSHCreateShellItemArrayFromIDLists(0, NULL, &psia); + ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr); + ok(psia == NULL, "Got %p\n", psia); + + psia = (void*)0xdeadbeef; + hr = pSHCreateShellItemArrayFromIDLists(0, pidl_array, &psia); + ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr); + ok(psia == NULL, "Got %p\n", psia); + + psia = (void*)0xdeadbeef; + pidl_array[0] = NULL; + hr = pSHCreateShellItemArrayFromIDLists(1, pidl_array, &psia); + todo_wine ok(hr == E_OUTOFMEMORY, "Got 0x%08x\n", hr); + ok(psia == NULL, "Got %p\n", psia); + + psia = (void*)0xdeadbeef; + pidl_array[0] = pidl_testdir; + pidl_array[1] = NULL; + hr = pSHCreateShellItemArrayFromIDLists(2, pidl_array, &psia); + todo_wine ok(hr == S_OK || broken(hr == E_INVALIDARG) /* Vista */, "Got 0x%08x\n", hr); + todo_wine ok(psia != NULL || broken(psia == NULL) /* Vista */, "Got %p\n", psia); + if(SUCCEEDED(hr)) + { + IShellItem *psi; + UINT count = 0; + + hr = IShellItemArray_GetCount(psia, &count); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(count == 2, "Got %d\n", count); + + hr = IShellItemArray_GetItemAt(psia, 0, &psi); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + LPWSTR path; + hr = IShellItem_GetDisplayName(psi, SIGDN_DESKTOPABSOLUTEPARSING, &path); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(!lstrcmpW(path, cTestDirW), "Got %s\n", wine_dbgstr_w(path)); + if(SUCCEEDED(hr)) + CoTaskMemFree(path); + + IShellItem_Release(psi); + } + + hr = IShellItemArray_GetItemAt(psia, 1, &psi); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + LPWSTR path; + WCHAR desktoppath[MAX_PATH]; + BOOL result; + + result = pSHGetSpecialFolderPathW(NULL, desktoppath, CSIDL_DESKTOPDIRECTORY, FALSE); + ok(result, "SHGetSpecialFolderPathW(CSIDL_DESKTOPDIRECTORY) failed! %u\n", GetLastError()); + + hr = IShellItem_GetDisplayName(psi, SIGDN_DESKTOPABSOLUTEPARSING, &path); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(!lstrcmpW(path, desktoppath), "Got %s\n", wine_dbgstr_w(path)); + if(SUCCEEDED(hr)) + CoTaskMemFree(path); + + IShellItem_Release(psi); + } + + + IShellItemArray_Release(psia); + } + + + /* Single pidl */ + psia = (void*)0xdeadbeef; + pidl_array[0] = pidl_testdir; + hr = pSHCreateShellItemArrayFromIDLists(1, pidl_array, &psia); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + IShellItem *psi; + UINT count = 0; + + hr = IShellItemArray_GetCount(psia, &count); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(count == 1, "Got %d\n", count); + + hr = IShellItemArray_GetItemAt(psia, 0, &psi); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + LPWSTR path; + hr = IShellItem_GetDisplayName(psi, SIGDN_DESKTOPABSOLUTEPARSING, &path); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(!lstrcmpW(path, cTestDirW), "Got %s\n", wine_dbgstr_w(path)); + if(SUCCEEDED(hr)) + CoTaskMemFree(path); + + IShellItem_Release(psi); + } + + IShellItemArray_Release(psia); + } + + + lstrcpyW(test1pathW, cTestDirW); + myPathAddBackslashW(test1pathW); + lstrcatW(test1pathW, test1W); + + SHGetDesktopFolder(&pdesktopsf); + + hr = IShellFolder_ParseDisplayName(pdesktopsf, NULL, NULL, test1pathW, NULL, &pidltest1, NULL); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + psia = (void*)0xdeadbeef; + pidl_array[0] = pidl_testdir; + pidl_array[1] = pidltest1; + hr = pSHCreateShellItemArrayFromIDLists(2, pidl_array, &psia); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + IShellItem *psi; + UINT count = 0; + + hr = IShellItemArray_GetCount(psia, &count); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(count == 2, "Got %d\n", count); + + hr = IShellItemArray_GetItemAt(psia, 0, &psi); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + LPWSTR path; + hr = IShellItem_GetDisplayName(psi, SIGDN_DESKTOPABSOLUTEPARSING, &path); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(!lstrcmpW(path, cTestDirW), "Got %s\n", wine_dbgstr_w(path)); + if(SUCCEEDED(hr)) + CoTaskMemFree(path); + + IShellItem_Release(psi); + } + + hr = IShellItemArray_GetItemAt(psia, 1, &psi); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + LPWSTR path; + hr = IShellItem_GetDisplayName(psi, SIGDN_DESKTOPABSOLUTEPARSING, &path); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(!lstrcmpW(path, test1pathW), "Got %s\n", wine_dbgstr_w(path)); + if(SUCCEEDED(hr)) + CoTaskMemFree(path); + + IShellItem_Release(psi); + } + + + IShellItemArray_Release(psia); + } + + pILFree(pidltest1); + } + + IShellFolder_Release(pdesktopsf); + } + else + skip("No SHCreateShellItemArrayFromIDLists.\n"); + IShellFolder_Release(psf); pILFree(pidl_testdir); Cleanup(); } +static void test_ShellItemArrayEnumItems(void) +{ + IShellFolder *pdesktopsf, *psf; + IEnumIDList *peidl; + WCHAR cTestDirW[MAX_PATH]; + HRESULT hr; + LPITEMIDLIST pidl_testdir; + static const WCHAR testdirW[] = {'t','e','s','t','d','i','r',0}; + + if(!pSHCreateShellItemArray) + { + win_skip("No SHCreateShellItemArray, skipping test...\n"); + return; + } + + CreateFilesFolders(); + + SHGetDesktopFolder(&pdesktopsf); + + GetCurrentDirectoryW(MAX_PATH, cTestDirW); + myPathAddBackslashW(cTestDirW); + lstrcatW(cTestDirW, testdirW); + + hr = IShellFolder_ParseDisplayName(pdesktopsf, NULL, NULL, cTestDirW, NULL, &pidl_testdir, 0); + ok(hr == S_OK, "got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + hr = IShellFolder_BindToObject(pdesktopsf, pidl_testdir, NULL, (REFIID)&IID_IShellFolder, + (void**)&psf); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + pILFree(pidl_testdir); + } + IShellFolder_Release(pdesktopsf); + + hr = IShellFolder_EnumObjects(psf, NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &peidl); + ok(hr == S_OK, "Got %08x\n", hr); + if(SUCCEEDED(hr)) + { + IShellItemArray *psia; + LPITEMIDLIST apidl[5]; + UINT done, numitems, i; + + for(done = 0; done < 5; done++) + if(IEnumIDList_Next(peidl, 1, &apidl[done], NULL) != S_OK) + break; + ok(done == 5, "Got %d pidls\n", done); + IEnumIDList_Release(peidl); + + /* Create a ShellItemArray */ + hr = pSHCreateShellItemArray(NULL, psf, done, (LPCITEMIDLIST*)apidl, &psia); + ok(hr == S_OK, "Got 0x%08x\n", hr); + if(SUCCEEDED(hr)) + { + IEnumShellItems *iesi; + IShellItem *my_array[10]; + ULONG fetched; + + IShellItemArray_GetCount(psia, &numitems); + ok(numitems == done, "Got %d, expected %d\n", numitems, done); + + iesi = NULL; + hr = IShellItemArray_EnumItems(psia, &iesi); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(iesi != NULL, "Got NULL\n"); + if(SUCCEEDED(hr)) + { + IEnumShellItems *iesi2; + + /* This should fail according to the documentation and Win7+ */ + for(i = 0; i < 10; i++) my_array[i] = (void*)0xdeadbeef; + hr = IEnumShellItems_Next(iesi, 2, my_array, NULL); + ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Got 0x%08x\n", hr); + for(i = 0; i < 2; i++) + { + ok(my_array[i] == (void*)0xdeadbeef || + broken(my_array[i] != (void*)0xdeadbeef && my_array[i] != NULL), /* Vista */ + "Got %p (%d)\n", my_array[i], i); + + if(my_array[i] != (void*)0xdeadbeef) + IShellItem_Release(my_array[i]); + } + ok(my_array[2] == (void*)0xdeadbeef, "Got %p\n", my_array[2]); + + IEnumShellItems_Reset(iesi); + for(i = 0; i < 10; i++) my_array[i] = (void*)0xdeadbeef; + hr = IEnumShellItems_Next(iesi, 1, my_array, NULL); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(my_array[0] != NULL && my_array[0] != (void*)0xdeadbeef, "Got %p\n", my_array[0]); + if(my_array[0] != NULL && my_array[0] != (void*)0xdeadbeef) + IShellItem_Release(my_array[0]); + ok(my_array[1] == (void*)0xdeadbeef, "Got %p\n", my_array[1]); + + IEnumShellItems_Reset(iesi); + fetched = 0; + for(i = 0; i < 10; i++) my_array[i] = (void*)0xdeadbeef; + hr = IEnumShellItems_Next(iesi, numitems, my_array, &fetched); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(fetched == numitems, "Got %d\n", fetched); + for(i = 0;i < numitems; i++) + { + ok(my_array[i] != NULL && my_array[i] != (void*)0xdeadbeef, + "Got %p at %d\n", my_array[i], i); + + if(my_array[i] != NULL && my_array[i] != (void*)0xdeadbeef) + IShellItem_Release(my_array[i]); + } + ok(my_array[i] == (void*)0xdeadbeef, "Got %p\n", my_array[i]); + + /* Compare all the items */ + IEnumShellItems_Reset(iesi); + for(i = 0; i < numitems; i++) + { + IShellItem *psi; + int order; + + hr = IShellItemArray_GetItemAt(psia, i, &psi); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = IEnumShellItems_Next(iesi, 1, my_array, &fetched); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(fetched == 1, "Got %d\n", fetched); + + hr = IShellItem_Compare(psi, my_array[0], 0, &order); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(order == 0, "Got %d\n", order); + + IShellItem_Release(psi); + IShellItem_Release(my_array[0]); + } + + my_array[0] = (void*)0xdeadbeef; + hr = IEnumShellItems_Next(iesi, 1, my_array, &fetched); + ok(hr == S_FALSE, "Got 0x%08x\n", hr); + ok(fetched == 0, "Got %d\n", fetched); + ok(my_array[0] == (void*)0xdeadbeef, "Got %p\n", my_array[0]); + + /* Cloning not implemented anywhere */ + iesi2 = (void*)0xdeadbeef; + hr = IEnumShellItems_Clone(iesi, &iesi2); + ok(hr == E_NOTIMPL, "Got 0x%08x\n", hr); + ok(iesi2 == NULL || broken(iesi2 == (void*)0xdeadbeef) /* Vista */, "Got %p\n", iesi2); + + IEnumShellItems_Release(iesi); + } + + IShellItemArray_Release(psia); + } + + for(i = 0; i < done; i++) + pILFree(apidl[i]); + } +} + + static void test_ShellItemBindToHandler(void) { IShellItem *psi; @@ -3640,8 +3979,8 @@ static void test_ShellItemBindToHandler(void) if(SUCCEEDED(hr)) IUnknown_Release(punk); /* BHID_Transfer - ITransferSource and ITransferDestination are accessible starting Vista, IUnknown is - supported start Win8. */ + ITransferSource and ITransferDestination are accessible starting from Vista, IUnknown is + supported starting from Win8. */ hr = IShellItem_BindToHandler(psi, NULL, &BHID_Transfer, &IID_ITransferSource, (void**)&punk); ok(hr == S_OK || broken(FAILED(hr)) /* pre-Vista */, "Got 0x%08x\n", hr); if(SUCCEEDED(hr)) @@ -3709,10 +4048,15 @@ static void test_ShellItemBindToHandler(void) static void test_ShellItemGetAttributes(void) { - IShellItem *psi; - LPITEMIDLIST pidl_desktop; + IShellItem *psi, *psi_folder1, *psi_file1; + IShellFolder *pdesktopsf; + LPITEMIDLIST pidl_desktop, pidl; SFGAOF sfgao; HRESULT hr; + WCHAR curdirW[MAX_PATH]; + WCHAR buf[MAX_PATH]; + static const WCHAR testdir1W[] = {'t','e','s','t','d','i','r',0}; + static const WCHAR testfile1W[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0}; if(!pSHCreateShellItem) { @@ -3747,6 +4091,148 @@ static void test_ShellItemGetAttributes(void) ok(sfgao == SFGAO_FOLDER || broken(sfgao == 0) /* missing_events = exp_data->notify_count; SHChangeNotify(exp_data->signal, SHCNF_PATHA | SHCNF_FLUSH, - strlen(exp_data->path_1) > 0 ? exp_data->path_1 : NULL, - strlen(exp_data->path_2) > 0 ? exp_data->path_2 : NULL); + exp_data->path_1[0] ? exp_data->path_1 : NULL, + exp_data->path_2[0] ? exp_data->path_2 : NULL); do_events(); ok(exp_data->missing_events == 0, "%s: Expected wndproc to be called\n", exp_data->id); @@ -4558,7 +5045,7 @@ static void test_SHCreateDefaultContextMenu(void) } GetCurrentDirectoryW(MAX_PATH, path); - if(!lstrlenW(path)) + if (!path[0]) { skip("GetCurrentDirectoryW returned an empty string.\n"); return; @@ -4757,6 +5244,7 @@ START_TEST(shlfolder) test_LocalizedNames(); test_SHCreateShellItem(); test_SHCreateShellItemArray(); + test_ShellItemArrayEnumItems(); test_desktop_IPersist(); test_GetUIObject(); test_SHSimpleIDListFromPath(); @@ -4770,6 +5258,7 @@ START_TEST(shlfolder) test_SHChangeNotify(TRUE); test_ShellItemBindToHandler(); test_ShellItemGetAttributes(); + test_ShellItemArrayGetAttributes(); test_SHCreateDefaultContextMenu(); test_SHCreateShellFolderView(); test_SHCreateShellFolderViewEx(); diff --git a/rostests/winetests/shell32/shlview.c b/rostests/winetests/shell32/shlview.c index 554e0869cc0..b9d07de1d6b 100644 --- a/rostests/winetests/shell32/shlview.c +++ b/rostests/winetests/shell32/shlview.c @@ -485,11 +485,6 @@ static const struct message folderview_getfocused_seq[] = { { 0 } }; -static const struct message folderview_itemcount_seq[] = { - { LVM_GETITEMCOUNT, sent }, - { 0 } -}; - static void test_IShellView_CreateViewWindow(void) { IShellFolder *desktop; -- 2.17.1