// ComponentHolder.cpp: implementation of the CComponentHolder class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ComponentHolder.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CComponentHolder::CComponentHolder() { // Both pointers are null for an uninited object m_pComponentDOS = NULL; m_pComponentWin = NULL; } CComponentHolder::~CComponentHolder() { // Just in case owner forgot Release(); } ////////////////////////////////////////////////////////////////// // Returns the component type (DOS or Windows) UINT CComponentHolder::GetType() { // Needs to be Initialzed ASSERT(!(m_pComponentDOS == NULL && m_pComponentWin == NULL)); // Return Type if(m_pComponentWin != NULL) return COMPONENT_WIN; else return COMPONENT_DOS; } ////////////////////////////////////////////////////////////////// // Returns a IUnknown to the current component IUnknown* CComponentHolder::GetUnknown() { // Needs to be Initialzed ASSERT(!(m_pComponentDOS == NULL && m_pComponentWin == NULL)); // When copying out a Pointer make sure to AddRef if(m_pComponentWin != NULL) { m_pComponentWin->AddRef(); return m_pComponentWin; } else { m_pComponentDOS->AddRef(); return m_pComponentDOS; } } ////////////////////////////////////////////////////////////////// // Accepts a String ID, converts it and then calls the real // Initialize HRESULT CComponentHolder::Initialize(const string& sID, const string& sRegKey) { ASSERT(!sRegKey.empty()); USES_CONVERSION; HRESULT hr; CLSID clsid; // Get the CLSID hr = CLSIDFromString(T2OLE(sID), &clsid); if(FAILED(hr)) return hr; // And then call the real version return Initialize(clsid, sRegKey); } ////////////////////////////////////////////////////////////////// // Loads and Initializes the Component HRESULT CComponentHolder::Initialize(const CLSID & clsid, const string& sRegKey) { ASSERT(!sRegKey.empty()); USES_CONVERSION; // If we're already Initialized then Release all the // and start again interfaces if(IsInitialized()) Release(); // Intitialize the Data Component m_Data.Initialize(sRegKey); // Get an IUnknown to the Component First // Since we don't know what it supports // (CComPtr) calls Release for this one HRESULT hr; CComPtr pUnk; hr = CoCreateInstance(clsid, NULL, /*CLSCTX_ALL*/CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER , IID_IUnknown, (void**) &pUnk); if(FAILED(hr)) return hr; // Check if it Supports IID_ISecureShutdownWin hr = pUnk->QueryInterface(IID_ISecureShutdownWin, (void**) &m_pComponentWin); if(FAILED(hr)) m_pComponentWin = NULL; // Check if it Supports IID_ISecureShutdownDOS hr = pUnk->QueryInterface(IID_ISecureShutdownDOS, (void**) &m_pComponentDOS); if(FAILED(hr)) m_pComponentDOS = NULL; // Did we catch something? if(!IsInitialized()) return hr; switch(GetType()) { case COMPONENT_WIN: // Give the Component it's Data Pointer hr = m_pComponentWin->SetData(m_Data.GetUnknown()); if(FAILED(hr)) return hr; break; case COMPONENT_DOS: // Give the Component it's Data Pointer hr = m_pComponentDOS->SetData(m_Data.GetUnknown()); if(FAILED(hr)) return hr; break; } // Get Name m_sName = GetInfoStr(nsName, _T("(No Name)")); return S_OK; } ////////////////////////////////////////////////////////////////// // Helper Function bool CComponentHolder::IsInitialized() { // Either one has to be initialized return !((m_pComponentDOS == NULL) && (m_pComponentWin == NULL)); } /*#ifndef NS_NO_PROPPAGE ////////////////////////////////////////////////////////////////// // Returns a pointer to the Property page for current component // or error if none HRESULT CComponentHolder::GetPropPage(CPropPageHolder** pPropPage) { // If we already have a Prop Page then just get pointer if(m_PropPage.IsInitialized()) { *pPropPage = &m_PropPage; return S_OK; } // Otherwise Create one HRESULT hr; // Get a IUnkown to the current Component CComPtr pUnk; // Releases Pointer GetIUnknown(&pUnk); // See if it likes us hr = m_PropPage.Initialize(pUnk); if(FAILED(hr)) return hr; // Return Pointer *pPropPage = &m_PropPage; return S_OK; } bool CComponentHolder::HasPropPage() { CPropPageHolder* pPropPage; return SUCCEEDED(GetPropPage(&pPropPage)); } #endif // NS_NO_PROPPAGE */ ////////////////////////////////////////////////////////////////// // Completely removes the component from Memory HRESULT CComponentHolder::Release() { /* // Check if we've got PropPage // If so then get rid of it if(m_PropPage.IsInitialized()) m_PropPage.Destroy(); */ // Save the Data to the DataObject // m_Data.Save(); // Only Update if Initialized if(IsInitialized()){ switch(GetType()){ case COMPONENT_WIN: // Get Component to Release Data Pointer m_pComponentWin->SetData(NULL); // Release Component m_pComponentWin->Release(); break; case COMPONENT_DOS: // Get Component to Release Data Pointer m_pComponentDOS->SetData(NULL); // Release Component m_pComponentDOS->Release(); break; } // Set to NULL as a flag m_pComponentWin = NULL; m_pComponentDOS = NULL; m_sName = _T(""); } return S_OK; } ////////////////////////////////////////////////////////////////// // Invokes actual shutdown (Windows Components Only) HRESULT CComponentHolder::DoShutdown(DWORD dwMode, HWND hwndParent) { // Needs to be Initialized First ASSERT(!(m_pComponentDOS == NULL && m_pComponentWin == NULL)); switch(GetType()){ case COMPONENT_WIN: // Call Shutdown. Only Windows return m_pComponentWin->DoShutdown((long)hwndParent, (long)dwMode); break; case COMPONENT_DOS: // Call Shutdown. DOS don't support ASSERT(false); return E_FAIL; break; } return E_FAIL; } ////////////////////////////////////////////////////////////////// // Retrieves Text for Batch File (DOS Components Only) HRESULT CComponentHolder::GetBatchText(string& sBatchText) { USES_CONVERSION; BSTR bstrBatchText; HRESULT hr; switch(GetType()) { case COMPONENT_WIN: // Not Supported in Windows return E_FAIL; break; case COMPONENT_DOS: // Get Batch Text. hr = m_pComponentDOS->GetBatchText(&bstrBatchText); // Transfer to CString if(SUCCEEDED(hr)) sBatchText = OLE2T(bstrBatchText); return hr; break; } return E_FAIL; } CComVariant CComponentHolder::GetInfo(NightSecInfo nsItem) { USES_CONVERSION; CComVariant vInfo; vInfo.vt = VT_EMPTY; HRESULT hr; switch(GetType()){ case COMPONENT_WIN: hr = m_pComponentWin->get_Info(nsItem, &vInfo); break; case COMPONENT_DOS: hr = m_pComponentDOS->get_Info(nsItem, &vInfo); break; } if(FAILED(hr)) vInfo.vt = VT_NULL; return vInfo; } string CComponentHolder::GetInfoStr(NightSecInfo nsItem, const string& sDefault) { USES_CONVERSION; // Get Name CComVariant vInfo = GetInfo(nsItem); if(vInfo.vt == VT_BSTR) return OLE2T(vInfo.bstrVal); return sDefault; } int CComponentHolder::GetInfoInt(NightSecInfo nsItem, int nDefault) { // Get Name CComVariant vInfo = GetInfo(nsItem); if(vInfo.vt == VT_NULL || vInfo.vt == VT_EMPTY) return nDefault; if(SUCCEEDED(vInfo.ChangeType(VT_I4))) return vInfo.lVal; return nDefault; }