#include "stdafx.h" #pragma hdrstop #include // let the shell dispatch objects know where to get their type lib // (this stuff lives here for no better reason than it must be in some cpp file) EXTERN_C GUID g_guidLibSdspatch = LIBID_Shell32; EXTERN_C USHORT g_wMajorVerSdspatch = 1; EXTERN_C USHORT g_wMinorVerSdspatch = 0; // This isn't a typical delay load since it's called only if wininet // is already loaded in memory. Otherwise the call is dropped on the floor. // Defview did it this way I assume to keep WININET out of first boot time. BOOL MyInternetSetOption(HANDLE h, DWORD dw1, LPVOID lpv, DWORD dw2) { BOOL bRet = FALSE; HMODULE hmod = GetModuleHandle(TEXT("wininet.dll")); if (hmod) { typedef BOOL (*PFNINTERNETSETOPTIONA)(HANDLE h, DWORD dw1, LPVOID lpv, DWORD dw2); PFNINTERNETSETOPTIONA fp = (PFNINTERNETSETOPTIONA)GetProcAddress(hmod, "InternetSetOptionA"); if (fp) { bRet = fp(h, dw1, lpv, dw2); } } return bRet; } // REVIEW: maybe just check (hwnd == GetShellWindow()) STDAPI_(BOOL) IsDesktopWindow(HWND hwnd) { TCHAR szName[80]; GetClassName(hwnd, szName, ARRAYSIZE(szName)); if (!lstrcmp(szName, TEXT(STR_DESKTOPCLASS))) { return hwnd == GetShellWindow(); } return FALSE; } // returns: // S_OK returned if the .htt (web view template) file associated with the folder we're viewing is trusted // S_FALSE or // E_ACCESSDENIED bad... don't expose local machine access STDAPI IsSafePage(IUnknown *punkSite) { // 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 (!punkSite) return S_FALSE; HRESULT hr = E_ACCESSDENIED; // There are two safe cases: // 1) we are contained by a signed MD5 hashed defview template. // 2) we are contained by a .html file that's on the Local Zone // // Case 1) find the template path from webview... VARIANT vPath = {0}; hr = IUnknown_QueryServiceExec(punkSite, SID_DefView, &CGID_DefView, DVCMDID_GETTEMPLATEDIRNAME, 0, NULL, &vPath); if (SUCCEEDED(hr)) { if (vPath.vt == VT_BSTR && vPath.bstrVal) { WCHAR wszPath[MAX_PATH]; DWORD cchPath = ARRAYSIZE(wszPath); if (S_OK != PathCreateFromUrlW(vPath.bstrVal, wszPath, &cchPath, 0)) { // it might not be an URL, in this case it is a file path StrCpyNW(wszPath, vPath.bstrVal, ARRAYSIZE(wszPath)); } // it might not be an URL, in this case it is a file path // allow intranet if this is hosted under defview hr = SHRegisterValidateTemplate(wszPath, SHRVT_VALIDATE | SHRVT_ALLOW_INTRANET | SHRVT_PROMPTUSER | SHRVT_REGISTERIFPROMPTOK); } VariantClear(&vPath); } else { IUnknown* punkToFree = NULL; // Case 2) ask the browser, for example we are in a .HTM doc BOOL fFound = FALSE; do { IBrowserService* pbs; hr = IUnknown_QueryService(punkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &pbs)); if (SUCCEEDED(hr)) { LPITEMIDLIST pidl; hr = pbs->GetPidl(&pidl); if (SUCCEEDED(hr)) { WCHAR wszPath[MAX_PATH]; DWORD dwAttribs = SFGAO_FOLDER; hr = SHGetNameAndFlagsW(pidl, SHGDN_FORPARSING, wszPath, ARRAYSIZE(wszPath), &dwAttribs); if (dwAttribs & SFGAO_FOLDER) { // A folder is not a .HTM file, so continue on up... ATOMICRELEASE(punkToFree); hr = IUnknown_GetSite(pbs, IID_PPV_ARG(IUnknown, &punkToFree)); // gotta start with pbs's parent (otherwise you'll get the same pbs again) if (FAILED(hr)) // to get by the weboc you need to explicitly ask for the oc's parent: { hr = IUnknown_QueryService(pbs, SID_QIClientSite, IID_PPV_ARG(IUnknown, &punkToFree)); } punkSite = punkToFree; } else { // Found the nearest containing non-folder object. fFound = TRUE; hr = LocalZoneCheckPath(wszPath, punkSite); // check for local zone } ILFree(pidl); } pbs->Release(); } } while (SUCCEEDED(hr) && !fFound); ATOMICRELEASE(punkToFree); } if (S_OK != hr) { hr = E_ACCESSDENIED; } return hr; } HRESULT HrSHGetValue(IN HKEY hKey, IN LPCTSTR pszSubKey, OPTIONAL IN LPCTSTR pszValue, OPTIONAL OUT LPDWORD pdwType, OPTIONAL OUT LPVOID pvData, OPTIONAL OUT LPDWORD pcbData) { DWORD dwError = SHGetValue(hKey, pszSubKey, pszValue, pdwType, pvData, pcbData); return HRESULT_FROM_WIN32(dwError); } STDAPI SHPropertyBag_WritePunk(IN IPropertyBag * pPropertyPage, IN LPCWSTR pwzPropName, IN IUnknown * punk) { HRESULT hr = E_INVALIDARG; if (pPropertyPage && pwzPropName) { VARIANT va; va.vt = VT_UNKNOWN; va.punkVal = punk; hr = pPropertyPage->Write(pwzPropName, &va); } return hr; } BOOL _GetRegValueString(HKEY hKey, LPCTSTR pszValName, LPTSTR pszString, int cchSize) { DWORD cbSize = sizeof(pszString[0]) * cchSize; DWORD dwType; DWORD dwError = SHQueryValueEx(hKey, pszValName, NULL, &dwType, (LPBYTE)pszString, &cbSize); return (ERROR_SUCCESS == dwError); } //------------------------------------------------------------------------------------ // // IconSet/GetRegValueString() // // Versions of Get/SetRegValueString that go to the user classes section. // // Returns: success of string setting / retrieval // //------------------------------------------------------------------------------------ BOOL IconSetRegValueString(const CLSID* pclsid, LPCTSTR lpszSubKey, LPCTSTR lpszValName, LPCTSTR lpszValue) { HKEY hkey; if (SUCCEEDED(SHRegGetCLSIDKey(*pclsid, lpszSubKey, TRUE, TRUE, &hkey))) { DWORD dwRet = SHRegSetPath(hkey, NULL, lpszValName, lpszValue, 0); RegCloseKey(hkey); return (dwRet == ERROR_SUCCESS); } return FALSE; } BOOL _IconGetRegValueString(BOOL fDisplayName, const CLSID* pclsid, LPCTSTR lpszSubKey, LPCTSTR lpszValName, LPTSTR lpszValue, int cchValue) { HKEY hkey; if (SUCCEEDED(SHRegGetCLSIDKey(*pclsid, lpszSubKey, TRUE, FALSE, &hkey)) || SUCCEEDED(SHRegGetCLSIDKey(*pclsid, lpszSubKey, FALSE, FALSE, &hkey))) { BOOL fRet; if (fDisplayName) { fRet = SUCCEEDED(SHLoadLegacyRegUIString(hkey, NULL, lpszValue, cchValue)); } else { fRet = _GetRegValueString(hkey, lpszValName, lpszValue, cchValue); } RegCloseKey(hkey); return fRet; } return FALSE; } BOOL IconGetRegNameString(const CLSID* pclsid, LPTSTR lpszValue, int cchValue) { return _IconGetRegValueString(TRUE, pclsid, NULL, NULL, lpszValue, cchValue); } // lpszValName is used if there are multiple icons ("full" and "empty" for recycle bin) BOOL IconGetRegIconString(const CLSID* pclsid, LPCTSTR lpszValName, LPTSTR lpszValue, int cchValue) { return _IconGetRegValueString(FALSE, pclsid, TEXT("DefaultIcon"), lpszValName, lpszValue, cchValue); } BOOL CALLBACK Cabinet_RefreshEnum(HWND hwnd, LPARAM lParam) { if (IsFolderWindow(hwnd) || IsExplorerWindow(hwnd)) { PostMessage(hwnd, WM_COMMAND, FCIDM_REFRESH, lParam); } return(TRUE); } BOOL CALLBACK Cabinet_UpdateWebViewEnum(HWND hwnd, LPARAM lParam) { if (IsFolderWindow(hwnd) || IsExplorerWindow(hwnd)) { // A value of -1L for lParam will force a refresh by loading the View window // with the new VID as specified in the global DefFolderSettings. PostMessage(hwnd, WM_COMMAND, SFVIDM_MISC_SETWEBVIEW, lParam); } return(TRUE); } void Cabinet_RefreshAll(WNDENUMPROC lpEnumFunc, LPARAM lParam) { HWND hwnd = FindWindowEx(NULL, NULL, TEXT(STR_DESKTOPCLASS), NULL); if (hwnd) PostMessage(hwnd, WM_COMMAND, FCIDM_REFRESH, 0L); hwnd = FindWindowEx(NULL, NULL, TEXT("Shell_TrayWnd"), NULL); if (hwnd) PostMessage(hwnd, TM_REFRESH, 0, 0L); EnumWindows(lpEnumFunc, lParam); }