Leaked source code of windows server 2003
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.

357 lines
9.5 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: AUCatalog.h
  6. //
  7. // Creator: PeterWi
  8. //
  9. // Purpose: AU Catalog Definitions
  10. //
  11. //=======================================================================
  12. #pragma once
  13. #include <stdio.h>
  14. #include <msxml.h>
  15. #include <windows.h>
  16. #include <safefunc.h>
  17. #include "Loadengine.h"
  18. #include "iu.h" //for IU engine exported functions' prototype
  19. #include "iuctl.h" //for definition of UPDATE_COMMAND_CANCEL
  20. #include "mistsafe.h"
  21. class AUCatalogItem;
  22. const WCHAR AUCLIENTINFO[] = L"<clientInfo xmlns=\"x-schema:http://schemas.windowsupdate.com/iu/clientInfo.xml\" clientName=\"au\" />";
  23. const WCHAR AUDRIVERCLIENTINFO[] = L"<clientInfo xmlns=\"x-schema:http://schemas.windowsupdate.com/iu/clientInfo.xml\" clientName=\"audriver\" />";
  24. const DWORD AUCATITEM_UNSELECTED = 0;
  25. const DWORD AUCATITEM_SELECTED = 1;
  26. const DWORD AUCATITEM_HIDDEN = 2;
  27. //global object should not use CAU_BSTR because its constructor and destructor will
  28. //make API calls which might cause dll loader deadlock
  29. class CAU_BSTR
  30. {
  31. public:
  32. CAU_BSTR() : m_bstr(NULL){};
  33. ~CAU_BSTR() {SafeFreeBSTR(m_bstr); }
  34. operator BSTR() { return m_bstr; }
  35. BOOL append(LPCWSTR wszToAppend)
  36. {
  37. if (NULL == wszToAppend)
  38. {
  39. return FALSE;
  40. }
  41. if (NULL == m_bstr)
  42. {
  43. m_bstr = SysAllocString(wszToAppend);
  44. return m_bstr != NULL;
  45. }
  46. int ilen = SysStringLen(m_bstr) + lstrlenW(wszToAppend) + 1;
  47. LPWSTR wszTmp = (LPWSTR) malloc(ilen * sizeof(WCHAR));
  48. if (NULL == wszTmp)
  49. {
  50. return FALSE;
  51. }
  52. BOOL fRet =
  53. SUCCEEDED(StringCchCopyExW(wszTmp, ilen, m_bstr, NULL, NULL, MISTSAFE_STRING_FLAGS)) &&
  54. SUCCEEDED(StringCchCatExW(wszTmp, ilen, wszToAppend, NULL, NULL, MISTSAFE_STRING_FLAGS)) &&
  55. SysReAllocString(&m_bstr, wszTmp);
  56. free(wszTmp);
  57. return fRet;
  58. }
  59. private:
  60. BSTR m_bstr;
  61. };
  62. class AU_VARIANT : public ::tagVARIANT
  63. {
  64. public:
  65. AU_VARIANT()
  66. {
  67. vt = VT_EMPTY;
  68. }
  69. AU_VARIANT(LPCWSTR wsz)
  70. {
  71. vt = VT_BSTR;
  72. if ( NULL == (bstrVal = SysAllocString(wsz)) )
  73. {
  74. vt = VT_EMPTY;
  75. }
  76. }
  77. AU_VARIANT(long newlVal)
  78. {
  79. vt = VT_I4;
  80. lVal = newlVal;
  81. }
  82. AU_VARIANT(GUID & guid)
  83. {
  84. WCHAR wszGUID[40]; // 725e35a2-ee11-4b34-834f-6eaf4bade994
  85. vt = VT_BSTR;
  86. if ( (0 == StringFromGUID2(guid, wszGUID, ARRAYSIZE(wszGUID))) ||
  87. (NULL == (bstrVal = SysAllocString(wszGUID))) )
  88. {
  89. DEBUGMSG("variant with guid failed");
  90. vt = VT_EMPTY;
  91. }
  92. }
  93. ~AU_VARIANT() { VariantClear(this); }
  94. BOOL IsEmpty(void) { return VT_EMPTY == vt; }
  95. };
  96. class AUCatalogItemList
  97. {
  98. public:
  99. AUCatalogItemList()
  100. :pList(NULL), uNum(0) {}
  101. ~AUCatalogItemList() { Clear(); }
  102. UINT Count(void) { return uNum; }
  103. AUCatalogItem & operator[] (UINT uIndex) const
  104. {
  105. return *pList[uIndex];
  106. }
  107. void Clear(void);
  108. HRESULT Allocate(DWORD cItems);
  109. HRESULT Allocate(VARIANT & var);
  110. BOOL Add(AUCatalogItem *pitem);
  111. void Remove(BSTR bstrItemID);
  112. INT Contains(BSTR bstrItemID);
  113. HRESULT Copy( AUCatalogItemList &itemlist2);
  114. HRESULT BuildIndirectDependency();
  115. UINT GetNum(DWORD dwSelectionStatus);
  116. UINT GetNumSelected(void) { return GetNum(AUCATITEM_SELECTED); }
  117. UINT GetNumUnselected(void) { return GetNum(AUCATITEM_UNSELECTED); }
  118. UINT GetNumHidden(void) { return GetNum(AUCATITEM_HIDDEN);}
  119. BOOL ItemIsRelevant(UINT index) ;
  120. void DbgDump(void);
  121. private:
  122. UINT uNum;
  123. AUCatalogItem **pList;
  124. };
  125. class AUCatalogItem
  126. {
  127. public:
  128. AUCatalogItem()
  129. : m_dwStatus(AUCATITEM_SELECTED),
  130. m_bstrID(NULL),
  131. m_bstrProviderName(NULL),
  132. m_bstrTitle(NULL),
  133. m_bstrDescription(NULL),
  134. m_bstrRTFPath(NULL),
  135. m_bstrEULAPath(NULL)
  136. {}
  137. AUCatalogItem(AUCatalogItem & item2)
  138. {
  139. m_bstrID = SysAllocString(item2.bstrID());
  140. m_bstrProviderName = SysAllocString(item2.bstrProviderName());
  141. m_bstrTitle = SysAllocString(item2.bstrTitle());
  142. m_bstrDescription = SysAllocString(item2.bstrDescription());
  143. m_bstrRTFPath = SysAllocString(item2.bstrRTFPath());
  144. m_bstrEULAPath = SysAllocString(item2.bstrEULAPath());
  145. m_dwStatus = item2.dwStatus();
  146. }
  147. void Clear()
  148. {
  149. SafeFreeBSTRNULL(m_bstrID);
  150. SafeFreeBSTRNULL(m_bstrTitle);
  151. SafeFreeBSTRNULL(m_bstrProviderName);
  152. SafeFreeBSTRNULL(m_bstrDescription);
  153. SafeFreeBSTRNULL(m_bstrRTFPath);
  154. SafeFreeBSTRNULL(m_bstrEULAPath);
  155. }
  156. ~AUCatalogItem()
  157. {
  158. Clear();
  159. }
  160. BOOL fEqual(AUCatalogItem & item2)
  161. {
  162. BOOL fRet = FALSE;
  163. BSTR myValues[] = {m_bstrID,
  164. m_bstrProviderName,
  165. m_bstrTitle,
  166. m_bstrDescription,
  167. m_bstrRTFPath,
  168. m_bstrEULAPath };
  169. BSTR theirValues[] = {item2.bstrID(),
  170. item2.bstrProviderName(),
  171. item2.bstrTitle(),
  172. item2.bstrDescription(),
  173. item2.bstrRTFPath(),
  174. item2.bstrEULAPath()};
  175. if (item2.dwStatus() != m_dwStatus)
  176. {
  177. goto done;
  178. }
  179. for ( UINT i= 0; i < ARRAYSIZE(myValues); i++ )
  180. {
  181. if (NULL != myValues[i] && NULL == theirValues[i]
  182. || NULL == myValues[i] && NULL != theirValues[i])
  183. {
  184. goto done;
  185. }
  186. else if (NULL != myValues[i] && NULL != theirValues[i])
  187. {
  188. if (0 != lstrcmpW(myValues[i], theirValues[i]))
  189. {
  190. goto done;
  191. }
  192. }
  193. }
  194. fRet = TRUE;
  195. done:
  196. return fRet;
  197. }
  198. void SetField(LPCSTR szFieldName, BSTR bstrVal)
  199. {
  200. BSTR * grValues[] = { &m_bstrID,
  201. &m_bstrProviderName,
  202. &m_bstrTitle,
  203. &m_bstrDescription,
  204. &m_bstrRTFPath,
  205. &m_bstrEULAPath };
  206. for ( int index = 0; index < ARRAYSIZE(grValues); index++ )
  207. {
  208. if ( 0 == _stricmp(szFieldName, m_pFieldNames[index]))
  209. {
  210. *grValues[index] = bstrVal;
  211. return;
  212. }
  213. }
  214. }
  215. void dump() //for debug
  216. {
  217. DEBUGMSG("dumping item content");
  218. DEBUGMSG("Item ID= %S", m_bstrID);
  219. DEBUGMSG("Provider Name= %S", m_bstrProviderName);
  220. DEBUGMSG("Title= %S", m_bstrTitle);
  221. DEBUGMSG("Desc= %S", m_bstrDescription);
  222. DEBUGMSG("RTF Path= %S", m_bstrRTFPath);
  223. DEBUGMSG("Eula Path= %S", m_bstrEULAPath);
  224. DEBUGMSG("status = %d", m_dwStatus);
  225. if (m_DependingItems.Count() == 0)
  226. {
  227. DEBUGMSG(" has no depending items");
  228. }
  229. else
  230. {
  231. DEBUGMSG(" has total %d depending items", m_DependingItems.Count());
  232. for (UINT i = 0; i < m_DependingItems.Count(); i++)
  233. {
  234. DEBUGMSG(" : %S", m_DependingItems[i].bstrID()); //only cares about itemID
  235. }
  236. }
  237. DEBUGMSG("dumping item done");
  238. }
  239. static char * m_pFieldNames[] ;
  240. DWORD dwStatus(void) { return m_dwStatus; }
  241. BSTR bstrID(void) { return (m_bstrID); }
  242. BSTR bstrProviderName(void) { return (m_bstrProviderName); }
  243. BSTR bstrTitle(void) { return (m_bstrTitle); }
  244. BSTR bstrDescription(void) { return (m_bstrDescription); }
  245. BSTR bstrRTFPath(void) { return (m_bstrRTFPath); }
  246. BSTR bstrEULAPath(void) { return (m_bstrEULAPath); }
  247. void SetStatus(DWORD dwStatus) { m_dwStatus = dwStatus; }
  248. void SetStatusHidden(void) { m_dwStatus = AUCATITEM_HIDDEN; }
  249. void SetStatusSelected(void) {m_dwStatus = AUCATITEM_SELECTED;}
  250. BOOL fSelected(void) { return (AUCATITEM_SELECTED == m_dwStatus); }
  251. BOOL fUnselected(void) { return (AUCATITEM_UNSELECTED == m_dwStatus); }
  252. BOOL fHidden(void) { return (AUCATITEM_HIDDEN == m_dwStatus); }
  253. AUCatalogItemList m_DependingItems; //all items that depends on this item, directly and indirectly
  254. private:
  255. DWORD m_dwStatus;
  256. BSTR m_bstrID;
  257. BSTR m_bstrProviderName;
  258. BSTR m_bstrTitle;
  259. BSTR m_bstrDescription;
  260. BSTR m_bstrRTFPath;
  261. BSTR m_bstrEULAPath;
  262. friend HRESULT TransformSafeArrayToItemList(VARIANT & var, AUCatalogItemList & ItemList);
  263. friend class AUCatalog;
  264. };
  265. //wrapper class for AU to do detection using IU
  266. class AUBaseCatalog
  267. {
  268. public:
  269. AUBaseCatalog()
  270. {
  271. Reset();
  272. }
  273. ~AUBaseCatalog();
  274. HRESULT PrepareIU(BOOL fOnline = TRUE);
  275. void FreeIU();
  276. HRESULT CancelNQuit(void);
  277. protected:
  278. HMODULE m_hIUCtl;
  279. HMODULE m_hIUEng;
  280. PFN_LoadIUEngine m_pfnCtlLoadIUEngine;
  281. PFN_UnLoadIUEngine m_pfnCtlUnLoadIUEngine;
  282. PFN_GetSystemSpec m_pfnGetSystemSpec;
  283. PFN_GetManifest m_pfnGetManifest;
  284. PFN_Detect m_pfnDetect;
  285. PFN_Install m_pfnInstall;
  286. PFN_SetOperationMode m_pfnSetOperationMode;
  287. PFN_CtlCancelEngineLoad m_pfnCtlCancelEngineLoad;
  288. PFN_CreateEngUpdateInstance m_pfnCreateEngUpdateInstance;
  289. PFN_DeleteEngUpdateInstance m_pfnDeleteEngUpdateInstance;
  290. BOOL m_fEngineLoaded;
  291. HIUENGINE m_hIUEngineInst;
  292. private:
  293. void Reset()
  294. {
  295. m_hIUCtl = NULL;
  296. m_hIUEng = NULL;
  297. m_pfnCtlLoadIUEngine = NULL;
  298. m_pfnCtlUnLoadIUEngine = NULL;
  299. m_pfnGetSystemSpec = NULL;
  300. m_pfnGetManifest = NULL;
  301. m_pfnDetect = NULL;
  302. m_pfnInstall = NULL;
  303. m_pfnSetOperationMode = NULL;
  304. m_pfnCtlCancelEngineLoad = NULL;
  305. m_pfnCreateEngUpdateInstance = NULL;
  306. m_pfnDeleteEngUpdateInstance = NULL;
  307. m_hIUEngineInst = NULL;
  308. m_fEngineLoaded = FALSE;
  309. }
  310. };
  311. extern HANDLE ghMutex; //mutex used to prevent catalog from being destructed while canceling it