diff options
Diffstat (limited to 'src/dutil/shelutil.cpp')
| -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); |
