701 lines
21 KiB
C++
701 lines
21 KiB
C++
// Moniker.cpp -- Implementation for the CStorageMoniker class
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
HRESULT CStorageMoniker::CreateStorageMoniker
|
|
(IUnknown *punkOuter,
|
|
IBindCtx __RPC_FAR *pbc,
|
|
LPOLESTR pszDisplayName,
|
|
ULONG __RPC_FAR *pchEaten,
|
|
IMoniker __RPC_FAR *__RPC_FAR *ppmkOut
|
|
)
|
|
{
|
|
CStorageMoniker *pstmk = New CStorageMoniker(punkOuter);
|
|
|
|
return FinishSetup(pstmk? pstmk->m_ImpIStorageMoniker.InitCreateStorageMoniker
|
|
(pbc, pszDisplayName, pchEaten)
|
|
: STG_E_INSUFFICIENTMEMORY,
|
|
pstmk, IID_IMoniker, (PPVOID) ppmkOut
|
|
);
|
|
}
|
|
|
|
CStorageMoniker::CImpIStorageMoniker::CImpIStorageMoniker
|
|
(CStorageMoniker *pBackObj, IUnknown *punkOuter)
|
|
: IITMoniker(pBackObj, punkOuter)
|
|
{
|
|
m_pStorageRoot = NULL;
|
|
m_awszStorageFile[0] = 0;
|
|
m_awszStoragePath[0] = 0;
|
|
#ifdef IE30Hack
|
|
m_acsTempFile [0] = 0;
|
|
m_pcsDisplayName = NULL;
|
|
#endif // IE30Hack
|
|
}
|
|
|
|
CStorageMoniker::CImpIStorageMoniker::~CImpIStorageMoniker(void)
|
|
{
|
|
if (m_pStorageRoot)
|
|
m_pStorageRoot->Release();
|
|
|
|
#ifdef IE30Hack
|
|
if (m_pcsDisplayName)
|
|
{
|
|
UnlockUrlCacheEntryFile(m_pcsDisplayName, 0);
|
|
|
|
delete [] m_pcsDisplayName;
|
|
}
|
|
|
|
if (m_acsTempFile[0])
|
|
DeleteFile(m_acsTempFile);
|
|
#endif // IE30Hack
|
|
}
|
|
|
|
HRESULT CStorageMoniker::CImpIStorageMoniker::InitCreateStorageMoniker
|
|
(IBindCtx __RPC_FAR *pbc,
|
|
LPOLESTR pszDisplayName,
|
|
ULONG __RPC_FAR *pchEaten
|
|
)
|
|
{
|
|
DWORD cwc = wcsLen(pszDisplayName) + 1;
|
|
DWORD cb = cwc * sizeof(WCHAR);
|
|
|
|
PWCHAR pwcsCopy = PWCHAR(_alloca(cwc * sizeof(WCHAR)));
|
|
|
|
if (!pwcsCopy) return E_OUTOFMEMORY;
|
|
|
|
memCpy(pwcsCopy, pszDisplayName, cb);
|
|
|
|
PWCHAR pwcsExternal = NULL;
|
|
PWCHAR pwcsInternal = NULL;
|
|
PWCHAR pwcsProtocol = NULL;
|
|
|
|
HRESULT hr = DisectUrl(pwcsCopy, &pwcsProtocol, &pwcsExternal, &pwcsInternal);
|
|
|
|
if (!SUCCEEDED(hr))
|
|
return (hr == INET_E_DEFAULT_ACTION)? INET_E_INVALID_URL : hr;
|
|
|
|
wcsCpy(m_awszStorageFile, pwcsExternal);
|
|
wcsCpy(m_awszStoragePath, pwcsInternal);
|
|
|
|
cwc = wcsLen(m_awszStoragePath);
|
|
|
|
if (m_awszStoragePath[cwc-1] == L'/')
|
|
m_awszStoragePath[cwc-1] = 0;
|
|
|
|
*pchEaten = cwc - 1;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// IPersist methods
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::GetClassID(
|
|
/* [out] */ CLSID __RPC_FAR *pClassID)
|
|
{
|
|
*pClassID = CLSID_ITStorage;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
// IPersistStream methods
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::IsDirty( void)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::Load(
|
|
/* [unique][in] */ IStream __RPC_FAR *pStm)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::Save(
|
|
/* [unique][in] */ IStream __RPC_FAR *pStm,
|
|
/* [in] */ BOOL fClearDirty)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::GetSizeMax(
|
|
/* [out] */ ULARGE_INTEGER __RPC_FAR *pcbSize)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
// IMoniker methods
|
|
|
|
/* [local] */ HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::BindToObject(
|
|
/* [unique][in] */ IBindCtx __RPC_FAR *pbc,
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkToLeft,
|
|
/* [in] */ REFIID riidResult,
|
|
/* [out] */ void __RPC_FAR *__RPC_FAR *ppvResult)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
#pragma data_seg(".text", "CODE")
|
|
static const char txtTomeMapKey [] = ITSS_MAP;
|
|
static const char txtTomeFinderKey[] = ITSS_FINDER;
|
|
#pragma data_seg()
|
|
|
|
HRESULT STDMETHODCALLTYPE FileExists(WCHAR *pwszStorageFile, const CHAR *pcsFullPath)
|
|
{
|
|
if (GetFileAttributes(pcsFullPath) == (DWORD) -1)
|
|
return STG_E_FILENOTFOUND;
|
|
|
|
// File exists! Now we need to convert the path to Unicode and store it.
|
|
|
|
WCHAR awcsPath[MAX_PATH];
|
|
|
|
UINT cwc = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, pcsFullPath, -1,
|
|
awcsPath, MAX_PATH
|
|
);
|
|
|
|
if (cwc == 0 || cwc > MAX_PATH)
|
|
return STG_E_FILENOTFOUND;
|
|
|
|
wcsCpy(pwszStorageFile, awcsPath);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
char * __stdcall FindMBCSExtension(char *pcsFileName)
|
|
{
|
|
char *pchLastPeriod = NULL;
|
|
|
|
for (;; pcsFileName = DBCS_SYSTEM()? CharNext(pcsFileName) : pcsFileName + 1)
|
|
{
|
|
char ch = *pcsFileName;
|
|
|
|
if (!ch) break;
|
|
|
|
if (ch != '.') continue;
|
|
|
|
pchLastPeriod = pcsFileName;
|
|
}
|
|
|
|
return pchLastPeriod;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE FindRootStorageFile(WCHAR * pwszStorageFile)
|
|
{
|
|
char csRoot [MAX_PATH * 2]; // * 2 for DBCS locales
|
|
char csBuffer[MAX_PATH * 2];
|
|
|
|
UINT cb = WideCharToMultiByte(CP_USER_DEFAULT(), WC_COMPOSITECHECK | WC_SEPCHARS,
|
|
pwszStorageFile, 1 + wcsLen(pwszStorageFile),
|
|
csRoot, sizeof(csRoot), NULL, NULL
|
|
);
|
|
|
|
if (cb == 0)
|
|
return STG_E_INVALIDNAME;
|
|
|
|
LPSTR pcsFileName = NULL;
|
|
|
|
UINT cbFull = GetFullPathName(csRoot, sizeof(csBuffer), csBuffer, &pcsFileName);
|
|
|
|
if (!cbFull || !pcsFileName)
|
|
return STG_E_INVALIDNAME;
|
|
|
|
HRESULT hr = FileExists(pwszStorageFile, (const char *) csBuffer);
|
|
|
|
if (hr == S_OK) return hr;
|
|
|
|
HKEY hkey;
|
|
DWORD type;
|
|
DWORD cbPath = MAX_PATH;
|
|
|
|
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, txtTomeMapKey, 0, KEY_READ, &hkey);
|
|
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
result = RegQueryValueEx(hkey, (const char *) pcsFileName, 0, &type,
|
|
(PBYTE) csRoot, &cbPath
|
|
);
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
hr = FileExists(pwszStorageFile, (const char *) csRoot);
|
|
|
|
if (hr == S_OK) return hr;
|
|
}
|
|
|
|
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, txtTomeFinderKey, 0, KEY_READ, &hkey);
|
|
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
result = RegQueryValueEx(hkey, (const char *) pcsFileName, 0, &type,
|
|
(PBYTE) csRoot, &cbPath
|
|
);
|
|
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
char *pcsFileExtension = FindMBCSExtension(pcsFileName);
|
|
|
|
if (pcsFileExtension)
|
|
result = RegQueryValueEx(hkey, pcsFileExtension, 0, &type,
|
|
(PBYTE) csRoot, &cbPath
|
|
);
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
hr = STG_E_FILENOTFOUND;
|
|
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
CLSID clsid;
|
|
|
|
WCHAR wcsFileName[MAX_PATH];
|
|
|
|
UINT cwc = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, csRoot, -1,
|
|
wcsFileName, MAX_PATH
|
|
);
|
|
|
|
if (cwc != 0)
|
|
{
|
|
HRESULT hr2 = CLSIDFromString(wcsFileName, &clsid);
|
|
|
|
if (hr2 == S_OK)
|
|
{
|
|
IITFileFinder *pFileFinder = NULL;
|
|
|
|
cwc = MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, pcsFileName, -1,
|
|
wcsFileName, MAX_PATH
|
|
);
|
|
if (cwc != 0)
|
|
{
|
|
hr2 = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IITFileFinder,
|
|
(void **) &pFileFinder
|
|
);
|
|
|
|
if (hr2 == S_OK)
|
|
__try
|
|
{
|
|
WCHAR *pwcsFullPath = NULL;
|
|
BOOL fRecord = FALSE;
|
|
|
|
hr2 = pFileFinder->FindThisFile((const WCHAR *) wcsFileName, &pwcsFullPath, &fRecord);
|
|
|
|
// REMOVE THIS
|
|
OutputDebugString("Moniker.cpp Find This File\n");
|
|
OutputDebugStringW(wcsFileName);
|
|
OutputDebugString("\n");
|
|
// REMOVE THIS
|
|
pFileFinder->Release(); pFileFinder = NULL;
|
|
|
|
if (hr2 == S_OK)
|
|
{
|
|
RonM_ASSERT(pwcsFullPath);
|
|
|
|
cb = WideCharToMultiByte(CP_USER_DEFAULT(), WC_COMPOSITECHECK | WC_SEPCHARS,
|
|
pwcsFullPath, 1 + wcsLen(pwcsFullPath),
|
|
csRoot, sizeof(csRoot), NULL, NULL
|
|
);
|
|
|
|
OLEHeap()->Free(pwcsFullPath);
|
|
|
|
hr = (cb == 0)? STG_E_FILENOTFOUND
|
|
: FileExists(pwszStorageFile, (const char *) csRoot);
|
|
|
|
if (hr == S_OK && fRecord)
|
|
{
|
|
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, txtTomeMapKey, 0, KEY_READ, &hkey);
|
|
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
result = RegSetValueEx(hkey, (const char *) pcsFileName, 0, REG_SZ,
|
|
(PBYTE) csRoot, lstrlen(csRoot)
|
|
);
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
__except (TRUE)
|
|
{
|
|
if (pFileFinder)
|
|
pFileFinder->Release();
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::OpenRootStorage
|
|
(DWORD grfMode)
|
|
{
|
|
PWCHAR pwc = wcsChr((const WCHAR *) m_awszStorageFile, L':');
|
|
|
|
if (pwc && pwc[1] == L':') // Ignore a "::" separator
|
|
pwc = NULL;
|
|
|
|
// Here we're special casing non-protocol references to a file.
|
|
// We recognize those situations by looking for a protocol prefix.
|
|
// Protocol prefixes have the form <Protocol Name> :
|
|
// where <Protocol Name> is always longer than one character.
|
|
|
|
if (!pwc || (pwc - m_awszStorageFile == 1))
|
|
{
|
|
HRESULT hr = FindRootStorageFile(m_awszStorageFile);
|
|
|
|
if (hr != S_OK) return hr;
|
|
|
|
return CITFileSystem::OpenITFileSystem(NULL, (const WCHAR *) m_awszStorageFile,
|
|
grfMode, (IStorageITEx **)&m_pStorageRoot
|
|
);
|
|
}
|
|
|
|
ILockBytes * plkbRoot = NULL;
|
|
|
|
HRESULT hr = CStrmLockBytes::OpenUrlStream((const WCHAR *) m_awszStorageFile,
|
|
&plkbRoot
|
|
);
|
|
|
|
if (hr == S_OK)
|
|
hr = CITFileSystem::OpenITFSOnLockBytes(NULL, plkbRoot, grfMode,
|
|
(IStorageITEx **)&m_pStorageRoot
|
|
);
|
|
|
|
if (plkbRoot)
|
|
plkbRoot->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
const PWCHAR apwcsDefaultPages[5] = { L"/default.htm", L"/default.html",
|
|
L"/index.htm", L"/index.html",
|
|
NULL
|
|
};
|
|
|
|
|
|
/* [local] */ HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::BindToStorage(
|
|
/* [unique][in] */ IBindCtx __RPC_FAR *pbc,
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkToLeft,
|
|
/* [in] */ REFIID riid,
|
|
/* [out] */ void __RPC_FAR *__RPC_FAR *ppvObj)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
|
|
BIND_OPTS bo;
|
|
|
|
bo.cbStruct = sizeof(bo);
|
|
|
|
hr = pbc->GetBindOptions(&bo);
|
|
|
|
// Streams and storages are always opened read-only with share deny-none
|
|
// in the context of a URL.
|
|
|
|
bo.grfMode &= ~(STGM_WRITE | STGM_READWRITE);
|
|
bo.grfMode &= ~(STGM_SHARE_DENY_NONE | STGM_SHARE_DENY_READ
|
|
| STGM_SHARE_DENY_WRITE
|
|
| STGM_SHARE_EXCLUSIVE
|
|
);
|
|
bo.grfMode |= STGM_SHARE_DENY_NONE;
|
|
|
|
if (hr != S_OK) return hr;
|
|
|
|
if (!m_pStorageRoot)
|
|
{
|
|
hr = OpenRootStorage(bo.grfMode);
|
|
|
|
if (hr != S_OK) return hr;
|
|
}
|
|
|
|
if (riid == IID_IStorage)
|
|
hr = m_pStorageRoot->OpenStorage(m_awszStoragePath, NULL, bo.grfMode,
|
|
NULL, 0, (IStorage **) ppvObj
|
|
);
|
|
else
|
|
if (riid == IID_IStream)
|
|
{
|
|
hr = m_pStorageRoot->OpenStream(m_awszStoragePath, NULL, bo.grfMode,
|
|
0, (IStream **) ppvObj
|
|
);
|
|
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
const PWCHAR *ppwcsDefPages = apwcsDefaultPages;
|
|
|
|
for (;;)
|
|
{
|
|
const PWCHAR pwcsDefPage = *ppwcsDefPages++;
|
|
|
|
if (!pwcsDefPage) break;
|
|
|
|
WCHAR awszDefault[MAX_PATH];
|
|
|
|
wcsCpy(awszDefault, m_awszStoragePath);
|
|
|
|
UINT cwc= wcsLen(m_awszStoragePath) + wcsLen(pwcsDefPage);
|
|
|
|
if (cwc < MAX_PATH)
|
|
{
|
|
wcsCat(awszDefault, pwcsDefPage);
|
|
|
|
hr = m_pStorageRoot->OpenStream(awszDefault, NULL, bo.grfMode,
|
|
0, (IStream **) ppvObj
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcsCpy(m_awszStoragePath, awszDefault);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else return E_NOINTERFACE;
|
|
|
|
#ifdef IE30Hack
|
|
// The following code is a slimey hack to work around a defect in the IE 3.0x
|
|
// URLMon code. The problem is that IE 3.0 treats the trailing part of our URL
|
|
// as if it were a file name, and that makes many things break.
|
|
//
|
|
// The code below crawls up the stack and follows several pointers to locate the
|
|
// incorrect file name and fix it to point to a file which a copy of the stream
|
|
// we've just opened.
|
|
|
|
if (SUCCEEDED(hr) && !IS_IE4()) // Running in IE 3.0x ???
|
|
{
|
|
PWCHAR pwcsDisplayName = NULL;
|
|
|
|
// We use a try/except bracket to recover from crawl failures.
|
|
|
|
__try
|
|
{
|
|
// First we compute stack frame pointers for BindToStorage
|
|
// and the next higher frame.
|
|
|
|
DWORD *pdwFrame = ((DWORD *) &pbc) - 3;
|
|
DWORD *pdwFrameNext = (DWORD *) *pdwFrame;
|
|
DWORD *pdwCINet;
|
|
|
|
// We're looking for a pointer to a CINetStream object. That pointer
|
|
// is located at different places in the retail and debug builds
|
|
// of URLMon.
|
|
|
|
if (pdwFrameNext - pdwFrame > 0x1b6)
|
|
pdwCINet = (DWORD *) pdwFrameNext[5]; // Debug build
|
|
else pdwCINet = (DWORD *) pdwFrame [8]; // Retail build
|
|
|
|
// From there we can get the pointer to the transaction object.
|
|
|
|
PBYTE pbTransData = (PBYTE) pdwCINet[0x8de];
|
|
|
|
// Then the transaction object contains the erroneous
|
|
// file paths.
|
|
|
|
PWCHAR pwcsFilePath = (PWCHAR) (pbTransData + 0xC );
|
|
PCHAR pcsFilePath = ( PCHAR) (pbTransData + 0x284);
|
|
|
|
hr = GetDisplayName(pbc, NULL, &pwcsDisplayName);
|
|
|
|
if ( SUCCEEDED(hr)
|
|
&& !wcsicmp_0x0409((const WCHAR *) pwcsDisplayName + 14, (const WCHAR *)pwcsFilePath)
|
|
)
|
|
{
|
|
#ifdef _DEBUG
|
|
HRESULT hr2 =
|
|
#endif // _DEBUG
|
|
StreamToIEFile((IStream *) *ppvObj, pwcsDisplayName, m_pcsDisplayName,
|
|
pcsFilePath, pwcsFilePath, m_acsTempFile,
|
|
(IMoniker *) this, FALSE, FALSE
|
|
);
|
|
|
|
RonM_ASSERT(SUCCEEDED(hr2));
|
|
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
}
|
|
|
|
if (pwcsDisplayName)
|
|
OLEHeap()->Free(pwcsDisplayName);
|
|
}
|
|
#endif // IE30Hack
|
|
return hr;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::Reduce(
|
|
/* [unique][in] */ IBindCtx __RPC_FAR *pbc,
|
|
/* [in] */ DWORD dwReduceHowFar,
|
|
/* [unique][out][in] */ IMoniker __RPC_FAR *__RPC_FAR *ppmkToLeft,
|
|
/* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmkReduced)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::ComposeWith(
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkRight,
|
|
/* [in] */ BOOL fOnlyIfNotGeneric,
|
|
/* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmkComposite)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::Enum(
|
|
/* [in] */ BOOL fForward,
|
|
/* [out] */ IEnumMoniker __RPC_FAR *__RPC_FAR *ppenumMoniker)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::IsEqual(
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkOtherMoniker)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::Hash(
|
|
/* [out] */ DWORD __RPC_FAR *pdwHash)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::IsRunning(
|
|
/* [unique][in] */ IBindCtx __RPC_FAR *pbc,
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkToLeft,
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkNewlyRunning)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::GetTimeOfLastChange(
|
|
/* [unique][in] */ IBindCtx __RPC_FAR *pbc,
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkToLeft,
|
|
/* [out] */ FILETIME __RPC_FAR *pFileTime)
|
|
{
|
|
STATSTG statstg;
|
|
|
|
HRESULT hr = m_pStorageRoot->Stat(&statstg, STATFLAG_NONAME);
|
|
|
|
if (!SUCCEEDED(hr))
|
|
return hr;
|
|
|
|
if (pFileTime)
|
|
*pFileTime = statstg.mtime;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::Inverse(
|
|
/* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmk)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::CommonPrefixWith(
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkOther,
|
|
/* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmkPrefix)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::RelativePathTo(
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkOther,
|
|
/* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmkRelPath)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::GetDisplayName(
|
|
/* [unique][in] */ IBindCtx __RPC_FAR *pbc,
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkToLeft,
|
|
/* [out] */ LPOLESTR __RPC_FAR *ppszDisplayName)
|
|
{
|
|
UINT cwcExternalPath = wcsLen(m_awszStorageFile);
|
|
UINT cwcInternalPath = wcsLen(m_awszStoragePath);
|
|
UINT cwcDisplayName = (IS_IE4()? 9 : 16) + cwcExternalPath + cwcInternalPath;
|
|
|
|
PWCHAR pwcsDisplayName = PWCHAR(OLEHeap()->Alloc(sizeof(WCHAR) * (cwcDisplayName + 1)));
|
|
|
|
if (!pwcsDisplayName)
|
|
return E_OUTOFMEMORY;
|
|
|
|
wcsCpy(pwcsDisplayName, IS_IE4()? L"ms-its:" :L"mk:@msitstore:");
|
|
wcsCat(pwcsDisplayName, m_awszStorageFile);
|
|
wcsCat(pwcsDisplayName, L"::");
|
|
wcsCat(pwcsDisplayName, m_awszStoragePath);
|
|
|
|
*ppszDisplayName = pwcsDisplayName;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::ParseDisplayName(
|
|
/* [unique][in] */ IBindCtx __RPC_FAR *pbc,
|
|
/* [unique][in] */ IMoniker __RPC_FAR *pmkToLeft,
|
|
/* [in] */ LPOLESTR pszDisplayName,
|
|
/* [out] */ ULONG __RPC_FAR *pchEaten,
|
|
/* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmkOut)
|
|
{
|
|
RonM_ASSERT(FALSE); // To catch unexpected uses of this interface...
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CStorageMoniker::CImpIStorageMoniker::IsSystemMoniker(
|
|
/* [out] */ DWORD __RPC_FAR *pdwMksys)
|
|
{
|
|
return MKSYS_NONE;
|
|
}
|
|
|
|
|