ReactOS 0.4.16-dev-550-g2186ce3
item_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: FileSystem PropertySheet implementation
5 * COPYRIGHT: Copyright 2024 Whindmar Saksit <whindsaks@proton.me>
6 */
7
8#include "precomp.h"
9
11
12static HRESULT
14{
17 {
18 hr = SHGetNameAndFlagsW(pidl, SHGDN_INFOLDER, Buf, cchBuf, NULL);
19 ILFree(pidl);
20 }
21 return hr;
22}
23
25{
26 typedef void (CALLBACK*PFNINITIALIZE)(LPCWSTR InitString, IDataObject *pDO,
27 HKEY *hKeys, UINT *cKeys);
28
29 static HRESULT Show(const CLSID *pClsidDefault, IDataObject *pDO,
30 PFNINITIALIZE InitFunc, LPCWSTR InitString)
31 {
32 HRESULT hr;
33 CRegKeyHandleArray keys;
34 if (InitFunc)
35 InitFunc(InitString, pDO, keys, keys);
36 WCHAR szCaption[MAX_PATH], *pszCaption = NULL;
37 if (SUCCEEDED(SHELL_GetCaptionFromDataObject(pDO, szCaption, _countof(szCaption))))
38 pszCaption = szCaption;
39 hr = SHOpenPropSheetW(pszCaption, keys, keys, pClsidDefault, pDO, NULL, NULL) ? S_OK : E_FAIL;
40 return hr;
41 }
42
43 struct DATA
44 {
51 };
52
53 static void FreeData(DATA *pData)
54 {
55 if (pData->InitString)
56 SHFree(pData->InitString);
58 }
59
60 static HRESULT ShowAsync(const CLSID *pClsidDefault, IDataObject *pDO,
61 PFNINITIALIZE InitFunc, LPCWSTR InitString)
62 {
63 DATA *pData = (DATA*)SHAlloc(sizeof(*pData));
64 if (!pData)
65 return E_OUTOFMEMORY;
66 ZeroMemory(pData, sizeof(*pData));
67 pData->InitFunc = InitFunc;
68 if (InitString && FAILED(SHStrDupW(InitString, &pData->InitString)))
69 {
71 return E_OUTOFMEMORY;
72 }
73 if (pClsidDefault)
74 {
75 pData->ClsidDefault = *pClsidDefault;
76 pData->pClsidDefault = &pData->ClsidDefault;
77 }
79
80 HRESULT hr = S_OK;
81 if (pDO)
83
86 {
87 if (pData->pObjStream)
88 pData->pObjStream->Release();
89 hr = E_FAIL;
90 }
91
92 if (SUCCEEDED(hr))
93 {
94 if (hEvent)
95 {
97 // Pump COM messages until the thread can create its own IDataObject (for CORE-19933).
98 // SHOpenPropSheetW is modal and we cannot wait for it to complete.
101 }
102 }
103 else
104 {
106 }
107 return hr;
108 }
109
111 {
112 DATA *pData = (DATA*)Param;
113 CComPtr<IDataObject> pDO, pLocalDO;
114 if (pData->pObjStream)
116 if (pDO && SUCCEEDED(SHELL_CloneDataObject(pDO, &pLocalDO)))
117 pDO = pLocalDO;
118 if (pData->hEvent)
119 SetEvent(pData->hEvent);
120 Show(pData->pClsidDefault, pDO, pData->InitFunc, pData->InitString);
122 return 0;
123 }
124};
125
126static void CALLBACK
128{
129 UNREFERENCED_PARAMETER(InitString);
130 CDataObjectHIDA cida(pDO);
131 if (SUCCEEDED(cida.hr()) && cida->cidl)
132 {
133 PCUITEMID_CHILD pidl = HIDA_GetPIDLItem(cida, 0);
134 AddFSClassKeysToArray(1, &pidl, hKeys, cKeys); // Add file-type specific pages
135 }
136}
137
138static void CALLBACK
139ClassPropDialogInitCallback(LPCWSTR InitString, IDataObject *pDO, HKEY *hKeys, UINT *cKeys)
140{
142 AddClassKeyToArray(InitString, hKeys, cKeys); // Add pages from HKCR\%ProgId% (with shellex\PropertySheetHandlers appended later)
143}
144
147{
148 CDataObjectHIDA cida(pDO);
149 HRESULT hr = cida.hr();
151 return hr;
152
153 const CLSID *pClsid = NULL;
155 LPCWSTR InitString = NULL;
156
157 if (_ILIsDrive(HIDA_GetPIDLItem(cida, 0)))
158 {
159 pClsid = &CLSID_ShellDrvDefExt;
161 InitString = L"Drive";
162 }
163 else
164 {
165 pClsid = &CLSID_ShellFileDefExt;
167 }
169 return Dialog.ShowAsync(pClsid, pDO, InitFunc, InitString);
170}
171
174{
175 WCHAR ClassBuf[6 + 38 + 1] = L"CLSID\\";
176 StringFromGUID2(*pClsid, ClassBuf + 6, 38 + 1);
178 return Dialog.ShowAsync(NULL, pDO, ClassPropDialogInitCallback, ClassBuf);
179}
180
183{
184 assert(pidl);
185
186 CComHeapPtr<ITEMIDLIST> alloc;
187 if (IS_INTRESOURCE(pidl))
188 {
189 HRESULT hr = SHGetSpecialFolderLocation(NULL, LOWORD(pidl), const_cast<LPITEMIDLIST*>(&pidl));
190 if (FAILED(hr))
191 return hr;
192 alloc.Attach(const_cast<LPITEMIDLIST>(pidl));
193 }
194 SHELLEXECUTEINFOA sei = {
195 sizeof(sei), SEE_MASK_INVOKEIDLIST | SEE_MASK_ASYNCOK, NULL, "properties",
196 NULL, NULL, NULL, SW_SHOWNORMAL, NULL, const_cast<LPITEMIDLIST>(pidl)
197 };
199}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout, ULONG cHandles, LPHANDLE pHandles, LPDWORD lpdwindex)
Definition: compobj.c:4578
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm)
Definition: marshal.c:2100
HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid, LPVOID *ppv)
Definition: marshal.c:2144
HRESULT SHGetNameAndFlagsW(_In_ LPCITEMIDLIST pidl, _In_ DWORD dwFlags, _Out_opt_ LPWSTR pszText, _In_ UINT cchBuf, _Inout_opt_ DWORD *pdwAttributes)
Definition: utils.cpp:476
HRESULT SHELL_CloneDataObject(_In_ IDataObject *pDO, _Out_ IDataObject **ppDO)
PIDLIST_ABSOLUTE SHELL_DataObject_ILCloneFullItem(_In_ IDataObject *pDO, _In_ UINT Index)
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3257
HRESULT WINAPI SHStrDupW(LPCWSTR src, LPWSTR *dest)
Definition: string.c:2018
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
Definition: thread.c:356
#define assert(x)
Definition: debug.h:53
#define INFINITE
Definition: serial.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static void CALLBACK FSFolderItemPropDialogInitCallback(LPCWSTR InitString, IDataObject *pDO, HKEY *hKeys, UINT *cKeys)
Definition: item_prop.cpp:127
static void CALLBACK ClassPropDialogInitCallback(LPCWSTR InitString, IDataObject *pDO, HKEY *hKeys, UINT *cKeys)
Definition: item_prop.cpp:139
static HRESULT SHELL_GetCaptionFromDataObject(IDataObject *pDO, LPWSTR Buf, UINT cchBuf)
Definition: item_prop.cpp:13
HRESULT SHELL32_ShowFilesystemItemPropertiesDialogAsync(IDataObject *pDO)
Definition: item_prop.cpp:146
HRESULT SHELL_ShowItemIDListProperties(LPCITEMIDLIST pidl)
Definition: item_prop.cpp:182
HRESULT SHELL32_ShowShellExtensionProperties(const CLSID *pClsid, IDataObject *pDO)
Definition: item_prop.cpp:173
static HANDLE hEvent
Definition: comm.c:54
unsigned int UINT
Definition: ndis.h:50
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define L(x)
Definition: ntvdm.h:50
@ COWAIT_DEFAULT
Definition: objbase.h:695
const GUID IID_IDataObject
#define LOWORD(l)
Definition: pedump.c:82
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1044
BOOL _ILIsDrive(LPCITEMIDLIST pidl)
Definition: pidl.c:2113
#define alloc
Definition: rosglue.h:13
#define SEE_MASK_ASYNCOK
Definition: shellapi.h:54
#define SEE_MASK_INVOKEIDLIST
Definition: shellapi.h:28
static PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const *pida, SIZE_T i)
Definition: shellutils.h:637
HRESULT HResultFromWin32(DWORD hr)
Definition: shellutils.h:70
void AddFSClassKeysToArray(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, HKEY *array, UINT *cKeys)
Definition: shlfolder.cpp:333
LSTATUS AddClassKeyToArray(const WCHAR *szClass, HKEY *array, UINT *cKeys)
Definition: shlfolder.cpp:311
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExA(LPSHELLEXECUTEINFOA sei)
Definition: shlexec.cpp:2379
HRESULT hr
Definition: shlfolder.c:183
#define CTF_PROCESS_REF
Definition: shlwapi.h:1963
#define CTF_COINIT
Definition: shlwapi.h:1964
#define CTF_INSIST
Definition: shlwapi.h:1961
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
Definition: window.h:372
const CLSID * pClsidDefault
Definition: item_prop.cpp:48
void(CALLBACK * PFNINITIALIZE)(LPCWSTR InitString, IDataObject *pDO, HKEY *hKeys, UINT *cKeys)
Definition: item_prop.cpp:26
static DWORD CALLBACK ShowPropertiesThread(LPVOID Param)
Definition: item_prop.cpp:110
static HRESULT ShowAsync(const CLSID *pClsidDefault, IDataObject *pDO, PFNINITIALIZE InitFunc, LPCWSTR InitString)
Definition: item_prop.cpp:60
static HRESULT Show(const CLSID *pClsidDefault, IDataObject *pDO, PFNINITIALIZE InitFunc, LPCWSTR InitString)
Definition: item_prop.cpp:29
static void FreeData(DATA *pData)
Definition: item_prop.cpp:53
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
EXTERN_C BOOL WINAPI SHOpenPropSheetW(_In_opt_ LPCWSTR pszCaption, _In_opt_ HKEY *ahKeys, _In_ UINT cKeys, _In_ const CLSID *pclsidDefault, _In_ IDataObject *pDataObject, _In_opt_ IShellBrowser *pShellBrowser, _In_opt_ LPCWSTR pszStartPage)
Definition: propsheet.cpp:204
#define ZeroMemory
Definition: winbase.h:1737
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define SW_SHOWNORMAL
Definition: winuser.h:773
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define IID_PPV_ARG(Itype, ppType)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185