Example #1
0
HRESULT CMenuFocusManager::IsTrackedWindowOrParent(HWND hWnd)
{
    for (int i = m_bandCount; --i >= 0;)
    {
        StackEntry& entry = m_bandStack[i];

        if (entry.type != TrackedMenuEntry)
        {
            HRESULT hr = entry.mb->IsWindowOwner(hWnd);
            if (FAILED_UNEXPECTEDLY(hr))
                return hr;
            if (hr == S_OK)
                return S_OK;
            if (entry.mb->_IsPopup() == S_OK)
            {
                CComPtr<IUnknown> site;
                CComPtr<IOleWindow> pw;
                hr = entry.mb->GetSite(IID_PPV_ARG(IUnknown, &site));
                if (FAILED_UNEXPECTEDLY(hr))
                    continue;
                hr = IUnknown_QueryService(site, SID_SMenuBandParent, IID_PPV_ARG(IOleWindow, &pw));
                if (FAILED_UNEXPECTEDLY(hr))
                    continue;

                HWND hParent;
                if (pw->GetWindow(&hParent) == S_OK && hParent == hWnd)
                    return S_OK;
            }
        }
    }

    return S_FALSE;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
HRESULT STDMETHODCALLTYPE CAddressEditBox::ParseNow(long paramC)
{
    ULONG eaten;
    ULONG attributes;
    HRESULT hr;
    HWND topLevelWindow;

    CComPtr<IShellBrowser> pisb;
    hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pisb));
    if (FAILED_UNEXPECTEDLY(hr))
        return hr;

    hr = IUnknown_GetWindow(pisb, &topLevelWindow);
    if (FAILED_UNEXPECTEDLY(hr))
        return hr;

    LPWSTR input;
    int inputLength = fCombobox.GetWindowTextLength() + 2;

    input = new WCHAR[inputLength];
    fCombobox.GetWindowText(input, inputLength);

    LPWSTR address;
    int addressLength = ExpandEnvironmentStrings(input, NULL, 0);

    if (addressLength <= 0)
    {
        address = input;
    }
    else
    {
        addressLength += 2;
        address = new WCHAR[addressLength];
        if (!ExpandEnvironmentStrings(input, address, addressLength))
        {
            delete[] address;
            address = input;
        }
    }

    CComPtr<IShellFolder> psfDesktop;
    hr = SHGetDesktopFolder(&psfDesktop);
    if (SUCCEEDED(hr))
    {
        hr = psfDesktop->ParseDisplayName(topLevelWindow, NULL, address, &eaten, &pidlLastParsed, &attributes);
    }

    if (address != input)
        delete [] address;
    delete [] input;

    return hr;
}
HRESULT GetSelectionFromSite(IUnknown *punkSite, BOOL fNoneImpliesFolder, IShellItemArray **ppsia)
{
    *ppsia = NULL;
    IFolderView2 *pfv;
    HRESULT hr = IUnknown_QueryService(punkSite, SID_SFolderView, IID_PPV_ARGS(&pfv));
    if (SUCCEEDED(hr))
    {
        hr = pfv->GetSelection(fNoneImpliesFolder, ppsia);
        pfv->Release();
    }
    return hr;
}
Example #6
0
HRESULT CBandProxy::FindBrowserWindow(IUnknown **browser)
{
    IWebBrowser2* webBrowser;
    HRESULT hResult;

    if (browser == NULL)
        return E_POINTER;
    hResult = IUnknown_QueryService(fSite, SID_IWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &webBrowser));
    if (FAILED_UNEXPECTEDLY(hResult))
        return hResult;
    *browser = webBrowser;
    return S_OK;
}
Example #7
0
HRESULT STDMETHODCALLTYPE CAddressEditBox::SetOwner(IUnknown *pOwner)
{
    if (!pOwner)
    {
        CComPtr<IBrowserService> browserService;
        HRESULT hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
        if (SUCCEEDED(hResult))
            AtlUnadvise(browserService, DIID_DWebBrowserEvents, fAdviseCookie);
        fSite = NULL; 
    }
    // connect to browser connection point
    return 0;
}
Example #8
0
HRESULT STDMETHODCALLTYPE CAddressEditBox::Init(HWND comboboxEx, HWND editControl, long param14, IUnknown *param18)
{
    CComPtr<IBrowserService> browserService;

    fCombobox.SubclassWindow(comboboxEx);
    fEditWindow.SubclassWindow(editControl);
    fSite = param18;

    SHAutoComplete(fEditWindow.m_hWnd, SHACF_FILESYSTEM | SHACF_URLALL | SHACF_USETAB);

    // take advice to watch events
    HRESULT hResult = IUnknown_QueryService(param18, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
    if (SUCCEEDED(hResult))
    {
        hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
    }

    return hResult;
}
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;
}
Example #10
0
HRESULT STDMETHODCALLTYPE CAddressEditBox::Execute(long paramC)
{
    HRESULT hr;

    /* 
     * Parse the path is it wasn't parsed
     */
    if (!pidlLastParsed)
        ParseNow(0);

    if (!pidlLastParsed)
        return E_FAIL;

    /* 
     * Get the IShellBrowser and IBrowserService interfaces of the shell browser 
     */
    CComPtr<IShellBrowser> pisb;
    hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pisb));
    if (FAILED(hr))
        return hr;

    CComPtr<IBrowserService> pbs;
    pisb->QueryInterface(IID_PPV_ARG(IBrowserService, &pbs));
    if (FAILED(hr))
        return hr;

    /*
     * Get the current pidl of the shellbrowser and check if it is the same with the parsed one
     */
    PIDLIST_ABSOLUTE pidl;
    hr = pbs->GetPidl(&pidl);
    if (FAILED(hr))
        return hr;

    CComPtr<IShellFolder> psf;
    hr = SHGetDesktopFolder(&psf);
    if (FAILED(hr))
        return hr;

    hr = psf->CompareIDs(0, pidl, pidlLastParsed);

    SHFree(pidl);
    if (hr == 0)
        return S_OK;

    /* 
     * Attempt to browse to the parsed pidl 
     */
    hr = pisb->BrowseObject(pidlLastParsed, 0);
    if (SUCCEEDED(hr))
        return hr;

    /* 
     * Browsing to the pidl failed so it's not a folder. So invoke its defaule command.
     */
    HWND topLevelWindow;
    hr = IUnknown_GetWindow(pisb, &topLevelWindow);
    if (FAILED(hr))
        return hr;

    LPCITEMIDLIST pidlChild;
    CComPtr<IShellFolder> sf;
    hr = SHBindToParent(pidlLastParsed, IID_PPV_ARG(IShellFolder, &sf), &pidlChild);
    if (FAILED(hr))
        return hr;

    hr = SHInvokeDefaultCommand(topLevelWindow, sf, pidlChild);
    if (FAILED(hr))
        return hr;

    return hr;
}
Example #11
0
bool BrowserFactory::AttachToBrowserUsingShellWindows(
    ProcessWindowInfo* process_window_info,
    std::string* error_message) {
    LOG(TRACE) << "Entering BrowserFactory::AttachToBrowserUsingShellWindows";

    CComPtr<IShellWindows> shell_windows;
    shell_windows.CoCreateInstance(CLSID_ShellWindows);

    CComPtr<IUnknown> enumerator_unknown;
    HRESULT hr = shell_windows->_NewEnum(&enumerator_unknown);
    if (FAILED(hr)) {
        LOGHR(WARN, hr) << "Unable to get enumerator from IShellWindows interface";
        return false;
    }

    clock_t end = clock() + (this->browser_attach_timeout_ / 1000 * CLOCKS_PER_SEC);

    CComPtr<IEnumVARIANT> enumerator;
    enumerator_unknown->QueryInterface<IEnumVARIANT>(&enumerator);
    while (process_window_info->hwndBrowser == NULL) {
        if (this->browser_attach_timeout_ > 0 && (clock() > end)) {
            break;
        }
        enumerator->Reset();
        for (CComVariant shell_window_variant;
                enumerator->Next(1, &shell_window_variant, NULL) == S_OK;
                shell_window_variant.Clear()) {

            if (shell_window_variant.vt != VT_DISPATCH) {
                continue;
            }

            CComPtr<IShellBrowser> shell_browser;
            hr = IUnknown_QueryService(shell_window_variant.pdispVal,
                                       SID_STopLevelBrowser,
                                       IID_PPV_ARGS(&shell_browser));
            if (shell_browser) {
                HWND hwnd;
                hr = shell_browser->GetWindow(&hwnd);
                if (SUCCEEDED(hr)) {
                    ::EnumChildWindows(hwnd,
                                       &BrowserFactory::FindChildWindowForProcess,
                                       reinterpret_cast<LPARAM>(process_window_info));
                    if (process_window_info->hwndBrowser != NULL) {
                        LOG(DEBUG) << "Found window handle "
                                   << process_window_info->hwndBrowser
                                   << " for window with class 'Internet Explorer_Server'"
                                   << " belonging to process with id "
                                   << process_window_info->dwProcessId;
                        CComPtr<IWebBrowser2> browser;
                        hr = shell_window_variant.pdispVal->QueryInterface<IWebBrowser2>(&browser);
                        if (FAILED(hr)) {
                            LOGHR(WARN, hr) << "Found browser window using ShellWindows "
                                            << "API, but QueryInterface for IWebBrowser2 "
                                            << "failed, so could not attach to the browser.";
                        } else {
                            process_window_info->pBrowser = browser.Detach();
                        }
                        break;
                    }
                }
            }
        }
        if (process_window_info->hwndBrowser == NULL ||
                process_window_info->pBrowser == NULL) {
            ::Sleep(250);
        }
    }

    if (process_window_info->hwndBrowser == NULL) {
        *error_message = StringUtilities::Format(ATTACH_TIMEOUT_ERROR_MESSAGE,
                         process_window_info->dwProcessId,
                         this->browser_attach_timeout_);
        return false;
    }

    if (process_window_info->pBrowser == NULL) {
        *error_message = ATTACH_FAILURE_ERROR_MESSAGE;
        return false;
    }
    return true;
}
Example #12
0
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;
}
Example #13
0
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;
}
Example #14
0
HRESULT STDMETHODCALLTYPE CAddressEditBox::ParseNow(long paramC)
{
    ULONG eaten;
    ULONG attributes;
    HRESULT hr;
    HWND topLevelWindow;
    PIDLIST_ABSOLUTE pidlCurrent= NULL;
    PIDLIST_RELATIVE pidlRelative = NULL;
    CComPtr<IShellFolder> psfCurrent;

    CComPtr<IBrowserService> pbs;
    hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &pbs));
    if (FAILED_UNEXPECTEDLY(hr))
        return hr;

    hr = IUnknown_GetWindow(pbs, &topLevelWindow);
    if (FAILED_UNEXPECTEDLY(hr))
        return hr;

    /* Get the path to browse and expand it if needed */
    LPWSTR input;
    int inputLength = fCombobox.GetWindowTextLength() + 2;

    input = new WCHAR[inputLength];
    fCombobox.GetWindowText(input, inputLength);

    LPWSTR address;
    int addressLength = ExpandEnvironmentStrings(input, NULL, 0);

    if (addressLength <= 0)
    {
        address = input;
    }
    else
    {
        addressLength += 2;
        address = new WCHAR[addressLength];
        if (!ExpandEnvironmentStrings(input, address, addressLength))
        {
            delete[] address;
            address = input;
        }
    }

    /* Try to parse a relative path and if it fails, try to browse an absolute path */
    CComPtr<IShellFolder> psfDesktop;
    hr = SHGetDesktopFolder(&psfDesktop);
    if (FAILED_UNEXPECTEDLY(hr))
        goto cleanup;

    hr = pbs->GetPidl(&pidlCurrent);
    if (FAILED_UNEXPECTEDLY(hr))
        goto cleanup;

    hr = psfDesktop->BindToObject(pidlCurrent, NULL, IID_PPV_ARG(IShellFolder, &psfCurrent));
    if (FAILED_UNEXPECTEDLY(hr))
        goto cleanup;

    hr = psfCurrent->ParseDisplayName(topLevelWindow, NULL, address, &eaten,  &pidlRelative, &attributes);
    if (SUCCEEDED(hr))
    {
        pidlLastParsed = ILCombine(pidlCurrent, pidlRelative);
        ILFree(pidlRelative);
        goto cleanup;
    }

    /* We couldn't parse a relative path, attempt to parse an absolute path */
    hr = psfDesktop->ParseDisplayName(topLevelWindow, NULL, address, &eaten, &pidlLastParsed, &attributes);

