mirror of
https://github.com/reactos/reactos.git
synced 2025-07-24 00:53:42 +00:00
[SHELL32_APITEST]
- Add tests for IShellFolder::CompareIDs. Patch by Mark Jansen, with additional test cases by Sylvain Deverre. CORE-10747 svn path=/trunk/; revision=71064
This commit is contained in:
parent
677a03e5af
commit
027a043944
4 changed files with 239 additions and 2 deletions
|
@ -7,8 +7,9 @@ add_executable(shell32_apitest
|
|||
CMyComputer.cpp
|
||||
CShellDesktop.cpp
|
||||
menu.cpp
|
||||
shelltest.cpp
|
||||
testlist.c)
|
||||
target_link_libraries(shell32_apitest wine uuid)
|
||||
target_link_libraries(shell32_apitest wine uuid ${PSEH_LIB})
|
||||
set_module_type(shell32_apitest win32cui)
|
||||
add_importlibs(shell32_apitest user32 gdi32 shell32 ole32 oleaut32 shlwapi msvcrt kernel32)
|
||||
add_importlibs(shell32_apitest user32 gdi32 shell32 ole32 oleaut32 shlwapi msvcrt kernel32 ntdll)
|
||||
add_cd_file(TARGET shell32_apitest DESTINATION reactos/bin FOR all)
|
||||
|
|
|
@ -3,17 +3,152 @@
|
|||
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
||||
* PURPOSE: Test for CShellDesktop
|
||||
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
|
||||
* Mark Jansen
|
||||
*/
|
||||
|
||||
#include "shelltest.h"
|
||||
#include <atlbase.h>
|
||||
#include <atlcom.h>
|
||||
#include <strsafe.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#include <shellutils.h>
|
||||
|
||||
|
||||
// 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<ITEMIDLIST> 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<ITEMIDLIST> 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<ITEMIDLIST> 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<IPersistFolder2> persist;
|
||||
hr = psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &persist));
|
||||
ok(hr == S_OK, "hr = %lx\n", hr);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
CComHeapPtr<ITEMIDLIST> 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<ITEMIDLIST> 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<ITEMIDLIST> 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<IShellFolder> psf2;
|
||||
hr = psf->BindToObject(programs, NULL, IID_IShellFolder, reinterpret_cast<void**>(&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<IShellFolder *>(psf2), "Expected %p == %p\n", static_cast<PVOID>(psf), static_cast<PVOID>(psf2));
|
||||
|
||||
TestShellFolder(psf2);
|
||||
TestCompareIDList(psf);
|
||||
}
|
||||
|
|
98
rostests/apitests/shell32/shelltest.cpp
Normal file
98
rostests/apitests/shell32/shelltest.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include "shelltest.h"
|
||||
#include <atlbase.h>
|
||||
#include <atlcom.h>
|
||||
|
||||
|
||||
// + Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20130503-00/?p=4463/
|
||||
// In short: We want to create an IDLIST from an item that does not exist,
|
||||
// so we have to provide WIN32_FIND_DATAW in a bind context.
|
||||
// If we don't, the FS will be queried, and we do not get a valid IDLIST for a non-existing path.
|
||||
|
||||
CComModule gModule;
|
||||
|
||||
class CFileSysBindData :
|
||||
public CComCoClass<CFileSysBindData>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IFileSystemBindData
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetFindData(const WIN32_FIND_DATAW *pfd)
|
||||
{
|
||||
m_Data = *pfd;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetFindData(WIN32_FIND_DATAW *pfd)
|
||||
{
|
||||
*pfd = m_Data;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CFileSysBindData)
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
BEGIN_COM_MAP(CFileSysBindData)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IFileSystemBindData, IFileSystemBindData)
|
||||
END_COM_MAP()
|
||||
private:
|
||||
WIN32_FIND_DATAW m_Data;
|
||||
};
|
||||
|
||||
static
|
||||
HRESULT
|
||||
AddFileSysBindCtx(_In_ IBindCtx *pbc)
|
||||
{
|
||||
CComPtr<IFileSystemBindData> spfsbc(new CComObject<CFileSysBindData>());
|
||||
WIN32_FIND_DATAW wfd = { 0 };
|
||||
wfd.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||
spfsbc->SetFindData(&wfd);
|
||||
HRESULT hr = pbc->RegisterObjectParam((LPOLESTR)STR_FILE_SYS_BIND_DATA, spfsbc);
|
||||
ok(hr == S_OK, "hr = %lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static
|
||||
HRESULT
|
||||
CreateBindCtxWithOpts(_In_ BIND_OPTS *pbo, _Outptr_ IBindCtx **ppbc)
|
||||
{
|
||||
CComPtr<IBindCtx> spbc;
|
||||
HRESULT hr = CreateBindCtx(0, &spbc);
|
||||
ok(hr == S_OK, "hr = %lx\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = spbc->SetBindOptions(pbo);
|
||||
ok(hr == S_OK, "hr = %lx\n", hr);
|
||||
}
|
||||
*ppbc = SUCCEEDED(hr) ? spbc.Detach() : NULL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
CreateFileSysBindCtx(_Outptr_ IBindCtx **ppbc)
|
||||
{
|
||||
CComPtr<IBindCtx> spbc;
|
||||
BIND_OPTS bo = { sizeof(bo), 0, STGM_CREATE, 0 };
|
||||
HRESULT hr = CreateBindCtxWithOpts(&bo, &spbc);
|
||||
ok(hr == S_OK, "hr = %lx\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = AddFileSysBindCtx(spbc);
|
||||
ok(hr == S_OK, "hr = %lx\n", hr);
|
||||
}
|
||||
*ppbc = SUCCEEDED(hr) ? spbc.Detach() : NULL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
VOID
|
||||
PathToIDList(LPCWSTR pszPath, ITEMIDLIST** ppidl)
|
||||
{
|
||||
CComPtr<IBindCtx> spbc;
|
||||
HRESULT hr = CreateFileSysBindCtx(&spbc);
|
||||
ok(hr == S_OK, "hr = %lx\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = SHParseDisplayName(pszPath, spbc, ppidl, 0, NULL);
|
||||
ok(hr == S_OK, "hr = %lx\n", hr);
|
||||
}
|
||||
}
|
||||
|
||||
// - Adapted from https://blogs.msdn.microsoft.com/oldnewthing/20130503-00/?p=4463/
|
|
@ -28,3 +28,5 @@
|
|||
DEFINE_GUID(CLSID_MenuBandSite, 0xE13EF4E4, 0xD2F2, 0x11D0, 0x98, 0x16, 0x00, 0xC0, 0x4F, 0xD9, 0x19, 0x72);
|
||||
|
||||
#include "unknownbase.h"
|
||||
|
||||
VOID PathToIDList(LPCWSTR pszPath, ITEMIDLIST** ppidl);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue