Files
Whindmar Saksit a5f51269c8 [SHELL32] Add FolderItems3 support (move/copy directory tree) (#9235)
- Added copy/move support for FolderItems collections.
- Added support for InvokeVerbEx on FolderItems collections.
- Added filter support for FolderItems collections.
2026-07-16 15:58:14 +02:00

96 lines
2.9 KiB
C++

/*
* PROJECT: shell32
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
* PURPOSE: [PROP]VARIANT functions
* COPYRIGHT: Copyright 2026 Whindmar Saksit <[email protected]>
*/
#define SHELL32_PROP_IMPL
#include "precomp.h"
#include "prop.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell_prop);
static const struct SHELL32PKEYMAP
{
PCWSTR pszLegacyName;
const PROPERTYKEY *pkey;
} g_PkMap[] =
{
// learn.microsoft.com/en-us/windows/win32/api/propsys/nf-propsys-psgetpropertydescriptionbyname
#define MKSH32PKEYMAP(sysname, legacyname, pkey) { (L##legacyname), &(pkey) },
MKSH32PKEYMAP(?, "Name", PKEYSHELL32_Name)
MKSH32PKEYMAP("System.ItemTypeText", "Type", PKEY_ItemTypeText)
MKSH32PKEYMAP("System.Size", "Size", PKEY_Size)
MKSH32PKEYMAP("System.FileAttributes", "Attributes", PKEY_FileAttributes)
MKSH32PKEYMAP("System.DateModified", "Write", PKEY_DateModified)
MKSH32PKEYMAP("System.Comment", "DocComments", PKEYSHELL32_Comments)
};
static const PROPERTYKEY*
SHELL_GetPropertyKeyFromLegacyName(_In_ PCWSTR pszString)
{
for (SIZE_T i = 0; i < _countof(g_PkMap); ++i)
{
if (!_wcsicmp(g_PkMap[i].pszLegacyName, pszString))
return g_PkMap[i].pkey;
}
return NULL;
}
#if /*TODO*/0 && (NTDDI_VERSION >= NTDDI_VISTA)
#define SHELL_PropertyKeyFromPropertyKeyString PSPropertyKeyFromString
#else
static HRESULT
SHELL_PropertyKeyFromPropertyKeyString(_In_ PCWSTR pszString, _Out_ PROPERTYKEY *pkey)
{
if (GUIDFromStringW(pszString, &pkey->fmtid))
{
for (pszString += 38; *pszString == ',' || *pszString == ' ';)
++pszString;
pkey->pid = StrToInt(pszString);
if (pkey->pid)
return S_OK;
}
return E_INVALIDARG;
}
#endif
const PROPERTYKEY*
SHELL_GetPropertyKeyFromString(_In_ PCWSTR pszString, _Out_ PROPERTYKEY *pkey)
{
if (SUCCEEDED(SHELL_PropertyKeyFromPropertyKeyString(pszString, pkey)))
return pkey;
return SHELL_GetPropertyKeyFromLegacyName(pszString);
}
HRESULT
VariantToIdlist(_In_ VARIANT *pV, _Out_ LPITEMIDLIST *ppidl)
{
HRESULT hr = E_FAIL;
if (V_VT(pV) == VT_I4)
{
hr = SHGetSpecialFolderLocation(NULL, V_I4(pV), ppidl);
}
else if (V_VT(pV) == VT_BSTR)
{
hr = SHILCreateFromPathW(V_BSTR(pV), ppidl, NULL);
}
return hr;
}
HRESULT
VariantQueryInterface(_In_ VARIANT *pV, _In_ REFIID riid, _Out_ void **ppv)
{
pV = VariantDerefVariant(pV);
switch (V_VT(pV))
{
case VT_DISPATCH | VT_BYREF:
return V_DISPATCHREF(pV) && *V_DISPATCHREF(pV) ? (*V_DISPATCHREF(pV))->QueryInterface(riid, ppv) : E_UNEXPECTED;
case VT_DISPATCH:
case VT_UNKNOWN:
return V_UNKNOWN(pV) ? V_UNKNOWN(pV)->QueryInterface(riid, ppv) : E_UNEXPECTED;
}
return E_FAIL;
}