Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

386 lines
7.9 KiB

  1. /*++
  2. Copyright (c) 2000, Microsoft Corporation
  3. Module Name:
  4. CollectionAlgModules.cpp
  5. Abstract:
  6. Implement a thread safe collection of CAlgModules
  7. Author:
  8. JP Duplessis (jpdup) 2000.01.19
  9. Revision History:
  10. --*/
  11. #include "PreComp.h"
  12. #include "CollectionAlgModules.h"
  13. #include "AlgController.h"
  14. CCollectionAlgModules::~CCollectionAlgModules()
  15. {
  16. MYTRACE_ENTER("CCollectionAlgModules::~CCollectionAlgModules()");
  17. Unload();
  18. }
  19. //
  20. // Add a new ALG Module only if it's uniq meaning that if it's alread in the collection
  21. // it will return the one found and not add a new one
  22. //
  23. CAlgModule*
  24. CCollectionAlgModules::AddUniqueAndStart(
  25. CRegKey& KeyEnumISV,
  26. LPCTSTR pszAlgID
  27. )
  28. {
  29. try
  30. {
  31. ENTER_AUTO_CS
  32. MYTRACE_ENTER("CCollectionAlgModules::AddUniqueAndStart");
  33. //
  34. // Is it already in the collection ?
  35. //
  36. for ( LISTOF_ALGMODULE::iterator theIterator = m_ThisCollection.begin();
  37. theIterator != m_ThisCollection.end();
  38. theIterator++
  39. )
  40. {
  41. if ( _wcsicmp( (*theIterator)->m_szID, pszAlgID) == 0 )
  42. {
  43. //
  44. // Found it already
  45. //
  46. MYTRACE("Already loaded nothing to do");
  47. return (*theIterator);
  48. }
  49. }
  50. //
  51. // At this point we know that it's not in the collection
  52. //
  53. //
  54. // Get more information on the ALG module
  55. //
  56. CRegKey RegAlg;
  57. RegAlg.Open(KeyEnumISV, pszAlgID, KEY_QUERY_VALUE);
  58. TCHAR szFriendlyName[MAX_PATH];
  59. DWORD dwSize = MAX_PATH;
  60. RegAlg.QueryValue(szFriendlyName, TEXT("Product"), &dwSize);
  61. //
  62. // Stuff in a CAlgModule that will be added to the collection
  63. //
  64. CAlgModule* pAlg = new CAlgModule(pszAlgID, szFriendlyName);
  65. if ( !pAlg )
  66. return NULL;
  67. HRESULT hr = pAlg->Start();
  68. if ( FAILED(hr) )
  69. {
  70. delete pAlg;
  71. }
  72. //
  73. // Now we know this is a valid and trouble free ALG plug-in we can safely cache it to our collection
  74. //
  75. try
  76. {
  77. m_ThisCollection.push_back(pAlg);
  78. }
  79. catch(...)
  80. {
  81. MYTRACE_ERROR("Had problem adding the ALG plun-in to the collection", 0);
  82. pAlg->Stop();
  83. delete pAlg;
  84. return NULL;
  85. }
  86. return pAlg;
  87. }
  88. catch(...)
  89. {
  90. return NULL;
  91. }
  92. return NULL;
  93. }
  94. //
  95. // Remove a AlgModule from the list (Thead safe)
  96. //
  97. HRESULT CCollectionAlgModules::Remove(
  98. CAlgModule* pAlgToRemove
  99. )
  100. {
  101. try
  102. {
  103. ENTER_AUTO_CS
  104. MYTRACE_ENTER("CCollectionAlgModules::Remove");
  105. LISTOF_ALGMODULE::iterator theIterator = std::find(
  106. m_ThisCollection.begin(),
  107. m_ThisCollection.end(),
  108. pAlgToRemove
  109. );
  110. if ( *theIterator )
  111. {
  112. m_ThisCollection.erase(theIterator);
  113. }
  114. }
  115. catch(...)
  116. {
  117. return E_FAIL;
  118. }
  119. return S_OK;
  120. }
  121. //
  122. // return TRUE is the ALG Module specified by pszAlgProgID
  123. // is currently marked as "Enable"
  124. //
  125. bool
  126. IsAlgModuleEnable(
  127. CRegKey& RegKeyISV,
  128. LPCTSTR pszAlgID
  129. )
  130. {
  131. DWORD dwSize = MAX_PATH;
  132. TCHAR szState[MAX_PATH];
  133. LONG nRet = RegKeyISV.QueryValue(
  134. szState,
  135. pszAlgID,
  136. &dwSize
  137. );
  138. if ( ERROR_SUCCESS != nRet )
  139. return false;
  140. if ( dwSize == 0 || dwSize > sizeof(szState)*sizeof(TCHAR) )
  141. return false;
  142. return ( _wcsicmp(szState, L"Enable") == 0);
  143. };
  144. //
  145. //
  146. //
  147. HRESULT
  148. CCollectionAlgModules::UnloadDisabledModule()
  149. {
  150. try
  151. {
  152. ENTER_AUTO_CS
  153. MYTRACE_ENTER("CCollectionAlgModules::UnloadDisabledModule()");
  154. CRegKey KeyEnumISV;
  155. LONG nError = KeyEnumISV.Open(HKEY_LOCAL_MACHINE, REGKEY_ALG_ISV, KEY_READ);
  156. bool bAllEnable = false;
  157. //
  158. // The total of item in the collectio is the maximum time we should attempt
  159. // to verify and unload Alg Module that are disable
  160. //
  161. int nPassAttemp = m_ThisCollection.size();
  162. while ( !bAllEnable && nPassAttemp > 0 )
  163. {
  164. bAllEnable = true;
  165. //
  166. // For all Module unload if not mark as "ENABLE"
  167. //
  168. for ( LISTOF_ALGMODULE::iterator theIterator = m_ThisCollection.begin();
  169. theIterator != m_ThisCollection.end();
  170. theIterator++
  171. )
  172. {
  173. if ( IsAlgModuleEnable(KeyEnumISV, (*theIterator)->m_szID) )
  174. {
  175. MYTRACE("ALG Module %S is ENABLE", (*theIterator)->m_szFriendlyName);
  176. }
  177. else
  178. {
  179. MYTRACE("ALG Module %S is DISABLE", (*theIterator)->m_szFriendlyName);
  180. //
  181. // Stop/Release/Unload this module it's not enabled
  182. //
  183. delete (*theIterator);
  184. m_ThisCollection.erase(theIterator);
  185. bAllEnable = false;
  186. break;
  187. }
  188. }
  189. nPassAttemp--; // Ok one pass done
  190. }
  191. }
  192. catch(...)
  193. {
  194. return E_FAIL;
  195. }
  196. return S_OK;
  197. }
  198. //
  199. //
  200. // Enumared the regsitry for all ALG-ISV module and verify that they are sign and CoCreates them and call there Initialise method
  201. //
  202. //
  203. int // Returns the total number of ISV ALG loaded or -1 for error or 0 is none where setup
  204. CCollectionAlgModules::Load()
  205. {
  206. MYTRACE_ENTER("CAlgController::LoadAll()");
  207. int nValidAlgLoaded = 0;
  208. CRegKey KeyEnumISV;
  209. LONG nError = KeyEnumISV.Open(HKEY_LOCAL_MACHINE, REGKEY_ALG_ISV, KEY_READ|KEY_ENUMERATE_SUB_KEYS);
  210. if ( ERROR_SUCCESS != nError )
  211. {
  212. MYTRACE_ERROR("Could not open RegKey 'HKLM\\SOFTWARE\\Microsoft\\ALG\\ISV'",nError);
  213. return nError;
  214. }
  215. DWORD dwIndex=0;
  216. TCHAR szID_AlgToLoad[256];
  217. DWORD dwKeyNameSize;
  218. LONG nRet;
  219. do
  220. {
  221. dwKeyNameSize = 256;
  222. nRet = RegEnumKeyEx(
  223. KeyEnumISV.m_hKey, // handle to key to enumerate
  224. dwIndex, // subkey index
  225. szID_AlgToLoad, // subkey name
  226. &dwKeyNameSize, // size of subkey buffer
  227. NULL, // reserved
  228. NULL, // class string buffer
  229. NULL, // size of class string buffer
  230. NULL // last write time
  231. );
  232. dwIndex++;
  233. if ( ERROR_NO_MORE_ITEMS == nRet )
  234. break; // All items are enumerated we are done here
  235. if ( ERROR_SUCCESS == nRet )
  236. {
  237. //
  238. // Must be flag as enable under the main ALG/ISV hive to be loaded
  239. //
  240. if ( IsAlgModuleEnable(KeyEnumISV, szID_AlgToLoad) )
  241. {
  242. MYTRACE("* %S Is 'ENABLE' make sure it's loaded", szID_AlgToLoad);
  243. AddUniqueAndStart(KeyEnumISV, szID_AlgToLoad);
  244. }
  245. else
  246. {
  247. MYTRACE("* %S Is 'DISABLE' will not be loaded", szID_AlgToLoad);
  248. }
  249. }
  250. else
  251. {
  252. MYTRACE_ERROR("RegEnumKeyEx", nRet);
  253. }
  254. } while ( ERROR_SUCCESS == nRet );
  255. return nValidAlgLoaded;
  256. }
  257. //
  258. // For all loaded ALG moudles calls the STOP method and release any resources
  259. //
  260. HRESULT
  261. CCollectionAlgModules::Unload()
  262. {
  263. try
  264. {
  265. ENTER_AUTO_CS
  266. MYTRACE_ENTER("CCollectionAlgModules::Unload ***");
  267. MYTRACE("Colletion size is %d", m_ThisCollection.size());
  268. HRESULT hr;
  269. LISTOF_ALGMODULE::iterator theIterator;
  270. while ( m_ThisCollection.size() > 0 )
  271. {
  272. theIterator = m_ThisCollection.begin();
  273. delete (*theIterator);
  274. m_ThisCollection.erase(theIterator);
  275. }
  276. }
  277. catch(...)
  278. {
  279. return E_FAIL;
  280. }
  281. return S_OK;
  282. }