387 lines
7.9 KiB
C++
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;
|
|
}
|
|
|
|
|
|
|