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.

788 lines
19 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: autoupd.cpp
  6. //
  7. // Owner: YanL
  8. //
  9. // Description:
  10. //
  11. // AutoApdateSupport
  12. //
  13. //=======================================================================
  14. #include "stdafx.h"
  15. #include "WUV3IS.h"
  16. #include <stdio.h>
  17. #include <initguid.h>
  18. #include <inseng.h>
  19. #include <shlwapi.h>
  20. #include <wininet.h>
  21. #define USEWUV3INCLUDES
  22. #include <wuv3.h>
  23. #undef USEWUV3INCLUDES
  24. #include <winspool.h>
  25. #include <cstate.h>
  26. #include <wustl.h>
  27. #include <osdet.h>
  28. #include "CV3.h"
  29. #include "detect.h"
  30. #include "callback.h"
  31. #include "locstr.h"
  32. #include "safearr.h"
  33. #include "install.h"
  34. #include "log.h"
  35. #include "filecrc.h"
  36. #include "newtrust.h"
  37. #define REGKEY_WUV3TEST _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\wuv3test")
  38. extern CState g_v3state; //defined in CV3.CPP
  39. extern void ProcessInstallList(Varray<DEPENDPUID>& vFinalList, int& cFinalList);
  40. static void Cleanup(PINVENTORY_ITEM pItem);
  41. // find auto-update catalog and get all puids in dependency order
  42. STDMETHODIMP CCV3::BuildCatalog(BOOL fGoOnline, DWORD dwType, BSTR bstrServerUrl)
  43. {
  44. LOG_block("CCV3::BuildCatalog");
  45. if (fGoOnline)
  46. {
  47. LOG_out("fGoOnline = true");
  48. }
  49. else
  50. {
  51. LOG_out("fGoOnline = false");
  52. }
  53. try
  54. {
  55. // we don't want to check the launch server from this interface
  56. m_bLaunchServChecked = TRUE;
  57. // Configure download
  58. CWUDownload::s_fOffline = ! fGoOnline;
  59. PUID puidCatalog = 0;
  60. #ifdef _WUV3TEST
  61. // catalog spoofing
  62. auto_hkey hkey;
  63. if (NO_ERROR == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WUV3TEST, 0, KEY_READ, &hkey)) {
  64. DWORD dwPuidCatalog = 0;
  65. DWORD dwSize = sizeof(dwPuidCatalog);
  66. if (NO_ERROR == RegQueryValueEx(hkey, _T("AutoUpdateCatalog"), 0, 0, (LPBYTE)&dwPuidCatalog, &dwSize))
  67. {
  68. LOG_out("Test override to catalog %d", dwPuidCatalog);
  69. puidCatalog = dwPuidCatalog;
  70. }
  71. }
  72. // only then do normal
  73. if (0 == puidCatalog)
  74. {
  75. #endif
  76. CCatalog* pCatalogList = ProcessCatalog(0, bstrServerUrl, 0, 0, WU_ALL_ITEMS, 0);
  77. if (NULL == pCatalogList)
  78. {
  79. LOG_error("Cannot open catalog list");
  80. return E_FAIL;
  81. }
  82. for(int nCatalog = 0; nCatalog < pCatalogList->GetHeader()->totalItems; nCatalog ++)
  83. {
  84. PINVENTORY_ITEM pItem = pCatalogList->GetItem(nCatalog);
  85. if (NULL == pItem)
  86. {
  87. continue;
  88. }
  89. if (pItem->ps->state != WU_ITEM_STATE_PRUNED && (pItem->pf->d.flags & dwType))
  90. {
  91. puidCatalog = pItem->pf->d.puid;
  92. LOG_out("Found AutoUpdate catalog %d", puidCatalog);
  93. break;
  94. }
  95. }
  96. #ifdef _WUV3TEST
  97. }
  98. #endif
  99. if (0 == puidCatalog)
  100. {
  101. LOG_error("Can't find AU catalog puid");
  102. return E_FAIL;
  103. }
  104. m_pCatalogAU = ProcessCatalog(puidCatalog, bstrServerUrl, 0, 0, WU_ALL_ITEMS, 0);
  105. if (NULL == m_pCatalogAU)
  106. {
  107. LOG_error("Cannot open catalog");
  108. return E_FAIL;
  109. }
  110. ReadHiddenPuids();
  111. // download common images and other files
  112. if (fGoOnline)
  113. {
  114. TCHAR szRtfDir[MAX_PATH];
  115. GetWindowsUpdateDirectory(szRtfDir);
  116. PathAppend(szRtfDir, _T("RTF"));
  117. V3_CreateDirectory(szRtfDir);
  118. (void)DownloadCommonRTFFiles(FALSE, NULL);
  119. }
  120. }
  121. catch(HRESULT hr)
  122. {
  123. LOG_error("error %08X", hr);
  124. return hr;
  125. }
  126. return S_OK;
  127. }
  128. // find auto-update catalog and get all puids in dependency order
  129. STDMETHODIMP CCV3::GetPuidsList(LONG* pcnPuids, PUID** ppPuids)
  130. {
  131. LOG_block("CCV3::GetPuidsList");
  132. HRESULT hrRet = S_OK;
  133. try
  134. {
  135. // Builds correct dependency array
  136. Varray<DEPENDPUID> vFinalList;
  137. int cFinalList = 0;
  138. ProcessInstallList(vFinalList, cFinalList);
  139. if (0 == cFinalList)
  140. return E_INVALIDARG;
  141. //output it
  142. m_apuids.resize(cFinalList);
  143. PUID* pPuids = m_apuids;
  144. for (int nPuid = 0; nPuid < cFinalList; nPuid++)
  145. pPuids[nPuid] = vFinalList[nPuid].puid;
  146. *pcnPuids = m_apuids.size();
  147. *ppPuids = m_apuids;
  148. }
  149. catch(HRESULT hr)
  150. {
  151. LOG_error("error %08X", hr);
  152. hrRet = hr;
  153. }
  154. return hrRet;
  155. }
  156. static void UrlAppend(LPTSTR pszURL, LPCTSTR pszPath)
  157. {
  158. if (_T('/') != pszURL[lstrlen(pszURL) - 1])
  159. lstrcat(pszURL, _T("/"));
  160. lstrcat(pszURL, pszPath);
  161. }
  162. STDMETHODIMP CCV3::QueryDownloadFiles(long puid, void* pCallbackParam, PFN_QueryDownloadFilesCallback pCallback)
  163. {
  164. LOG_block("CCV3::QueryDownloadFiles");
  165. LOG_out("puid %d", puid);
  166. try
  167. {
  168. USES_CONVERSION;
  169. PINVENTORY_ITEM pItem;
  170. if (!g_v3state.GetCatalogAndItem(puid, &pItem, NULL))
  171. return E_INVALIDARG;
  172. // Buffers that we will use
  173. TCHAR szURL[INTERNET_MAX_URL_LENGTH];
  174. TCHAR szLocalFile[MAX_PATH];
  175. // CIF
  176. if (pItem->recordType == WU_TYPE_ACTIVE_SETUP_RECORD)
  177. {
  178. PWU_VARIABLE_FIELD pvCif = pItem->pd->pv->Find(WU_DESC_CIF_CRC);
  179. if (NULL == pvCif)
  180. return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  181. TCHAR szCifBaseName[16];
  182. wsprintf(szCifBaseName, _T("%d.cif"), puid);
  183. TCHAR szCifCRCName[64];
  184. HRESULT hr = MakeCRCName(szCifBaseName, (WUCRC_HASH*)pvCif->pData, szCifCRCName, sizeof(szCifCRCName));
  185. if (FAILED(hr))
  186. return hr;
  187. GetWindowsUpdateDirectory(szLocalFile);
  188. PathAppend(szLocalFile, szCifBaseName);
  189. lstrcpy(szURL, g_v3state.GetRootServer());
  190. UrlAppend(szURL, _T("CRCCif"));
  191. UrlAppend(szURL, szCifCRCName);
  192. pCallback(pCallbackParam, puid, T2W(szURL), T2W(szLocalFile));
  193. }
  194. // read this first pages
  195. PWU_VARIABLE_FIELD pvRTFCRC = pItem->pd->pv->Find(WU_DESC_RTF_CRC_ARRAY);
  196. if (pvRTFCRC != NULL)
  197. {
  198. PWU_VARIABLE_FIELD pvRTFImages = pItem->pd->pv->Find(WU_DESC_RTF_IMAGES);
  199. // build a multisz string of file names
  200. BYTE mszFileNames[512];
  201. int iLen = sprintf((char*)mszFileNames, "%d.htm", pItem->GetPuid());
  202. mszFileNames[++iLen] = '\0';
  203. if (pvRTFImages != NULL)
  204. {
  205. // we have images
  206. memcpy(mszFileNames + iLen, pvRTFImages->pData, pvRTFImages->len - 4);
  207. }
  208. // local directory
  209. TCHAR szLocalDir[MAX_PATH];
  210. GetWindowsUpdateDirectory(szLocalDir);
  211. wsprintf(szLocalFile, _T("RTF\\%d"), pItem->GetPuid()); // reuse szLocalFile as a temp buffer
  212. PathAppend(szLocalDir, szLocalFile);
  213. for(int iFileNo = 0; true; iFileNo++)
  214. {
  215. TCHAR szLocalName[128];
  216. TCHAR szServerName[128];
  217. if (FAILED(GetCRCNameFromList(iFileNo, mszFileNames, pvRTFCRC->pData, szServerName, sizeof(szServerName), szLocalName)))
  218. {
  219. // end of the list
  220. break;
  221. }
  222. // build full paths
  223. lstrcpy(szLocalFile, szLocalDir);
  224. PathAppend(szLocalFile, szLocalName);
  225. lstrcpy(szURL, g_v3state.GetRootServer());
  226. UrlAppend(szURL, _T("CRCRtf"));
  227. UrlAppend(szURL, szServerName);
  228. LOG_out("%s - %s", szURL, szLocalFile);
  229. pCallback(pCallbackParam, puid, T2W(szURL), T2W(szLocalFile));
  230. } // for
  231. }
  232. // Cabs
  233. TCHAR szLocalDir[MAX_PATH];
  234. GetWindowsUpdateDirectory(szLocalDir);
  235. wsprintf(szLocalFile, _T("Cabs\\%d"), puid); // reuse szLocalFile as a temp buffer
  236. PathAppend(szLocalDir, szLocalFile);
  237. //See if the package has a server override defined.
  238. PWU_VARIABLE_FIELD pvServer = pItem->pd->pv->Find(WU_DESCRIPTION_SERVERROOT);
  239. LPCTSTR pszCabPoolServer = pvServer ? A2T((LPSTR)(pvServer->pData)) : g_v3state.GetCabPoolServer();
  240. PWU_VARIABLE_FIELD pvCabs = pItem->pd->pv->Find(WU_DESCRIPTION_CABFILENAME);
  241. PWU_VARIABLE_FIELD pvCRCs = pItem->pd->pv->Find(WU_DESC_CRC_ARRAY);
  242. if (NULL == pvCabs || NULL == pvCRCs)
  243. {
  244. // Active setup items can have no cabs
  245. if( pItem->recordType != WU_TYPE_ACTIVE_SETUP_RECORD)
  246. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  247. }
  248. else
  249. {
  250. for(int iCabNo = 0; true; iCabNo++)
  251. {
  252. TCHAR szLocalCab[128];
  253. TCHAR szServerCab[128];
  254. if (FAILED(GetCRCNameFromList(iCabNo, pvCabs->pData, pvCRCs->pData, szServerCab, sizeof(szServerCab) , szLocalCab)))
  255. break;
  256. PathCombine(szLocalFile, szLocalDir, szLocalCab);
  257. lstrcpy(szURL, pszCabPoolServer);
  258. UrlAppend(szURL, _T("CabPool"));
  259. UrlAppend(szURL, szServerCab);
  260. LOG_out("%s - %s", szURL, szLocalFile);
  261. pCallback(pCallbackParam, puid, T2W(szURL), T2W(szLocalFile));
  262. }
  263. }
  264. }
  265. catch (HRESULT hr)
  266. {
  267. LOG_error("error %08X", hr);
  268. return hr;
  269. }
  270. return S_OK;
  271. }
  272. STDMETHODIMP CCV3::GetCatalogArray(VARIANT *pCatalogArray)
  273. {
  274. LOG_block("CCV3::GetCatalogArray");
  275. try
  276. {
  277. return MakeReturnCatalogArray(m_pCatalogAU, WU_UPDATE_ITEMS, 0, pCatalogArray);
  278. }
  279. catch (HRESULT hr)
  280. {
  281. LOG_error("error %08X", hr);
  282. return hr;
  283. }
  284. return S_OK;
  285. }
  286. STDMETHODIMP CCV3::SelectAllPuids()
  287. {
  288. LOG_block("CCV3::SelectAllPuids");
  289. try
  290. {
  291. for(int nItem = 0; nItem < m_pCatalogAU->GetHeader()->totalItems; nItem ++)
  292. {
  293. PINVENTORY_ITEM pItem = m_pCatalogAU->GetItem(nItem);
  294. if (NULL == pItem)
  295. {
  296. continue;
  297. }
  298. if (! pItem->ps->bHidden && (
  299. WU_TYPE_ACTIVE_SETUP_RECORD == pItem->recordType ||
  300. WU_TYPE_CDM_RECORD == pItem->recordType ||
  301. WU_TYPE_RECORD_TYPE_PRINTER == pItem->recordType
  302. ) && (
  303. WU_ITEM_STATE_INSTALL == pItem->ps->state ||
  304. WU_ITEM_STATE_UPDATE == pItem->ps->state
  305. )) {
  306. PUID puid = (WU_TYPE_ACTIVE_SETUP_RECORD == pItem->recordType) ? pItem->pf->a.puid : pItem->pf->d.puid;
  307. if (!IsPuidHidden(puid))
  308. g_v3state.m_selectedItems.Select(puid, TRUE);
  309. }
  310. }
  311. }
  312. catch (HRESULT hr)
  313. {
  314. LOG_error("error %08X", hr);
  315. return hr;
  316. }
  317. return S_OK;
  318. }
  319. STDMETHODIMP CCV3::UnselectAllPuids()
  320. {
  321. LOG_block("CCV3::UnselectAllPuids");
  322. try
  323. {
  324. g_v3state.m_selectedItems.Clear();
  325. }
  326. catch (HRESULT hr)
  327. {
  328. LOG_error("error %08X", hr);
  329. return hr;
  330. }
  331. return S_OK;
  332. }
  333. STDMETHODIMP CCV3::SelectPuid(long puid)
  334. {
  335. LOG_block("CCV3::SelectPuid");
  336. try
  337. {
  338. if (IsPuidHidden(puid))
  339. throw E_INVALIDARG;
  340. g_v3state.m_selectedItems.Select(puid, TRUE);
  341. }
  342. catch (HRESULT hr)
  343. {
  344. LOG_error("error %08X", hr);
  345. return hr;
  346. }
  347. return S_OK;
  348. }
  349. STDMETHODIMP CCV3::UnselectPuid(long puid)
  350. {
  351. LOG_block("CCV3::UnselectPuid");
  352. try
  353. {
  354. if (IsPuidHidden(puid))
  355. throw E_INVALIDARG;
  356. g_v3state.m_selectedItems.Unselect(puid);
  357. }
  358. catch (HRESULT hr)
  359. {
  360. LOG_error("error %08X", hr);
  361. return hr;
  362. }
  363. return S_OK;
  364. }
  365. static void RemoveFiles(long puid, bool fCif)
  366. {
  367. TCHAR szBaseName[16];
  368. TCHAR szLocalFile[MAX_PATH];
  369. if (fCif)
  370. {
  371. wsprintf(szBaseName, _T("%d.cif"), puid);
  372. GetWindowsUpdateDirectory(szLocalFile);
  373. PathAppend(szLocalFile, szBaseName);
  374. DeleteFile(szLocalFile);
  375. }
  376. wsprintf(szBaseName, _T("Cabs\\%d"), puid);
  377. GetWindowsUpdateDirectory(szLocalFile);
  378. PathAppend(szLocalFile, szBaseName);
  379. DeleteNode(szLocalFile);
  380. wsprintf(szBaseName, _T("RTF\\%d"), puid);
  381. GetWindowsUpdateDirectory(szLocalFile);
  382. PathAppend(szLocalFile, szBaseName);
  383. DeleteNode(szLocalFile);
  384. }
  385. STDMETHODIMP CCV3::HidePuid(long puid)
  386. {
  387. LOG_block("CCV3::HidePuid");
  388. try
  389. {
  390. PINVENTORY_ITEM pItem;
  391. if (!g_v3state.GetCatalogAndItem(puid, &pItem, NULL))
  392. return E_INVALIDARG;
  393. // Hide it in catalog
  394. pItem->ps->bHidden = TRUE;
  395. pItem->ps->dwReason = WU_STATE_REASON_BACKEND;
  396. // Unselect it
  397. g_v3state.m_selectedItems.Unselect(puid);
  398. HidePuidAndSave(puid);
  399. RemoveFiles(puid, pItem->recordType == WU_TYPE_ACTIVE_SETUP_RECORD);
  400. }
  401. catch (HRESULT hr)
  402. {
  403. LOG_error("error %08X", hr);
  404. return hr;
  405. }
  406. return S_OK;
  407. }
  408. STDMETHODIMP CCV3::InstallSelectedPuids(void* pCallbackParam, PFN_InstallCallback pCallback)
  409. {
  410. LOG_block("CCV3::InstallSelectedPuids");
  411. try
  412. {
  413. // Builds correct dependency array
  414. Varray<DEPENDPUID> vFinalList;
  415. int cFinalList = 0;
  416. ProcessInstallList(vFinalList, cFinalList);
  417. //output it
  418. for (int nPuid = 0; nPuid < cFinalList; nPuid++)
  419. {
  420. PINVENTORY_ITEM pItem;
  421. if (!g_v3state.GetCatalogAndItem(vFinalList[nPuid].puid, &pItem, NULL))
  422. throw E_FAIL;
  423. SELECTITEMINFO info;
  424. info.bInstall = TRUE;
  425. info.puid = vFinalList[nPuid].puid;
  426. info.iStatus = ITEM_STATUS_SUCCESS;
  427. info.hrError = S_OK;
  428. InstallItemAU(pItem, &info);
  429. LOG_out("%d status %d error %d(%08X)\n", info.puid, info.iStatus, info.hrError, info.hrError);
  430. pCallback(pCallbackParam, info.puid, info.iStatus, info.hrError);
  431. }
  432. }
  433. catch(HRESULT hr)
  434. {
  435. LOG_error("error %08X", hr);
  436. return hr;
  437. }
  438. return S_OK;
  439. }
  440. STDMETHODIMP CCV3::CleanupCabsAndReadThis(void)
  441. {
  442. LOG_block("CCV3::CleanupCabsAndReadThis");
  443. TCHAR szCabDir[MAX_PATH];
  444. GetWindowsUpdateDirectory(szCabDir);
  445. PathAppend(szCabDir, _T("Cabs"));
  446. DeleteNode(szCabDir);
  447. CleanupReadThis();
  448. return S_OK;
  449. }
  450. STDMETHODIMP CCV3::UnhideAllPuids(void)
  451. {
  452. LOG_block("CCV3::CleanupCabsAndReadThis");
  453. RegDeleteKey(HKEY_LOCAL_MACHINE, REGISTRYHIDING_KEY);
  454. return S_OK;
  455. }
  456. STDMETHODIMP CCV3::StatusReport(long puid, LPCSTR pszStatus)
  457. {
  458. LOG_block("CCV3::StatusReport");
  459. try
  460. {
  461. PINVENTORY_ITEM pItem;
  462. if (!g_v3state.GetCatalogAndItem(puid, &pItem, NULL))
  463. {
  464. LOG_error("invalid arg");
  465. return E_INVALIDARG;
  466. }
  467. CWUDownload dl(g_v3state.GetIdentServer(), 8192);
  468. // build the URL with parameters
  469. TCHAR szURL[INTERNET_MAX_PATH_LENGTH];
  470. wsprintf(szURL, _T("wutrack.bin?PUID=%d&PLAT=%d&LOCALE=%s&STATUS=%s&RID=%4.4x%4.4x"),
  471. pItem->GetPuid(),
  472. m_pCatalogAU->GetPlatform(),
  473. m_pCatalogAU->GetMachineLocaleSZ(),
  474. pszStatus,
  475. rand(),
  476. rand());
  477. // ping the URL and receive the response in memory
  478. PVOID pMemBuf;
  479. ULONG ulMemSize;
  480. if (dl.QCopy(szURL, &pMemBuf, &ulMemSize))
  481. {
  482. // we don't care about the response so we just free it
  483. LOG_error("%s", szURL);
  484. V3_free(pMemBuf);
  485. }
  486. else
  487. {
  488. LOG_out("%s", szURL);
  489. }
  490. }
  491. catch (HRESULT hr)
  492. {
  493. LOG_error("error %08X", hr);
  494. }
  495. return S_OK;
  496. }
  497. STDMETHODIMP CCV3::DownloadReadThisPage(long puid)
  498. {
  499. LOG_block("CCV3::DownloadReadThisPage");
  500. LOG_out("puid = %d", puid);
  501. try
  502. {
  503. PINVENTORY_ITEM pItem;
  504. if (!g_v3state.GetCatalogAndItem(puid, &pItem, NULL))
  505. {
  506. LOG_error("no item");
  507. return E_INVALIDARG;
  508. }
  509. return DownloadReadThis(pItem);
  510. }
  511. catch (HRESULT hr)
  512. {
  513. LOG_error("error %08X", hr);
  514. return hr;
  515. }
  516. return S_OK;
  517. }
  518. void CCV3::InstallItemAU(PINVENTORY_ITEM pItem, PSELECTITEMINFO pinfo)
  519. {
  520. LOG_block("CCV3::InstallItemAU");
  521. try
  522. {
  523. GetCurTime(&(pinfo->stDateTime));
  524. CDiamond diamond;
  525. // local directory
  526. TCHAR szLocalDir[MAX_PATH];
  527. GetWindowsUpdateDirectory(szLocalDir);
  528. TCHAR szTmp[40];
  529. wsprintf(szTmp, _T("Cabs\\%d"), pinfo->puid);
  530. PathAppend(szLocalDir, szTmp);
  531. // Decompress cab files
  532. PWU_VARIABLE_FIELD pvCabs = pItem->pd->pv->Find(WU_DESCRIPTION_CABFILENAME);
  533. PWU_VARIABLE_FIELD pvCRCs = pItem->pd->pv->Find(WU_DESC_CRC_ARRAY);
  534. if (NULL != pvCabs && NULL != pvCRCs)
  535. {
  536. for(int iCabNo = 0; true; iCabNo++)
  537. {
  538. TCHAR szLocalCab[128];
  539. TCHAR szLocalFile[MAX_PATH]; // we don't care about server file name
  540. if (FAILED(GetCRCNameFromList(iCabNo, pvCabs->pData, pvCRCs->pData, szLocalFile, sizeof(szLocalFile), szLocalCab)))
  541. break;
  542. PathCombine(szLocalFile, szLocalDir, szLocalCab);
  543. // check signature of the download CAB file
  544. // Don't show MS cert.
  545. // use the VerifyFile function (see WU bug # 12251)
  546. HRESULT hr = VerifyFile(szLocalFile, FALSE);
  547. if (FAILED(hr))
  548. throw hr;
  549. if( pItem->recordType != WU_TYPE_ACTIVE_SETUP_RECORD && diamond.IsValidCAB(szLocalFile))
  550. diamond.Decompress(szLocalFile, _T("*"));
  551. }
  552. }
  553. switch (pItem->recordType)
  554. {
  555. case WU_TYPE_ACTIVE_SETUP_RECORD:
  556. {
  557. TCHAR szCIFFile[MAX_PATH];
  558. TCHAR szCifBaseName[16];
  559. wsprintf(szCifBaseName, _T("%d.cif"), pItem->GetPuid());
  560. GetWindowsUpdateDirectory(szCIFFile);
  561. PathAppend(szCIFFile, szCifBaseName);
  562. // Decompress if we need to
  563. if (diamond.IsValidCAB(szCIFFile))
  564. {
  565. TCHAR szTmpCif[MAX_PATH];
  566. lstrcpy(szTmpCif, szCIFFile);
  567. lstrcpy(szTmpCif, _T(".cab"));
  568. MoveFile(szCIFFile, szTmpCif);
  569. diamond.Decompress(szTmpCif, szCIFFile);
  570. DeleteFile(szTmpCif);
  571. }
  572. LOG_out("calling InstallActiveSetupItem(szLocalDir=%s, szCIFFile=%s) for puid %d", szLocalDir, szCIFFile, pinfo->puid);
  573. InstallActiveSetupItem(szLocalDir, szCIFFile, pinfo, NULL);
  574. }
  575. break;
  576. case WU_TYPE_CDM_RECORD:
  577. LOG_out("calling InstallDriverItem(szLocalDir=%s) for puid %d", szLocalDir, pinfo->puid);
  578. InstallDriverItem(szLocalDir, IsWindowsNT(), _T(""), pItem, pinfo);
  579. break;
  580. case WU_TYPE_RECORD_TYPE_PRINTER:
  581. {
  582. PWU_VARIABLE_FIELD pvDriverName = pItem->pv->Find(WU_CDM_DRIVER_NAME);
  583. PWU_VARIABLE_FIELD pvArchitecture = pItem->pv->Find(WU_CDM_PRINTER_DRIVER_ARCH);
  584. if (NULL == pvDriverName || NULL == pvArchitecture)
  585. throw E_UNEXPECTED; // should never happen
  586. LOG_out("calling InstallPrinterItem(szDriverName=%s, szLocalDir=%s) for puid %d", (LPCTSTR)pvDriverName->pData, szLocalDir, pinfo->puid);
  587. InstallPrinterItem((LPCTSTR)pvDriverName->pData, szLocalDir, (LPCTSTR)pvArchitecture->pData);
  588. }
  589. break;
  590. case WU_TYPE_CDM_RECORD_PLACE_HOLDER:
  591. case WU_TYPE_SECTION_RECORD:
  592. case WU_TYPE_SUBSECTION_RECORD:
  593. case WU_TYPE_SUBSUBSECTION_RECORD:
  594. default:
  595. LOG_error(" cannot install recordtype %d for puid %d", pItem->recordType, pinfo->puid);
  596. throw E_UNEXPECTED;
  597. }
  598. }
  599. catch(HRESULT hr)
  600. {
  601. pinfo->iStatus = ITEM_STATUS_FAILED;
  602. pinfo->hrError = hr;
  603. }
  604. // Cleanup
  605. RemoveFiles(pItem->GetPuid(), pItem->recordType == WU_TYPE_ACTIVE_SETUP_RECORD);
  606. UpdateInstallHistory(pinfo, 1);
  607. }
  608. void CCV3::ReadHiddenPuids()
  609. {
  610. auto_hkey hKey;
  611. if (NO_ERROR == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRYHIDING_KEY, 0, KEY_READ, &hKey))
  612. {
  613. DWORD dwSize;
  614. if (
  615. NO_ERROR == RegQueryValueEx(hKey, _T("AutoUpdateItems"), NULL, NULL, NULL, &dwSize)
  616. && dwSize > 0
  617. ) {
  618. m_abHiddenPuids.resize(dwSize);
  619. if (NO_ERROR != RegQueryValueEx(hKey, _T("AutoUpdateItems"), NULL, NULL, m_abHiddenPuids, &dwSize))
  620. m_abHiddenPuids.resize(0);
  621. }
  622. }
  623. PUID* ppuidHidden =(PUID*)(LPBYTE)m_abHiddenPuids;
  624. for(int nOffset = 0; nOffset < m_abHiddenPuids.size(); nOffset += sizeof(PUID))
  625. {
  626. PINVENTORY_ITEM pItem;
  627. if (g_v3state.GetCatalogAndItem(*ppuidHidden, &pItem, NULL))
  628. {
  629. // Hide it in catalog
  630. pItem->ps->bHidden = TRUE;
  631. pItem->ps->dwReason = WU_STATE_REASON_BACKEND;
  632. }
  633. ppuidHidden ++;
  634. }
  635. }
  636. bool CCV3::IsPuidHidden(PUID puid)
  637. {
  638. PUID* ppuidHidden =(PUID*)(LPBYTE)m_abHiddenPuids;
  639. for(int nOffset = 0; nOffset < m_abHiddenPuids.size(); nOffset += sizeof(PUID))
  640. {
  641. if (*ppuidHidden == puid)
  642. return true;
  643. ppuidHidden ++;
  644. }
  645. return false;
  646. }
  647. void CCV3::HidePuidAndSave(PUID puid)
  648. {
  649. // Bug 378289
  650. // The following block of reading the registry value and putting it into m_abHiddenPuids has been added.
  651. // This is because, in the earlier case the m_abHiddenPuids would be read the first time from the registry
  652. // and would hold on to the registry values.
  653. // Due to this it would not reflect the new changes made by the user (eg. Clear History), and would write back the old values in m_abHiddenPuids back onto the registry
  654. // By making the following change m_abHiddenPuids contains the updated registry values.
  655. m_abHiddenPuids.resize(0);
  656. auto_hkey hKey;
  657. if (NO_ERROR == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRYHIDING_KEY, 0, KEY_READ, &hKey))
  658. {
  659. DWORD dwSize;
  660. if (
  661. NO_ERROR == RegQueryValueEx(hKey, _T("AutoUpdateItems"), NULL, NULL, NULL, &dwSize)
  662. && dwSize > 0
  663. ) {
  664. m_abHiddenPuids.resize(dwSize);
  665. if (NO_ERROR != RegQueryValueEx(hKey, _T("AutoUpdateItems"), NULL, NULL, m_abHiddenPuids, &dwSize))
  666. m_abHiddenPuids.resize(0);
  667. }
  668. }
  669. if (IsPuidHidden(puid))
  670. return;
  671. int cbSize = m_abHiddenPuids.size();
  672. m_abHiddenPuids.resize(cbSize + sizeof(PUID));
  673. *(PUID*)((LPBYTE)m_abHiddenPuids + cbSize) = puid;
  674. DWORD dwDisposition;
  675. if (NO_ERROR == RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGISTRYHIDING_KEY, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition))
  676. {
  677. if (0 == m_abHiddenPuids.size())
  678. {
  679. RegDeleteValue(hKey, _T("AutoUpdateItems"));
  680. }
  681. else
  682. {
  683. RegSetValueEx(hKey, _T("AutoUpdateItems"), 0, REG_BINARY, m_abHiddenPuids, m_abHiddenPuids.size());
  684. }
  685. }
  686. }