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 #define SHLWAPI_ISHELLFOLDER_HELPERS 14 #include <shlwapi_undoc.h> 15 16 static INT s_nStep = 0; 17 18 class CTestShellFolder : public IShellFolder 19 { 20 public: 21 CTestShellFolder() { } 22 virtual ~CTestShellFolder() { } 23 24 static void *operator new(size_t size) 25 { 26 return LocalAlloc(LPTR, size); 27 } 28 static void operator delete(void *ptr) 29 { 30 LocalFree(ptr); 31 } 32 static void operator delete(void *ptr, size_t size) 33 { 34 LocalFree(ptr); 35 } 36 37 // IUnknown methods 38 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject) override 39 { 40 ok_int(s_nStep, 11); 41 ok_int(IsEqualGUID(riid, IID_IShellFolder2), TRUE); 42 ++s_nStep; 43 return E_NOINTERFACE; 44 } 45 STDMETHOD_(ULONG, AddRef)() override 46 { 47 ok_int(TRUE, FALSE); 48 return 1; 49 } 50 STDMETHOD_(ULONG, Release)() override 51 { 52 ok_int(TRUE, FALSE); 53 return 1; 54 } 55 56 // IShellFolder methods 57 STDMETHOD(ParseDisplayName)( 58 HWND hwndOwner, 59 LPBC pbc, 60 LPOLESTR lpszDisplayName, 61 ULONG *pchEaten, 62 PIDLIST_RELATIVE *ppidl, 63 ULONG *pdwAttributes) override 64 { 65 ok_ptr(*ppidl, NULL); 66 ok_long(*pdwAttributes, 0); 67 ++s_nStep; 68 return 0xDEADFACE; 69 } 70 STDMETHOD(EnumObjects)( 71 HWND hwndOwner, 72 DWORD dwFlags, 73 LPENUMIDLIST *ppEnumIDList) override 74 { 75 ok_int(TRUE, FALSE); 76 return E_NOTIMPL; 77 } 78 STDMETHOD(BindToObject)( 79 PCUIDLIST_RELATIVE pidl, 80 LPBC pbcReserved, 81 REFIID riid, 82 LPVOID *ppvOut) override 83 { 84 ok_int(TRUE, FALSE); 85 return E_NOTIMPL; 86 } 87 STDMETHOD(BindToStorage)( 88 PCUIDLIST_RELATIVE pidl, 89 LPBC pbcReserved, 90 REFIID riid, 91 LPVOID *ppvOut) override 92 { 93 ok_int(TRUE, FALSE); 94 return E_NOTIMPL; 95 } 96 STDMETHOD(CompareIDs)( 97 LPARAM lParam, 98 PCUIDLIST_RELATIVE pidl1, 99 PCUIDLIST_RELATIVE pidl2) override 100 { 101 switch (s_nStep) 102 { 103 case 11: 104 // It shouldn't come here 105 ok_int(TRUE, FALSE); 106 break; 107 case 12: 108 ok_long((LONG)lParam, 0x00001234); 109 break; 110 case 13: 111 ok_long((LONG)lParam, 0x00005678); 112 break; 113 default: 114 skip("\n"); 115 break; 116 } 117 ++s_nStep; 118 return 0xFEEDF00D; 119 } 120 STDMETHOD(CreateViewObject)( 121 HWND hwndOwner, 122 REFIID riid, 123 LPVOID *ppvOut) override 124 { 125 ok_int(TRUE, FALSE); 126 return E_NOTIMPL; 127 } 128 STDMETHOD(GetAttributesOf)( 129 UINT cidl, 130 PCUITEMID_CHILD_ARRAY apidl, 131 DWORD *rgfInOut) override 132 { 133 ok_int(TRUE, FALSE); 134 return E_NOTIMPL; 135 } 136 STDMETHOD(GetUIObjectOf)( 137 HWND hwndOwner, 138 UINT cidl, 139 PCUITEMID_CHILD_ARRAY apidl, 140 REFIID riid, 141 UINT * prgfInOut, 142 LPVOID * ppvOut) override 143 { 144 ok_int(TRUE, FALSE); 145 return E_NOTIMPL; 146 } 147 STDMETHOD(GetDisplayNameOf)( 148 PCUITEMID_CHILD pidl, 149 DWORD dwFlags, 150 LPSTRRET strRet) override 151 { 152 switch (s_nStep) 153 { 154 case 0: 155 ok_long(dwFlags, SHGDN_FORPARSING | SHGDN_FORADDRESSBAR | SHGDN_FOREDITING | 156 SHGDN_INFOLDER); 157 break; 158 case 1: 159 ok_long(dwFlags, SHGDN_FORPARSING | SHGDN_FORADDRESSBAR | SHGDN_INFOLDER); 160 break; 161 case 2: 162 ok_long(dwFlags, SHGDN_FORPARSING | SHGDN_INFOLDER); 163 break; 164 case 3: 165 ok_long(dwFlags, SHGDN_FORPARSING); 166 break; 167 case 4: 168 ok_long(dwFlags, SHGDN_FORADDRESSBAR | SHGDN_FOREDITING | SHGDN_INFOLDER); 169 break; 170 case 5: 171 ok_long(dwFlags, SHGDN_FORADDRESSBAR | SHGDN_INFOLDER); 172 break; 173 case 6: 174 ok_long(dwFlags, SHGDN_INFOLDER); 175 break; 176 case 7: 177 ok_long(dwFlags, SHGDN_FORPARSING | SHGDN_INFOLDER); 178 break; 179 case 8: 180 ok_long(dwFlags, SHGDN_INFOLDER); 181 break; 182 case 9: 183 ok_long(dwFlags, SHGDN_NORMAL); 184 break; 185 default: 186 skip("\n"); 187 break; 188 } 189 ++s_nStep; 190 return E_FAIL; 191 } 192 STDMETHOD(SetNameOf)( 193 HWND hwndOwner, 194 PCUITEMID_CHILD pidl, 195 LPCOLESTR lpName, 196 DWORD dwFlags, 197 PITEMID_CHILD *pPidlOut) override 198 { 199 ok_int(TRUE, FALSE); 200 return E_NOTIMPL; 201 } 202 }; 203 204 static void Test_GetDisplayNameOf(void) 205 { 206 CTestShellFolder *psf = new CTestShellFolder(); 207 HRESULT hr; 208 209 hr = IShellFolder_GetDisplayNameOf( 210 psf, 211 NULL, 212 SHGDN_FOREDITING | SHGDN_FORADDRESSBAR | SHGDN_FORPARSING | SHGDN_INFOLDER, 213 NULL, 214 0); 215 ok_long(hr, E_FAIL); 216 ok_int(s_nStep, 4); 217 218 hr = IShellFolder_GetDisplayNameOf( 219 psf, 220 NULL, 221 SHGDN_FOREDITING | SHGDN_FORADDRESSBAR | SHGDN_INFOLDER, 222 NULL, 223 0); 224 ok_long(hr, E_FAIL); 225 ok_int(s_nStep, 10); 226 227 if (s_nStep != 10) 228 skip("s_nStep value is wrong\n"); 229 230 delete psf; 231 } 232 233 static void Test_ParseDisplayName(void) 234 { 235 CTestShellFolder *psf = new CTestShellFolder(); 236 HRESULT hr; 237 238 s_nStep = 10; 239 LPITEMIDLIST pidl = (LPITEMIDLIST)UlongToPtr(0xDEADDEAD); 240 hr = IShellFolder_ParseDisplayName( 241 psf, 242 NULL, 243 NULL, 244 NULL, 245 NULL, 246 &pidl, 247 NULL); 248 ok_long(hr, 0xDEADFACE); 249 ok_int(s_nStep, 11); 250 251 delete psf; 252 } 253 254 typedef HRESULT (WINAPI *FN_IShellFolder_CompareIDs)( 255 _In_ IShellFolder *psf, 256 _In_ LPARAM lParam, 257 _In_ PCUIDLIST_RELATIVE pidl1, 258 _In_ PCUIDLIST_RELATIVE pidl2); 259 260 static void Test_CompareIDs(void) 261 { 262 FN_IShellFolder_CompareIDs fnIShellFolder_CompareIDs; 263 fnIShellFolder_CompareIDs = 264 (FN_IShellFolder_CompareIDs) 265 GetProcAddress(GetModuleHandleA("shlwapi"), MAKEINTRESOURCEA(551)); 266 267 if (IsWindowsVistaOrGreater()) 268 { 269 skip("Vista+\n"); 270 ok(fnIShellFolder_CompareIDs == NULL, "Vista+ has no IShellFolder_CompareIDs\n"); 271 return; 272 } 273 274 CTestShellFolder *psf = new CTestShellFolder(); 275 HRESULT hr; 276 277 s_nStep = 11; 278 hr = fnIShellFolder_CompareIDs( 279 psf, 280 0xFFFF1234, 281 NULL, 282 NULL); 283 ok_long(hr, 0xFEEDF00D); 284 ok_int(s_nStep, 13); 285 286 s_nStep = 13; 287 hr = fnIShellFolder_CompareIDs( 288 psf, 289 0x00005678, 290 NULL, 291 NULL); 292 ok_long(hr, 0xFEEDF00D); 293 ok_int(s_nStep, 14); 294 295 delete psf; 296 } 297 298 START_TEST(IShellFolderHelpers) 299 { 300 HRESULT hrCoInit = ::CoInitialize(NULL); 301 302 Test_GetDisplayNameOf(); 303 Test_ParseDisplayName(); 304 Test_CompareIDs(); 305 306 if (SUCCEEDED(hrCoInit)) 307 ::CoUninitialize(); 308 } 309