HRESULT ShellExecInExplorerProcess(PCWSTR pszFile) { IShellView *psv; HRESULT hr = GetShellViewForDesktop(IID_PPV_ARGS(&psv)); if (SUCCEEDED(hr)) { IShellDispatch2 *psd; hr = GetShellDispatchFromView(psv, IID_PPV_ARGS(&psd)); if (SUCCEEDED(hr)) { BSTR bstrFile = SysAllocString(pszFile); hr = bstrFile ? S_OK : E_OUTOFMEMORY; if (SUCCEEDED(hr)) { VARIANT vtEmpty = {}; // VT_EMPTY hr = psd->ShellExecuteW(bstrFile, vtEmpty, vtEmpty, vtEmpty, vtEmpty); SysFreeString(bstrFile); } psd->Release(); } psv->Release(); } return hr; }
/******************************************************************** ShelExecUnelevated() - executes a target unelevated. *******************************************************************/ extern "C" HRESULT DAPI ShelExecUnelevated( __in_z LPCWSTR wzTargetPath, __in_z_opt LPCWSTR wzParameters, __in_z_opt LPCWSTR wzVerb, __in_z_opt LPCWSTR wzWorkingDirectory, __in int nShowCmd ) { HRESULT hr = S_OK; BSTR bstrTargetPath = NULL; VARIANT vtParameters = { }; VARIANT vtVerb = { }; VARIANT vtWorkingDirectory = { }; VARIANT vtShow = { }; IShellView* psv = NULL; IShellDispatch2* psd = NULL; bstrTargetPath = ::SysAllocString(wzTargetPath); ExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate target path BSTR."); if (wzParameters && *wzParameters) { vtParameters.vt = VT_BSTR; vtParameters.bstrVal = ::SysAllocString(wzParameters); ExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate parameters BSTR."); } if (wzVerb && *wzVerb) { vtVerb.vt = VT_BSTR; vtVerb.bstrVal = ::SysAllocString(wzVerb); ExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate verb BSTR."); } if (wzWorkingDirectory && *wzWorkingDirectory) { vtWorkingDirectory.vt = VT_BSTR; vtWorkingDirectory.bstrVal = ::SysAllocString(wzWorkingDirectory); ExitOnNull(bstrTargetPath, hr, E_OUTOFMEMORY, "Failed to allocate working directory BSTR."); } vtShow.vt = VT_INT; vtShow.intVal = nShowCmd; hr = GetDesktopShellView(IID_PPV_ARGS(&psv)); ExitOnFailure(hr, "Failed to get desktop shell view."); hr = GetShellDispatchFromView(psv, IID_PPV_ARGS(&psd)); ExitOnFailure(hr, "Failed to get shell dispatch from view."); hr = psd->ShellExecute(bstrTargetPath, vtParameters, vtWorkingDirectory, vtVerb, vtShow); if (S_FALSE == hr) { hr = HRESULT_FROM_WIN32(ERROR_CANCELLED); } ExitOnRootFailure1(hr, "Failed to launch unelevate executable: %ls", bstrTargetPath); LExit: ReleaseObject(psd); ReleaseObject(psv); ReleaseBSTR(vtWorkingDirectory.bstrVal); ReleaseBSTR(vtVerb.bstrVal); ReleaseBSTR(vtParameters.bstrVal); ReleaseBSTR(bstrTargetPath); return hr; }
int ShellExecAsUser(const TCHAR *pcOperation, const TCHAR *pcFileName, const TCHAR *pcParameters, const HWND parentHwnd) { /*BOOL bRet; HANDLE hToken; HANDLE hNewToken; // Notepad is used as an example //WCHAR wszProcessName[MAX_PATH] = L"C:\\Windows\\Notepad.exe"; // Low integrity SID: 0x1000 = 4096. To use Medium integrity, use 0x2000 = 8192 WCHAR wszIntegritySid[20] = L"S-1-16-4096"; PSID pIntegritySid = NULL; TOKEN_MANDATORY_LABEL TIL = {0}; PROCESS_INFORMATION ProcInfo = {0}; STARTUPINFO StartupInfo = {0}; ULONG ExitCode = 0; if (OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hToken)) { if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hNewToken)) { if (ConvertStringSidToSid(wszIntegritySid, &pIntegritySid)) { TIL.Label.Attributes = SE_GROUP_INTEGRITY; TIL.Label.Sid = pIntegritySid; // Set the process integrity level if (SetTokenInformation(hNewToken, TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid))) { // Create the new process at Low integrity bRet = CreateProcessAsUser(hNewToken, NULL, (LPWSTR)pcFileName, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcInfo); } LocalFree(pIntegritySid); } CloseHandle(hNewToken); } CloseHandle(hToken); } return bRet;*/ int bSuccess = 0; HRESULT hr = CoInitialize(NULL); if((hr == S_FALSE) || (hr == S_OK)) { IShellWindows *psw = NULL; hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw)); if(SUCCEEDED(hr)) { HWND hwnd = 0; IDispatch* pdisp = NULL; variant_t vEmpty; if(S_OK == psw->FindWindowSW(&vEmpty.get(), &vEmpty.get(), SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp)) { if((hwnd != NULL) && (hwnd != INVALID_HANDLE_VALUE)) { IShellBrowser *psb; hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb)); if(SUCCEEDED(hr)) { IShellView *psv = NULL; hr = psb->QueryActiveShellView(&psv); if(SUCCEEDED(hr)) { IDispatch *pdispBackground = NULL; hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground)); if (SUCCEEDED(hr)) { IShellFolderViewDual *psfvd = NULL; hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd)); if (SUCCEEDED(hr)) { IDispatch *pdisp2 = NULL; hr = psfvd->get_Application(&pdisp2); if (SUCCEEDED(hr)) { IShellDispatch2 *psd; hr = pdisp2->QueryInterface(IID_PPV_ARGS(&psd)); if(SUCCEEDED(hr)) { variant_t verb(pcOperation); variant_t file(pcFileName); variant_t para(pcParameters); variant_t show(SW_SHOWNORMAL); hr = psd->ShellExecute(file.get().bstrVal, para.get(), vEmpty.get(), verb.get(), show.get()); if(SUCCEEDED(hr)) bSuccess = 1; psd->Release(); psd = NULL; } pdisp2->Release(); pdisp2 = NULL; } } pdispBackground->Release(); pdispBackground = NULL; } psv->Release(); psv = NULL; } psb->Release(); psb = NULL; } } pdisp->Release(); pdisp = NULL; } psw->Release(); psw = NULL; } CoUninitialize(); } if(bSuccess < 1) { dcassert(0); HINSTANCE hInst = ShellExecuteW(parentHwnd, pcOperation, pcFileName, pcParameters, NULL, SW_SHOWNORMAL); if(((int) hInst) <= 32) bSuccess = -1; } return bSuccess; }
static int ShellExecAsUser_ShellDispatchProc(const TCHAR *pcOperation, const TCHAR *pcFileName, const TCHAR *pcParameters, const HWND parentHwnd) { int iSuccess = SHELLEXECASUSER_ERROR_FAILED; IShellWindows *psw = NULL; HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw)); if(SUCCEEDED(hr)) { HWND hwnd = 0; IDispatch* pdisp = NULL; variant_t vEmpty; if(S_OK == psw->FindWindowSW(vEmpty, vEmpty, SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp)) { if((hwnd != NULL) && (hwnd != INVALID_HANDLE_VALUE)) { IShellBrowser *psb; hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb)); if(SUCCEEDED(hr)) { IShellView *psv = NULL; hr = psb->QueryActiveShellView(&psv); if(SUCCEEDED(hr)) { IDispatch *pdispBackground = NULL; HRESULT hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground)); if (SUCCEEDED(hr)) { IShellFolderViewDual *psfvd = NULL; hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd)); if (SUCCEEDED(hr)) { IDispatch *pdisp = NULL; hr = psfvd->get_Application(&pdisp); if (SUCCEEDED(hr)) { IShellDispatch2 *psd; hr = pdisp->QueryInterface(IID_PPV_ARGS(&psd)); if(SUCCEEDED(hr)) { DispatchPendingMessages(125); variant_t verb(pcOperation); variant_t file(pcFileName); variant_t para(pcParameters); variant_t show(SW_SHOWNORMAL); hr = psd->ShellExecute(file, para, vEmpty, verb, show); if(SUCCEEDED(hr)) { iSuccess = SHELLEXECASUSER_ERROR_SUCCESS; } psd->Release(); psd = NULL; } pdisp->Release(); pdisp = NULL; } } pdispBackground->Release(); pdispBackground = NULL; } psv->Release(); psv = NULL; } psb->Release(); psb = NULL; } } pdisp->Release(); pdisp = NULL; } psw->Release(); psw = NULL; } return iSuccess; }