ReactOS  0.4.15-dev-5496-g599ba9c
shldataobject.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: shell32
3  * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4  * PURPOSE: SHGetAttributesFromDataObject implementation
5  * COPYRIGHT: Copyright 2021 Mark Jansen <mark.jansen@reactos.org>
6  */
7 
8 
9 #include "precomp.h"
10 
12 
13 
14 static CLIPFORMAT g_DataObjectAttributes = 0;
15 static const DWORD dwDefaultAttributeMask = SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_STORAGE | SFGAO_CANRENAME |
16  SFGAO_CANDELETE | SFGAO_READONLY | SFGAO_STREAM | SFGAO_FOLDER;
17 
19 {
23 };
24 
25 static_assert(sizeof(DataObjectAttributes) == 0xc, "Unexpected struct size!");
26 
27 
28 static
30 {
31  CComPtr<IShellFolder> spDesktop;
32  HRESULT hr = SHGetDesktopFolder(&spDesktop);
33  if (FAILED(hr))
34  return hr;
35 
36  return spDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &spFolder));
37 }
38 
40 HRESULT WINAPI SHGetAttributesFromDataObject(IDataObject* pDataObject, DWORD dwAttributeMask, DWORD* pdwAttributes, UINT* pcItems)
41 {
42  DWORD dwAttributes = 0;
43  DWORD cItems = 0;
44  HRESULT hr = S_OK;
45 
46  TRACE("(%p, 0x%x, %p, %p)\n", pDataObject, dwAttributeMask, pdwAttributes, pcItems);
47 
49  g_DataObjectAttributes = (CLIPFORMAT)RegisterClipboardFormatW(L"DataObjectAttributes");
50 
51  if (pDataObject)
52  {
54  if (FAILED(DataObject_GetData(pDataObject, g_DataObjectAttributes, &data, sizeof(data))))
55  {
56  TRACE("No attributes yet, creating new\n");
57  memset(&data, 0, sizeof(data));
58  }
59 
60  DWORD dwQueryAttributes = dwAttributeMask | dwDefaultAttributeMask;
61 
62  if ((data.dwMask & dwQueryAttributes) != dwQueryAttributes)
63  {
64  CDataObjectHIDA hida(pDataObject);
65  CComPtr<IShellFolder> spFolder;
66 
67  if (!FAILED_UNEXPECTEDLY(hr = hida.hr()) &&
69  {
71  for (UINT n = 0; n < hida->cidl; ++n)
72  {
73  apidl.Add(HIDA_GetPIDLItem(hida, n));
74  }
75 
76  SFGAOF rgfInOut = dwQueryAttributes;
77  hr = spFolder->GetAttributesOf(apidl.GetSize(), apidl.GetData(), &rgfInOut);
78  if (!FAILED_UNEXPECTEDLY(hr))
79  {
80  data.dwMask = dwQueryAttributes;
81  // Only store what we asked for
82  data.dwAttributes = rgfInOut & dwQueryAttributes;
83  data.cItems = apidl.GetSize();
84 
85  hr = DataObject_SetData(pDataObject, g_DataObjectAttributes, &data, sizeof(data));
87  }
88  }
89  }
90 
91  // Only give the user what they asked for, not everything else we have!
92  dwAttributes = data.dwAttributes & dwAttributeMask;
93  cItems = data.cItems;
94  }
95 
96  if (pdwAttributes)
97  *pdwAttributes = dwAttributes;
98 
99  if (pcItems)
100  *pcItems = cItems;
101 
102  return hr;
103 }
static HRESULT _BindToObject(PCUIDLIST_ABSOLUTE pidl, CComPtr< IShellFolder > &spFolder)
BOOL Add(const T &t)
Definition: atlsimpcoll.h:58
HRESULT hr
Definition: shlfolder.c:183
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
static PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const *pida, SIZE_T i)
Definition: shellutils.h:569
GLdouble n
Definition: glext.h:7729
static int int const SCRIPT_CONTROL const SCRIPT_STATE SCRIPT_ITEM ULONG int * pcItems
Definition: usp10.c:62
#define IID_PPV_ARG(Itype, ppType)
int GetSize() const
Definition: atlsimpcoll.h:104
DWORD dwAttributes
Definition: vdmdbg.h:34
#define L(x)
Definition: ntvdm.h:50
EXTERN_C HRESULT WINAPI SHGetAttributesFromDataObject(IDataObject *pDataObject, DWORD dwAttributeMask, DWORD *pdwAttributes, UINT *pcItems)
#define TRACE(s)
Definition: solgame.cpp:4
static HRESULT WINAPI DataObject_SetData(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
Definition: view.c:203
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
LONG HRESULT
Definition: typedefs.h:79
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:82
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static HRESULT WINAPI DataObject_GetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
Definition: view.c:175
WINE_DEFAULT_DEBUG_CHANNEL(shell)
static PCUIDLIST_ABSOLUTE HIDA_GetPIDLFolder(CIDA const *pida)
Definition: shellutils.h:564
#define S_OK
Definition: intsafe.h:52
const ITEMIDLIST_ABSOLUTE UNALIGNED * PCUIDLIST_ABSOLUTE
Definition: shtypes.idl:63
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define EXTERN_C
Definition: basetyps.h:12
#define memset(x, y, z)
Definition: compat.h:39
static const DWORD dwDefaultAttributeMask
static CLIPFORMAT g_DataObjectAttributes
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83