X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=rostests%2Fapitests%2Fshell32%2FCShellDesktop.cpp;h=5a3a0d854d11de94d34afd441414cc4b84da17c0;hp=c11348b7160070bd692d215429b72e48cbb4fddb;hb=027a0439440ef94a26889f7f18256a53b9ec4ed9;hpb=677a03e5af4bae50fd44d3dbf688b917b7c59a96 diff --git a/rostests/apitests/shell32/CShellDesktop.cpp b/rostests/apitests/shell32/CShellDesktop.cpp index c11348b7160..5a3a0d854d1 100644 --- a/rostests/apitests/shell32/CShellDesktop.cpp +++ b/rostests/apitests/shell32/CShellDesktop.cpp @@ -3,17 +3,152 @@ * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory * PURPOSE: Test for CShellDesktop * PROGRAMMER: Thomas Faber + * Mark Jansen */ #include "shelltest.h" #include #include #include +#include #define NDEBUG #include #include + +// We would normally use S_LESSTHAN and S_GREATERTHAN, but w2k3 returns numbers like 3 and -3... +// So instead we check on the sign bit (compare result is the low word of the hresult). +#define SHORT_SIGN_BIT 0x8000 + +static +VOID +compare_imp(IShellFolder* psf, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, HRESULT expected) +{ + HRESULT hr; + _SEH2_TRY + { + hr = psf->CompareIDs(0, pidl1, pidl2); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + winetest_ok(0, "Exception %lx!\n", _SEH2_GetExceptionCode()); + hr = HRESULT_FROM_WIN32(RtlNtStatusToDosError(_SEH2_GetExceptionCode())); + } + _SEH2_END; + if (expected == S_LESSTHAN) + winetest_ok(SUCCEEDED(hr) && (hr & SHORT_SIGN_BIT), "hr = %lx\n", hr); + else if (expected == S_EQUAL) + winetest_ok(hr == S_EQUAL, "hr = %lx\n", hr); + else if (expected == S_GREATERTHAN) + winetest_ok(SUCCEEDED(hr) && !(hr & SHORT_SIGN_BIT), "hr = %lx\n", hr); + else + winetest_ok(hr == expected, "hr = %lx\n", hr); +} + +// make the winetest_ok look like it came from the line where the compare function was called, and not from inside the compare_imp function :) +#define compare (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : compare_imp + +static +VOID +TestCompareIDList(IShellFolder* psf) +{ + compare(psf, NULL, NULL, E_INVALIDARG); + + CComHeapPtr desktop; + HRESULT hr = SHGetFolderLocation(NULL, CSIDL_DESKTOP, NULL, NULL, &desktop); + ok(hr == S_OK, "hr = %lx\n", hr); + compare(psf, desktop, NULL, E_INVALIDARG); + compare(psf, NULL, desktop, E_INVALIDARG); + compare(psf, desktop, desktop, S_EQUAL); + + // First check the ordering of some special folders against eachother + CComHeapPtr internet; + hr = SHGetFolderLocation(NULL, CSIDL_INTERNET, NULL, NULL, &internet); + ok(hr == S_OK, "hr = %lx\n", hr); + compare(psf, internet, desktop, S_LESSTHAN); + compare(psf, desktop, internet, S_GREATERTHAN); + + CComHeapPtr programs; + hr = SHGetFolderLocation(NULL, CSIDL_PROGRAMS, NULL, NULL, &programs); + ok(hr == S_OK, "hr = %lx\n", hr); + compare(psf, programs, desktop, S_LESSTHAN); + compare(psf, desktop, programs, S_GREATERTHAN); + compare(psf, internet, programs, S_GREATERTHAN); + compare(psf, programs, internet, S_LESSTHAN); + + // Verify that an idlist retrieved from GetCurFolder is equal to the original one. + CComPtr persist; + hr = psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &persist)); + ok(hr == S_OK, "hr = %lx\n", hr); + if (hr == S_OK) + { + CComHeapPtr cur; + hr = persist->GetCurFolder(&cur); + ok(hr == S_OK, "hr = %lx\n", hr); + compare(psf, cur, desktop, S_EQUAL); + compare(psf, desktop, cur, S_EQUAL); + } + + // Compare special folders against full paths + CComHeapPtr dir1, dir2; + PathToIDList(L"A:\\AAA.AAA", &dir1); + PathToIDList(L"A:\\ZZZ.ZZZ", &dir2); + + compare(psf, dir1, desktop, S_LESSTHAN); + compare(psf, desktop, dir1, S_GREATERTHAN); + compare(psf, dir1, programs, S_LESSTHAN); + compare(psf, programs, dir1, S_GREATERTHAN); + compare(psf, dir1, dir1, S_EQUAL); + + compare(psf, dir2, desktop, S_LESSTHAN); + compare(psf, desktop, dir2, S_GREATERTHAN); + compare(psf, dir2, programs, S_LESSTHAN); + compare(psf, programs, dir2, S_GREATERTHAN); + compare(psf, dir2, dir2, S_EQUAL); + + CComHeapPtr dir3, dir4; + PathToIDList(L"Z:\\AAA.AAA", &dir3); + PathToIDList(L"Z:\\ZZZ.ZZZ", &dir4); + + compare(psf, dir3, desktop, S_LESSTHAN); + compare(psf, desktop, dir3, S_GREATERTHAN); + compare(psf, dir3, programs, S_GREATERTHAN); + compare(psf, programs, dir3, S_LESSTHAN); + compare(psf, dir3, dir3, S_EQUAL); + + compare(psf, dir4, desktop, S_LESSTHAN); + compare(psf, desktop, dir4, S_GREATERTHAN); + compare(psf, dir4, programs, S_GREATERTHAN); + compare(psf, programs, dir4, S_LESSTHAN); + compare(psf, dir4, dir4, S_EQUAL); + + // Now compare the paths against eachother. + compare(psf, dir1, dir2, S_LESSTHAN); + compare(psf, dir2, dir1, S_GREATERTHAN); + + compare(psf, dir2, dir3, S_LESSTHAN); + compare(psf, dir3, dir2, S_GREATERTHAN); + + compare(psf, dir3, dir4, S_LESSTHAN); + compare(psf, dir4, dir3, S_GREATERTHAN); + + // Check that comparing desktop pidl with another one with another IShellFolder fails + CComPtr psf2; + hr = psf->BindToObject(programs, NULL, IID_IShellFolder, reinterpret_cast(&psf2)); + ok(hr == S_OK, "Impossible to bind to Programs pidl"); + if (hr == S_OK) + { + // Compare desktop pidl in programs scope should fail since it's relative pidl + compare(psf2, desktop, programs, E_INVALIDARG); + compare(psf2, programs, desktop, E_INVALIDARG); + // For the same reasons, filesystem paths can't be compared with special shell + // folders that don't have CFSFolder in children + compare(psf2, dir1, dir2, E_INVALIDARG); + compare(psf2, dir2, dir1, E_INVALIDARG); + } +} + static VOID TestShellFolder( @@ -83,4 +218,5 @@ START_TEST(CShellDesktop) ok(psf == static_cast(psf2), "Expected %p == %p\n", static_cast(psf), static_cast(psf2)); TestShellFolder(psf2); + TestCompareIDList(psf); }