Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1336 lines
34 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996.
//
// File: classmon.cxx
//
// Contents: Implementation of CClassMoniker
//
// Classes: CClassMoniker
//
// Functions: CreateClassMoniker
//
// History: 22-Feb-96 ShannonC Created
//
//----------------------------------------------------------------------------
#include <ole2int.h>
#include "classmon.hxx"
#include "mnk.h"
#ifndef OLETRACEIN
#define OLETRACEIN(x)
#endif
#ifndef OLETRACEOUT
#define OLETRACEOUT(x)
#endif
//+---------------------------------------------------------------------------
//
// Function: CreateClassMoniker
//
// Synopsis: Creates a class moniker for the specified CLSID.
//
// Arguments: [rclsid] - Supplies the CLSID of the class.
// [ppmk] - Returns interface pointer of the new moniker.
//
// Returns: S_OK
// E_INVALIDARG
// E_OUTOFMEMORY
//
//----------------------------------------------------------------------------
STDAPI CreateClassMoniker(
REFCLSID rclsid,
IMoniker **ppmk)
{
HRESULT hr;
CLSID clsid;
IMoniker *pmk;
__try
{
OLETRACEIN((API_CreateClassMoniker,
PARAMFMT("rclsid= %I, ppmk= %p"),
&rclsid, ppmk));
//Validate parameters.
*ppmk = NULL;
clsid = rclsid;
pmk = new CClassMoniker(clsid);
if (pmk != NULL)
{
*ppmk = pmk;
hr = S_OK;
CALLHOOKOBJECTCREATE(hr,
CLSID_ClassMoniker,
IID_IMoniker,
(IUnknown **)ppmk);
}
else
{
hr = E_OUTOFMEMORY;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
OLETRACEOUT((API_CreateFileMoniker, hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::CClassMoniker
//
// Synopsis: Constructor for class moniker.
//
// Arguments: rclsid - Supplies the CLSID of the class.
//
//----------------------------------------------------------------------------
CClassMoniker::CClassMoniker(REFCLSID rclsid)
: _cRefs(1), _pExtra(NULL)
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::CClassMoniker(%x,%I)\n",
this, &rclsid));
_data.clsid = rclsid;
_data.cbExtra = 0;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::~CClassMoniker
//
// Synopsis: Constructor for class moniker.
//
// Arguments: rclsid - Supplies the CLSID of the class.
//
//----------------------------------------------------------------------------
CClassMoniker::~CClassMoniker()
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::~CClassMoniker(%x)\n",
this));
if(_pExtra != NULL)
{
PrivMemFree(_pExtra);
}
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::SetParameters
//
// Synopsis: Set the parameters on the class moniker
//
// Arguments: pszName - Name of the parameter.
// pszValue - Value of the parameter.
//
//----------------------------------------------------------------------------
HRESULT CClassMoniker::SetParameters(
LPCWSTR pszParameters)
{
HRESULT hr = S_OK;
//Free the old data.
if(_pExtra != NULL)
{
PrivMemFree(_pExtra);
_pExtra = NULL;
}
if(pszParameters != NULL)
{
_data.cbExtra = lstrlenW(pszParameters) * sizeof(WCHAR) + sizeof(WCHAR);
//Allocate memory for the extra bytes.
_pExtra = PrivMemAlloc(_data.cbExtra);
if(_pExtra != 0)
{
memcpy(_pExtra, pszParameters, _data.cbExtra);
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::QueryInterface
//
// Synopsis: Gets a pointer to the specified interface. The class
// moniker supports the IMarshal, IMoniker, IPersistStream,
// IPersist, IROTData, and IUnknown interfaces. The class
// moniker also supports CLSID_ClassMoniker so that the
// IsEqual method can directly access the data members.
//
// Arguments: [iid] -- the requested interface
// [ppv] -- where to put the interface pointer
//
// Returns: S_OK
// E_INVALIDARG
// E_NOINTERFACE
//
// Notes: Bad parameters will raise an exception. The exception
// handler catches exceptions and returns E_INVALIDARG.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::QueryInterface(
REFIID riid,
void **ppv)
{
HRESULT hr;
__try
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::QueryInterface(%x,%I,%x)\n",
this, &riid, ppv));
//Parameter validation.
*ppv = NULL;
if (IsEqualIID(riid, IID_IMarshal))
{
AddRef();
*ppv = (IMarshal *) this;
hr = S_OK;
}
else if (IsEqualIID(riid, IID_IUnknown)
|| IsEqualIID(riid, IID_IMoniker)
|| IsEqualIID(riid, IID_IPersistStream)
|| IsEqualIID(riid, IID_IPersist))
{
AddRef();
*ppv = (IMoniker *) this;
hr = S_OK;
}
else if (IsEqualIID(riid, IID_IROTData))
{
AddRef();
*ppv = (IROTData *) this;
hr = S_OK;
}
else if (IsEqualIID(riid, CLSID_ClassMoniker))
{
AddRef();
*ppv = (CClassMoniker *) this;
hr = S_OK;
}
else
{
hr = E_NOINTERFACE;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::AddRef
//
// Synopsis: Increment the reference count.
//
// Arguments: void
//
// Returns: ULONG -- the new reference count
//
// Notes: Use InterlockedIncrement to make it multi-thread safe.
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CClassMoniker::AddRef(void)
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::AddRef(%x)\n",
this));
InterlockedIncrement(&_cRefs);
return _cRefs;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::Release
//
// Synopsis: Decrement the reference count.
//
// Arguments: void
//
// Returns: ULONG -- the remaining reference count
//
// Notes: Use InterlockedDecrement to make it multi-thread safe.
// We use a local variable so that we don't access
// a data member after decrementing the reference count.
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CClassMoniker::Release(void)
{
ULONG count = _cRefs - 1;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::Release(%x)\n",
this));
if(0 == InterlockedDecrement(&_cRefs))
{
delete this;
count = 0;
}
return count;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::GetClassID
//
// Synopsis: Gets the class ID of the object.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::GetClassID(
CLSID *pClassID)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::GetClassID(%x,%x)\n",
this, pClassID));
__try
{
*pClassID = CLSID_ClassMoniker;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::IsDirty
//
// Synopsis: Checks the object for changes since it was last saved.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::IsDirty()
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::IsDirty(%x)\n",
this));
return S_FALSE;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::Load
//
// Synopsis: Loads a class moniker from a stream
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::Load(
IStream *pStream)
{
HRESULT hr;
ULONG cbRead;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::Load(%x,%x)\n",
this, pStream));
__try
{
hr = pStream->Read(&_data, sizeof(_data), &cbRead);
if(SUCCEEDED(hr))
{
if(sizeof(_data) == cbRead)
{
if(_data.cbExtra != 0)
{
//Free the old buffer if necessary.
if(_pExtra != NULL)
{
PrivMemFree(_pExtra);
}
//Allocate buffer and read the extra bytes.
_pExtra = PrivMemAlloc(_data.cbExtra);
if(_pExtra != NULL)
{
hr = pStream->Read(_pExtra,
_data.cbExtra,
&cbRead);
if(SUCCEEDED(hr))
{
if(cbRead == _data.cbExtra)
hr = S_OK;
else
hr = STG_E_READFAULT;
}
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
hr = S_OK;
}
}
else
{
hr = STG_E_READFAULT;
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::Save
//
// Synopsis: Save the class moniker to a stream
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::Save(
IStream *pStream,
BOOL fClearDirty)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::Save(%x,%x,%x)\n",
this, pStream, fClearDirty));
__try
{
hr = pStream->Write(&_data, sizeof(_data), NULL);
if(SUCCEEDED(hr) && _pExtra != NULL && _data.cbExtra > 0)
{
//Write the extra bytes.
hr = pStream->Write(_pExtra, _data.cbExtra, NULL);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::GetSizeMax
//
// Synopsis: Get the maximum size required to serialize this moniker
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::GetSizeMax(
ULARGE_INTEGER * pcbSize)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::GetSizeMax(%x,%x)\n",
this, pcbSize));
__try
{
ULISet32(*pcbSize, sizeof(_data) + _data.cbExtra);
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::BindToObject
//
// Synopsis: Bind to the object named by this moniker.
//
// Notes: If pmkToLeft is zero, then the class moniker calls
// CoGetClassObject to get an interface pointer to the class object.
//
// If pmkToLeft is non-zero, then the class moniker binds to the
// IClassActivator interface and then calls
// IClassActivator::GetClassObject.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::BindToObject (
IBindCtx *pbc,
IMoniker *pmkToLeft,
REFIID iidResult,
void ** ppvResult)
{
HRESULT hr;
IID iid;
BIND_OPTS2 bindOpts;
__try
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::BindToObject(%x,%x,%x,%I,%x)\n",
this, pbc, pmkToLeft, &iidResult, ppvResult));
//Validate parameters
*ppvResult = NULL;
iid = iidResult;
bindOpts.cbStruct = sizeof(bindOpts);
hr = pbc->GetBindOptions(&bindOpts);
if(SUCCEEDED(hr))
{
//Get the class object.
if(NULL == pmkToLeft)
{
//Call the internal CoGetClassObject.
hr = ICoGetClassObject(_data.clsid,
bindOpts.dwClassContext,
NULL,
iid,
ppvResult);
}
else
{
IClassActivator *pActivate;
hr = pmkToLeft->BindToObject(pbc,
NULL,
IID_IClassActivator,
(void **) &pActivate);
if(SUCCEEDED(hr))
{
hr = pActivate->GetClassObject(_data.clsid,
bindOpts.dwClassContext,
bindOpts.locale,
iid,
ppvResult);
pActivate->Release();
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::BindToStorage
//
// Synopsis: Bind to the storage for the object named by the moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::BindToStorage(
IBindCtx *pbc,
IMoniker *pmkToLeft,
REFIID riid,
void ** ppv)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::BindToStorage(%x,%x,%x,%I,%x)\n",
this, pbc, pmkToLeft, &riid, ppv));
hr = BindToObject(pbc, pmkToLeft, riid, ppv);
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::Reduce
//
// Synopsis: Reduce the moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::Reduce(
IBindCtx * pbc,
DWORD dwReduceHowFar,
IMoniker ** ppmkToLeft,
IMoniker ** ppmkReduced)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::Reduce(%x,%x,%x,%x,%x)\n",
this, pbc, dwReduceHowFar, ppmkToLeft, ppmkReduced));
__try
{
//Validate parameters.
*ppmkReduced = NULL;
AddRef();
*ppmkReduced = (IMoniker *) this;
hr = MK_S_REDUCED_TO_SELF;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::ComposeWith
//
// Synopsis: Compose another moniker onto the end of this moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::ComposeWith(
IMoniker * pmkRight,
BOOL fOnlyIfNotGeneric,
IMoniker **ppmkComposite)
{
HRESULT hr;
IMoniker *pmk;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::ComposeWith(%x,%x,%x,%x)\n",
this, pmkRight, fOnlyIfNotGeneric, ppmkComposite));
__try
{
//Validate parameters.
*ppmkComposite = NULL;
//Check for an anti-moniker
hr = pmkRight->QueryInterface(CLSID_AntiMoniker, (void **)&pmk);
if(FAILED(hr))
{
//pmkRight is not an anti-moniker.
if (!fOnlyIfNotGeneric)
{
hr = CreateGenericComposite(this, pmkRight, ppmkComposite);
}
else
{
hr = MK_E_NEEDGENERIC;
}
}
else
{
//pmkRight is an anti-moniker.
pmk->Release();
hr = S_OK;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::Enum
//
// Synopsis: Enumerate the components of this moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::Enum(
BOOL fForward,
IEnumMoniker ** ppenumMoniker)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::Enum(%x,%x,%x)\n",
this, fForward, ppenumMoniker));
__try
{
*ppenumMoniker = NULL;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::IsEqual
//
// Synopsis: Compares with another moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::IsEqual(
IMoniker *pmkOther)
{
HRESULT hr;
CClassMoniker *pClassMoniker;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::IsEqual(%x,%x)\n",
this, pmkOther));
__try
{
hr = pmkOther->QueryInterface(CLSID_ClassMoniker,
(void **) &pClassMoniker);
if(SUCCEEDED(hr))
{
if(IsEqualCLSID(_data.clsid,
pClassMoniker->_data.clsid))
{
hr = S_OK;
}
else
{
hr = S_FALSE;
}
pClassMoniker->Release();
}
else
{
hr = S_FALSE;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::Hash
//
// Synopsis: Compute a hash value
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::Hash(
DWORD * pdwHash)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::Hash(%x,%x)\n",
this, pdwHash));
__try
{
*pdwHash = _data.clsid.Data1;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::IsRunning
//
// Synopsis: Determines if the object identified by this moniker is
// running. Since we can't search the class table to determine
// if the object is running, we just return E_NOTIMPL.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::IsRunning(
IBindCtx * pbc,
IMoniker * pmkToLeft,
IMoniker * pmkNewlyRunning)
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::IsRunning(%x,%x,%x,%x)\n",
this, pbc, pmkToLeft, pmkNewlyRunning));
return E_NOTIMPL;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::GetTimeOfLastChange
//
// Synopsis: Returns the time when the object identified by this moniker
// was changed.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::GetTimeOfLastChange (
IBindCtx * pbc,
IMoniker * pmkToLeft,
FILETIME * pFileTime)
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::GetTimeOfLastChange(%x,%x,%x,%x)\n",
this, pbc, pmkToLeft, pFileTime));
return MK_E_UNAVAILABLE;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::Inverse
//
// Synopsis: Returns the inverse of this moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::Inverse(
IMoniker ** ppmk)
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::Inverse(%x,%x)\n",
this, ppmk));
return CreateAntiMoniker(ppmk);
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::CommonPrefixWith
//
// Synopsis: Returns the common prefix shared by this moniker and the
// other moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::CommonPrefixWith(
IMoniker * pmkOther,
IMoniker ** ppmkPrefix)
{
HRESULT hr;
CClassMoniker *pClassMoniker;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::CommonPrefixWith(%x,%x,%x)\n",
this, pmkOther, ppmkPrefix));
__try
{
//Validate parameters.
*ppmkPrefix = NULL;
hr = pmkOther->QueryInterface(CLSID_ClassMoniker,
(void **) &pClassMoniker);
if(SUCCEEDED(hr))
{
if(IsEqualCLSID(_data.clsid,
pClassMoniker->_data.clsid))
{
AddRef();
*ppmkPrefix = (IMoniker *) this;
hr = MK_S_US;
}
else
{
hr = MK_E_NOPREFIX;
}
pClassMoniker->Release();
}
else
{
hr = MonikerCommonPrefixWith(this, pmkOther, ppmkPrefix);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::RelativePathTo
//
// Synopsis: Returns the relative path between this moniker and the
// other moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::RelativePathTo(
IMoniker * pmkOther,
IMoniker ** ppmkRelPath)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::RelativePathTo(%x,%x,%x)\n",
this, pmkOther, ppmkRelPath));
__try
{
*ppmkRelPath = NULL;
hr = MonikerRelativePathTo(this, pmkOther, ppmkRelPath, TRUE);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::GetDisplayName
//
// Synopsis: Get the display name of this moniker.
//
// Notes: Call ProgIDFromClassID to get the ProgID
// Append a ':' to the end of the string.
// If no ProgID is available, then use
// clsid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx;parameters:
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::GetDisplayName(
IBindCtx * pbc,
IMoniker * pmkToLeft,
LPWSTR * lplpszDisplayName)
{
HRESULT hr = E_FAIL;
LPWSTR pszDisplayName;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::GetDisplayName(%x,%x,%x,%x)\n",
this, pbc, pmkToLeft, lplpszDisplayName));
__try
{
LPWSTR pszPrefix;
WCHAR szClassID[37];
LPWSTR pszParameters = (LPWSTR) _pExtra;
//Validate parameters.
*lplpszDisplayName = NULL;
//Create a display name from the class ID.
//Get the class ID string.
wStringFromUUID(_data.clsid, szClassID);
//Get the prefix
hr = ProgIDFromCLSID(CLSID_ClassMoniker,
&pszPrefix);
if(SUCCEEDED(hr))
{
ULONG cName;
cName = lstrlenW(pszPrefix) + 1 + lstrlenW(szClassID);
if(pszParameters != NULL)
{
cName += lstrlenW(pszParameters);
}
cName += 2;
pszDisplayName = (LPWSTR) CoTaskMemAlloc(cName * sizeof(wchar_t));
if(pszDisplayName != NULL)
{
lstrcpyW(pszDisplayName, pszPrefix);
lstrcatW(pszDisplayName, L":");
lstrcatW(pszDisplayName, szClassID);
if(pszParameters != NULL)
{
lstrcatW(pszDisplayName, pszParameters);
}
lstrcatW(pszDisplayName, L":");
*lplpszDisplayName = pszDisplayName;
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
}
CoTaskMemFree(pszPrefix);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::ParseDisplayName
//
// Synopsis: Parse the display name.
//
// Algorithm: Call BindToObject to get an IParseDisplayName on the class
// object. Call IParseDisplayName::ParseDisplayName on the
// class object.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::ParseDisplayName (
IBindCtx * pbc,
IMoniker * pmkToLeft,
LPWSTR lpszDisplayName,
ULONG * pchEaten,
IMoniker ** ppmkOut)
{
HRESULT hr;
IParseDisplayName *pPDN;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::ParseDisplayName(%x,%x,%x,%ws,%x,%x)\n",
this, pbc, pmkToLeft, lpszDisplayName, pchEaten, ppmkOut));
__try
{
//Validate parameters
*ppmkOut = NULL;
*pchEaten = 0;
hr = BindToObject(pbc,
pmkToLeft,
IID_IParseDisplayName,
(void **) &pPDN);
if(SUCCEEDED(hr))
{
//Register the object with the bind context.
hr = pbc->RegisterObjectBound(pPDN);
if(SUCCEEDED(hr))
{
//Parse the display name.
hr = pPDN->ParseDisplayName(pbc,
lpszDisplayName,
pchEaten,
ppmkOut);
}
pPDN->Release();
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::IsSystemMoniker
//
// Synopsis: Determines if this is one of the system supplied monikers.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::IsSystemMoniker(
DWORD * pdwType)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::IsSystemMoniker(%x,%x)\n",
this, pdwType));
__try
{
*pdwType = MKSYS_CLASSMONIKER;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::GetComparisonData
//
// Synopsis: Get comparison data for registration in the ROT
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::GetComparisonData(
byte * pbData,
ULONG cbMax,
DWORD *pcbData)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::GetComparisonData(%x,%x,%x,%x)\n",
this, pbData, cbMax, pcbData));
__try
{
*pcbData = 0;
if(cbMax >= sizeof(CLSID_ClassMoniker) + sizeof(_data.clsid))
{
memcpy(pbData, &CLSID_ClassMoniker, sizeof(CLSID_ClassMoniker));
pbData += sizeof(CLSID);
memcpy(pbData, &_data.clsid, sizeof(_data.clsid));
*pcbData = sizeof(CLSID_ClassMoniker) + sizeof(_data.clsid);
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::GetUnmarshalClass
//
// Synopsis: Get the class ID.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::GetUnmarshalClass(
REFIID riid,
LPVOID pv,
DWORD dwDestContext,
LPVOID pvDestContext,
DWORD mshlflags,
CLSID * pClassID)
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::GetUnmarshalClass(%x,%I,%x,%x,%x,%x,%x)\n",
this, &riid, pv, dwDestContext, pvDestContext, mshlflags,
pClassID));
return GetClassID(pClassID);
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::GetMarshalSizeMax
//
// Synopsis: Get maximum size of marshalled moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::GetMarshalSizeMax(
REFIID riid,
LPVOID pv,
DWORD dwDestContext,
LPVOID pvDestContext,
DWORD mshlflags,
DWORD *pSize)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::GetMarshalSizeMax(%x,%I,%x,%x,%x,%x,%x)\n",
this, &riid, pv, dwDestContext, pvDestContext, mshlflags,
pSize));
__try
{
*pSize = sizeof(_data) + _data.cbExtra;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::MarshalInterface
//
// Synopsis: Marshal moniker into a stream.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::MarshalInterface(
IStream * pStream,
REFIID riid,
void * pv,
DWORD dwDestContext,
LPVOID pvDestContext,
DWORD mshlflags)
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::MarshalInterface(%x,%x,%I,%x,%x,%x,%x)\n",
this, pStream, &riid, pv, dwDestContext, pvDestContext,
mshlflags));
return Save(pStream, FALSE);
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::UnmarshalInterface
//
// Synopsis: Unmarshal moniker from a stream.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::UnmarshalInterface(
IStream * pStream,
REFIID riid,
void ** ppv)
{
HRESULT hr;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::UnmarshalInterface(%x,%x,%I,%x)\n",
this, pStream, &riid, ppv));
__try
{
//Validate parameters.
*ppv = NULL;
hr = Load(pStream);
if(SUCCEEDED(hr))
{
hr = QueryInterface(riid, ppv);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = E_INVALIDARG;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::ReleaseMarshalData
//
// Synopsis: Release a marshalled class moniker.
// Just seek to the end of the marshalled class moniker.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::ReleaseMarshalData(
IStream * pStream)
{
HRESULT hr;
LARGE_INTEGER liSize;
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::ReleaseMarshalData(%x,%x)\n",
this, pStream));
hr = GetSizeMax((ULARGE_INTEGER *) &liSize);
if(SUCCEEDED(hr))
{
hr = pStream->Seek(liSize, STREAM_SEEK_CUR, NULL);
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CClassMoniker::DisconnectObject
//
// Synopsis: Disconnect the object.
//
//----------------------------------------------------------------------------
STDMETHODIMP CClassMoniker::DisconnectObject(
DWORD dwReserved)
{
mnkDebugOut((DEB_ITRACE,
"CClassMoniker::DisconnectObject(%x,%x)\n",
this, dwReserved));
return S_OK;
}