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.

1706 lines
52 KiB

  1. //
  2. // Author: DebiM/UShaji
  3. // Date: Jan 97 - Apr 98
  4. //
  5. // Class Store Query and Fetch Implementation
  6. //
  7. //
  8. //---------------------------------------------------------------------
  9. //
  10. #include "cstore.hxx"
  11. //
  12. // List of Attributes for On-Demand Package Lookup Query
  13. //
  14. LPOLESTR pszInstallInfoAttrNames[] =
  15. {
  16. PKGFILEEXTNLIST, LOCALEID, ARCHLIST, PACKAGEFLAGS, SCRIPTPATH, PKGCLSIDLIST,
  17. PACKAGETYPE, PKGUSN, VERSIONHI, VERSIONLO, UPGRADESPACKAGES, UILEVEL,
  18. PACKAGENAME, HELPURL, PUBLISHER, REVISION, PRODUCTCODE, OBJECTDN,
  19. OBJECTGUID
  20. };
  21. DWORD cInstallInfoAttr = 19;
  22. //
  23. // List of Attributes for Enumeration of Packages (with Filters)
  24. //
  25. LPOLESTR pszPackageInfoAttrNames[] =
  26. {
  27. PACKAGEFLAGS, PACKAGETYPE, SCRIPTPATH, SCRIPTSIZE, PKGUSN, LOCALEID, ARCHLIST,
  28. PACKAGENAME, VERSIONHI, VERSIONLO, UPGRADESPACKAGES, UILEVEL, PUBLISHER, HELPURL,
  29. REVISION, PRODUCTCODE, OBJECTGUID, OBJECTDN
  30. };
  31. DWORD cPackageInfoAttr = 18;
  32. //
  33. // List of Attributes for GetPackageDetail() method
  34. //
  35. LPOLESTR pszPackageDetailAttrNames[] =
  36. {
  37. PACKAGEFLAGS, PACKAGETYPE, SCRIPTPATH, SCRIPTSIZE, SETUPCOMMAND, HELPURL, PKGUSN,
  38. VERSIONHI, VERSIONLO, UILEVEL, UPGRADESPACKAGES, ARCHLIST, LOCALEID, PKGCLSIDLIST,
  39. PKGIIDLIST, PKGTLBIDLIST, PKGFILEEXTNLIST, PACKAGENAME, MSIFILELIST, PKGCATEGORYLIST,MVIPC,
  40. PRODUCTCODE, REVISION, OBJECTGUID
  41. };
  42. DWORD cPackageDetailAttr = 24;
  43. LPOLESTR pszDeleteAttrNames[] =
  44. {
  45. PACKAGEFLAGS, OBJECTDN
  46. };
  47. DWORD cDeleteAttr = 2;
  48. //
  49. // List of Attributes for App Categories
  50. //
  51. LPOLESTR pszCategoryAttrNames[] =
  52. {
  53. LOCALEDESCRIPTION, CATEGORYCATID
  54. };
  55. DWORD cCategoryAttr = 2;
  56. BOOL MatchPlatform(
  57. CSPLATFORM *pReqPlatform,
  58. CSPLATFORM *pPkgPlatform,
  59. BOOL fX86OnAlpha)
  60. {
  61. //
  62. // Make sure this is the correct platform
  63. //
  64. if (pReqPlatform->dwPlatformId != pPkgPlatform->dwPlatformId)
  65. {
  66. return FALSE;
  67. }
  68. //
  69. // ProcessorArch must match
  70. //
  71. if (pReqPlatform->dwProcessorArch != pPkgPlatform->dwProcessorArch)
  72. {
  73. //
  74. // If the caller didn't request x86 on alpha, inequality between
  75. // architectures is automatic disqualification
  76. //
  77. if (!fX86OnAlpha)
  78. {
  79. return FALSE;
  80. }
  81. //
  82. // Caller specified that we should allow x86 packages on alpha --
  83. // see if we are in that situation, and only disqualify the package if not
  84. //
  85. if ( ! ((PROCESSOR_ARCHITECTURE_ALPHA == pReqPlatform->dwProcessorArch) &&
  86. (PROCESSOR_ARCHITECTURE_INTEL == pPkgPlatform->dwProcessorArch)))
  87. {
  88. return FALSE;
  89. }
  90. }
  91. //
  92. // Check the OS version, hi part first -- this requested platform must be at least as
  93. // high as the package platform -- if not, it is disqualified
  94. //
  95. if (pReqPlatform->dwVersionHi < pPkgPlatform->dwVersionHi)
  96. {
  97. return FALSE;
  98. }
  99. //
  100. // If the hi version is the same, check the low part of the os version
  101. //
  102. if (pReqPlatform->dwVersionHi == pPkgPlatform->dwVersionHi)
  103. {
  104. //
  105. // If the requested platform is less than the package, it cannot
  106. // support that package, so the package is disqualified.
  107. //
  108. if (pReqPlatform->dwVersionLo < pPkgPlatform->dwVersionLo)
  109. {
  110. return FALSE;
  111. }
  112. }
  113. //
  114. // We passed all the tests -- the package matches the requested platform
  115. //
  116. return TRUE;
  117. }
  118. // this has to change if the Msi can give us a preferred list etc.
  119. DWORD PlatformWt(
  120. CSPLATFORM *pReqPlatform,
  121. CSPLATFORM *pPkgPlatform,
  122. BOOL fX86OnAlpha)
  123. {
  124. if (MatchPlatform(pReqPlatform,
  125. pPkgPlatform,
  126. fX86OnAlpha))
  127. {
  128. return PRI_ARCH_PREF1;
  129. }
  130. return 0;
  131. }
  132. DWORD ClassContextWt(DWORD ClsCtx)
  133. {
  134. if (ClsCtx & CLSCTX_INPROC_SERVER)
  135. return PRI_CLSID_INPSVR;
  136. if (ClsCtx & CLSCTX_LOCAL_SERVER)
  137. return PRI_CLSID_LCLSVR;
  138. if (ClsCtx & CLSCTX_REMOTE_SERVER)
  139. return PRI_CLSID_REMSVR;
  140. return 0;
  141. }
  142. //
  143. //
  144. void GetCurrentUsn(LPOLESTR pStoreUsn)
  145. {
  146. //
  147. // Get the current time as USN for the Class Store container
  148. //
  149. SYSTEMTIME SystemTime;
  150. GetSystemTime(&SystemTime);
  151. wsprintf (pStoreUsn, L"%04d%02d%02d%02d%02d%02d",
  152. SystemTime.wYear,
  153. SystemTime.wMonth,
  154. SystemTime.wDay,
  155. SystemTime.wHour,
  156. SystemTime.wMinute,
  157. SystemTime.wSecond);
  158. }
  159. void TimeToUsn (LPOLESTR szTimeStamp, CSUSN *pUsn)
  160. {
  161. SYSTEMTIME SystemTime;
  162. if (szTimeStamp)
  163. {
  164. CSDBGPrint((L"szTimeStamp = %s", szTimeStamp));
  165. UINT l = wcslen(szTimeStamp) - 1;
  166. LPOLESTR pStr = szTimeStamp;
  167. for (UINT i=0; i < l; ++i)
  168. {
  169. if (*pStr == L' ')
  170. *pStr = L'0';
  171. ++pStr;
  172. }
  173. swscanf (szTimeStamp, L"%4d%2d%2d%2d%2d%2d",
  174. &SystemTime.wYear,
  175. &SystemTime.wMonth,
  176. &SystemTime.wDay,
  177. &SystemTime.wHour,
  178. &SystemTime.wMinute,
  179. &SystemTime.wSecond);
  180. SystemTimeToFileTime(&SystemTime, (LPFILETIME) pUsn);
  181. }
  182. else
  183. pUsn->dwHighDateTime = pUsn->dwLowDateTime = 0;
  184. }
  185. HRESULT UsnGet(ADS_ATTR_INFO Attr, CSUSN *pUsn)
  186. {
  187. //
  188. // Read the USN for the Class Store container or Package
  189. //
  190. WCHAR *szTimeStamp=NULL;
  191. UnpackStrFrom(Attr, &szTimeStamp);
  192. TimeToUsn (szTimeStamp, pUsn);
  193. return S_OK;
  194. }
  195. // FetchInstallData
  196. //-----------------
  197. //
  198. //
  199. // Gets the result set of the ondemand lookup query to locate an install package.
  200. // Returns the properties of the most likely Package in PackageInfo structure.
  201. //
  202. // In case more than one package meets the criteria, their priorities are returned.
  203. // BUGBUG:: In case of E_OUTOFMEMORY in Unpack, we return the packages
  204. // that we have already got.
  205. HRESULT FetchInstallData(HANDLE hADs,
  206. ADS_SEARCH_HANDLE hADsSearchHandle,
  207. QUERYCONTEXT *pQryContext,
  208. uCLSSPEC *pclsspec,
  209. LPOLESTR pszFileExt,
  210. ULONG cRows,
  211. ULONG *pcRowsFetched,
  212. PACKAGEDISPINFO *pPackageInfo,
  213. UINT *pdwPriority,
  214. BOOL OnDemandInstallOnly
  215. )
  216. {
  217. HRESULT hr = S_OK;
  218. UINT i, j;
  219. LPOLESTR szUsn = NULL;
  220. ULONG cCount = 0;
  221. LPOLESTR * pszList = NULL;
  222. DWORD * pdwList = NULL;
  223. ADS_SEARCH_COLUMN column;
  224. CSPLATFORM PkgPlatform;
  225. //
  226. // Get the rows
  227. //
  228. //
  229. // Clear the caller supplied buffer in case the call to
  230. // get the first row fails
  231. //
  232. memset(pPackageInfo, 0, sizeof(PACKAGEDISPINFO));
  233. *pcRowsFetched = 0;
  234. if (*pcRowsFetched == cRows)
  235. return S_OK;
  236. for (hr = ADSIGetFirstRow(hADs, hADsSearchHandle);
  237. ((SUCCEEDED(hr)) && (hr != S_ADS_NOMORE_ROWS));
  238. hr = ADSIGetNextRow(hADs, hADsSearchHandle))
  239. {
  240. //
  241. // Get the data from each row
  242. //
  243. //
  244. // Clear the caller supplied buffer in case previous
  245. // trips through this loop have written data
  246. //
  247. memset(pPackageInfo, 0, sizeof(PACKAGEDISPINFO));
  248. if(FAILED(hr))
  249. {
  250. //
  251. // BUGBUG. Missing cleanup.
  252. //
  253. return hr;
  254. }
  255. //
  256. // If querying by file ext check match and priority
  257. // .
  258. *pdwPriority = 0;
  259. if (pszFileExt)
  260. {
  261. //Column = fileExtension
  262. hr = ADSIGetColumn(hADs, hADsSearchHandle, PKGFILEEXTNLIST, &column);
  263. cCount = 0;
  264. if (SUCCEEDED(hr))
  265. UnpackStrArrFrom(column, &pszList, &cCount);
  266. UINT cLen = wcslen(pszFileExt);
  267. for (j=0; j < cCount; ++j)
  268. {
  269. LPOLESTR pStr = NULL;
  270. if (wcslen(pszList[j]) != (cLen+3))
  271. continue;
  272. if (wcsncmp(pszList[j], pszFileExt, wcslen(pszFileExt)) != 0)
  273. continue;
  274. *pdwPriority = (wcstoul(pszList[j]+(cLen+1), &pStr, 10))*PRI_EXTN_FACTOR;
  275. break;
  276. }
  277. if (SUCCEEDED(hr))
  278. ADSIFreeColumn(hADs, &column);
  279. CoTaskMemFree(pszList); pszList = NULL;
  280. //
  281. // If none matched skip this package
  282. //
  283. if (j == cCount)
  284. continue;
  285. }
  286. //Column = packageFlags
  287. //
  288. // Need to get this so we can properly interpret the machine
  289. // architecture settings since there is at least one flag,
  290. // ACTFLG_X86OnAlpha, that affects our processing of the
  291. // machine architecture. Also need one of the flags to
  292. // do language matches.
  293. //
  294. hr = ADSIGetColumn(hADs, hADsSearchHandle, PACKAGEFLAGS, &column);
  295. if (SUCCEEDED(hr))
  296. {
  297. UnpackDWFrom(column, &(pPackageInfo->dwActFlags));
  298. ADSIFreeColumn(hADs, &column);
  299. }
  300. else
  301. continue;
  302. //
  303. // Now check Locale and Platform -- only do this
  304. // if a locale was specified
  305. //
  306. if (0 != pQryContext->Locale)
  307. {
  308. DWORD Wt = 0, MaxWt = 0;
  309. LANGID DesiredLang;
  310. DesiredLang = LANGIDFROMLCID(pQryContext->Locale);
  311. //Column = localeID
  312. hr = ADSIGetColumn(hADs, hADsSearchHandle, LOCALEID, &column);
  313. cCount = 0;
  314. if (SUCCEEDED(hr))
  315. {
  316. // Minor BUGBUG:: int converted to long.
  317. cCount = 0;
  318. UnpackDWArrFrom(column, &pdwList, &cCount);
  319. ADSIFreeColumn(hADs, &column);
  320. }
  321. for (j=0; j < cCount; ++j)
  322. {
  323. //
  324. // If the caller specifies LANG_SYSTEM_DEFAULT, we interpret this
  325. // to mean that the caller wants us to choose apps according
  326. // to the language precedence in GetLanguagePriority. If some
  327. // other langid was given, we then only accept exact matches and
  328. // give those matches the highest priority, PRI_LANG_ALWAYSMATCH
  329. //
  330. if (LANG_SYSTEM_DEFAULT == DesiredLang)
  331. {
  332. Wt = GetLanguagePriority (
  333. LANGIDFROMLCID(pdwList[j]),
  334. pPackageInfo->dwActFlags);
  335. }
  336. else
  337. {
  338. Wt = (DesiredLang == LANGIDFROMLCID(pdwList[j])) ?
  339. PRI_LANG_ALWAYSMATCH :
  340. 0;
  341. }
  342. if (Wt > MaxWt)
  343. MaxWt = Wt;
  344. }
  345. //
  346. // If none matched skip this package
  347. //
  348. if (pdwList)
  349. CoTaskMemFree(pdwList);
  350. pdwList = NULL;
  351. // if nothing matched, quit
  352. if (MaxWt == 0)
  353. continue;
  354. *pdwPriority += MaxWt;
  355. }
  356. hr = ADSIGetColumn(hADs, hADsSearchHandle, ARCHLIST, &column);
  357. // machineArchitecture
  358. if (SUCCEEDED(hr))
  359. {
  360. // Minor BUGBUG:: int converted to long.
  361. cCount = 0;
  362. DWORD Wt = 0, MaxWt = 0;
  363. UnpackDWArrFrom(column, &pdwList, &cCount);
  364. ADSIFreeColumn(hADs, &column);
  365. for (j=0; j < cCount; ++j)
  366. {
  367. PackPlatform (pdwList[j], &PkgPlatform);
  368. Wt = PlatformWt (&(pQryContext->Platform),
  369. &PkgPlatform,
  370. pPackageInfo->dwActFlags & ACTFLG_X86OnAlpha);
  371. if (Wt > MaxWt)
  372. MaxWt = Wt;
  373. }
  374. if (pdwList)
  375. CoTaskMemFree(pdwList);
  376. pdwList = NULL;
  377. //
  378. // If none matched skip this package
  379. //
  380. if (MaxWt == 0)
  381. continue;
  382. *pdwPriority += MaxWt;
  383. }
  384. else
  385. continue;
  386. // passed all the filters.
  387. //
  388. // Does it support AutoInstall?
  389. //
  390. if ((OnDemandInstallOnly) && (!(pPackageInfo->dwActFlags & ACTFLG_OnDemandInstall)))
  391. continue;
  392. // If it is neither Published nor Assigned then skip it.
  393. if ((!(pPackageInfo->dwActFlags & ACTFLG_Published)) &&
  394. (!(pPackageInfo->dwActFlags & ACTFLG_Assigned)))
  395. {
  396. continue;
  397. }
  398. // If it is an Orphaned App OR Uninstalled App do not return.
  399. if ((pPackageInfo->dwActFlags & ACTFLG_Orphan) ||
  400. (pPackageInfo->dwActFlags & ACTFLG_Uninstall))
  401. {
  402. continue;
  403. }
  404. //Column = OBJECTGUID
  405. hr = ADSIGetColumn(hADs, hADsSearchHandle, OBJECTGUID, &column);
  406. if (SUCCEEDED(hr))
  407. {
  408. LPOLESTR pStr = NULL;
  409. UnpackGUIDFrom(column, &(pPackageInfo->PackageGuid));
  410. ADSIFreeColumn(hADs, &column);
  411. }
  412. //Column = ScriptPath
  413. hr = ADSIGetColumn(hADs, hADsSearchHandle, SCRIPTPATH, &column);
  414. if (SUCCEEDED(hr))
  415. {
  416. UnpackStrAllocFrom(column, &(pPackageInfo->pszScriptPath));
  417. ADSIFreeColumn(hADs, &column);
  418. }
  419. //Column = comClassID
  420. hr = ADSIGetColumn(hADs, hADsSearchHandle, PKGCLSIDLIST, &column);
  421. cCount = 0;
  422. if (SUCCEEDED(hr))
  423. {
  424. UnpackStrArrFrom(column, &pszList, &cCount);
  425. if (cCount)
  426. {
  427. if (pclsspec->tyspec == TYSPEC_CLSID)
  428. {
  429. DWORD i=0, Ctx = 0;
  430. WCHAR szClsid[STRINGGUIDLEN], *szPtr = NULL;
  431. StringFromGUID(pclsspec->tagged_union.clsid, szClsid);
  432. for (i = 0; i < cCount; i++)
  433. if (wcsncmp(pszList[i], szClsid, STRINGGUIDLEN-1) == 0)
  434. break;
  435. //
  436. // The below assert is only hit if there is bad data -- if we find the
  437. // clsid, i will not be cCount, and cCount will never be 0. Basically,
  438. // we're asserting that the search should always succeed if the ds data
  439. // is good.
  440. //
  441. ASSERT(i != cCount);
  442. if (i == cCount)
  443. continue;
  444. if (wcslen(pszList[i]) > (STRINGGUIDLEN-1))
  445. Ctx = wcstoul(pszList[i]+STRINGGUIDLEN, &szPtr, 16);
  446. if ((Ctx & (pQryContext->dwContext)) == 0)
  447. {
  448. CoTaskMemFree(pszList);
  449. ADSIFreeColumn(hADs, &column);
  450. // none of the class context matched.
  451. continue;
  452. }
  453. else
  454. *pdwPriority += ClassContextWt((Ctx & pQryContext->dwContext));
  455. }
  456. pPackageInfo->pClsid = (GUID *)CoTaskMemAlloc(sizeof(GUID));
  457. if (wcslen(pszList[0]) > (STRINGGUIDLEN-1))
  458. pszList[0][STRINGGUIDLEN-1] = L'\0';
  459. // Only access the first entry
  460. if (pPackageInfo->pClsid)
  461. GUIDFromString(pszList[0], pPackageInfo->pClsid);
  462. // o/w return NULL.
  463. CoTaskMemFree(pszList);
  464. }
  465. ADSIFreeColumn(hADs, &column);
  466. }
  467. //Column = packageType
  468. hr = ADSIGetColumn(hADs, hADsSearchHandle, PACKAGETYPE, &column);
  469. if (SUCCEEDED(hr))
  470. {
  471. UnpackDWFrom(column, (DWORD *)&(pPackageInfo->PathType));
  472. ADSIFreeColumn(hADs, &column);
  473. }
  474. //Column = lastUpdateSequence
  475. hr = ADSIGetColumn(hADs, hADsSearchHandle, PKGUSN, &column);
  476. if (SUCCEEDED(hr))
  477. {
  478. UnpackStrFrom(column, &szUsn);
  479. TimeToUsn (szUsn, (CSUSN *)(&(pPackageInfo->Usn)));
  480. ADSIFreeColumn(hADs, &column);
  481. }
  482. else {
  483. ReleasePackageInfo(pPackageInfo);
  484. continue;
  485. }
  486. hr = ADSIGetColumn(hADs, hADsSearchHandle, PRODUCTCODE, &column);
  487. if (SUCCEEDED(hr))
  488. {
  489. UnpackGUIDFrom(column, &(pPackageInfo->ProductCode));
  490. ADSIFreeColumn(hADs, &column);
  491. }
  492. //Column = versionNumberHi
  493. hr = ADSIGetColumn(hADs, hADsSearchHandle, VERSIONHI, &column);
  494. if (SUCCEEDED(hr))
  495. {
  496. UnpackDWFrom(column, &(pPackageInfo->dwVersionHi));
  497. ADSIFreeColumn(hADs, &column);
  498. }
  499. //Column = versionNumberLo
  500. hr = ADSIGetColumn(hADs, hADsSearchHandle, VERSIONLO, &column);
  501. if (SUCCEEDED(hr))
  502. {
  503. UnpackDWFrom(column, &(pPackageInfo->dwVersionLo));
  504. ADSIFreeColumn(hADs, &column);
  505. }
  506. //Column = revision
  507. hr = ADSIGetColumn(hADs, hADsSearchHandle, REVISION, &column);
  508. if (SUCCEEDED(hr))
  509. {
  510. UnpackDWFrom(column, &(pPackageInfo->dwRevision));
  511. ADSIFreeColumn(hADs, &column);
  512. }
  513. hr = ADSIGetColumn(hADs, hADsSearchHandle, UPGRADESPACKAGES, &column);
  514. if (SUCCEEDED(hr))
  515. {
  516. LPOLESTR *pProp = NULL;
  517. hr = UnpackStrArrAllocFrom(column, &pProp, (DWORD *)&(pPackageInfo->cUpgrades));
  518. if (pPackageInfo->cUpgrades)
  519. pPackageInfo->prgUpgradeInfoList = (UPGRADEINFO *)CoTaskMemAlloc(sizeof(UPGRADEINFO)*
  520. (pPackageInfo->cUpgrades));
  521. if (pPackageInfo->prgUpgradeInfoList)
  522. {
  523. memset(pPackageInfo->prgUpgradeInfoList, 0, sizeof(UPGRADEINFO)*(pPackageInfo->cUpgrades));
  524. for (j=0; j < ( pPackageInfo->cUpgrades); ++j)
  525. {
  526. WCHAR *pStr = NULL;
  527. LPOLESTR ptr = (pPackageInfo->prgUpgradeInfoList[j].szClassStore) = pProp[j];
  528. UINT len = wcslen (ptr);
  529. if (len <= 41)
  530. continue;
  531. *(ptr + len - 3) = NULL;
  532. (pPackageInfo->prgUpgradeInfoList[j].Flag) = wcstoul(ptr+(len-2), &pStr, 16);
  533. *(ptr + len - 3 - 36 - 2) = L'\0';
  534. /* -GUID-'::'*/
  535. GUIDFromString(ptr+len-3-36, &(pPackageInfo->prgUpgradeInfoList[j].PackageGuid));
  536. }
  537. pPackageInfo->cUpgrades = j; // we might have skipped some.
  538. }
  539. ADSIFreeColumn(hADs, &column);
  540. }
  541. hr = ADSIGetColumn(hADs, hADsSearchHandle, UILEVEL, &column);
  542. if (SUCCEEDED(hr))
  543. {
  544. UnpackDWFrom(column, (DWORD *)&(pPackageInfo->InstallUiLevel));
  545. ADSIFreeColumn(hADs, &column);
  546. }
  547. hr = ADSIGetColumn(hADs, hADsSearchHandle, PACKAGENAME, &column);
  548. if (SUCCEEDED(hr))
  549. {
  550. UnpackStrAllocFrom(column, &(pPackageInfo->pszPackageName));
  551. ADSIFreeColumn(hADs, &column);
  552. CSDBGPrint((L"FetchInstallData:: Returning Package %s", pPackageInfo->pszPackageName));
  553. }
  554. else {
  555. ReleasePackageInfo(pPackageInfo);
  556. continue;
  557. }
  558. hr = ADSIGetColumn(hADs, hADsSearchHandle, HELPURL, &column);
  559. if (SUCCEEDED(hr))
  560. {
  561. UnpackStrAllocFrom(column, &(pPackageInfo->pszUrl));
  562. ADSIFreeColumn(hADs, &column);
  563. }
  564. hr = ADSIGetColumn(hADs, hADsSearchHandle, PUBLISHER, &column);
  565. if (SUCCEEDED(hr))
  566. {
  567. UnpackStrAllocFrom(column, &(pPackageInfo->pszPublisher));
  568. ADSIFreeColumn(hADs, &column);
  569. }
  570. // source list
  571. hr = ADSIGetColumn(hADs, hADsSearchHandle, MSIFILELIST, &column);
  572. if (SUCCEEDED(hr))
  573. {
  574. LPOLESTR *rpszSourceList = NULL, psz = NULL, pStr = NULL;
  575. DWORD Loc = 0, cSources = 0;
  576. UnpackStrArrFrom(column, &(rpszSourceList), &cSources);
  577. // reorder and allocate spaces.
  578. if (cSources > 1)
  579. {
  580. pPackageInfo->fHasTransforms = 1;
  581. /*
  582. pPackageInfo->pszSourceList = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*
  583. (pPackageInfo->cSources));
  584. // if we could not, plod on, the caller will get back as much as possible.
  585. if (!(pPackageInfo->pszSourceList)) {
  586. pPackageInfo->cSources = 0;
  587. }
  588. memset(pPackageInfo->pszSourceList, 0, sizeof(LPOLESTR)*(pPackageInfo->cSources));
  589. for (count = 0; count < (pPackageInfo->cSources); count++)
  590. {
  591. pPackageInfo->pszSourceList[count] = (LPOLESTR)CoTaskMemAlloc(
  592. sizeof(WCHAR)*(wcslen(rpszSourceList[count])+1));
  593. if (!(pPackageInfo->pszSourceList[count]))
  594. break;
  595. }
  596. // if mem couldn't be allocated
  597. if (count != pPackageInfo->cSources) {
  598. for (count = 0; count < (pPackageInfo->cSources); count++)
  599. if ((pPackageInfo->pszSourceList[count]))
  600. CoTaskMemFree(pPackageInfo->pszSourceList[count]);
  601. CoTaskMemFree(pPackageInfo->pszSourceList);
  602. pPackageInfo->cSources = 0;
  603. }
  604. for (count = 0; count < (pPackageInfo->cSources); count++)
  605. {
  606. psz = wcschr(rpszSourceList[count], L':');
  607. *psz = L'\0';
  608. Loc = wcstoul(rpszSourceList[count], &pStr, 10);
  609. wsprintf(pPackageDetail->pszSourceList[Loc], L"%s", psz+1);
  610. }
  611. */
  612. }
  613. else
  614. pPackageInfo->fHasTransforms = 0;
  615. ADSIFreeColumn(hADs, &column);
  616. CoTaskMemFree(rpszSourceList);
  617. }
  618. ++pPackageInfo;
  619. ++pdwPriority;
  620. (*pcRowsFetched)++;
  621. if (*pcRowsFetched == cRows)
  622. break;
  623. }
  624. //
  625. // Check if we found as many as asked for
  626. //
  627. if (*pcRowsFetched != cRows)
  628. return S_FALSE;
  629. return S_OK;
  630. }
  631. // FetchPackageInfo
  632. //-----------------
  633. //
  634. // Gets the result set of the query : List of Package objects.
  635. // Returns the properties in PackageInfo structure.
  636. //
  637. HRESULT FetchPackageInfo(HANDLE hADs,
  638. ADS_SEARCH_HANDLE hADsSearchHandle,
  639. DWORD dwFlags,
  640. CSPLATFORM *pPlatform,
  641. ULONG cRows,
  642. ULONG *pcRowsFetched,
  643. PACKAGEDISPINFO *pPackageInfo,
  644. BOOL *fFirst
  645. )
  646. {
  647. HRESULT hr = S_OK;
  648. UINT i, j;
  649. ULONG cPlatforms = 0;
  650. DWORD * dwPlatformList=NULL;
  651. LCID * dwLocaleList=NULL;
  652. DWORD dwPackageFlags;
  653. ULONG cFetched = 0;
  654. ULONG cRowsLeft = 0;
  655. CSPLATFORM PkgPlatform;
  656. ADS_SEARCH_COLUMN column;
  657. LPOLESTR szUsn = NULL;
  658. BOOL fX86OnAlpha;
  659. *pcRowsFetched = 0;
  660. cRowsLeft = cRows;
  661. if (!cRowsLeft)
  662. return S_OK;
  663. // The LDAP filter performs a part of the selection
  664. // The flag filters are interpreted on the client after obtaining the result set
  665. for (;(cRowsLeft);)
  666. {
  667. if ((*fFirst) && (!(*pcRowsFetched))) {
  668. *fFirst = FALSE;
  669. hr = ADSIGetFirstRow(hADs, hADsSearchHandle);
  670. }
  671. else
  672. hr = ADSIGetNextRow(hADs, hADsSearchHandle);
  673. if ((FAILED(hr)) || (hr == S_ADS_NOMORE_ROWS))
  674. break;
  675. dwPackageFlags = 0;
  676. // Get the Flag Value: Column = packageFlags
  677. hr = ADSIGetColumn(hADs, hADsSearchHandle, PACKAGEFLAGS, &column);
  678. if (SUCCEEDED(hr))
  679. {
  680. UnpackDWFrom(column, &dwPackageFlags);
  681. ADSIFreeColumn(hADs, &column);
  682. }
  683. else
  684. continue;
  685. //
  686. // Check flag values to see if this package meets the filter
  687. //
  688. //
  689. // If it is an Orphaned App, we only return it for APPINFO_ALL.
  690. //
  691. if ((dwPackageFlags & ACTFLG_Orphan) && (!(dwFlags & APPINFO_ALL)))
  692. {
  693. continue;
  694. }
  695. // If it is an Uninstalled App return it if asked for by APPINFO_ALL
  696. if ((dwPackageFlags & ACTFLG_Uninstall) && (!(dwFlags & APPINFO_ALL)))
  697. {
  698. continue;
  699. }
  700. if ((dwFlags & APPINFO_PUBLISHED) && (!(dwPackageFlags & ACTFLG_Published)))
  701. {
  702. continue;
  703. }
  704. if ((dwFlags & APPINFO_ASSIGNED) && (!(dwPackageFlags & ACTFLG_Assigned)))
  705. {
  706. continue;
  707. }
  708. if ((dwFlags & APPINFO_VISIBLE) && (!(dwPackageFlags & ACTFLG_UserInstall)))
  709. {
  710. continue;
  711. }
  712. if ((dwFlags & APPINFO_AUTOINSTALL) && (!(dwPackageFlags & ACTFLG_OnDemandInstall)))
  713. {
  714. continue;
  715. }
  716. //
  717. // Move the data into PackageInfo structure
  718. //
  719. memset(pPackageInfo, 0, sizeof(PACKAGEDISPINFO));
  720. //Column = packageType
  721. hr = ADSIGetColumn(hADs, hADsSearchHandle, PACKAGETYPE, &column);
  722. if (SUCCEEDED(hr))
  723. {
  724. UnpackDWFrom(column, (DWORD *)&(pPackageInfo->PathType));
  725. ADSIFreeColumn(hADs, &column);
  726. }
  727. if (( dwFlags & APPINFO_MSI ) && (pPackageInfo->PathType != DrwFilePath))
  728. continue;
  729. pPackageInfo->LangId = LANG_NEUTRAL;
  730. //
  731. // If the package flags specify that we should ignore locale, or the
  732. // caller specified that all locale's are acceptable, skip the language
  733. // checks
  734. //
  735. if ( ! (dwPackageFlags & ACTFLG_IgnoreLanguage) &&
  736. ! (dwFlags & APPINFO_ALLLOCALE) )
  737. {
  738. LANGID PackageLangId;
  739. DWORD cLanguages;
  740. hr = ADSIGetColumn(hADs, hADsSearchHandle, LOCALEID, &column);
  741. dwLocaleList = NULL;
  742. if (SUCCEEDED(hr))
  743. {
  744. // type change. shouldn't affect anything.
  745. UnpackDWArrFrom(column, &dwLocaleList, &cLanguages);
  746. ADSIFreeColumn(hADs, &column);
  747. }
  748. else
  749. continue;
  750. //
  751. // We only care about the first language returned -- originally
  752. // the packages in the ds could support multiple locales, but
  753. // we now only support one language
  754. //
  755. if (cLanguages)
  756. {
  757. PackageLangId = LANGIDFROMLCID(dwLocaleList[0]);
  758. }
  759. CoTaskMemFree(dwLocaleList);
  760. if (!cLanguages || !MatchLanguage(PackageLangId, dwPackageFlags))
  761. continue;
  762. pPackageInfo->LangId = PackageLangId;
  763. }
  764. if (pPlatform != NULL)
  765. {
  766. //Column = machineArchitecture
  767. hr = ADSIGetColumn(hADs, hADsSearchHandle, ARCHLIST, &column);
  768. cPlatforms = 0;
  769. dwPlatformList = NULL;
  770. if (SUCCEEDED(hr))
  771. {
  772. UnpackDWArrFrom(column, &dwPlatformList, &cPlatforms);
  773. ADSIFreeColumn(hADs, &column);
  774. }
  775. else
  776. continue;
  777. for (j=0; j < cPlatforms; ++j)
  778. {
  779. PackPlatform (dwPlatformList[j], &PkgPlatform);
  780. if (MatchPlatform (pPlatform,
  781. &PkgPlatform,
  782. dwPackageFlags & ACTFLG_X86OnAlpha))
  783. break;
  784. }
  785. if (dwPlatformList)
  786. CoTaskMemFree(dwPlatformList);
  787. //
  788. // If none matched skip this package
  789. //
  790. if (j == cPlatforms)
  791. continue;
  792. }
  793. pPackageInfo->dwActFlags = dwPackageFlags;
  794. //Column = packageName. freeing this????
  795. hr = ADSIGetColumn(hADs, hADsSearchHandle, PACKAGENAME, &column);
  796. if (SUCCEEDED(hr))
  797. {
  798. UnpackStrAllocFrom(column, &(pPackageInfo->pszPackageName));
  799. CSDBGPrint((L"FetchPackageInfo:: Returning Package %s", pPackageInfo->pszPackageName));
  800. ADSIFreeColumn(hADs, &column);
  801. }
  802. else {
  803. ReleasePackageInfo(pPackageInfo);
  804. continue;
  805. }
  806. //Column = OBJECTGUID
  807. hr = ADSIGetColumn(hADs, hADsSearchHandle, OBJECTGUID, &column);
  808. if (SUCCEEDED(hr))
  809. {
  810. UnpackGUIDFrom(column, &(pPackageInfo->PackageGuid));
  811. ADSIFreeColumn(hADs, &column);
  812. }
  813. //Column = ScriptPath
  814. hr = ADSIGetColumn(hADs, hADsSearchHandle, SCRIPTPATH, &column);
  815. if (SUCCEEDED(hr))
  816. {
  817. UnpackStrAllocFrom(column, &(pPackageInfo->pszScriptPath));
  818. ADSIFreeColumn(hADs, &column);
  819. }
  820. //Column = ScriptSize
  821. hr = ADSIGetColumn(hADs, hADsSearchHandle, SCRIPTSIZE, &column);
  822. if (SUCCEEDED(hr))
  823. {
  824. UnpackDWFrom(column, &(pPackageInfo->cScriptLen));
  825. ADSIFreeColumn(hADs, &column);
  826. }
  827. //Column = lastUpdateSequence,
  828. hr = ADSIGetColumn(hADs, hADsSearchHandle, PKGUSN, &column);
  829. if (SUCCEEDED(hr))
  830. {
  831. UnpackStrFrom(column, &szUsn);
  832. TimeToUsn (szUsn, (CSUSN *)(&(pPackageInfo->Usn)));
  833. ADSIFreeColumn(hADs, &column);
  834. }
  835. else {
  836. ReleasePackageInfo(pPackageInfo);
  837. continue;
  838. }
  839. // ProductCode
  840. hr = ADSIGetColumn(hADs, hADsSearchHandle, PRODUCTCODE, &column);
  841. if (SUCCEEDED(hr))
  842. {
  843. UnpackGUIDFrom(column, &(pPackageInfo->ProductCode));
  844. ADSIFreeColumn(hADs, &column);
  845. }
  846. //Column = versionNumberHi
  847. hr = ADSIGetColumn(hADs, hADsSearchHandle, VERSIONHI, &column);
  848. if (SUCCEEDED(hr))
  849. {
  850. UnpackDWFrom(column, &(pPackageInfo->dwVersionHi));
  851. ADSIFreeColumn(hADs, &column);
  852. }
  853. //Column = versionNumberLo
  854. hr = ADSIGetColumn(hADs, hADsSearchHandle, VERSIONLO, &column);
  855. if (SUCCEEDED(hr))
  856. {
  857. UnpackDWFrom(column, &(pPackageInfo->dwVersionLo));
  858. ADSIFreeColumn(hADs, &column);
  859. }
  860. //Column = revision
  861. hr = ADSIGetColumn(hADs, hADsSearchHandle, REVISION, &column);
  862. if (SUCCEEDED(hr))
  863. {
  864. UnpackDWFrom(column, &(pPackageInfo->dwRevision));
  865. ADSIFreeColumn(hADs, &column);
  866. }
  867. hr = ADSIGetColumn(hADs, hADsSearchHandle, UPGRADESPACKAGES, &column);
  868. if (SUCCEEDED(hr))
  869. {
  870. LPOLESTR *pProp = NULL;
  871. hr = UnpackStrArrAllocFrom(column, &pProp, (DWORD *)&(pPackageInfo->cUpgrades));
  872. if (pPackageInfo->cUpgrades)
  873. pPackageInfo->prgUpgradeInfoList = (UPGRADEINFO *)CoTaskMemAlloc(sizeof(UPGRADEINFO)*
  874. (pPackageInfo->cUpgrades));
  875. if (pPackageInfo->prgUpgradeInfoList)
  876. {
  877. memset(pPackageInfo->prgUpgradeInfoList, 0, sizeof(UPGRADEINFO)*(pPackageInfo->cUpgrades));
  878. for (j=0; j < ( pPackageInfo->cUpgrades); ++j)
  879. {
  880. WCHAR *pStr = NULL;
  881. LPOLESTR ptr = (pPackageInfo->prgUpgradeInfoList[j].szClassStore) = pProp[j];
  882. UINT len = wcslen (ptr);
  883. if (len <= 41)
  884. continue;
  885. *(ptr + len - 3) = NULL;
  886. (pPackageInfo->prgUpgradeInfoList[j].Flag) = wcstoul(ptr+(len-2), &pStr, 16);
  887. *(ptr + len - 3 - 36 - 2) = L'\0';
  888. /* -GUID-'::'*/
  889. GUIDFromString(ptr+len-3-36, &(pPackageInfo->prgUpgradeInfoList[j].PackageGuid));
  890. }
  891. pPackageInfo->cUpgrades = j; // we might have skipped some.
  892. }
  893. }
  894. hr = ADSIGetColumn(hADs, hADsSearchHandle, UILEVEL, &column);
  895. if (SUCCEEDED(hr))
  896. {
  897. UnpackDWFrom(column, (DWORD *)&(pPackageInfo->InstallUiLevel));
  898. ADSIFreeColumn(hADs, &column);
  899. }
  900. hr = ADSIGetColumn(hADs, hADsSearchHandle, HELPURL, &column);
  901. if (SUCCEEDED(hr))
  902. {
  903. UnpackStrAllocFrom(column, &(pPackageInfo->pszUrl));
  904. ADSIFreeColumn(hADs, &column);
  905. }
  906. hr = ADSIGetColumn(hADs, hADsSearchHandle, PUBLISHER, &column);
  907. if (SUCCEEDED(hr))
  908. {
  909. UnpackStrAllocFrom(column, &(pPackageInfo->pszPublisher));
  910. ADSIFreeColumn(hADs, &column);
  911. }
  912. hr = ADSIGetColumn(hADs, hADsSearchHandle, MSIFILELIST, &column);
  913. if (SUCCEEDED(hr))
  914. {
  915. LPOLESTR *rpszSourceList = NULL, psz = NULL, pStr = NULL;
  916. DWORD Loc = 0, cSources=0;
  917. UnpackStrArrFrom(column, &(rpszSourceList), &cSources);
  918. // reorder and allocate spaces.
  919. if (cSources > 1)
  920. {
  921. pPackageInfo->fHasTransforms = 1;
  922. /*
  923. (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*
  924. (pPackageInfo->cSources));
  925. // if we could not, plod on, the caller will get back as much as possible.
  926. if (!(pPackageInfo->pszSourceList)) {
  927. pPackageInfo->cSources = 0;
  928. }
  929. memset(pPackageInfo->pszSourceList, 0, sizeof(LPOLESTR)*(pPackageInfo->cSources));
  930. for (count = 0; count < (pPackageInfo->cSources); count++)
  931. {
  932. pPackageInfo->pszSourceList[count] = (LPOLESTR)CoTaskMemAlloc(
  933. sizeof(WCHAR)*(wcslen(rpszSourceList[count])+1));
  934. if (!(pPackageInfo->pszSourceList[count]))
  935. break;
  936. }
  937. // if mem couldn't be allocated
  938. if (count != pPackageInfo->cSources) {
  939. for (count = 0; count < (pPackageInfo->cSources); count++)
  940. if ((pPackageInfo->pszSourceList[count]))
  941. CoTaskMemFree(pPackageInfo->pszSourceList[count]);
  942. CoTaskMemFree(pPackageInfo->pszSourceList);
  943. pPackageInfo->cSources = 0;
  944. }
  945. for (count = 0; count < (pPackageInfo->cSources); count++)
  946. {
  947. psz = wcschr(rpszSourceList[count], L':');
  948. *psz = L'\0';
  949. Loc = wcstoul(rpszSourceList[count], &pStr, 10);
  950. wsprintf(pPackageDetail->pszSourceList[Loc], L"%s", psz+1);
  951. }
  952. */
  953. }
  954. else
  955. pPackageInfo->fHasTransforms = 0;
  956. CoTaskMemFree(rpszSourceList);
  957. ADSIFreeColumn(hADs, &column);
  958. }
  959. ++pPackageInfo;
  960. cRowsLeft--;
  961. (*pcRowsFetched)++;
  962. }
  963. if (!cRowsLeft)
  964. return S_OK;
  965. return S_FALSE;
  966. }
  967. // FetchCategory
  968. //--------------
  969. //
  970. // List of columns this routine fetches.
  971. //
  972. HRESULT FetchCategory(HANDLE hADs,
  973. ADS_SEARCH_HANDLE hADsSearchHandle,
  974. APPCATEGORYINFOLIST *pCategoryInfoList,
  975. LCID Locale
  976. )
  977. {
  978. HRESULT hr = S_OK;
  979. ADS_SEARCH_COLUMN column;
  980. LPOLESTR * pszDesc = NULL;
  981. DWORD cdesc = 0, i = 0;
  982. LPOLESTR szCatid = NULL;
  983. for (hr = ADSIGetFirstRow(hADs, hADsSearchHandle), i = 0;
  984. ((SUCCEEDED(hr)) && ((hr) != S_ADS_NOMORE_ROWS));
  985. hr = ADSIGetNextRow(hADs, hADsSearchHandle), i++)
  986. {
  987. // Get the data from each row ignoring the error returned.
  988. // allocated number of buffers.
  989. if (i >= (pCategoryInfoList->cCategory))
  990. break;
  991. //Column = description
  992. hr = ADSIGetColumn(hADs, hADsSearchHandle, LOCALEDESCRIPTION, &column);
  993. cdesc = 0; pszDesc = NULL;
  994. if (SUCCEEDED(hr))
  995. UnpackStrArrFrom(column, &pszDesc, &cdesc);
  996. (pCategoryInfoList->pCategoryInfo)[i].Locale = Locale;
  997. (pCategoryInfoList->pCategoryInfo)[i].pszDescription =
  998. (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR)*128);
  999. // BUGBUG:: Restricting the desc to 128.
  1000. if ((pCategoryInfoList->pCategoryInfo)[i].pszDescription)
  1001. GetCategoryLocaleDesc(pszDesc, cdesc, &((pCategoryInfoList->pCategoryInfo)[i].Locale),
  1002. (pCategoryInfoList->pCategoryInfo)[i].pszDescription);
  1003. if (SUCCEEDED(hr))
  1004. ADSIFreeColumn(hADs, &column);
  1005. if (pszDesc)
  1006. CoTaskMemFree(pszDesc);
  1007. // catid
  1008. hr = ADSIGetColumn(hADs, hADsSearchHandle, CATEGORYCATID, &column);
  1009. if (SUCCEEDED(hr))
  1010. {
  1011. UnpackGUIDFrom(column, &((pCategoryInfoList->pCategoryInfo)[i].AppCategoryId));
  1012. ADSIFreeColumn(hADs, &column);
  1013. }
  1014. }
  1015. pCategoryInfoList->cCategory = i;
  1016. return S_OK;
  1017. }
  1018. HRESULT GetClassDetail(WCHAR *szClassPath, CLASSDETAIL *pClassDetail)
  1019. {
  1020. HRESULT hr = S_OK;
  1021. WCHAR *szGUID = NULL;
  1022. ADS_ATTR_INFO *pAttrsGot = NULL;
  1023. HANDLE hADs = NULL;
  1024. LPOLESTR AttrNames[] = {PROGIDLIST, TREATASCLSID, CLASSCLSID};
  1025. DWORD posn = 0, cProp = 0, cgot = 0;
  1026. hr = ADSIOpenDSObject(szClassPath, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND,
  1027. &hADs);
  1028. RETURN_ON_FAILURE(hr);
  1029. hr = ADSIGetObjectAttributes(hADs, AttrNames, 3, &pAttrsGot, &cgot);
  1030. ERROR_ON_FAILURE(hr);
  1031. posn = GetPropertyFromAttr(pAttrsGot, cgot, CLASSCLSID);
  1032. if (posn < cgot) {
  1033. UnpackStrFrom(pAttrsGot[posn], &szGUID);
  1034. GUIDFromString(szGUID, &(pClassDetail->Clsid));
  1035. }
  1036. else
  1037. {
  1038. hr = CS_E_OBJECT_NOTFOUND;
  1039. ERROR_ON_FAILURE(hr);
  1040. }
  1041. posn = GetPropertyFromAttr(pAttrsGot, cgot, PROGIDLIST);
  1042. if (posn < cgot)
  1043. UnpackStrArrAllocFrom(pAttrsGot[posn], &(pClassDetail->prgProgId),
  1044. &(pClassDetail->cProgId));
  1045. posn = GetPropertyFromAttr(pAttrsGot, cgot, TREATASCLSID);
  1046. if (posn < cgot)
  1047. {
  1048. UnpackStrFrom(pAttrsGot[posn], &szGUID);
  1049. GUIDFromString(szGUID, &(pClassDetail->TreatAs));
  1050. }
  1051. Error_Cleanup:
  1052. if (pAttrsGot)
  1053. FreeADsMem(pAttrsGot);
  1054. if (hADs)
  1055. ADSICloseDSObject(hADs);
  1056. return hr;
  1057. }
  1058. HRESULT GetPackageDetail (HANDLE hPackageADs, WCHAR *szClassContainerPath,
  1059. PACKAGEDETAIL *pPackageDetail)
  1060. {
  1061. HRESULT hr = S_OK;
  1062. GUID PkgGuid;
  1063. DWORD *pdwArch = NULL, count = 0;
  1064. PLATFORMINFO *pPlatformInfo = NULL;
  1065. INSTALLINFO *pInstallInfo = NULL;
  1066. ACTIVATIONINFO *pActInfo = NULL;
  1067. ADS_ATTR_INFO *pAttr = NULL;
  1068. DWORD posn, cgot = 0;
  1069. DWORD cClasses = 0;
  1070. LPOLESTR *szClasses = NULL;
  1071. DWORD dwUiLevel = 0;
  1072. DWORD cProgId = 0;
  1073. LPOLESTR *pszProgId = NULL;
  1074. memset (pPackageDetail, 0, sizeof (PACKAGEDETAIL));
  1075. hr = ADSIGetObjectAttributes(hPackageADs, pszPackageDetailAttrNames, cPackageDetailAttr,
  1076. &pAttr, &cgot);
  1077. RETURN_ON_FAILURE(hr);
  1078. pInstallInfo = pPackageDetail->pInstallInfo = (INSTALLINFO *) CoTaskMemAlloc(sizeof (INSTALLINFO));
  1079. if (!pInstallInfo)
  1080. ERROR_ON_FAILURE((hr=E_OUTOFMEMORY));
  1081. memset(pInstallInfo, NULL, sizeof(INSTALLINFO));
  1082. posn = GetPropertyFromAttr(pAttr, cgot, PACKAGEFLAGS);
  1083. if (posn < cgot)
  1084. UnpackDWFrom(pAttr[posn], (DWORD *)&(pInstallInfo->dwActFlags));
  1085. else
  1086. ERROR_ON_FAILURE((hr=CS_E_OBJECT_NOTFOUND));
  1087. posn = GetPropertyFromAttr(pAttr, cgot, PACKAGETYPE);
  1088. if (posn < cgot)
  1089. UnpackDWFrom(pAttr[posn], (DWORD *)&(pInstallInfo->PathType));
  1090. else
  1091. ERROR_ON_FAILURE((hr=CS_E_OBJECT_NOTFOUND));
  1092. posn = GetPropertyFromAttr(pAttr, cgot, SCRIPTPATH);
  1093. if (posn < cgot)
  1094. UnpackStrAllocFrom(pAttr[posn], &(pInstallInfo->pszScriptPath));
  1095. posn = GetPropertyFromAttr(pAttr, cgot, SCRIPTSIZE);
  1096. if (posn < cgot)
  1097. UnpackDWFrom(pAttr[posn], &(pInstallInfo->cScriptLen));
  1098. posn = GetPropertyFromAttr(pAttr, cgot, SETUPCOMMAND);
  1099. if (posn < cgot)
  1100. UnpackStrAllocFrom(pAttr[posn], &(pInstallInfo->pszSetupCommand));
  1101. posn = GetPropertyFromAttr(pAttr, cgot, HELPURL);
  1102. if (posn < cgot)
  1103. UnpackStrAllocFrom(pAttr[posn], &(pInstallInfo->pszUrl));
  1104. posn = GetPropertyFromAttr(pAttr, cgot, PKGUSN);
  1105. if (posn < cgot)
  1106. UsnGet(pAttr[posn], (CSUSN *)&(pInstallInfo->Usn));
  1107. else
  1108. ERROR_ON_FAILURE((hr=CS_E_OBJECT_NOTFOUND));
  1109. posn = GetPropertyFromAttr(pAttr, cgot, PRODUCTCODE);
  1110. if (posn < cgot)
  1111. UnpackGUIDFrom(pAttr[posn], &(pInstallInfo->ProductCode));
  1112. posn = GetPropertyFromAttr(pAttr, cgot, MVIPC);
  1113. if (posn < cgot)
  1114. UnpackGUIDFrom(pAttr[posn], &(pInstallInfo->Mvipc));
  1115. // doesn't matter if the property itself is multivalued.
  1116. posn = GetPropertyFromAttr(pAttr, cgot, OBJECTGUID);
  1117. if (posn < cgot)
  1118. UnpackGUIDFrom(pAttr[posn], &(pInstallInfo->PackageGuid));
  1119. posn = GetPropertyFromAttr(pAttr, cgot, VERSIONHI);
  1120. if (posn < cgot)
  1121. UnpackDWFrom(pAttr[posn], &(pInstallInfo->dwVersionHi));
  1122. posn = GetPropertyFromAttr(pAttr, cgot, VERSIONLO);
  1123. if (posn < cgot)
  1124. UnpackDWFrom(pAttr[posn], &(pInstallInfo->dwVersionLo));
  1125. posn = GetPropertyFromAttr(pAttr, cgot, REVISION);
  1126. if (posn < cgot)
  1127. UnpackDWFrom(pAttr[posn], &(pInstallInfo->dwRevision));
  1128. posn = GetPropertyFromAttr(pAttr, cgot, UILEVEL);
  1129. if (posn < cgot)
  1130. UnpackDWFrom(pAttr[posn], &dwUiLevel);
  1131. pInstallInfo->InstallUiLevel = dwUiLevel;
  1132. posn = GetPropertyFromAttr(pAttr, cgot, UPGRADESPACKAGES);
  1133. if (posn < cgot)
  1134. {
  1135. LPOLESTR *pProp = NULL;
  1136. UnpackStrArrAllocFrom(pAttr[posn], &pProp, (DWORD *)&(pInstallInfo->cUpgrades));
  1137. if (pInstallInfo->cUpgrades)
  1138. pInstallInfo->prgUpgradeInfoList = (UPGRADEINFO *)CoTaskMemAlloc(sizeof(UPGRADEINFO)*
  1139. pInstallInfo->cUpgrades);
  1140. if (!(pInstallInfo->prgUpgradeInfoList))
  1141. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  1142. memset(pInstallInfo->prgUpgradeInfoList, 0, sizeof(UPGRADEINFO)*(pInstallInfo->cUpgrades));
  1143. for (count = 0; (count < (pInstallInfo->cUpgrades)); count++)
  1144. {
  1145. WCHAR *pStr = NULL;
  1146. LPOLESTR ptr = (pInstallInfo->prgUpgradeInfoList[count].szClassStore) = pProp[count];
  1147. UINT len = wcslen (ptr);
  1148. if (len <= 41)
  1149. continue;
  1150. *(ptr + len - 3) = NULL;
  1151. pInstallInfo->prgUpgradeInfoList[count].Flag = wcstoul(ptr+(len-2), &pStr, 16);
  1152. *(ptr + len - 3 - 36 - 2) = L'\0';
  1153. /* -GUID-'::'*/
  1154. GUIDFromString(ptr+len-3-36, &(pInstallInfo->prgUpgradeInfoList[count].PackageGuid));
  1155. }
  1156. pInstallInfo->cUpgrades = count; // we might have skipped some.
  1157. }
  1158. pPlatformInfo = pPackageDetail->pPlatformInfo =
  1159. (PLATFORMINFO *) CoTaskMemAlloc(sizeof (PLATFORMINFO));
  1160. if (!pPlatformInfo)
  1161. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  1162. memset(pPlatformInfo, NULL, sizeof(PLATFORMINFO));
  1163. posn = GetPropertyFromAttr(pAttr, cgot, ARCHLIST);
  1164. if (posn < cgot)
  1165. // Minor BUGBUG:: int converted to long.
  1166. UnpackDWArrFrom(pAttr[posn], &pdwArch, (unsigned long *)&(pPlatformInfo->cPlatforms));
  1167. pPlatformInfo->prgPlatform = (CSPLATFORM *)CoTaskMemAlloc(sizeof(CSPLATFORM)*
  1168. (pPlatformInfo->cPlatforms));
  1169. if (!(pPlatformInfo->prgPlatform))
  1170. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  1171. for (count = 0; (count < (pPlatformInfo->cPlatforms)); count++)
  1172. PackPlatform (pdwArch[count], (pPlatformInfo->prgPlatform)+count);
  1173. CoTaskMemFree(pdwArch);
  1174. posn = GetPropertyFromAttr(pAttr, cgot, LOCALEID);
  1175. if (posn < cgot)
  1176. // Minor BUGBUG:: int converted to long.
  1177. UnpackDWArrFrom(pAttr[posn], &(pPlatformInfo->prgLocale),
  1178. (unsigned long *)&(pPlatformInfo->cLocales));
  1179. //
  1180. // fill in ActivationInfo.
  1181. //
  1182. pActInfo = pPackageDetail->pActInfo =
  1183. (ACTIVATIONINFO *) CoTaskMemAlloc(sizeof (ACTIVATIONINFO));
  1184. if (!pActInfo) {
  1185. hr = E_OUTOFMEMORY;
  1186. ERROR_ON_FAILURE(hr);
  1187. }
  1188. memset(pActInfo, NULL, sizeof(ACTIVATIONINFO));
  1189. // get the progids so that we can eliminate progids from Clsids that do not match.
  1190. posn = GetPropertyFromAttr(pAttr, cgot, PKGCLSIDLIST);
  1191. cClasses = 0; szClasses = NULL;
  1192. if (posn < cgot)
  1193. UnpackStrArrFrom(pAttr[posn], &szClasses, &cClasses);
  1194. pActInfo->cClasses = cClasses;
  1195. if (cClasses)
  1196. {
  1197. pActInfo->pClasses = (CLASSDETAIL *) CoTaskMemAlloc (cClasses * sizeof(CLASSDETAIL));
  1198. if (!(pActInfo->pClasses))
  1199. return E_OUTOFMEMORY;
  1200. memset (pActInfo->pClasses, NULL, cClasses * sizeof(CLASSDETAIL));
  1201. for (count = 0; count < cClasses; count++)
  1202. {
  1203. WCHAR *szADsFullClassPath=NULL;
  1204. WCHAR szClassName[_MAX_PATH];
  1205. if (wcslen(szClasses[count]) > (STRINGGUIDLEN-1))
  1206. {
  1207. WCHAR *szPtr = NULL;
  1208. szClasses[count][STRINGGUIDLEN-1] = L'\0';
  1209. pActInfo->pClasses[count].dwComClassContext =
  1210. wcstoul(szClasses[count]+STRINGGUIDLEN, &szPtr, 16);
  1211. }
  1212. wsprintf(szClassName, L"CN=%s", szClasses[count]);
  1213. BuildADsPathFromParent(szClassContainerPath, szClassName, &szADsFullClassPath);
  1214. hr = GetClassDetail(szADsFullClassPath, &(pActInfo->pClasses[count]));
  1215. ERROR_ON_FAILURE(hr);
  1216. // remove all the progids that do not belong to this package.
  1217. FreeADsMem(szADsFullClassPath);
  1218. }
  1219. CoTaskMemFree(szClasses);
  1220. }
  1221. posn = GetPropertyFromAttr(pAttr, cgot, PKGIIDLIST);
  1222. cClasses = 0; szClasses = NULL;
  1223. if (posn < cgot)
  1224. UnpackStrArrFrom(pAttr[posn], &szClasses, &cClasses);
  1225. pActInfo->cInterfaces = cClasses;
  1226. if (cClasses)
  1227. {
  1228. pActInfo->prgInterfaceId = (IID *) CoTaskMemAlloc (cClasses * sizeof(GUID));
  1229. if (!(pActInfo->prgInterfaceId))
  1230. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  1231. for (count = 0; count < cClasses; count++)
  1232. {
  1233. GUIDFromString(szClasses[count], (pActInfo->prgInterfaceId + count));
  1234. }
  1235. CoTaskMemFree(szClasses);
  1236. }
  1237. posn = GetPropertyFromAttr(pAttr, cgot, PKGTLBIDLIST);
  1238. cClasses = 0; szClasses = NULL;
  1239. if (posn < cgot)
  1240. UnpackStrArrFrom(pAttr[posn], &szClasses, &cClasses);
  1241. pActInfo->cTypeLib = cClasses;
  1242. if (cClasses)
  1243. {
  1244. pActInfo->prgTlbId = (IID *) CoTaskMemAlloc (cClasses * sizeof(GUID));
  1245. if (!(pActInfo->prgTlbId))
  1246. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  1247. for (count = 0; count < cClasses; count++)
  1248. {
  1249. GUIDFromString(szClasses[count], (pActInfo->prgTlbId + count));
  1250. }
  1251. CoTaskMemFree(szClasses);
  1252. }
  1253. posn = GetPropertyFromAttr(pAttr, cgot, PKGFILEEXTNLIST);
  1254. cClasses = 0;
  1255. if (posn < cgot)
  1256. UnpackStrArrAllocFrom(pAttr[posn], &(pActInfo->prgShellFileExt), &cClasses);
  1257. pActInfo->cShellFileExt = cClasses;
  1258. if (cClasses)
  1259. {
  1260. pActInfo->prgPriority = (UINT *)CoTaskMemAlloc(cClasses * sizeof(UINT));
  1261. if (!(pActInfo->prgPriority))
  1262. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  1263. for (count = 0; count < cClasses; count++)
  1264. {
  1265. LPOLESTR pStr=NULL;
  1266. UINT cLen = wcslen((pActInfo->prgShellFileExt)[count]);
  1267. *((pActInfo->prgShellFileExt)[count] + (cLen - 3)) = NULL;
  1268. (pActInfo->prgPriority)[count] =
  1269. wcstoul((pActInfo->prgShellFileExt)[count]+(cLen-2), &pStr, 10);
  1270. }
  1271. }
  1272. //
  1273. // fill in package misc info
  1274. //
  1275. posn = GetPropertyFromAttr(pAttr, cgot, PACKAGENAME);
  1276. if (posn < cgot)
  1277. UnpackStrAllocFrom(pAttr[posn], &(pPackageDetail->pszPackageName));
  1278. else
  1279. ERROR_ON_FAILURE(hr=CS_E_OBJECT_NOTFOUND);
  1280. posn = GetPropertyFromAttr(pAttr, cgot, MSIFILELIST);
  1281. if (posn < cgot) {
  1282. LPOLESTR *rpszSourceList = NULL, psz = NULL, pStr = NULL;
  1283. DWORD Loc = 0;
  1284. UnpackStrArrFrom(pAttr[posn], &(rpszSourceList),
  1285. (DWORD *)&(pPackageDetail->cSources));
  1286. // reorder and allocate spaces.
  1287. if (pPackageDetail->cSources)
  1288. {
  1289. pPackageDetail->pszSourceList = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*
  1290. (pPackageDetail->cSources));
  1291. if (!(pPackageDetail->pszSourceList))
  1292. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  1293. for (count = 0; count < (pPackageDetail->cSources); count++)
  1294. {
  1295. psz = wcschr(rpszSourceList[count], L':');
  1296. *psz = L'\0';
  1297. Loc = wcstoul(rpszSourceList[count], &pStr, 10);
  1298. pPackageDetail->pszSourceList[Loc] = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR)*(wcslen(psz+1)+1));
  1299. if (!(pPackageDetail->pszSourceList[Loc]))
  1300. ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
  1301. wsprintf(pPackageDetail->pszSourceList[Loc], L"%s", psz+1);
  1302. }
  1303. }
  1304. CoTaskMemFree(rpszSourceList);
  1305. }
  1306. posn = GetPropertyFromAttr(pAttr, cgot, PKGCATEGORYLIST);
  1307. cClasses = 0; szClasses = NULL;
  1308. if (posn < cgot)
  1309. UnpackStrArrFrom(pAttr[posn], &szClasses, &cClasses);
  1310. if (cClasses)
  1311. {
  1312. pPackageDetail->rpCategory = (GUID *)CoTaskMemAlloc (sizeof(GUID) * cClasses);
  1313. if (!(pPackageDetail->rpCategory))
  1314. ERROR_ON_FAILURE(hr = E_OUTOFMEMORY);
  1315. pPackageDetail->cCategories = cClasses;
  1316. for (count = 0; count < cClasses; count++)
  1317. {
  1318. GUIDFromString(szClasses[count], (pPackageDetail->rpCategory + count));
  1319. }
  1320. CoTaskMemFree(szClasses);
  1321. }
  1322. return S_OK;
  1323. Error_Cleanup:
  1324. ReleasePackageDetail(pPackageDetail);
  1325. memset(pPackageDetail, 0, sizeof(PACKAGEDETAIL));
  1326. if (pAttr)
  1327. FreeADsMem(pAttr);
  1328. return hr;
  1329. }