ReactOS 0.4.15-dev-7918-g2a2556c
SHGetAttributesFromDataObject.cpp File Reference
#include "shelltest.h"
#include <ndk/rtlfuncs.h>
#include <stdio.h>
#include <shellutils.h>
#include <shlwapi.h>
Include dependency graph for SHGetAttributesFromDataObject.cpp:

Go to the source code of this file.

Classes

struct  TmpFile
 

Macros

#define ok_attributes   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_attributes_
 
#define ok_hr_ret(x, y)   ok_hr(x, y); if (x != y) return
 

Functions

CComPtr< IShellFolder_BindToObject (PCUIDLIST_ABSOLUTE pidl)
 
static void ok_attributes_ (IDataObject *pDataObject, HRESULT expect_hr, DWORD expect_mask, DWORD expect_attr, UINT expect_items)
 
static void test_SpecialCases ()
 
static void test_AttributesRegistration ()
 
static void test_MultipleFiles ()
 
 START_TEST (SHGetAttributesFromDataObject)
 

Variables

static CLIPFORMAT g_DataObjectAttributes = 0
 
static const DWORD dwDefaultAttributeMask
 

Macro Definition Documentation

◆ ok_attributes

#define ok_attributes   (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_attributes_

Definition at line 88 of file SHGetAttributesFromDataObject.cpp.

◆ ok_hr_ret

#define ok_hr_ret (   x,
  y 
)    ok_hr(x, y); if (x != y) return

Definition at line 89 of file SHGetAttributesFromDataObject.cpp.

Function Documentation

◆ _BindToObject()

CComPtr< IShellFolder > _BindToObject ( PCUIDLIST_ABSOLUTE  pidl)

Definition at line 41 of file SHGetAttributesFromDataObject.cpp.

42{
43 CComPtr<IShellFolder> spDesktop, spResult;
44 HRESULT hr = SHGetDesktopFolder(&spDesktop);
46 return spResult;
47
48 if (FAILED_UNEXPECTEDLY(spDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &spResult))))
49 {
50 spResult.Release();
51 }
52 return spResult;
53}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#define NULL
Definition: types.h:112
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
HRESULT hr
Definition: shlfolder.c:183
#define IID_PPV_ARG(Itype, ppType)

Referenced by test_MultipleFiles().

◆ ok_attributes_()

static void ok_attributes_ ( IDataObject pDataObject,
HRESULT  expect_hr,
DWORD  expect_mask,
DWORD  expect_attr,
UINT  expect_items 
)
static

Definition at line 56 of file SHGetAttributesFromDataObject.cpp.

57{
58 FORMATETC fmt = { g_DataObjectAttributes, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
59 STGMEDIUM medium = {};
60
61 HRESULT hr = pDataObject->GetData(&fmt, &medium);
62 winetest_ok(hr == expect_hr, "Unexpected result from GetData, got 0x%lx, expected 0x%lx\n", hr, expect_hr);
63
64 if (hr == expect_hr && expect_hr == S_OK)
65 {
66 LPVOID blob = GlobalLock(medium.hGlobal);
67 winetest_ok(blob != nullptr, "Failed to lock hGlobal\n");
68 if (blob)
69 {
70 SIZE_T size = GlobalSize(medium.hGlobal);
71 winetest_ok(size == 0xc, "Unexpected size, got %lu, expected 12\n", size);
72 if (size == 0xc)
73 {
75 winetest_ok(data[0] == expect_mask, "Unexpected mask, got 0x%lx, expected 0x%lx\n", data[0], expect_mask);
76 winetest_ok(data[1] == expect_attr, "Unexpected attr, got 0x%lx, expected 0x%lx\n", data[1], expect_attr);
77 winetest_ok(data[2] == expect_items, "Unexpected item count, got %lu, expected %u\n", data[2], expect_items);
78 }
79 GlobalUnlock(medium.hGlobal);
80 }
81 }
82
83 if (SUCCEEDED(hr))
84 ReleaseStgMedium(&medium);
85}
static CLIPFORMAT g_DataObjectAttributes
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
HRESULT GetData([in, unique] FORMATETC *pformatetcIn, [out] STGMEDIUM *pmedium)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define expect_hr(expected, got)
Definition: assoc.c:27
DWORD * PDWORD
Definition: pedump.c:68
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
Definition: image.c:134
Definition: dsound.c:943
ULONG_PTR SIZE_T
Definition: typedefs.h:80

◆ START_TEST()

Definition at line 302 of file SHGetAttributesFromDataObject.cpp.

303{
304 HRESULT hr;
305
307 ok_hr(hr, S_OK);
308 if (!SUCCEEDED(hr))
309 return;
310
311 g_DataObjectAttributes = (CLIPFORMAT)RegisterClipboardFormatW(L"DataObjectAttributes");
312 ok(g_DataObjectAttributes != 0, "Unable to register DataObjectAttributes\n");
313
317
319}
#define ok_hr(status, expected)
Definition: ACListISF.cpp:31
static void test_SpecialCases()
static void test_AttributesRegistration()
static void test_MultipleFiles()
#define ok(value,...)
Definition: atltest.h:57
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define L(x)
Definition: ntvdm.h:50
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)

