ReactOS  0.4.15-dev-1207-g698a8e6
EnumObjects.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: Test for zipfldr
5  * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 static bool g_bOldZipfldr = false;
11 
12 void ok_displayname_(const char* file, int line, IShellFolder* pFolder, PCUITEMID_CHILD pidl, SHGDNF Flags, LPCWSTR Name)
13 {
14  STRRET NameRet;
15  HRESULT hr;
16 
17  hr = pFolder->GetDisplayNameOf(pidl, Flags, &NameRet);
18  ok_hr_(file, line, hr, S_OK);
19  if (!SUCCEEDED(hr))
20  return;
21 
22  WCHAR DisplayName[MAX_PATH];
23  hr = StrRetToBufW(&NameRet, pidl, DisplayName, RTL_NUMBER_OF(DisplayName));
24  ok_hr_(file, line, hr, S_OK);
25  if (!SUCCEEDED(hr))
26  return;
27 
28  ok_wstr_(file, line, DisplayName, Name);
29 }
30 
31 struct ZipFiles
32 {
35 };
36 
39 
40 static void test_EnumObjects_Files(const WCHAR* Filename, IShellFolder* pFolder)
41 {
42  CComPtr<IEnumIDList> spEnum;
43  HRESULT hr = pFolder->EnumObjects(NULL, SHCONTF_NONFOLDERS, &spEnum);
44  ok_hr(hr, S_OK);
45  if (!SUCCEEDED(hr))
46  return;
47 
48  SFGAOF BaseAttributes = SFGAO_STREAM | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | SFGAO_CANCOPY | SFGAO_CANMOVE;
49  ZipFiles ExpectedFiles[] = {
50  { L"cccc.txt", BaseAttributes },
51  { L"bbbb.txt", BaseAttributes },
52  };
53 
54  ULONG totalFetched = 0;
55  do
56  {
57  CComHeapPtr<ITEMID_CHILD> child;
58  ULONG celtFetched = 0;
59  hr = spEnum->Next(1, &child, &celtFetched);
60  if (hr != S_OK)
61  break;
62  ok_int(celtFetched, 1);
63  if (celtFetched != 1)
64  break;
65 
66  LPCWSTR ExpectedName = totalFetched < RTL_NUMBER_OF(ExpectedFiles) ? ExpectedFiles[totalFetched].Name : L"<TOO MANY FILES>";
67  SFGAOF ExpectedAttributes = totalFetched < RTL_NUMBER_OF(ExpectedFiles) ? ExpectedFiles[totalFetched].Attributes : 0xdeaddead;
68 
69  totalFetched++;
70 
71 
72  CComPtr<IDataObject> spDataObj;
73  hr = pFolder->GetUIObjectOf(NULL, 1, &child, IID_IDataObject, NULL, reinterpret_cast<LPVOID*>(&spDataObj));
74  ok_hr(hr, S_OK);
75 
76  if (!g_bOldZipfldr && !IsFormatAdvertised(spDataObj, cfHIDA, TYMED_HGLOBAL))
77  {
78  trace("Pre-Vista zipfldr\n");
79  // No seconds in filetimes, less functional IStream* implementation
80  g_bOldZipfldr = true;
81  }
82 
83  ok_displayname(pFolder, child, SHGDN_NORMAL, ExpectedName);
84  if (g_bOldZipfldr)
85  {
86  ok_displayname(pFolder, child, SHGDN_FORPARSING, ExpectedName);
87  }
88  else
89  {
91  StringCchPrintfW(Buffer, _countof(Buffer), L"%s\\%s", Filename, ExpectedName);
92  ok_displayname(pFolder, child, SHGDN_FORPARSING, Buffer);
93  }
94  ok_displayname(pFolder, child, SHGDN_FORPARSING | SHGDN_INFOLDER, ExpectedName);
95  ok_displayname(pFolder, child, SHGDN_FOREDITING , ExpectedName);
96  ok_displayname(pFolder, child, SHGDN_FOREDITING | SHGDN_INFOLDER, ExpectedName);
97  ok_displayname(pFolder, child, SHGDN_FORADDRESSBAR , ExpectedName);
98  ok_displayname(pFolder, child, SHGDN_FORADDRESSBAR | SHGDN_INFOLDER, ExpectedName);
99 
100  SFGAOF Attributes = 0;
101  hr = pFolder->GetAttributesOf(1, &child, &Attributes);
102  ok_hr(hr, S_OK);
103  ok_hex(Attributes, ExpectedAttributes);
104 
105  STGMEDIUM medium = {0};
106  FORMATETC etc = { cfFileDescriptor, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
107  HRESULT hr = spDataObj->GetData(&etc, &medium);
108  ok_hex(hr, S_OK);
109  if (!SUCCEEDED(hr))
110  continue;
111 
112  ok_hex(medium.tymed, TYMED_HGLOBAL);
113  PVOID pData = GlobalLock(medium.hGlobal);
114  FILEGROUPDESCRIPTORW* Descriptor = static_cast<FILEGROUPDESCRIPTORW*>(pData);
115  ok_hex(Descriptor->cItems, 1);
116  if (Descriptor->cItems == 1)
117  ok_wstr(Descriptor->fgd[0].cFileName, ExpectedName);
118  GlobalUnlock(medium.hGlobal);
119  ReleaseStgMedium(&medium);
120  } while (true);
121 
122  ok_int(totalFetched, RTL_NUMBER_OF(ExpectedFiles));
123  ok_hr(hr, S_FALSE);
124 }
125 
127 {
128  CComPtr<IEnumIDList> spEnum;
129  HRESULT hr = pFolder->EnumObjects(NULL, SHCONTF_FOLDERS, &spEnum);
130  ok_hr(hr, S_OK);
131  if (!SUCCEEDED(hr))
132  return;
133 
134  SFGAOF BaseAttributes = SFGAO_FOLDER | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | SFGAO_CANCOPY | SFGAO_CANMOVE;
135  ZipFiles ExpectedFolders[] = {
136  { L"aaaa", BaseAttributes | (g_bOldZipfldr ? 0 : SFGAO_STORAGE) },
137  { L"cccc", BaseAttributes | (g_bOldZipfldr ? 0 : SFGAO_STORAGE) },
138  };
139 
140  LPCWSTR ExpectedExtraFiles[2][4] =
141  {
142  {
143  L"aaaa\\a_aaaa",
144  L"aaaa\\a_cccc",
145  L"aaaa\\a_bbbb.txt",
146  L"aaaa\\a_cccc.txt",
147  },
148  {
149  L"cccc\\c_cccc",
150  L"cccc\\c_bbbb.txt",
151  L"cccc\\c_cccc.txt",
152  L"cccc\\c_aaaa",
153  },
154  };
155 
156  ULONG totalFetched = 0;
157  do
158  {
159  CComHeapPtr<ITEMID_CHILD> child;
160  ULONG celtFetched = 0;
161  hr = spEnum->Next(1, &child, &celtFetched);
162  if (hr != S_OK)
163  break;
164  ok_int(celtFetched, 1);
165  if (celtFetched != 1)
166  break;
167 
168  LPCWSTR ExpectedName = totalFetched < RTL_NUMBER_OF(ExpectedFolders) ? ExpectedFolders[totalFetched].Name : L"<TOO MANY FILES>";
169  SFGAOF ExpectedAttributes = totalFetched < RTL_NUMBER_OF(ExpectedFolders) ? ExpectedFolders[totalFetched].Attributes : 0xdeaddead;
170  LPCWSTR* ExtraFiles = totalFetched < RTL_NUMBER_OF(ExpectedExtraFiles) ? ExpectedExtraFiles[totalFetched] : ExpectedExtraFiles[0];
171 
172  totalFetched++;
173 
174  ok_displayname(pFolder, child, SHGDN_NORMAL, ExpectedName);
175  if (g_bOldZipfldr)
176  {
177  ok_displayname(pFolder, child, SHGDN_FORPARSING, ExpectedName);
178  }
179  else
180  {
182  StringCchPrintfW(Buffer, _countof(Buffer), L"%s\\%s", Filename, ExpectedName);
183  ok_displayname(pFolder, child, SHGDN_FORPARSING, Buffer);
184  }
185  ok_displayname(pFolder, child, SHGDN_FORPARSING | SHGDN_INFOLDER, ExpectedName);
186  ok_displayname(pFolder, child, SHGDN_FOREDITING , ExpectedName);
187  ok_displayname(pFolder, child, SHGDN_FOREDITING | SHGDN_INFOLDER, ExpectedName);
188 
189  SFGAOF Attributes = 0;
190  hr = pFolder->GetAttributesOf(1, &child, &Attributes);
191  ok_hr(hr, S_OK);
192  ok_hex(Attributes, ExpectedAttributes);
193 
194  CComPtr<IDataObject> spData;
195  hr = pFolder->GetUIObjectOf(NULL, 1, &child, IID_IDataObject, NULL, reinterpret_cast<LPVOID*>(&spData));
196  ok_hr(hr, S_OK);
197 
198  STGMEDIUM medium = {0};
199  FORMATETC etc = { cfFileDescriptor, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
200  HRESULT hr = spData->GetData(&etc, &medium);
201  ok_hex(hr, S_OK);
202  if (!SUCCEEDED(hr))
203  continue;
204 
205  ok_hex(medium.tymed, TYMED_HGLOBAL);
206  PVOID pData = GlobalLock(medium.hGlobal);
207  FILEGROUPDESCRIPTORW* Descriptor = static_cast<FILEGROUPDESCRIPTORW*>(pData);
208  ok_hex(Descriptor->cItems, 5);
209  if (Descriptor->cItems == 5)
210  {
211  ok_wstr(Descriptor->fgd[0].cFileName, ExpectedName);
212  ok_wstr(Descriptor->fgd[1].cFileName, ExtraFiles[0]);
213  ok_wstr(Descriptor->fgd[2].cFileName, ExtraFiles[1]);
214  ok_wstr(Descriptor->fgd[3].cFileName, ExtraFiles[2]);
215  ok_wstr(Descriptor->fgd[4].cFileName, ExtraFiles[3]);
216  }
217  GlobalUnlock(medium.hGlobal);
218  ReleaseStgMedium(&medium);
219  } while (true);
220 
221  ok_int(totalFetched, RTL_NUMBER_OF(ExpectedFolders));
222  ok_hr(hr, S_FALSE);
223 }
224 
225 static void test_EnumObjects(const WCHAR* Filename)
226 {
227  CComPtr<IShellFolder> spFolder;
228  if (!InitializeShellFolder(Filename, spFolder))
229  return;
230 
231  // Let's ask the shell how it wants to display the full path to our zip file
232  WCHAR ZipFilename[MAX_PATH] = L"<Failed to query zip path>";
233  {
234  CComPtr<IPersistFolder2> spPersistFolder;
235  HRESULT hr = spFolder->QueryInterface(IID_PPV_ARG(IPersistFolder2, &spPersistFolder));
236  ok_hr(hr, S_OK);
237  if (SUCCEEDED(hr))
238  {
239  CComHeapPtr<ITEMIDLIST_ABSOLUTE> zipPidl;
240  hr = spPersistFolder->GetCurFolder(&zipPidl);
241  ok_hr(hr, S_OK);
242  if (SUCCEEDED(hr))
243  {
244  BOOL bHasPath = SHGetPathFromIDListW(zipPidl, ZipFilename);
245  ok_int(bHasPath, TRUE);
246  }
247  }
248  }
249 
250 
251  test_EnumObjects_Files(ZipFilename, spFolder);
252  test_EnumObjects_Folders(ZipFilename, spFolder);
253 }
254 
256 {
257  skip("Code in zipfldr not implemented yet\n");
258  return;
259 
261 
262  ok_hr(hr, S_OK);
263  if (!SUCCEEDED(hr))
264  return;
265 
266  WCHAR ZipTestFile[MAX_PATH];
268  return;
269  test_EnumObjects(ZipTestFile);
270  DeleteFileW(ZipTestFile);
271  CoUninitialize();
272 }
#define ok_hr(status, expected)
Definition: ACListISF.cpp:30
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
#define IsFormatAdvertised(pDataObj, cfFormat, tymed)
Definition: precomp.h:28
#define TRUE
Definition: types.h:120
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1522
#define ok_displayname(pFolder, pidl, Flags, Name)
Definition: precomp.h:31
static bool extract_resource(const WCHAR *Filename, LPCWSTR ResourceName)
Definition: db.cpp:1460
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1294
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
const GUID IID_IDataObject
#define IDR_ZIP_TEST_ENUM
Definition: resource.h:3
#define IID_PPV_ARG(Itype, ppType)
#define ok_hex(expression, result)
Definition: atltest.h:94
static HWND child
Definition: cursoricon.c:298
int WINAPI EnumObjects(_In_ HDC, _In_ int, _In_ GOBJENUMPROC, _In_ LPARAM)
IN PVCB IN PBCB OUT PDIRENT IN USHORT IN POEM_STRING Filename
Definition: fatprocs.h:934
HRESULT GetDisplayNameOf([in] PCUITEMID_CHILD pidl, [in] SHGDNF uFlags, [out] STRRET *lpName)
static void test_EnumObjects_Files(const WCHAR *Filename, IShellFolder *pFolder)
Definition: EnumObjects.cpp:40
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned int BOOL
Definition: ntddk_ex.h:94
START_TEST(EnumObjects)
HRESULT EnumObjects([in] HWND hwndOwner, [in] SHCONTF grfFlags, [out] IEnumIDList **ppenumIDList)
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
#define S_FALSE
Definition: winerror.h:2357
HRESULT GetAttributesOf([in] UINT cidl, [in, size_is(cidl)] PCUITEMID_CHILD_ARRAY apidl, [in, out] SFGAOF *rgfInOut)
smooth NULL
Definition: ftsmooth.c:416
#define ok_int(expression, result)
Definition: atltest.h:134
Definition: parser.c:48
Definition: bufpool.h:45
#define ok_wstr_(file, line, x, y)
Definition: test.h:870
static void test_EnumObjects_Folders(const WCHAR *Filename, IShellFolder *pFolder)
static CLIPFORMAT cfHIDA
Definition: EnumObjects.cpp:37
static bool g_bOldZipfldr
Definition: EnumObjects.cpp:10
#define ok_hr_(file, line, status, expected)
Definition: apitest.h:36
#define trace
Definition: atltest.h:70
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
#define _countof(array)
Definition: sndvol32.h:68
#define MAX_PATH
Definition: compat.h:34
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: cdrom.h:932
static CLIPFORMAT cfFileDescriptor
Definition: EnumObjects.cpp:38
static const WCHAR L[]
Definition: oid.c:1250
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define ok_wstr(x, y)
Definition: atltest.h:130
UINT WINAPI RegisterClipboardFormatA(_In_ LPCSTR)
#define S_OK
Definition: intsafe.h:51
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
static void test_EnumObjects(const WCHAR *Filename)
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define InitializeShellFolder(Filename, pFolder)
Definition: precomp.h:25
#define skip(...)
Definition: atltest.h:64
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
unsigned int ULONG
Definition: retypes.h:1
#define CFSTR_SHELLIDLISTA
Definition: shlobj.h:345
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
LPCWSTR Name
Definition: EnumObjects.cpp:33
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
SFGAOF Attributes
Definition: EnumObjects.cpp:34
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
void ok_displayname_(const char *file, int line, IShellFolder *pFolder, PCUITEMID_CHILD pidl, SHGDNF Flags, LPCWSTR Name)
Definition: EnumObjects.cpp:12
#define SUCCEEDED(hr)
Definition: intsafe.h:49
static const WCHAR CFSTR_FILEDESCRIPTORW[]
Definition: shlobj.h:439
HRESULT GetUIObjectOf([in] HWND hwndOwner, [in] UINT cidl, [in, size_is(cidl)] PCUITEMID_CHILD_ARRAY apidl, [in] REFIID riid, [in, out, unique] UINT *prgfInOut, [out, iid_is(riid)] void **ppvOut)
Definition: fci.c:126