2020-09-30 17:12:32 +02:00

1136 lines
22 KiB
C++

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// persist.cpp
// IPersistFolder for the cdfview class.
// History:
// 3/16/97 edwardp Created.
// Includes
#include "stdinc.h"
#include "cdfidl.h"
#include "persist.h"
#include "xmlutil.h"
#include "cdfview.h"
#include "bindstcb.h"
#include "chanapi.h"
#include "resource.h"
#include <winineti.h> // MAX_CACHE_ENTRY_INFO_SIZE
#include "dll.h"
#define _SHDOCVW_
#include <shdocvw.h>
#include <mluisupp.h>
// Constructor and destructor
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CPersist::CPersist ***
// Constructor.
CPersist::CPersist(
void
)
: m_bCdfParsed(FALSE)
{
ASSERT(0 == *m_szPath);
ASSERT(NULL == m_polestrURL);
ASSERT(NULL == m_pIWebBrowser2);
ASSERT(NULL == m_hwnd);
ASSERT(NULL == m_pIXMLDocument);
ASSERT(FALSE == m_fPendingNavigation);
ASSERT(IT_UNKNOWN == m_rgInitType);
return;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CPersist::CPersist ***
// Constructor.
CPersist::CPersist(
BOOL bCdfParsed
)
: m_bCdfParsed(bCdfParsed)
{
ASSERT(0 == *m_szPath);
ASSERT(NULL == m_polestrURL);
ASSERT(NULL == m_pIWebBrowser2);
ASSERT(NULL == m_hwnd);
ASSERT(NULL == m_pIXMLDocument);
ASSERT(FALSE == m_fPendingNavigation);
return;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CPersist::CPersist ***
// Constructor.
CPersist::~CPersist(
void
)
{
if (m_fPendingNavigation && m_pIWebBrowser2 && m_pIXMLDocument) {
}
if (m_polestrURL)
CoTaskMemFree(m_polestrURL);
if (m_pIWebBrowser2)
m_pIWebBrowser2->Release();
if (m_pIXMLDocument)
m_pIXMLDocument->Release();
return;
}
// IPersist methods.
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::GetClassID ***
// Description:
// Parameters:
// Return:
// Comments:
STDMETHODIMP
CPersist::GetClassID(
LPCLSID lpClassID
)
{
ASSERT(lpClassID);
// REVIEW: Two possible class IDs CLSID_CDFVIEW & CLSID_CDF_INI
*lpClassID = CLSID_CDFVIEW;
return S_OK;
}
// IPersistFile methods.
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::IsDirty ***
// Description:
// Parameters:
// Return:
// Comments:
STDMETHODIMP
CPersist::IsDirty(
void
)
{
return E_NOTIMPL;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::Load ***
// Description:
// Parameters:
// Return:
// Comments:
STDMETHODIMP
CPersist::Load(
LPCOLESTR pszFileName,
DWORD dwMode
)
{
ASSERT(pszFileName);
HRESULT hr;
if (SHUnicodeToTChar(pszFileName, m_szPath, ARRAYSIZE(m_szPath))) {
hr = S_OK;
QuickCheckInitType();
} else {
hr = E_FAIL;
}
return hr;
}
void CPersist::QuickCheckInitType(void)
{
// if the path is a directory then
// it has to be a Shellfolder we were initialised for.
// we are calculating this here so that we can avoid hitting the disk
// in GetInitType if at all possible.
if (PathIsDirectory(m_szPath)) {
m_rgInitType = IT_INI;
}
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::Save ***
// Description:
// Parameters:
// Return:
// Comments:
STDMETHODIMP
CPersist::Save(
LPCOLESTR pszFileName,
BOOL fRemember
)
{
return E_NOTIMPL;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::SaveCompleted ***
// Description:
// Parameters:
// Return:
// Comments:
STDMETHODIMP
CPersist::SaveCompleted(
LPCOLESTR pszFileName
)
{
return E_NOTIMPL;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::GetCurFile ***
// Description:
// Parameters:
// Return:
// Comments:
STDMETHODIMP
CPersist::GetCurFile(
LPOLESTR* ppszFileName
)
{
return E_NOTIMPL;
}
// IPersistFolder methods.
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::Initialize ***
// Description:
// This function is called with the fully qualified id list (location) of
// the selected cdf file.
// Parameters:
// [In] pidl - The pidl of the selected cdf file. This pidl conatins the
// full path to the CDF.
// Return:
// S_OK if content for the cdf file could be created.
// E_OUTOFMEMORY otherwise.
// Comments:
// This function can be called more than once for a given folder. When a
// CDFView is being instantiated from a desktop.ini file the shell calls
// Initialize once before it calls GetUIObjectOf asking for IDropTarget.
// After the GetUIObjectOf call the folder is Released. It then calls
// Initialize again on a new folder. This time it keeps the folder and it
// ends up being displayed.
STDMETHODIMP
CPersist::Initialize(
LPCITEMIDLIST pidl
)
{
ASSERT(pidl);
ASSERT(0 == *m_szPath);
HRESULT hr = SHGetPathFromIDList(pidl, m_szPath) ? S_OK : E_FAIL;
QuickCheckInitType();
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CPersist::Parse ***
// Description:
// Parameters:
// Return:
// Comments:
HRESULT
CPersist::Parse(
LPTSTR szURL,
IXMLDocument** ppIXMLDocument
)
{
ASSERT(szURL);
HRESULT hr;
DLL_ForcePreloadDlls(PRELOAD_MSXML);
hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDocument, (void**)ppIXMLDocument);
BOOL bCoInit = FALSE;
if ((CO_E_NOTINITIALIZED == hr || REGDB_E_IIDNOTREG == hr) && SUCCEEDED(CoInitialize(NULL))) {
bCoInit = TRUE;
hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDocument, (void**)ppIXMLDocument);
}
if (SUCCEEDED(hr)) {
ASSERT(*ppIXMLDocument);
hr = XML_SynchronousParse(*ppIXMLDocument, szURL);
}
if (bCoInit)
CoUninitialize();
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::ParseCdf ***
// Description:
// Parses the cdf file associated with this folder.
// Parameters:
// [In] hwndOwner - The parent window of any dialogs that need to be
// displayed.
// [Out] ppIXMLDocument - A pointer that receives the xml document.
// Return:
// S_OK if the cdf file was found and successfully parsed.
// E_FAIL otherwise.
// Comments:
// Uses the m_pidlRoot that was set during IPersistFolder::Initialize.
HRESULT
CPersist::ParseCdf(
HWND hwndOwner,
IXMLDocument** ppIXMLDocument,
DWORD dwParseFlags
)
{
ASSERT(ppIXMLDocument);
HRESULT hr;
if (*m_szPath) {
INITTYPE it = GetInitType(m_szPath);
switch (it) {
case IT_FILE:
hr = InitializeFromURL(m_szPath, ppIXMLDocument, dwParseFlags);
break;
case IT_INI:
{
TCHAR szURL[INTERNET_MAX_URL_LENGTH];
if (ReadFromIni(TSTR_INI_URL, szURL, ARRAYSIZE(szURL))) {
hr = InitializeFromURL(szURL, ppIXMLDocument, dwParseFlags);
} else {
hr = E_FAIL;
}
}
break;
case IT_SHORTCUT:
case IT_UNKNOWN:
hr = E_FAIL;
break;
}
} else {
hr = E_OUTOFMEMORY;
}
// REVIEW: Properly notify user on failure to init.
if (FAILED(hr) && hwndOwner) {
TCHAR szText[MAX_PATH];
TCHAR szTitle[MAX_PATH];
MLLoadString(IDS_ERROR_DLG_TEXT, szText, MAX_PATH);
MLLoadString(IDS_ERROR_DLG_TITLE, szTitle, MAX_PATH);
MessageBox(hwndOwner, szText, szTitle, MB_OK | MB_ICONWARNING);
}
ASSERT((SUCCEEDED(hr) && *ppIXMLDocument) || FAILED(hr));
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::GetInitType ***
// Description:
// Determines the method being used to designate the cdf file.
// Parameters:
// [In] szPath - The path passed in to IPersistFolder::Initialize.
// Return:
// IT_INI if this instance is being created from a desktop.ini file
// located in a right protected directory.
// IT_FILE if this instance is being created from opening a cdf file.
// IT_UNKNOWN if the method can not be determined.
// Comments:
INITTYPE
CPersist::GetInitType(
LPTSTR szPath
)
{
if (m_rgInitType != IT_UNKNOWN) {
return m_rgInitType;
}
ASSERT(szPath);
INITTYPE itRet;
if (PathIsDirectory(szPath)) {
itRet = IT_INI;
} else {
itRet = IT_FILE;
}
m_rgInitType = itRet;
return itRet;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CCdfView::InitializeFromURL ***
// Description:
// Given an URL to a cdf an attempt is made to parse the cdf and initialize
// the current (root) folder.
// Parameters:
// [In] szURL - The URL of the cdf file.
// [Out] ppIXMLDocument - A pointer that receives the xml document.
// Return:
// S_OK if initializtion succeeded.
// E_FAIL otherwise.
// Comments:
// All other initialize methods eventually resolve to an URL and call this
// methhod.
HRESULT
CPersist::InitializeFromURL(
LPTSTR pszURL,
IXMLDocument** ppIXMLDocument,
DWORD dwParseFlags
)
{
ASSERT(pszURL);
ASSERT(ppIXMLDocument);
HRESULT hr;
TCHAR szCanonicalURL[INTERNET_MAX_URL_LENGTH];
if (PathIsURL(pszURL)) {
ULONG cch = ARRAYSIZE(szCanonicalURL);
if (InternetCanonicalizeUrl(pszURL, szCanonicalURL, &cch, 0))
pszURL = szCanonicalURL;
}
// Get an XML document object from the cache if it's there. Otherwise
// parse it and place it in the cache.
if (PARSE_REPARSE & dwParseFlags) {
(void)Cache_RemoveItem(pszURL);
hr = E_FAIL;
} else {
hr = Cache_QueryItem(pszURL, ppIXMLDocument, dwParseFlags);
if (SUCCEEDED(hr))
TraceMsg(TF_CDFPARSE, "[XML Document Cache]");
}
if (FAILED(hr)) {
DWORD dwCacheCount = g_dwCacheCount;
FILETIME ftLastMod;
if (dwParseFlags & PARSE_LOCAL) {
TCHAR szLocalFile[MAX_PATH];
hr = URLGetLocalFileName(pszURL, szLocalFile,
ARRAYSIZE(szLocalFile), &ftLastMod);
if (SUCCEEDED(hr)) {
hr = Parse(szLocalFile, ppIXMLDocument);
} else {
hr = OLE_E_NOCACHE;
}
} else {
TraceMsg(TF_CDFPARSE, "[*** CDF parse enabled to hit net!!! ***]");
hr = Parse(pszURL, ppIXMLDocument);
URLGetLastModTime(pszURL, &ftLastMod);
// Stuff the images files into the cache.
if (SUCCEEDED(hr)) {
ASSERT(*ppIXMLDocument);
XML_DownloadImages(*ppIXMLDocument);
}
}
if (SUCCEEDED(hr)) {
Cache_AddItem(pszURL, *ppIXMLDocument, dwParseFlags, ftLastMod,
dwCacheCount);
}
}
if (SUCCEEDED(hr)) {
ASSERT(*ppIXMLDocument);
m_bCdfParsed = TRUE;
if (dwParseFlags & PARSE_REMOVEGLEAM)
ClearGleamFlag(pszURL, m_szPath);
}
ASSERT((SUCCEEDED(hr) && m_bCdfParsed && *ppIXMLDocument) || FAILED(hr));
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CPersist::ReadFromIni ***
// Description:
// Reads a string from the channel desktop.ini file.
// Parameters:
// pszKey - The key to read.
// szOut - The result.
// cch - The size of the szout Buffer
// Return:
// A bstr containing the value associated with the key.
// Comments:
BOOL
CPersist::ReadFromIni(
LPCTSTR pszKey,
LPTSTR szOut,
int cch
)
{
ASSERT(pszKey);
ASSERT(szOut || 0 == cch);
BOOL fRet = FALSE;
if (m_szPath && *m_szPath) {
INITTYPE it = GetInitType(m_szPath);
if (it == IT_INI) {
LPCTSTR szFile = TSTR_INI_FILE;
LPCTSTR szSection = TSTR_INI_SECTION;
LPCTSTR szKey = pszKey;
TCHAR szPath[MAX_PATH];
StrCpyN(szPath, m_szPath, ARRAYSIZE(szPath) - StrLen(szFile));
StrCat(szPath, szFile);
if (GetPrivateProfileString(szSection, szKey, TEXT(""), szOut, cch, szPath)) {
fRet = TRUE;
}
}
}
return fRet;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CPersist::ReadFromIni ***
// Description:
// Reads a string from the channel desktop.ini file.
// Parameters:
// pszKey - The key to read.
// Return:
// A bstr containing the value associated with the key.
// Comments:
BSTR
CPersist::ReadFromIni(
LPCTSTR pszKey
)
{
ASSERT(pszKey);
BSTR bstrRet = NULL;
TCHAR szURL[INTERNET_MAX_URL_LENGTH];
if (ReadFromIni(pszKey, szURL, ARRAYSIZE(szURL))) {
WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
if (SHTCharToUnicode(szURL, wszURL, ARRAYSIZE(wszURL)))
bstrRet = SysAllocString(wszURL);
}
return bstrRet;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CPersist::IsUnreadCdf ***
// Description:
// Parameters:
// Return:
// Comments:
BOOL
CPersist::IsUnreadCdf(
void
)
{
BOOL fRet = FALSE;
TCHAR szURL[INTERNET_MAX_URL_LENGTH];
if (ReadFromIni(TSTR_INI_URL, szURL, ARRAYSIZE(szURL))) {
fRet = IsRecentlyChangedURL(szURL);
}
return fRet;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** CPersist::IsNewContent ***
// Description:
// Parameters:
// Return:
// Comments:
BOOL
CPersist::IsRecentlyChangedURL(
LPCTSTR pszURL
)
{
ASSERT(pszURL);
BOOL fRet = FALSE;
HRESULT hr;
IPropertySetStorage* pIPropertySetStorage;
hr = QueryInternetShortcut(pszURL, IID_IPropertySetStorage,
(void**)&pIPropertySetStorage);
if (SUCCEEDED(hr)) {
ASSERT(pIPropertySetStorage);
IPropertyStorage* pIPropertyStorage;
hr = pIPropertySetStorage->Open(FMTID_InternetSite, STGM_READWRITE,
&pIPropertyStorage);
if (SUCCEEDED(hr)) {
ASSERT(pIPropertyStorage);
PROPSPEC propspec = {PRSPEC_PROPID, PID_INTSITE_FLAGS};
PROPVARIANT propvar;
PropVariantInit(&propvar);
hr = pIPropertyStorage->ReadMultiple(1, &propspec, &propvar);
if (SUCCEEDED(hr) && (VT_UI4 == propvar.vt)) {
fRet = propvar.ulVal & PIDISF_RECENTLYCHANGED;
} else {
PropVariantClear(&propvar);
}
pIPropertyStorage->Release();
}
pIPropertySetStorage->Release();
}
return fRet;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** ClearGleamFlag ***
// Description:
// Parameters:
// Return:
// Comments:
HRESULT
ClearGleamFlag(
LPCTSTR pszURL,
LPCTSTR pszPath
)
{
ASSERT(pszURL);
ASSERT(pszPath);
HRESULT hr;
IPropertySetStorage* pIPropertySetStorage;
hr = QueryInternetShortcut(pszURL, IID_IPropertySetStorage,
(void**)&pIPropertySetStorage);
if (SUCCEEDED(hr)) {
ASSERT(pIPropertySetStorage);
IPropertyStorage* pIPropertyStorage;
hr = pIPropertySetStorage->Open(FMTID_InternetSite, STGM_READWRITE,
&pIPropertyStorage);
if (SUCCEEDED(hr)) {
ASSERT(pIPropertyStorage);
PROPSPEC propspec = {PRSPEC_PROPID, PID_INTSITE_FLAGS};
PROPVARIANT propvar;
PropVariantInit(&propvar);
hr = pIPropertyStorage->ReadMultiple(1, &propspec, &propvar);
if (SUCCEEDED(hr) && (VT_UI4 == propvar.vt) &&
(propvar.ulVal & PIDISF_RECENTLYCHANGED)) {
TCHAR szHash[MAX_PATH];
int iIndex;
UINT uFlags;
int iImageIndex;
HRESULT hr2 = PreUpdateChannelImage(pszPath, szHash, &iIndex,
&uFlags, &iImageIndex);
propvar.ulVal &= ~PIDISF_RECENTLYCHANGED;
hr = pIPropertyStorage->WriteMultiple(1, &propspec, &propvar,
0);
if (SUCCEEDED(hr))
hr = pIPropertyStorage->Commit(STGC_DEFAULT);
TraceMsg(TF_GLEAM, "- Gleam Cleared %s", pszURL);
if (SUCCEEDED(hr) && SUCCEEDED(hr2)) {
WCHAR wszHash[MAX_PATH];
SHTCharToUnicode(szHash, wszHash, ARRAYSIZE(wszHash));
UpdateChannelImage(wszHash, iIndex, uFlags, iImageIndex);
}
} else {
PropVariantClear(&propvar);
}
pIPropertyStorage->Release();
}
pIPropertySetStorage->Release();
}
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// *** URLGetLocalFileName ***
// Description:
// Parameters:
// Return:
// Comments:
HRESULT
URLGetLocalFileName(
LPCTSTR pszURL,
LPTSTR szLocalFile,
int cch,
FILETIME* pftLastMod
)
{
ASSERT(pszURL);
ASSERT(szLocalFile || 0 == cch);
HRESULT hr = E_FAIL;
if (pftLastMod) {
pftLastMod->dwLowDateTime = 0;
pftLastMod->dwHighDateTime = 0;
}
// by using the internal shlwapi function, we avoid loading WININET
// unless we really really need it...
if (PathIsURL(pszURL)) {
PARSEDURL rgCrackedURL = {0};
rgCrackedURL.cbSize = sizeof(rgCrackedURL);
if (SUCCEEDED(ParseURL(pszURL, &rgCrackedURL))) {
switch (rgCrackedURL.nScheme) {
case URL_SCHEME_HTTP:
case URL_SCHEME_FTP:
case URL_SCHEME_GOPHER:
{
ULONG cbSize = MAX_CACHE_ENTRY_INFO_SIZE;
INTERNET_CACHE_ENTRY_INFO* piceiAlloced =
(INTERNET_CACHE_ENTRY_INFO*) new BYTE[cbSize];
if (piceiAlloced) {
piceiAlloced->dwStructSize =
sizeof(INTERNET_CACHE_ENTRY_INFO);
if (GetUrlCacheEntryInfoEx(pszURL, piceiAlloced,
&cbSize, NULL, NULL,
NULL, 0)) {
if (StrCpyN(szLocalFile,
piceiAlloced->lpszLocalFileName, cch)) {
if (pftLastMod) {
*pftLastMod =
piceiAlloced->LastModifiedTime;
}
hr = S_OK;
}
}
delete[] piceiAlloced;
}
}
break;
case URL_SCHEME_FILE:
hr = PathCreateFromUrl(pszURL, szLocalFile, (LPDWORD)&cch, 0);
break;
}
}
} else {
if (StrCpyN(szLocalFile, pszURL, cch))
hr = S_OK;
}
return hr;
}
// Get the last modified time of the URL.
HRESULT
URLGetLastModTime(
LPCTSTR pszURL,
FILETIME* pftLastMod
)
{
ASSERT(pszURL);
ASSERT(pftLastMod);
pftLastMod->dwLowDateTime = 0;
pftLastMod->dwHighDateTime = 0;
ULONG cbSize = 0;
if (!GetUrlCacheEntryInfoEx(pszURL, NULL, &cbSize, NULL, NULL, NULL, 0)
&& cbSize > 0) {
INTERNET_CACHE_ENTRY_INFO* piceiAlloced =
(INTERNET_CACHE_ENTRY_INFO*) new BYTE[cbSize];
if (piceiAlloced) {
piceiAlloced->dwStructSize = sizeof(INTERNET_CACHE_ENTRY_INFO);
if (GetUrlCacheEntryInfoEx(pszURL, piceiAlloced, &cbSize, NULL,
NULL, NULL, 0)) {
*pftLastMod = piceiAlloced->LastModifiedTime;
}
delete[] piceiAlloced;
}
}
return S_OK;
}
/*STDMETHODIMP
CPersist::IsDirty(
void
)
{
return E_NOTIMPL;
}*/
STDMETHODIMP
CPersist::Load(
BOOL fFullyAvailable,
IMoniker* pIMoniker,
IBindCtx* pIBindCtx,
DWORD grfMode
)
{
ASSERT(pIMoniker);
ASSERT(pIBindCtx);
HRESULT hr;
ASSERT(NULL == m_polestrURL);
hr = pIMoniker->GetDisplayName(pIBindCtx, NULL, &m_polestrURL);
if (SUCCEEDED(hr)) {
ASSERT(m_polestrURL);
ASSERT(NULL == m_pIXMLDocument)
DLL_ForcePreloadDlls(PRELOAD_MSXML);
hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDocument, (void**)&m_pIXMLDocument);
if (SUCCEEDED(hr)) {
ASSERT(m_pIXMLDocument);
CBindStatusCallback* pCBindStatusCallback = new CBindStatusCallback(
m_pIXMLDocument,
m_polestrURL);
if (pCBindStatusCallback) {
IBindStatusCallback* pPrevIBindStatusCallback;
hr = RegisterBindStatusCallback(pIBindCtx,
(IBindStatusCallback*)pCBindStatusCallback,
&pPrevIBindStatusCallback, 0);
if (SUCCEEDED(hr)) {
pCBindStatusCallback->Init(pPrevIBindStatusCallback);
IPersistMoniker* pIPersistMoniker;
hr = m_pIXMLDocument->QueryInterface(IID_IPersistMoniker,
(void**)&pIPersistMoniker);
if (SUCCEEDED(hr)) {
ASSERT(pIPersistMoniker);
hr = pIPersistMoniker->Load(fFullyAvailable, pIMoniker,
pIBindCtx, grfMode);
pIPersistMoniker->Release();
}
}
pCBindStatusCallback->Release();
} else {
hr = E_OUTOFMEMORY;
}
}
}
return hr;
}
STDMETHODIMP
CPersist::Save(
IMoniker* pIMoniker,
IBindCtx* pIBindCtx,
BOOL fRemember
)
{
return E_NOTIMPL;
}
STDMETHODIMP CPersist::SaveCompleted(IMoniker* pIMoniker, IBindCtx* pIBindCtx)
{
return E_NOTIMPL;
}
STDMETHODIMP CPersist::GetCurMoniker(IMoniker** ppIMoniker)
{
return E_NOTIMPL;
}