◆ test_AttributesRegistration()

static void test_AttributesRegistration ( )
static

Definition at line 113 of file SHGetAttributesFromDataObject.cpp.

114{
115 WCHAR Buffer[MAX_PATH] = {};
116
118 CComHeapPtr<ITEMIDLIST_ABSOLUTE> spPath(ILCreateFromPathW(Buffer));
119
120 ok(spPath != nullptr, "Unable to create pidl from %S\n", Buffer);
121 if (spPath == nullptr)
122 return;
123
124 SFGAOF attributes = dwDefaultAttributeMask;
125 HRESULT hr;
126 {
127 CComPtr<IShellFolder> spFolder;
129 hr = SHBindToParent(spPath, IID_PPV_ARG(IShellFolder, &spFolder), &child);
130 ok_hr_ret(hr, S_OK);
131
132 hr = spFolder->GetAttributesOf(1, &child, &attributes);
133 ok_hr_ret(hr, S_OK);
134
135 attributes &= dwDefaultAttributeMask;
136 }
137
138 CComHeapPtr<ITEMIDLIST> parent(ILClone(spPath));
141
142 CComPtr<IDataObject> spDataObject;
143 hr = CIDLData_CreateFromIDArray(parent, 1, &child, &spDataObject);
144 ok_hr_ret(hr, S_OK);
145
146 /* Not registered yet */
147 ok_attributes(spDataObject, DV_E_FORMATETC, 0, 0, 0);
148
149 /* Ask for attributes, without specifying any */
150 DWORD dwAttributeMask = 0, dwAttributes = 0;
151 UINT cItems = 0;
152 hr = SHGetAttributesFromDataObject(spDataObject, dwAttributeMask, &dwAttributes, &cItems);
153 ok_hr(hr, S_OK);
154
155 /* Now there are attributes registered */
156 ok_attributes(spDataObject, S_OK, dwDefaultAttributeMask, attributes, 1);
157
158 // Now add an additional mask value (our exe should have a propsheet!)
159 dwAttributeMask = SFGAO_HASPROPSHEET;
160 dwAttributes = 0;
161 cItems = 0;
162 hr = SHGetAttributesFromDataObject(spDataObject, dwAttributeMask, &dwAttributes, &cItems);
163 ok_hr(hr, S_OK);
164
165 // Observe that this is now also cached
166 ok_attributes(spDataObject, S_OK, dwDefaultAttributeMask | SFGAO_HASPROPSHEET, attributes | SFGAO_HASPROPSHEET, 1);
167}
static const DWORD dwDefaultAttributeMask
#define ok_attributes
#define ok_hr_ret(x, y)
Definition: bufpool.h:45
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
r parent
Definition: btrfs.c:3010
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
unsigned long DWORD
Definition: ntddk_ex.h:95
static HWND child
Definition: cursoricon.c:298
unsigned int UINT
Definition: ndis.h:50
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
Definition: pidl.c:221
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1361
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:995
HRESULT WINAPI CIDLData_CreateFromIDArray(PCIDLIST_ABSOLUTE pidlFolder, UINT cpidlFiles, PCUIDLIST_RELATIVE_ARRAY lppidlFiles, LPDATAOBJECT *ppdataObject)
Definition: shellord.c:2213
EXTERN_C HRESULT WINAPI SHGetAttributesFromDataObject(IDataObject *pDataObject, DWORD dwAttributeMask, DWORD *pdwAttributes, UINT *pcItems)
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
#define _countof(array)
Definition: sndvol32.h:68
DWORD dwAttributes
Definition: vdmdbg.h:34
#define DV_E_FORMATETC
Definition: winerror.h:2633
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ test_MultipleFiles()

static void test_MultipleFiles ( )
static

