diff options
Diffstat (limited to '')
-rw-r--r-- | src/dutil/shelutil.cpp | 69 |
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 | |||
5 | static PFN_SHELLEXECUTEEXW vpfnShellExecuteExW = ::ShellExecuteExW; | 20 | static PFN_SHELLEXECUTEEXW vpfnShellExecuteExW = ::ShellExecuteExW; |
6 | 21 | ||
7 | static HRESULT GetDesktopShellView( | 22 | static 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 | ||
135 | LExit: | 150 | LExit: |
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 | ||
168 | LExit: | 183 | LExit: |
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 | ||
223 | LExit: | 238 | LExit: |
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 | ||
286 | LExit: | 301 | LExit: |
@@ -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 | ||
321 | LExit: | 336 | LExit: |
322 | ReleaseObject(pdisp); | 337 | ReleaseObject(pdisp); |