|
|
#include "priv.h"
#include "caggunk.h"
#include "srchasst.h"
#include "dhuihand.h"
#include "mlang.h" // fo char conversion
#include "..\browseui\legacy.h" // for CITIDM_GETFOLDERSEARCHES
#include "varutil.h"
#include <wininet.h>
/////////////////////////////////////////////////////////////////////////////
// CSearchAssistantOC
// If you change this, change browseui also.
const WCHAR c_wszThisBandIsYourBand[] = L"$$SearchBand$$";
// HKLM values
#define REG_SZ_SEARCH L"Software\\Microsoft\\Internet Explorer\\Search"
#define REG_SZ_SEARCHASSIST L"SearchAssistant"
#define REG_SZ_SEARCHCFG L"CustomizeSearch"
// HKCU values
#define REG_SZ_IE_MAIN L"Software\\Microsoft\\Internet Explorer\\Main"
#define REG_SZ_IE_SEARCURL L"Software\\Microsoft\\Internet Explorer\\SearchURL"
#define REG_SZ_SEARCHBAR L"Search Bar"
#define REG_SZ_USECUSTOM L"Use Custom Search URL"
#define REG_SZ_AUTOSEARCH L"AutoSearch"
#define REG_SZ_PROVIDER L"Provider"
#define REG_SZ_USE_SEARCH_COMP L"Use Search Asst"
#define SAOC_VERSION 2
const WCHAR c_wszSearchProps[] = REG_SZ_SEARCH L"\\SearchProperties";
STDAPI_(VARIANT_BOOL) UseCustomInternetSearch() { VARIANT_BOOL bRet; DWORD dwVal; DWORD cbVal = sizeof(dwVal); if ((SHGetValueW(HKEY_CURRENT_USER, REG_SZ_IE_MAIN, REG_SZ_USECUSTOM, NULL, &dwVal, &cbVal) == ERROR_SUCCESS) && (FALSE != dwVal)) { bRet = VARIANT_TRUE; } else { bRet = VARIANT_FALSE; }
return bRet; }
STDAPI_(BOOL) GetSearchAssistantUrlW(LPWSTR pwszUrl, int cchUrl, BOOL bSubstitute, BOOL bCustomize) { BOOL bResult; WCHAR wszUrlTmp[MAX_URL_STRING]; WCHAR *pwszUrlRead; DWORD cb;
ASSERT(pwszUrl); *pwszUrl = 0;
if (bSubstitute) { cb = sizeof(wszUrlTmp); pwszUrlRead = wszUrlTmp; } else { cb = cchUrl * sizeof(WCHAR); pwszUrlRead = pwszUrl; } bResult = SHGetValueW(HKEY_LOCAL_MACHINE, REG_SZ_SEARCH, bCustomize ? REG_SZ_SEARCHCFG : REG_SZ_SEARCHASSIST, NULL, (BYTE *)pwszUrlRead, &cb) == ERROR_SUCCESS; if (bResult && bSubstitute) { bResult = SUCCEEDED(URLSubstitution(wszUrlTmp, pwszUrl, cchUrl, URLSUB_ALL)); }
return bResult; }
STDAPI_(BOOL) GetDefaultInternetSearchUrlW(LPWSTR pwszUrl, int cchUrl, BOOL bSubstitute) { BOOL bResult = FALSE; DWORD cb;
ASSERT(pwszUrl); *pwszUrl = 0;
if (UseCustomInternetSearch()) { // First try the user specific value
cb = cchUrl * sizeof(TCHAR); bResult = SHGetValueW(HKEY_CURRENT_USER, REG_SZ_IE_MAIN, REG_SZ_SEARCHBAR, NULL, (BYTE *)pwszUrl, &cb) == ERROR_SUCCESS; } if (!bResult) { bResult = GetSearchAssistantUrlW(pwszUrl, cchUrl, bSubstitute, FALSE); }
return bResult; }
STDAPI_(BOOL) GetSearchAssistantUrlA(LPSTR pszUrl, int cchUrl, BOOL bSubstitute, BOOL bCustomize) { WCHAR wszUrl[INTERNET_MAX_URL_LENGTH];
BOOL bResult = GetSearchAssistantUrlW(wszUrl, ARRAYSIZE(wszUrl), bSubstitute, bCustomize);
SHUnicodeToAnsi(wszUrl, pszUrl, cchUrl);
return bResult; }
STDAPI_(BOOL) GetDefaultInternetSearchUrlA(LPSTR pszUrl, int cchUrl, BOOL bSubstitute) { WCHAR wszUrl[INTERNET_MAX_URL_LENGTH];
BOOL bResult = GetDefaultInternetSearchUrlW(wszUrl, ARRAYSIZE(wszUrl), bSubstitute);
SHUnicodeToAnsi(wszUrl, pszUrl, cchUrl);
return bResult; }
void SetDefaultInternetSearchUrlW(LPCWSTR pwszUrl) { DWORD dwUseCustom = FALSE; DWORD cb; if ((NULL != pwszUrl) && (0 != *pwszUrl)) { cb = (lstrlenW(pwszUrl) + 1) * sizeof(WCHAR); if (SHSetValueW(HKEY_CURRENT_USER, REG_SZ_IE_MAIN, REG_SZ_SEARCHBAR, REG_SZ, pwszUrl, cb) == ERROR_SUCCESS) { dwUseCustom = TRUE; } }
cb = sizeof(dwUseCustom);
SHSetValueW(HKEY_CURRENT_USER, REG_SZ_IE_MAIN, REG_SZ_USECUSTOM, REG_DWORD, &dwUseCustom, cb); }
HRESULT CSearch_Create(GUID *pguid, BSTR bstrTitle, BSTR bstrUrl, ISearch **ppSearch) { HRESULT hres = E_INVALIDARG;
ASSERT(ppSearch); *ppSearch = NULL;
if (bstrTitle && bstrUrl && pguid) { BSTR _bstrTitle = SysAllocString(bstrTitle); BSTR _bstrUrl = SysAllocString(bstrUrl);
if (_bstrTitle && _bstrUrl) { CSearch *ps = new CSearch(pguid, _bstrTitle, _bstrUrl);
if (ps) { hres = ps->QueryInterface(IID_ISearch, (void **)ppSearch); ps->Release(); } } else { if (_bstrTitle) SysFreeString(_bstrTitle);
if (_bstrUrl) SysFreeString(_bstrUrl);
hres = E_OUTOFMEMORY; } } return hres; }
CSearch::CSearch(GUID *pguid, BSTR bstrTitle, BSTR bstrUrl) : _cRef(1), _bstrTitle(bstrTitle), _bstrUrl(bstrUrl), CImpIDispatch(LIBID_SHDocVw, 1, 1, IID_ISearch) { SHStringFromGUID(*pguid, _szId, ARRAYSIZE(_szId)); }
CSearch::~CSearch() { if (_bstrTitle) SysFreeString(_bstrTitle);
if (_bstrUrl) SysFreeString(_bstrUrl); }
STDMETHODIMP CSearch::QueryInterface(REFIID riid, void** ppv) { static const QITAB qit[] = { QITABENT(CSearch, ISearch), QITABENTMULTI(CSearch, IDispatch, ISearch), { 0 }, };
return QISearch(this, qit, riid, ppv); }
STDMETHODIMP_(ULONG) CSearch::AddRef() { InterlockedIncrement(&_cRef); return _cRef; }
STDMETHODIMP_(ULONG) CSearch::Release() { if (InterlockedDecrement(&_cRef) > 0) return _cRef;
delete this; return 0; }
HRESULT CSearch::get_Title(BSTR *pbstrTitle) { HRESULT hres = NOERROR; *pbstrTitle = SysAllocString(_bstrTitle); if (!*pbstrTitle) hres = E_OUTOFMEMORY;
return hres; }
HRESULT CSearch::get_Id(BSTR *pbstrId) { HRESULT hres = NOERROR;
*pbstrId = SysAllocString(_szId); if (!*pbstrId) hres = E_OUTOFMEMORY;
return hres; }
HRESULT CSearch::get_Url(BSTR *pbstrUrl) { HRESULT hres = NOERROR; *pbstrUrl = SysAllocString(_bstrUrl); if (!*pbstrUrl) hres = E_OUTOFMEMORY;
return hres; }
HRESULT CSearchCollection_Create(IFolderSearches *pfs, ISearches **ppSearches) { HRESULT hres = E_INVALIDARG; ASSERT(ppSearches); *ppSearches = NULL;
if (pfs) { CSearchCollection *psc = new CSearchCollection(pfs);
if (psc) { hres = psc->QueryInterface(IID_ISearches, (void **)ppSearches); psc->Release(); } else hres = E_OUTOFMEMORY; } return hres; }
CSearchCollection::CSearchCollection(IFolderSearches *pfs) : _cRef(1), CImpIDispatch(LIBID_SHDocVw, 1, 1, IID_ISearches) { GUID guid;
if (SUCCEEDED(pfs->DefaultSearch(&guid))) SHStringFromGUID(guid, _szDefault, ARRAYSIZE(_szDefault)); _hdsaItems = DSA_Create(SIZEOF(URLSEARCH), 4); if (_hdsaItems) { IEnumUrlSearch *penum;
if (SUCCEEDED(pfs->EnumSearches(&penum))) { URLSEARCH us; ULONG cElt;
penum->Reset(); while (S_OK == penum->Next(1, &us, &cElt) && 1 == cElt) DSA_AppendItem(_hdsaItems, &us);
penum->Release(); } } }
CSearchCollection::~CSearchCollection() { DSA_Destroy(_hdsaItems); _hdsaItems = NULL; }
STDMETHODIMP CSearchCollection::QueryInterface(REFIID riid, void** ppv) { static const QITAB qit[] = { QITABENT(CSearchCollection, ISearches), QITABENTMULTI(CSearchCollection, IDispatch, ISearches), { 0 }, };
return QISearch(this, qit, riid, ppv); }
STDMETHODIMP_(ULONG) CSearchCollection::AddRef() { InterlockedIncrement(&_cRef); return _cRef; }
STDMETHODIMP_(ULONG) CSearchCollection::Release() { if (InterlockedDecrement(&_cRef) > 0) return _cRef;
delete this; return 0; }
STDMETHODIMP CSearchCollection::get_Count(long *plCount) { *plCount = 0; if (_hdsaItems) { *plCount = DSA_GetItemCount(_hdsaItems); } return S_OK; }
STDMETHODIMP CSearchCollection::get_Default(BSTR *pbstrDefault) { HRESULT hres = E_OUTOFMEMORY; *pbstrDefault = SysAllocString(_szDefault); if (*pbstrDefault) hres = S_OK; return hres; }
STDMETHODIMP CSearchCollection::Item(VARIANT index, ISearch **ppid) { HRESULT hres = E_NOTIMPL; *ppid = NULL; switch (index.vt) { case VT_I2: index.lVal = (long)index.iVal; // And fall through...
case VT_I4: if ((index.lVal >= 0) && (index.lVal < DSA_GetItemCount(_hdsaItems))) { LPURLSEARCH pus;
pus = (LPURLSEARCH)DSA_GetItemPtr(_hdsaItems, index.lVal); ASSERT(pus); hres = CSearch_Create(&pus->guid, pus->wszName, pus->wszUrl, ppid); }
break; #if 0
// should we worry about this one?
case VT_BSTR: #endif
}
return hres; }
STDMETHODIMP CSearchCollection::_NewEnum(IUnknown **ppunk) { *ppunk = NULL; return E_NOTIMPL; }
CSearchAssistantOC::CSearchAssistantOC() : m_punkSite(NULL) { #ifdef UNIX
m_dwSafety = 0; #endif
}
CSearchAssistantOC::~CSearchAssistantOC() { ATOMICRELEASE(m_pSearchBandTBHelper); ATOMICRELEASE(m_punkSite); }
HRESULT CSearchAssistantOC::OnDraw(ATL_DRAWINFO& di) { return S_OK; }
STDMETHODIMP CSearchAssistantOC::SetClientSite(IOleClientSite *pClientSite) { if (NULL != pClientSite) { HRESULT hr; IWebBrowser2 *pWebBrowser2;
hr = IUnknown_QueryService(pClientSite, SID_SWebBrowserApp, IID_IWebBrowser2, (void **)&pWebBrowser2); if (SUCCEEDED(hr)) { BSTR bstrProp = SysAllocString(c_wszThisBandIsYourBand); if (bstrProp) { VARIANT var; hr = pWebBrowser2->GetProperty(bstrProp, &var); if (SUCCEEDED(hr)) { if (var.vt == VT_UNKNOWN) { ATOMICRELEASE(m_pSearchBandTBHelper);
hr = var.punkVal->QueryInterface(IID_ISearchBandTBHelper, (void **)&m_pSearchBandTBHelper); ASSERT(SUCCEEDED(hr));
if (m_pSearchBandTBHelper) m_pSearchBandTBHelper->SetOCCallback(this); }
VariantClear(&var); }
SysFreeString(bstrProp); } pWebBrowser2->Release(); } } else { if (NULL != m_pSearchBandTBHelper) { m_pSearchBandTBHelper->SetOCCallback(NULL); ATOMICRELEASE(m_pSearchBandTBHelper); } } return IOleObjectImpl<CSearchAssistantOC>::SetClientSite(pClientSite); }
STDMETHODIMP CSearchAssistantOC::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) { return E_NOTIMPL; } STDMETHODIMP CSearchAssistantOC::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) { HRESULT hr = E_UNEXPECTED; if (NULL == pguidCmdGroup) { switch (nCmdID) { case SBID_SEARCH_NEXT: if ((NULL != pvaIn) && (pvaIn->vt == VT_I4)) { Fire_OnNextMenuSelect(pvaIn->lVal);
hr = S_OK; } else { hr = E_INVALIDARG; } break;
case SBID_SEARCH_NEW: if (NULL != pvaOut) { m_bEventHandled = VARIANT_FALSE;
Fire_OnNewSearch();
pvaOut->vt = VT_BOOL; pvaOut->boolVal = m_bEventHandled;
hr = S_OK; } else { hr = E_INVALIDARG; } break; } }
return hr; }
STDMETHODIMP CSearchAssistantOC::AddNextMenuItem(BSTR bstrText, long idItem) { HRESULT hr;
if (IsTrustedSite()) { if (NULL != m_pSearchBandTBHelper) { hr = m_pSearchBandTBHelper->AddNextMenuItem(bstrText, idItem);
ASSERT(SUCCEEDED(hr));
} hr = S_OK; } else { hr = E_ACCESSDENIED; } return hr; }
STDMETHODIMP CSearchAssistantOC::ResetNextMenu() { HRESULT hr;
if (IsTrustedSite()) { if (NULL != m_pSearchBandTBHelper) { hr = m_pSearchBandTBHelper->ResetNextMenu(); ASSERT(SUCCEEDED(hr)); } hr = S_OK; } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::SetDefaultSearchUrl(BSTR bstrUrl) { HRESULT hr; if (IsTrustedSite()) { SetDefaultInternetSearchUrlW(bstrUrl); hr = S_OK; } else { hr = E_ACCESSDENIED; } return hr; }
STDMETHODIMP CSearchAssistantOC::NavigateToDefaultSearch() { HRESULT hr;
IWebBrowser2 *pWebBrowser2;
hr = IUnknown_QueryService(m_spClientSite, SID_SWebBrowserApp, IID_IWebBrowser2, (void **)&pWebBrowser2); if (SUCCEEDED(hr)) { WCHAR wszUrl[INTERNET_MAX_URL_LENGTH];
if (GetDefaultInternetSearchUrlW(wszUrl, ARRAYSIZE(wszUrl), TRUE)) { BSTR bstrUrl = SysAllocString(wszUrl);
if (NULL != bstrUrl) { VARIANT varFrame; varFrame.vt = VT_BSTR; varFrame.bstrVal = SysAllocString(L"_search"); if (NULL != varFrame.bstrVal) { hr = pWebBrowser2->Navigate(bstrUrl, NULL, &varFrame, NULL, NULL);
ASSERT(SUCCEEDED(hr));
SysFreeString(varFrame.bstrVal); }
SysFreeString(bstrUrl); } } pWebBrowser2->Release(); } return S_OK; }
typedef struct _GUIDREST { const GUID * pguid; RESTRICTIONS rest; } GUIDREST;
HRESULT CSearchAssistantOC::IsRestricted(BSTR bstrGuid, VARIANT_BOOL *pVal) { HRESULT hr; GUID guid;
if (IsTrustedSite()) { *pVal = VARIANT_FALSE; // default to not restricted
if (SUCCEEDED(SHCLSIDFromString(bstrGuid, &guid))) { // find computer is special because if it restricted then we show
// it else don't show it (restriction name is HASFINDCOMPUTER
if (IsEqualGUID(guid, SRCID_SFindComputer)) { if (!SHRestricted(REST_HASFINDCOMPUTERS)) *pVal = VARIANT_TRUE; } else { static GUIDREST agr[] = { {&SRCID_SFileSearch, REST_NOFIND}, // rest_nofindprinter does not exist yet
//{&SRCID_SFindPrinter, REST_NOFINDPRINTER},
};
for (int i=0; i < ARRAYSIZE(agr); i++) { if (IsEqualGUID(guid, *agr[i].pguid)) { if (SHRestricted(agr[i].rest)) *pVal = VARIANT_TRUE; break; } } } } hr = S_OK; } else { hr = E_ACCESSDENIED; }
return hr; }
HRESULT CSearchAssistantOC::get_ShellFeaturesEnabled(VARIANT_BOOL *pVal) { HRESULT hr; if (IsTrustedSite()) { if (pVal) { *pVal = (GetUIVersion() >= 5) ? VARIANT_TRUE : VARIANT_FALSE; hr = S_OK; } else { hr = E_INVALIDARG; } } else { hr = E_ACCESSDENIED; } return hr; }
HRESULT CSearchAssistantOC::get_SearchAssistantDefault(VARIANT_BOOL *pVal) { HRESULT hr;
if (IsTrustedSite()) { if (pVal) { *pVal = !UseCustomInternetSearch(); hr = S_OK; } else { hr = E_INVALIDARG; } } else { hr = E_ACCESSDENIED; } return hr; }
STDMETHODIMP CSearchAssistantOC::get_Searches(ISearches **ppid) { HRESULT hr; *ppid = NULL;
if (IsTrustedSite()) { IServiceProvider *psp; hr = IUnknown_QueryService(m_spClientSite, SID_STopLevelBrowser, IID_IServiceProvider, (void**)&psp); if (SUCCEEDED(hr)) { IOleCommandTarget *pct;
hr = psp->QueryService(SID_SExplorerToolbar, IID_IOleCommandTarget, (void **)&pct); if (SUCCEEDED(hr)) { VARIANTARG var = {0}; hr = pct->Exec(&CGID_PrivCITCommands, CITIDM_GETFOLDERSEARCHES, 0, NULL, &var); if (SUCCEEDED(hr)) { IFolderSearches *pfs;
ASSERT(var.vt == VT_UNKNOWN && var.punkVal); hr = var.punkVal->QueryInterface(IID_IFolderSearches, (void **)&pfs); if (SUCCEEDED(hr)) { hr = CSearchCollection_Create(pfs, ppid); pfs->Release(); } var.punkVal->Release(); } pct->Release(); hr = S_OK; }
psp->Release(); } } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::get_InWebFolder(VARIANT_BOOL *pVal) { HRESULT hr;
if (IsTrustedSite()) { ASSERT(pVal); *pVal = VARIANT_FALSE;
IBrowserService2 *pbs; hr = IUnknown_QueryService(m_spClientSite, SID_STopLevelBrowser, IID_IBrowserService2, (void **)&pbs);
if (SUCCEEDED(hr)) { ITEMIDLIST *pidl;
hr = pbs->GetPidl(&pidl);
if (SUCCEEDED(hr)) { // REARCHITECT: Don't use ILIsWeb(). We should use IShellFolder2::GetDefaultSearchGUID() and
// test for SRCID_SWebSearch vs. SRCID_SFileSearch/SRCID_SFindComputer/SRCID_SFindPrinter.
// This is because Shell Extensions need a way to indicate what kind of search they want
// and ILIsWeb() doesn't provide that. An example of this is "Web Folders" won't return
// TRUE from ILIsWeb(). The use of ILIsWeb() should be limited.
if (ILIsWeb(pidl)) { *pVal = VARIANT_TRUE; } ILFree(pidl); } pbs->Release(); } hr = S_OK; } else { hr = E_ACCESSDENIED; } return hr; }
void GetPerLocalePath(WCHAR *pwszKeyName, int cchKeyName) { ASSERT(cchKeyName >= (ARRAYSIZE(c_wszSearchProps) + 1)); StrCpyNW(pwszKeyName, c_wszSearchProps, cchKeyName); *(pwszKeyName + (ARRAYSIZE(c_wszSearchProps) - 1)) = L'\\';
GetWebLocaleAsRFC1766(pwszKeyName + ARRAYSIZE(c_wszSearchProps), cchKeyName - (ARRAYSIZE(c_wszSearchProps))); }
STDMETHODIMP CSearchAssistantOC::PutProperty(VARIANT_BOOL bPerLocale, BSTR bstrName, BSTR bstrValue) { HRESULT hr;
if (IsTrustedSite()) { HKEY hkey; LPCWSTR pwszKeyName; WCHAR wszKeyName[MAX_PATH]; DWORD dwDisposition;
if (bPerLocale) { GetPerLocalePath(wszKeyName, ARRAYSIZE(wszKeyName)); pwszKeyName = wszKeyName; } else { pwszKeyName = c_wszSearchProps; }
if (RegCreateKeyExW(HKEY_CURRENT_USER, pwszKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dwDisposition) == ERROR_SUCCESS) { if ((NULL != bstrValue) && (bstrValue[0] != 0)) { RegSetValueExW(hkey, bstrName, 0, REG_BINARY, (LPBYTE)bstrValue, SysStringByteLen(bstrValue)); } else { // Empty or NULL string means remove the property
RegDeleteValue(hkey, bstrName); } RegCloseKey(hkey); } hr = S_OK; } else { hr = E_ACCESSDENIED; } return hr; }
STDMETHODIMP CSearchAssistantOC::GetProperty(VARIANT_BOOL bPerLocale, BSTR bstrName, BSTR *pbstrValue) { HRESULT hr;
if (NULL != pbstrValue) { *pbstrValue = NULL; if (IsTrustedSite()) { HKEY hkey; LPCWSTR pwszKeyName; WCHAR wszKeyName[MAX_PATH];
if (bPerLocale) { GetPerLocalePath(wszKeyName, ARRAYSIZE(wszKeyName)); pwszKeyName = wszKeyName; } else { pwszKeyName = c_wszSearchProps; }
if (RegOpenKeyExW(HKEY_CURRENT_USER, pwszKeyName, 0, KEY_READ, &hkey) == ERROR_SUCCESS) { DWORD dwType; DWORD cbSize; if ((RegQueryValueExW(hkey, bstrName, NULL, &dwType, NULL, &cbSize) == ERROR_SUCCESS) && (dwType == REG_BINARY)) { BSTR bstrValue = SysAllocStringByteLen(NULL, cbSize);
if (NULL != bstrValue) { if (RegQueryValueExW(hkey, bstrName, NULL, &dwType, (LPBYTE)bstrValue, &cbSize) == ERROR_SUCCESS) { *pbstrValue = bstrValue; } else { SysFreeString(bstrValue); } } } RegCloseKey(hkey); } hr = S_OK; } else { hr = E_ACCESSDENIED; } } else { hr = E_INVALIDARG; } return hr; }
STDMETHODIMP CSearchAssistantOC::put_EventHandled(VARIANT_BOOL bHandled) { HRESULT hr; if (IsTrustedSite()) { m_bEventHandled = bHandled; hr = S_OK; } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::GetSearchAssistantURL(VARIANT_BOOL bSubstitute, VARIANT_BOOL bCustomize, BSTR *pbstrValue) { HRESULT hr; if (IsTrustedSite()) { if (NULL != pbstrValue) { WCHAR wszUrl[INTERNET_MAX_URL_LENGTH];
if (GetSearchAssistantUrlW(wszUrl, ARRAYSIZE(wszUrl), bSubstitute, bCustomize)) { *pbstrValue = SysAllocString(wszUrl); } hr = S_OK; } else { hr = E_INVALIDARG; } } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::NotifySearchSettingsChanged() { HRESULT hr; if (IsTrustedSite()) { SendShellIEBroadcastMessage(WM_WININICHANGE, 0, (LPARAM)SEARCH_SETTINGS_CHANGED, 3000); hr = S_OK; } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::put_ASProvider(BSTR Provider) { HRESULT hr; if (IsTrustedSite()) { if (Provider) { DWORD dwRet = SHSetValueW(HKEY_CURRENT_USER, REG_SZ_IE_SEARCURL, REG_SZ_PROVIDER, REG_SZ, Provider, (lstrlenW(Provider) + 1) * sizeof(WCHAR));
ASSERT(ERROR_SUCCESS == dwRet); } hr = S_OK; } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::get_ASProvider(BSTR *pProvider) { HRESULT hr; if (IsTrustedSite()) { if (NULL != pProvider) { HKEY hkey;
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CURRENT_USER, REG_SZ_IE_SEARCURL, 0, KEY_READ, &hkey)) { DWORD dwType; DWORD dwSize; if ((ERROR_SUCCESS == RegQueryValueExW(hkey, REG_SZ_PROVIDER, NULL, &dwType, NULL, &dwSize)) && (REG_SZ == dwType)) { *pProvider = SysAllocStringByteLen(NULL, dwSize); if (NULL != *pProvider) { if (ERROR_SUCCESS != RegQueryValueExW(hkey, REG_SZ_PROVIDER, NULL, &dwType, (LPBYTE)*pProvider, &dwSize)) { *pProvider = 0; } } } RegCloseKey(hkey); } hr = S_OK; } else { hr = E_INVALIDARG; } } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::put_ASSetting(int Setting) { HRESULT hr; if (IsTrustedSite()) { DWORD dwRet = SHSetValueW(HKEY_CURRENT_USER, REG_SZ_IE_MAIN, REG_SZ_AUTOSEARCH, REG_DWORD, &Setting, sizeof(DWORD));
ASSERT(ERROR_SUCCESS == dwRet); hr = S_OK; } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::get_ASSetting(int *pSetting) { HRESULT hr; if (IsTrustedSite()) { if (NULL != pSetting) { DWORD dwSize = sizeof(int);
*pSetting = -1; DWORD dwRet = SHGetValueW(HKEY_CURRENT_USER, REG_SZ_IE_MAIN, REG_SZ_AUTOSEARCH, NULL, pSetting, &dwSize);
hr = S_OK; } else { hr = E_INVALIDARG; } } else { hr = E_ACCESSDENIED; }
return hr; }
BOOL CSearchAssistantOC::IsTrustedSite() { if (!m_bSafetyInited && m_spClientSite) { m_bSafetyInited = TRUE;
IHTMLDocument2 *pHTMLDocument2; HRESULT hr = GetHTMLDoc2(m_spClientSite, &pHTMLDocument2);
if (SUCCEEDED(hr)) { ASSERT(NULL != pHTMLDocument2);
IHTMLLocation *pHTMLLocation;
hr = pHTMLDocument2->get_location(&pHTMLLocation);
if (SUCCEEDED(hr) && (NULL != pHTMLLocation)) { BSTR bstrUrl;
pHTMLLocation->get_href(&bstrUrl);
if (SUCCEEDED(hr) && (NULL != bstrUrl)) { HKEY hkey; // FEATURE (tnoonan)
// This code is duped with CSearchBand::_IsSafeUrl in browseui
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\SafeSites", 0, KEY_READ, &hkey) == ERROR_SUCCESS) { WCHAR wszValue[MAX_PATH]; WCHAR wszData[MAX_URL_STRING]; WCHAR wszExpandedUrl[MAX_URL_STRING]; DWORD cbData = SIZEOF(wszData); DWORD cchValue = ARRAYSIZE(wszValue);
for (int i=0; RegEnumValueW(hkey, i, wszValue, &cchValue, NULL, NULL, (LPBYTE)wszData, &cbData) == ERROR_SUCCESS; i++) { if (SHExpandEnvironmentStringsW(wszData, wszExpandedUrl, ARRAYSIZE(wszExpandedUrl)) > 0) { cchValue = ARRAYSIZE(wszExpandedUrl); if (SUCCEEDED(UrlCanonicalizeW(wszExpandedUrl, wszExpandedUrl, &cchValue, 0))) { if (cchValue > 0) { BOOL bRet; if (wszExpandedUrl[cchValue-1] == L'*') { bRet = StrCmpNIW(bstrUrl, wszExpandedUrl, cchValue - 1) == 0; } else { bRet = StrCmpIW(bstrUrl, wszExpandedUrl) == 0; }
m_bIsTrustedSite = bRet ? TRUE : FALSE; if (m_bIsTrustedSite) break; } } cbData = SIZEOF(wszData); cchValue = ARRAYSIZE(wszValue); } } RegCloseKey(hkey); }
SysFreeString(bstrUrl); } pHTMLLocation->Release(); } pHTMLDocument2->Release(); } }
return m_bIsTrustedSite; }
HRESULT CSearchAssistantOC::UpdateRegistry(BOOL bRegister) { //this control uses selfreg.inx, not the ATL registry goo
return S_OK; }
STDMETHODIMP CSearchAssistantOC::FindOnWeb() { if (!IsTrustedSite() && m_punkSite==NULL) return E_ACCESSDENIED ;
return ShowSearchBand( SRCID_SWebSearch ) ; }
STDMETHODIMP CSearchAssistantOC::FindFilesOrFolders() { if (!IsTrustedSite() && m_punkSite==NULL) return E_ACCESSDENIED ;
return ShowSearchBand( SRCID_SFileSearch ) ; }
STDMETHODIMP CSearchAssistantOC::FindComputer() { if (!IsTrustedSite() && m_punkSite==NULL) return E_ACCESSDENIED ;
return ShowSearchBand( SRCID_SFindComputer ) ; }
STDMETHODIMP CSearchAssistantOC::FindPrinter() { if (!IsTrustedSite() && m_punkSite==NULL) return E_ACCESSDENIED ;
HRESULT hr = E_FAIL; IShellDispatch2* psd2; if( SUCCEEDED( (hr = CoCreateInstance( CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch2, (void**)&psd2 )) ) ) { hr = psd2->FindPrinter( NULL, NULL, NULL ) ; psd2->Release(); } return hr ; }
STDMETHODIMP CSearchAssistantOC::FindPeople() { if (!IsTrustedSite() && m_punkSite==NULL) { return E_ACCESSDENIED; }
SHELLEXECUTEINFO sei = {0}; sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.hwnd = HWND_DESKTOP; sei.lpVerb = TEXT("open"); sei.lpFile = TEXT("wab.exe"); sei.lpParameters = TEXT("/find"); sei.lpDirectory = NULL; sei.nShow = SW_SHOWNORMAL;
if (!ShellExecuteEx(&sei)) { return HRESULT_FROM_WIN32(GetLastError()); } else { return S_OK; } }
// Wininet helper method to retry autodetection
// check to make sure that the hosting page is on
// the local computer.
// stolen from the zones code by joshco
//
STDMETHODIMP CSearchAssistantOC::LocalZoneCheck( ) { HRESULT hr = E_ACCESSDENIED;
// Return S_FALSE if we don't have a host site since we have no way of doing a
// security check. This is as far as VB 5.0 apps get.
if (!m_spClientSite) return S_FALSE;
// 1) Get an IHTMLDocument2 pointer
// 2) Get URL from doc
// 3) Create security manager
// 4) Check if doc URL zone is local, if so everything's S_OK
// 5) Otherwise, get and compare doc URL SID to requested URL SID
IHTMLDocument2 *pHtmlDoc; if (SUCCEEDED(GetHTMLDoc2(m_spClientSite, &pHtmlDoc))) { ASSERT(pHtmlDoc); BSTR bstrDocUrl; if (SUCCEEDED(pHtmlDoc->get_URL(&bstrDocUrl))) { ASSERT(bstrDocUrl); IInternetSecurityManager *pSecMgr;
if (SUCCEEDED(CoCreateInstance(CLSID_InternetSecurityManager, NULL, CLSCTX_INPROC_SERVER, IID_IInternetSecurityManager, (void **)&pSecMgr))) { ASSERT(pSecMgr); DWORD dwZoneID = URLZONE_UNTRUSTED; if (SUCCEEDED(pSecMgr->MapUrlToZone(bstrDocUrl, &dwZoneID, 0))) { if (dwZoneID == URLZONE_LOCAL_MACHINE) hr = S_OK; } pSecMgr->Release(); } SysFreeString(bstrDocUrl); } pHtmlDoc->Release(); } else { // If we don't have an IHTMLDocument2 we aren't running in a browser that supports
// our OM. We shouldn't block in this case since we could potentially
// get here from other hosts (VB, WHS, etc.).
hr = S_FALSE; }
return hr; }
// set flags so that the next navigate will cause
// a proxy autodetection cycle
// used in dnserr.htm along with location.reload.
// added by joshco
//
STDMETHODIMP CSearchAssistantOC::NETDetectNextNavigate() { HRESULT hr = S_FALSE;
CHAR szConnectionName[100]; DWORD dwBufLen; DWORD dwFlags; BOOL fResult;
if ( LocalZoneCheck() != S_OK ) { // some security problem.. time to bail.
hr=E_ACCESSDENIED; goto error; }
dwBufLen = sizeof(szConnectionName);
// find the connection name via internetconnected state
fResult = InternetGetConnectedStateExA(&dwFlags, szConnectionName,dwBufLen, 0 );
INTERNET_PER_CONN_OPTION_LISTA list; INTERNET_PER_CONN_OPTIONA option; list.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LISTA); if(!fResult || (dwFlags & INTERNET_CONNECTION_LAN)) { list.pszConnection = NULL; } else { list.pszConnection = szConnectionName; }
list.dwOptionCount = 1; list.pOptions = &option; option.dwOption = INTERNET_PER_CONN_FLAGS; dwBufLen= sizeof(list);
// now call internetsetoption to do it..
// first set this connectoid to enable autodetect
if ( ! InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION , &list,&dwBufLen) ) { goto error; } option.Value.dwValue |= PROXY_TYPE_AUTO_DETECT ;
if ( ! InternetSetOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION , &list,sizeof(list))) { goto error; }
if ( ! InternetInitializeAutoProxyDll(0) ) { goto error; }
// Now set the autodetect flags for this connectoid to
// do a passive detect and shut itself off if it doesnt work
option.dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS; if ( ! InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION , &list,&dwBufLen) ) { goto error; } option.Value.dwValue &= ~(AUTO_PROXY_FLAG_DETECTION_RUN) ;
if ( ! InternetSetOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION , &list,sizeof(list))) { goto error; }
if ( ! InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED,NULL, 0) ) { goto error; }
hr=S_OK; error: ; return hr; }
STDMETHODIMP CSearchAssistantOC::PutFindText(BSTR FindText) { HRESULT hr; if (IsTrustedSite()) { IServiceProvider *pServiceProvider; hr = IUnknown_QueryService(m_pSearchBandTBHelper, SID_SProxyBrowser, IID_IServiceProvider, (void **)&pServiceProvider); if (SUCCEEDED(hr)) { IWebBrowser2 *pWebBrowser2; hr = pServiceProvider->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (void **)&pWebBrowser2); if (SUCCEEDED(hr)) { ::PutFindText(pWebBrowser2, FindText); pWebBrowser2->Release(); } pServiceProvider->Release(); } hr = S_OK; } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::get_Version(int *pVersion) { if (NULL != pVersion) { *pVersion = SAOC_VERSION; } return S_OK; }
// x_hex_digit and URLEncode were stolen from trident
inline int x_hex_digit(int c) { if (c >= 0 && c <= 9) { return c + '0'; } if (c >= 10 && c <= 15) { return c - 10 + 'A'; } return '0'; }
/*
The following array was copied directly from NCSA Mosaic 2.2 */ static const unsigned char isAcceptable[96] = /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, /* 2x !"#$%&'()*+,-./ */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x 0123456789:;<=>? */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x @ABCDEFGHIJKLMNO */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x PQRSTUVWXYZ[\]^_ */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x `abcdefghijklmno */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}; /* 7x pqrstuvwxyz{\}~
DEL */
// Performs URL-encoding of null-terminated strings. Pass NULL in pbOut
// to find buffer length required. Note that '\0' is not written out.
int URLEncode(char * pbOut, const char * pchIn) { int lenOut = 0; char * pchOut = pbOut;
ASSERT(pchIn);
for (; *pchIn; pchIn++, lenOut++) { if (*pchIn == ' ') { if (pchOut) *pchOut++ = '+'; } else if (*pchIn >= 32 && *pchIn <= 127 && isAcceptable[*pchIn - 32]) { if (pchOut) *pchOut++ = *pchIn; } else { if (pchOut) *pchOut++ = '%'; lenOut++;
if (pchOut) *pchOut++ = (char)x_hex_digit((*pchIn >> 4) & 0xf); lenOut++;
if (pchOut) *pchOut++ = (char)x_hex_digit(*pchIn & 0xf); } } return lenOut; }
STDMETHODIMP CSearchAssistantOC::EncodeString(BSTR bstrValue, BSTR bstrCharSet, VARIANT_BOOL bUseUTF8, BSTR *pbstrResult) {
if ((NULL != bstrValue) && (NULL != pbstrResult)) { HRESULT hr; IMultiLanguage2 *pMultiLanguage2;
*pbstrResult = NULL; hr = CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (void**)&pMultiLanguage2);
if (SUCCEEDED(hr)) { UINT uiCodePage = CP_BOGUS; UINT cchVal = SysStringLen(bstrValue); DWORD dwMode = 0;
if (!bUseUTF8) { // We're not using UTF so try and get the code page from the
// charset.
MIMECSETINFO info; hr = pMultiLanguage2->GetCharsetInfo(bstrCharSet, &info);
if (SUCCEEDED(hr)) { hr = pMultiLanguage2->ConvertStringFromUnicodeEx(&dwMode, info.uiCodePage, bstrValue, &cchVal, NULL, NULL, MLCONVCHARF_NOBESTFITCHARS, NULL); if (S_OK == hr) { uiCodePage = info.uiCodePage; } } } else { uiCodePage = CP_UTF_8; }
if (uiCodePage == CP_BOGUS) { // we have characters which don't work in the charset or the charset
// is unknown to MLang, maybe MLang can figure out a code page to use.
IMLangCodePages *pMLangCodePages;
// When all else fails...
uiCodePage = CP_ACP;
hr = pMultiLanguage2->QueryInterface(IID_IMLangCodePages, (void **)&pMLangCodePages); if (SUCCEEDED(hr)) { DWORD dwCodePages = 0; long cchProcessed = 0; UINT uiTmpCP = 0; if (SUCCEEDED(pMLangCodePages->GetStrCodePages(bstrValue, cchVal, 0, &dwCodePages, &cchProcessed))
&&
SUCCEEDED(pMLangCodePages->CodePagesToCodePage(dwCodePages, 0, &uiTmpCP))) { uiCodePage = uiTmpCP; }
pMLangCodePages->Release(); } }
dwMode = 0;
UINT cbVal = 0;
// Ask MLang how big of a buffer we need
hr = pMultiLanguage2->ConvertStringFromUnicode(&dwMode, uiCodePage, bstrValue, &cchVal, NULL, &cbVal);
if (SUCCEEDED(hr)) { CHAR *pszValue = new CHAR[cbVal + 1];
if (NULL != pszValue) { // Really convert the string
hr = pMultiLanguage2->ConvertStringFromUnicode(&dwMode, uiCodePage, bstrValue, &cchVal, pszValue, &cbVal); if (SUCCEEDED(hr)) { pszValue[cbVal] = 0; int cbEncVal = URLEncode(NULL, pszValue); CHAR *pszEncVal = new CHAR[cbEncVal];
if (NULL != pszEncVal) { URLEncode(pszEncVal, pszValue);
int cchResult = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszEncVal, cbEncVal, NULL, 0);
*pbstrResult = SysAllocStringLen(NULL, cchResult);
if (NULL != *pbstrResult) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszEncVal, cbEncVal, *pbstrResult, cchResult); }
delete [] pszEncVal; } } delete [] pszValue; } } pMultiLanguage2->Release(); } }
return S_OK; }
STDMETHODIMP CSearchAssistantOC::get_ShowFindPrinter(VARIANT_BOOL *pbShowFindPrinter) { HRESULT hr;
if (IsTrustedSite()) { if (NULL != pbShowFindPrinter) { IShellDispatch2* psd;
*pbShowFindPrinter = VARIANT_FALSE;
if (SUCCEEDED(CoCreateInstance(CLSID_Shell, 0, CLSCTX_INPROC_SERVER, IID_IShellDispatch2, (void**)&psd))) { BSTR bstrName = SysAllocString( L"DirectoryServiceAvailable");
if (bstrName) { VARIANT varRet = {0}; if (SUCCEEDED(psd->GetSystemInformation(bstrName, &varRet))) { ASSERT(VT_BOOL == varRet.vt); *pbShowFindPrinter = varRet.boolVal; } SysFreeString(bstrName); } psd->Release(); } hr = S_OK; } else { hr = E_INVALIDARG; } } else { hr = E_ACCESSDENIED; }
return hr; }
STDMETHODIMP CSearchAssistantOC::get_SearchCompanionAvailable(VARIANT_BOOL *pbAvailable) { HRESULT hr = E_ACCESSDENIED; if (IsTrustedSite()) { if (pbAvailable != NULL) { BOOL fSCAvailable = FALSE; // need to determine if search companion is available on system and supports user locale
ISearchCompanionInfo* psci; hr = CoCreateInstance(CLSID_SearchCompanionInfo, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(ISearchCompanionInfo, &psci)); if (SUCCEEDED(hr)) { hr = psci->IsSearchCompanionInetAvailable(&fSCAvailable); psci->Release(); } *pbAvailable = fSCAvailable ? VARIANT_TRUE : VARIANT_FALSE; hr = S_OK; } else { hr = E_INVALIDARG; } } return hr; }
STDMETHODIMP CSearchAssistantOC::put_UseSearchCompanion(VARIANT_BOOL bUseSC) { HRESULT hr = E_ACCESSDENIED; if (IsTrustedSite()) { LPCTSTR pszUseSC = bUseSC ? TEXT("yes") : TEXT("no"); SHSetValue(HKEY_CURRENT_USER, REG_SZ_IE_MAIN, REG_SZ_USE_SEARCH_COMP, REG_SZ, pszUseSC, CbFromCch(lstrlen(pszUseSC) + 1));
if (bUseSC) { // disable "Use Custom Search URL" as SC won't launch if custom search URL is defined
DWORD dwUseCustom = FALSE; SHSetValue(HKEY_CURRENT_USER, REG_SZ_IE_MAIN, REG_SZ_USECUSTOM, REG_DWORD, &dwUseCustom, sizeof(dwUseCustom)); } hr = S_OK; } return hr; }
STDMETHODIMP CSearchAssistantOC::get_UseSearchCompanion(VARIANT_BOOL *pbUseSC) { HRESULT hr = E_ACCESSDENIED; if (IsTrustedSite()) { if (pbUseSC != NULL) { BOOL fUseSC = SHRegGetBoolUSValue(REG_SZ_IE_MAIN, REG_SZ_USE_SEARCH_COMP, FALSE, FALSE); *pbUseSC = fUseSC ? VARIANT_TRUE : VARIANT_FALSE; hr = S_OK; } else { hr = E_INVALIDARG; } } return hr; }
#ifdef ENABLE_THIS_FOR_IE5X
STDMETHODIMP CSearchAssistantOC::RefreshLocation(IDispatch *pLocation) { HRESULT hr; if (IsTrustedSite()) { if (NULL != pLocation) { IHTMLLocation *pHTMLLocation;
IUnknown_QueryService(pLocation, IID_IHTMLLocation, IID_IHTMLLocation, (void **)&pHTMLLocation);
if (pHTMLLocation) { pHTMLLocation->reload(VARIANT_TRUE); pHTMLLocation->Release(); } } hr = S_OK; } else { hr = E_ACCESSDENIED; }
return hr;
}
#endif
//-------------------------------------------------------------------------//
#define REG_SZ_SHELL_SEARCH TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\") \
TEXT("Explorer\\FindExtensions\\Static\\ShellSearch") //-------------------------------------------------------------------------//
HRESULT GetSearchURLs( IN REFGUID guidSearch, OUT LPTSTR pszUrl, IN DWORD cch, OUT OPTIONAL LPTSTR pszUrlNavNew, OUT DWORD cchNavNew, OUT BOOL *pfRunInProcess ) { HRESULT hr = E_FAIL ; DWORD cb ; DWORD dwType ; DWORD dwErr ;
*pfRunInProcess = FALSE ; if( pszUrlNavNew && cchNavNew ) *pszUrlNavNew = 0 ;
if( IsEqualGUID( guidSearch, SRCID_SWebSearch ) ) { if( GetDefaultInternetSearchUrlW( pszUrl, cch, TRUE ) ) hr = S_OK ; } else { // The shell search URL-eating stuff was adapted from
// CShellSearchExt::_GetSearchUrls() in browseui\browband.cpp,
// and should be kept in sync.
TCHAR szSubKey[32]; HKEY hkey, hkeySub; if( (dwErr = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_SZ_SHELL_SEARCH, 0, KEY_READ, &hkey )) != ERROR_SUCCESS ) return HRESULT_FROM_WIN32( dwErr ) ;
hr = E_FAIL ;
for( int i = 0; wnsprintf( szSubKey, ARRAYSIZE(szSubKey), TEXT("%d"), i ), RegOpenKey(hkey, szSubKey, &hkeySub) == ERROR_SUCCESS ; i++ ) { TCHAR szSearchGuid[MAX_PATH];
cb = SIZEOF(szSearchGuid); if( SHGetValue( hkeySub, TEXT("SearchGUID"), NULL, &dwType, (BYTE*)szSearchGuid, &cb ) == ERROR_SUCCESS ) { GUID guid; SHCLSIDFromString(szSearchGuid, &guid);
if( IsEqualGUID( guid, guidSearch ) ) { cb = cch * sizeof(TCHAR); if( SHGetValue( hkeySub, TEXT("SearchGUID\\Url"), NULL, &dwType, (BYTE*)pszUrl, &cb ) == ERROR_SUCCESS ) { if( pszUrlNavNew && cchNavNew ) { // See if there is a secondary URL that we should navigate to
cb = cchNavNew * sizeof(TCHAR); SHGetValue(hkeySub, TEXT("SearchGUID\\UrlNavNew"), NULL, &dwType, (BYTE*)pszUrlNavNew, &cb); }
// try to grab the RunInProcess flag
*pfRunInProcess = (BOOL)SHRegGetIntW( hkeySub, L"RunInProcess", 0 );
RegCloseKey(hkeySub); hr = S_OK ; break; } } } RegCloseKey(hkeySub); } RegCloseKey( hkey ) ; } return hr ; }
STDMETHODIMP _IsShellSearchBand( REFGUID guidSearch ) { if (IsEqualGUID( guidSearch, SRCID_SFileSearch ) || IsEqualGUID( guidSearch, SRCID_SFindComputer ) || IsEqualGUID( guidSearch, SRCID_SFindPrinter ) ) return S_OK; return S_FALSE; }
//-------------------------------------------------------------------------//
// Establishes the correct shell search dialog, etc.
STDMETHODIMP _ShowShellSearchBand( IWebBrowser2* pwb2, REFGUID guidSearch ) { ASSERT( pwb2 ); ASSERT( S_OK == _IsShellSearchBand( guidSearch ) );
HRESULT hr; VARIANT varBand; if (SUCCEEDED( (hr = InitBSTRVariantFromGUID(&varBand, CLSID_FileSearchBand)) )) { // Retrieve the FileSearchBand's unknown from the browser frame as a VT_UNKNOWN property;
// (FileSearchBand initialized and this when he was created and hosted.)
VARIANT varFsb; if (SUCCEEDED( (hr = pwb2->GetProperty( varBand.bstrVal, &varFsb )) )) { if (VT_UNKNOWN == varFsb.vt && varFsb.punkVal != NULL ) { // Retrieve the IFileSearchBand interface
IFileSearchBand* pfsb; if (SUCCEEDED( (hr = varFsb.punkVal->QueryInterface( IID_IFileSearchBand, (LPVOID*)&pfsb )) )) { // Assign the correct search type to the band
VARIANT varSearchID; if (SUCCEEDED( (hr = InitBSTRVariantFromGUID(&varSearchID, guidSearch)) )) { VARIANT varNil = {0}; VARIANT_BOOL bNavToResults = VARIANT_FALSE ; // Note [scotthan]: we only navigate to results when we create a
// new frame for the search, which we never do from srchasst.
pfsb->SetSearchParameters( &varSearchID.bstrVal, bNavToResults, &varNil, &varNil ); VariantClear( &varSearchID ); } pfsb->Release(); } } VariantClear( &varFsb ); } VariantClear( &varBand ); } return hr; }
//-------------------------------------------------------------------------//
// The goop to show a search band in the current browser frame.
// 6/1
HRESULT CSearchAssistantOC::ShowSearchBand( REFGUID guidSearch ) { HRESULT hr = E_FAIL; TCHAR szUrl[MAX_URL_STRING]; TCHAR szUrlNavNew[MAX_URL_STRING]; CLSID clsidBand; BOOL fShellSearchBand = FALSE; BOOL fRunInProcess = FALSE; IUnknown* punkSite = m_punkSite ? m_punkSite : (IUnknown*)m_spClientSite;
if( !punkSite ) return E_UNEXPECTED ;
// Determine band class and whether the band supports navigation
if( (fShellSearchBand = (S_OK == _IsShellSearchBand( guidSearch ))) ) { if (SHRestricted(REST_NOFIND) && IsEqualGUID(guidSearch, SRCID_SFileSearch)) return E_ACCESSDENIED; clsidBand = CLSID_FileSearchBand; } else { clsidBand = CLSID_SearchBand; // we need to navigate to a search URL, grope the registry for that special URL
if( FAILED( (hr= GetSearchURLs( guidSearch, szUrl, ARRAYSIZE(szUrl), szUrlNavNew, ARRAYSIZE(szUrlNavNew), &fRunInProcess )) ) ) return hr; } // FEATURE [scotthan]: this function will fail unless invoked from within a browser.
// This sits fine for now since SearchAsst is designed as a browser band.
IWebBrowser2* pwb2; hr = IUnknown_QueryServiceForWebBrowserApp(punkSite, IID_PPV_ARG(IWebBrowser2, &pwb2)); if (SUCCEEDED(hr)) { SA_BSTRGUID bstrClsid; InitFakeBSTR(&bstrClsid, clsidBand);
VARIANT var; var.bstrVal = bstrClsid.wsz; var.vt = VT_BSTR;
VARIANT varNil = {0}; // show a search bar
hr = pwb2->ShowBrowserBar(&var, &varNil, &varNil); if( SUCCEEDED( hr ) ) { VARIANT varFlags; if( fShellSearchBand ) { hr= _ShowShellSearchBand( pwb2, guidSearch ); } else { varFlags.vt = VT_I4; varFlags.lVal = navBrowserBar; var.bstrVal = SysAllocString( T2W( szUrl ) ) ; var.vt = VT_BSTR ;
// navigate the search bar to the correct url
hr = pwb2->Navigate2(&var, &varFlags, &varNil, &varNil, &varNil);
SysFreeString(var.bstrVal); if( SUCCEEDED( hr ) ) { hr = pwb2->put_Visible( TRUE ) ; } } } pwb2->Release(); } return hr; }
STDMETHODIMP CSearchAssistantOC::SetSite( IUnknown* punkSite ) { ATOMICRELEASE(m_punkSite); if ((m_punkSite = punkSite) != NULL) m_punkSite->AddRef() ; return S_OK ; }
STDMETHODIMP CSearchAssistantOC::GetSite( REFIID riid, void** ppvSite ) { if( !m_punkSite ) return E_FAIL ; return m_punkSite->QueryInterface( riid, ppvSite ) ; }
|