ReactOS 0.4.17-dev-1190-g4c812f4
prop.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: shell32
3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4 * PURPOSE: [PROP]VARIANT functions
5 * COPYRIGHT: Copyright 2026 Whindmar Saksit <whindsaks@proton.me>
6 */
7
8#define SHELL32_PROP_IMPL
9#include "precomp.h"
10#include "prop.h"
11
13
14static const struct SHELL32PKEYMAP
15{
17 const PROPERTYKEY *pkey;
18} g_PkMap[] =
19{
20// learn.microsoft.com/en-us/windows/win32/api/propsys/nf-propsys-psgetpropertydescriptionbyname
21#define MKSH32PKEYMAP(sysname, legacyname, pkey) { (L##legacyname), &(pkey) },
22MKSH32PKEYMAP(?, "Name", PKEYSHELL32_Name)
23MKSH32PKEYMAP("System.ItemTypeText", "Type", PKEY_ItemTypeText)
24MKSH32PKEYMAP("System.Size", "Size", PKEY_Size)
25MKSH32PKEYMAP("System.FileAttributes", "Attributes", PKEY_FileAttributes)
26MKSH32PKEYMAP("System.DateModified", "Write", PKEY_DateModified)
27MKSH32PKEYMAP("System.Comment", "DocComments", PKEYSHELL32_Comments)
28};
29
30static const PROPERTYKEY*
32{
33 for (SIZE_T i = 0; i < _countof(g_PkMap); ++i)
34 {
35 if (!_wcsicmp(g_PkMap[i].pszLegacyName, pszString))
36 return g_PkMap[i].pkey;
37 }
38 return NULL;
39}
40
41#if /*TODO*/0 && (NTDDI_VERSION >= NTDDI_VISTA)
42#define SHELL_PropertyKeyFromPropertyKeyString PSPropertyKeyFromString
43#else
44static HRESULT
46{
47 if (GUIDFromStringW(pszString, &pkey->fmtid))
48 {
49 for (pszString += 38; *pszString == ',' || *pszString == ' ';)
50 ++pszString;
51 pkey->pid = StrToInt(pszString);
52 if (pkey->pid)
53 return S_OK;
54 }
55 return E_INVALIDARG;
56}
57#endif
58
59const PROPERTYKEY*
60SHELL_GetPropertyKeyFromString(_In_ PCWSTR pszString, _Out_ PROPERTYKEY *pkey)
61{
63 return pkey;
64 return SHELL_GetPropertyKeyFromLegacyName(pszString);
65}
66
69{
71 if (V_VT(pV) == VT_I4)
72 {
74 }
75 else if (V_VT(pV) == VT_BSTR)
76 {
77 hr = SHILCreateFromPathW(V_BSTR(pV), ppidl, NULL);
78 }
79 return hr;
80}
81
84{
85 pV = VariantDerefVariant(pV);
86 switch (V_VT(pV))
87 {
88 case VT_DISPATCH | VT_BYREF:
90 case VT_DISPATCH:
91 case VT_UNKNOWN:
92 return V_UNKNOWN(pV) ? V_UNKNOWN(pV)->QueryInterface(riid, ppv) : E_UNEXPECTED;
93 }
94 return E_FAIL;
95}
96
97static HRESULT
99{
100 // VariantCopy does not copy VT_DATE?
101 if (V_VT(pvs) <= VT_DATE || (VT_DECIMAL <= V_VT(pvs) && V_VT(pvs) <= VT_PTR))
102 {
103 CopyMemory(pvd, pvs, sizeof(*pvd));
104 return S_OK;
105 }
106 return VariantCopy(pvd, pvs);
107}
108
109static HRESULT WINAPI
110FallbackVariantToPropVariant(_In_ const VARIANT *pVar, _Out_ PROPVARIANT *pPropVar)
111{
112 if (!pVar || !pPropVar)
113 return E_INVALIDARG;
114
115 return SHELL_VariantCopy((VARIANT*)pPropVar, pVar);
116}
117
119SHELL_VariantToPropVariant(_In_ const VARIANT *pVar, _Out_ PROPVARIANT *pPropVar)
120{
121 static FARPROC func = NULL;
122 if (!func)
123 {
124 if (HMODULE hPropSys = LoadLibraryW(L"PROPSYS"))
125 func = GetProcAddress(hPropSys, "VariantToPropVariant");
126 if (!func)
128 }
129
130 HRESULT hr = ((HRESULT(WINAPI*)(const VARIANT*,void*))func)(pVar, pPropVar);
132 {
133 switch (V_VT(pVar))
134 {
135 case VT_DATE:
136 return FallbackVariantToPropVariant(pVar, pPropVar);
137 }
138 }
139 return hr;
140}
141
142static HRESULT WINAPI
143FallbackPropVariantChangeType(_Out_ PROPVARIANT *ppvDest, _In_ REFPROPVARIANT pvSrc, _In_ int reserved, _In_ VARTYPE vt)
144{
145 if (!ppvDest || (SIZE_T)ppvDest == (SIZE_T)&pvSrc) // MSDN: The source and destination PROPVARIANT structures must be separate structures.
146 return E_INVALIDARG;
147
148 const VARTYPE finalvt = vt;
149 switch (vt)
150 {
151 case VT_LPWSTR: vt = VT_BSTR; break;
152 case VT_FILETIME: vt = VT_DATE; break;
153 }
154
155 VARIANT v;
156 HRESULT hr;
157 if (V_VT((VARIANT*)&pvSrc) == vt)
158 hr = SHELL_VariantCopy(&v, (VARIANT*)&pvSrc);
159 else
160 hr = VariantChangeType(&v, (VARIANT*)&pvSrc, 0, vt);
161
162 if (FAILED(hr))
163 {
164 if (pvSrc.vt == VT_UI4 && finalvt == VT_UI8)
165 {
166 ppvDest->vt = finalvt;
167 ppvDest->uhVal.QuadPart = pvSrc.ulVal;
168 return S_OK;
169 }
170
171 if (pvSrc.vt == VT_UI4 && finalvt == VT_I4 && pvSrc.ulVal <= INT_MAX)
172 goto copy;
173
174 if (pvSrc.vt == VT_UI4 && finalvt == VT_UI4)
175 {
176 copy:
177 CopyMemory(ppvDest, &pvSrc, sizeof(*ppvDest));
178 ppvDest->vt = finalvt;
179 return S_OK;
180 }
181 return hr;
182 }
183
184 switch (finalvt)
185 {
186 case VT_LPWSTR:
187 if (SUCCEEDED(hr = SHStrDupW(V_BSTR(&v), &ppvDest->pwszVal)))
188 ppvDest->vt = finalvt;
189 VariantClear(&v);
190 return hr;
191 case VT_FILETIME:
192 if (VariantTimeToFileTime(V_DATE(&v), &ppvDest->filetime))
193 {
194 ppvDest->vt = finalvt;
195 VariantClear(&v);
196 return S_OK;
197 }
198 break;
199 }
200
201 hr = SHELL_VariantToPropVariant(&v, ppvDest);
202 VariantClear(&v);
203 return hr;
204}
205
207SHELL_PropVariantChangeType(_Out_ PROPVARIANT *ppvDest, _In_ REFPROPVARIANT pvSrc, _In_ VARTYPE vt)
208{
209 static FARPROC func = NULL;
210 if (!func)
211 {
212 if (HMODULE hPropSys = LoadLibraryW(L"PROPSYS"))
213 func = GetProcAddress(hPropSys, "PropVariantChangeType");
214 if (!func)
216 }
217
218 HRESULT hr = ((HRESULT(WINAPI*)(PROPVARIANT*,REFPROPVARIANT,int,VARTYPE))func)(ppvDest, pvSrc, 0, vt);
220 {
221 switch (vt)
222 {
223 case VT_FILETIME:
224 return FallbackPropVariantChangeType(ppvDest, pvSrc, 0, vt);
225 }
226 }
227 return hr;
228}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
_Check_return_ _In_ PQUERY_INTERFACE QueryInterface
Definition: dispmprt.h:1318
#define NULL
Definition: types.h:112
int(* FARPROC)()
Definition: compat.h:36
#define GetProcAddress(x, y)
Definition: compat.h:753
unsigned short VARTYPE
Definition: compat.h:2254
#define LoadLibraryW(x)
Definition: compat.h:747
@ VT_UI8
Definition: compat.h:2315
@ VT_BSTR
Definition: compat.h:2303
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_BYREF
Definition: compat.h:2342
@ VT_PTR
Definition: compat.h:2320
@ VT_DECIMAL
Definition: compat.h:2309
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_I4
Definition: compat.h:2298
@ VT_FILETIME
Definition: compat.h:2329
@ VT_DATE
Definition: compat.h:2302
@ VT_UI4
Definition: compat.h:2313
@ VT_DISPATCH
Definition: compat.h:2304
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:90
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
#define INT_MAX
Definition: limits.h:26
HRESULT WINAPI SHStrDupW(const WCHAR *src, WCHAR **dest)
Definition: main.c:1692
static VARIANT * VariantDerefVariant(_In_ const VARIANT *pV)
Definition: prop.h:36
static BOOL VariantTimeToFileTime(_In_ const DOUBLE vtime, _Out_ FILETIME *pft)
Definition: prop.h:44
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:4574
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define L(x)
Definition: resources.c:13
r reserved
Definition: btrfs.c:3006
const GLdouble * v
Definition: gl.h:2040
GLenum func
Definition: glext.h:6028
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define CopyMemory
Definition: minwinbase.h:29
static const PROPERTYKEY PKEY_Size
Definition: CShellItem.cpp:13
static const PROPERTYKEY PKEY_DateModified
Definition: CShellItem.cpp:14
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_VT(A)
Definition: oleauto.h:211
#define V_DISPATCHREF(A)
Definition: oleauto.h:240
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_I4(A)
Definition: oleauto.h:247
#define V_DATE(A)
Definition: oleauto.h:231
BOOL WINAPI GUIDFromStringW(_In_ PCWSTR psz, _Out_ LPGUID pguid)
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:404
HRESULT SHELL_PropVariantChangeType(_Out_ PROPVARIANT *ppvDest, _In_ REFPROPVARIANT pvSrc, _In_ VARTYPE vt)
Definition: prop.cpp:207
HRESULT VariantToIdlist(_In_ VARIANT *pV, _Out_ LPITEMIDLIST *ppidl)
Definition: prop.cpp:68
static HRESULT SHELL_PropertyKeyFromPropertyKeyString(_In_ PCWSTR pszString, _Out_ PROPERTYKEY *pkey)
Definition: prop.cpp:45
static HRESULT SHELL_VariantCopy(_Out_ VARIANT *pvd, _In_ const VARIANT *pvs)
Definition: prop.cpp:98
static HRESULT WINAPI FallbackPropVariantChangeType(_Out_ PROPVARIANT *ppvDest, _In_ REFPROPVARIANT pvSrc, _In_ int reserved, _In_ VARTYPE vt)
Definition: prop.cpp:143
#define MKSH32PKEYMAP(sysname, legacyname, pkey)
static HRESULT WINAPI FallbackVariantToPropVariant(_In_ const VARIANT *pVar, _Out_ PROPVARIANT *pPropVar)
Definition: prop.cpp:110
static const struct SHELL32PKEYMAP g_PkMap[]
static const PROPERTYKEY * SHELL_GetPropertyKeyFromLegacyName(_In_ PCWSTR pszString)
Definition: prop.cpp:31
HRESULT VariantQueryInterface(_In_ VARIANT *pV, _In_ REFIID riid, _Out_ void **ppv)
Definition: prop.cpp:83
HRESULT SHELL_VariantToPropVariant(_In_ const VARIANT *pVar, _Out_ PROPVARIANT *pPropVar)
Definition: prop.cpp:119
const PROPERTYKEY * SHELL_GetPropertyKeyFromString(_In_ PCWSTR pszString, _Out_ PROPERTYKEY *pkey)
Definition: prop.cpp:60
#define REFIID
Definition: guiddef.h:118
#define StrToInt
Definition: shlwapi.h:1256
PSYMCRYPT_MLKEM_VECTOR pvs
Definition: sc_lib_mlkem.h:105
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
#define _countof(array)
Definition: sndvol32.h:70
const PROPERTYKEY * pkey
Definition: prop.cpp:17
PCWSTR pszLegacyName
Definition: prop.cpp:16
const uint16_t * PCWSTR
Definition: typedefs.h:57
ULONG_PTR SIZE_T
Definition: typedefs.h:80
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, const VARIANTARG *pvargSrc)
Definition: variant.c:724
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, const VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:939
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:626
#define WINAPI
Definition: msvc.h:6
#define E_UNEXPECTED
Definition: winerror.h:3528