Definition at line 169 of file SHGetAttributesFromDataObject.cpp.

170{
171 TmpFile TmpFile1, TmpFile2, TmpFile3;
172
173 CComHeapPtr<ITEMIDLIST> pidl_tmpfolder;
174 CComHeapPtr<ITEMIDLIST> pidl1, pidl2, pidl3;
175
176 ITEMIDLIST* items[3] = {};
177 SFGAOF attributes_first = dwDefaultAttributeMask;
178 SFGAOF attributes2 = dwDefaultAttributeMask;
179 SFGAOF attributes3 = dwDefaultAttributeMask;
180 SFGAOF attributes_last = dwDefaultAttributeMask;
181
182 HRESULT hr;
183 {
184 WCHAR TempFolder[MAX_PATH] = {};
185 GetTempPathW(_countof(TempFolder), TempFolder);
186
187 // Create temp files
188 TmpFile1.Create(TempFolder);
189 TmpFile2.Create(TempFolder);
190 TmpFile3.Create(TempFolder);
191
192 // Last file is read-only
194
195 hr = SHParseDisplayName(TempFolder, NULL, &pidl_tmpfolder, NULL, NULL);
196 ok_hr_ret(hr, S_OK);
197
198 CComPtr<IShellFolder> spFolder = _BindToObject(pidl_tmpfolder);
199 ok(!!spFolder, "Unable to bind to tmp folder\n");
200 if (!spFolder)
201 return;
202
203 hr = spFolder->ParseDisplayName(NULL, 0, PathFindFileNameW(TmpFile1.Buffer), NULL, &pidl1, NULL);
204 ok_hr_ret(hr, S_OK);
205
206 hr = spFolder->ParseDisplayName(NULL, 0, PathFindFileNameW(TmpFile2.Buffer), NULL, &pidl2, NULL);
207 ok_hr_ret(hr, S_OK);
208
209 hr = spFolder->ParseDisplayName(NULL, 0, PathFindFileNameW(TmpFile3.Buffer), NULL, &pidl3, NULL);
210 ok_hr_ret(hr, S_OK);
211
212 items[0] = pidl1;
213 items[1] = pidl2;
214 items[2] = pidl3;
215
216 // Query file attributes
217 hr = spFolder->GetAttributesOf(1, items, &attributes_first);
218 ok_hr(hr, S_OK);
219
220 hr = spFolder->GetAttributesOf(2, items, &attributes2);
221 ok_hr(hr, S_OK);
222
223 hr = spFolder->GetAttributesOf(3, items, &attributes3);
224 ok_hr(hr, S_OK);
225
226 hr = spFolder->GetAttributesOf(1, items + 2, &attributes_last);
227 ok_hr(hr, S_OK);
228
229 // Ignore any non-default attributes
230 attributes_first &= dwDefaultAttributeMask;
231 attributes2 &= dwDefaultAttributeMask;
232 attributes3 &= dwDefaultAttributeMask;
233 attributes_last &= dwDefaultAttributeMask;
234 }
235
236 // Only 'single' files have the stream attribute set
237 ok(attributes_first & SFGAO_STREAM, "Expected SFGAO_STREAM on attributes_first (0x%lx)\n", attributes_first);
238 ok(!(attributes2 & SFGAO_STREAM), "Expected no SFGAO_STREAM on attributes2 (0x%lx)\n", attributes2);
239 ok(!(attributes3 & SFGAO_STREAM), "Expected no SFGAO_STREAM on attributes3 (0x%lx)\n", attributes3);
240 ok(attributes_last & SFGAO_STREAM, "Expected SFGAO_STREAM on attributes_last (0x%lx)\n", attributes_last);
241
242 // Only attributes common on all are returned, so only the last has the readonly bit set!
243 ok(!(attributes_first & SFGAO_READONLY), "Expected no SFGAO_READONLY on attributes_first (0x%lx)\n", attributes_first);
244 ok(!(attributes2 & SFGAO_READONLY), "Expected no SFGAO_READONLY on attributes2 (0x%lx)\n", attributes2);
245 ok(!(attributes3 & SFGAO_READONLY), "Expected no SFGAO_READONLY on attributes3 (0x%lx)\n", attributes3);
246 ok(attributes_last & SFGAO_READONLY, "Expected SFGAO_READONLY on attributes_last (0x%lx)\n", attributes_last);
247
248 // The actual tests
249 {
250 // Just the first file
251 CComPtr<IDataObject> spDataObject;
252 hr = CIDLData_CreateFromIDArray(pidl_tmpfolder, 1, items, &spDataObject);
253 ok_hr_ret(hr, S_OK);
254
255 DWORD dwAttributeMask = 0, dwAttributes = 123;
256 UINT cItems = 123;
257 hr = SHGetAttributesFromDataObject(spDataObject, dwAttributeMask, &dwAttributes, &cItems);
258 ok_hr(hr, S_OK);
259 ok_attributes(spDataObject, S_OK, dwDefaultAttributeMask, attributes_first, 1);
260 }
261
262 {
263 // First 2 files
264 CComPtr<IDataObject> spDataObject;
265 hr = CIDLData_CreateFromIDArray(pidl_tmpfolder, 2, items, &spDataObject);
266 ok_hr_ret(hr, S_OK);
267
268 DWORD dwAttributeMask = 0, dwAttributes = 123;
269 UINT cItems = 123;
270 hr = SHGetAttributesFromDataObject(spDataObject, dwAttributeMask, &dwAttributes, &cItems);
271 ok_hr(hr, S_OK);
272 ok_attributes(spDataObject, S_OK, dwDefaultAttributeMask, attributes2, 2);
273 }
274
275 {
276 // All 3 files
277 CComPtr<IDataObject> spDataObject;
278 hr = CIDLData_CreateFromIDArray(pidl_tmpfolder, 3, items, &spDataObject);
279 ok_hr_ret(hr, S_OK);
280
281 DWORD dwAttributeMask = 0, dwAttributes = 123;
282 UINT cItems = 123;
283 hr = SHGetAttributesFromDataObject(spDataObject, dwAttributeMask, &dwAttributes, &cItems);
284 ok_hr(hr, S_OK);
285 ok_attributes(spDataObject, S_OK, dwDefaultAttributeMask, attributes3, 3);
286 }
287
288 {
289 // Only the last file
290 CComPtr<IDataObject> spDataObject;
291 hr = CIDLData_CreateFromIDArray(pidl_tmpfolder, 1, items + 2, &spDataObject);
292 ok_hr_ret(hr, S_OK);
293
294 DWORD dwAttributeMask = 0, dwAttributes = 123;
295 UINT cItems = 123;
296 hr = SHGetAttributesFromDataObject(spDataObject, dwAttributeMask, &dwAttributes, &cItems);
297 ok_hr(hr, S_OK);
298 ok_attributes(spDataObject, S_OK, dwDefaultAttributeMask, attributes_last, 1);
299 }
300}
CComPtr< IShellFolder > _BindToObject(PCUIDLIST_ABSOLUTE pidl)
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
static TCHAR * items[]
Definition: page1.c:45
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1405
void Create(LPCWSTR Folder)
WCHAR Buffer[MAX_PATH]

