aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/shelutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dutil/shelutil.cpp69
1 files changed, 42 insertions, 27 deletions
diff --git a/src/dutil/shelutil.cpp b/src/dutil/shelutil.cpp
index a69c9eaa..2eb9a52a 100644
--- a/src/dutil/shelutil.cpp
+++ b/src/dutil/shelutil.cpp
@@ -2,6 +2,21 @@
2 2
3#include "precomp.h" 3#include "precomp.h"
4 4
5
6// Exit macros
7#define ShelExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__)
8#define ShelExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__)
9#define ShelExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__)
10#define ShelExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__)
11#define ShelExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__)
12#define ShelExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__)
13#define ShelExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_SHELUTIL, p, x, e, s, __VA_ARGS__)
14#define ShelExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_SHELUTIL, p, x, s, __VA_ARGS__)
15#define ShelExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_SHELUTIL, p, x, e, s, __VA_ARGS__)
16#define ShelExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_SHELUTIL, p, x, s, __VA_ARGS__)
17#define ShelExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_SHELUTIL, e, x, s, __VA_ARGS__)
18#define ShelExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_SHELUTIL, g, x, s, __VA_ARGS__)
19
5static PFN_SHELLEXECUTEEXW vpfnShellExecuteExW = ::ShellExecuteExW; 20static PFN_SHELLEXECUTEEXW vpfnShellExecuteExW = ::ShellExecuteExW;
6 21
7static HRESULT GetDesktopShellView( 22static HRESULT GetDesktopShellView(
@@ -55,7 +70,7 @@ extern "C" HRESULT DAPI ShelExec(
55 70
56 if (!vpfnShellExecuteExW(&shExecInfo)) 71 if (!vpfnShellExecuteExW(&shExecInfo))
57 { 72 {
58 ExitWithLastError(hr, "ShellExecEx failed with return code: %d", Dutil_er); 73 ShelExitWithLastError(hr, "ShellExecEx failed with return code: %d", Dutil_er);
59 } 74 }
60 75
61 if (phProcess) 76 if (phProcess)
@@ -93,44 +108,44 @@ extern "C" HRESULT DAPI ShelExecUnelevated(
93 IShellDispatch2* psd = NULL; 108 IShellDispatch2* psd = NULL;
94 109
95 bstrTargetPath = ::SysAllocString(wzTargetPath); 110 bstrTargetPath = ::SysAllocString(wzTargetPath);
96 ExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate target path BSTR."); 111 ShelExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate target path BSTR.");
97 112
98 if (wzParameters && *wzParameters) 113 if (wzParameters && *wzParameters)
99 { 114 {
100 vtParameters.vt = VT_BSTR; 115 vtParameters.vt = VT_BSTR;
101 vtParameters.bstrVal = ::SysAllocString(wzParameters); 116 vtParameters.bstrVal = ::SysAllocString(wzParameters);
102 ExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate parameters BSTR."); 117 ShelExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate parameters BSTR.");
103 } 118 }
104 119
105 if (wzVerb && *wzVerb) 120 if (wzVerb && *wzVerb)
106 { 121 {
107 vtVerb.vt = VT_BSTR; 122 vtVerb.vt = VT_BSTR;
108 vtVerb.bstrVal = ::SysAllocString(wzVerb); 123 vtVerb.bstrVal = ::SysAllocString(wzVerb);
109 ExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate verb BSTR."); 124 ShelExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate verb BSTR.");
110 } 125 }
111 126
112 if (wzWorkingDirectory && *wzWorkingDirectory) 127 if (wzWorkingDirectory && *wzWorkingDirectory)
113 { 128 {
114 vtWorkingDirectory.vt = VT_BSTR; 129 vtWorkingDirectory.vt = VT_BSTR;
115 vtWorkingDirectory.bstrVal = ::SysAllocString(wzWorkingDirectory); 130 vtWorkingDirectory.bstrVal = ::SysAllocString(wzWorkingDirectory);
116 ExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate working directory BSTR."); 131 ShelExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate working directory BSTR.");
117 } 132 }
118 133
119 vtShow.vt = VT_INT; 134 vtShow.vt = VT_INT;
120 vtShow.intVal = nShowCmd; 135 vtShow.intVal = nShowCmd;
121 136
122 hr = GetDesktopShellView(IID_PPV_ARGS(&psv)); 137 hr = GetDesktopShellView(IID_PPV_ARGS(&psv));
123 ExitOnFailure(hr, "Failed to get desktop shell view."); 138 ShelExitOnFailure(hr, "Failed to get desktop shell view.");
124 139
125 hr = GetShellDispatchFromView(psv, IID_PPV_ARGS(&psd)); 140 hr = GetShellDispatchFromView(psv, IID_PPV_ARGS(&psd));
126 ExitOnFailure(hr, "Failed to get shell dispatch from view."); 141 ShelExitOnFailure(hr, "Failed to get shell dispatch from view.");
127 142
128 hr = psd->ShellExecute(bstrTargetPath, vtParameters, vtWorkingDirectory, vtVerb, vtShow); 143 hr = psd->ShellExecute(bstrTargetPath, vtParameters, vtWorkingDirectory, vtVerb, vtShow);
129 if (S_FALSE == hr) 144 if (S_FALSE == hr)
130 { 145 {
131 hr = HRESULT_FROM_WIN32(ERROR_CANCELLED); 146 hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
132 } 147 }
133 ExitOnRootFailure(hr, "Failed to launch unelevate executable: %ls", bstrTargetPath); 148 ShelExitOnRootFailure(hr, "Failed to launch unelevate executable: %ls", bstrTargetPath);
134 149
135LExit: 150LExit:
136 ReleaseObject(psd); 151 ReleaseObject(psd);
@@ -157,13 +172,13 @@ extern "C" HRESULT DAPI ShelGetFolder(
157 WCHAR wzPath[MAX_PATH]; 172 WCHAR wzPath[MAX_PATH];
158 173
159 hr = ::SHGetFolderPathW(NULL, csidlFolder | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, wzPath); 174 hr = ::SHGetFolderPathW(NULL, csidlFolder | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, wzPath);
160 ExitOnFailure(hr, "Failed to get folder path for CSIDL: %d", csidlFolder); 175 ShelExitOnFailure(hr, "Failed to get folder path for CSIDL: %d", csidlFolder);
161 176
162 hr = StrAllocString(psczFolderPath, wzPath, 0); 177 hr = StrAllocString(psczFolderPath, wzPath, 0);
163 ExitOnFailure(hr, "Failed to copy shell folder path: %ls", wzPath); 178 ShelExitOnFailure(hr, "Failed to copy shell folder path: %ls", wzPath);
164 179
165 hr = PathBackslashTerminate(psczFolderPath); 180 hr = PathBackslashTerminate(psczFolderPath);
166 ExitOnFailure(hr, "Failed to backslash terminate shell folder path: %ls", *psczFolderPath); 181 ShelExitOnFailure(hr, "Failed to backslash terminate shell folder path: %ls", *psczFolderPath);
167 182
168LExit: 183LExit:
169 return hr; 184 return hr;
@@ -206,19 +221,19 @@ extern "C" HRESULT DAPI ShelGetKnownFolder(
206 TraceError(hr, "Failed to load shell32.dll"); 221 TraceError(hr, "Failed to load shell32.dll");
207 ExitFunction1(hr = E_NOTIMPL); 222 ExitFunction1(hr = E_NOTIMPL);
208 } 223 }
209 ExitOnFailure(hr, "Failed to load shell32.dll."); 224 ShelExitOnFailure(hr, "Failed to load shell32.dll.");
210 225
211 pfn = reinterpret_cast<PFN_SHGetKnownFolderPath>(::GetProcAddress(hShell32Dll, "SHGetKnownFolderPath")); 226 pfn = reinterpret_cast<PFN_SHGetKnownFolderPath>(::GetProcAddress(hShell32Dll, "SHGetKnownFolderPath"));
212 ExitOnNull(pfn, hr, E_NOTIMPL, "Failed to find SHGetKnownFolderPath entry point."); 227 ShelExitOnNull(pfn, hr, E_NOTIMPL, "Failed to find SHGetKnownFolderPath entry point.");
213 228
214 hr = pfn(rfidFolder, KF_FLAG_CREATE, NULL, &pwzPath); 229 hr = pfn(rfidFolder, KF_FLAG_CREATE, NULL, &pwzPath);
215 ExitOnFailure(hr, "Failed to get known folder path."); 230 ShelExitOnFailure(hr, "Failed to get known folder path.");
216 231
217 hr = StrAllocString(psczFolderPath, pwzPath, 0); 232 hr = StrAllocString(psczFolderPath, pwzPath, 0);
218 ExitOnFailure(hr, "Failed to copy shell folder path: %ls", pwzPath); 233 ShelExitOnFailure(hr, "Failed to copy shell folder path: %ls", pwzPath);
219 234
220 hr = PathBackslashTerminate(psczFolderPath); 235 hr = PathBackslashTerminate(psczFolderPath);
221 ExitOnFailure(hr, "Failed to backslash terminate shell folder path: %ls", *psczFolderPath); 236 ShelExitOnFailure(hr, "Failed to backslash terminate shell folder path: %ls", *psczFolderPath);
222 237
223LExit: 238LExit:
224 if (pwzPath) 239 if (pwzPath)
@@ -255,32 +270,32 @@ static HRESULT GetDesktopShellView(
255 // desktop web browser and then grabs its view 270 // desktop web browser and then grabs its view
256 // returns IShellView, IFolderView and related interfaces 271 // returns IShellView, IFolderView and related interfaces
257 hr = ::CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw)); 272 hr = ::CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw));
258 ExitOnFailure(hr, "Failed to get shell view."); 273 ShelExitOnFailure(hr, "Failed to get shell view.");
259 274
260 hr = psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp); 275 hr = psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp);
261 if (S_OK == hr) 276 if (S_OK == hr)
262 { 277 {
263 hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb)); 278 hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb));
264 ExitOnFailure(hr, "Failed to get desktop window."); 279 ShelExitOnFailure(hr, "Failed to get desktop window.");
265 280
266 hr = psb->QueryActiveShellView(&psv); 281 hr = psb->QueryActiveShellView(&psv);
267 ExitOnFailure(hr, "Failed to get active shell view."); 282 ShelExitOnFailure(hr, "Failed to get active shell view.");
268 283
269 hr = psv->QueryInterface(riid, ppv); 284 hr = psv->QueryInterface(riid, ppv);
270 ExitOnFailure(hr, "Failed to query for the desktop shell view."); 285 ShelExitOnFailure(hr, "Failed to query for the desktop shell view.");
271 } 286 }
272 else if (S_FALSE == hr) 287 else if (S_FALSE == hr)
273 { 288 {
274 //Windows XP 289 //Windows XP
275 hr = SHGetDesktopFolder(&psf); 290 hr = SHGetDesktopFolder(&psf);
276 ExitOnFailure(hr, "Failed to get desktop folder."); 291 ShelExitOnFailure(hr, "Failed to get desktop folder.");
277 292
278 hr = psf->CreateViewObject(NULL, IID_IShellView, ppv); 293 hr = psf->CreateViewObject(NULL, IID_IShellView, ppv);
279 ExitOnFailure(hr, "Failed to query for the desktop shell view."); 294 ShelExitOnFailure(hr, "Failed to query for the desktop shell view.");
280 } 295 }
281 else 296 else
282 { 297 {
283 ExitOnFailure(hr, "Failed to get desktop window."); 298 ShelExitOnFailure(hr, "Failed to get desktop window.");
284 } 299 }
285 300
286LExit: 301LExit:
@@ -307,16 +322,16 @@ static HRESULT GetShellDispatchFromView(
307 // From a shell view object, gets its automation interface and from that get the shell 322 // From a shell view object, gets its automation interface and from that get the shell
308 // application object that implements IShellDispatch2 and related interfaces. 323 // application object that implements IShellDispatch2 and related interfaces.
309 hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground)); 324 hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground));
310 ExitOnFailure(hr, "Failed to get the automation interface for shell."); 325 ShelExitOnFailure(hr, "Failed to get the automation interface for shell.");
311 326
312 hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd)); 327 hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd));
313 ExitOnFailure(hr, "Failed to get shell folder view dual."); 328 ShelExitOnFailure(hr, "Failed to get shell folder view dual.");
314 329
315 hr = psfvd->get_Application(&pdisp); 330 hr = psfvd->get_Application(&pdisp);
316 ExitOnFailure(hr, "Failed to application object."); 331 ShelExitOnFailure(hr, "Failed to application object.");
317 332
318 hr = pdisp->QueryInterface(riid, ppv); 333 hr = pdisp->QueryInterface(riid, ppv);
319 ExitOnFailure(hr, "Failed to get IShellDispatch2."); 334 ShelExitOnFailure(hr, "Failed to get IShellDispatch2.");
320 335
321LExit: 336LExit:
322 ReleaseObject(pdisp); 337 ReleaseObject(pdisp);