ReactOS  0.4.15-dev-5649-gd5999c6
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 hr
Definition: shlfolder.c:183
#define IID_PPV_ARG(Itype, ppType)
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
LONG HRESULT
Definition: typedefs.h:79
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:82
#define NULL
Definition: types.h:112

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 }
HRESULT hr
Definition: shlfolder.c:183
Definition: image.c:133
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
HRESULT GetData([in, unique] FORMATETC *pformatetcIn, [out] STGMEDIUM *pmedium)
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
if SUCCEEDED(hr)
GLsizeiptr size
Definition: glext.h:5919
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
LONG HRESULT
Definition: typedefs.h:79
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define expect_hr(expected, got)
Definition: assoc.c:27
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define S_OK
Definition: intsafe.h:52
#define NULL
Definition: types.h:112
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
DWORD * PDWORD
Definition: pedump.c:68
static CLIPFORMAT g_DataObjectAttributes
Definition: dsound.c:943

◆ 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 
318  CoUninitialize();
319 }
#define ok_hr(status, expected)
Definition: ACListISF.cpp:31
HRESULT hr
Definition: shlfolder.c:183
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
#define L(x)
Definition: ntvdm.h:50
if SUCCEEDED(hr)
LONG HRESULT
Definition: typedefs.h:79
static void test_MultipleFiles()
#define S_OK
Definition: intsafe.h:52
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define ok(value,...)
Definition: atltest.h:57
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
#define NULL
Definition: types.h:112
static CLIPFORMAT g_DataObjectAttributes
static void test_AttributesRegistration()
static void test_SpecialCases()

◆ 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 }
#define ok_hr(status, expected)
Definition: ACListISF.cpp:31
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HRESULT hr
Definition: shlfolder.c:183
static const DWORD dwDefaultAttributeMask
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
Definition: pidl.c:212
#define IID_PPV_ARG(Itype, ppType)
static HWND child
Definition: cursoricon.c:298
DWORD dwAttributes
Definition: vdmdbg.h:34
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:189
Definition: bufpool.h:45
EXTERN_C HRESULT WINAPI SHGetAttributesFromDataObject(IDataObject *pDataObject, DWORD dwAttributeMask, DWORD *pdwAttributes, UINT *pcItems)
#define DV_E_FORMATETC
Definition: winerror.h:2633
#define ok_hr_ret(x, y)
r parent
Definition: btrfs.c:3010
__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
unsigned long DWORD
Definition: ntddk_ex.h:95
#define S_OK
Definition: intsafe.h:52
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1337
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:228
#define ok(value,...)
Definition: atltest.h:57
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define ok_attributes
HRESULT WINAPI CIDLData_CreateFromIDArray(PCIDLIST_ABSOLUTE pidlFolder, UINT cpidlFiles, PCUIDLIST_RELATIVE_ARRAY lppidlFiles, LPDATAOBJECT *ppdataObject)
Definition: shellord.c:2173
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:982
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83

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 }
#define ok_hr(status, expected)
Definition: ACListISF.cpp:31
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
void Create(LPCWSTR Folder)
HRESULT hr
Definition: shlfolder.c:183
static const DWORD dwDefaultAttributeMask
WCHAR Buffer[MAX_PATH]
DWORD dwAttributes
Definition: vdmdbg.h:34
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
EXTERN_C HRESULT WINAPI SHGetAttributesFromDataObject(IDataObject *pDataObject, DWORD dwAttributeMask, DWORD *pdwAttributes, UINT *pcItems)
#define ok_hr_ret(x, y)
__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
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
unsigned long DWORD
Definition: ntddk_ex.h:95
#define S_OK
Definition: intsafe.h:52
#define ok(value,...)
Definition: atltest.h:57
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1381
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
CComPtr< IShellFolder > _BindToObject(PCUIDLIST_ABSOLUTE pidl)
#define ok_attributes
HRESULT WINAPI CIDLData_CreateFromIDArray(PCIDLIST_ABSOLUTE pidlFolder, UINT cpidlFiles, PCUIDLIST_RELATIVE_ARRAY lppidlFiles, LPDATAOBJECT *ppdataObject)
Definition: shellord.c:2173
static TCHAR * items[]
Definition: page1.c:45
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83

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);
98  ok_int(dwAttributes, 0);
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);
109  ok_int(dwAttributes, 0);
110 }
#define ok_hr(status, expected)
Definition: ACListISF.cpp:31
HRESULT hr
Definition: shlfolder.c:183
DWORD dwAttributes
Definition: vdmdbg.h:34
#define ok_int(expression, result)
Definition: atltest.h:134
EXTERN_C HRESULT WINAPI SHGetAttributesFromDataObject(IDataObject *pDataObject, DWORD dwAttributeMask, DWORD *pdwAttributes, UINT *pcItems)
LONG HRESULT
Definition: typedefs.h:79
unsigned long DWORD
Definition: ntddk_ex.h:95
#define S_OK
Definition: intsafe.h:52
unsigned int UINT
Definition: ndis.h:50

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().