cleanup:
    if (pidlCurrent)
        ILFree(pidlCurrent);
    if (address != input)
        delete [] address;
    delete [] input;

    return hr;
}
Example #15
0
HRESULT STDMETHODCALLTYPE CAddressEditBox::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
    WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    CComPtr<IBrowserService> isb;
    CComPtr<IShellFolder> sf;
    HRESULT hr;
    INT indexClosed, indexOpen, itemExists, oldIndex;
    DWORD result;
    COMBOBOXEXITEMW item;
    PIDLIST_ABSOLUTE absolutePIDL;
    LPCITEMIDLIST pidlChild;
    LPITEMIDLIST pidlPrevious;
    STRRET ret;
    WCHAR buf[4096];

    if (pDispParams == NULL)
        return E_INVALIDARG;

    switch (dispIdMember)
    {
    case DISPID_NAVIGATECOMPLETE2:
    case DISPID_DOCUMENTCOMPLETE:
        pidlLastParsed = NULL;

        oldIndex = fCombobox.SendMessage(CB_GETCURSEL, 0, 0);

        itemExists = FALSE;
        pidlPrevious = NULL;

        ZeroMemory(&item, sizeof(item));
        item.mask = CBEIF_LPARAM;
        item.iItem = 0;
        if (fCombobox.SendMessage(CBEM_GETITEM, 0, reinterpret_cast<LPARAM>(&item)))
        {
            pidlPrevious = reinterpret_cast<LPITEMIDLIST>(item.lParam);
            if (pidlPrevious)
                itemExists = TRUE;
        }

        hr = IUnknown_QueryService(fSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &isb));
        if (FAILED_UNEXPECTEDLY(hr))
            return hr;

        hr = isb->GetPidl(&absolutePIDL);
        if (FAILED_UNEXPECTEDLY(hr))
            return hr;

        hr = SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild);
        if (FAILED_UNEXPECTEDLY(hr))
            return hr;

        hr = sf->GetDisplayNameOf(pidlChild, SHGDN_FORADDRESSBAR | SHGDN_FORPARSING, &ret);
        if (FAILED_UNEXPECTEDLY(hr))
            return hr;

        hr = StrRetToBufW(&ret, pidlChild, buf, 4095);
        if (FAILED_UNEXPECTEDLY(hr))
            return hr;

        indexClosed = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen);

        item.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM;
        item.iItem = 0;
        item.iImage = indexClosed;
        item.iSelectedImage = indexOpen;
        item.pszText = buf;
        item.lParam = reinterpret_cast<LPARAM>(absolutePIDL);

        if (itemExists)
        {
            result = fCombobox.SendMessage(CBEM_SETITEM, 0, reinterpret_cast<LPARAM>(&item));
            oldIndex = 0;

            if (result)
            {
                ILFree(pidlPrevious);
            }
        }
        else
        {
            oldIndex = fCombobox.SendMessage(CBEM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&item));

            if (oldIndex < 0)
                DbgPrint("ERROR %d\n", GetLastError());
        }

        fCombobox.SendMessage(CB_SETCURSEL, -1, 0);
        fCombobox.SendMessage(CB_SETCURSEL, oldIndex, 0);

        //fAddressEditBox->SetCurrentDir(index);
    }
    return S_OK;
}