ReactOS 0.4.16-dev-477-g6ada597
propsheet.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: SHOpenPropSheetW implementation
5 * COPYRIGHT: Copyright 2024 Whindmar Saksit <whindsaks@proton.me>
6 */
7
8#include "precomp.h"
9
11
12static HRESULT
14{
15 // First try the key name
17 return S_OK;
18 WCHAR buf[42];
19 DWORD cb = sizeof(buf);
20 // and then the default value
23}
24
25static HRESULT
27{
28 *ppv = NULL;
31 if (SUCCEEDED(hr))
32 {
35 if (SUCCEEDED(hr))
36 hr = Init->Initialize(pidlFolder, pDO, hkeyProgID);
37
38 if (SUCCEEDED(hr))
39 *ppv = (void*)pUnk;
40 else
41 pUnk->Release();
42 }
43 return hr;
44}
45
46static HRESULT
48{
51 if (SUCCEEDED(hr))
52 {
53 UINT OldCount = psh.nPages;
54 hr = SheetExt->AddPages(AddPropSheetPageCallback, (LPARAM)&psh);
55 // The returned index is one-based (relative to this extension).
56 // See https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishellpropsheetext-addpages
57 if (hr > 0)
58 {
59 hr += OldCount;
60 psh.nStartPage = hr - 1;
61 }
62 }
63 return hr;
64}
65
66static HRESULT
68{
69 PWSTR Path;
70 if (!pidl || FAILED(SHGetNameFromIDList(pidl, SIGDN_DESKTOPABSOLUTEPARSING, &Path)))
71 Path = NULL; // If we can't get a path, we simply will not be able to reuse this window
72
74 SHFree(Path);
76 SHFILEINFO sfi;
77 if (SUCCEEDED(hr) && SHGetFileInfoW((LPWSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL | flags))
78 stub.SendMessage(WM_SETICON, ICON_BIG, (LPARAM)sfi.hIcon);
79 return hr;
80}
81
82/*************************************************************************
83 * SHELL32_PropertySheet [INTERNAL]
84 * PropertySheetW with stub window.
85 */
86static INT_PTR
88{
90 POINT pt, *ppt = NULL;
91 if (pDO && SUCCEEDED(DataObject_GetOffset(pDO, &pt)))
92 ppt = &pt;
95 ILFree(pidl);
96 if (FAILED(hr))
97 return hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) ? 0 : -1;
98
99 INT_PTR Result = -1;
100 ppsh->hwndParent = stub;
101 if (ppsh->nPages)
102 {
103 Result = PropertySheetW(ppsh);
104 }
105 else
106 {
107 WCHAR szFormat[128], szMessage[_countof(szFormat) + 42];
109 wsprintfW(szMessage, szFormat, ERROR_CAN_NOT_COMPLETE);
110 MessageBoxW(NULL, szMessage, NULL, MB_ICONERROR);
111 }
112 stub.DestroyWindow();
113 return Result;
114}
115
116/*************************************************************************
117 * SHELL32_OpenPropSheet [INTERNAL]
118 * The real implementation of SHOpenPropSheetW.
119 */
120static BOOL
121SHELL32_OpenPropSheet(LPCWSTR pszCaption, HKEY *ahKeys, UINT cKeys,
122 const CLSID *pclsidDefault, IDataObject *pDO, LPCWSTR pStartPage)
123{
124 HKEY hKeyProgID = cKeys ? ahKeys[cKeys - 1] : NULL; // Windows uses the last key for some reason
126 PROPSHEETHEADERW psh = { sizeof(psh), PSH_PROPTITLE };
127 psh.phpage = hppages;
129 psh.pszCaption = pszCaption;
130 psh.pStartPage = pStartPage;
131
132 if (pclsidDefault)
133 AddPropSheetHandlerPages(*pclsidDefault, pDO, hKeyProgID, psh);
134
135 for (UINT i = 0; i < cKeys; ++i)
136 {
137 // Note: We can't use SHCreatePropSheetExtArrayEx because we need the AddPages() return value (see AddPropSheetHandlerPages).
138 HKEY hKey;
139 if (RegOpenKeyExW(ahKeys[i], L"shellex\\PropertySheetHandlers", 0, KEY_ENUMERATE_SUB_KEYS, &hKey))
140 continue;
141 for (UINT index = 0;; ++index)
142 {
146 if (err == ERROR_MORE_DATA)
147 continue;
148 if (err)
149 break;
150 CLSID clsid;
152 AddPropSheetHandlerPages(clsid, pDO, hKeyProgID, psh);
153 }
155 }
156
157 if (pStartPage == psh.pStartPage && pStartPage)
160 return (Result != -1);
161}
162
163/*************************************************************************
164 * SHOpenPropSheetW [SHELL32.80]
165 *
166 * @see https://learn.microsoft.com/en-us/windows/win32/api/shlobj/nf-shlobj-shopenpropsheetw
167 */
170 _In_opt_ LPCWSTR pszCaption,
171 _In_opt_ HKEY *ahKeys,
172 _In_ UINT cKeys,
173 _In_ const CLSID *pclsidDefault,
174 _In_ IDataObject *pDataObject,
175 _In_opt_ IShellBrowser *pShellBrowser,
176 _In_opt_ LPCWSTR pszStartPage)
177{
178 UNREFERENCED_PARAMETER(pShellBrowser); /* MSDN says "Not used". */
179 return SHELL32_OpenPropSheet(pszCaption, ahKeys, cKeys, pclsidDefault, pDataObject, pszStartPage);
180}
181
182/*************************************************************************
183 * SH_CreatePropertySheetPage [Internal]
184 *
185 * creates a property sheet page from a resource id
186 */
190{
192 Page.pszTemplate = MAKEINTRESOURCEW(wDialogId);
193 Page.pfnDlgProc = pfnDlgProc;
194 Page.lParam = lParam;
195 Page.pszTitle = pwszTitle;
196 Page.pfnCallback = Callback;
197
198 if (pwszTitle)
199 Page.dwFlags |= PSP_USETITLE;
200
201 if (Callback)
202 Page.dwFlags |= PSP_USECALLBACK;
203
205}
206
208SH_CreatePropertySheetPage(WORD wDialogId, DLGPROC pfnDlgProc, LPARAM lParam, LPCWSTR pwszTitle)
209{
210 return SH_CreatePropertySheetPageEx(wDialogId, pfnDlgProc, lParam, pwszTitle, NULL);
211}
PRTL_UNICODE_STRING_BUFFER Path
#define shell32_hInstance
#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 EXTERN_C
Definition: basetyps.h:12
#define RegCloseKey(hKey)
Definition: registry.h:49
@ TYPE_PROPERTYSHEET
Definition: precomp.h:206
LPARAM lParam
Definition: combotst.c:139
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define DLGPROC
Definition: maze.c:62
#define NULL
Definition: types.h:112
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2393
HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage)
Definition: propsheet.c:3086
INT_PTR WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh)
Definition: propsheet.c:2916
#define MAX_PATH
Definition: compat.h:34
#define RRF_RT_REG_SZ
Definition: driver.c:575
PIDLIST_ABSOLUTE SHELL_DataObject_ILCloneFullItem(_In_ IDataObject *pDO, _In_ UINT Index)
BOOL CALLBACK AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
Definition: precomp.h:136
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
DWORD WINAPI SHCLSIDFromStringW(LPCWSTR clsid, CLSID *id)
Definition: shellole.c:256
HRESULT WINAPI SHCoCreateInstance(LPCWSTR aclsid, const CLSID *clsid, LPUNKNOWN pUnkOuter, REFIID refiid, LPVOID *ppv)
Definition: shellole.c:105
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
#define pt(x, y)
Definition: drawing.c:79
#define SHGFI_ADDOVERLAYS
Definition: entries.h:77
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxAutoRegKey hKey
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
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
nsresult QueryInterface(nsIIDRef riid, void **result)
nsrefcnt Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
REFCLSID clsid
Definition: msctf.c:82
struct _PSP * HPROPSHEETPAGE
Definition: mstask.idl:90
unsigned int UINT
Definition: ndis.h:50
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1313
#define L(x)
Definition: ntvdm.h:50
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1044
HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWSTR *ppszName)
Definition: pidl.c:1568
#define PSH_PROPTITLE
Definition: prsht.h:40
#define PSH_USEPSTARTPAGE
Definition: prsht.h:46
#define PSP_USETITLE
Definition: prsht.h:26
#define PSP_DEFAULT
Definition: prsht.h:22
#define PSP_USECALLBACK
Definition: prsht.h:30
#define LPFNPSPCALLBACK
Definition: prsht.h:388
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define err(...)
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:430
#define SHGFI_ICON
Definition: shellapi.h:165
#define SHGFI_PIDL
Definition: shellapi.h:181
#define MAX_PROPERTY_SHEET_PAGE
HRESULT hr
Definition: shlfolder.c:183
#define IDS_CANTSHOWPROPERTIES
Definition: shresdef.h:150
#define _countof(array)
Definition: sndvol32.h:70
HINSTANCE hInstance
Definition: prsht.h:296
LPCWSTR pStartPage
Definition: prsht.h:305
DWORD dwFlags
Definition: prsht.h:294
HWND hwndParent
Definition: prsht.h:295
HPROPSHEETPAGE * phpage
Definition: prsht.h:309
LPCWSTR pszCaption
Definition: prsht.h:301
HICON hIcon
Definition: shellapi.h:366
Definition: stubgen.c:11
struct _stub stub
#define ICON_BIG
Definition: tnclass.cpp:51
uint16_t * PWSTR
Definition: typedefs.h:56
int32_t INT_PTR
Definition: typedefs.h:64
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
static BOOL SHELL32_OpenPropSheet(LPCWSTR pszCaption, HKEY *ahKeys, UINT cKeys, const CLSID *pclsidDefault, IDataObject *pDO, LPCWSTR pStartPage)
Definition: propsheet.cpp:121
static HRESULT SHELL_InitializeExtension(REFCLSID clsid, PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDO, HKEY hkeyProgID, REFIID riid, void **ppv)
Definition: propsheet.cpp:26
HPROPSHEETPAGE SH_CreatePropertySheetPage(WORD wDialogId, DLGPROC pfnDlgProc, LPARAM lParam, LPCWSTR pwszTitle)
Definition: propsheet.cpp:208
static HRESULT SHELL_CreatePropSheetStubWindow(CStubWindow32 &stub, PCIDLIST_ABSOLUTE pidl, const POINT *pPt)
Definition: propsheet.cpp:67
static HRESULT AddPropSheetHandlerPages(REFCLSID clsid, IDataObject *pDO, HKEY hkeyProgID, PROPSHEETHEADERW &psh)
Definition: propsheet.cpp:47
static HRESULT SHELL_GetShellExtensionRegCLSID(HKEY hKey, LPCWSTR KeyName, CLSID &clsid)
Definition: propsheet.cpp:13
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:169
static INT_PTR SHELL32_PropertySheet(LPPROPSHEETHEADERW ppsh, IDataObject *pDO)
Definition: propsheet.cpp:87
HPROPSHEETPAGE SH_CreatePropertySheetPageEx(WORD wDialogId, DLGPROC pfnDlgProc, LPARAM lParam, LPCWSTR pwszTitle, LPFNPSPCALLBACK Callback)
Definition: propsheet.cpp:188
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
#define WINAPI
Definition: msvc.h:6
#define ERROR_CAN_NOT_COMPLETE
Definition: winerror.h:582
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:790
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#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