/*============================================================================ * * File Name: Tribble.cpp * * Class Tribble * * Description: Test Class tribble - does very little - and so * do tribbles. * * Author: Roger Hughes * * Date: 14/10/98 * * *==============================================================================*/ #include "stdafx.h" #include "dllmain.h" // for Lock/Unlock module #include "Tribble.h" #include "OleCharConv.h" CString ResolveIIDName(REFIID riid); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// Tribble::Tribble() : m_cRef(0), m_ClsId(CLSID_Tribble), m_dwROTFile(0L), m_pmkFile(NULL), m_dwROTCmp(0L), m_pmkCmp(NULL) { } Tribble::~Tribble() { IRunningObjectTable *pROT; HRESULT hr= GetRunningObjectTable(0,&pROT); if (SUCCEEDED(hr)) { // Clear ourselves from the ROT if (m_dwROTFile) pROT->Revoke(m_dwROTFile); if (m_dwROTCmp) pROT->Revoke(m_dwROTCmp); pROT->Release(); } // Free these Monikers if(m_pmkFile) m_pmkFile->Release(); if(m_pmkCmp) m_pmkCmp->Release(); } //=== Tribble Implementation ========================================= //--------------------------------------------------------------------------- // Method: Tribble::Sleep // Purpose: Tribble is asleep //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Tribble::Sleep(void) { return S_OK; } // Tribble::Sleep //--------------------------------------------------------------------------- // Method: Tribble::Wake // Purpose: Tribble wakes up //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Tribble::Wake(void) { return S_OK; } // Tribble::Wake //--------------------------------------------------------------------------- // Method: Tribble::Eat // Purpose: Tribble Eats!!! //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Tribble::Eat(/* [in] */ const unsigned char * strMyFood) { if(strMyFood) m_strFood = strMyFood; else m_strFood = ""; return S_OK; } // Tribble::Eat //=== IUnknown Implementation =============================================== //--------------------------------------------------------------------------- // Method: Tribble::Release // Purpose: Dec the Ref count and release //--------------------------------------------------------------------------- ULONG Tribble::Release() { OutputDebugString("Tribble::Release\n"); ::InterlockedDecrement(&m_cRef); if(m_cRef == 0) { delete this; UnlockModule(); } return(m_cRef); } // Tribble::Release //--------------------------------------------------------------------------- // Method: Tribble::AddRef // Purpose: Increment the reference count //--------------------------------------------------------------------------- ULONG Tribble::AddRef() { OutputDebugString("Tribble::AddRef\n"); ::InterlockedIncrement(&m_cRef); if(m_cRef == 1) // the first call LockModule(); return(m_cRef); } // Tribble::AddRef //--------------------------------------------------------------------------- // Method: Tribble::QueryInterface // Purpose: QI //--------------------------------------------------------------------------- HRESULT Tribble::QueryInterface(REFIID riid, void ** pObj) { // this is the standard implementation of QI // better ones exist - so try one! HRESULT hr = S_OK; CString strInterface = ResolveIIDName(riid); CString strOut; if((riid == IID_IUnknown) || (IID_ITribble == riid)) *pObj = static_cast (this); else if (IID_IPersistFile == riid) *pObj = static_cast (this); else if (IID_IOleItemContainer == riid) *pObj = static_cast (this); else if (IID_IParseDisplayName == riid) *pObj = static_cast (this); else { // we've been asked for something we don't support // so find out what it is strOut.Format("Tribble::QueryInterface() - Unsupported IID: %s\n",strInterface); OutputDebugString(strOut); hr = E_NOINTERFACE; *pObj = 0; } // note the double check here!!! if(hr == S_OK) { strOut.Format("Tribble::QueryInterface() - IID: %s\n",strInterface); OutputDebugString(strOut); ((IUnknown *) (*pObj))->AddRef (); } return(hr); } // Tribble::QueryInterface //--------------------------------------------------------------------------- // Method: Tribble::put_Name // Purpose: Sets the Tribbles name //--------------------------------------------------------------------------- HRESULT Tribble::put_Name(const unsigned char * lpName) { HRESULT hr = S_OK; m_Name = lpName; return hr; } // Tribble::put_Name //--------------------------------------------------------------------------- // Method: Tribble::put_Colour // Purpose: Sets the tribbles colour //--------------------------------------------------------------------------- HRESULT Tribble::put_Colour(const unsigned char * lpColour) { HRESULT hr = S_OK; m_Colour = lpColour; return hr; } // Tribble::put_Colour //--------------------------------------------------------------------------- // Method: Tribble::put_Name // Purpose: Gets the Tribbles name //--------------------------------------------------------------------------- HRESULT Tribble::get_Name(unsigned char * lpName) { HRESULT hr = S_OK; lstrcpy((char *)lpName,(LPCSTR)m_Name); return hr; } // Tribble::get_Name //--------------------------------------------------------------------------- // Method: Tribble::get_Colour // Purpose: Gets the tribbles colour //--------------------------------------------------------------------------- HRESULT Tribble::get_Colour(unsigned char * lpColour) { HRESULT hr = S_OK; strcpy((char *)lpColour,(LPCSTR)m_Colour); return hr; } // Tribble::get_Colour //--------------------------------------------------------------------------- // Method: ResolveIIDName - Helper // Purpose: Is someone asking for an unsupported interface? // If so, find out what it is. //--------------------------------------------------------------------------- CString ResolveIIDName(REFIID riid) { CString strIIDName = ""; LPOLESTR pOleStr; HRESULT hr = StringFromCLSID(riid, //CLSID to be converted &pOleStr); //Address of output variable that receives a // pointer to the resulting string); if(SUCCEEDED(hr)) { // we now have the IDD as a char * string COleCharConv ch(pOleStr); CString strIID = "Interface\\"; strIID += (LPCSTR)ch; HKEY hKey = NULL; if(::RegOpenKey(HKEY_CLASSES_ROOT,strIID,&hKey) == ERROR_SUCCESS) { DWORD nCountBytes; // the size of the data DWORD dwType; // first get the size of the entry if(::RegQueryValueEx(hKey,"",NULL,&dwType,(LPBYTE)NULL,&nCountBytes) == ERROR_SUCCESS) { try { LPSTR ptr = (LPSTR)strIIDName.GetBufferSetLength((int)(nCountBytes+20)); // having enough memory - now get the file name if(::RegQueryValueEx(hKey,"",NULL,&dwType,(LPBYTE)ptr,&nCountBytes) != ERROR_SUCCESS) { *ptr = '\0'; } strIIDName.ReleaseBuffer(); } catch(...) // who cares here - I don't... { } } ::RegCloseKey(hKey); } } return strIIDName; } /*============================================================================ * End of File: Tribble.cpp ==============================================================================*/