windows-nt/Source/XPSP1/NT/net/homenet/alg/exe/collectionalgmodules.cpp
2020-09-26 16:20:57 +08:00

387 lines
7.9 KiB
C++

/*++
Copyright (c) 2000, Microsoft Corporation
Module Name:
CollectionAlgModules.cpp
Abstract:
Implement a thread safe collection of CAlgModules
Author:
JP Duplessis (jpdup) 2000.01.19
Revision History:
--*/
#include "PreComp.h"
#include "CollectionAlgModules.h"
#include "AlgController.h"
CCollectionAlgModules::~CCollectionAlgModules()
{
MYTRACE_ENTER("CCollectionAlgModules::~CCollectionAlgModules()");
Unload();
}
//
// Add a new ALG Module only if it's uniq meaning that if it's alread in the collection
// it will return the one found and not add a new one
//
CAlgModule*
CCollectionAlgModules::AddUniqueAndStart(
CRegKey& KeyEnumISV,
LPCTSTR pszAlgID
)
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAlgModules::AddUniqueAndStart");
//
// Is it already in the collection ?
//
for ( LISTOF_ALGMODULE::iterator theIterator = m_ThisCollection.begin();
theIterator != m_ThisCollection.end();
theIterator++
)
{
if ( _wcsicmp( (*theIterator)->m_szID, pszAlgID) == 0 )
{
//
// Found it already
//
MYTRACE("Already loaded nothing to do");
return (*theIterator);
}
}
//
// At this point we know that it's not in the collection
//
//
// Get more information on the ALG module
//
CRegKey RegAlg;
RegAlg.Open(KeyEnumISV, pszAlgID, KEY_QUERY_VALUE);
TCHAR szFriendlyName[MAX_PATH];
DWORD dwSize = MAX_PATH;
RegAlg.QueryValue(szFriendlyName, TEXT("Product"), &dwSize);
//
// Stuff in a CAlgModule that will be added to the collection
//
CAlgModule* pAlg = new CAlgModule(pszAlgID, szFriendlyName);
if ( !pAlg )
return NULL;
HRESULT hr = pAlg->Start();
if ( FAILED(hr) )
{
delete pAlg;
}
//
// Now we know this is a valid and trouble free ALG plug-in we can safely cache it to our collection
//
try
{
m_ThisCollection.push_back(pAlg);
}
catch(...)
{
MYTRACE_ERROR("Had problem adding the ALG plun-in to the collection", 0);
pAlg->Stop();
delete pAlg;
return NULL;
}
return pAlg;
}
catch(...)
{
return NULL;
}
return NULL;
}
//
// Remove a AlgModule from the list (Thead safe)
//
HRESULT CCollectionAlgModules::Remove(
CAlgModule* pAlgToRemove
)
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAlgModules::Remove");
LISTOF_ALGMODULE::iterator theIterator = std::find(
m_ThisCollection.begin(),
m_ThisCollection.end(),
pAlgToRemove
);
if ( *theIterator )
{
m_ThisCollection.erase(theIterator);
}
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}
//
// return TRUE is the ALG Module specified by pszAlgProgID
// is currently marked as "Enable"
//
bool
IsAlgModuleEnable(
CRegKey& RegKeyISV,
LPCTSTR pszAlgID
)
{
DWORD dwSize = MAX_PATH;
TCHAR szState[MAX_PATH];
LONG nRet = RegKeyISV.QueryValue(
szState,
pszAlgID,
&dwSize
);
if ( ERROR_SUCCESS != nRet )
return false;
if ( dwSize == 0 || dwSize > sizeof(szState)*sizeof(TCHAR) )
return false;
return ( _wcsicmp(szState, L"Enable") == 0);
};
//
//
//
HRESULT
CCollectionAlgModules::UnloadDisabledModule()
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAlgModules::UnloadDisabledModule()");
CRegKey KeyEnumISV;
LONG nError = KeyEnumISV.Open(HKEY_LOCAL_MACHINE, REGKEY_ALG_ISV, KEY_READ);
bool bAllEnable = false;
//
// The total of item in the collectio is the maximum time we should attempt
// to verify and unload Alg Module that are disable
//
int nPassAttemp = m_ThisCollection.size();
while ( !bAllEnable && nPassAttemp > 0 )
{
bAllEnable = true;
//
// For all Module unload if not mark as "ENABLE"
//
for ( LISTOF_ALGMODULE::iterator theIterator = m_ThisCollection.begin();
theIterator != m_ThisCollection.end();
theIterator++
)
{
if ( IsAlgModuleEnable(KeyEnumISV, (*theIterator)->m_szID) )
{
MYTRACE("ALG Module %S is ENABLE", (*theIterator)->m_szFriendlyName);
}
else
{
MYTRACE("ALG Module %S is DISABLE", (*theIterator)->m_szFriendlyName);
//
// Stop/Release/Unload this module it's not enabled
//
delete (*theIterator);
m_ThisCollection.erase(theIterator);
bAllEnable = false;
break;
}
}
nPassAttemp--; // Ok one pass done
}
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}
//
//
// Enumared the regsitry for all ALG-ISV module and verify that they are sign and CoCreates them and call there Initialise method
//
//
int // Returns the total number of ISV ALG loaded or -1 for error or 0 is none where setup
CCollectionAlgModules::Load()
{
MYTRACE_ENTER("CAlgController::LoadAll()");
int nValidAlgLoaded = 0;
CRegKey KeyEnumISV;
LONG nError = KeyEnumISV.Open(HKEY_LOCAL_MACHINE, REGKEY_ALG_ISV, KEY_READ|KEY_ENUMERATE_SUB_KEYS);
if ( ERROR_SUCCESS != nError )
{
MYTRACE_ERROR("Could not open RegKey 'HKLM\\SOFTWARE\\Microsoft\\ALG\\ISV'",nError);
return nError;
}
DWORD dwIndex=0;
TCHAR szID_AlgToLoad[256];
DWORD dwKeyNameSize;
LONG nRet;
do
{
dwKeyNameSize = 256;
nRet = RegEnumKeyEx(
KeyEnumISV.m_hKey, // handle to key to enumerate
dwIndex, // subkey index
szID_AlgToLoad, // subkey name
&dwKeyNameSize, // size of subkey buffer
NULL, // reserved
NULL, // class string buffer
NULL, // size of class string buffer
NULL // last write time
);
dwIndex++;
if ( ERROR_NO_MORE_ITEMS == nRet )
break; // All items are enumerated we are done here
if ( ERROR_SUCCESS == nRet )
{
//
// Must be flag as enable under the main ALG/ISV hive to be loaded
//
if ( IsAlgModuleEnable(KeyEnumISV, szID_AlgToLoad) )
{
MYTRACE("* %S Is 'ENABLE' make sure it's loaded", szID_AlgToLoad);
AddUniqueAndStart(KeyEnumISV, szID_AlgToLoad);
}
else
{
MYTRACE("* %S Is 'DISABLE' will not be loaded", szID_AlgToLoad);
}
}
else
{
MYTRACE_ERROR("RegEnumKeyEx", nRet);
}
} while ( ERROR_SUCCESS == nRet );
return nValidAlgLoaded;
}
//
// For all loaded ALG moudles calls the STOP method and release any resources
//
HRESULT
CCollectionAlgModules::Unload()
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAlgModules::Unload ***");
MYTRACE("Colletion size is %d", m_ThisCollection.size());
HRESULT hr;
LISTOF_ALGMODULE::iterator theIterator;
while ( m_ThisCollection.size() > 0 )
{
theIterator = m_ThisCollection.begin();
delete (*theIterator);
m_ThisCollection.erase(theIterator);
}
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}