//+--------------------------------------------------------------------------- // // 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 #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; }