Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
util.cpp
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 146k
Category:
Windows Kernel
Development Platform:
Visual C++
- /***************************************************************************/
- /* WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! */
- /***************************************************************************/
- /* As part of the shdocvw/browseui split, parts of this file are moving to */
- /* shell32/shlwapi (#ifdef POSTPOSTSPLIT). Make sure you make your delta */
- /* to the shell32/shlwapi version also! */
- /***************************************************************************/
- #include "priv.h"
- #include "sccls.h"
- #include "shlobj.h"
- #include <fsmenu.h>
- #include <tchar.h>
- #ifndef UNIX
- #include <webcheck.h>
- #else
- #include <subsmgr.h>
- #endif
- #include "resource.h"
- #include "mshtml.h" // for IHTMLElement
- #include "mlang.h" // fo char conversion
- #include <advpub.h> // for IE activesetup GUID
- #include "winineti.h" // For name of a mutex used in IsWininetLoadedAnywhere()
- #include "htregmng.h"
- #include <ntverp.h>
- #include "mruex.h"
- #include "mttf.h"
- #include <platform.h>
- #include <mobsync.h>
- #include <mobsyncp.h>
- #include <winuser.h>
- #include <mluisupp.h>
- #include "shdocfl.h"
- #include <shlwapip.h>
- #include "../lib/brutil.cpp"
- STDAPI CDelegateMalloc_Create(void *pv, SIZE_T cbSize, WORD wOuter, IMalloc **ppmalloc);
- const VARIANT c_vaEmpty = {0};
- const TCHAR c_szRegKeyTypedURLs[] = TEXT("Software\Microsoft\Internet Explorer\TypedURLs");
- #define DM_SESSIONCOUNT 0
- int g_cxIcon = 0;
- int g_cyIcon = 0;
- int g_cxSmIcon = 0;
- int g_cySmIcon = 0;
- const DISPPARAMS c_dispparamsNoArgs = {NULL, NULL, 0, 0};
- const LARGE_INTEGER c_li0 = { 0, 0 };
- const ITEMIDLIST s_idlNULL = { 0 } ;
- int InitColorDepth(void)
- {
- static int s_lrFlags = 0; // Flags passed to LoadImage
- if (s_lrFlags == 0)
- {
- int nColorRes, nIconDepth = 0;
- HKEY hkey;
- // Determine the color depth so we can load the best image
- // (This code was stolen from FileIconInit in shell32)
- // Get the user prefered icon size (and color depth) from the
- // registry.
- //
- if (NO_ERROR == RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_METRICS, &hkey))
- {
- nIconDepth = SHRegGetIntW(hkey, L"Shell Icon Bpp", nIconDepth);
- RegCloseKey(hkey);
- }
- nColorRes = GetCurColorRes();
- if (nIconDepth > nColorRes)
- nIconDepth = 0;
- if (nColorRes <= 8)
- nIconDepth = 0; // wouldn't have worked anyway
- if (nColorRes > 4 && nIconDepth <= 4)
- s_lrFlags = LR_VGACOLOR;
- else
- s_lrFlags = LR_DEFAULTCOLOR;
- }
- return s_lrFlags;
- }
- HICON g_hiconSplat = NULL;
- HICON g_hiconSplatSm = NULL; // small version
- void LoadCommonIcons(void)
- {
- if (NULL == g_hiconSplat)
- {
- // Use LoadLibraryEx so we don't load code pages
- HINSTANCE hinst = LoadLibrary(TEXT("url.dll"));
- if (hinst)
- {
- int lrFlags = InitColorDepth();
- g_hiconSplat = (HICON)LoadImage(hinst, MAKEINTRESOURCE(IDI_URL_SPLAT), IMAGE_ICON, g_cxIcon, g_cyIcon, lrFlags);
- g_hiconSplatSm = (HICON)LoadImage(hinst, MAKEINTRESOURCE(IDI_URL_SPLAT), IMAGE_ICON, g_cxSmIcon, g_cySmIcon, lrFlags);
- FreeLibrary(hinst);
- }
- }
- }
- STDAPI_(BOOL) UrlHitsNetW(LPCWSTR pszURL)
- {
- BOOL fResult;
- // Handle the easy ones on our own and call URLMON for the others.
- switch (GetUrlScheme(pszURL))
- {
- case URL_SCHEME_FILE:
- case URL_SCHEME_RES:
- fResult = FALSE;
- break;
- case URL_SCHEME_HTTP:
- case URL_SCHEME_HTTPS:
- case URL_SCHEME_FTP:
- case URL_SCHEME_GOPHER:
- case URL_SCHEME_TELNET:
- case URL_SCHEME_WAIS:
- fResult = TRUE;
- break;
- default:
- {
- DWORD fHitsNet;
- DWORD dwSize;
- fResult = SUCCEEDED(CoInternetQueryInfo(
- pszURL, QUERY_USES_NETWORK,
- 0, &fHitsNet, sizeof(fHitsNet), &dwSize, 0)) && fHitsNet;
- }
- }
- return fResult;
- }
- STDAPI_(BOOL) CallCoInternetQueryInfo(LPCTSTR pszURL, QUERYOPTION QueryOption)
- {
- DWORD fRetVal;
- DWORD dwSize;
- return SUCCEEDED(CoInternetQueryInfo(
- pszURL, QueryOption,
- 0, &fRetVal, sizeof(fRetVal), &dwSize, 0)) && fRetVal;
- }
- // see if a given URL is in the cache
- STDAPI_(BOOL) UrlIsInCache(LPCTSTR pszURL)
- {
- return CallCoInternetQueryInfo(pszURL, QUERY_IS_CACHED);
- }
- // See if a give URL is actually present as an installed entry
- STDAPI_(BOOL) UrlIsInstalledEntry(LPCTSTR pszURL)
- {
- return CallCoInternetQueryInfo(pszURL, QUERY_IS_INSTALLEDENTRY);
- }
- // see if a given URL is in the cache OR if it is mapped
- STDAPI_(BOOL) UrlIsMappedOrInCache(LPCTSTR pszURL)
- {
- return CallCoInternetQueryInfo(pszURL, QUERY_IS_CACHED_OR_MAPPED);
- }
- BOOL IsFileUrlW(LPCWSTR pcwzUrl)
- {
- return (GetUrlSchemeW(pcwzUrl) == URL_SCHEME_FILE);
- }
- BOOL IsFileUrl(LPCSTR psz)
- {
- return (GetUrlSchemeA(psz) == URL_SCHEME_FILE);
- }
- BOOL PathIsFilePath(LPCWSTR lpszPath)
- {
- #ifdef UNIX
- if (lpszPath[0] == TEXT('/'))
- #else
- if ((lpszPath[0] == TEXT('\')) || (lpszPath[1] == TEXT(':')))
- #endif
- return TRUE;
- return IsFileUrlW(lpszPath);
- }
- BOOL IsSubscribableW(LPCWSTR pszUrl)
- {
- // BUGBUG: this should be method on the subscription mgr interface - zekel
- DWORD dwScheme = GetUrlSchemeW(pszUrl);
- return (dwScheme == URL_SCHEME_HTTP) || (dwScheme == URL_SCHEME_HTTPS);
- }
- BOOL IsSubscribableA(LPCSTR pszUrl)
- {
- // BUGBUG: this should be method on the subscription mgr interface - zekel
- DWORD dwScheme = GetUrlSchemeA(pszUrl);
- return (dwScheme == URL_SCHEME_HTTP) || (dwScheme == URL_SCHEME_HTTPS);
- }
- DWORD SHRandom(void)
- {
- GUID guid;
- DWORD dw;
- CoCreateGuid(&guid);
- HashData((LPBYTE)&guid, SIZEOF(guid), (LPBYTE)&dw, SIZEOF(dw));
- return dw;
- }
- // See if we are hosted by IE (explorer.exe or iexplore.exe)
- BOOL IsInternetExplorerApp()
- {
- if ((g_fBrowserOnlyProcess) || // if in iexplore.exe process,
- (GetModuleHandle(TEXT("EXPLORER.EXE")))) // or explorer.exe process,
- {
- return TRUE; // then we are IE
- }
- return FALSE;
- }
- BOOL IsTopFrameBrowser(IServiceProvider *psp, IUnknown *punk)
- {
- IShellBrowser *psb;
- ASSERT(psp);
- ASSERT(punk);
- BOOL fRet = FALSE;
- if(SUCCEEDED(psp->QueryService(SID_STopFrameBrowser, IID_IShellBrowser, (void **)&psb)))
- {
- fRet = IsSameObject(psb, punk);
- psb->Release();
- }
- return fRet;
- }
- DWORD GetUrlSchemePidl(LPITEMIDLIST pidl)
- {
- if (pidl && IsURLChild(pidl, TRUE))
- {
- TCHAR szUrl[MAX_URL_STRING];
- if (SUCCEEDED(IEGetDisplayName(pidl, szUrl, SHGDN_FORPARSING)))
- return GetUrlScheme(szUrl);
- }
- return URL_SCHEME_INVALID;
- }
- //-----------------------------------------------------------------------------
- #ifndef POSTPOSTSPLIT
- STDAPI_(BSTR) LoadBSTR(UINT uID)
- {
- WCHAR wszBuf[MAX_PATH];
- if (MLLoadStringW(uID, wszBuf, ARRAYSIZE(wszBuf)))
- {
- return SysAllocString(wszBuf);
- }
- return NULL;
- }
- #endif
- BOOL StringIsUTF8A(LPCSTR psz, DWORD cb)
- {
- BOOL fRC = FALSE;
- CHAR *pb;
- CHAR b;
- DWORD dwCnt;
- DWORD dwUTF8Cnt;
- if(!psz || !(*psz) || cb == 0)
- return(FALSE);
- pb = (CHAR*)psz;
- while(cb-- && *pb)
- {
- if((*pb & 0xc0) == 0xc0) // bit pattern starts with 11
- {
- dwCnt = dwUTF8Cnt = 0;
- b = *pb;
- while((b & 0xc0) == 0xc0)
- {
- dwCnt++;
- if((*(pb+dwCnt) & 0xc0) == 0x80) // bits at dwCnt bytes from current offset in str aren't 10
- dwUTF8Cnt++;
- b = (b << 1) & 0xff;
- }
- if(dwCnt == dwUTF8Cnt)
- fRC = TRUE; // Found UTF8 encoded chars
- pb += ++dwCnt;
- }
- else
- {
- pb++;
- }
- }
- return(fRC);
- }
- BOOL StringIsUTF8W(LPCWSTR pwz, DWORD cb)
- {
- BOOL fRC = FALSE;
- WCHAR *pb;
- WCHAR b;
- DWORD dwCnt;
- DWORD dwUTF8Cnt;
- if(!pwz || !(*pwz) || cb == 0)
- return(FALSE);
- pb = (WCHAR*)pwz;
- while(cb-- && *pb)
- {
- if(*pb > 255) // Non ansi so bail
- return(FALSE);
- if((*pb & 0xc0) == 0xc0) // bit pattern starts with 11
- {
- dwCnt = dwUTF8Cnt = 0;
- b = *pb;
- while((b & 0xc0) == 0xc0)
- {
- dwCnt++;
- if((*(pb+dwCnt) & 0xc0) == 0x80) // bits at dwCnt bytes from current offset in str aren't 10
- dwUTF8Cnt++;
- b = (b << 1) & 0xff;
- }
- if(dwCnt == dwUTF8Cnt)
- fRC = TRUE; // Found UTF8 encoded chars
- pb += ++dwCnt;
- }
- else
- {
- pb++;
- }
- }
- return(fRC);
- }
- //
- // StringContainsHighAnsi
- //
- // Determine if string contains high-ANSI characters. Search is
- // stopped when we hit the first high-ANSI character, when we hit the terminator
- // or when we have decremented dwInLen to zero
- //
- // Return Value:
- // TRUE - pszIn contains one or more high-ANSI characters
- //
- // FALSE - pszIn (or substring of length dwInLen) does not contain
- // high-ANSI characters
- //
- BOOL StringContainsHighAnsiA(LPCSTR pszIn, DWORD dwInLen)
- {
- while (dwInLen-- && *pszIn)
- {
- if (*pszIn++ & 0x80)
- return TRUE;
- }
- return FALSE;
- }
- BOOL StringContainsHighAnsiW(LPCWSTR pszIn, DWORD dwInLen)
- {
- while (dwInLen-- && *pszIn)
- {
- if (*pszIn++ & 0x80)
- return TRUE;
- }
- return FALSE;
- }
- BOOL UTF8Enabled(VOID)
- {
- static DWORD dwIE = URL_ENCODING_NONE;
- DWORD dwOutLen = sizeof(DWORD);
- if(dwIE == URL_ENCODING_NONE)
- UrlMkGetSessionOption(URLMON_OPTION_URL_ENCODING, &dwIE, sizeof(DWORD), &dwOutLen, NULL);
- return(dwIE == URL_ENCODING_ENABLE_UTF8);
- }
- //
- // PrepareURLForDisplay
- //
- // Decodes without stripping file:// prefix
- //
- #undef PrepareURLForDisplay
- BOOL PrepareURLForDisplayW(LPCWSTR pwz, LPWSTR pwzOut, LPDWORD pcbOut)
- {
- if (PathIsFilePath(pwz))
- {
- if (IsFileUrlW(pwz))
- return SUCCEEDED(PathCreateFromUrlW(pwz, pwzOut, pcbOut, 0));
- StrCpyNW(pwzOut, pwz, *pcbOut);
- *pcbOut = lstrlenW(pwzOut);
- return TRUE;
- }
- return SUCCEEDED(UrlUnescapeW((LPWSTR)pwz, pwzOut, pcbOut, 0));
- }
- //
- // PrepareURLForDisplayUTF8W
- //
- // pwz - [In] UTF8 encoded string like "%e6%aa%e4%a6.doc".
- // pwzOut - [Out] UTF8 decoded string.
- // pcchOut - [In/Out] Count of characters in pwzOut on input. Number of chars copies to pwzOut on output
- // including the terminating null.
- // fUTF8Enabled - [In] Flag to indicated whether UTF8 is enabled.
- //
- // Returns:
- // S_OK upon success.
- // E_FAIL for failure.
- // ERROR_BUFFER_OVERFLOW if the number of converted chars is greater than the passed in size of output buffer.
- //
- // Note: If UTF8 is not enabled or the string does not contain UTF8 the output string will be unescaped
- // and will return S_OK.
- //
- HRESULT PrepareURLForDisplayUTF8W(LPCWSTR pwz, LPWSTR pwzOut, LPDWORD pcchOut, BOOL fUTF8Enabled)
- {
- HRESULT hr = E_FAIL;
- DWORD cch;
- DWORD cch1;
- CHAR szBuf[MAX_URL_STRING];
- CHAR *pszBuf = szBuf;
- if(!pwz || !pwzOut || !pcchOut)
- {
- if(pcchOut)
- *pcchOut = 0;
- return(hr);
- }
- cch = *pcchOut;
- cch1 = ARRAYSIZE(szBuf);
- hr = UrlUnescapeW((LPWSTR)pwz, pwzOut, pcchOut, 0);
- if(SUCCEEDED(hr))
- {
- if (fUTF8Enabled && StringIsUTF8W(pwzOut, cch))
- {
- if(*pcchOut > ARRAYSIZE(szBuf)) // Internal buffer not big enough so alloc one
- {
- if((pszBuf = (CHAR *)LocalAlloc(LPTR, ((*pcchOut)+1) * sizeof(CHAR))) == NULL)
- {
- *pcchOut = 0;
- return(E_OUTOFMEMORY);
- }
- cch1 = *pcchOut;
- }
- // Compress wide string
- CHAR *pIn = (CHAR *)pwzOut;
- CHAR *pOut = pszBuf;
- while((*pIn != '') || (*(pIn+1) != '') && --cch1)
- {
- if(*pIn != '')
- {
- *pOut = *pIn;
- pOut++;
- }
- pIn++;
- }
- *pOut = '';
- // Convert to UTF8 wide string
- if((cch1 = SHAnsiToUnicodeCP(CP_UTF8, pszBuf, pwzOut, cch)) != 0)
- {
- hr = S_OK;
- *pcchOut = cch1;
- }
- // SHAnsiToUnicode doesn't tell us if it has truncated the convertion to fit the output buffer
- RIPMSG(cch1 != cch, "PrepareUrlForDisplayUTF8: Passed in size of out buf equal to converted size; buffer might be truncated");
- if((pszBuf != NULL) && (pszBuf != szBuf))
- LocalFree((CHAR *)pszBuf);
- }
- else
- {
- hr = S_OK;;
- }
- }
- return(hr);
- }
- //
- // PrepareURLForExternalApp -
- //
- // Decodes and strips, if needed, file:// prefix
- //
- // BUGBUGCOMPAT - for IE30 compatibility reasons, we have to Unescape all Urls - zekel - 1-JUL-97
- // before passing them to an APP. this does limit their use, but
- // people already depend on this behavior. specifically MS Chat.
- BOOL PrepareURLForExternalApp (LPCWSTR psz, LPWSTR pszOut, LPDWORD pcchOut)
- {
- if(IsFileUrlW(psz))
- return SUCCEEDED(PathCreateFromUrl(psz, pszOut, pcchOut, 0));
- else
- return SUCCEEDED(UrlUnescape((LPWSTR)psz, pszOut, pcchOut, 0));
- }
- BOOL ParseURLFromOutsideSourceW (LPCWSTR psz, LPWSTR pszOut, LPDWORD pcchOut, LPBOOL pbWasSearchURL)
- {
- // This is our hardest case. Users and outside applications might
- // type fully-escaped, partially-escaped, or unescaped URLs at us.
- // We need to handle all these correctly. This API will attempt to
- // determine what sort of URL we've got, and provide us a returned URL
- // that is guaranteed to be FULLY escaped.
- IURLQualify(psz, UQF_DEFAULT, pszOut, pbWasSearchURL, NULL);
- //
- // go ahead and canonicalize this appropriately
- //
- if (FAILED(UrlCanonicalize(pszOut, pszOut, pcchOut, URL_ESCAPE_SPACES_ONLY)))
- {
- //
- // we cant resize from here.
- // NOTE UrlCan will return E_POINTER if it is an insufficient buffer
- //
- TraceMsg(DM_ERROR, "sdv PUFOS:UC() failed.");
- return FALSE;
- }
- return TRUE;
- } // ParseURLFromOutsideSource
- BOOL ParseURLFromOutsideSourceA (LPCSTR psz, LPSTR pszOut, LPDWORD pcchOut, LPBOOL pbWasSearchURL)
- {
- SHSTRW strw;
- DWORD cch ;
- ASSERT(psz);
- ASSERT(pszOut);
- ASSERT(pcchOut && *pcchOut);
- //
- // BUGBUG we arent guaranteed to have the correct cch's here - zekel - 27-jan-97
- // but for now this is adequate.
- //
- if(SUCCEEDED(strw.SetStr(psz)) && SUCCEEDED(strw.SetSize(cch = *pcchOut)) &&
- ParseURLFromOutsideSourceW((LPCWSTR) strw, (LPWSTR) strw, pcchOut, pbWasSearchURL))
- {
- return SHUnicodeToAnsi((LPCWSTR)strw, pszOut, cch);
- }
- return FALSE;
- }
- int DPA_ILFreeCallback(void * p, void * d)
- {
- Pidl_Set((LPITEMIDLIST*)&p, NULL);
- return 1;
- }
- void _DeletePidlDPA(HDPA hdpa)
- {
- DPA_DestroyCallback(hdpa, (PFNDPAENUMCALLBACK)DPA_ILFreeCallback, 0);
- }
- BOOL _InitComCtl32()
- {
- static BOOL fInitialized = FALSE;
- if (!fInitialized)
- {
- INITCOMMONCONTROLSEX icc;
- icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
- icc.dwICC = ICC_USEREX_CLASSES | ICC_COOL_CLASSES | ICC_INTERNET_CLASSES | ICC_PAGESCROLLER_CLASS | ICC_NATIVEFNTCTL_CLASS;
- fInitialized = InitCommonControlsEx(&icc);
- }
- return fInitialized;
- }
- #ifndef ALPHA_WARNING_IS_DUMB
- #pragma message("building with alpha warning enabled")
- void AlphaWarning(HWND hwnd)
- {
- static BOOL fShown = FALSE;
- TCHAR szTemp[265];
- TCHAR szFull[2048];
- szFull[0] = TEXT('');
- int i = IDS_ALPHAWARNING;
- if (fShown)
- return;
- fShown = TRUE;
- while(MLLoadShellLangString (i++, szTemp, ARRAYSIZE(szTemp))) {
- StrCatBuff(szFull, szTemp, ARRAYSIZE(szFull));
- }
- MessageBox(hwnd, szFull, TEXT("Internet Explorer"), MB_ICONINFORMATION | MB_OK);
- }
- #endif
- #if 0
- // t-neilb: Should be able to remove
- /*******************************************************************
- NAME: InitHistoryList
- SYNOPSIS: Reads persistent addresses from registry and puts them
- into a combo box.
- ********************************************************************/
- BOOL InitHistoryList(HWND hwndCB)
- {
- ASSERT(hwndCB); // window needs to have been created
- if (!hwndCB)
- return FALSE;
- // open the registry key containing addresses
- HKEY hKey;
- DWORD result;
- result = RegCreateKey(HKEY_CURRENT_USER, c_szRegKeyTypedURLs, &hKey);
- if (result != ERROR_SUCCESS)
- return FALSE;
- ASSERT(hKey);
- // read values from registry and put them in combo box
- UINT nTrys;
- UINT nCount = 0;
- TCHAR szValueName[10]; // big enough for "url99"
- TCHAR szAddress[MAX_URL_STRING+1];
- DWORD dwAddress;
- for (nTrys = 0; nTrys < MAX_SAVE_TYPED_URLS; nTrys++) {
- // make a value name a la "url1" (1-based for historical reasons)
- wnsprintf(szValueName, ARRAYSIZE(szValueName), TEXT("url%u"), nTrys+1);
- dwAddress = ARRAYSIZE(szAddress);
- if (RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE)szAddress,
- &dwAddress) == ERROR_SUCCESS) {
- if (szAddress[0]) {
- ComboBox_InsertString(hwndCB, nCount, szAddress);
- nCount++;
- }
- }
- }
- RegCloseKey(hKey);
- return TRUE;
- }
- BOOL SaveHistoryList(HWND hwndCB)
- {
- ASSERT(hwndCB); // address window needs to have been created
- if (!hwndCB)
- return FALSE;
- // open the registry key containing addresses
- HKEY hKey;
- DWORD result = RegCreateKey(HKEY_CURRENT_USER, c_szRegKeyTypedURLs, &hKey);
- if (result != ERROR_SUCCESS)
- return FALSE;
- ASSERT(hKey);
- // get the number of items in combo box
- int nItems = ComboBox_GetCount(hwndCB);
- int nTrys;
- TCHAR szValueName[10]; // big enough for "url99"
- TCHAR szAddress[MAX_URL_STRING+1];
- // loop through every potential saved URL in registry.
- for (nTrys = 0; nTrys < MAX_SAVE_TYPED_URLS; nTrys++) {
- // make a value name a la "url1" (1-based for historical reasons)
- wnsprintf(szValueName,ARRAYSIZE(szValueName), TEXT("url%u"),nTrys+1);
- // for every combo box item we have, get the corresponding
- // text and save it in the registry
- if (nTrys < nItems) {
- // get text from combo box
- if (ComboBox_GetLBText(hwndCB, nTrys, szAddress)) {
- // store it in registry
- RegSetValueEx(hKey,szValueName,0,REG_SZ,(LPBYTE)
- szAddress,(lstrlen(szAddress)*sizeof(TCHAR))+1);
- continue;
- }
- }
- // if we get here, we've run out of combo box items (or
- // failed to retrieve text for one of them). Delete any
- // extra items that may be lingering in the registry.
- RegDeleteValue(hKey,szValueName);
- }
- RegCloseKey(hKey);
- return TRUE;
- }
- #endif
- #ifndef POSTPOSTSPLIT
- #endif
- #define DM_NAV TF_SHDNAVIGATE
- #define DM_ZONE TF_SHDNAVIGATE
- #define DM_IEDDE DM_TRACE
- #define DM_CANCELMODE 0
- #define DM_UIWINDOW 0
- #define DM_ENABLEMODELESS 0
- #define DM_EXPLORERMENU 0
- #define DM_BACKFORWARD 0
- #define DM_PROTOCOL 0
- #define DM_ITBAR 0
- #define DM_STARTUP 0
- #define DM_AUTOLIFE 0
- #define DM_PALETTE 0
- PFNSHCHANGENOTIFYREGISTER g_pfnSHChangeNotifyRegister = NULL;
- PFNSHCHANGENOTIFYDEREGISTER g_pfnSHChangeNotifyDeregister = NULL;
- BOOL g_fNewNotify = FALSE; // Are we using classic mode (W95 or new mode?
- BOOL CALLBACK AddPropSheetPage(HPROPSHEETPAGE hpage, LPARAM lParam)
- {
- PROPSHEETHEADER * ppsh = (PROPSHEETHEADER *)lParam;
- if (ppsh->nPages < MAX_PAGES)
- {
- ppsh->phpage[ppsh->nPages++] = hpage;
- return TRUE;
- }
- return FALSE;
- }
- BOOL SHIsRegisteredClient(LPCTSTR pszClient)
- {
- LONG cbSize = 0;
- TCHAR szKey[80];
- wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("Software\Clients\%s"), pszClient);
- return (RegQueryValue(HKEY_LOCAL_MACHINE, szKey, NULL, &cbSize) == ERROR_SUCCESS) &&
- (cbSize > sizeof(TCHAR));
- }
- // Exporting by ordinal is not available on UNIX.
- // But we have all these symbols exported because it's UNIX default.
- #ifdef UNIX
- #define GET_PRIVATE_PROC_ADDRESS(_hinst, _fname, _ord) GetProcAddress(_hinst, _fname)
- #else
- #define GET_PRIVATE_PROC_ADDRESS(_hinst, _fname, _ord) GetProcAddress(_hinst, _ord)
- #endif
- ULONG RegisterNotify(HWND hwnd, UINT nMsg, LPCITEMIDLIST pidl, DWORD dwEvents, UINT uFlags, BOOL fRecursive)
- {
- SHChangeNotifyEntry fsne;
- // See if we need to still figure out which version of SHChange Notify to call?
- if (g_pfnSHChangeNotifyDeregister == NULL)
- {
- HMODULE hmodShell32 = ::GetModuleHandle(TEXT("SHELL32"));
- if (!hmodShell32)
- return 0; // Nothing registered...
- g_pfnSHChangeNotifyRegister = (PFNSHCHANGENOTIFYREGISTER)GET_PRIVATE_PROC_ADDRESS(hmodShell32,
- "NTSHChangeNotifyRegister",
- (LPSTR)640);
- if (g_pfnSHChangeNotifyRegister && (WhichPlatform() == PLATFORM_INTEGRATED))
- {
- g_pfnSHChangeNotifyDeregister = (PFNSHCHANGENOTIFYDEREGISTER)GET_PRIVATE_PROC_ADDRESS(hmodShell32,
- "NTSHChangeNotifyDeregister",
- (LPSTR)641);
- g_fNewNotify = TRUE;
- }
- else
- {
- g_pfnSHChangeNotifyRegister = (PFNSHCHANGENOTIFYREGISTER)GET_PRIVATE_PROC_ADDRESS(hmodShell32,
- "SHChangeNotifyRegister",
- (LPSTR)2);
- g_pfnSHChangeNotifyDeregister = (PFNSHCHANGENOTIFYDEREGISTER)GET_PRIVATE_PROC_ADDRESS(hmodShell32,
- "SHChangeNotifyDeregister",
- (LPSTR)4);
- }
- if (g_pfnSHChangeNotifyDeregister == NULL)
- return 0; // Could not get either to work...
- }
- uFlags |= SHCNRF_ShellLevel | SHCNRF_InterruptLevel;
- if (g_fNewNotify)
- uFlags |= SHCNRF_NewDelivery;
- fsne.fRecursive = fRecursive;
- fsne.pidl = pidl;
- return g_pfnSHChangeNotifyRegister(hwnd, uFlags, dwEvents, nMsg, 1, &fsne);
- }
- //----------------------------------------------------------------------------
- // Just like shells SHRestricted() only this put up a message if the restricion
- // is in effect.
- // BUGBUG: this function is identical to shell32's SHIsRestricted
- BOOL SHIsRestricted(HWND hwnd, RESTRICTIONS rest)
- {
- if (SHRestricted(rest))
- {
- SHRestrictedMessageBox(hwnd);
- return TRUE;
- }
- return FALSE;
- }
- BOOL SHIsRestricted2W(HWND hwnd, BROWSER_RESTRICTIONS rest, LPCWSTR pwzUrl, DWORD dwReserved)
- {
- if (SHRestricted2W(rest, pwzUrl, dwReserved))
- {
- SHRestrictedMessageBox(hwnd);
- return TRUE;
- }
- return FALSE;
- }
- BOOL bIsValidString(LPCSTR pszString, ULONG cbLen)
- {
- if (cbLen == 0) return TRUE;
- while (cbLen--)
- if (*pszString++ == '') return TRUE;
- return FALSE;
- }
- BOOL ViewIDFromViewMode(UINT uViewMode, SHELLVIEWID *pvid)
- {
- switch (uViewMode)
- {
- case FVM_ICON:
- *pvid = VID_LargeIcons;
- break;
- case FVM_SMALLICON:
- *pvid = VID_SmallIcons;
- break;
- case FVM_LIST:
- *pvid = VID_List;
- break;
- case FVM_DETAILS:
- *pvid = VID_Details;
- break;
- default:
- *pvid = VID_LargeIcons;
- return(FALSE);
- }
- return(TRUE);
- }
- HIMAGELIST g_himlSysSmall = NULL;
- HIMAGELIST g_himlSysLarge = NULL;
- void _InitSysImageLists()
- {
- if (!g_himlSysSmall)
- {
- Shell_GetImageLists(&g_himlSysLarge, &g_himlSysSmall);
- ImageList_GetIconSize(g_himlSysLarge, &g_cxIcon, &g_cyIcon);
- ImageList_GetIconSize(g_himlSysSmall, &g_cxSmIcon, &g_cySmIcon);
- }
- }
- #define SZAPPNAME TEXT("Explorer")
- #define SZDEFAULT TEXT(".Default")
- void IEPlaySound(LPCTSTR pszSound, BOOL fSysSound)
- {
- #if !defined(UNIX)
- TCHAR szKey[256];
- // check the registry first
- // if there's nothing registered, we blow off the play,
- // but we don't set the MM_DONTLOAD flag so that if they register
- // something we will play it
- wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("AppEvents\Schemes\Apps\%s\%s\.current"),
- (fSysSound ? SZDEFAULT : SZAPPNAME), pszSound);
- TCHAR szFileName[MAX_PATH];
- szFileName[0] = 0;
- LONG cbSize = SIZEOF(szFileName);
- // note the test for an empty string, PlaySound will play the Default Sound if we
- // give it a sound it cannot find...
- if ((RegQueryValue(HKEY_CURRENT_USER, szKey, szFileName, &cbSize) == ERROR_SUCCESS)
- && cbSize && szFileName[0] != 0)
- {
- //
- // Unlike SHPlaySound in shell32.dll, we get the registry value
- // above and pass it to PlaySound with SND_FILENAME instead of
- // SDN_APPLICATION, so that we play sound even if the application
- // is not Explroer.exe (such as IExplore.exe or WebBrowserOC).
- //
- PlaySoundWrapW(szFileName, NULL, SND_FILENAME | SND_ASYNC | SND_NODEFAULT);
- }
- #endif //!UNIX
- }
- #ifndef POSTPOSTSPLIT
- void* DataObj_GetDataOfType(IDataObject* pdtobj, UINT cfType, STGMEDIUM *pstg)
- {
- void * pret = NULL;
- FORMATETC fmte = {cfType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- if (pdtobj->GetData(&fmte, pstg) == S_OK) {
- pret = GlobalLock(pstg->hGlobal);
- if (!pret)
- ReleaseStgMedium(pstg);
- }
- return pret;
- }
- void ReleaseStgMediumHGLOBAL(STGMEDIUM *pstg)
- {
- ASSERT(pstg->tymed == TYMED_HGLOBAL);
- GlobalUnlock(pstg->hGlobal);
- ReleaseStgMedium(pstg);
- }
- #endif
- #ifndef POSTPOSTSPLIT
- // Copied from shell32 (was _ILCreate), which does not export this.
- // The fsmenu code needs this function.
- STDAPI_(LPITEMIDLIST) IEILCreate(UINT cbSize)
- {
- LPITEMIDLIST pidl = (LPITEMIDLIST)SHAlloc(cbSize);
- if (pidl)
- memset(pidl, 0, cbSize); // needed for external task allicator
- return pidl;
- }
- #endif
- DWORD CommonDragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt)
- {
- DWORD dwEffect = DROPEFFECT_NONE;
- FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- if (pdtobj->QueryGetData(&fmte) == S_OK)
- dwEffect = DROPEFFECT_COPY | DROPEFFECT_LINK;
- else
- {
- InitClipboardFormats();
- fmte.cfFormat = g_cfHIDA;
- if (pdtobj->QueryGetData(&fmte) == S_OK)
- dwEffect = DROPEFFECT_LINK;
- else {
- fmte.cfFormat = g_cfURL;
- if (pdtobj->QueryGetData(&fmte) == S_OK)
- dwEffect = DROPEFFECT_LINK | DROPEFFECT_COPY | DROPEFFECT_MOVE;
- }
- }
- return dwEffect;
- }
- // MapNbspToSp
- //
- // Purpose:
- // Unicode character code point 0x00a0 is designated to HTML
- // entity  , but some windows code pages don't have code
- // point that can map from 0x00a0. In the most occasion in the
- // shell, NBSP is just a space when it's rendered so we can
- // replace it with 0x0020 safely.
- // This function takes lpwszIn as a string that has
- // non-displayable characters in it, and tries to translate
- // it again after removing NBSP (00a0) from it.
- // returns S_OK if this re-translation is successful.
- //
- #define nbsp 0x00a0
- HRESULT SHMapNbspToSp(LPCWSTR lpwszIn, LPSTR lpszOut, int cbszOut)
- {
- BOOL fFoundNbsp = FALSE;
- BOOL fNotDisplayable = TRUE; // assumes FAIL
- LPWSTR pwsz, p;
- if (!lpwszIn || !lpszOut || cbszOut == 0)
- return E_FAIL;
- ASSERT(IS_VALID_STRING_PTRW(lpwszIn, -1));
- ASSERT(IS_VALID_WRITE_BUFFER(lpszOut, TCHAR, cbszOut));
- int cch = lstrlenW(lpwszIn) + 1;
- pwsz = (LPWSTR)LocalAlloc(LPTR, cch * sizeof(WCHAR));
- if (pwsz)
- {
- StrCpyNW(pwsz, lpwszIn, cch);
- p = pwsz;
- while (*p)
- {
- if (*p== nbsp)
- {
- *p= 0x0020; // replace with space
- if (!fFoundNbsp)
- fFoundNbsp = TRUE;
- }
- p++;
- }
- // don't call WC2MB unless we found Nbsp - for perf reason
- if (fFoundNbsp)
- {
- int iret = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, lpszOut,
- cbszOut, NULL, &fNotDisplayable);
- if (!fNotDisplayable && iret == 0)
- {
- // truncated. make it dbcs safe.
- SHTruncateString(lpszOut, cbszOut);
- }
- }
- LocalFree((LOCALHANDLE)pwsz);
- }
- return (fFoundNbsp && !fNotDisplayable) ? S_OK : S_FALSE;
- }
- #undef nbsp
- int PropBag_ReadInt4(IPropertyBag* pPropBag, LPWSTR pszKey, int iDefault)
- {
- VARIANT var = {VT_I4}; // VT_I4 (not 0) so get coercion
- HRESULT hres = pPropBag->Read(pszKey, &var, NULL);
- if (hres==S_OK) {
- if (var.vt==VT_I4) {
- iDefault = var.lVal;
- }
- else {
- VariantClear(&var);
- }
- }
- return iDefault;
- }
- HRESULT _SetPreferedDropEffect(IDataObject *pdtobj, DWORD dwEffect)
- {
- InitClipboardFormats();
- HRESULT hres = E_OUTOFMEMORY;
- DWORD *pdw = (DWORD *)GlobalAlloc(GPTR, sizeof(DWORD));
- if (pdw)
- {
- STGMEDIUM medium;
- FORMATETC fmte = {g_cfPreferedEffect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- *pdw = dwEffect;
- medium.tymed = TYMED_HGLOBAL;
- medium.hGlobal = pdw;
- medium.pUnkForRelease = NULL;
- hres = pdtobj->SetData(&fmte, &medium, TRUE);
- if (FAILED(hres))
- GlobalFree((HGLOBAL)pdw);
- }
- return hres;
- }
- #ifndef POSTPOSTSPLIT
- HRESULT DragDrop(HWND hwnd, IShellFolder * psfParent, LPCITEMIDLIST pidl, DWORD dwPrefEffect, DWORD *pdwEffect)
- {
- HRESULT hres = E_FAIL;
- LPCITEMIDLIST pidlChild;
- if (!psfParent)
- IEBindToParentFolder(pidl, &psfParent, &pidlChild);
- else
- {
- pidlChild = pidl;
- psfParent->AddRef();
- }
- if (psfParent)
- {
- DWORD dwAttrib = DROPEFFECT_MOVE | DROPEFFECT_COPY | DROPEFFECT_LINK;
- psfParent->GetAttributesOf(1, &pidlChild, &dwAttrib);
- IDataObject *pdtobj;
- hres = psfParent->GetUIObjectOf(NULL, 1, &pidlChild, IID_IDataObject, NULL, (void**)&pdtobj);
- if (SUCCEEDED(hres))
- {
- DWORD dwEffect = (DROPEFFECT_MOVE | DROPEFFECT_COPY | DROPEFFECT_LINK) & dwAttrib;
- if (dwPrefEffect)
- {
- //win95 shell32 doesn't know about prefered drop effect, so make it the only effect
- if (IsOS(OS_WIN95) && (WhichPlatform() == PLATFORM_BROWSERONLY))
- {
- dwEffect = DROPEFFECT_LINK & dwAttrib;
- }
- else if (dwPrefEffect & dwEffect)
- {
- _SetPreferedDropEffect(pdtobj, dwPrefEffect);
- }
- }
- ASSERT(dwEffect);
- // Win95 Browser Only - the shell32 in this process doesn't know
- // ole is loaded, even though it is.
- SHLoadOLE(SHELLNOTIFY_OLELOADED);
- IDragSourceHelper* pDragImages;
- if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper, (void**)&pDragImages)))
- {
- pDragImages->InitializeFromWindow(hwnd, 0, pdtobj);
- pDragImages->Release();
- }
- hres = SHDoDragDrop(hwnd, pdtobj, NULL, dwEffect, &dwEffect);
- if (pdwEffect)
- *pdwEffect = dwEffect;
- pdtobj->Release();
- }
- psfParent->Release();
- }
- return hres;
- }
- #endif
- #define IEICONTYPE_GETFILEINFO 0x00000001
- #define IEICONTYPE_DEFAULTICON 0x00000002
- typedef struct tagIEICONS
- {
- int nDefaultIcon;
- int nIEIcon;
- LPCTSTR szFile;
- LPCTSTR szFileExt;
- int nIconResourceNum;
- LPCTSTR szCLSID;
- DWORD dwType;
- } IEICONS;
- IEICONS g_IEIcons[] = {
- {-1, -1, TEXT("MSHTML.DLL"), TEXT(".htm"), 1, NULL, IEICONTYPE_GETFILEINFO},
- {-1, -1, TEXT("URL.DLL"), TEXT("http\DefaultIcon"), 0, TEXT("{FBF23B42-E3F0-101B-8488-00AA003E56F8}"), IEICONTYPE_DEFAULTICON}
- };
- //This function returns the IE icon regardless of the which browser is default
- void _GenerateIEIcons(void)
- {
- int nIndex;
- for (nIndex = 0; nIndex < ARRAYSIZE(g_IEIcons); nIndex++)
- {
- SHFILEINFO sfi;
- TCHAR szModule[MAX_PATH];
- HMODULE hmod = GetModuleHandle(g_IEIcons[nIndex].szFile);
- if (hmod)
- {
- GetModuleFileName(hmod, szModule, ARRAYSIZE(szModule));
- }
- else
- { //HACKHACK : This is a hack to get the mstml
- TCHAR szKey[GUIDSTR_MAX * 4];
- TCHAR szGuid[GUIDSTR_MAX];
- //The CLSID used here belongs to MS HTML Generic Page. If someone changes the guid then we
- // are tossed.
- if (!g_IEIcons[nIndex].szCLSID)
- SHStringFromGUID(CLSID_HTMLDocument, szGuid, GUIDSTR_MAX);
- wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("CLSID\%s\InProcServer32"), g_IEIcons[nIndex].szCLSID ? g_IEIcons[nIndex].szCLSID : szGuid);
- long cb = SIZEOF(szModule);
- RegQueryValue(HKEY_CLASSES_ROOT, szKey, szModule, &cb);
- }
- g_IEIcons[nIndex].nIEIcon = Shell_GetCachedImageIndex(szModule, g_IEIcons[nIndex].nIconResourceNum, 0);
- switch(g_IEIcons[nIndex].dwType)
- {
- case IEICONTYPE_GETFILEINFO:
- sfi.iIcon = 0;
- StrCpyN(szModule, TEXT("c:\notexist"), ARRAYSIZE(szModule));
- StrCatBuff(szModule, g_IEIcons[nIndex].szFileExt, ARRAYSIZE(szModule));
- SHGetFileInfo(szModule, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES);
- g_IEIcons[nIndex].nDefaultIcon = sfi.iIcon;
- break;
- case IEICONTYPE_DEFAULTICON:
- {
- TCHAR szPath[MAX_PATH];
- DWORD cbSize = SIZEOF(szPath);
- SHGetValue(HKEY_CLASSES_ROOT, g_IEIcons[nIndex].szFileExt, TEXT(""), NULL, szPath, &cbSize);
- g_IEIcons[nIndex].nDefaultIcon = Shell_GetCachedImageIndex(szPath, PathParseIconLocation(szPath), 0);
- }
- break;
- }
- }
- }
- int IEMapPIDLToSystemImageListIndex(IShellFolder *psfParent, LPCITEMIDLIST pidlChild, int *piSelectedImage)
- {
- int nIndex;
- int nIcon = SHMapPIDLToSystemImageListIndex(psfParent, pidlChild, piSelectedImage);
- if (-1 == g_IEIcons[0].nDefaultIcon)
- _GenerateIEIcons();
- for (nIndex = 0; nIndex < ARRAYSIZE(g_IEIcons); nIndex++)
- {
- if((nIcon == g_IEIcons[nIndex].nDefaultIcon) ||
- (piSelectedImage && *piSelectedImage == g_IEIcons[nIndex].nDefaultIcon))
- {
- nIcon = g_IEIcons[nIndex].nIEIcon;
- if (piSelectedImage)
- *piSelectedImage = nIcon;
- break;
- }
- }
- return nIcon;
- }
- void IEInvalidateImageList(void)
- {
- g_IEIcons[0].nDefaultIcon = -1;
- }
- int _GetIEHTMLImageIndex()
- {
- if (-1 == g_IEIcons[0].nDefaultIcon)
- _GenerateIEIcons();
- return g_IEIcons[0].nIEIcon;
- }
- // Checks to see if any process at all
- // has loaded wininet
- static BOOL g_fWininetLoadedSomeplace = FALSE;
- BOOL IsWininetLoadedAnywhere()
- {
- HANDLE hMutex = NULL;
- BOOL fRet;
- if(g_fWininetLoadedSomeplace)
- return TRUE;
- //
- // Use OpenMutexA so it works on W95.
- // wininet is ansi and created this mutex with CreateMutexA
- hMutex = OpenMutexA(SYNCHRONIZE, FALSE, WININET_STARTUP_MUTEX);
- if(hMutex)
- {
- fRet = TRUE;
- g_fWininetLoadedSomeplace = TRUE;
- CloseHandle(hMutex);
- }
- else
- {
- fRet = FALSE;
- }
- return fRet;
- }
- // Checks if global state is offline
- BOOL SHIsGlobalOffline(void)
- {
- DWORD dwState = 0, dwSize = sizeof(DWORD);
- BOOL fRet = FALSE;
- if(!IsWininetLoadedAnywhere())
- return FALSE;
- // Since wininet is already loaded someplace
- // We have to load wininet to check if offline
- if(InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState,
- &dwSize))
- {
- if(dwState & INTERNET_STATE_DISCONNECTED_BY_USER)
- fRet = TRUE;
- }
- return fRet;
- }
- void SetGlobalOffline(BOOL fOffline)
- {
- INTERNET_CONNECTED_INFO ci;
- memset(&ci, 0, sizeof(ci));
- if(fOffline) {
- ci.dwConnectedState = INTERNET_STATE_DISCONNECTED_BY_USER;
- ci.dwFlags = ISO_FORCE_DISCONNECTED;
- } else {
- ci.dwConnectedState = INTERNET_STATE_CONNECTED;
- }
- InternetSetOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
- }
- // This API is documented and is called by apps outside
- // the shell such as OE
- #ifdef UNIX
- extern "C"
- #endif
- void SetShellOfflineState(BOOL fPutOffline)
- {
- BOOL fWasOffline = SHIsGlobalOffline();
- if(fWasOffline != fPutOffline)
- {
- SetGlobalOffline(fPutOffline); // Set the state
- // Tell all browser windows to update their title
- SendShellIEBroadcastMessage(WM_WININICHANGE,0,0, 1000);
- }
- }
- BOOL GetHistoryFolderPath(LPTSTR pszPath, int cchPath)
- {
- INTERNET_CACHE_CONFIG_INFO cci;
- DWORD cbcci = sizeof(INTERNET_CACHE_CONFIG_INFO);
- if (GetUrlCacheConfigInfo(&cci, &cbcci, CACHE_CONFIG_HISTORY_PATHS_FC))
- {
- StrCpyN(pszPath, cci.CachePaths[0].CachePath, cchPath);
- return TRUE;
- }
- return FALSE;
- }
- #ifndef POSTPOSTSPLIT
- // in:
- // pidlRoot root part of pidl.
- // pidl equal to or child below pidlRoot
- // pszKey root key to store stuff under, should match pidlRoot
- // grfMode read/write
- //
- // example:
- // pidlRoot = c:winfavorites
- // pidl = c:winfavoriteschannels
- // pszKey = "MenuOrderFavorites"
- // result -> stream comes from HKCU...MenuOrderFavoriteschannels
- //
- IStream * OpenPidlOrderStream(LPCITEMIDLIST pidlRoot, LPCITEMIDLIST pidl, LPCSTR pszKey, DWORD grfMode)
- {
- LPITEMIDLIST pidlAlloc = NULL;
- TCHAR szRegPath[MAX_URL_STRING];
- TCHAR szKey[MAXIMUM_SUB_KEY_LENGTH];
- SHAnsiToTChar(pszKey, szKey, ARRAYSIZE(szKey));
- StrCpyN(szRegPath, TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer"), ARRAYSIZE(szRegPath));
- StrCatBuff(szRegPath, szKey, ARRAYSIZE(szRegPath));
- // deal with ordinal vs true pidls
- if (HIWORD(pidlRoot) == 0)
- {
- // Sundown: coercion to int since we are assuming ordinal pidl
- SHGetSpecialFolderLocation(NULL, PtrToLong(pidlRoot), &pidlAlloc);
- pidlRoot = pidlAlloc;
- }
- // build a reg key from the names of the items below the pidlRoot folder. we do
- // this because IEGetDisplayName(SFGAO_FORPARSING) has a bug for file system
- // junctions (channel contents) that returns garbage path names.
- if (pidlRoot)
- {
- LPITEMIDLIST pidlCopy = ILClone(pidl);
- if (pidlCopy)
- {
- LPCITEMIDLIST pidlTail = ILFindChild(pidlRoot, pidlCopy);
- if (pidlTail)
- {
- LPITEMIDLIST pidlNext;
- for (pidlNext = ILGetNext(pidlTail); pidlNext; pidlNext = ILGetNext(pidlNext))
- {
- WORD cbSave = pidlNext->mkid.cb;
- pidlNext->mkid.cb = 0;
- IShellFolder *psf;
- LPCITEMIDLIST pidlChild;
- // we do a full bind every time, we could skip this for sub items
- // and bind from this point down but this code is simpler and binds
- // aren't that bad...
- if (SUCCEEDED(IEBindToParentFolder(pidlCopy, &psf, &pidlChild)))
- {
- STRRET sr;
- if (SUCCEEDED(psf->GetDisplayNameOf(pidlChild, SHGDN_NORMAL, &sr)))
- {
- LPTSTR pszName;
- if (SUCCEEDED(StrRetToStr(&sr, pidlChild, &pszName)))
- {
- StrCatBuff(szRegPath, TEXT("\"), ARRAYSIZE(szRegPath));
- StrCatBuff(szRegPath, pszName, ARRAYSIZE(szRegPath));
- CoTaskMemFree(pszName);
- }
- }
- psf->Release();
- }
- pidlNext->mkid.cb = cbSave;
- }
- }
- ILFree(pidlCopy);
- }
- if (pidlAlloc)
- ILFree(pidlAlloc);
- return SHOpenRegStream(HKEY_CURRENT_USER, szRegPath, TEXT("Order"), grfMode);
- }
- return NULL;
- }
- #endif
- HRESULT GetHTMLElementID(IHTMLElement *pielem, LPTSTR pszName, DWORD cchSize)
- {
- // only do this persistence thing if we're in ( or completing ) an operation
- BSTR bstrID = NULL;
- HRESULT hr;
- if (!pielem)
- hr = E_INVALIDARG;
- else if (SUCCEEDED(hr = pielem->get_id(&bstrID)))
- {
- SHUnicodeToTChar(bstrID, pszName, cchSize);
- SysFreeString(bstrID);
- }
- return hr;
- }
- /**********************************************************************
- * SHRestricted2
- *
- * These are new restrictions that apply to browser only and integrated
- * mode. (Since we're not changing shell32 in browser only mode, we
- * need to duplicate the functionality.)
- *
- * BUGBUG: What window will listen to the WM_WININICHANGE
- * lParam="Policy" message and invalidate the cache?
- * Remember not to cache the per zone values.
- **********************************************************************/
- // The ZAW compliant policy location.
- const TCHAR c_szInfodeliveryBase[] = TEXT("Software\Policies\Microsoft\Internet Explorer\Infodelivery");
- const TCHAR c_szInfodeliveryKey[] = TEXT("Restrictions");
- // The normal policy location.
- const TCHAR c_szExplorerBase[] = TEXT("Software\Microsoft\Windows\CurrentVersion\Policies");
- const TCHAR c_szExplorerKey[] = TEXT("Explorer");
- // The browser policy location that SP2 used
- const TCHAR c_szBrowserBase[] = TEXT("Software\Policies\Microsoft\Internet Explorer");
- const TCHAR c_szBrowserKey[] = TEXT("Restrictions");
- const TCHAR c_szToolbarKey[] = TEXT("Toolbars\Restrictions");
- const SHRESTRICTIONITEMS c_rgRestrictionItems[] =
- {
- // explorer restrictions
- { REST_NOTOOLBARCUSTOMIZE, c_szExplorerKey, TEXT("NoToolbarCustomize") },
- { REST_NOBANDCUSTOMIZE, c_szExplorerKey, TEXT("NoBandCustomize") },
- { REST_SMALLICONS, c_szExplorerKey, TEXT("SmallIcons") },
- { REST_LOCKICONSIZE, c_szExplorerKey, TEXT("LockIconSize") },
- { REST_SPECIFYDEFAULTBUTTONS, c_szExplorerKey, TEXT("SpecifyDefaultButtons") },
- { REST_BTN_BACK, c_szExplorerKey, TEXT("Btn_Back") },
- { REST_BTN_FORWARD, c_szExplorerKey, TEXT("Btn_Forward") },
- { REST_BTN_STOPDOWNLOAD, c_szExplorerKey, TEXT("Btn_Stop") },
- { REST_BTN_REFRESH, c_szExplorerKey, TEXT("Btn_Refresh") },
- { REST_BTN_HOME, c_szExplorerKey, TEXT("Btn_Home") },
- { REST_BTN_SEARCH, c_szExplorerKey, TEXT("Btn_Search") },
- { REST_BTN_HISTORY, c_szExplorerKey, TEXT("Btn_History") },
- { REST_BTN_FAVORITES, c_szExplorerKey, TEXT("Btn_Favorites") },
- { REST_BTN_ALLFOLDERS, c_szExplorerKey, TEXT("Btn_Folders") },
- { REST_BTN_THEATER, c_szExplorerKey, TEXT("Btn_Fullscreen") },
- { REST_BTN_TOOLS, c_szExplorerKey, TEXT("Btn_Tools") },
- { REST_BTN_MAIL, c_szExplorerKey, TEXT("Btn_MailNews") },
- { REST_BTN_FONTS, c_szExplorerKey, TEXT("Btn_Size") },
- { REST_BTN_PRINT, c_szExplorerKey, TEXT("Btn_Print") },
- { REST_BTN_EDIT, c_szExplorerKey, TEXT("Btn_Edit") },
- { REST_BTN_DISCUSSIONS, c_szExplorerKey, TEXT("Btn_Discussions") },
- { REST_BTN_CUT, c_szExplorerKey, TEXT("Btn_Cut") },
- { REST_BTN_COPY, c_szExplorerKey, TEXT("Btn_Copy") },
- { REST_BTN_PASTE, c_szExplorerKey, TEXT("Btn_Paste") },
- { REST_BTN_ENCODING, c_szExplorerKey, TEXT("Btn_Encoding") },
- { REST_NoUserAssist, c_szExplorerKey, TEXT("NoInstrumentation"), },
- { REST_NoWindowsUpdate, c_szExplorerKey, TEXT("NoWindowsUpdate"), },
- { REST_NoExpandedNewMenu, c_szExplorerKey, TEXT("NoExpandedNewMenu"), },
- // ported from SP1
- { REST_NOFILEURL, c_szExplorerKey, TEXT("NoFileUrl"), },
- // infodelivery restrictions
- { REST_NoChannelUI, c_szInfodeliveryKey, TEXT("NoChannelUI") },
- { REST_NoAddingChannels, c_szInfodeliveryKey, TEXT("NoAddingChannels") },
- { REST_NoEditingChannels, c_szInfodeliveryKey, TEXT("NoEditingChannels") },
- { REST_NoRemovingChannels, c_szInfodeliveryKey, TEXT("NoRemovingChannels") },
- { REST_NoAddingSubscriptions, c_szInfodeliveryKey, TEXT("NoAddingSubscriptions") },
- { REST_NoEditingSubscriptions, c_szInfodeliveryKey, TEXT("NoEditingSubscriptions") },
- { REST_NoRemovingSubscriptions, c_szInfodeliveryKey, TEXT("NoRemovingSubscriptions") },
- { REST_NoChannelLogging, c_szInfodeliveryKey, TEXT("NoChannelLogging") },
- { REST_NoManualUpdates, c_szInfodeliveryKey, TEXT("NoManualUpdates") },
- { REST_NoScheduledUpdates, c_szInfodeliveryKey, TEXT("NoScheduledUpdates") },
- { REST_NoUnattendedDialing, c_szInfodeliveryKey, TEXT("NoUnattendedDialing") },
- { REST_NoChannelContent, c_szInfodeliveryKey, TEXT("NoChannelContent") },
- { REST_NoSubscriptionContent, c_szInfodeliveryKey, TEXT("NoSubscriptionContent") },
- { REST_NoEditingScheduleGroups, c_szInfodeliveryKey, TEXT("NoEditingScheduleGroups") },
- { REST_MaxChannelSize, c_szInfodeliveryKey, TEXT("MaxChannelSize") },
- { REST_MaxSubscriptionSize, c_szInfodeliveryKey, TEXT("MaxSubscriptionSize") },
- { REST_MaxChannelCount, c_szInfodeliveryKey, TEXT("MaxChannelCount") },
- { REST_MaxSubscriptionCount, c_szInfodeliveryKey, TEXT("MaxSubscriptionCount") },
- { REST_MinUpdateInterval, c_szInfodeliveryKey, TEXT("MinUpdateInterval") },
- { REST_UpdateExcludeBegin, c_szInfodeliveryKey, TEXT("UpdateExcludeBegin") },
- { REST_UpdateExcludeEnd, c_szInfodeliveryKey, TEXT("UpdateExcludeEnd") },
- { REST_UpdateInNewProcess, c_szInfodeliveryKey, TEXT("UpdateInNewProcess") },
- { REST_MaxWebcrawlLevels, c_szInfodeliveryKey, TEXT("MaxWebcrawlLevels") },
- { REST_MaxChannelLevels, c_szInfodeliveryKey, TEXT("MaxChannelLevels") },
- { REST_NoSubscriptionPasswords, c_szInfodeliveryKey, TEXT("NoSubscriptionPasswords")},
- { REST_NoBrowserSaveWebComplete,c_szInfodeliveryKey, TEXT("NoBrowserSaveWebComplete") },
- { REST_NoSearchCustomization, c_szInfodeliveryKey, TEXT("NoSearchCustomization"), },
- { REST_NoSplash, c_szInfodeliveryKey, TEXT("NoSplash"), },
- // browser restrictions ported from SP2
- { REST_NoFileOpen, c_szBrowserKey, TEXT("NoFileOpen"), },
- { REST_NoFileNew, c_szBrowserKey, TEXT("NoFileNew"), },
- { REST_NoBrowserSaveAs , c_szBrowserKey, TEXT("NoBrowserSaveAs"), },
- { REST_NoBrowserOptions, c_szBrowserKey, TEXT("NoBrowserOptions"), },
- { REST_NoFavorites, c_szBrowserKey, TEXT("NoFavorites"), },
- { REST_NoSelectDownloadDir, c_szBrowserKey, TEXT("NoSelectDownloadDir"), },
- { REST_NoBrowserContextMenu, c_szBrowserKey, TEXT("NoBrowserContextMenu"), },
- { REST_NoBrowserClose, c_szBrowserKey, TEXT("NoBrowserClose"), },
- { REST_NoOpeninNewWnd, c_szBrowserKey, TEXT("NoOpeninNewWnd"), },
- { REST_NoTheaterMode, c_szBrowserKey, TEXT("NoTheaterMode"), },
- { REST_NoFindFiles, c_szBrowserKey, TEXT("NoFindFiles"), },
- { REST_NoViewSource, c_szBrowserKey, TEXT("NoViewSource"), },
- { REST_GoMenu, c_szBrowserKey, TEXT("RestGoMenu"), },
- { REST_NoToolbarOptions, c_szToolbarKey, TEXT("NoToolbarOptions"), },
- { REST_AlwaysPromptWhenDownload,c_szBrowserKey, TEXT("AlwaysPromptWhenDownload"),},
- { REST_NoHelpItem_TipOfTheDay, c_szBrowserKey, TEXT("NoHelpItemTipOfTheDay"), },
- { REST_NoHelpItem_NetscapeHelp, c_szBrowserKey, TEXT("NoHelpItemNetscapeHelp"), },
- { REST_NoHelpItem_Tutorial, c_szBrowserKey, TEXT("NoHelpItemTutorial"), },
- { REST_NoHelpItem_SendFeedback, c_szBrowserKey, TEXT("NoHelpItemSendFeedback"), },
- { REST_NoNavButtons, c_szBrowserKey, TEXT("NoNavButtons"), },
- { REST_NoHelpMenu, c_szBrowserKey, TEXT("NoHelpMenu"), },
- { REST_NoBrowserBars, c_szBrowserKey, TEXT("NoBrowserBars"), },
- { REST_NoToolBar, c_szToolbarKey, TEXT("NoToolBar"), },
- { REST_NoAddressBar, c_szToolbarKey, TEXT("NoAddressBar"), },
- { REST_NoLinksBar, c_szToolbarKey, TEXT("NoLinksBar"), },
- {0, NULL, NULL},
- };
- typedef struct {
- BROWSER_RESTRICTIONS rest;
- DWORD dwAction;
- } ACTIONITEM;
- const ACTIONITEM c_ActionItems[] = {
- { REST_NoAddingChannels, URLACTION_INFODELIVERY_NO_ADDING_CHANNELS },
- { REST_NoEditingChannels, URLACTION_INFODELIVERY_NO_EDITING_CHANNELS },
- { REST_NoRemovingChannels, URLACTION_INFODELIVERY_NO_REMOVING_CHANNELS },
- { REST_NoAddingSubscriptions, URLACTION_INFODELIVERY_NO_ADDING_SUBSCRIPTIONS },
- { REST_NoEditingSubscriptions, URLACTION_INFODELIVERY_NO_EDITING_SUBSCRIPTIONS },
- { REST_NoRemovingSubscriptions, URLACTION_INFODELIVERY_NO_REMOVING_SUBSCRIPTIONS },
- { REST_NoChannelLogging, URLACTION_INFODELIVERY_NO_CHANNEL_LOGGING },
- };
- #define REST_WITHACTION_FIRST REST_NoAddingChannels
- #define REST_WITHACTION_LAST REST_NoChannelLogging
- #define RESTRICTIONMAX (c_rgRestrictionItems[ARRAYSIZE(c_rgRestrictionItems) - 1].rest)
- DWORD g_rgRestrictionItemValues[ARRAYSIZE(c_rgRestrictionItems)];
- DWORD SHRestricted2W(BROWSER_RESTRICTIONS rest, LPCWSTR pwzUrl, DWORD dwReserved)
- {
- // Validate restriction and dwReserved
- if (dwReserved)
- {
- RIPMSG(0, "SHRestricted2W: Invalid dwReserved");
- return 0;
- }
- if (!(InRange(rest, REST_EXPLORER_FIRST, REST_EXPLORER_LAST))
- && !(InRange(rest, REST_INFO_FIRST, REST_INFO_LAST))
- && !(InRange(rest, REST_BROWSER_FIRST, REST_BROWSER_LAST)))
- {
- RIPMSG(0, "SHRestricted2W: Invalid browser restriction");
- return 0;
- }
- // See if the restriction is in place in the URL zone
- // BUGBUG: Should we assert on NULL URLs if the restriction is per zone?
- // It might be reasonable to query the global setting.
- if (pwzUrl && InRange(rest, REST_WITHACTION_FIRST, REST_WITHACTION_LAST))
- {
- // Compute the index into the table
- int index = rest - REST_WITHACTION_FIRST;
- ASSERT(c_ActionItems[index].dwAction);
- IInternetSecurityManager *pism = NULL;
- HRESULT hr;
- hr = CoCreateInstance(CLSID_InternetSecurityManager, NULL, CLSCTX_INPROC_SERVER,
- IID_IInternetSecurityManager, (void**)&pism);
- if (SUCCEEDED(hr) && pism)
- {
- DWORD dwPolicy = 0;
- DWORD dwContext = 0;
- hr = pism->ProcessUrlAction(pwzUrl,
- c_ActionItems[index].dwAction,
- (BYTE *)&dwPolicy,
- sizeof(dwPolicy),
- (BYTE *)&dwContext,
- sizeof(dwContext),
- PUAF_NOUI,
- 0);
- pism->Release();
- if (SUCCEEDED(hr))
- {
- if (GetUrlPolicyPermissions(dwPolicy) == URLPOLICY_ALLOW)
- return 0;
- else
- return 1; // restrict for query and disallow
- }
- }
- }
- // The cache may be invalid. Check first! We have to use
- // a global named semaphore in case this function is called
- // from a process other than the shell process. (And we're
- // sharing the same count between shell32 and shdocvw.)
- static HANDLE hRestrictions = NULL;
- static long lRestrictionCount = -1;
- if (hRestrictions == NULL)
- hRestrictions = SHGlobalCounterCreate(GUID_Restrictions);
- long lGlobalCount = SHGlobalCounterGetValue(hRestrictions);
- if (lGlobalCount != lRestrictionCount)
- {
- memset((LPBYTE)g_rgRestrictionItemValues, (BYTE)-1, SIZEOF(g_rgRestrictionItemValues));
- lRestrictionCount = lGlobalCount;
- }
- LPCWSTR pszBaseKey;
- if (InRange(rest, REST_EXPLORER_FIRST, REST_EXPLORER_LAST))
- pszBaseKey = c_szExplorerBase;
- else
- {
- if (InRange(rest, REST_BROWSER_FIRST, REST_BROWSER_LAST))
- pszBaseKey = c_szBrowserBase;
- else
- pszBaseKey = c_szInfodeliveryBase;
- }
- return SHRestrictionLookup(rest, pszBaseKey, c_rgRestrictionItems, g_rgRestrictionItemValues);
- }
- DWORD SHRestricted2A(BROWSER_RESTRICTIONS rest, LPCSTR pszUrl, DWORD dwReserved)
- {
- if (pszUrl)
- {
- WCHAR wzUrl[MAX_URL_STRING];
- ASSERT(ARRAYSIZE(wzUrl) > lstrlenA(pszUrl)); // We only work for Urls of MAX_URL_STRING or shorter.
- AnsiToUnicode(pszUrl, wzUrl, ARRAYSIZE(wzUrl));
- return SHRestricted2W(rest, wzUrl, dwReserved);
- }
- else
- {
- return SHRestricted2W(rest, NULL, dwReserved);
- }
- }
- /**********************************************************************
- *
- **********************************************************************/
- #define MAX_SUBSTR_SIZE 100
- typedef struct tagURLSub
- {
- LPCTSTR szTag;
- DWORD dwType;
- } URLSUB;
- const static URLSUB c_UrlSub[] = {
- {TEXT("{SUB_CLSID}"), URLSUB_CLSID},
- {TEXT("{SUB_PRD}"), URLSUB_PRD},
- {TEXT("{SUB_PVER}"), URLSUB_PVER},
- {TEXT("{SUB_OS}"), URLSUB_OS},
- {TEXT("{SUB_RFC1766}"), URLSUB_RFC1766}
- };
- void GetWebLocaleAsRFC1766(LPTSTR pszLocale, int cchLocale)
- {
- LCID lcid;
- TCHAR szValue[MAX_PATH];
- DWORD cbVal = sizeof(szValue);
- DWORD dwType;
- ASSERT(NULL != pszLocale);
- *pszLocale = TEXT('');
- if ((SHGetValue(HKEY_CURRENT_USER, REGSTR_PATH_INTERNATIONAL,
- REGSTR_VAL_ACCEPT_LANGUAGE,
- &dwType, szValue, &cbVal) == ERROR_SUCCESS) &&
- (REG_SZ == dwType))
- {
- TCHAR *psz = szValue;
- // Use the first one we find so terminate at the comma or semicolon
- while (*psz && (*psz != TEXT(',')) && (*psz != TEXT(';')))
- {
- psz = CharNext(psz);
- }
- *psz = TEXT('');
- // If it's user defined, this will fail and we will fall back
- // to the system default.
- if (SUCCEEDED(Rfc1766ToLcid(&lcid, szValue)))
- {
- StrCpyN(pszLocale, szValue, cchLocale);
- }
- }
- if (TEXT('') == *pszLocale)
- {
- // No entry in the registry or it's a user defined header.
- // Either way we fall back to the system default.
- LcidToRfc1766(GetUserDefaultLCID(), pszLocale, cchLocale);
- }
- }
- HRESULT URLSubstitution(LPCWSTR pszUrlIn, LPWSTR pszUrlOut, DWORD cchSize, DWORD dwSubstitutions)
- {
- HRESULT hr = S_OK;
- DWORD dwIndex;
- WCHAR szTempUrl[MAX_URL_STRING];
- ASSERT(cchSize <= ARRAYSIZE(szTempUrl)); // We will truncate anything longer than MAX_URL_STRING
- StrCpyNW(szTempUrl, pszUrlIn, ARRAYSIZE(szTempUrl));
- for (dwIndex = 0; dwIndex < ARRAYSIZE(c_UrlSub); dwIndex++)
- {
- while (IsFlagSet(dwSubstitutions, c_UrlSub[dwIndex].dwType))
- {
- LPWSTR pszTag = StrStr(szTempUrl, c_UrlSub[dwIndex].szTag);
- if (pszTag)
- {
- TCHAR szCopyUrl[MAX_URL_STRING];
- TCHAR szSubStr[MAX_SUBSTR_SIZE]; // The Substitution
- // Copy URL Before Substitution.
- StrCpyN(szCopyUrl, szTempUrl, (int)(pszTag-szTempUrl+1));
- pszTag += lstrlen(c_UrlSub[dwIndex].szTag);
- switch (c_UrlSub[dwIndex].dwType)
- {
- case URLSUB_CLSID:
- {
- // REVIEW (tnoonan)
- // Should we be using the inetcpl locale settings here?
- LCID lcid = GetUserDefaultLCID();
- wnsprintf(szSubStr, ARRAYSIZE(szSubStr), TEXT("%#04lx"), lcid);
- }
- break;
- case URLSUB_PRD:
- MLLoadString(IDS_SUBSTR_PRD, szSubStr, ARRAYSIZE(szSubStr));
- break;
- case URLSUB_PVER:
- MLLoadString(IDS_SUBSTR_PVER, szSubStr, ARRAYSIZE(szSubStr));
- break;
- case URLSUB_OS:
- if (g_bRunOnMemphis)
- {
- StrCpyN(szSubStr, TEXT("98"), ARRAYSIZE(szSubStr));
- }
- else if (g_fRunningOnNT)
- {
- if (g_bRunOnNT5)
- StrCpyN(szSubStr, TEXT("N5"), ARRAYSIZE(szSubStr));
- else
- StrCpyN(szSubStr, TEXT("N4"), ARRAYSIZE(szSubStr));
- }
- else
- {
- StrCpyN(szSubStr, TEXT("95"), ARRAYSIZE(szSubStr));
- }
- break;
- case URLSUB_RFC1766:
- GetWebLocaleAsRFC1766(szSubStr, ARRAYSIZE(szSubStr));
- break;
- default:
- szSubStr[0] = TEXT('');
- ASSERT(FALSE); // Not Impl.
- hr = E_NOTIMPL;
- break;
- }
- // Add the Substitution String to the end (will become the middle)
- StrCatBuff(szCopyUrl, szSubStr, ARRAYSIZE(szCopyUrl));
- // Add the rest of the URL after the substitution substring.
- StrCatBuff(szCopyUrl, pszTag, ARRAYSIZE(szCopyUrl));
- StrCpyN(szTempUrl, szCopyUrl, ARRAYSIZE(szTempUrl));
- }
- else
- break; // This will allow us to replace all the occurances of this string.
- }
- }
- StrCpyN(pszUrlOut, szTempUrl, cchSize);
- return hr;
- }
- // inetcpl.cpl uses this.
- STDAPI URLSubRegQueryA(LPCSTR pszKey, LPCSTR pszValue, BOOL fUseHKCU,
- LPSTR pszUrlOut, DWORD cchSizeOut, DWORD dwSubstitutions)
- {
- HRESULT hr;
- TCHAR szKey[MAX_PATH];
- TCHAR szValue[MAX_PATH];
- TCHAR szUrlOut[MAX_URL_STRING];
- AnsiToTChar(pszKey, szKey, ARRAYSIZE(szKey));
- AnsiToTChar(pszValue, szValue, ARRAYSIZE(szValue));
- hr = URLSubRegQueryW(szKey, szValue, fUseHKCU, szUrlOut, ARRAYSIZE(szUrlOut), dwSubstitutions);
- TCharToAnsi(szUrlOut, pszUrlOut, cchSizeOut);
- return hr;
- }
- HRESULT URLSubRegQueryW(LPCWSTR pszKey, LPCWSTR pszValue, BOOL fUseHKCU,
- LPWSTR pszUrlOut, DWORD cchSizeOut, DWORD dwSubstitutions)
- {
- HRESULT hr = E_FAIL;
- WCHAR szTempUrl[MAX_URL_STRING];
- DWORD ccbSize = sizeof(szTempUrl);
- if (ERROR_SUCCESS == SHRegGetUSValueW(pszKey, pszValue, NULL, szTempUrl,
- &ccbSize, !fUseHKCU, NULL, NULL))
- {
- hr = URLSubstitution(szTempUrl, pszUrlOut, cchSizeOut, dwSubstitutions);
- }
- return hr;
- }
- // note that anyone inside shdocvw should pass hInst==NULL to
- // ensure that pluggable UI works correctly. anyone outside of shdocvw
- // must pass an hInst for their appropriate resource dll
- HRESULT URLSubLoadString(HINSTANCE hInst, UINT idRes, LPWSTR pszUrlOut,
- DWORD cchSizeOut, DWORD dwSubstitutions)
- {
- HRESULT hr = E_FAIL;
- WCHAR szTempUrl[MAX_URL_STRING];
- int nStrLen;
- nStrLen = 0;
- if (hInst == NULL)
- {
- // this is for internal users who want pluggable UI to work
- nStrLen = MLLoadStringW(idRes, szTempUrl, ARRAYSIZE(szTempUrl));
- }
- else
- {
- // this is for external users who use us to load some
- // of their own resources but whom we can't change (like shell32)
- nStrLen = LoadStringWrap(hInst, idRes, szTempUrl, ARRAYSIZE(szTempUrl));
- }
- if (nStrLen > 0)
- {
- hr = URLSubstitution(szTempUrl, pszUrlOut, cchSizeOut, dwSubstitutions);
- }
- return hr;
- }
- /**********************************************************************
- FUNCTION: ILIsWeb
- DESCRIPTION:
- ILIsUrlChild() will find pidls that exist under "DesktopThe Internet"
- section of the Shell Name Space. This function includes those items
- and file system items that have a "txt/html.
- **********************************************************************/
- BOOL ILIsWeb(LPCITEMIDLIST pidl)
- {
- BOOL fIsWeb = FALSE;
- if (pidl)
- {
- if (IsURLChild(pidl, TRUE))
- fIsWeb = TRUE;
- else
- {
- TCHAR szPath[MAX_PATH];
- fIsWeb = (!ILIsRooted(pidl)
- && SUCCEEDED(SHGetPathFromIDList(pidl, szPath))
- && (PathIsHTMLFile(szPath) ||
- PathIsContentType(szPath, TEXT("text/xml"))));
- }
- }
- return fIsWeb;
- }
- //
- // in:
- // pidlTo
- STDAPI CreateLinkToPidl(LPCITEMIDLIST pidlTo, LPCTSTR pszDir, LPCTSTR pszTitle, LPTSTR pszOut, int cchOut)
- {
- HRESULT hres = E_FAIL;
- TCHAR szPathDest[MAX_URL_STRING];
- BOOL fCopyLnk;
- if (SHGetNewLinkInfo((LPCTSTR)pidlTo, pszDir, szPathDest, &fCopyLnk, SHGNLI_PIDL))
- {
- IShellLinkA *pslA; // Use A version for W95.
- if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkA, (void**)&pslA)))
- {
- TCHAR szPathSrc[MAX_URL_STRING];
- DWORD dwAttributes = SFGAO_FILESYSTEM | SFGAO_FOLDER;
- // get source
- BOOL fPath = SUCCEEDED(SHGetNameAndFlags(pidlTo, SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, szPathSrc, ARRAYSIZE(szPathSrc), &dwAttributes));
- if (fCopyLnk)
- {
- if (((dwAttributes & (SFGAO_FILESYSTEM | SFGAO_FOLDER)) == SFGAO_FILESYSTEM) && CopyFile(szPathSrc, szPathDest, TRUE))
- {
- SHChangeNotify(SHCNE_CREATE, SHCNF_PATH, szPathDest, NULL);
- SHChangeNotify(SHCNE_FREESPACE, SHCNF_PATH, szPathDest, NULL);
- hres = S_OK;
- }
- else
- {
- // load the source object that will be "copied" below (with the ::Save call)
- SAFERELEASE(pslA);
- hres = SHGetUIObjectFromFullPIDL(pidlTo, NULL, IID_IShellLinkA, (void **)&pslA);
- // this pslA is released at the end of the topmost if
- if (SUCCEEDED(hres))
- {
- IPersistFile *ppf;
- hres = pslA->QueryInterface(IID_IPersistFile, (void**)&ppf);
- if (SUCCEEDED(hres))
- {
- hres = ppf->Save(szPathDest, TRUE);
- ppf->Release();
- }
- }
- }
- }
- else
- {
- IPersistFile *ppf;
- pslA->SetIDList(pidlTo);
- //
- // make sure the working directory is set to the same
- // directory as the app (or document).
- //
- // dont do this for non-FS pidls (ie control panel)
- //
- // what about a UNC directory? we go ahead and set
- // it, wont work for a WIn16 app.
- //
- if (fPath && !PathIsDirectory(szPathSrc)) {
- ASSERT(!PathIsRelative(szPathSrc));
- PathRemoveFileSpec(szPathSrc);
- // Try to get the W version.
- IShellLinkW* pslW;
- if (SUCCEEDED(pslA->QueryInterface(IID_IShellLinkW, (void**)&pslW)))
- {
- ASSERT(pslW);
- pslW->SetWorkingDirectory(szPathSrc);
- pslW->Release();
- }
- else
- {
- CHAR szPathSrcA[MAX_URL_STRING];
- SHUnicodeToAnsi(szPathSrc, szPathSrcA, ARRAYSIZE(szPathSrcA));
- pslA->SetWorkingDirectory(szPathSrcA);
- }
- }
- hres = pslA->QueryInterface(IID_IPersistFile, (void **)&ppf);
- if (SUCCEEDED(hres)) {
- WCHAR wszPath[ARRAYSIZE(szPathDest)];
- if (pszTitle && pszTitle[0]) {
- PathRemoveFileSpec(szPathDest);
- PathAppend(szPathDest, pszTitle);
- StrCatBuff(szPathDest, TEXT(".lnk"), ARRAYSIZE(szPathDest));
- }
- SHTCharToUnicode(szPathDest, wszPath, ARRAYSIZE(wszPath));
- hres = ppf->Save(wszPath, TRUE);
- if (pszOut)
- {
- StrCpyN(pszOut, wszPath, cchOut);
- }
- ppf->Release();
- }
- }
- pslA->Release();
- }
- }
- return hres;
- }
- #ifndef POSTPOSTSPLIT
- int GetColorComponent(LPTSTR *ppsz)
- {
- int iColor = 0;
- if (*ppsz) {
- LPTSTR pBuf = *ppsz;
- iColor = StrToInt(pBuf);
- // find the next comma
- while(pBuf && *pBuf && *pBuf!=TEXT(','))
- pBuf++;
- // if valid and not NULL...
- if (pBuf && *pBuf)
- pBuf++; // increment
- *ppsz = pBuf;
- }
- return iColor;
- }
- // Read the registry for a string (REG_SZ) of comma separated RGB values
- COLORREF RegGetColorRefString( HKEY hkey, LPTSTR RegValue, COLORREF Value)
- {
- TCHAR SmallBuf[80];
- TCHAR *pBuf;
- DWORD cb;
- int iRed, iGreen, iBlue;
- cb = ARRAYSIZE(SmallBuf);
- if (RegQueryValueEx(hkey, RegValue, NULL, NULL, (LPBYTE)&SmallBuf, &cb)
- == ERROR_SUCCESS)
- {
- pBuf = SmallBuf;
- iRed = GetColorComponent(&pBuf);
- iGreen = GetColorComponent(&pBuf);
- iBlue = GetColorComponent(&pBuf);
- // make sure all values are valid
- iRed %= 256;
- iGreen %= 256;
- iBlue %= 256;
- Value = RGB(iRed, iGreen, iBlue);
- }
- return Value;
- }
- #endif
- #ifdef DEBUG // {
- //*** SearchDW -- scan for DWORD in buffer
- // ENTRY/EXIT
- // pdwBuf buffer
- // cbBuf size of buffer in *bytes* (*not* DWORDs)
- // dwVal DWORD we're looking for
- // dOff (return) byte offset in buffer; o.w. -1 if not found
- //
- int SearchDW(DWORD *pdwBuf, int cbBuf, DWORD dwVal)
- {
- int dOff;
- for (dOff = 0; dOff < cbBuf; dOff += SIZEOF(DWORD), pdwBuf++) {
- if (*pdwBuf == dwVal)
- return dOff;
- }
- return -1;
- }
- #endif // }
- // NOTE: These are directly copied from fsnotify.c in shell32. Please make sure
- // NOTE: any changes are reflected there also.
- // this is the NEW SHCNE_UPDATEIMAGE stuff, it passes renough data so that the recieving process
- // has a vague chance that it can find the right index to refresh.
- extern "C" void WINAPI _SHUpdateImageA( LPCSTR pszHashItem, int iIndex, UINT uFlags, int iImageIndex )
- {
- WCHAR szWHash[MAX_PATH];
- MultiByteToWideChar( CP_ACP, 0, pszHashItem, -1, szWHash, MAX_PATH );
- _SHUpdateImageW( szWHash, iIndex, uFlags, iImageIndex );
- }
- extern "C" void WINAPI _SHUpdateImageW( LPCWSTR pszHashItem, int iIndex, UINT uFlags, int iImageIndex )
- {
- SHChangeUpdateImageIDList rgPidl;
- SHChangeDWORDAsIDList rgDWord;
- int cLen = MAX_PATH - (lstrlenW( pszHashItem ) + 1);
- cLen *= sizeof( WCHAR );
- if ( cLen < 0 )
- cLen = 0;
- // make sure we send a valid index
- if ( iImageIndex == -1 )
- iImageIndex = II_DOCUMENT;
- rgPidl.dwProcessID = GetCurrentProcessId();
- rgPidl.iIconIndex = iIndex;
- rgPidl.iCurIndex = iImageIndex;
- rgPidl.uFlags = uFlags;
- StrCpyNW( rgPidl.szName, pszHashItem, MAX_PATH );
- rgPidl.cb = (USHORT)(sizeof( rgPidl ) - cLen);
- _ILNext( (LPITEMIDLIST) &rgPidl )->mkid.cb = 0;
- rgDWord.cb = (unsigned short) PtrDiff(&rgDWord.cbZero, &rgDWord);
- rgDWord.dwItem1 = (DWORD) iImageIndex;
- rgDWord.dwItem2 = 0;
- rgDWord.cbZero = 0;
- // pump it as an extended event
- SHChangeNotify( SHCNE_UPDATEIMAGE, SHCNF_IDLIST, &rgDWord, &rgPidl );
- }
- // ancient shell API wrapper...
- extern "C" int _WorA_Shell_GetCachedImageIndex(LPCWSTR pszIconPath, int iIconIndex, UINT uIconFlags);
- #ifndef POSTPOSTSPLIT
- extern "C" int WINAPI _SHHandleUpdateImage( LPCITEMIDLIST pidlExtra )
- {
- SHChangeUpdateImageIDList * pUs = (SHChangeUpdateImageIDList*) pidlExtra;
- if ( !pUs )
- {
- return -1;
- }
- // if in the same process, or an old style notification
- if ( pUs->dwProcessID == GetCurrentProcessId())
- {
- return (int) pUs->iCurIndex;
- }
- else
- {
- WCHAR szBuffer[MAX_PATH];
- int iIconIndex = *(int UNALIGNED *)((BYTE *)&pUs->iIconIndex);
- UINT uFlags = *(UINT UNALIGNED *)((BYTE *)&pUs->uFlags);
- ualstrcpynW( szBuffer, pUs->szName, ARRAYSIZE(szBuffer) );
- // we are in a different process, look up the hash in our index to get the right one...
- return _WorA_Shell_GetCachedImageIndex( szBuffer, iIconIndex, uFlags );
- }
- }
- #endif
- HRESULT FormatUrlForDisplay(LPWSTR pwzURL, LPWSTR pwzFriendly, UINT cchBuf, BOOL fSeperate, DWORD dwCodePage)
- {
- const DWORD dwMaxPathLen = 32;
- const DWORD dwMaxHostLen = 32;
- const DWORD dwMaxTemplateLen = 64;
- const DWORD dwElipsisLen = 3;
- const CHAR rgchElipsis[] = "...";
- HRESULT hrRC = E_FAIL;
- HRESULT hr;
- if (pwzURL==NULL || pwzFriendly==NULL)
- return E_POINTER;
- *pwzFriendly = '';
- if (!*pwzURL)
- return S_OK;
- if (!cchBuf)
- return E_FAIL;
- // Wininet can't deal with code pages other than CP_ACP so convert the URL ourself and call InterCrackUrlA
- URL_COMPONENTSA urlComp;
- CHAR rgchScheme[INTERNET_MAX_SCHEME_LENGTH];
- CHAR rgchHostName[INTERNET_MAX_HOST_NAME_LENGTH];
- CHAR rgchUrlPath[MAX_PATH];
- CHAR rgchCanonicalUrl[MAX_URL_STRING];
- LPSTR pszURL;
- DWORD dwLen;
- if((pszURL = (LPSTR)LocalAlloc(LPTR, (cchBuf*2) * sizeof(CHAR))) != NULL)
- {
- SHUnicodeToAnsiCP(dwCodePage, pwzURL, pszURL, cchBuf);
- dwLen = ARRAYSIZE(rgchCanonicalUrl);
- hr = UrlCanonicalizeA(pszURL, rgchCanonicalUrl, &dwLen, 0);
- if (SUCCEEDED(hr))
- {
- ZeroMemory(&urlComp, sizeof(urlComp));
- urlComp.dwStructSize = sizeof(urlComp);
- urlComp.lpszHostName = rgchHostName;
- urlComp.dwHostNameLength = ARRAYSIZE(rgchHostName);
- urlComp.lpszUrlPath = rgchUrlPath;
- urlComp.dwUrlPathLength = ARRAYSIZE(rgchUrlPath);
- urlComp.lpszScheme = rgchScheme;
- urlComp.dwSchemeLength = ARRAYSIZE(rgchScheme);
- hr = InternetCrackUrlA(rgchCanonicalUrl, lstrlenA(rgchCanonicalUrl), 0, &urlComp);
- if (SUCCEEDED(hr))
- {
- DWORD dwPathLen = lstrlenA(rgchUrlPath);
- DWORD dwHostLen = lstrlenA(rgchHostName);
- DWORD dwSchemeLen = lstrlenA(rgchScheme);
- CHAR rgchHostForDisplay[INTERNET_MAX_HOST_NAME_LENGTH];
- CHAR rgchPathForDisplay[MAX_PATH];
- ZeroMemory(rgchHostForDisplay, sizeof(rgchHostForDisplay));
- ZeroMemory(rgchPathForDisplay, sizeof(rgchPathForDisplay));
- if (dwHostLen>dwMaxHostLen)
- {
- DWORD dwOverFlow = dwHostLen - dwMaxHostLen + dwElipsisLen + 1;
- wnsprintfA(rgchHostForDisplay, ARRAYSIZE(rgchHostForDisplay), "%s%s", rgchElipsis, rgchHostName+dwOverFlow);
- dwHostLen = dwMaxHostLen;
- }
- else
- StrCpyNA(rgchHostForDisplay, rgchHostName, ARRAYSIZE(rgchHostForDisplay));