static int MyShellDispatch_ShellDispatchProc(const shell_dispatch_handler_t handler, void *const data) { int iSuccess = SHELL_DISPATCH_FAILED; IShellWindows *psw = NULL; HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw)); if(SUCCEEDED(hr)) { HWND desktopHwnd = 0; IDispatch* pdisp = NULL; variant_t vEmpty; if(S_OK == psw->FindWindowSW(vEmpty, vEmpty, SWC_DESKTOP, (long*)&desktopHwnd, SWFO_NEEDDISPATCH, &pdisp)) { if(VALID_HANDLE(desktopHwnd)) { 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)) { MyShellDispatch_AllowSetForegroundWindow(desktopHwnd); IShellFolderViewDual *psfvd = NULL; HRESULT hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd)); if(SUCCEEDED(hr)) { IDispatch *pdisp = NULL; hr = psfvd->get_Application(&pdisp); if(SUCCEEDED(hr)) { IShellDispatch2 *pShellDispatch; hr = pdisp->QueryInterface(IID_PPV_ARGS(&pShellDispatch)); if(SUCCEEDED(hr)) { iSuccess = handler(pShellDispatch, data); } RELEASE_OBJ(pdisp); } RELEASE_OBJ(psfvd); } RELEASE_OBJ(pdispBackground); } RELEASE_OBJ(psv); } RELEASE_OBJ(psb); } } RELEASE_OBJ(pdisp); } RELEASE_OBJ(psw); } return iSuccess; }
static HRESULT GetDesktopShellView( __in REFIID riid, __out void **ppv ) { HRESULT hr = S_OK; IShellWindows* psw = NULL; HWND hwnd = NULL; IDispatch* pdisp = NULL; VARIANT vEmpty = {}; // VT_EMPTY IShellBrowser* psb = NULL; IShellFolder* psf = NULL; IShellView* psv = NULL; // use the shell view for the desktop using the shell windows automation to find the // desktop web browser and then grabs its view // returns IShellView, IFolderView and related interfaces hr = ::CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw)); ExitOnFailure(hr, "Failed to get shell view."); hr = psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp); if (S_OK == hr) { hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb)); ExitOnFailure(hr, "Failed to get desktop window."); hr = psb->QueryActiveShellView(&psv); ExitOnFailure(hr, "Failed to get active shell view."); hr = psv->QueryInterface(riid, ppv); ExitOnFailure(hr, "Failed to query for the desktop shell view."); } else if (S_FALSE == hr) { //Windows XP hr = SHGetDesktopFolder(&psf); ExitOnFailure(hr, "Failed to get desktop folder."); hr = psf->CreateViewObject(NULL, IID_IShellView, ppv); ExitOnFailure(hr, "Failed to query for the desktop shell view."); } else { ExitOnFailure(hr, "Failed to get desktop window."); } LExit: ReleaseObject(psv); ReleaseObject(psb); ReleaseObject(psf); ReleaseObject(pdisp); ReleaseObject(psw); return hr; }
HRESULT GetShellViewForDesktop(REFIID riid, void **ppv) { *ppv = NULL; IShellWindows *psw; HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw)); if (SUCCEEDED(hr)) { HWND hwnd; IDispatch* pdisp; VARIANT vEmpty = {}; // VT_EMPTY if (S_OK == psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp)) { IShellBrowser *psb; hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb)); if (SUCCEEDED(hr)) { IShellView *psv; hr = psb->QueryActiveShellView(&psv); if (SUCCEEDED(hr)) { hr = psv->QueryInterface(riid, ppv); psv->Release(); } psb->Release(); } pdisp->Release(); } else { hr = E_FAIL; } psw->Release(); } 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; }