util.cpp
资源名称:shell.rar [点击查看]
上传用户:xhy777
上传日期:2007-02-14
资源大小:24088k
文件大小:146k
源码类别:
系统编程
开发平台:
Visual C++
- if (dwPathLen>dwMaxPathLen)
- {
- DWORD dwOverFlow = dwPathLen - dwMaxPathLen + dwElipsisLen;
- wnsprintfA(rgchPathForDisplay, ARRAYSIZE(rgchPathForDisplay), "/%s%s", rgchElipsis, rgchUrlPath+dwOverFlow);
- dwPathLen = dwMaxPathLen;
- }
- else
- StrCpyNA(rgchPathForDisplay, rgchUrlPath, ARRAYSIZE(rgchPathForDisplay));
- WCHAR rgwchScheme[INTERNET_MAX_SCHEME_LENGTH];
- WCHAR rgwchHostForDisplay[INTERNET_MAX_HOST_NAME_LENGTH];
- WCHAR rgwchPathForDisplay[MAX_PATH];
- WCHAR rgwchUrlPath[MAX_PATH];
- SHAnsiToUnicodeCP(dwCodePage, rgchScheme, rgwchScheme, ARRAYSIZE(rgwchScheme));
- SHAnsiToUnicodeCP(dwCodePage, rgchHostForDisplay, rgwchHostForDisplay, ARRAYSIZE(rgwchHostForDisplay));
- SHAnsiToUnicodeCP(dwCodePage, rgchPathForDisplay, rgwchPathForDisplay, ARRAYSIZE(rgwchPathForDisplay));
- SHAnsiToUnicodeCP(dwCodePage, rgchUrlPath, rgwchUrlPath, ARRAYSIZE(rgwchUrlPath));
- if (fSeperate)
- {
- // Format string as "X from Y"
- WCHAR rgwchTemplate[dwMaxTemplateLen];
- WCHAR *pwzFileName = PathFindFileNameW(rgwchPathForDisplay);
- DWORD dwCount;
- //
- // remove cache decoration goop to map ie5setup[1].exe to ie5setup.exe
- //
- PathUndecorateW(pwzFileName);
- ZeroMemory(rgwchTemplate, sizeof(rgwchTemplate));
- dwCount = MLLoadString(IDS_TARGETFILE, rgwchTemplate, ARRAYSIZE(rgwchTemplate));
- if (dwCount > 0)
- {
- if (urlComp.nScheme == INTERNET_SCHEME_FILE)
- {
- StrCpyNW(rgwchHostForDisplay, rgwchUrlPath, ARRAYSIZE(rgwchPathForDisplay));
- PathRemoveFileSpecW(rgwchHostForDisplay);
- }
- if (dwPathLen+lstrlenW(rgwchTemplate)+dwHostLen <= cchBuf)
- {
- _FormatMessage(rgwchTemplate, pwzFriendly, cchBuf, pwzFileName, rgwchHostForDisplay);
- hrRC = S_OK;
- }
- }
- }
- else // !fSeperate
- {
- if (3+dwPathLen+dwHostLen+dwSchemeLen < cchBuf)
- {
- wnsprintf(pwzFriendly, cchBuf, TEXT("%ws://%ws%ws"), rgwchScheme, rgwchHostForDisplay, rgwchPathForDisplay);
- hrRC = S_OK;
- }
- }
- }
- }
- LocalFree(pszURL);
- }
- return(hrRC);
- }
- BOOL __cdecl _FormatMessage(LPCWSTR szTemplate, LPWSTR szBuf, UINT cchBuf, ...)
- {
- BOOL fRet;
- va_list ArgList;
- va_start(ArgList, cchBuf);
- fRet = FormatMessage(FORMAT_MESSAGE_FROM_STRING, szTemplate, 0, 0, szBuf, cchBuf, &ArgList);
- va_end(ArgList);
- return fRet;
- }
- // Navigate to a given Url (wszUrl) using IE. Returns an error if IE does not exist.
- // fNewWindow = TRUE ==> A new window is compulsory
- // fNewWindow = FALSE ==> Do not launch a new window if one already is open.
- HRESULT NavToUrlUsingIEW(LPCWSTR wszUrl, BOOL fNewWindow)
- {
- HRESULT hr = S_OK;
- if (!EVAL(wszUrl))
- return E_INVALIDARG;
- if(IsIEDefaultBrowser() && !fNewWindow)
- {
- // ShellExecute navigates to the Url using the same browser window,
- // if one is already open.
- SHELLEXECUTEINFOW sei = {0};
- sei.cbSize = sizeof(sei);
- sei.lpFile = wszUrl;
- sei.nShow = SW_SHOWNORMAL;
- ShellExecuteExW(&sei);
- }
- else
- {
- IWebBrowser2 *pwb2;
- #ifndef UNIX
- hr = CoCreateInstance(CLSID_InternetExplorer, NULL,
- CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (LPVOID*)&pwb2);
- #else
- hr = CoCreateInternetExplorer( IID_IWebBrowser2,
- CLSCTX_LOCAL_SERVER,
- (LPVOID*) &pwb2 );
- #endif
- if(SUCCEEDED(hr))
- {
- SA_BSTR sstrURL;
- StrCpyNW(sstrURL.wsz, wszUrl, ARRAYSIZE(sstrURL.wsz));
- sstrURL.cb = lstrlenW(sstrURL.wsz) * SIZEOF(WCHAR);
- VARIANT varURL;
- varURL.vt = VT_BSTR;
- varURL.bstrVal = sstrURL.wsz;
- VARIANT varFlags;
- varFlags.vt = VT_I4;
- varFlags.lVal = 0;
- hr = pwb2->Navigate2(&varURL, &varFlags, PVAREMPTY, PVAREMPTY, PVAREMPTY);
- ASSERT(SUCCEEDED(hr)); // mikesh sez there's no way for Navigate2 to fail
- hr = pwb2->put_Visible( TRUE );
- pwb2->Release();
- }
- }
- return hr;
- }
- HRESULT NavToUrlUsingIEA(LPCSTR szUrl, BOOL fNewWindow)
- {
- WCHAR wszUrl[INTERNET_MAX_URL_LENGTH];
- AnsiToUnicode(szUrl, wszUrl, ARRAYSIZE(wszUrl));
- return NavToUrlUsingIEW(wszUrl, fNewWindow);
- }
- STDAPI_(BSTR) SysAllocStringA(LPCSTR pszAnsiStr)
- {
- OLECHAR *bstrOut = NULL;
- LPWSTR pwzTemp;
- UINT cchSize = (lstrlenA(pszAnsiStr) + 2); // Count of characters
- if (!pszAnsiStr)
- return NULL; // What the hell do you expect?
- pwzTemp = (LPWSTR) LocalAlloc(LPTR, cchSize * sizeof(WCHAR));
- if (pwzTemp)
- {
- SHAnsiToUnicode(pszAnsiStr, pwzTemp, cchSize);
- bstrOut = SysAllocString(pwzTemp);
- LocalFree(pwzTemp);
- }
- return bstrOut;
- }
- // MultiByteToWideChar doesn't truncate if the buffer is too small.
- // these utils do.
- // returns:
- // # of chars converted (WIDE chars) into out buffer (pwstr)
- int _AnsiToUnicode(UINT uiCP, LPCSTR pstr, LPWSTR pwstr, int cch)
- {
- int cchDst = 0;
- ASSERT(IS_VALID_STRING_PTRA(pstr, -1));
- ASSERT(NULL == pwstr || IS_VALID_WRITE_BUFFER(pwstr, WCHAR, cch));
- if (cch && pwstr)
- pwstr[0] = 0;
- switch (uiCP)
- {
- case 1200: // UCS-2 (Unicode)
- uiCP = 65001;
- // fall through
- case 50000: // "User Defined"
- case 65000: // UTF-7
- case 65001: // UTF-8
- {
- INT cchSrc, cchSrcOriginal;
- cchSrc = cchSrcOriginal = lstrlenA(pstr) + 1;
- cchDst = cch;
- if (SUCCEEDED(ConvertINetMultiByteToUnicode(NULL, uiCP, pstr,
- &cchSrc, pwstr, &cchDst)) &&
- cchSrc < cchSrcOriginal)
- {
- LPWSTR pwsz = (LPWSTR)LocalAlloc(LPTR, cchDst * SIZEOF(WCHAR));
- if (pwsz)
- {
- if (SUCCEEDED(ConvertINetMultiByteToUnicode( NULL, uiCP, pstr,
- &cchSrcOriginal, pwsz, &cchDst )))
- {
- StrCpyNW( pwstr, pwsz, cch );
- cchDst = cch;
- }
- LocalFree(pwsz);
- }
- }
- break;
- }
- default:
- cchDst = MultiByteToWideChar(uiCP, 0, pstr, -1, pwstr, cch);
- if (!cchDst) {
- // failed.
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- int cchNeeded = MultiByteToWideChar(uiCP, 0, pstr, -1, NULL, 0);
- if (cchNeeded) {
- LPWSTR pwsz = (LPWSTR)LocalAlloc(LPTR, cchNeeded * SIZEOF(WCHAR));
- if (pwsz) {
- cchDst = MultiByteToWideChar(uiCP, 0, pstr, -1, pwsz, cchNeeded);
- if (cchDst) {
- StrCpyNW(pwstr, pwsz, cch);
- cchDst = cch;
- }
- LocalFree(pwsz);
- }
- }
- }
- }
- break;
- }
- return cchDst;
- }
- #ifndef POSTPOSTSPLIT
- HRESULT ContextMenu_GetCommandStringVerb(IContextMenu *pcm, UINT idCmd, LPTSTR pszVerb, int cchVerb)
- {
- HRESULT hres = E_FAIL;
- // Try the WCHAR string first on NT systems
- if (g_fRunningOnNT)
- {
- hres = pcm->GetCommandString(idCmd, GCS_VERBW, NULL, (LPSTR)pszVerb, cchVerb);
- }
- // Try the ANSI string next
- if (FAILED(hres))
- {
- char szVerbAnsi[80];
- hres = pcm->GetCommandString(idCmd, GCS_VERBA, NULL, szVerbAnsi, ARRAYSIZE(szVerbAnsi));
- SHAnsiToTChar(szVerbAnsi, pszVerb, cchVerb);
- }
- return hres;
- }
- #endif
- UINT g_cfURL = 0;
- UINT g_cfFileDescA = 0;
- UINT g_cfFileContents = 0;
- UINT g_cfPreferedEffect = 0;
- #ifndef POSTPOSTSPLIT
- UINT g_cfHIDA = 0;
- UINT g_cfFileDescW = 0;
- #endif
- void InitClipboardFormats()
- {
- if (g_cfURL == 0)
- {
- g_cfURL = RegisterClipboardFormat(CFSTR_SHELLURL);
- g_cfFileDescA = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA);
- g_cfFileContents = RegisterClipboardFormat(CFSTR_FILECONTENTS);
- g_cfPreferedEffect = RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
- #ifndef POSTPOSTSPLIT
- g_cfHIDA = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
- g_cfFileDescW = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
- #endif
- }
- }
- // BUGBUG [raymondc] use SHGlobalCounter
- // We need to use a cross process browser count.
- // We use a named semaphore.
- //
- EXTERN_C HANDLE g_hSemBrowserCount = NULL;
- #define SESSION_COUNT_SEMAPHORE_NAME "_ie_sessioncount"
- HANDLE GetSessionCountSemaphoreHandle()
- {
- if (!g_hSemBrowserCount)
- {
- //
- // Use the "A" version so it works on W95 w/o a wrapper.
- //
- // Too afraid to use CreateAllAccessSecurityAttributes because
- // who knows what'll happen when two people with different
- // security attributes try to access the same winlist...
- g_hSemBrowserCount = CreateSemaphoreA(NULL, 0, 0x7FFFFFFF, SESSION_COUNT_SEMAPHORE_NAME);
- if (!g_hSemBrowserCount)
- {
- ASSERT(GetLastError() == ERROR_ALREADY_EXISTS);
- g_hSemBrowserCount = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS,
- FALSE, SESSION_COUNT_SEMAPHORE_NAME);
- }
- }
- return g_hSemBrowserCount;
- }
- LONG GetSessionCount()
- {
- LONG lPrevCount = 0x7FFFFFFF;
- HANDLE hSem = GetSessionCountSemaphoreHandle();
- ASSERT(hSem);
- if(hSem)
- {
- ReleaseSemaphore(hSem, 1, &lPrevCount);
- WaitForSingleObject(hSem, 0);
- }
- return lPrevCount;
- }
- LONG IncrementSessionCount()
- {
- LONG lPrevCount = 0x7FFFFFFF;
- HANDLE hSem = GetSessionCountSemaphoreHandle();
- ASSERT(hSem);
- if(hSem)
- {
- ReleaseSemaphore(hSem, 1, &lPrevCount);
- }
- return lPrevCount;
- }
- LONG DecrementSessionCount()
- {
- LONG lPrevCount = 0x7FFFFFFF;
- HANDLE hSem = GetSessionCountSemaphoreHandle();
- ASSERT(hSem);
- if(hSem)
- {
- ReleaseSemaphore(hSem, 1, &lPrevCount); // increment first to make sure deadlock
- // never occurs
- ASSERT(lPrevCount > 0);
- if(lPrevCount > 0)
- {
- WaitForSingleObject(hSem, 0);
- WaitForSingleObject(hSem, 0);
- lPrevCount--;
- }
- else
- {
- // Oops - Looks like a bug !
- // Just return it back to normal and leave
- WaitForSingleObject(hSem, 0);
- }
- }
- return lPrevCount;
- }
- //
- // The following is the message that autodial monitors expect to receive
- // when it's a good time to hang up
- //
- #define WM_IEXPLORER_EXITING (WM_USER + 103)
- long SetQueryNetSessionCount(enum SessionOp Op)
- {
- long lCount = 0;
- switch(Op) {
- case SESSION_QUERY:
- lCount = GetSessionCount();
- TraceMsg(DM_SESSIONCOUNT, "SetQueryNetSessionCount SessionCount=%d (query)", lCount);
- break;
- case SESSION_INCREMENT_NODEFAULTBROWSERCHECK:
- case SESSION_INCREMENT:
- lCount = IncrementSessionCount();
- TraceMsg(DM_SESSIONCOUNT, "SetQueryNetSessionCount SessionCount=%d (incr)", lCount);
- if ((PLATFORM_INTEGRATED == WhichPlatform()))
- {
- // Weird name here... But in integrated mode we make every new browser window
- // look like a new session wrt how we use the cache. Basically this is the way things appear to the
- // user. This effects the way we look for new pages vs doing an if modified
- // since. The ie3/ie4 switch says "look for new pages on each session start"
- // but wininet folks implemented this as a end session name. Woops.
- // Note that things like authentication etc aren't reset by this, but rather
- // only when all browsers are closed via the INTERNET_OPTION_END_BROWSER_SESSION option.
- InternetSetOption(NULL, INTERNET_OPTION_RESET_URLCACHE_SESSION, NULL, 0);
- }
- if (!lCount && (Op == SESSION_INCREMENT))
- {
- // this forces a reload of the title
- DetectAndFixAssociations();
- }
- break;
- case SESSION_DECREMENT:
- lCount = DecrementSessionCount();
- TraceMsg(DM_SESSIONCOUNT, "SetQueryNetSessionCount SessionCount=%d (decr)", lCount);
- if(!lCount) {
- // if we've closed all the net browsers, we need to flush the cache
- InternetSetOption(NULL, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
- InternetSetOption(NULL, INTERNET_OPTION_RESET_URLCACHE_SESSION, NULL, 0);
- // flush the Java VM cache too (if the Java VM is loaded in this process
- // and we're in integrated mode)
- if (WhichPlatform() == PLATFORM_INTEGRATED)
- {
- HMODULE hmod = GetModuleHandle(TEXT("msjava.dll"));
- if (hmod)
- {
- typedef HRESULT (*PFNNOTIFYBROWSERSHUTDOWN)(LPVOID);
- FARPROC fp = GetProcAddress(hmod, "NotifyBrowserShutdown");
- if (fp)
- {
- HRESULT hr = ((PFNNOTIFYBROWSERSHUTDOWN)fp)(NULL);
- ASSERT(SUCCEEDED(hr));
- }
- }
- }
- // Inform dial monitor that it's a good time to hang up
- HWND hwndMonitorWnd = FindWindow(TEXT("MS_AutodialMonitor"),NULL);
- if (hwndMonitorWnd) {
- PostMessage(hwndMonitorWnd,WM_IEXPLORER_EXITING,0,0);
- }
- hwndMonitorWnd = FindWindow(TEXT("MS_WebcheckMonitor"),NULL);
- if (hwndMonitorWnd) {
- PostMessage(hwndMonitorWnd,WM_IEXPLORER_EXITING,0,0);
- }
- // reset offline mode on all platforms except Win2K.
- OSVERSIONINFOA vi;
- vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
- GetVersionExA(&vi);
- if( vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ||
- vi.dwMajorVersion < 5)
- {
- // wininet is loaded - tell it to go online
- INTERNET_CONNECTED_INFO ci;
- memset(&ci, 0, sizeof(ci));
- ci.dwConnectedState = INTERNET_STATE_CONNECTED;
- InternetSetOption(NULL, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
- }
- }
- break;
- }
- return lCount;
- }
- #ifdef DEBUG
- //---------------------------------------------------------------------------
- // Copy the exception info so we can get debug info for Raised exceptions
- // which don't go through the debugger.
- void _CopyExceptionInfo(LPEXCEPTION_POINTERS pep)
- {
- PEXCEPTION_RECORD per;
- per = pep->ExceptionRecord;
- TraceMsg(DM_ERROR, "Exception %x at %#08x.", per->ExceptionCode, per->ExceptionAddress);
- if (per->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
- {
- // If the first param is 1 then this was a write.
- // If the first param is 0 then this was a read.
- if (per->ExceptionInformation[0])
- {
- TraceMsg(DM_ERROR, "Invalid write to %#08x.", per->ExceptionInformation[1]);
- }
- else
- {
- TraceMsg(DM_ERROR, "Invalid read of %#08x.", per->ExceptionInformation[1]);
- }
- }
- }
- #else
- #define _CopyExceptionInfo(x) TRUE
- #endif
- int WELCallback(LPVOID p, LPVOID pData)
- {
- STATURL* pstat = (STATURL*)p;
- if (pstat->pwcsUrl) {
- OleFree(pstat->pwcsUrl);
- }
- return 1;
- }
- int CALLBACK WELCompare(LPVOID p1, LPVOID p2, LPARAM lParam)
- {
- HDSA hdsa = (HDSA)lParam;
- // Sundown: coercion to long because parameter is an index
- STATURL* pstat1 = (STATURL*)DSA_GetItemPtr(hdsa, PtrToLong(p1));
- STATURL* pstat2 = (STATURL*)DSA_GetItemPtr(hdsa, PtrToLong(p2));
- if (pstat1 && pstat2) {
- return CompareFileTime(&pstat2->ftLastVisited, &pstat1->ftLastVisited);
- }
- ASSERT(0);
- return 0;
- }
- #define MACRO_STR(x) #x
- #define VERSION_HEADER_STR "Microsoft Internet Explorer 5.0 Error Log -- "
- MACRO_STR(VER_MAJOR_PRODUCTVER) "."
- MACRO_STR(VER_MINOR_PRODUCTVER) "."
- MACRO_STR(VER_PRODUCTBUILD) "."
- MACRO_STR(VER_PRODUCTBUILD_QFE) "rn"
- void IEWriteErrorLog(const EXCEPTION_RECORD* pexr)
- {
- HANDLE hfile = INVALID_HANDLE_VALUE;
- _try
- {
- //
- // Post a message to the MTTF tool if running
- //
- PostMTTFMessage(MTTF_CRASHTRAPPED);
- TCHAR szWindows[MAX_PATH];
- GetWindowsDirectory(szWindows, ARRAYSIZE(szWindows));
- PathAppend(szWindows, TEXT("IE4 Error Log.txt"));
- HANDLE hfile = CreateFile(szWindows, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if(hfile != INVALID_HANDLE_VALUE)
- {
- const static CHAR c_szCRLF[] = "rn";
- DWORD cbWritten;
- CHAR szBuf[MAX_URL_STRING];
- // Write the title and product version.
- WriteFile(hfile, VERSION_HEADER_STR, lstrlenA(VERSION_HEADER_STR), &cbWritten, NULL);
- // Write the current time.
- SYSTEMTIME st;
- FILETIME ft;
- GetSystemTime(&st);
- SystemTimeToFileTime(&st, &ft);
- SHFormatDateTimeA(&ft, NULL, szBuf, SIZECHARS(szBuf));
- const static CHAR c_szCurrentTime[] = "CurrentTime: ";
- WriteFile(hfile, c_szCurrentTime, SIZEOF(c_szCurrentTime)-1, &cbWritten, NULL);
- WriteFile(hfile, szBuf, lstrlenA(szBuf), &cbWritten, NULL);
- WriteFile(hfile, c_szCRLF, SIZEOF(c_szCRLF)-1, &cbWritten, NULL);
- if (pexr) {
- const static CHAR c_szExcCode[] = "Exception Info: Code=%x Flags=%x Address=%xrn";
- const static CHAR c_szExcParam[] = "Exception Param:";
- wnsprintfA(szBuf, ARRAYSIZE(szBuf), c_szExcCode, pexr->ExceptionCode, pexr->ExceptionFlags, pexr->ExceptionAddress);
- WriteFile(hfile, szBuf, lstrlenA(szBuf), &cbWritten, NULL);
- if (pexr->NumberParameters) {
- WriteFile(hfile, c_szExcParam, SIZEOF(c_szExcParam)-1, &cbWritten, NULL);
- for (UINT iParam=0; iParam<pexr->NumberParameters; iParam++) {
- wnsprintfA(szBuf, ARRAYSIZE(szBuf), " %x", pexr->ExceptionInformation[iParam]);
- WriteFile(hfile, szBuf, lstrlenA(szBuf), &cbWritten, NULL);
- }
- }
- WriteFile(hfile, c_szCRLF, SIZEOF(c_szCRLF)-1, &cbWritten, NULL);
- WriteFile(hfile, c_szCRLF, SIZEOF(c_szCRLF)-1, &cbWritten, NULL);
- }
- IUrlHistoryStg* pUrlHistStg;
- HRESULT hres = CoCreateInstance(CLSID_CUrlHistory, NULL, CLSCTX_INPROC_SERVER,
- IID_IUrlHistoryStg, (void **)&pUrlHistStg);
- if (SUCCEEDED(hres)) {
- IEnumSTATURL* penum;
- hres = pUrlHistStg->EnumUrls(&penum);
- if (SUCCEEDED(hres)) {
- // Allocate DSA for an array of STATURL
- HDSA hdsa = DSA_Create(SIZEOF(STATURL), 32);
- if (hdsa) {
- // Allocate DPA for sorting
- HDPA hdpa = DPA_Create(32);
- if (hdpa) {
- STATURL stat;
- stat.cbSize = SIZEOF(stat.cbSize);
- while(penum->Next(1, &stat, NULL)==S_OK && stat.pwcsUrl) {
- DSA_AppendItem(hdsa, &stat);
- DPA_AppendPtr(hdpa, (LPVOID)(DSA_GetItemCount(hdsa)-1));
- }
- DPA_Sort(hdpa, WELCompare, (LPARAM)hdsa);
- for (int i=0; i<10 && i<DPA_GetPtrCount(hdpa) ; i++) {
- // Sundown: typecast to long is OK
- STATURL* pstat = (STATURL*)DSA_GetItemPtr(hdsa, PtrToLong(DPA_GetPtr(hdpa, i)));
- if (pstat && pstat->pwcsUrl) {
- SHFormatDateTimeA(&pstat->ftLastVisited, NULL, szBuf, SIZECHARS(szBuf));
- WriteFile(hfile, szBuf, lstrlenA(szBuf), &cbWritten, NULL);
- const static TCHAR c_szColumn[] = TEXT(" -- ");
- WriteFile(hfile, c_szColumn, SIZEOF(c_szColumn)-1, &cbWritten, NULL);
- WideCharToMultiByte(CP_ACP, 0, pstat->pwcsUrl, -1,
- szBuf, ARRAYSIZE(szBuf), NULL, NULL);
- WriteFile(hfile, szBuf, lstrlenA(szBuf), &cbWritten, NULL);
- WriteFile(hfile, c_szCRLF, SIZEOF(c_szCRLF)-1, &cbWritten, NULL);
- } else {
- ASSERT(0);
- }
- }
- DPA_Destroy(hdpa);
- }
- DSA_DestroyCallback(hdsa, WELCallback, NULL);
- }
- penum->Release();
- } else {
- ASSERT(0);
- }
- pUrlHistStg->Release();
- } else {
- ASSERT(0);
- }
- CloseHandle( hfile );
- hfile = INVALID_HANDLE_VALUE;
- }
- }
- _except((SetErrorMode(SEM_NOGPFAULTERRORBOX),
- _CopyExceptionInfo(GetExceptionInformation()),
- UnhandledExceptionFilter(GetExceptionInformation())
- ))
- {
- // We hit an exception while handling an exception.
- // Do nothing; we have already displayed the error dialog box.
- if(hfile != INVALID_HANDLE_VALUE) {
- CloseHandle(hfile);
- }
- }
- __endexcept
- }
- int CDECL MRUILIsEqual(const void *pidl1, const void *pidl2, size_t cb)
- {
- // First cheap hack to see if they are 100 percent equal for performance
- int iCmp = memcmp(pidl1, pidl2, cb);
- if (iCmp == 0)
- return 0;
- if (ILIsEqual((LPITEMIDLIST)pidl1, (LPITEMIDLIST)pidl2))
- return 0;
- return iCmp;
- }
- IStream* SHGetViewStream(LPCITEMIDLIST pidl, DWORD grfMode, LPCTSTR pszName, LPCTSTR pszStreamMRU, LPCTSTR pszStreams)
- {
- IStream *pstm = NULL;
- HANDLE hmru;
- int iFoundSlot = -1;
- UINT cbPidl;
- static DWORD s_dwMRUSize = 0;
- DWORD dwSize = sizeof(s_dwMRUSize);
- if ((0 == s_dwMRUSize) &&
- (ERROR_SUCCESS != SHGetValue(HKEY_CURRENT_USER, pszStreamMRU, TEXT("MRU Size"), NULL, (LPVOID) &s_dwMRUSize, &dwSize)))
- {
- s_dwMRUSize = 200; // The default.
- }
- MRUINFO mi = {
- SIZEOF(MRUINFO),
- s_dwMRUSize, // we store this many view streams
- MRU_BINARY,
- HKEY_CURRENT_USER,
- pszStreamMRU,
- (MRUCMPPROC)MRUILIsEqual,
- };
- ASSERT(pidl);
- // should be checked by caller - if this is not true we'll flush the
- // MRU cache with internet pidls! FTP and other URL Shell Extension PIDLs
- // that act like a folder and need similar persistence and fine. This
- // is especially true because recently the cache size was increased from
- // 30 or so to 200.
- ASSERT(ILIsEqual(pidl, c_pidlURLRoot) || !IsBrowserFrameOptionsPidlSet(pidl, BFO_BROWSER_PERSIST_SETTINGS));
- cbPidl = ILGetSize(pidl);
- // Now lets try to save away the other information associated with view.
- hmru = CreateMRUListLazyEx(&mi, pidl, cbPidl, &iFoundSlot);
- if (!hmru)
- return NULL;
- // Did we find the item?
- if (iFoundSlot < 0 && ((grfMode & (STGM_READ|STGM_WRITE|STGM_READWRITE)) == STGM_READ))
- {
- // Do not create the stream if it does not exist and we are
- // only reading
- }
- else
- {
- HKEY hkCabStreams;
- TCHAR szRegPath[MAX_PATH];
- StrCpyN(szRegPath, REGSTR_PATH_EXPLORER TEXT("\"), ARRAYSIZE(szRegPath));
- StrCatBuff(szRegPath, pszStreams, ARRAYSIZE(szRegPath));
- // Note that we always create the key here, since we have
- // already checked whether we are just reading and the MRU
- // thing does not exist
- if (RegCreateKey(HKEY_CURRENT_USER, szRegPath, &hkCabStreams) == ERROR_SUCCESS)
- {
- HKEY hkValues;
- TCHAR szValue[32], szSubVal[64];
- wnsprintf(szValue, ARRAYSIZE(szValue), TEXT("%d"), AddMRUDataEx(hmru, pidl, cbPidl));
- if (iFoundSlot < 0 && RegOpenKey(hkCabStreams, szValue, &hkValues) == ERROR_SUCCESS)
- {
- // This means that we have created a new MRU
- // item for this PIDL, so clear out any
- // information residing at this slot
- // Note that we do not just delete the key,
- // since that could fail if it has any sub-keys
- DWORD dwType, dwSize = ARRAYSIZE(szSubVal);
- while (RegEnumValue(hkValues, 0, szSubVal, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS)
- {
- if (RegDeleteValue(hkValues, szSubVal) != ERROR_SUCCESS)
- {
- break;
- }
- }
- RegCloseKey(hkValues);
- }
- pstm = OpenRegStream(hkCabStreams, szValue, pszName, grfMode);
- RegCloseKey(hkCabStreams);
- }
- }
- FreeMRUListEx(hmru);
- return pstm;
- }
- #define c_szExploreClass TEXT("ExploreWClass")
- #define c_szIExploreClass TEXT("IEFrame")
- #ifdef IE3CLASSNAME
- #define c_szCabinetClass TEXT("IEFrame")
- #else
- #define c_szCabinetClass TEXT("CabinetWClass")
- #endif
- BOOL IsNamedWindow(HWND hwnd, LPCTSTR pszClass)
- {
- TCHAR szClass[32];
- GetClassName(hwnd, szClass, ARRAYSIZE(szClass));
- return StrCmp(szClass, pszClass) == 0;
- }
- BOOL IsTrayWindow(HWND hwnd)
- {
- return IsNamedWindow(hwnd, TEXT(WNDCLASS_TRAYNOTIFY));
- }
- BOOL IsExplorerWindow(HWND hwnd)
- {
- return IsNamedWindow(hwnd, c_szExploreClass);
- }
- BOOL IsFolderWindow(HWND hwnd)
- {
- TCHAR szClass[32];
- GetClassName(hwnd, szClass, ARRAYSIZE(szClass));
- return (StrCmp(szClass, c_szCabinetClass) == 0) || (StrCmp(szClass, c_szIExploreClass) == 0);
- }
- HRESULT _SendOrPostDispatchMessage(HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL fPostMessage, BOOL fCheckFirst)
- {
- HRESULT hr = HRESULT_FROM_WIN32(ERROR_BUSY);
- DWORD idProcess;
- // in case of wParam = DSID_NAVIGATEIEBROWSER, lParam is LocalAlloced structure
- // so we better make sure we are in process 'coz otherwise will fault
- GetWindowThreadProcessId(hwnd, &idProcess);
- if (idProcess == GetCurrentProcessId() && IsWindowEnabled(hwnd) && IsWindowVisible(hwnd))
- {
- if (!fPostMessage || fCheckFirst)
- {
- // sync or we are querying the windows readiness
- ULONG_PTR result;
- if (SendMessageTimeoutA(hwnd, WMC_DISPATCH, (fCheckFirst ? DSID_NOACTION : wParam),
- lParam, SMTO_ABORTIFHUNG, 400, &result))
- hr = (HRESULT) result;
- }
- // handle the post only if the window was ready
- if (fPostMessage && (!fCheckFirst || SUCCEEDED(hr)))
- hr = (PostMessage(hwnd, WMC_DISPATCH, wParam, lParam) ? S_OK : E_FAIL);
- }
- return hr;
- }
- //---------------------------------------------------------------------------
- HRESULT FindBrowserWindowOfClass(LPCTSTR pszClass, WPARAM wParam, LPARAM lParam, BOOL fPostMessage, HWND* phwnd)
- {
- //If there is no window, assume the user is in the process of shutting down IE, and return E_FAIL
- //Otherwise, if there is at least one window, start cycling through the windows until you find
- //one that's not busy, and give it our message. If all are busy, return
- //HRESULT_FROM_WIN32(ERROR_BUSY)
- HWND hwnd = NULL;
- HRESULT hr = E_FAIL;
- while (FAILED(hr)
- && (hwnd = FindWindowEx(NULL, hwnd, pszClass, NULL)) != NULL)
- {
- hr = _SendOrPostDispatchMessage(hwnd, wParam, lParam, fPostMessage, fPostMessage);
- }
- *phwnd = hwnd;
- return hr;
- }
- //This common function gets called when the DDE engine doesn't seem to care in which window something
- //happens. It returns in which window that something happened. 0 means all windows are busy.
- //
- //phwnd: a pointer the hwnd to which to send the message. <= 0 means any window will do.
- // this is also an out parameter that specifies in which window it happened.
- //fPostMessage: when doing navigations, we have to do a PostMessage instead of a SendMessageTimeout
- // or a CoCreateInstance later on in CDocObjectHost::_BindFileMoniker will fail. So when
- // this function is called from CDDEAuto_Navigate, we make this flag TRUE
- HRESULT CDDEAuto_Common(WPARAM wParam, LPARAM lParam, HWND *phwnd, BOOL fPostMessage)
- {
- HRESULT hr = HRESULT_FROM_WIN32(ERROR_BUSY);
- HWND hwnd;
- //if we're told to go to a specific window
- if (phwnd && (*phwnd != (HWND)-1))
- {
- hr = _SendOrPostDispatchMessage(*phwnd, wParam, lParam, fPostMessage, FALSE);
- }
- if (HRESULT_FROM_WIN32(ERROR_BUSY) == hr)
- {
- hr = FindBrowserWindowOfClass(c_szIExploreClass, wParam, lParam, fPostMessage, &hwnd);
- if (!hwnd)
- hr = FindBrowserWindowOfClass(c_szCabinetClass, wParam, lParam, fPostMessage, &hwnd);
- if (phwnd)
- *phwnd = hwnd;
- }
- return hr;
- }
- //
- // Before changing the behavior of this function look at itemmenu.cpp in
- // cdfview.
- //
- HRESULT CDDEAuto_Navigate(BSTR str, HWND *phwnd, long) //the long is for lTransID, which is currently
- //turned off
- {
- DDENAVIGATESTRUCT *pddens = NULL;
- HRESULT hres = E_FAIL;
- if (phwnd == NULL)
- return E_INVALIDARG;
- pddens = new DDENAVIGATESTRUCT;
- if (!pddens)
- hres = E_OUTOFMEMORY;
- else
- {
- pddens->wszUrl = StrDupW(str);
- if (!pddens->wszUrl)
- hres = E_OUTOFMEMORY;
- else
- {
- // Don't do the navigate if *phwnd == 0, in that case we want to either
- // create a new window or activate an existing one that already is viewing
- // this URL.
- if (*phwnd != NULL)
- {
- BOOL fForceWindowReuse = FALSE;
- BSTR bstrUrl = NULL;
- // If there is even a single window with a location
- // you are basically assured that you cannot force a
- // reuse of windows. essentially
- // case 1 : only iexplore -nohome windows implies we want to force reuse
- // case 2 : only windows that have a location - we don't want to force reuse
- // just follow user's preference
- // case 3: mix of iexplore -nohome windows and windows with location. we don't
- // know what state we are in - don't force reuse
- hres = CDDEAuto_get_LocationURL(&bstrUrl, *phwnd);
- if(FAILED(hres) ||
- (!bstrUrl) ||
- (SUCCEEDED(hres) && (*bstrUrl == L' ')))
- {
- fForceWindowReuse = TRUE;
- }
- if(bstrUrl)
- SysFreeString(bstrUrl);
- if( !(GetAsyncKeyState(VK_SHIFT) < 0)
- && (fForceWindowReuse || SHRegGetBoolUSValue(REGSTR_PATH_MAIN, TEXT("AllowWindowReuse"), FALSE, TRUE)))
- {
- hres = CDDEAuto_Common(DSID_NAVIGATEIEBROWSER, (LPARAM)pddens, phwnd, FALSE);
- }
- }
- if (SUCCEEDED(hres) && (*phwnd != 0) && (*phwnd != (HWND)-1))
- {
- // We found an existing browser window and successfully sent the
- // navigate message to it. Make the window foreground.
- SetForegroundWindow(*phwnd);
- if (IsIconic(*phwnd))
- ShowWindowAsync(*phwnd,SW_RESTORE);
- }
- //
- // If we are using whatever window and all the browser windows are busy
- // (*phwnd == 0), or if there's no browser window opened (*phwnd == -1)
- // or we are asked to create a new one, then take the official OLE automation
- // route to start a new window.
- //
- if ((*phwnd == 0) ||
- (*phwnd == (HWND)-1))
- {
- //BUGBUG: this route doesn't give us the ability to return the hwnd of the window
- //in which the navigation took place (while we could - it's too hard and not worth it)
- LPITEMIDLIST pidlNew;
- TCHAR szURL[MAX_URL_STRING];
- OleStrToStrN(szURL, ARRAYSIZE(szURL), str, (UINT)-1);
- hres = IECreateFromPath(szURL, &pidlNew);
- if (SUCCEEDED(hres))
- {
- // See if there is already a browser viewing this URL, if so just
- // make him foreground otherwise create a new browser.
- if ((hres = WinList_FindFolderWindow(pidlNew, NULL, phwnd, NULL)) == S_OK)
- {
- ILFree(pidlNew);
- SetForegroundWindow(*phwnd);
- ShowWindow(*phwnd, SW_SHOWNORMAL);
- }
- else
- {
- SHOpenNewFrame(pidlNew, NULL, 0, 0);
- }
- }
- }
- }
- // It will be set to NULL if we don't need to free it.
- if (pddens)
- {
- if (pddens->wszUrl)
- {
- LocalFree(pddens->wszUrl);
- }
- delete pddens;
- }
- }
- return hres;
- }
- HRESULT CDDEAuto_get_LocationURL(BSTR * pstr, HWND hwnd)
- {
- return CDDEAuto_Common(DSID_GETLOCATIONURL, (LPARAM)pstr, &hwnd, FALSE);
- }
- HRESULT CDDEAuto_get_LocationTitle(BSTR * pstr, HWND hwnd)
- {
- return CDDEAuto_Common(DSID_GETLOCATIONTITLE, (LPARAM)pstr, &hwnd, FALSE);
- }
- HRESULT CDDEAuto_get_HWND(long * phwnd)
- {
- return CDDEAuto_Common(DSID_GETHWND, (LPARAM)phwnd, NULL, FALSE);
- }
- HRESULT CDDEAuto_Exit()
- {
- return CDDEAuto_Common(DSID_EXIT, (LPARAM)NULL, NULL, FALSE);
- }
- #ifndef POSTPOSTSPLIT
- #define DXTRACK 1
- void FrameTrack(HDC hdc, LPRECT prc, UINT uFlags)
- {
- COLORREF clrSave, clr;
- RECT rc;
- // upperleft
- switch (uFlags)
- {
- case TRACKHOT:
- clr = GetSysColor(COLOR_BTNHILIGHT);
- break;
- case TRACKNOCHILD:
- case TRACKEXPAND:
- clr = GetSysColor(COLOR_BTNSHADOW);
- break;
- default:
- ASSERT(FALSE);
- clr = GetSysColor(COLOR_BTNSHADOW);
- break;
- }
- clrSave = SetBkColor(hdc, clr);
- rc = *prc;
- rc.bottom = rc.top + DXTRACK;
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
- rc.bottom = prc->bottom;
- rc.right = rc.left + DXTRACK;
- rc.top = prc->top + DXTRACK;
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
- // lowerright
- switch (uFlags)
- {
- case TRACKHOT:
- clr = GetSysColor(COLOR_BTNSHADOW);
- break;
- case TRACKNOCHILD:
- case TRACKEXPAND:
- clr = GetSysColor(COLOR_BTNHILIGHT);
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- SetBkColor(hdc, clr);
- if (uFlags & (TRACKHOT | TRACKNOCHILD))
- {
- rc.right = prc->right;
- rc.top = rc.bottom - DXTRACK;
- rc.left = prc->left;
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
- }
- rc.right = prc->right;
- rc.left = prc->right - DXTRACK;
- rc.top = prc->top;
- rc.bottom = prc->bottom;
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
- SetBkColor(hdc, clrSave);
- return;
- }
- #endif
- #undef new // Hack!! Need to remove this (edwardp)
- class CDelagateMalloc : public IMalloc
- {
- public:
- // IUnknown
- virtual STDMETHODIMP QueryInterface(REFIID,void **);
- virtual STDMETHODIMP_(ULONG) AddRef(void);
- virtual STDMETHODIMP_(ULONG) Release(void);
- // IMalloc
- virtual STDMETHODIMP_(LPVOID) Alloc(SIZE_T cb);
- virtual STDMETHODIMP_(LPVOID) Realloc(void *pv, SIZE_T cb);
- virtual STDMETHODIMP_(void) Free(void *pv);
- virtual STDMETHODIMP_(SIZE_T) GetSize(void *pv);
- virtual STDMETHODIMP_(int) DidAlloc(void *pv);
- virtual STDMETHODIMP_(void) HeapMinimize();
- private:
- CDelagateMalloc(void *pv, SIZE_T cbSize, WORD wOuter);
- ~CDelagateMalloc();
- void* operator new(size_t cbClass, SIZE_T cbSize);
- friend HRESULT CDelegateMalloc_Create(void *pv, SIZE_T cbSize, WORD wOuter, IMalloc **ppmalloc);
- protected:
- LONG _cRef;
- WORD _wOuter; // delegate item outer signature
- WORD _wUnused; // to allign
- #ifdef DEBUG
- UINT _cAllocs;
- #endif
- SIZE_T _cb;
- BYTE _data[EMPTY_SIZE];
- };
- void* CDelagateMalloc::operator new(size_t cbClass, SIZE_T cbSize)
- {
- return ::operator new(cbClass + cbSize);
- }
- CDelagateMalloc::CDelagateMalloc(void *pv, SIZE_T cbSize, WORD wOuter)
- {
- _cRef = 1;
- _wOuter = wOuter;
- _cb = cbSize;
- memcpy(_data, pv, _cb);
- }
- CDelagateMalloc::~CDelagateMalloc()
- {
- // This isn't something we need to worry about and it causes way
- // too much noise. -BryanSt
- // DEBUG_CODE( TraceMsg(DM_TRACE, "DelegateMalloc destroyed with %d allocs performed", _cAllocs); )
- }
- HRESULT CDelagateMalloc::QueryInterface(REFIID riid, void **ppvObj)
- {
- if (IsEqualIID(riid, IID_IMalloc) || IsEqualIID(riid, IID_IUnknown))
- {
- *ppvObj = SAFECAST(this, IMalloc *);
- }
- else
- {
- *ppvObj = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- ULONG CDelagateMalloc::AddRef()
- {
- return InterlockedIncrement(&_cRef);
- }
- ULONG CDelagateMalloc::Release()
- {
- if (InterlockedDecrement(&_cRef))
- return _cRef;
- delete this;
- return 0;
- }
- void *CDelagateMalloc::Alloc(SIZE_T cb)
- {
- WORD cbActualSize = (WORD)(
- SIZEOF(DELEGATEITEMID) - 1 + // header (-1 sizeof(rgb[0])
- cb + // inner
- _cb); // outer data
- PDELEGATEITEMID pidl = (PDELEGATEITEMID)SHAlloc(cbActualSize + 2); // +2 for pidl term
- if (pidl)
- {
- pidl->cbSize = cbActualSize;
- pidl->wOuter = _wOuter;
- pidl->cbInner = (WORD)cb;
- memcpy(&pidl->rgb[cb], _data, _cb);
- *(WORD *)&(((BYTE *)pidl)[cbActualSize]) = 0;
- #ifdef DEBUG
- _cAllocs++;
- #endif
- }
- return pidl;
- }
- void *CDelagateMalloc::Realloc(void *pv, SIZE_T cb)
- {
- return NULL;
- }
- void CDelagateMalloc::Free(void *pv)
- {
- SHFree(pv);
- }
- SIZE_T CDelagateMalloc::GetSize(void *pv)
- {
- return (SIZE_T)-1;
- }
- int CDelagateMalloc::DidAlloc(void *pv)
- {
- return -1;
- }
- void CDelagateMalloc::HeapMinimize()
- {
- }
- STDAPI CDelegateMalloc_Create(void *pv, SIZE_T cbSize, WORD wOuter, IMalloc **ppmalloc)
- {
- CDelagateMalloc *pdm = new(cbSize) CDelagateMalloc(pv, cbSize, wOuter);
- if (pdm)
- {
- HRESULT hres = pdm->QueryInterface(IID_IMalloc, (void **)ppmalloc);
- pdm->Release();
- return hres;
- }
- return E_OUTOFMEMORY;
- }
- //+-------------------------------------------------------------------------
- // This function scans the head of an html document for the desired element
- // with a particular attribute. If a match is found, the first occurance
- // of that element is returned in punkDesired and S_OK is returned.
- // Otherwise, E_FAIL is returned.
- //
- // Example: Find the first meta element with name="ProgID":
- //
- // SearchForElementInHead(pHTMLDoc, OLESTR("Name"), OLESTR("ProgId"),
- // IID_IHTMLMetaElement, (IUnknown**)&pMetaElement);
- //
- //--------------------------------------------------------------------------
- HRESULT SearchForElementInHead
- (
- IHTMLDocument2* pHTMLDocument, // [in] document to search
- LPOLESTR pszAttribName, // [in] attribute to check for
- LPOLESTR pszAttrib, // [in] value the attribute must have
- REFIID iidDesired, // [in] element interface to return
- IUnknown** ppunkDesired // [out] returned interface
- )
- {
- ASSERT(NULL != pHTMLDocument);
- ASSERT(NULL != pszAttribName);
- ASSERT(NULL != pszAttrib);
- ASSERT(NULL != ppunkDesired);
- HRESULT hr = E_FAIL;
- *ppunkDesired = NULL;
- BSTR bstrAttribName = SysAllocString(pszAttribName);
- if (NULL == bstrAttribName)
- {
- return E_OUTOFMEMORY;
- }
- //
- // First get all document elements. Note that this is very fast in
- // ie5 because the collection directly accesses the internal tree.
- //
- IHTMLElementCollection * pAllCollection;
- if (SUCCEEDED(pHTMLDocument->get_all(&pAllCollection)))
- {
- IUnknown* punk;
- IHTMLBodyElement* pBodyElement;
- IHTMLFrameSetElement* pFrameSetElement;
- IDispatch* pDispItem;
- //
- // Now we scan the document for the desired tags. Since we're only
- // searching the head, and since Trident always creates a body tag
- // (unless there is a frameset), we can stop looking when we hit the
- // body or frameset.
- //
- // Note, the alternative of using pAllCollection->tags to return the
- // collection of desired tags is likely more expensive because it will
- // walk the whole tree (unless Trident optimizes this).
- //
- long lItemCnt;
- VARIANT vEmpty;
- V_VT(&vEmpty) = VT_EMPTY;
- VARIANT vIndex;
- V_VT(&vIndex) = VT_I4;
- EVAL(SUCCEEDED(pAllCollection->get_length(&lItemCnt)));
- for (long lItem = 0; lItem < lItemCnt; lItem++)
- {
- V_I4(&vIndex) = lItem;
- if (S_OK == pAllCollection->item(vIndex, vEmpty, &pDispItem))
- {
- //
- // First see if it's the desired element type
- //
- if (SUCCEEDED(pDispItem->QueryInterface(iidDesired,
- (void **)&punk)))
- {
- //
- // Next see if it has the desired attribute
- //
- IHTMLElement* pElement;
- if (SUCCEEDED(pDispItem->QueryInterface(IID_IHTMLElement, (void **)&pElement)))
- {
- VARIANT varAttrib;
- V_VT(&varAttrib) = VT_EMPTY;
- if (SUCCEEDED(pElement->getAttribute(bstrAttribName, FALSE, &varAttrib)) &&
- (V_VT(&varAttrib) == VT_BSTR) && varAttrib.bstrVal &&
- (StrCmpIW(varAttrib.bstrVal, pszAttrib) == 0) )
- {
- // Found it!
- *ppunkDesired = punk;
- punk = NULL;
- hr = S_OK;
- // Terminate the search;
- lItem = lItemCnt;
- }
- pElement->Release();
- VariantClear(&varAttrib);
- }
- if (punk)
- punk->Release();
- }
- //
- // Next check for the body tag
- //
- else if (SUCCEEDED(pDispItem->QueryInterface(IID_IHTMLBodyElement,
- (void **)&pBodyElement)) )
- {
- // Found a body tag, so terminate the search
- lItem = lItemCnt;
- pBodyElement->Release();
- }
- //
- // Finally, check for a frameset tag
- //
- else if (SUCCEEDED(pDispItem->QueryInterface(IID_IHTMLFrameSetElement,
- (void **)&pFrameSetElement)) )
- {
- // Found a frameset tag, so terminate the search
- lItem = lItemCnt;
- pFrameSetElement->Release();
- }
- pDispItem->Release();
- }
- }
- // Make sure that these don't have to be cleared (should not have been modified)
- ASSERT(vEmpty.vt == VT_EMPTY);
- ASSERT(vIndex.vt == VT_I4);
- pAllCollection->Release();
- }
- SysFreeString(bstrAttribName);
- return hr;
- }
- //+-------------------------------------------------------------------
- // JITCoCreateInstance
- //
- // This function makes sure that the Option pack which
- // has this class id is installed.
- // It attempts to make sure that the Option pack corresponding
- // to the current IE Build.
- // If the feature does get installed correctly, it will
- // attempt to CoCreate the specified CLSID
- //
- //+------------------------------------------------------------------
- HRESULT
- JITCoCreateInstance(
- REFCLSID rclsid,
- LPUNKNOWN pUnkOuter,
- DWORD dwClsContext,
- REFIID riid,
- LPVOID FAR* ppv,
- HWND hwndParent,
- DWORD dwJitFlags
- )
- {
- uCLSSPEC ucs;
- QUERYCONTEXT qc = { 0 };
- HRESULT hr;
- ucs.tyspec = TYSPEC_CLSID;
- ucs.tagged_union.clsid = rclsid;
- ASSERT((dwJitFlags & ~(FIEF_FLAG_FORCE_JITUI | FIEF_FLAG_PEEK)) == 0);
- hr = FaultInIEFeature(hwndParent, &ucs, &qc, dwJitFlags);
- if (SUCCEEDED(hr))
- {
- hr = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
- }
- return hr;
- }
- BOOL IsFeaturePotentiallyAvailable(REFCLSID rclsid)
- {
- uCLSSPEC ucs;
- QUERYCONTEXT qc = { 0 };
- ucs.tyspec = TYSPEC_CLSID;
- ucs.tagged_union.clsid = rclsid;
- return (FaultInIEFeature(NULL, &ucs, &qc, FIEF_FLAG_FORCE_JITUI | FIEF_FLAG_PEEK) != E_ACCESSDENIED);
- }
- BOOL CreateFromDesktop(PNEWFOLDERINFO pfi)
- {
- //
- // BUGBUGHACKHACK - we need to handle differences in the way we parse the command line
- // on IE4 integrated. we should not be called by anybody but IE4's Explorer.exe
- //
- ASSERT(GetUIVersion() == 4);
- if (!pfi->pidl)
- {
- if ((pfi->uFlags & (COF_ROOTCLASS | COF_NEWROOT)) || pfi->pidlRoot)
- {
- pfi->pidl = ILRootedCreateIDList(pfi->uFlags & COF_ROOTCLASS ? &pfi->clsid : NULL, pfi->pidlRoot);
- pfi->uFlags &= ~(COF_ROOTCLASS | COF_NEWROOT);
- ILFree(pfi->pidlRoot);
- pfi->pidlRoot = NULL;
- pfi->clsid = CLSID_NULL;
- }
- else if (!PathIsURLA(pfi->pszPath))
- {
- CHAR szTemp[MAX_PATH];
- GetCurrentDirectoryA(ARRAYSIZE(szTemp), szTemp);
- PathCombineA(szTemp, szTemp, pfi->pszPath);
- Str_SetPtrA(&(pfi->pszPath), szTemp);
- }
- }
- ASSERT(!(pfi->uFlags & (COF_ROOTCLASS | COF_NEWROOT)));
- return SHCreateFromDesktop(pfi);
- }
- //*** IsVK_TABCycler -- is key a TAB-equivalent
- // ENTRY/EXIT
- // dir 0 if not a TAB, non-0 if a TAB
- // NOTES
- // NYI: -1 for shift+tab, 1 for tab
- //
- int IsVK_TABCycler(MSG *pMsg)
- {
- if (!pMsg)
- return 0;
- if (pMsg->message != WM_KEYDOWN)
- return 0;
- if (! (pMsg->wParam == VK_TAB || pMsg->wParam == VK_F6))
- return 0;
- return (GetKeyState(VK_SHIFT) < 0) ? -1 : 1;
- }
- #ifdef DEBUG
- //
- // This function fully fills the input buffer, trashing stuff so we fault
- // when the size is wrong :-)
- //
- // We should hopefully catch people passing buffers that are too small here by
- // having a reproable stack corruption.
- //
- #define CH_BADCHARA ((CHAR)0xCC)
- #define CH_BADCHARW ((WCHAR)0xCCCC)
- #ifdef UNICODE
- #define CH_BADCHAR CH_BADCHARW
- #else // UNICODE
- #define CH_BADCHAR CH_BADCHARA
- #endif // UNICODE
- void DebugFillInputString(LPTSTR pszBuffer, DWORD cchSize)
- {
- while (cchSize--)
- {
- pszBuffer[0] = CH_BADCHAR;
- pszBuffer++;
- }
- }
- void DebugFillInputStringA(LPSTR pszBuffer, DWORD cchSize)
- {
- while (cchSize--)
- {
- pszBuffer[0] = CH_BADCHARA;
- pszBuffer++;
- }
- }
- #endif // DEBUG
- // Review chrisny: this can be moved into an object easily to handle generic droptarget, dropcursor
- // , autoscrool, etc. . .
- void _DragEnter(HWND hwndTarget, const POINTL ptStart, IDataObject *pdtObject)
- {
- RECT rc;
- POINT pt;
- GetWindowRect(hwndTarget, &rc);
- if (IS_WINDOW_RTL_MIRRORED(hwndTarget))
- pt.x = rc.right - ptStart.x;
- else
- pt.x = ptStart.x - rc.left;
- pt.y = ptStart.y - rc.top;
- DAD_DragEnterEx2(hwndTarget, pt, pdtObject);
- return;
- }
- void _DragMove(HWND hwndTarget, const POINTL ptStart)
- {
- RECT rc;
- POINT pt;
- GetWindowRect(hwndTarget, &rc);
- if (IS_WINDOW_RTL_MIRRORED(hwndTarget))
- pt.x = rc.right - ptStart.x;
- else
- pt.x = ptStart.x - rc.left;
- pt.y = ptStart.y - rc.top;
- DAD_DragMove(pt);
- return;
- }
- STDAPI_(IBindCtx *) CreateBindCtxForUI(IUnknown * punkSite)
- {
- IBindCtx * pbc = NULL;
- if (EVAL(punkSite && SUCCEEDED(CreateBindCtx(0, &pbc))))
- {
- if (FAILED(pbc->RegisterObjectParam(STR_DISPLAY_UI_DURING_BINDING, punkSite)))
- {
- // It failed damn nagit.
- ATOMICRELEASE(pbc);
- }
- }
- return pbc;
- }
- //
- // Return the location of the internet cache
- // HRESULT GetCacheLocation(
- // dwSize no. of chars in pszCacheLocation
- STDAPI GetCacheLocation(LPTSTR pszCacheLocation, DWORD dwSize)
- {
- HRESULT hr = S_OK;
- DWORD dwLastErr;
- LPINTERNET_CACHE_CONFIG_INFO lpCCI = NULL; // init to suppress bogus C4701 warning
- DWORD dwCCISize = sizeof(INTERNET_CACHE_CONFIG_INFO);
- BOOL fOnceErrored = FALSE;
- while (TRUE)
- {
- if ((lpCCI = (LPINTERNET_CACHE_CONFIG_INFO) LocalAlloc(LPTR,
- dwCCISize)) == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto cleanup;
- }
- if (!GetUrlCacheConfigInfo(lpCCI, &dwCCISize,
- CACHE_CONFIG_CONTENT_PATHS_FC))
- {
- if ((dwLastErr = GetLastError()) != ERROR_INSUFFICIENT_BUFFER ||
- fOnceErrored)
- {
- hr = HRESULT_FROM_WIN32(dwLastErr);
- goto cleanup;
- }
- //
- // We have insufficient buffer size; reallocate a buffer with the
- // new dwCCISize set by GetUrlCacheConfigInfo
- // Set fOnceErrored to TRUE so that we don't loop indefinitely
- //
- fOnceErrored = TRUE;
- }
- else
- {
- LPTSTR pszPath = lpCCI->CachePaths[0].CachePath;
- INT iLen;
- PathRemoveBackslash(pszPath);
- iLen = lstrlen(pszPath) + 1; // + 1 is for the null char
- if ((DWORD) iLen < dwSize)
- {
- StrCpyN(pszCacheLocation, pszPath, iLen);
- }
- else
- {
- hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
- }
- break;
- }
- LocalFree(lpCCI);
- lpCCI = NULL;
- }
- cleanup:
- if (lpCCI != NULL)
- {
- LocalFree(lpCCI);
- }
- return hr;
- }
- STDAPI_(UINT) GetWheelMsg()
- {
- static UINT s_msgMSWheel = 0;
- if (s_msgMSWheel == 0)
- s_msgMSWheel = RegisterWindowMessage(TEXT("MSWHEEL_ROLLMSG"));
- return s_msgMSWheel;
- }
- STDAPI StringToStrRet(LPCTSTR pString, STRRET *pstrret)
- {
- HRESULT hr = SHStrDup(pString, &pstrret->pOleStr);
- if (SUCCEEDED(hr))
- {
- pstrret->uType = STRRET_WSTR;
- }
- return hr;
- }
- // these two functions are duplicated from browseui
- HINSTANCE GetComctl32Hinst()
- {
- static HINSTANCE s_hinst = NULL;
- if (!s_hinst)
- s_hinst = GetModuleHandle(TEXT("comctl32.dll"));
- return s_hinst;
- }
- // since we don't define the proper WINVER we do this ourselves
- #ifndef IDC_HAND
- #define IDC_HAND MAKEINTRESOURCE(32649)
- #endif
- STDAPI_(HCURSOR) LoadHandCursor(DWORD dwRes)
- {
- if (g_bRunOnNT5 || g_bRunOnMemphis)
- {
- HCURSOR hcur = LoadCursor(NULL, IDC_HAND); // from USER, system supplied
- if (hcur)
- return hcur;
- }
- return LoadCursor(GetComctl32Hinst(), IDC_HAND_INTERNAL);
- }
- //+-------------------------------------------------------------------------
- // Returns true if this type of url may not be available when offline unless
- // it is cached by wininet
- //--------------------------------------------------------------------------
- BOOL MayBeUnavailableOffline(LPTSTR pszUrl)
- {
- BOOL fRet = FALSE;
- URL_COMPONENTS uc = {0};
- uc.dwStructSize = sizeof(uc);
- if (SUCCEEDED(InternetCrackUrl(pszUrl, 0, 0, &uc)))
- {
- fRet = uc.nScheme == INTERNET_SCHEME_HTTP ||
- uc.nScheme == INTERNET_SCHEME_HTTPS ||
- uc.nScheme == INTERNET_SCHEME_FTP ||
- uc.nScheme == INTERNET_SCHEME_GOPHER;
- }
- return fRet;
- }
- //+-------------------------------------------------------------------------
- // If the folder is a link, the associated URL is returned.
- //--------------------------------------------------------------------------
- HRESULT GetNavTargetName(IShellFolder* psf, LPCITEMIDLIST pidl, LPTSTR pszUrl, UINT cMaxChars)
- {
- LPITEMIDLIST pidlTarget;
- HRESULT hr = SHGetNavigateTarget(psf, pidl, &pidlTarget, NULL);
- if (SUCCEEDED(hr))
- {
- // Get the URL
- hr = IEGetNameAndFlags(pidlTarget, SHGDN_FORADDRESSBAR, pszUrl, cMaxChars, NULL);
- ILFree(pidlTarget);
- }
- else
- *pszUrl = 0;
- return hr;
- }
- //+-------------------------------------------------------------------------
- // Returns info about whether this item is available offline. Returns E_FAIL
- // if the item is not a link.
- // if we navigate to this item
- // (true if we're online, items in the cache or otherwise available)
- // if item is a sticky cache entry
- //--------------------------------------------------------------------------
- // BUGBUG: this should use an interface to bind to this information abstractly
- // psf->GetUIObjectOf(IID_IAvailablility, ...);
- HRESULT GetLinkInfo(IShellFolder* psf, LPCITEMIDLIST pidlItem, BOOL* pfAvailable, BOOL* pfSticky)
- {
- if (pfAvailable)
- *pfAvailable = TRUE;
- if (pfSticky)
- *pfSticky = FALSE;
- //
- // See if it is a link. If it is not, then it can't be in the wininet cache and can't
- // be pinned (sticky cache entry) or greyed (unavailable when offline)
- //
- WCHAR szUrl[MAX_URL_STRING];
- DWORD dwFlags = 0;
- HRESULT hr = GetNavTargetName(psf, pidlItem, szUrl, ARRAYSIZE(szUrl));
- if (SUCCEEDED(hr))
- {
- CHAR szUrlAnsi[MAX_URL_STRING];
- //
- // Get the cache info for this item. Note that we use GetUrlCacheEntryInfoEx instead
- // of GetUrlCacheEntryInfo because it follows any redirects that occured. This wacky
- // api uses a variable length buffer, so we have to guess the size and retry if the
- // call fails.
- //
- BOOL fInCache = FALSE;
- WCHAR szBuf[512];
- LPINTERNET_CACHE_ENTRY_INFOA pCE = (LPINTERNET_CACHE_ENTRY_INFOA)szBuf;
- DWORD dwEntrySize = ARRAYSIZE(szBuf);
- SHTCharToAnsi(szUrl, szUrlAnsi, ARRAYSIZE(szUrlAnsi));
- if (!(fInCache = GetUrlCacheEntryInfoExA(szUrlAnsi, pCE, &dwEntrySize, NULL, NULL, NULL, 0)))
- {
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- {
- // We guessed too small for the buffer so allocate the correct size & retry
- pCE = (LPINTERNET_CACHE_ENTRY_INFOA)LocalAlloc(LPTR, dwEntrySize);
- if (pCE)
- {
- fInCache = GetUrlCacheEntryInfoExA(szUrlAnsi, pCE, &dwEntrySize, NULL, NULL, NULL, 0);
- }
- }
- }
- //
- // If we are offline, see if the item is in the cache.
- //
- if (pfAvailable && SHIsGlobalOffline() && MayBeUnavailableOffline(szUrl) && !fInCache)
- {
- // Not available
- *pfAvailable = FALSE;
- }
- //
- // See if it's a sticky cache entry
- //
- if (pCE)
- {
- if (pfSticky && fInCache && (pCE->CacheEntryType & STICKY_CACHE_ENTRY))
- {
- *pfSticky = TRUE;
- }
- if ((TCHAR*)pCE != szBuf)
- {
- LocalFree(pCE);
- }
- }
- }
- return hr;
- }
- //
- // Get the avg char width given an hwnd
- //
- int GetAvgCharWidth(HWND hwnd)
- {
- ASSERT(hwnd);
- int nWidth = 0;
- HFONT hfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
- if (hfont)
- {
- HDC hdc = GetDC(NULL);
- if(hdc)
- {
- HFONT hfontOld = (HFONT)SelectObject(hdc, hfont);
- TEXTMETRIC tm;
- if (GetTextMetrics(hdc, &tm))
- nWidth = tm.tmAveCharWidth;
- SelectObject(hdc, hfontOld);
- ReleaseDC(NULL, hdc);
- }
- }
- return nWidth;
- }
- //
- // Converts all "&" into "&&" so that they show up
- // in menus
- //
- void FixAmpersands(LPWSTR pszToFix, UINT cchMax)
- {
- ASSERT(pszToFix && cchMax > 0);
- WCHAR szBuf[MAX_URL_STRING];
- LPWSTR pszBuf = szBuf;
- LPWSTR pszSrc = pszToFix;
- UINT cch = 0;
- while (*pszSrc && cch < ARRAYSIZE(szBuf)-2)
- {
- if (*pszSrc == '&')
- {
- *pszBuf++ = '&';
- ++cch;
- }
- *pszBuf++ = *pszSrc++;
- ++cch;
- }
- *pszBuf = 0;
- StrCpyN(pszToFix, szBuf, cchMax);
- }
- // EVIL: return an aliased pointer to the pidl in this variant (that is why it is const)
- // see VariantToIDList
- STDAPI_(LPCITEMIDLIST) VariantToConstIDList(const VARIANT *pv)
- {
- if (pv == NULL)
- return NULL;
- LPCITEMIDLIST pidl = NULL;
- if (pv->vt == (VT_BYREF | VT_VARIANT) && pv->pvarVal)
- pv = pv->pvarVal;
- switch (pv->vt)
- {
- case VT_UINT_PTR:
- // HACK in process case, avoid the use of this if possible
- pidl = (LPCITEMIDLIST)pv->byref;
- ASSERT(pidl);
- break;
- case VT_ARRAY | VT_UI1:
- pidl = (LPCITEMIDLIST)pv->parray->pvData; // alias: PIDL encoded
- break;
- }
- return pidl;
- }
- STDAPI_(LPITEMIDLIST) VariantToIDList(const VARIANT *pv)
- {
- LPITEMIDLIST pidl = NULL;
- if (pv)
- {
- if (pv->vt == (VT_BYREF | VT_VARIANT) && pv->pvarVal)
- pv = pv->pvarVal;
- switch (pv->vt)
- {
- case VT_I2:
- pidl = SHCloneSpecialIDList(NULL, pv->iVal, TRUE);
- break;
- case VT_I4:
- pidl = SHCloneSpecialIDList(NULL, pv->lVal, TRUE);
- break;
- case VT_BSTR:
- pidl = ILCreateFromPath(pv->bstrVal);
- break;
- case VT_ARRAY | VT_UI1:
- pidl = ILClone((LPCITEMIDLIST)pv->parray->pvData);
- break;
- default:
- LPCITEMIDLIST pidlToCopy = VariantToConstIDList(pv);
- if (pidlToCopy)
- pidl = ILClone(pidlToCopy);
- break;
- }
- }
- return pidl;
- }
- STDAPI VariantToBuffer(const VARIANT* pvar, void *pv, UINT cb)
- {
- if (pvar && pvar->vt == (VT_ARRAY | VT_UI1))
- {
- memcpy(pv, pvar->parray->pvData, cb);
- return TRUE;
- }
- return FALSE;
- }
- STDAPI VariantToGUID(VARIANT *pvar, GUID *pguid)
- {
- return VariantToBuffer(pvar, pguid, sizeof(*pguid));
- }
- STDAPI InitVariantFromBuffer(VARIANT *pvar, const void *pv, UINT cb)
- {
- HRESULT hres;
- SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, cb); // create a one-dimensional safe array
- if (psa)
- {
- memcpy(psa->pvData, pv, cb);
- memset(pvar, 0, sizeof(*pvar)); // VariantInit()
- pvar->vt = VT_ARRAY | VT_UI1;
- pvar->parray = psa;
- hres = S_OK;
- }
- else
- hres = E_OUTOFMEMORY;
- return hres;
- }
- STDAPI_(BOOL) InitVariantFromIDList(VARIANT* pvar, LPCITEMIDLIST pidl)
- {
- return SUCCEEDED(InitVariantFromBuffer(pvar, pidl, ILGetSize(pidl)));
- }
- STDAPI_(BOOL) InitVariantFromGUID(VARIANT *pvar, GUID *pguid)
- {
- return SUCCEEDED(InitVariantFromBuffer(pvar, pguid, SIZEOF(*pguid)));
- }
- // EVIL: if you know the VARIANT will be passed in process only you can
- // use this. note code above that decodes this properly
- //
- // the lifetime of the pidl must equal that of the VARIANT
- STDAPI_(void) InitVariantFromIDListInProc(VARIANT *pvar, LPCITEMIDLIST pidl)
- {
- memset(pvar, 0, sizeof(*pvar)); // VariantInit()
- pvar->vt = VT_UINT_PTR;
- pvar->byref = (PVOID)pidl;
- }
- #define SZ_REGKEY_INETCPL_POLICIES TEXT("Software\Policies\Microsoft\Internet Explorer\Control Panel")
- BOOL IsInetcplRestricted(LPWSTR pszCommand)
- {
- BOOL fDisabled;
- DWORD dwData;
- DWORD dwSize = sizeof(dwData);
- DWORD dwType;
- if (ERROR_SUCCESS == SHRegGetUSValue(
- SZ_REGKEY_INETCPL_POLICIES,
- pszCommand,
- &dwType,
- (LPVOID)&dwData,
- &dwSize,
- FALSE,
- NULL,
- 0))
- {
- fDisabled = dwData;
- }
- else
- {
- // If the value is missing from the registry, then
- // assume the feature is enabled
- fDisabled = FALSE;
- }
- return fDisabled;
- }
- BOOL HasExtendedChar(LPCWSTR pszQuery)
- {
- BOOL fNonAscii = FALSE;
- for (LPCWSTR psz = pszQuery; *psz; psz++)
- {
- if (*psz > 0x7f)
- {
- fNonAscii = TRUE;
- break;
- }
- }
- return fNonAscii;
- }
- void ConvertToUtf8Escaped(LPWSTR pszUrl, int cch)
- {
- // Convert to utf8
- char szBuf[MAX_URL_STRING];
- SHUnicodeToAnsiCP(CP_UTF8, pszUrl, szBuf, ARRAYSIZE(szBuf));
- // Escape the string into the original buffer
- LPSTR pchIn;
- LPWSTR pchOut = pszUrl;
- WCHAR ch;
- static const WCHAR hex[] = L"0123456789ABCDEF";
- for (pchIn = szBuf; *pchIn && cch > 3; pchIn++)
- {
- ch = *pchIn;
- if (ch > 0x7f)
- {
- cch -= 3;
- *pchOut++ = L'%';
- *pchOut++ = hex[(ch >> 4) & 15];
- *pchOut++ = hex[ch & 15];
- }
- else
- {
- --cch;
- *pchOut++ = *pchIn;
- }
- }
- *pchOut = L' ';
- }
- HRESULT IExtractIcon_GetIconLocation(
- IUnknown *punk,
- IN UINT uInFlags,
- OUT LPTSTR pszIconFile,
- IN UINT cchIconFile,
- OUT PINT pniIcon,
- OUT PUINT puOutFlags)
- {
- ASSERT(punk);
- HRESULT hr;
- if (g_fRunningOnNT)
- {
- IExtractIcon *pxi;
- hr = punk->QueryInterface(IID_IExtractIcon, (void **)&pxi);
- if (SUCCEEDED(hr))
- {
- hr = pxi->GetIconLocation(uInFlags, pszIconFile, cchIconFile, pniIcon, puOutFlags);
- pxi->Release();
- }
- }
- else
- {
- IExtractIconA *pxi;
- hr = punk->QueryInterface(IID_IExtractIconA, (void **)&pxi);
- if (SUCCEEDED(hr))
- {
- CHAR sz[MAX_PATH];
- hr = pxi->GetIconLocation(uInFlags, sz, SIZECHARS(sz), pniIcon, puOutFlags);
- if (SUCCEEDED(hr))
- SHAnsiToTChar(sz, pszIconFile, cchIconFile);
- pxi->Release();
- }
- }
- return hr;
- }
- HRESULT IExtractIcon_Extract(
- IUnknown *punk,
- IN LPCTSTR pszIconFile,
- IN UINT iIcon,
- OUT HICON * phiconLarge,
- OUT HICON * phiconSmall,
- IN UINT ucIconSize)
- {
- ASSERT(punk);
- HRESULT hr;
- if (g_fRunningOnNT)
- {
- IExtractIcon *pxi;
- hr = punk->QueryInterface(IID_IExtractIcon, (void **)&pxi);
- if (SUCCEEDED(hr))
- {
- hr = pxi->Extract(pszIconFile, iIcon, phiconLarge, phiconSmall, ucIconSize);
- pxi->Release();
- }
- }
- else
- {
- IExtractIconA *pxi;
- hr = punk->QueryInterface(IID_IExtractIconA, (void **)&pxi);
- if (SUCCEEDED(hr))
- {
- CHAR sz[MAX_PATH];
- SHTCharToAnsi(pszIconFile, sz, SIZECHARS(sz));
- hr = pxi->Extract(sz, iIcon, phiconLarge, phiconSmall, ucIconSize);
- pxi->Release();
- }
- }
- return hr;
- }
- typedef EXECUTION_STATE (__stdcall *PFNSTES) (EXECUTION_STATE);
- EXECUTION_STATE _SetThreadExecutionState(EXECUTION_STATE esFlags)
- {
- static PFNSTES _pfnSetThreadExecutionState = (PFNSTES)0xffffffff;
- if(_pfnSetThreadExecutionState == (PFNSTES)0xffffffff)
- _pfnSetThreadExecutionState = (PFNSTES)GetProcAddress(GetModuleHandleA("kernel32.dll"), "SetThreadExecutionState");
- if(_pfnSetThreadExecutionState != (PFNSTES)NULL)
- return(_pfnSetThreadExecutionState(esFlags));
- else
- return((EXECUTION_STATE)NULL);
- }
- HRESULT SHPathPrepareForWriteWrap(HWND hwnd, IUnknown *punkEnableModless, LPCTSTR pszPath, UINT wFunc, DWORD dwFlags)
- {
- HRESULT hr;
- if (g_bRunOnNT5)
- {
- // NT5's version of the API is better.
- hr = _SHPathPrepareForWriteW(hwnd, punkEnableModless, pszPath, dwFlags);
- }
- else
- {
- hr = SHCheckDiskForMedia(hwnd, punkEnableModless, pszPath, wFunc);
- }
- return hr;
- }
- void GetPathOtherFormA(LPSTR lpszPath, LPSTR lpszNewPath, DWORD dwSize)
- {
- BOOL bQuotes = FALSE;
- LPSTR szStart = lpszPath;
- LPSTR szEnd = NULL;
- LPSTR szNewStart = lpszNewPath;
- ZeroMemory(lpszNewPath, dwSize);
- // Cull out the starting and ending " because GetShortPathName does not
- // like it.
- if (*lpszPath == '"')
- {
- bQuotes = TRUE;
- szStart = lpszPath + 1;
- szEnd = lpszPath + lstrlenA(lpszPath) - 1; // Point to the last "
- *szEnd = ' ';
- szNewStart = lpszNewPath + 1; // So that we can insert the " in it.
- dwSize = dwSize - 2; // for the two double quotes to be added.
- }
- if (GetShortPathNameA(szStart, szNewStart, dwSize) != 0)
- {
- if (StrCmpIA(szStart, szNewStart) == 0)
- { // The original Path is a SFN. So NewPath needs to be LFN.
- GetLongPathNameA((LPCSTR)szStart, szNewStart, dwSize);
- }
- }
- // Now add the " to the NewPath so that it is in the expected form
- if (bQuotes)
- {
- int len = 0;
- // Fix the Original path.
- *szEnd = '"';
- // Fix the New path.
- *lpszNewPath = '"'; // Insert " in the beginning.
- len = lstrlenA(lpszNewPath);
- *(lpszNewPath + len) = '"'; // Add the " in the end.
- *(lpszNewPath + len + 1) = ' '; // Terminate the string.
- }
- return;
- }
- int GetUrlSchemeFromPidl(LPCITEMIDLIST pidl)
- {
- ASSERT(pidl);
- ASSERT(IsURLChild(pidl, FALSE));
- int nRet = URL_SCHEME_INVALID;
- WCHAR szUrl[MAX_URL_STRING];
- if (SUCCEEDED(IEGetNameAndFlags(pidl, SHGDN_FORPARSING, szUrl,
- ARRAYSIZE(szUrl), NULL)))
- {
- nRet = GetUrlScheme(szUrl);
- }
- return nRet;
- }
- //
- // Check if it is safe to create a shortcut for the given url. Used by add
- // to favorites code.
- //
- BOOL IEIsLinkSafe(HWND hwnd, LPCITEMIDLIST pidl, ILS_ACTION ilsFlag)
- {
- ASSERT(pidl);
- BOOL fRet = TRUE;
- if (IsURLChild(pidl, FALSE))
- {
- int nScheme = GetUrlSchemeFromPidl(pidl);
- if (URL_SCHEME_JAVASCRIPT == nScheme || URL_SCHEME_VBSCRIPT == nScheme)
- {
- WCHAR szTitle[MAX_PATH];
- WCHAR szText[MAX_PATH];
- MLLoadString(IDS_SECURITYALERT, szTitle, ARRAYSIZE(szTitle));
- MLLoadString(IDS_ADDTOFAV_WARNING + ilsFlag, szText,
- ARRAYSIZE(szText));
- fRet = (IDYES == MLShellMessageBox(hwnd, szText, szTitle, MB_YESNO |
- MB_ICONWARNING | MB_APPLMODAL |
- MB_DEFBUTTON2));
- }
- }
- return fRet;
- }
- BOOL AccessAllowed(LPCWSTR pwszURL1, LPCWSTR pwszURL2)
- {
- BOOL fRet = FALSE;
- IInternetSecurityManager *pSecMgr = NULL;
- if (pwszURL1 && pwszURL2 && SUCCEEDED(CoCreateInstance(CLSID_InternetSecurityManager,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IInternetSecurityManager,
- (void **)&pSecMgr)))
- {
- BYTE reqSid[MAX_SIZE_SECURITY_ID], docSid[MAX_SIZE_SECURITY_ID];
- DWORD cbReqSid = ARRAYSIZE(reqSid);
- DWORD cbDocSid = ARRAYSIZE(docSid);
- if ( SUCCEEDED(pSecMgr->GetSecurityId(pwszURL1, reqSid, &cbReqSid, 0))
- && SUCCEEDED(pSecMgr->GetSecurityId(pwszURL2, docSid, &cbDocSid, 0))
- && (cbReqSid == cbDocSid)
- && (memcmp(reqSid, docSid, cbReqSid) == 0))
- {
- fRet = TRUE;
- }
- pSecMgr->Release();
- }
- return fRet;
- }
English
