ReactOS 0.4.17-dev-1190-g4c812f4
IShellFolderHelpers.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for SHLWAPI IShellFolder helpers
5 * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include <apitest.h>
9#include <shlobj.h>
10#include <shlwapi.h>
11#include <versionhelpers.h>
12
13#include <shlwapi_undoc.h>
15
16static INT s_nStep = 0;
17
19{
20public:
21 int m_QISF2 = 0;
22
24 virtual ~CTestShellFolder() { }
25
26 static void *operator new(size_t size)
27 {
28 return LocalAlloc(LPTR, size);
29 }
30 static void operator delete(void *ptr)
31 {
33 }
34 static void operator delete(void *ptr, size_t size)
35 {
37 }
38
39 // IUnknown methods
40 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject) override
41 {
42 if (riid == IID_IShellFolder2)
43 {
44 if (m_QISF2 && !ppvObject)
45 {
46 return E_POINTER;
47 }
48 else if (m_QISF2 > 0)
49 {
50 *ppvObject = static_cast<IShellFolder*>(this); // Note: This is a lie, we are just a v1
51 AddRef();
52 return S_OK;
53 }
54 else if (m_QISF2 < 0)
55 {
56 *ppvObject = NULL;
57 return E_NOINTERFACE;
58 }
59 }
60
61 ok_int(s_nStep, 11);
62 ok_int(IsEqualGUID(riid, IID_IShellFolder2), TRUE);
63 ++s_nStep;
64 return E_NOINTERFACE;
65 }
66 STDMETHOD_(ULONG, AddRef)() override
67 {
68 ok(m_QISF2 > 0, "Unexpected unless we implement IShellFolder2\n");
69 return 1;
70 }
72 {
73 ok(m_QISF2 > 0, "Unexpected unless we implement IShellFolder2\n");
74 return 1;
75 }
76
77 // IShellFolder methods
79 HWND hwndOwner,
80 LPBC pbc,
81 LPOLESTR lpszDisplayName,
82 ULONG *pchEaten,
83 PIDLIST_RELATIVE *ppidl,
84 ULONG *pdwAttributes) override
85 {
86 ok_ptr(*ppidl, NULL);
87 ok_long(*pdwAttributes, 0);
88 ++s_nStep;
89 return 0xDEADFACE;
90 }
92 HWND hwndOwner,
94 LPENUMIDLIST *ppEnumIDList) override
95 {
97 return E_NOTIMPL;
98 }
101 LPBC pbcReserved,
102 REFIID riid,
103 LPVOID *ppvOut) override
104 {
105 ok_int(TRUE, FALSE);
106 return E_NOTIMPL;
107 }
110 LPBC pbcReserved,
111 REFIID riid,
112 LPVOID *ppvOut) override
113 {
114 ok_int(TRUE, FALSE);
115 return E_NOTIMPL;
116 }
119 PCUIDLIST_RELATIVE pidl1,
120 PCUIDLIST_RELATIVE pidl2) override
121 {
122 switch (s_nStep)
123 {
124 case 11:
125 // It shouldn't come here
126 ok_int(TRUE, FALSE);
127 break;
128 case 12:
129 ok_long((LONG)lParam, 0x00001234);
130 break;
131 case 13:
132 ok_long((LONG)lParam, 0x00005678);
133 break;
134 case 99:
135 return lParam;
136 default:
137 skip("\n");
138 break;
139 }
140 ++s_nStep;
141 return 0xFEEDF00D;
142 }
144 HWND hwndOwner,
145 REFIID riid,
146 LPVOID *ppvOut) override
147 {
148 ok_int(TRUE, FALSE);
149 return E_NOTIMPL;
150 }
152 UINT cidl,
154 DWORD *rgfInOut) override
155 {
156 ok_int(TRUE, FALSE);
157 return E_NOTIMPL;
158 }
160 HWND hwndOwner,
161 UINT cidl,
163 REFIID riid,
164 UINT * prgfInOut,
165 LPVOID * ppvOut) override
166 {
167 ok_int(TRUE, FALSE);
168 return E_NOTIMPL;
169 }
171 PCUITEMID_CHILD pidl,
173 LPSTRRET strRet) override
174 {
175 switch (s_nStep)
176 {
177 case 0:
180 break;
181 case 1:
183 break;
184 case 2:
186 break;
187 case 3:
189 break;
190 case 4:
192 break;
193 case 5:
195 break;
196 case 6:
198 break;
199 case 7:
201 break;
202 case 8:
204 break;
205 case 9:
207 break;
208 default:
209 skip("\n");
210 break;
211 }
212 ++s_nStep;
213 return E_FAIL;
214 }
216 HWND hwndOwner,
217 PCUITEMID_CHILD pidl,
218 LPCOLESTR lpName,
220 PITEMID_CHILD *pPidlOut) override
221 {
222 ok_int(TRUE, FALSE);
223 return E_NOTIMPL;
224 }
225};
226
227static void Test_GetDisplayNameOf(void)
228{
230 HRESULT hr;
231
233 psf,
234 NULL,
235 SHGDN_FOREDITING | SHGDN_FORADDRESSBAR | SHGDN_FORPARSING | SHGDN_INFOLDER,
236 NULL,
237 0);
238 ok_long(hr, E_FAIL);
239 ok_int(s_nStep, 4);
240
242 psf,
243 NULL,
244 SHGDN_FOREDITING | SHGDN_FORADDRESSBAR | SHGDN_INFOLDER,
245 NULL,
246 0);
247 ok_long(hr, E_FAIL);
248 ok_int(s_nStep, 10);
249
250 if (s_nStep != 10)
251 skip("s_nStep value is wrong\n");
252
253 delete psf;
254}
255
256static void Test_ParseDisplayName(void)
257{
259 HRESULT hr;
260
261 s_nStep = 10;
262 LPITEMIDLIST pidl = (LPITEMIDLIST)UlongToPtr(0xDEADDEAD);
264 psf,
265 NULL,
266 NULL,
267 NULL,
268 NULL,
269 &pidl,
270 NULL);
271 ok_long(hr, 0xDEADFACE);
272 ok_int(s_nStep, 11);
273
274 delete psf;
275}
276
278 _In_ IShellFolder *psf,
282
283static void Test_CompareIDs(void)
284{
285 FN_IShellFolder_CompareIDs fnIShellFolder_CompareIDs;
286 fnIShellFolder_CompareIDs =
289
291 {
292 skip("Vista+\n");
293 ok(fnIShellFolder_CompareIDs == NULL, "Vista+ has no IShellFolder_CompareIDs\n");
294 return;
295 }
296
298 HRESULT hr;
299
300 s_nStep = 11;
301 hr = fnIShellFolder_CompareIDs(
302 psf,
303 0xFFFF1234,
304 NULL,
305 NULL);
306 ok_long(hr, 0xFEEDF00D);
307 ok_int(s_nStep, 13);
308
309 s_nStep = 13;
310 hr = fnIShellFolder_CompareIDs(
311 psf,
312 0x00005678,
313 NULL,
314 NULL);
315 ok_long(hr, 0xFEEDF00D);
316 ok_int(s_nStep, 14);
317
318 psf->m_QISF2 = -1; // No IShellFolder2 support, flags should be masked away
319 s_nStep = 12;
320 hr = fnIShellFolder_CompareIDs(psf, 0xFFFF1234, NULL, NULL);
321 ok_long(hr, 0xFEEDF00D);
322 psf->m_QISF2 = 0;
323
324 psf->m_QISF2 = 1; // "Implements" IShellFolder2, we can handle all flags
325 s_nStep = 99;
326 hr = fnIShellFolder_CompareIDs(psf, 0x87654321, NULL, NULL);
327 ok_long(hr, 0x87654321);
328 psf->m_QISF2 = 0;
329
330 delete psf;
331}
332
333START_TEST(IShellFolderHelpers)
334{
335 HRESULT hrCoInit = ::CoInitialize(NULL);
336
340
341 if (SUCCEEDED(hrCoInit))
343}
static INT s_nStep
static void Test_CompareIDs(void)
static void Test_ParseDisplayName(void)
HRESULT(WINAPI * FN_IShellFolder_CompareIDs)(_In_ IShellFolder *psf, _In_ LPARAM lParam, _In_ PCUIDLIST_RELATIVE pidl1, _In_ PCUIDLIST_RELATIVE pidl2)
static void Test_GetDisplayNameOf(void)
#define ok_long(expression, result)
Definition: atltest.h:133
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
#define ok_ptr(expression, result)
Definition: atltest.h:108
#define STDMETHOD(m)
Definition: basetyps.h:62
STDMETHOD() GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) override
STDMETHOD_(ULONG, Release)() override
STDMETHOD_(ULONG, AddRef)() override
STDMETHOD() GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut, LPVOID *ppvOut) override
STDMETHOD() CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut) override
STDMETHOD() BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) override
STDMETHOD() BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) override
STDMETHOD() CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) override
STDMETHOD() GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut) override
STDMETHOD() EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) override
STDMETHOD() SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut) override
LPARAM lParam
Definition: combotst.c:139
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
_Check_return_ _In_ PQUERY_INTERFACE QueryInterface
Definition: dispmprt.h:1318
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
#define IShellFolder_ParseDisplayName
Definition: utils.cpp:14
#define IShellFolder_GetDisplayNameOf
Definition: utils.cpp:13
#define UlongToPtr(u)
Definition: config.h:106
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
unsigned int UINT
Definition: sysinfo.c:13
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
REFIID riid
Definition: atlbase.h:39
@ SHGDN_FORADDRESSBAR
Definition: shobjidl.idl:165
ULONG AddRef()
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define LPTR
Definition: minwinbase.h:93
LONG_PTR LPARAM
Definition: minwindef.h:175
static PVOID ptr
Definition: dispmode.c:27
static IParseDisplayName ParseDisplayName
Definition: moniker.c:1141
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _In_
Definition: no_sal2.h:158
interface IBindCtx * LPBC
Definition: objfwd.h:18
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
const ITEMIDLIST_RELATIVE UNALIGNED * PCUIDLIST_RELATIVE
Definition: shtypes.idl:57
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
VERSIONHELPERAPI IsWindowsVistaOrGreater()
_In_ LPCSTR lpName
Definition: winbase.h:2519
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480