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.

407 lines
9.2 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. REGEVENT.CPP
  5. Abstract:
  6. Declares the CRegEvent class
  7. History:
  8. a-davj 1-July-97 Created.
  9. --*/
  10. #include "precomp.h"
  11. #include "node.h"
  12. #include "eventreg.h"
  13. #include <impdyn.h>
  14. #include "regevent.h"
  15. CRegEventSet gSet;
  16. struct BaseTypes2
  17. {
  18. LPTSTR lpName;
  19. HKEY hKey;
  20. } Bases2[] =
  21. {
  22. {TEXT("HKEY_CLASSES_ROOT") , HKEY_CLASSES_ROOT},
  23. {TEXT("HKEY_CURRENT_USER") , HKEY_CURRENT_USER},
  24. {TEXT("HKEY_LOCAL_MACHINE") , HKEY_LOCAL_MACHINE},
  25. {TEXT("HKEY_USERS") , HKEY_USERS},
  26. {TEXT("HKEY_PERFORMANCE_DATA") , HKEY_PERFORMANCE_DATA},
  27. {TEXT("HKEY_CURRENT_CONFIG") , HKEY_CURRENT_CONFIG},
  28. {TEXT("HKEY_DYN_DATA") , HKEY_DYN_DATA}};
  29. DWORD AddToCheckSub(DWORD & dwNewCheckSum, void * pData, DWORD dwDataSize)
  30. {
  31. return 0;
  32. }
  33. void CRegEvent::TimerCheck()
  34. {
  35. DWORD dwError;
  36. CNode * pNewHiveImage = NULL;
  37. // todo, need some sort of mutex so as not to reenter this. Also need to create
  38. // a thread to do this!!!!
  39. DWORD dwNewCheckSum = 0;
  40. HKEY hSubKey = NULL;
  41. // Open the root key
  42. TCHAR * pSt = m_sRegPath;
  43. TCHAR * pAfter = NULL;
  44. HKEY hBase = NULL;
  45. int iSlash = m_sRegPath.Find('\\');
  46. if(iSlash < 0)
  47. {
  48. return;
  49. }
  50. pSt[iSlash] = 0;
  51. pAfter = pSt + iSlash + 1;
  52. for(int iCnt = 0; iCnt < sizeof(Bases2) / sizeof(struct BaseTypes2 ); iCnt++)
  53. if(!lstrcmpi(Bases2[iCnt].lpName, pSt))
  54. {
  55. hBase = Bases2[iCnt].hKey;
  56. break;
  57. }
  58. if(hBase == NULL)
  59. {
  60. return; //todo, bitch
  61. }
  62. long lRes = RegOpenKeyEx(hBase, pAfter, 0, KEY_READ, &hSubKey);
  63. if(lRes != 0)
  64. {
  65. dwError = GetLastError();
  66. return; //todo, bitch
  67. }
  68. if(m_bSaveHiveImage)
  69. pNewHiveImage = new CNode;
  70. CalcHive(hSubKey, dwNewCheckSum);
  71. RegCloseKey(hSubKey);
  72. if(dwNewCheckSum != m_dwCheckSum)
  73. {
  74. //todo, send event
  75. m_dwCheckSum = dwNewCheckSum;
  76. }
  77. if(m_bSaveHiveImage)
  78. {
  79. if(m_pLastHiveImage)
  80. {
  81. m_pLastHiveImage->CompareAndReportDiffs(pNewHiveImage);
  82. {
  83. }
  84. delete m_pLastHiveImage;
  85. }
  86. m_pLastHiveImage = pNewHiveImage;
  87. }
  88. }
  89. DWORD CRegEvent::CalcHive(HKEY hKey,DWORD & dwNewCheckSum)
  90. {
  91. long lRes;
  92. DWORD dwRet = 0;
  93. TCHAR * pSubKeyName = NULL;
  94. TCHAR * pValueName = NULL;
  95. BYTE * pValue = NULL;
  96. DWORD dwError;
  97. // Get the general info on the directory.
  98. DWORD dwSubKeys, dwMaxSubKeyLen, dwValues, dwMaxValueNameLen, dwMaxValueLen;
  99. lRes = RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwSubKeys, &dwMaxSubKeyLen, NULL,
  100. &dwValues, &dwMaxValueNameLen, &dwMaxValueLen, NULL, NULL);
  101. if(lRes != ERROR_SUCCESS)
  102. {
  103. DWORD dwRet = GetLastError();
  104. goto CalcHiveCleanup;
  105. }
  106. // Allocate space to hold the various names and data
  107. pValueName = new TCHAR[dwMaxValueNameLen+1];
  108. if(dwMaxValueLen > 0)
  109. pValue = new BYTE[dwMaxValueLen];
  110. if(pValueName == NULL || (dwMaxValueLen > 0 &&pValue == NULL))
  111. {
  112. dwRet = WBEM_E_OUT_OF_MEMORY;
  113. goto CalcHiveCleanup;
  114. }
  115. // Enumerate each value, add the name, type, and data to the check sum
  116. DWORD dwCnt;
  117. for(dwCnt = 0; dwCnt < dwValues ; dwCnt++)
  118. {
  119. DWORD dwTempNameSize = dwMaxValueNameLen+1;
  120. DWORD dwType;
  121. DWORD dwTempDataSize = dwMaxValueLen;
  122. lRes = RegEnumValue(hKey, dwCnt, pValueName, &dwTempNameSize, 0, &dwType,
  123. pValue, &dwTempDataSize);
  124. if(lRes != ERROR_SUCCESS)
  125. {
  126. DWORD dwRet = GetLastError();
  127. goto CalcHiveCleanup;
  128. }
  129. AddToCheckSub(dwNewCheckSum, pValueName, dwTempNameSize);
  130. AddToCheckSub(dwNewCheckSum, &dwType, sizeof(DWORD));
  131. AddToCheckSub(dwNewCheckSum, pValue, dwTempNameSize);
  132. }
  133. // Free up the memory which is no longer needed
  134. if(pValueName)
  135. delete pValueName;
  136. pValueName = NULL;
  137. if(pValue)
  138. delete pValue;
  139. pValue = NULL;
  140. // Enumerate the subkeys and calculate them
  141. pSubKeyName = new TCHAR[dwMaxSubKeyLen+1];
  142. for(dwCnt = 0; dwCnt < dwSubKeys ; dwCnt++)
  143. {
  144. lRes = RegEnumKey(hKey, dwCnt, pSubKeyName, dwMaxSubKeyLen+1);
  145. if(lRes != ERROR_SUCCESS)
  146. {
  147. DWORD dwRet = GetLastError();
  148. goto CalcHiveCleanup;
  149. }
  150. // Add the name to the check sum, open the key and call this recursively
  151. AddToCheckSub(dwNewCheckSum, pSubKeyName, lstrlen(pSubKeyName));
  152. HKEY hSubKey = NULL;
  153. long lRes = RegOpenKeyEx(hKey, pSubKeyName, 0, KEY_READ, &hSubKey);
  154. if(lRes != 0)
  155. {
  156. dwError = GetLastError();
  157. return dwError; //todo, bitch
  158. }
  159. CalcHive(hSubKey, dwNewCheckSum);
  160. RegCloseKey(hSubKey);
  161. }
  162. CalcHiveCleanup:
  163. if(pSubKeyName)
  164. delete pSubKeyName;
  165. if(pValueName)
  166. delete pValueName;
  167. if(pValue)
  168. delete pValue;
  169. return dwRet;
  170. }
  171. SCODE MyCreateInstance(IWbemServices * pGateway, WCHAR * pwcClass, WCHAR * pwcKeyName,
  172. WCHAR * pwcKeyValue, IWbemClassObject ** ppNewInst)
  173. {
  174. SCODE sc;
  175. if(pGateway == NULL || pwcClass == NULL || pwcKeyName == NULL ||
  176. pwcKeyValue == NULL || ppNewInst == NULL)
  177. return WBEM_E_INVALID_PARAMETER;
  178. *ppNewInst = NULL;
  179. // Create the new instance
  180. IWbemClassObject * pClassObj = NULL;
  181. sc = pGateway->GetObject(pwcClass,0, NULL, &pClassObj,NULL);
  182. if(FAILED(sc))
  183. return sc;
  184. sc = pClassObj->SpawnInstance(0, ppNewInst);
  185. pClassObj->Release();
  186. if(FAILED(sc))
  187. return sc;
  188. VARIANT var;
  189. var.vt = VT_BSTR;
  190. var.bstrVal = SysAllocString(pwcKeyValue);
  191. if(var.bstrVal == NULL)
  192. return sc;
  193. sc = (*ppNewInst)->Put(pwcKeyName,0,&var,0);
  194. VariantClear(&var);
  195. return sc;
  196. }
  197. SCODE CreateTimerEvent(WCHAR * pwcName, long lTimeIntSec, IWbemServices * pGateway)
  198. {
  199. IWbemClassObject * pNewInst = NULL;
  200. SCODE sc = MyCreateInstance(pGateway, L"__IntervalTimerInstruction",
  201. L"TimerID", pwcName, &pNewInst);
  202. if(sc != S_OK)
  203. return sc;
  204. VARIANT var;
  205. VariantInit(&var);
  206. var.vt = VT_I4;
  207. var.lVal = lTimeIntSec * 1000;
  208. sc = pNewInst->Put(L"IntervalBetweenEvents",0,&var,0);
  209. var.vt = VT_BOOL;
  210. var.boolVal = VARIANT_FALSE;
  211. sc = pNewInst->Put(L"SkipIfPassed",0,&var,0);
  212. sc = pGateway->PutInstance(pNewInst, 0, NULL, NULL);
  213. return sc;
  214. }
  215. CRegEvent::CRegEvent(IWbemClassObject * pObj, IWbemServices * pWbem)
  216. {
  217. m_dwCheckSum = 0xffffffff; // indicates that check sum has never been done
  218. // Save a pointer to the core
  219. m_bSaveHiveImage = FALSE;
  220. m_pLastHiveImage = NULL;
  221. if(pWbem)
  222. {
  223. m_pWbem = pWbem;
  224. m_pWbem->AddRef();
  225. }
  226. else
  227. m_pWbem = NULL;
  228. // generate a unique name by creating a new GUID and convert it to string format
  229. GUID guid;
  230. int iLen;
  231. SCODE sc = CoCreateGuid(&guid);
  232. if(sc == S_OK)
  233. iLen = StringFromGUID2(guid,m_wcGuid,39);
  234. else
  235. m_wcGuid[0] = 0;
  236. // Read the path and possibly value field
  237. VARIANT var;
  238. VariantInit(&var);
  239. sc = pObj->Get(L"Key", 0, &var, NULL, NULL);
  240. if(sc == S_OK && var.vt == VT_BSTR && var.bstrVal != NULL)
  241. m_sRegPath = var.bstrVal;
  242. VariantInit(&var);
  243. sc = pObj->Get(L"Value", 0, &var, NULL, NULL);
  244. if(sc == S_OK && var.vt == VT_BSTR && var.bstrVal != NULL)
  245. m_sRegValue = var.bstrVal;
  246. VariantInit(&var);
  247. sc = pObj->Get(L"PollingIntervalSec", 0, &var, NULL, NULL);
  248. if(sc == S_OK && var.vt == VT_I4)
  249. {
  250. WCHAR wcQuery[256];
  251. wcscpy(wcQuery, L"select * from __TimerEvent where TimerId = \"");
  252. wcscat(wcQuery, m_wcGuid);
  253. wcscat(wcQuery, L"\"");
  254. m_lTimeIntSec = var.lVal;
  255. m_TimerEvent.SetQuery(wcQuery);
  256. sc = m_TimerEvent.StoreToWBEM(m_pWbem);
  257. sc = CreateTimerEvent(m_wcGuid, m_lTimeIntSec, m_pWbem);
  258. }
  259. }
  260. CRegEvent::~CRegEvent()
  261. {
  262. if(m_pWbem)
  263. m_pWbem->Release();
  264. if(m_pLastHiveImage)
  265. delete m_pLastHiveImage;
  266. //todo, release the timer objects????
  267. }
  268. CRegEventSet::CRegEventSet()
  269. {
  270. }
  271. SCODE CRegEventSet::Initialize(IWbemServices * pWbem)
  272. {
  273. SCODE sc;
  274. m_pWbem = pWbem;
  275. if(m_pWbem)
  276. {
  277. m_pWbem->AddRef();
  278. //fornow, loop through the list of RegEvent instances and create an entry for each
  279. IWbemClassObject * pNewInst = NULL;
  280. IEnumWbemClassObject FAR* pIEnum = NULL;
  281. sc = m_pWbem->CreateInstanceEnum(L"RegEvent", 0, NULL, &pIEnum);
  282. while (sc == S_OK)
  283. {
  284. ULONG uRet;
  285. sc = pIEnum->Next(-1, 1,&pNewInst,&uRet);
  286. if(sc == S_OK)
  287. {
  288. CRegEvent * pNewEvent = new CRegEvent(pNewInst,m_pWbem);
  289. if(pNewEvent)
  290. m_Set.Add(pNewEvent);
  291. pNewInst->Release();
  292. }
  293. }
  294. if(pIEnum)
  295. pIEnum->Release();
  296. // fornow, register to get change events for that class.
  297. m_Event.SetQuery(L"select * from __InstanceCreationEvent where newinstance.__class = \"regevent\"");
  298. sc = m_Event.StoreToWBEM(m_pWbem);
  299. }
  300. return WBEM_E_INVALID_PARAMETER;
  301. }
  302. CRegEventSet::~CRegEventSet()
  303. {
  304. if(m_pWbem)
  305. m_pWbem->Release();
  306. m_Set.Empty();
  307. }
  308. void CRegEventSet::FindEvent(WCHAR * pwcID)
  309. {
  310. CRegEvent * pEvent;
  311. for(long lEvent = 0; lEvent < m_Set.Size(); lEvent++)
  312. {
  313. pEvent = (CRegEvent *)m_Set.GetAt(lEvent);
  314. if(pEvent && pEvent->IsMatch(pwcID))
  315. pEvent->TimerCheck();
  316. }
  317. }