reactos/modules/rostests/apitests/shlwapi/IShellFolderHelpers.cpp
Katayama Hirofumi MZ 53518bbab3
[SHLWAPI][SHLWAPI_APITEST][SDK] Implement IShellFolder_GetDisplayNameOf (#6918)
This export function is needed to implement
shell32!SHGetRealIDL function correctly.
JIRA issue: CORE-19278
- Implement IShellFolder_GetDisplayNameOf
  function (This function is not inline function in
  this case) with retry data.
- Add SFGDNO_RETRYALWAYS flag to
  <shlwapi_undoc.h>.
- Add IShellFolderHelpers testcase.
2024-05-23 22:57:31 +09:00

309 lines
7.3 KiB
C++

/*
* PROJECT: ReactOS api tests
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Tests for SHLWAPI IShellFolder helpers
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
#include <apitest.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <versionhelpers.h>
#define SHLWAPI_ISHELLFOLDER_HELPERS
#include <shlwapi_undoc.h>
static INT s_nStep = 0;
class CTestShellFolder : public IShellFolder
{
public:
CTestShellFolder() { }
virtual ~CTestShellFolder() { }
static void *operator new(size_t size)
{
return LocalAlloc(LPTR, size);
}
static void operator delete(void *ptr)
{
LocalFree(ptr);
}
static void operator delete(void *ptr, size_t size)
{
LocalFree(ptr);
}
// IUnknown methods
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject) override
{
ok_int(s_nStep, 11);
ok_int(IsEqualGUID(riid, IID_IShellFolder2), TRUE);
++s_nStep;
return E_NOINTERFACE;
}
STDMETHOD_(ULONG, AddRef)() override
{
ok_int(TRUE, FALSE);
return 1;
}
STDMETHOD_(ULONG, Release)() override
{
ok_int(TRUE, FALSE);
return 1;
}
// IShellFolder methods
STDMETHOD(ParseDisplayName)(
HWND hwndOwner,
LPBC pbc,
LPOLESTR lpszDisplayName,
ULONG *pchEaten,
PIDLIST_RELATIVE *ppidl,
ULONG *pdwAttributes) override
{
ok_ptr(*ppidl, NULL);
ok_long(*pdwAttributes, 0);
++s_nStep;
return 0xDEADFACE;
}
STDMETHOD(EnumObjects)(
HWND hwndOwner,
DWORD dwFlags,
LPENUMIDLIST *ppEnumIDList) override
{
ok_int(TRUE, FALSE);
return E_NOTIMPL;
}
STDMETHOD(BindToObject)(
PCUIDLIST_RELATIVE pidl,
LPBC pbcReserved,
REFIID riid,
LPVOID *ppvOut) override
{
ok_int(TRUE, FALSE);
return E_NOTIMPL;
}
STDMETHOD(BindToStorage)(
PCUIDLIST_RELATIVE pidl,
LPBC pbcReserved,
REFIID riid,
LPVOID *ppvOut) override
{
ok_int(TRUE, FALSE);
return E_NOTIMPL;
}
STDMETHOD(CompareIDs)(
LPARAM lParam,
PCUIDLIST_RELATIVE pidl1,
PCUIDLIST_RELATIVE pidl2) override
{
switch (s_nStep)
{
case 11:
// It shouldn't come here
ok_int(TRUE, FALSE);
break;
case 12:
ok_long((LONG)lParam, 0x00001234);
break;
case 13:
ok_long((LONG)lParam, 0x00005678);
break;
default:
skip("\n");
break;
}
++s_nStep;
return 0xFEEDF00D;
}
STDMETHOD(CreateViewObject)(
HWND hwndOwner,
REFIID riid,
LPVOID *ppvOut) override
{
ok_int(TRUE, FALSE);
return E_NOTIMPL;
}
STDMETHOD(GetAttributesOf)(
UINT cidl,
PCUITEMID_CHILD_ARRAY apidl,
DWORD *rgfInOut) override
{
ok_int(TRUE, FALSE);
return E_NOTIMPL;
}
STDMETHOD(GetUIObjectOf)(
HWND hwndOwner,
UINT cidl,
PCUITEMID_CHILD_ARRAY apidl,
REFIID riid,
UINT * prgfInOut,
LPVOID * ppvOut) override
{
ok_int(TRUE, FALSE);
return E_NOTIMPL;
}
STDMETHOD(GetDisplayNameOf)(
PCUITEMID_CHILD pidl,
DWORD dwFlags,
LPSTRRET strRet) override
{
switch (s_nStep)
{
case 0:
ok_long(dwFlags, SHGDN_FORPARSING | SHGDN_FORADDRESSBAR | SHGDN_FOREDITING |
SHGDN_INFOLDER);
break;
case 1:
ok_long(dwFlags, SHGDN_FORPARSING | SHGDN_FORADDRESSBAR | SHGDN_INFOLDER);
break;
case 2:
ok_long(dwFlags, SHGDN_FORPARSING | SHGDN_INFOLDER);
break;
case 3:
ok_long(dwFlags, SHGDN_FORPARSING);
break;
case 4:
ok_long(dwFlags, SHGDN_FORADDRESSBAR | SHGDN_FOREDITING | SHGDN_INFOLDER);
break;
case 5:
ok_long(dwFlags, SHGDN_FORADDRESSBAR | SHGDN_INFOLDER);
break;
case 6:
ok_long(dwFlags, SHGDN_INFOLDER);
break;
case 7:
ok_long(dwFlags, SHGDN_FORPARSING | SHGDN_INFOLDER);
break;
case 8:
ok_long(dwFlags, SHGDN_INFOLDER);
break;
case 9:
ok_long(dwFlags, SHGDN_NORMAL);
break;
default:
skip("\n");
break;
}
++s_nStep;
return E_FAIL;
}
STDMETHOD(SetNameOf)(
HWND hwndOwner,
PCUITEMID_CHILD pidl,
LPCOLESTR lpName,
DWORD dwFlags,
PITEMID_CHILD *pPidlOut) override
{
ok_int(TRUE, FALSE);
return E_NOTIMPL;
}
};
static void Test_GetDisplayNameOf(void)
{
CTestShellFolder *psf = new CTestShellFolder();
HRESULT hr;
hr = IShellFolder_GetDisplayNameOf(
psf,
NULL,
SHGDN_FOREDITING | SHGDN_FORADDRESSBAR | SHGDN_FORPARSING | SHGDN_INFOLDER,
NULL,
0);
ok_long(hr, E_FAIL);
ok_int(s_nStep, 4);
hr = IShellFolder_GetDisplayNameOf(
psf,
NULL,
SHGDN_FOREDITING | SHGDN_FORADDRESSBAR | SHGDN_INFOLDER,
NULL,
0);
ok_long(hr, E_FAIL);
ok_int(s_nStep, 10);
if (s_nStep != 10)
skip("s_nStep value is wrong\n");
delete psf;
}
static void Test_ParseDisplayName(void)
{
CTestShellFolder *psf = new CTestShellFolder();
HRESULT hr;
s_nStep = 10;
LPITEMIDLIST pidl = (LPITEMIDLIST)UlongToPtr(0xDEADDEAD);
hr = IShellFolder_ParseDisplayName(
psf,
NULL,
NULL,
NULL,
NULL,
&pidl,
NULL);
ok_long(hr, 0xDEADFACE);
ok_int(s_nStep, 11);
delete psf;
}
typedef HRESULT (WINAPI *FN_IShellFolder_CompareIDs)(
_In_ IShellFolder *psf,
_In_ LPARAM lParam,
_In_ PCUIDLIST_RELATIVE pidl1,
_In_ PCUIDLIST_RELATIVE pidl2);
static void Test_CompareIDs(void)
{
FN_IShellFolder_CompareIDs fnIShellFolder_CompareIDs;
fnIShellFolder_CompareIDs =
(FN_IShellFolder_CompareIDs)
GetProcAddress(GetModuleHandleA("shlwapi"), MAKEINTRESOURCEA(551));
if (IsWindowsVistaOrGreater())
{
skip("Vista+\n");
ok(fnIShellFolder_CompareIDs == NULL, "Vista+ has no IShellFolder_CompareIDs\n");
return;
}
CTestShellFolder *psf = new CTestShellFolder();
HRESULT hr;
s_nStep = 11;
hr = fnIShellFolder_CompareIDs(
psf,
0xFFFF1234,
NULL,
NULL);
ok_long(hr, 0xFEEDF00D);
ok_int(s_nStep, 13);
s_nStep = 13;
hr = fnIShellFolder_CompareIDs(
psf,
0x00005678,
NULL,
NULL);
ok_long(hr, 0xFEEDF00D);
ok_int(s_nStep, 14);
delete psf;
}
START_TEST(IShellFolderHelpers)
{
HRESULT hrCoInit = ::CoInitialize(NULL);
Test_GetDisplayNameOf();
Test_ParseDisplayName();
Test_CompareIDs();
if (SUCCEEDED(hrCoInit))
::CoUninitialize();
}