Author: tfaber
Date: Mon Mar 28 15:35:21 2016
New Revision: 71064
URL:
http://svn.reactos.org/svn/reactos?rev=71064&view=rev
Log:
[SHELL32_APITEST]
- Add tests for IShellFolder::CompareIDs. Patch by Mark Jansen, with additional test cases
by Sylvain Deverre.
CORE-10747
Added:
trunk/rostests/apitests/shell32/shelltest.cpp (with props)
Modified:
trunk/rostests/apitests/shell32/CMakeLists.txt
trunk/rostests/apitests/shell32/CShellDesktop.cpp
trunk/rostests/apitests/shell32/shelltest.h
Modified: trunk/rostests/apitests/shell32/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/shell32/CMakeLis…
==============================================================================
--- trunk/rostests/apitests/shell32/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/apitests/shell32/CMakeLists.txt [iso-8859-1] Mon Mar 28 15:35:21 2016
@@ -7,8 +7,9 @@
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)
Modified: trunk/rostests/apitests/shell32/CShellDesktop.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/shell32/CShellDe…
==============================================================================
--- trunk/rostests/apitests/shell32/CShellDesktop.cpp [iso-8859-1] (original)
+++ trunk/rostests/apitests/shell32/CShellDesktop.cpp [iso-8859-1] Mon Mar 28 15:35:21
2016
@@ -3,16 +3,151 @@
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
* PURPOSE: Test for CShellDesktop
* PROGRAMMER: Thomas Faber <thomas.faber(a)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
@@ -83,4 +218,5 @@
ok(psf == static_cast<IShellFolder *>(psf2), "Expected %p == %p\n",
static_cast<PVOID>(psf), static_cast<PVOID>(psf2));
TestShellFolder(psf2);
-}
+ TestCompareIDList(psf);
+}
Added: trunk/rostests/apitests/shell32/shelltest.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/shell32/shelltes…
==============================================================================
--- trunk/rostests/apitests/shell32/shelltest.cpp (added)
+++ trunk/rostests/apitests/shell32/shelltest.cpp [iso-8859-1] Mon Mar 28 15:35:21 2016
@@ -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/
Propchange: trunk/rostests/apitests/shell32/shelltest.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/apitests/shell32/shelltest.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/shell32/shelltes…
==============================================================================
--- trunk/rostests/apitests/shell32/shelltest.h [iso-8859-1] (original)
+++ trunk/rostests/apitests/shell32/shelltest.h [iso-8859-1] Mon Mar 28 15:35:21 2016
@@ -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);