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.

937 lines
22 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: safearr.cpp
  6. //
  7. // Purpose: Safe array creation
  8. //
  9. //=======================================================================
  10. #include "stdafx.h"
  11. #include "safearr.h"
  12. #include "speed.h"
  13. extern CState g_v3state; //defined in CV3.CPP
  14. //This function adds a record to a safe array. The format of the
  15. //record is given by the szFmt parameter and can contain either
  16. //%d or %s for NUMBER or STRING data types. This function is used
  17. //with safe arrays that are 2 dimensional.
  18. void AddSafeArrayRecord(
  19. LPVARIANT rgElems, //pointer to locked safe array
  20. int record, //record (first dimension) for which the fields are to be set.
  21. int nRcrds, //number of records in safe array
  22. LPSTR szFmt, //printf style format string that describes the order and type of the fields. Currently we support %d for NUMBER and %s for string.
  23. ... //The actual data for the records fields.
  24. )
  25. {
  26. va_list marker;
  27. char ch;
  28. char *ptr;
  29. int iField;
  30. USES_CONVERSION;
  31. //Initialize variable arguments.
  32. va_start(marker, szFmt);
  33. iField = record;
  34. while( ch = *szFmt++ )
  35. {
  36. if ( ch != '%' )
  37. continue;
  38. if ( *szFmt == 'd' || *szFmt == 'D' )
  39. {
  40. rgElems[iField].vt = VT_I4;
  41. rgElems[iField].lVal = va_arg( marker, int);
  42. iField += nRcrds;
  43. continue;
  44. }
  45. if ( *szFmt == 's' || *szFmt == 'S' )
  46. {
  47. PWSTR wptr = va_arg( marker, PWSTR);
  48. PCWSTR waptr;
  49. // this macro will allocate stack space for an aligned
  50. // copy of the string (if it's unaligned) We'll allocate
  51. // room on the stack for each unaligned string parameter,
  52. // which may be problematic if we ever call this function
  53. // with lots of string arguments
  54. waptr = wptr;
  55. if (waptr)
  56. {
  57. WSTR_ALIGNED_STACK_COPY(&waptr, wptr);
  58. }
  59. rgElems[iField].vt = VT_BSTR;
  60. rgElems[iField].bstrVal = ( waptr ) ? ::SysAllocString(waptr) : NULL;
  61. iField += nRcrds;
  62. continue;
  63. }
  64. }
  65. //Reset variable arguments.
  66. va_end( marker );
  67. return;
  68. }
  69. //This function cleans up the memory allocated by the AddSafeArrayRecord
  70. //function. The szFmt parameter needs to match the szFmt parameter passed
  71. //to the AddSafeArrayRecord function. This function is only called needed
  72. //if an error occurs during the construction of the safe array. Otherwise
  73. //the memory for array will belong to the IE VBscript engine.
  74. void DeleteSafeArrayRecord(
  75. LPVARIANT rgElems, //locked pointer to safe array data
  76. int record, //record index to delete
  77. int nRcrds, //number for records (dim 1) in safearray
  78. LPSTR szFmt //printf style format string that describes the order and type of the fields. Currently we support %d for NUMBER and %s for string.
  79. )
  80. {
  81. char ch;
  82. int iField;
  83. iField = record;
  84. while( ch = *szFmt++ )
  85. {
  86. if ( ch != '%' )
  87. continue;
  88. if ( *szFmt == 'd' || *szFmt == 'D' )
  89. {
  90. iField += nRcrds;
  91. continue;
  92. }
  93. if ( *szFmt == 's' || *szFmt == 'S' )
  94. {
  95. VariantClear(&rgElems[iField]);
  96. iField += nRcrds;
  97. continue;
  98. }
  99. }
  100. return;
  101. }
  102. //This function converts our internal V3 item structure into a safearray of variants
  103. //that the VBScript web page uses. The format of the safe array will be:
  104. //array(0) = NUMBER puid
  105. //array(1) = STRING TITLE
  106. //array(2) = STRING Description
  107. //array(3) = NUMBER Item Status
  108. //array(4) = NUMBER Download Size in Bytes
  109. //array(5) = NUMBER Download Time in minutes
  110. //array(6) = STRING Uninstall Key
  111. //array(7) = STRING Read This Url
  112. HRESULT MakeReturnItemArray(
  113. PINVENTORY_ITEM pItem, //Item to copy to returned safe array.
  114. VARIANT *pvaVariant //pointer to returned safe array.
  115. )
  116. {
  117. USES_CONVERSION;
  118. HRESULT hr = NOERROR;
  119. LPVARIANT rgElems;
  120. LPSAFEARRAY psa;
  121. SAFEARRAYBOUND rgsabound;
  122. if (!pvaVariant || !pItem)
  123. {
  124. return E_INVALIDARG;
  125. }
  126. VariantInit(pvaVariant);
  127. rgsabound.lLbound = 0;
  128. rgsabound.cElements = 8;
  129. psa = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);
  130. if ( !psa )
  131. return E_OUTOFMEMORY;
  132. //Plug references to the data into the SAFEARRAY
  133. if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&rgElems)))
  134. return hr;
  135. PUID puid;
  136. pItem->GetFixedFieldInfo(WU_ITEM_PUID, (PVOID)&puid);
  137. PWU_VARIABLE_FIELD pvTitle = pItem->pd->pv->Find(WU_DESCRIPTION_TITLE);
  138. PWU_VARIABLE_FIELD pvDescription = pItem->pd->pv->Find(WU_DESCRIPTION_DESCRIPTION);
  139. PWU_VARIABLE_FIELD pvUninstall = pItem->pd->pv->Find(WU_DESCRIPTION_UNINSTALL_KEY);
  140. PWU_VARIABLE_FIELD pvReadThisUrl = pItem->pd->pv->Find(WU_DESCRIPTION_READTHIS_URL);
  141. try
  142. {
  143. AddSafeArrayRecord(rgElems, 0, (int)1,
  144. "%d%s%s%d%d%d%s%s",
  145. puid,
  146. pvTitle ? (PWSTR)pvTitle->pData : NULL,
  147. pvDescription ? (PWSTR)pvDescription->pData : NULL,
  148. GetItemReturnStatus(pItem),
  149. pItem->pd->size,
  150. CalcDownloadTime(pItem->pd->size, pItem->pd->downloadTime),
  151. pvUninstall ? A2W((char*)pvUninstall->pData) : NULL,
  152. pvReadThisUrl ? A2W((char*)pvReadThisUrl->pData) : NULL);
  153. }
  154. catch(HRESULT hr)
  155. {
  156. DeleteSafeArrayRecord(rgElems, 0, (int)rgsabound.cElements, "%d%s%s%d%d%d%s%s");
  157. SafeArrayUnaccessData(psa);
  158. VariantInit(pvaVariant);
  159. throw hr;
  160. }
  161. SafeArrayUnaccessData(psa);
  162. V_VT(pvaVariant) = VT_ARRAY | VT_VARIANT;
  163. V_ARRAY(pvaVariant) = psa;
  164. return NOERROR;
  165. }
  166. //array(0) = NUMBER puid
  167. //This function creates the dependency puid safe array.
  168. HRESULT MakeDependencyArray(
  169. Varray<DEPENDPUID>& vDepPuids,
  170. const int cDepPuids,
  171. VARIANT *pvaVariant //returned safe array pointer.
  172. )
  173. {
  174. int i;
  175. HRESULT hr;
  176. LPVARIANT rgElems;
  177. LPSAFEARRAY psa;
  178. SAFEARRAYBOUND rgsabound;
  179. if (!pvaVariant)
  180. return E_INVALIDARG;
  181. VariantInit(pvaVariant);
  182. hr = NOERROR;
  183. rgsabound.lLbound = 0;
  184. rgsabound.cElements = cDepPuids;
  185. psa = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);
  186. if (!psa)
  187. return E_OUTOFMEMORY;
  188. //Plug references to the data into the SAFEARRAY
  189. if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&rgElems)))
  190. return hr;
  191. for (i=0; i <cDepPuids; i++)
  192. {
  193. rgElems[i].vt = VT_I4;
  194. rgElems[i].lVal = vDepPuids[i].puid;
  195. }
  196. SafeArrayUnaccessData(psa);
  197. V_VT(pvaVariant) = VT_ARRAY | VT_VARIANT;
  198. V_ARRAY(pvaVariant) = psa;
  199. return NOERROR;
  200. }
  201. //This function creates the safe array that is returned to the GetInstallMetrics
  202. //array.
  203. //array(0,0) = NUMBER puid The identifier for this catalog item.
  204. //array(0,1) = NUMBER DownloadSize Total download size of all selected items in bytes.
  205. //array(0,2) = NUMBER Downloadtime Total download time for all currently selected items at 28.8 this
  206. HRESULT MakeInstallMetricArray(
  207. PSELECTITEMINFO pSelInfo, //Pointer to selected item information array.
  208. int iSelItems, //Total selected items
  209. VARIANT *pvaVariant //Pointer to returned safe array.
  210. )
  211. {
  212. HRESULT hr;
  213. LPVARIANT rgElems;
  214. LPSAFEARRAY psa;
  215. SAFEARRAYBOUND rgsabound[2];
  216. PINVENTORY_ITEM pItem = NULL;
  217. int j;
  218. int cInstallItems = 0;
  219. PSELECTITEMINFO pInfo;
  220. if ( !pvaVariant )
  221. return E_INVALIDARG;
  222. VariantInit(pvaVariant);
  223. //we have to calculate the number of items for install and not for removal
  224. pInfo = pSelInfo;
  225. for (j = 0; j < iSelItems; j++)
  226. {
  227. if (pInfo[j].bInstall)
  228. cInstallItems++;
  229. }
  230. rgsabound[0].lLbound = 0;
  231. rgsabound[0].cElements = cInstallItems;
  232. rgsabound[1].lLbound = 0;
  233. rgsabound[1].cElements = 3;
  234. psa = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
  235. if (!psa)
  236. return E_OUTOFMEMORY;
  237. //Plug references to the data into the SAFEARRAY
  238. if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&rgElems)))
  239. return hr;
  240. hr = NOERROR;
  241. //For each item in puid array get download size and time
  242. int isa = 0; //index into the safe array
  243. pInfo = pSelInfo;
  244. for (j = 0; j < iSelItems; j++)
  245. {
  246. if (!pInfo[j].bInstall)
  247. continue;
  248. //Note: we had better have only valid items here. The ChangeItemState
  249. //method is responsible for only selecting items for installation that
  250. //are valid.
  251. if ((FALSE == g_v3state.GetCatalogAndItem(pInfo[j].puid, &pItem, NULL)) || (NULL == pItem))
  252. continue;
  253. //array(0,0) = NUMBER puid
  254. //array(0,1) = NUMBER DownloadSize
  255. //array(0,2) = NUMBER Downloadtime
  256. try
  257. {
  258. AddSafeArrayRecord(rgElems, isa, (int)rgsabound[0].cElements, "%d%d%d",
  259. pInfo[j].puid, pItem->pd->size, CalcDownloadTime(pItem->pd->size, pItem->pd->downloadTime));
  260. }
  261. catch(HRESULT hr)
  262. {
  263. for (; isa; isa--)
  264. DeleteSafeArrayRecord(rgElems, isa, (int)rgsabound[0].cElements, "%d%d%d");
  265. SafeArrayUnaccessData(psa);
  266. VariantInit(pvaVariant);
  267. throw hr;
  268. }
  269. isa++;
  270. }
  271. SafeArrayUnaccessData(psa);
  272. V_VT(pvaVariant) = VT_ARRAY | VT_VARIANT;
  273. V_ARRAY(pvaVariant) = psa;
  274. return NOERROR;
  275. }
  276. //This function makes the returned eula safe array. The Eula array is
  277. //setup to be sorted by Eula.
  278. //
  279. //array(0,0) = NUMBER eula number Number of eula. This number changes when the eula
  280. // url changes. This makes it possible for the caller
  281. // to construct a list of items that this eula applies
  282. // to simply be checking when this field changes value.
  283. //array(0,1) = NUMBER puid The identifier for this catalog item.
  284. //array(0,2) = STRING url Url of eurl page to display for this item. Note: If
  285. // three items have the same url then this field is filled
  286. // in for the first item and blank for the remaining two
  287. // items.
  288. HRESULT MakeEulaArray(
  289. PSELECTITEMINFO pInfo, //Pointer to selected item information array.
  290. int iTotalItems, //Total selected items
  291. VARIANT *pvaVariant //Pointer to returned safe array.
  292. )
  293. {
  294. USES_CONVERSION;
  295. Varray<PUID> puids; //array of selected item puids.
  296. HRESULT hr;
  297. LPVARIANT rgElems;
  298. LPSAFEARRAY psa;
  299. SAFEARRAYBOUND rgsabound[2];
  300. PINVENTORY_ITEM pItem;
  301. PWU_VARIABLE_FIELD pvTmp;
  302. int i;
  303. int n;
  304. int iEulaNumber;
  305. int iEulaArrayIndex;
  306. char szLastEula[64];
  307. char szCurrEula[64];
  308. char szFullEula[MAX_PATH];
  309. BOOL bEulaChanged;
  310. CCatalog * pCatalog;
  311. if (!pvaVariant || !pInfo)
  312. return E_INVALIDARG;
  313. VariantInit(pvaVariant);
  314. hr = NOERROR;
  315. //Copy puid array so we can overwrite it
  316. for(i=0; i<iTotalItems; i++)
  317. {
  318. if (pInfo[i].bInstall)
  319. puids[i] = pInfo[i].puid;
  320. else
  321. puids[i] = WU_NO_LINK;
  322. }
  323. rgsabound[0].lLbound = 0;
  324. rgsabound[0].cElements = 0;
  325. //Count the number of eula's to return
  326. for(i=0; i<iTotalItems; i++)
  327. {
  328. if (puids[i] != WU_NO_LINK)
  329. {
  330. if (!g_v3state.GetCatalogAndItem(puids[i], &pItem, NULL))
  331. {
  332. continue;
  333. }
  334. if (pItem->pd->pv->Find(WU_DESC_EULA))
  335. rgsabound[0].cElements++;
  336. }
  337. }
  338. rgsabound[1].lLbound = 0;
  339. rgsabound[1].cElements = 3;
  340. psa = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
  341. if ( !psa )
  342. return E_OUTOFMEMORY;
  343. //Plug references to the data into the SAFEARRAY
  344. if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&rgElems)))
  345. return hr;
  346. iEulaNumber = -1;
  347. iEulaArrayIndex = 0;
  348. szLastEula[0] = '\0';
  349. for(i = 0; i < iTotalItems; i++)
  350. {
  351. //if this record has not already been processed
  352. if (puids[i] != WU_NO_LINK)
  353. {
  354. if (!g_v3state.GetCatalogAndItem(puids[i], &pItem, &pCatalog))
  355. {
  356. continue;
  357. }
  358. //if there is not a Eula for this item then continue to next item.
  359. if (!(pvTmp = pItem->pd->pv->Find(WU_DESC_EULA)))
  360. continue;
  361. //if this is the default eula (eula.htm), there'll be
  362. //no data in the field
  363. if (sizeof(WU_VARIABLE_FIELD) == pvTmp->len || !*(pvTmp->pData)) // second test is for 64-bit, since we pad this structure to fix alignment problems
  364. {
  365. strcpy(szCurrEula, "eula.htm");
  366. }
  367. else
  368. {
  369. strcpy(szCurrEula, (LPCSTR) pvTmp->pData);
  370. }
  371. bEulaChanged = (_stricmp(szLastEula, szCurrEula) != 0);
  372. if (bEulaChanged)
  373. {
  374. iEulaNumber++;
  375. strcpy(szLastEula, szCurrEula);
  376. //the actual EULA filename is of the form PLAT_LOC_fn
  377. sprintf(szFullEula, "/eula/%d_%s_%s", pCatalog->GetPlatform(), T2A(pCatalog->GetBrowserLocaleSZ()), szCurrEula);
  378. }
  379. try
  380. {
  381. AddSafeArrayRecord(rgElems, iEulaArrayIndex, (int)rgsabound[0].cElements, "%d%d%s",
  382. iEulaNumber, puids[i], bEulaChanged ? A2W(szFullEula) : L"");
  383. }
  384. catch(HRESULT hr)
  385. {
  386. // cleanup
  387. for (n = iEulaArrayIndex-1; n >= 0; n--)
  388. DeleteSafeArrayRecord(rgElems, n, (int)rgsabound[0].cElements, "%d%d%s");
  389. SafeArrayUnaccessData(psa);
  390. VariantInit(pvaVariant);
  391. throw hr;
  392. }
  393. //Set to next safe array index
  394. iEulaArrayIndex++;
  395. }
  396. }
  397. SafeArrayUnaccessData(psa);
  398. V_VT(pvaVariant) = VT_ARRAY | VT_VARIANT;
  399. V_ARRAY(pvaVariant) = psa;
  400. return NOERROR;
  401. }
  402. //This function makes the InstallStatus safe array.
  403. //array(0, 0) = NUMBER puid The identifier for this record.
  404. //array(0,1) = NUMBER Status This field is one of the following:
  405. // ITEM_STATUS_SUCCESS The package was installed successfully.
  406. // ITEM_STATUS_INSTALLED_ERROR The package was Installed however there were some minor problems that did not prevent installation.
  407. // ITEM_STATUS_FAILED The packages was not installed.
  408. //array(0,2) = NUMBER Error Error describing the reason that the package did not install if the Status field is not equal to SUCCESS.
  409. HRESULT MakeInstallStatusArray(
  410. PSELECTITEMINFO pInfo, //Pointer to selected item information.
  411. int iTotalItems, //Total selected items
  412. VARIANT *pvaVariant //Pointer to returned safe array.
  413. )
  414. {
  415. HRESULT hr;
  416. LPVARIANT rgElems;
  417. LPSAFEARRAY psa;
  418. SAFEARRAYBOUND rgsabound[2];
  419. int i;
  420. Varray<SELECTITEMINFO> vNonHidden;
  421. int cNonHidden = 0;
  422. if (!pvaVariant)
  423. return E_INVALIDARG;
  424. VariantInit(pvaVariant);
  425. //
  426. // copy the nonhidden items into a new varray. we have to make a new copy since the SELECTEDITEMS
  427. // structure does not tell us if the item is hidden. So we need to call the GetCatalogAndItem call
  428. // to get the pointer to the item and check the hidden state
  429. //
  430. for (i = 0; i < iTotalItems; i++)
  431. {
  432. PINVENTORY_ITEM pItem;
  433. if (g_v3state.GetCatalogAndItem(pInfo[i].puid, &pItem, NULL))
  434. {
  435. if (!pItem->ps->bHidden)
  436. {
  437. vNonHidden[cNonHidden] = pInfo[i];
  438. cNonHidden++;
  439. }
  440. }
  441. }
  442. rgsabound[0].lLbound = 0;
  443. rgsabound[0].cElements = cNonHidden;
  444. rgsabound[1].lLbound = 0;
  445. rgsabound[1].cElements = 3;
  446. psa = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
  447. if ( !psa )
  448. return E_OUTOFMEMORY;
  449. //Plug references to the data into the SAFEARRAY
  450. if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&rgElems)))
  451. return hr;
  452. hr = NOERROR;
  453. //For each item in puid array get download size and time
  454. for (i = 0; i < cNonHidden; i++)
  455. {
  456. // array(0,0) = NUMBER puid
  457. // array(0,1) = NUMBER Status
  458. // array(0,2) = NUMBER Error
  459. try
  460. {
  461. AddSafeArrayRecord(rgElems, i, (int)rgsabound[0].cElements, "%d%d%d",
  462. vNonHidden[i].puid, vNonHidden[i].iStatus, vNonHidden[i].hrError);
  463. }
  464. catch(HRESULT hr)
  465. {
  466. for (; i; i--)
  467. DeleteSafeArrayRecord(rgElems, i, (int)rgsabound[0].cElements, "%d%d%d");
  468. SafeArrayUnaccessData(psa);
  469. VariantInit(pvaVariant);
  470. throw hr;
  471. }
  472. }
  473. SafeArrayUnaccessData(psa);
  474. V_VT(pvaVariant) = VT_ARRAY | VT_VARIANT;
  475. V_ARRAY(pvaVariant) = psa;
  476. return NOERROR;
  477. }
  478. //This function reads and converts our internal Install History into a safe array
  479. //format for the VBScript caller.
  480. //
  481. //array(0,0) = NUMBER puid
  482. //array(0,1) = STRING date
  483. //array(0,2) = STRING time
  484. //array(0,3) = STRING item title
  485. //array(0,4) = STRING version string
  486. //array(0,5) = NUMBER flags = INSTALL_OPERATION, REMOVE_OPERATION, OPERATION_ERROR, OPERATION_SUCCESS, OPERATION_STARTED
  487. //array(0,6) = NUMBER error code if OPERATION_ERROR
  488. HRESULT MakeInstallHistoryArray(
  489. Varray<HISTORYSTRUCT> &History, //History Array
  490. int iTotalItems, //Total items in history array.
  491. VARIANT *pvaVariant //Pointer to returned safe array.
  492. )
  493. {
  494. USES_CONVERSION;
  495. DWORD dwFlags;
  496. HRESULT hr;
  497. LPVARIANT rgElems;
  498. LPSAFEARRAY psa;
  499. SAFEARRAYBOUND rgsabound[2];
  500. int i;
  501. if (!pvaVariant)
  502. return E_INVALIDARG;
  503. VariantInit(pvaVariant);
  504. rgsabound[0].lLbound = 0;
  505. rgsabound[0].cElements = iTotalItems;
  506. rgsabound[1].lLbound = 0;
  507. rgsabound[1].cElements = 7;
  508. psa = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
  509. if (!psa)
  510. return E_OUTOFMEMORY;
  511. //Plug references to the data into the SAFEARRAY
  512. if (FAILED(hr = SafeArrayAccessData(psa,(LPVOID*)&rgElems)))
  513. return hr;
  514. hr = NOERROR;
  515. //For each item in puid array get download size and time
  516. for (i = 0; i < iTotalItems; i++)
  517. {
  518. if (History[i].bV2)
  519. {
  520. // no flags for V2
  521. dwFlags = 0;
  522. }
  523. else
  524. {
  525. // flags for V3
  526. if (History[i].bInstall)
  527. {
  528. dwFlags = INSTALL_OPERATION;
  529. }
  530. else
  531. {
  532. dwFlags = REMOVE_OPERATION;
  533. }
  534. if (History[i].bResult == OPERATION_SUCCESS)
  535. {
  536. dwFlags |= OPERATION_SUCCESS;
  537. }
  538. else if (History[i].bResult == OPERATION_STARTED)
  539. {
  540. dwFlags |= OPERATION_STARTED;
  541. }
  542. else
  543. {
  544. dwFlags |= OPERATION_ERROR;
  545. }
  546. }
  547. try
  548. {
  549. AddSafeArrayRecord(rgElems, i, (int)rgsabound[0].cElements, "%d%s%s%s%s%d%d",
  550. History[i].puid, A2W(History[i].szDate), A2W(History[i].szTime), A2W(History[i].szTitle), A2W(History[i].szVersion),
  551. dwFlags, (int)History[i].hrError);
  552. }
  553. catch(HRESULT hr)
  554. {
  555. for (; i; i--)
  556. DeleteSafeArrayRecord(rgElems, i, (int)rgsabound[0].cElements, "%d%s%s%s%s%d%d");
  557. SafeArrayUnaccessData(psa);
  558. VariantInit(pvaVariant);
  559. throw hr;
  560. }
  561. }
  562. SafeArrayUnaccessData(psa);
  563. V_VT(pvaVariant) = VT_ARRAY | VT_VARIANT;
  564. V_ARRAY(pvaVariant) = psa;
  565. return NOERROR;
  566. }
  567. //This function converts the internal status for a catalog item into the formated that is
  568. //returned by GetCatalog() and GetCatalogItem() safe arrays.
  569. int GetItemReturnStatus(PINVENTORY_ITEM pItem)
  570. {
  571. int status = 0;
  572. BYTE itemFlags = 0;
  573. if (pItem->ps->bHidden)
  574. {
  575. if (pItem->ps->dwReason == WU_STATE_REASON_PERSONALIZE)
  576. status |= GETCATALOG_STATUS_PERSONALIZE_HIDDEN;
  577. else
  578. status |= GETCATALOG_STATUS_HIDDEN;
  579. }
  580. if (pItem->ps->bChecked )
  581. status |= GETCATALOG_STATUS_SELECTED;
  582. if (pItem->pd->flags & DESCRIPTION_FLAGS_NEW)
  583. status |= GETCATALOG_STATUS_NEW;
  584. if (pItem->pd->flags & DESCRIPTION_FLAGS_POWER)
  585. status |= GETCATALOG_STATUS_POWER;
  586. if (pItem->pd->flags & DESCRIPTION_FLAGS_REGISTRATION)
  587. status |= GETCATALOG_STATUS_REGISTRATION;
  588. if (pItem->pd->flags & DESCRIPTION_FLAGS_COOL)
  589. status |= GETCATALOG_STATUS_COOL;
  590. if (pItem->pd->flags & DESCRIPTION_EXCLUSIVE)
  591. status |= GETCATALOG_STATUS_EXCLUSIVE;
  592. if (pItem->pd->flags & DESCRIPTION_WARNING_SCARY)
  593. status |= GETCATALOG_STATUS_WARNING_SCARY;
  594. pItem->GetFixedFieldInfo(WU_ITEM_FLAGS, &itemFlags);
  595. if (itemFlags & WU_PATCH_ITEM_FLAG )
  596. status |= GETCATALOG_STATUS_PATCH;
  597. if (pItem->recordType == WU_TYPE_SECTION_RECORD )
  598. status |= GETCATALOG_STATUS_SECTION;
  599. else if (pItem->recordType == WU_TYPE_SUBSECTION_RECORD )
  600. status |= GETCATALOG_STATUS_SUBSECTION;
  601. else if (pItem->recordType == WU_TYPE_SUBSUBSECTION_RECORD )
  602. status |= GETCATALOG_STATUS_SUBSUBSECTION;
  603. else
  604. {
  605. //flag the current install status
  606. switch( pItem->ps->state )
  607. {
  608. case WU_ITEM_STATE_INSTALL:
  609. status |= GETCATALOG_STATUS_INSTALL;
  610. break;
  611. case WU_ITEM_STATE_UPDATE:
  612. status |= GETCATALOG_STATUS_UPDATE;
  613. break;
  614. case WU_ITEM_STATE_PRUNED:
  615. break;
  616. case WU_ITEM_STATE_CURRENT:
  617. status |= GETCATALOG_STATUS_CURRENT;
  618. break;
  619. default:
  620. status |= GETCATALOG_STATUS_UNKNOWN;
  621. break;
  622. }
  623. }
  624. return status;
  625. }
  626. int CalcDownloadTime(int size, int downloadTime)
  627. {
  628. if (size != 0)
  629. {
  630. DWORD dwBPS = CConnSpeed::BytesPerSecond();
  631. if (dwBPS != 0)
  632. {
  633. // calculate size (in KB) based on modem speed
  634. downloadTime = size * 1024 / dwBPS;
  635. }
  636. else
  637. {
  638. // time in the inventory list is in minutes, convert it to seconds
  639. downloadTime *= 60;
  640. }
  641. }
  642. else
  643. downloadTime = 0;
  644. if (downloadTime == 0)
  645. downloadTime = 1;
  646. return downloadTime;
  647. }
  648. //This function checks to see if the inventory item matches the filter specification
  649. //supplied by the user in the GetCatalog function.
  650. BOOL FilterCatalogItem(
  651. PINVENTORY_ITEM pItem, //Pointer to inventory item to be checked.
  652. long lFilters //Filter specification to check item against.
  653. )
  654. {
  655. BYTE itemFlags = 0;
  656. pItem->GetFixedFieldInfo(WU_ITEM_FLAGS, &itemFlags);
  657. //
  658. // we never return pruned items
  659. //
  660. if ( pItem->ps->state == WU_ITEM_STATE_PRUNED )
  661. return FALSE;
  662. //
  663. // BEGIN special cases with WU_ALL_ITEMS (=0)
  664. //
  665. if (lFilters == WU_ALL_ITEMS)
  666. {
  667. if (pItem->ps->bHidden)
  668. return FALSE;
  669. else
  670. return TRUE;
  671. }
  672. if ((lFilters == WU_NO_DEVICE_DRIVERS)) //WU_ALL_ITEMS | WU_NO_DEVICE_DRIVERS
  673. {
  674. if (pItem->recordType == WU_TYPE_CDM_RECORD || pItem->recordType == WU_TYPE_CDM_RECORD_PLACE_HOLDER)
  675. return FALSE;
  676. else
  677. return TRUE;
  678. }
  679. if ((lFilters == WU_PERSONALIZE_HIDDEN)) //WU_ALL_ITEMS | WU_PERSONALIZE_HIDDEN
  680. {
  681. if (pItem->ps->bHidden && pItem->ps->dwReason != WU_STATE_REASON_PERSONALIZE)
  682. return FALSE;
  683. else
  684. return TRUE;
  685. }
  686. //
  687. // END special case with WU_ALL_ITEMS
  688. //
  689. // Special case for WU_UPDATE_ITEMS (used by AutoUpdate)
  690. // This will not return sections, and will return drivers
  691. // only if there's no driver currently installed for the device
  692. if (lFilters == WU_UPDATE_ITEMS)
  693. {
  694. if (pItem->ps->bHidden)
  695. return FALSE;
  696. if (WU_TYPE_CDM_RECORD_PLACE_HOLDER == pItem->recordType)
  697. return FALSE;
  698. if ((WU_TYPE_ACTIVE_SETUP_RECORD == pItem->recordType)
  699. &&
  700. (
  701. WU_ITEM_STATE_INSTALL == pItem->ps->state ||
  702. WU_ITEM_STATE_UPDATE == pItem->ps->state
  703. ))
  704. return TRUE;
  705. if ((WU_TYPE_CDM_RECORD == pItem->recordType ||
  706. WU_TYPE_RECORD_TYPE_PRINTER == pItem->recordType)
  707. &&
  708. (
  709. WU_ITEM_STATE_INSTALL == pItem->ps->state
  710. ))
  711. return TRUE;
  712. return FALSE;
  713. }
  714. // end case for WU_UPDATE_ITEMS
  715. if ((lFilters & WU_NO_DEVICE_DRIVERS))
  716. {
  717. if (pItem->recordType == WU_TYPE_CDM_RECORD || pItem->recordType == WU_TYPE_CDM_RECORD_PLACE_HOLDER)
  718. return FALSE;
  719. }
  720. if ( (lFilters & WU_PATCH_ITEMS) && (itemFlags & WU_PATCH_ITEM_FLAG) )
  721. return TRUE;
  722. if ( (lFilters & WU_HIDDEN_ITEMS) && pItem->ps->bHidden )
  723. return TRUE;
  724. if ( (lFilters & WU_SELECTED_ITEMS) && pItem->ps->bChecked )
  725. return TRUE;
  726. if ( (lFilters & WU_NOT_SELECTED_ITEMS) && !pItem->ps->bChecked )
  727. return TRUE;
  728. if ( (lFilters & WU_NEW_ITEMS) && (pItem->pd->flags & DESCRIPTION_FLAGS_NEW) )
  729. return TRUE;
  730. if ( (lFilters & WU_POWER_ITEMS) && (pItem->pd->flags & DESCRIPTION_FLAGS_POWER) )
  731. return TRUE;
  732. if ( (lFilters & WU_REGISTER_ITEMS) && (pItem->pd->flags & DESCRIPTION_FLAGS_REGISTRATION) )
  733. return TRUE;
  734. if ( (lFilters & WU_COOL_ITEMS) && (pItem->pd->flags & DESCRIPTION_FLAGS_COOL) )
  735. return TRUE;
  736. if ( (lFilters & WU_EUAL_ITEMS) && pItem->pd->pv->Find(WU_DESC_EULA) )
  737. return TRUE;
  738. if ( (lFilters & WU_PATCH_ITEMS) && (itemFlags & WU_CRITICAL_UPDATE_ITEM_FLAG) )
  739. return TRUE;
  740. return FALSE;
  741. }