Referenced by START_TEST().

◆ test_SpecialCases()

static void test_SpecialCases ( )
static

Definition at line 91 of file SHGetAttributesFromDataObject.cpp.

92{
93 DWORD dwAttributeMask = 0, dwAttributes = 123;
94 UINT cItems = 123;
95
96 HRESULT hr = SHGetAttributesFromDataObject(nullptr, dwAttributeMask, &dwAttributes, &cItems);
97 ok_hr(hr, S_OK);
99 ok_int(cItems, 0);
100
101 cItems = 123;
102 hr = SHGetAttributesFromDataObject(nullptr, dwAttributeMask, nullptr, &cItems);
103 ok_hr(hr, S_OK);
104 ok_int(cItems, 0);
105
106 dwAttributes = 123;
107 hr = SHGetAttributesFromDataObject(nullptr, dwAttributeMask, &dwAttributes, nullptr);
108 ok_hr(hr, S_OK);
110}
#define ok_int(expression, result)
Definition: atltest.h:134

Referenced by START_TEST().

Variable Documentation

◆ dwDefaultAttributeMask

const DWORD dwDefaultAttributeMask
static
Initial value:
= SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_STORAGE | SFGAO_CANRENAME | SFGAO_CANDELETE |
SFGAO_READONLY | SFGAO_STREAM | SFGAO_FOLDER

Definition at line 16 of file SHGetAttributesFromDataObject.cpp.

Referenced by test_AttributesRegistration(), and test_MultipleFiles().

◆ g_DataObjectAttributes

CLIPFORMAT g_DataObjectAttributes = 0
static

Definition at line 15 of file SHGetAttributesFromDataObject.cpp.

Referenced by ok_attributes_(), and START_TEST().