// ComponentArray.cpp: implementation of the CComponentArray class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ComponentArray.h" #include "defines.h" #include using std::find; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CComponentArray::CComponentArray() { } CComponentArray::~CComponentArray() { UnloadComponents(); } ////////////////////////////////////////////////////////////////// // LoadComponents from Registry (Public Function) // // returns number of components. UINT CComponentArray::LoadComponents() { // Can only load if empty ASSERT(empty()); // Make sure List of Installed Components is Loaded LoadInstalledComponents(); // Open Key CRegKey regKey; if(regKey.Create(HKEY_CURRENT_USER, NS_REG_COMPONENTS) != ERROR_SUCCESS) return 0; // Enumerate Subkeys which should contain Component ID's (GetIDFromKey) DWORD dwCnt = 0; DWORD dwLoadedCnt = 0; string sKeyName; while(!RegEnumKey(regKey.m_hKey, dwCnt, sKeyName.get_buffer(MAX_PATH), MAX_PATH)) { sKeyName.release_buffer(); dwCnt++; // Add the Component if(SUCCEEDED(AddComponent(sKeyName))) dwLoadedCnt++; // Increment Return Value } // Check if there's anymore that are Installed // But the user didn't have previously loaded (CheckOffInstalledComponent) while(!m_asInstalledComponents.empty()) { // Add the Component if(SUCCEEDED(AddComponent(m_asInstalledComponents[0]))) dwLoadedCnt++; } // Remove All NULL Spaces in array as we put each component // at location requested by registry iterator iter = begin(); for(int nCnt = 0; nCnt < size(); nCnt++) { while((*this)[nCnt] == NULL) erase(begin() + nCnt); } if(empty()) return 0; // Move DOS Components to End of Array CComponentHolder* pComponent = NULL; CComponentHolder* pLastComp = at(size() - 1); for(nCnt = 0; nCnt < size() && pComponent != pLastComp; nCnt++) { pComponent = at(nCnt); if(pComponent->GetType() == COMPONENT_DOS) { erase(begin() + nCnt); push_back(pComponent); } } // Return Number of Components return (UINT)dwLoadedCnt; } ////////////////////////////////////////////////////////////////// // Loads the component into memory and adds it to array at // location requested. HRESULT CComponentArray::AddComponent(const string& sKeyName) { CComponentHolder* pComponent; HRESULT hr; // Get the Component ID from a Registry KeyName // eg: 'NightSecurity.ClearInetCache' would come from 'NightSecurity.ClearInetCache 2' string sID = GetIDFromKey(sKeyName); // Load and Initialize Component pComponent = new CComponentHolder; hr = pComponent->Initialize(sID, NS_REG_COMPONENTS + (_T("\\") + sKeyName)); // If Failed then return NULL if(SUCCEEDED(hr)) { // Get the Component's Position int nPos = pComponent->GetPos(); // Add at nPos // If nPos is already used insert before if(nPos < size()) { if(at(nPos) == NULL) at(nPos) = pComponent; else insert(begin() + nPos, pComponent); } else { resize(nPos + 1, NULL); at(nPos) = pComponent; } } // Check it off from Installed List CheckOffInstalledComponent(sID); return hr; } ///////////////////////////////////////////////////////// // LoadInstalledComponents : Loads list of installed // components for access later on // UINT CComponentArray::LoadInstalledComponents() { // Open Key CRegKey regKey; if(regKey.Create(HKEY_LOCAL_MACHINE, NS_REG_INSTALLEDCOMPONENTS) != ERROR_SUCCESS) return 0; // Enumerate Subkeys which should be the IDs of Components DWORD dwCnt = 0; string sKeyName; while(!RegEnumKey(regKey.m_hKey, dwCnt, sKeyName.get_buffer(MAX_PATH), MAX_PATH)) { sKeyName.release_buffer(); // Add to List m_asInstalledComponents.push_back(sKeyName); dwCnt++; } // Return Number of Components return (UINT)dwCnt; } ////////////////////////////////////////////////////////////////// // Checks off the component from the Installed Components list // Loaded with Installed Components bool CComponentArray::CheckOffInstalledComponent(const string& sID) { int nFound = -1; string_array::iterator iter; iter = find(m_asInstalledComponents.begin(), m_asInstalledComponents.end(), sID); // If we found one then remove it // Have to remove it outside of loop or we mess up the // Array Index if(iter != m_asInstalledComponents.end()) { m_asInstalledComponents.erase(iter); return true; } // Couldn't Find return false; } ////////////////////////////////////////////////////////////////// // Remove the components from memory UINT CComponentArray::UnloadComponents() { int nCnt = 0; while(!empty()) { nCnt++; // First let it do it's Clean Up at(0)->Release(); // Then Delete it delete at(0); // Then Remove it from Array erase(begin()); } // Return Number of Components return nCnt; } ////////////////////////////////////////////////////////////////// // Takes a Component registry key and extracts the Program ID // ID should come before space in Key // eg: 'NightSecurity.ClearInetCache' would come from 'NightSecurity.ClearInetCache 2' string CComponentArray::GetIDFromKey(const string& sKeyName) { // ID should come before space in Key // eg: 'NightSecurity.ClearInetCache' would come from 'NightSecurity.ClearInetCache 2' string::size_type pos = sKeyName.find(_T(' ')); // return first part // find return string::npos if fails (which also means end of string) return sKeyName.substr(0, pos); } ////////////////////////////////////////////////////////////////// // Saves each components data to the Registry HRESULT CComponentArray::SaveComponentData() { HRESULT hrRet = S_OK; // Ask Each Component to Save it's own Data iterator iter = begin(); for(; iter != end(); iter++) { // CComponentHolder checks to make sure that the // Components are loaded, so we don't have to // include error checking here. HRESULT hr = (*iter)->GetData()->Save(); if(FAILED(hr)) hrRet = hr; } return hrRet; }