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.

1488 lines
41 KiB

  1. //
  2. // Author: DebiM
  3. // Date: January 97
  4. //
  5. //
  6. // Class Store Administration Implementation
  7. //
  8. // This source file contains implementations for
  9. // IClassAdmin interface.
  10. //
  11. // It uses ADs interfaces (over LDAP) to talk to an LDAP
  12. // provider such as NTDS.
  13. //
  14. //---------------------------------------------------------------------
  15. #include "cstore.hxx"
  16. void GetCurrentUsn(LPOLESTR pStoreUsn);
  17. //----------------------------------------------------------
  18. // Implementation for CClassContainer
  19. //----------------------------------------------------------
  20. //
  21. CClassContainer::CClassContainer()
  22. {
  23. m_fOpen = FALSE;
  24. m_ADsContainer = NULL;
  25. m_pADsClassStore = NULL;
  26. m_ADsClassContainer = NULL;
  27. m_ADsPackageContainer = NULL;
  28. m_ADsCategoryContainer = NULL;
  29. m_uRefs = 1;
  30. StartQuery(&m_pIDBCreateCommand);
  31. }
  32. //
  33. // CClassContainer implementation
  34. //
  35. CClassContainer::CClassContainer(LPOLESTR szStoreName,
  36. HRESULT *phr)
  37. {
  38. IADs *pADs = NULL;
  39. LPOLESTR pszName = NULL;
  40. DWORD dwStoreVersion = 0;
  41. *phr = S_OK;
  42. m_fOpen = FALSE;
  43. m_ADsContainer = NULL;
  44. m_pADsClassStore = NULL;
  45. m_ADsClassContainer = NULL;
  46. m_ADsPackageContainer = NULL;
  47. m_ADsCategoryContainer = NULL;
  48. //
  49. // For every interface pointer, we create a separate Query session
  50. //
  51. StartQuery(&m_pIDBCreateCommand);
  52. // Bind to a Class Store Container Object
  53. // Cache the interface pointer
  54. //
  55. wcscpy (m_szContainerName, szStoreName);
  56. *phr = ADsGetObject(
  57. szStoreName,
  58. IID_IADsContainer,
  59. (void **)&m_ADsContainer
  60. );
  61. if (!SUCCEEDED(*phr))
  62. return;
  63. //
  64. // Check the Schema Version of this container
  65. //
  66. *phr = m_ADsContainer->QueryInterface (IID_IADs, (void **)&m_pADsClassStore);
  67. if (!SUCCEEDED(*phr))
  68. return;
  69. *phr = GetPropertyDW (m_pADsClassStore, STOREVERSION, &dwStoreVersion);
  70. if ((!SUCCEEDED(*phr)) ||
  71. (dwStoreVersion != SCHEMA_VERSION_NUMBER))
  72. {
  73. *phr = CS_E_INVALID_VERSION;
  74. return;
  75. }
  76. //
  77. // Bind to the class container Object
  78. // Cache the interface pointer
  79. //
  80. m_ADsClassContainer = NULL;
  81. *phr = m_ADsContainer->GetObject(
  82. NULL,
  83. CLASSCONTAINERNAME,
  84. (IDispatch **)&pADs
  85. );
  86. if (!SUCCEEDED(*phr))
  87. return;
  88. pADs->QueryInterface(IID_IADsContainer,
  89. (void **)&m_ADsClassContainer
  90. );
  91. *phr = pADs->get_ADsPath(&pszName);
  92. wcscpy (m_szClassName, pszName);
  93. SysFreeString(pszName);
  94. pADs->Release();
  95. pADs = NULL;
  96. if (!SUCCEEDED(*phr))
  97. return;
  98. //
  99. // Bind to the Package container Object
  100. // Cache the interface pointer
  101. //
  102. m_ADsPackageContainer = NULL;
  103. *phr = m_ADsContainer->GetObject(
  104. NULL,
  105. PACKAGECONTAINERNAME,
  106. (IDispatch **)&pADs);
  107. if (!SUCCEEDED(*phr))
  108. return;
  109. pADs->QueryInterface(IID_IADsContainer,
  110. (void **)&m_ADsPackageContainer
  111. );
  112. *phr = pADs->get_ADsPath(&pszName);
  113. wcscpy (m_szPackageName, pszName);
  114. SysFreeString(pszName);
  115. pADs->Release();
  116. pADs = NULL;
  117. if (!SUCCEEDED(*phr))
  118. return;
  119. //
  120. // Bind to the category container Object
  121. // Cache the interface pointer
  122. //
  123. m_ADsCategoryContainer = NULL;
  124. *phr = m_ADsContainer->GetObject(
  125. NULL,
  126. CATEGORYCONTAINERNAME,
  127. (IDispatch **)&pADs);
  128. if (!SUCCEEDED(*phr))
  129. return;
  130. pADs->QueryInterface(IID_IADsContainer,
  131. (void **)&m_ADsCategoryContainer
  132. );
  133. pADs->Release();
  134. pADs = NULL;
  135. m_fOpen = TRUE;
  136. m_uRefs = 1;
  137. return;
  138. }
  139. CClassContainer::~CClassContainer(void)
  140. {
  141. UINT i;
  142. EndQuery(m_pIDBCreateCommand);
  143. m_pIDBCreateCommand = NULL;
  144. if (m_fOpen)
  145. {
  146. m_fOpen = FALSE;
  147. }
  148. if (m_ADsClassContainer)
  149. {
  150. m_ADsClassContainer->Release();
  151. m_ADsClassContainer = NULL;
  152. }
  153. if (m_ADsPackageContainer)
  154. {
  155. m_ADsPackageContainer->Release();
  156. m_ADsPackageContainer = NULL;
  157. }
  158. if (m_ADsCategoryContainer)
  159. {
  160. m_ADsCategoryContainer->Release();
  161. m_ADsCategoryContainer = NULL;
  162. }
  163. if (m_ADsContainer)
  164. {
  165. m_ADsContainer->Release();
  166. m_ADsContainer = NULL;
  167. }
  168. if (m_pADsClassStore)
  169. {
  170. m_pADsClassStore->Release();
  171. m_pADsClassStore = NULL;
  172. }
  173. }
  174. //
  175. // Removing a class from the database
  176. //
  177. HRESULT CClassContainer::DeleteClass (LPOLESTR szClsid)
  178. {
  179. WCHAR szName[_MAX_PATH];
  180. HRESULT hr = S_OK;
  181. IADs *pADs = NULL;
  182. DWORD refcount = 0;
  183. if (!m_fOpen)
  184. return E_FAIL;
  185. wsprintf(szName, L"CN=%s", szClsid);
  186. hr = m_ADsClassContainer->GetObject(NULL, szName, (IDispatch **)&pADs);
  187. if (SUCCEEDED(hr))
  188. hr = GetPropertyDW(pADs, CLASSREFCOUNTER, &refcount);
  189. if (refcount <= 1)
  190. hr = m_ADsClassContainer->Delete(CLASS_CS_CLASS, szName);
  191. else {
  192. refcount--;
  193. hr = SetPropertyDW(pADs, CLASSREFCOUNTER, refcount);
  194. if (SUCCEEDED(hr))
  195. hr = StoreIt(pADs);
  196. }
  197. if (pADs)
  198. pADs->Release();
  199. return hr;
  200. }
  201. extern LPOLESTR szPackageInfoColumns;
  202. HRESULT CClassContainer::EnumPackages(
  203. LPOLESTR pszFileExt,
  204. GUID *pCategory,
  205. DWORD dwAppFlags,
  206. DWORD *pdwLocale,
  207. CSPLATFORM *pPlatform,
  208. IEnumPackage **ppIEnumPackage
  209. )
  210. {
  211. HRESULT hr = S_OK;
  212. CEnumPackage *pEnum = NULL;
  213. WCHAR szCommand[1000], szQry[1000];
  214. if (pszFileExt && IsBadStringPtr(pszFileExt, _MAX_PATH))
  215. return E_INVALIDARG;
  216. if (pCategory && !IsValidReadPtrIn(pCategory, sizeof(GUID)))
  217. return E_INVALIDARG;
  218. if (!IsValidPtrOut(ppIEnumPackage, sizeof(IEnumPackage *)))
  219. return E_INVALIDARG;
  220. *ppIEnumPackage = NULL;
  221. pEnum = new CEnumPackage;
  222. if(NULL == pEnum)
  223. return E_OUTOFMEMORY;
  224. //
  225. // Create a CommandText
  226. //
  227. wsprintf(szCommand, L"<%s>;(& (objectClass=packageRegistration) ", m_szPackageName);
  228. if (pszFileExt)
  229. {
  230. wsprintf(szQry, L"(%s=%s*) ", PKGFILEEXTNLIST, pszFileExt);
  231. wcscat(szCommand, szQry);
  232. }
  233. if (pCategory)
  234. {
  235. STRINGGUID szCat;
  236. StringFromGUID (*pCategory, szCat);
  237. wsprintf(szQry, L"(%s=%s) ", PKGCATEGORYLIST, szCat);
  238. wcscat(szCommand, szQry);
  239. }
  240. wcscat(szCommand, L");");
  241. wsprintf(szQry, L" %s", szPackageInfoColumns);
  242. wcscat(szCommand, szQry);
  243. hr = pEnum->Initialize(szCommand, dwAppFlags, pdwLocale, pPlatform);
  244. if (FAILED(hr)) {
  245. delete pEnum;
  246. return hr;
  247. }
  248. hr = pEnum->QueryInterface(IID_IEnumPackage, (void**)ppIEnumPackage);
  249. return hr;
  250. }
  251. // GetPackageDetails
  252. // pszPackageName : name of the package to be got.
  253. // pInstallInfo : InstallInfo to be filled in. ignored if NULL.
  254. // pPlatformInfo : PlatformInfo to be filled in. ignored if NULL.
  255. // both can be sent in as NULL to check whether package exists or not.
  256. HRESULT CClassContainer::GetPackageDetails (
  257. LPOLESTR pszPackageName,
  258. PACKAGEDETAIL *pPackageDetail)
  259. {
  260. HRESULT hr = S_OK;
  261. IADs *pPackageADs = NULL;
  262. WCHAR szRdn [_MAX_PATH];
  263. if ((!pszPackageName) || IsBadStringPtr(pszPackageName, _MAX_PATH))
  264. return E_INVALIDARG;
  265. wcscpy (szRdn, L"CN=");
  266. wcscat (szRdn, pszPackageName);
  267. hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pPackageADs);
  268. if (!SUCCEEDED(hr))
  269. return CS_E_PACKAGE_NOTFOUND;
  270. hr = GetPackageDetail (pPackageADs, pPackageDetail);
  271. return hr;
  272. }
  273. HRESULT CClassContainer::ChangePackageProperties(
  274. LPOLESTR pszPackageName,
  275. LPOLESTR pszNewName,
  276. DWORD *pdwFlags,
  277. LPOLESTR pszUrl,
  278. LPOLESTR pszScriptPath,
  279. UINT *pInstallUiLevel
  280. )
  281. {
  282. HRESULT hr = S_OK;
  283. IADs *pPackageADs = NULL;
  284. WCHAR szRdn [_MAX_PATH];
  285. WCHAR szNewRdn [_MAX_PATH];
  286. LPOLESTR pszPackageDN;
  287. WCHAR Usn[20];
  288. if ((!pszPackageName) || IsBadStringPtr(pszPackageName, _MAX_PATH))
  289. return E_INVALIDARG;
  290. wcscpy (szRdn, L"CN=");
  291. wcscat (szRdn, pszPackageName);
  292. if (pszNewName)
  293. {
  294. //
  295. // rename package
  296. //
  297. if (IsBadStringPtr(pszNewName, _MAX_PATH))
  298. return E_INVALIDARG;
  299. //
  300. // Check to see if any other change is requested.
  301. //
  302. if (pszScriptPath ||
  303. pszUrl ||
  304. pdwFlags ||
  305. pInstallUiLevel)
  306. return E_INVALIDARG;
  307. BuildADsPathFromParent (m_szPackageName, szRdn, &pszPackageDN);
  308. wcscpy (szNewRdn, L"CN=");
  309. wcscat (szNewRdn, pszNewName);
  310. hr = m_ADsPackageContainer->MoveHere(pszPackageDN, szNewRdn, (IDispatch **)&pPackageADs);
  311. FreeADsMem(pszPackageDN);
  312. if (SUCCEEDED(hr))
  313. {
  314. hr = SetProperty(pPackageADs, PACKAGENAME, pszNewName);
  315. if (SUCCEEDED(hr))
  316. hr = StoreIt(pPackageADs);
  317. pPackageADs->Release();
  318. }
  319. return hr;
  320. }
  321. if (!(pszScriptPath ||
  322. pszUrl ||
  323. pdwFlags ||
  324. pInstallUiLevel))
  325. return E_INVALIDARG;
  326. //
  327. // No rename.
  328. // Just change some properties.
  329. //
  330. hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pPackageADs);
  331. if (!SUCCEEDED(hr))
  332. return CS_E_PACKAGE_NOTFOUND;
  333. //
  334. // Update the TimeStamp
  335. //
  336. GetCurrentUsn(&Usn[0]);
  337. hr = UsnUpd(pPackageADs, PKGUSN, &Usn[0]);
  338. ERROR_ON_FAILURE(hr);
  339. //
  340. // Change Package Flags
  341. //
  342. if (pdwFlags)
  343. {
  344. hr = SetPropertyDW (pPackageADs, PACKAGEFLAGS, *pdwFlags);
  345. ERROR_ON_FAILURE(hr);
  346. }
  347. //
  348. // Change Package Script
  349. //
  350. if (pszScriptPath)
  351. {
  352. hr = SetProperty(pPackageADs, SCRIPTPATH, pszScriptPath);
  353. ERROR_ON_FAILURE(hr);
  354. }
  355. //
  356. // Change Package Help URL
  357. //
  358. if (pszUrl)
  359. {
  360. hr = SetProperty(pPackageADs, HELPURL, pszUrl);
  361. ERROR_ON_FAILURE(hr);
  362. }
  363. //
  364. // Change UI Level
  365. //
  366. if (pInstallUiLevel)
  367. {
  368. hr = SetPropertyDW (pPackageADs, UILEVEL, *pInstallUiLevel);
  369. ERROR_ON_FAILURE(hr);
  370. }
  371. hr = StoreIt(pPackageADs);
  372. Error_Cleanup:
  373. pPackageADs->Release();
  374. return hr;
  375. }
  376. HRESULT CClassContainer::ChangePackageCategories(
  377. LPOLESTR pszPackageName,
  378. UINT cCategories,
  379. GUID *rpCategory
  380. )
  381. {
  382. //
  383. // Does not change USN
  384. //
  385. HRESULT hr = S_OK;
  386. IADs *pPackageADs = NULL;
  387. WCHAR szRdn [_MAX_PATH];
  388. LPOLESTR *pszGuid = NULL;
  389. UINT count;
  390. wcscpy (szRdn, L"CN=");
  391. wcscat (szRdn, pszPackageName);
  392. if ((!cCategories) ||
  393. (!rpCategory) ||
  394. (!IsValidReadPtrIn(rpCategory, sizeof(GUID) * cCategories)))
  395. return E_INVALIDARG;
  396. hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pPackageADs);
  397. if (!SUCCEEDED(hr))
  398. return CS_E_PACKAGE_NOTFOUND;
  399. // fill in the categories
  400. pszGuid = (LPOLESTR *)CoTaskMemAlloc(cCategories * sizeof(LPOLESTR));
  401. if (!pszGuid)
  402. {
  403. hr = E_OUTOFMEMORY;
  404. ERROR_ON_FAILURE(hr);
  405. }
  406. for (count = 0; (count < cCategories); count++)
  407. {
  408. pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(STRINGGUIDLEN*sizeof(WCHAR));
  409. {
  410. hr = E_OUTOFMEMORY;
  411. ERROR_ON_FAILURE(hr);
  412. }
  413. StringFromGUID(rpCategory[count], pszGuid[count]);
  414. }
  415. hr = SetPropertyList(pPackageADs, PKGCATEGORYLIST, cCategories,
  416. pszGuid);
  417. ERROR_ON_FAILURE(hr);
  418. for (count = 0; (count < cCategories); count++)
  419. CoTaskMemFree(pszGuid[count]);
  420. CoTaskMemFree(pszGuid);
  421. hr = StoreIt(pPackageADs);
  422. Error_Cleanup:
  423. pPackageADs->Release();
  424. return hr;
  425. }
  426. HRESULT CClassContainer::SetPriorityByFileExt(
  427. LPOLESTR pszPackageName,
  428. LPOLESTR pszFileExt,
  429. UINT Priority
  430. )
  431. {
  432. //
  433. // Does not change USN
  434. //
  435. HRESULT hr = S_OK;
  436. IADs *pPackageADs = NULL;
  437. WCHAR szRdn [_MAX_PATH];
  438. LPOLESTR *prgFileExt = NULL;
  439. ULONG cShellFileExt;
  440. UINT i;
  441. wcscpy (szRdn, L"CN=");
  442. wcscat (szRdn, pszPackageName);
  443. hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pPackageADs);
  444. if (!SUCCEEDED(hr))
  445. return CS_E_PACKAGE_NOTFOUND;
  446. hr = GetPropertyListAlloc (pPackageADs, PKGFILEEXTNLIST,
  447. &cShellFileExt,
  448. &prgFileExt);
  449. for (i=0; i < cShellFileExt; ++i)
  450. {
  451. if (wcsncmp(prgFileExt[i], pszFileExt, wcslen(pszFileExt)) == 0)
  452. {
  453. wsprintf(prgFileExt[i], L"%s:%2d",
  454. pszFileExt,
  455. Priority);
  456. break;
  457. }
  458. }
  459. if (i == cShellFileExt)
  460. {
  461. hr = CS_E_PACKAGE_NOTFOUND;
  462. ERROR_ON_FAILURE(hr);
  463. }
  464. hr = SetPropertyList(pPackageADs, PKGFILEEXTNLIST, cShellFileExt, prgFileExt);
  465. hr = StoreIt(pPackageADs);
  466. Error_Cleanup:
  467. pPackageADs->Release();
  468. return hr;
  469. }
  470. extern LPOLESTR szAppCategoryColumns;
  471. HRESULT CClassContainer::GetAppCategories (
  472. LCID Locale,
  473. APPCATEGORYINFOLIST *pAppCategoryList
  474. )
  475. {
  476. HRESULT hr = S_OK;
  477. WCHAR szCommand[1000], szQry[1000];
  478. WCHAR szRootPath[_MAX_PATH],
  479. szAppCategoryContainer[_MAX_PATH];
  480. IRowset * pIRow = NULL;
  481. HACCESSOR HAcc;
  482. IAccessor * pIAccessor = NULL;
  483. IDBCreateCommand * pIDBCreateCommand = NULL;
  484. LPOLESTR ** ppszDesc = NULL;
  485. DWORD cgot = 0;
  486. if (!IsValidPtrOut(pAppCategoryList, sizeof(APPCATEGORYINFOLIST)))
  487. return E_INVALIDARG;
  488. hr = GetRootPath(szRootPath);
  489. wsprintf(szAppCategoryContainer, L"%s%s%s", LDAPPREFIX,
  490. APPCATEGORYCONTAINERNAME, szRootPath+wcslen(LDAPPREFIX));
  491. wsprintf(szCommand, L"<%s>; (objectClass=categoryRegistration); %s", szAppCategoryContainer,
  492. szAppCategoryColumns);
  493. hr = StartQuery(&(pIDBCreateCommand));
  494. RETURN_ON_FAILURE(hr);
  495. hr = ExecuteQuery (pIDBCreateCommand,
  496. szCommand,
  497. APPCATEGORY_COLUMN_COUNT,
  498. NULL,
  499. &HAcc,
  500. &pIAccessor,
  501. &pIRow
  502. );
  503. RETURN_ON_FAILURE(hr);
  504. pAppCategoryList->cCategory = 500;
  505. // upper limit presently.
  506. hr = FetchCategory(pIRow,
  507. HAcc,
  508. (pAppCategoryList->cCategory),
  509. &cgot,
  510. &(pAppCategoryList->pCategoryInfo),
  511. Locale);
  512. pAppCategoryList->cCategory = cgot;
  513. CloseQuery(pIAccessor,
  514. HAcc,
  515. pIRow);
  516. EndQuery(pIDBCreateCommand);
  517. return hr;
  518. }
  519. HRESULT CClassContainer::RegisterAppCategory (
  520. APPCATEGORYINFO *pAppCategory
  521. )
  522. {
  523. WCHAR szRootPath[_MAX_PATH], *localedescription = NULL,
  524. szAppCategoryContainer[_MAX_PATH], szRDN[_MAX_PATH];
  525. HRESULT hr = S_OK;
  526. IADsContainer *pADsContainer = NULL;
  527. IADs *pADs = NULL;
  528. IDispatch *pUnknown = NULL;
  529. ULONG i, j, cdesc, posn;
  530. LPOLESTR *pszDescExisting = NULL, *pszDesc = NULL;
  531. if (!pAppCategory || !IsValidReadPtrIn(pAppCategory, sizeof(APPCATEGORYINFO)))
  532. return E_INVALIDARG;
  533. if ((pAppCategory->pszDescription == NULL) ||
  534. IsBadStringPtr(pAppCategory->pszDescription, _MAX_PATH))
  535. return E_INVALIDARG;
  536. if (IsNullGuid(pAppCategory->AppCategoryId))
  537. return E_INVALIDARG;
  538. hr = GetRootPath(szRootPath);
  539. // Bind to a AppCategory container
  540. wsprintf(szAppCategoryContainer, L"%s%s%s", LDAPPREFIX,
  541. APPCATEGORYCONTAINERNAME, szRootPath+wcslen(LDAPPREFIX));
  542. hr = ADsGetObject(
  543. szAppCategoryContainer,
  544. IID_IADsContainer,
  545. (void **)&pADsContainer
  546. );
  547. RETURN_ON_FAILURE(hr);
  548. RdnFromGUID(pAppCategory->AppCategoryId, szRDN);
  549. localedescription = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR)*(128+16));
  550. wsprintf(localedescription, L"%x %s %s", pAppCategory->Locale, CATSEPERATOR,
  551. pAppCategory->pszDescription);
  552. hr = pADsContainer->GetObject(NULL, szRDN, (IDispatch **)&pADs);
  553. if (SUCCEEDED(hr))
  554. {
  555. hr = GetPropertyListAlloc (pADs, LOCALEDESCRIPTION, &cdesc, &pszDescExisting);
  556. ERROR_ON_FAILURE(hr);
  557. // Existing list of descriptions
  558. pszDesc = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*(cdesc+1));
  559. if ((cdesc) && (!pszDesc)) {
  560. hr = E_OUTOFMEMORY;
  561. ERROR_ON_FAILURE(hr);
  562. }
  563. for (j = 0; j < cdesc; j++)
  564. pszDesc[j] = pszDescExisting[j];
  565. if (!(posn = FindDescription(pszDescExisting, cdesc, &(pAppCategory->Locale), NULL, 0)))
  566. {
  567. // if no description exists for the lcid.
  568. pszDesc[cdesc] = localedescription;
  569. cdesc++;
  570. }
  571. else
  572. { // overwrite the old value
  573. CoTaskMemFree(pszDesc[posn-1]);
  574. pszDesc[posn-1] = localedescription;
  575. }
  576. }
  577. else
  578. {
  579. hr = pADsContainer->Create(
  580. CLASS_CS_CATEGORY,
  581. szRDN,
  582. &pUnknown
  583. );
  584. ERROR_ON_FAILURE(hr);
  585. pszDesc = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR));
  586. if (!pszDesc) {
  587. hr = E_OUTOFMEMORY;
  588. ERROR_ON_FAILURE(hr);
  589. }
  590. cdesc = 1;
  591. pszDesc[0] = localedescription;
  592. hr = pUnknown->QueryInterface(IID_IADs, (void **)&pADs);
  593. RETURN_ON_FAILURE(hr);
  594. pUnknown->Release();
  595. }
  596. hr = SetPropertyGuid(pADs, CATEGORYCATID, pAppCategory->AppCategoryId);
  597. ERROR_ON_FAILURE(hr);
  598. hr = SetPropertyList(pADs, LOCALEDESCRIPTION, cdesc, pszDesc);
  599. for (j = 0; j < cdesc; j++)
  600. CoTaskMemFree(pszDesc[j]);
  601. CoTaskMemFree(pszDesc);
  602. ERROR_ON_FAILURE(hr);
  603. hr = StoreIt(pADs);
  604. ERROR_ON_FAILURE(hr);
  605. Error_Cleanup:
  606. if (pADs)
  607. pADs->Release();
  608. if (pADsContainer)
  609. pADsContainer->Release();
  610. // Add this category.
  611. return hr;
  612. }
  613. HRESULT CClassContainer::UnregisterAppCategory (
  614. GUID *pAppCategoryId
  615. )
  616. {
  617. WCHAR szRootPath[_MAX_PATH], szRDN[_MAX_PATH],
  618. szAppCategoryContainer[_MAX_PATH];
  619. HRESULT hr = S_OK;
  620. IADsContainer *pADsContainer = NULL;
  621. if (!IsValidReadPtrIn(pAppCategoryId, sizeof(GUID)))
  622. return E_INVALIDARG;
  623. hr = GetRootPath(szRootPath);
  624. // Bind to a AppCategory container
  625. wsprintf(szAppCategoryContainer, L"%s%s%s", LDAPPREFIX,
  626. APPCATEGORYCONTAINERNAME, szRootPath+wcslen(LDAPPREFIX));
  627. hr = ADsGetObject(
  628. szAppCategoryContainer,
  629. IID_IADsContainer,
  630. (void **)&pADsContainer
  631. );
  632. RETURN_ON_FAILURE(hr);
  633. RdnFromGUID(*pAppCategoryId, szRDN);
  634. hr = pADsContainer->Delete(CLASS_CS_CATEGORY, szRDN);
  635. pADsContainer->Release();
  636. // Delete this category
  637. return hr;
  638. }
  639. //+
  640. HRESULT CClassContainer::RemovePackage (LPOLESTR pszPackageName)
  641. //
  642. // Remove a Package and the associated Classes from class store
  643. //
  644. {
  645. HRESULT hr = S_OK;
  646. IADs *pADs = NULL;
  647. DWORD cClasses = 0, count = 0;
  648. WCHAR szRdn [_MAX_PATH];
  649. LPOLESTR *szClasses;
  650. if ((!pszPackageName) || IsBadStringPtr(pszPackageName, _MAX_PATH))
  651. return E_INVALIDARG;
  652. if ((pszPackageName == NULL) ||
  653. (*(pszPackageName) == NULL))
  654. return E_INVALIDARG;
  655. wcscpy (szRdn, L"CN=");
  656. wcscat (szRdn, pszPackageName);
  657. if (!m_fOpen)
  658. return E_FAIL;
  659. hr = m_ADsPackageContainer->GetObject(NULL, szRdn, (IDispatch **)&pADs);
  660. RETURN_ON_FAILURE(hr);
  661. hr = GetPropertyListAlloc(pADs, PKGCLSIDLIST, &cClasses, &szClasses);
  662. for (count = 0; count < cClasses; count++)
  663. hr = DeleteClass(szClasses[count]);
  664. // ignore errors
  665. for (count = 0; count < cClasses; count++)
  666. CoTaskMemFree(szClasses[count]);
  667. CoTaskMemFree(szClasses);
  668. pADs->Release();
  669. hr = m_ADsPackageContainer->Delete(CLASS_CS_PACKAGE, szRdn);
  670. return hr;
  671. }
  672. //+
  673. HRESULT CClassContainer::NewClass (CLASSDETAIL *pClassDetail)
  674. //
  675. // Add a new class to the database
  676. //
  677. {
  678. HRESULT hr = S_OK;
  679. IADs * pADs = NULL;
  680. IDispatch * pUnknown = NULL;
  681. STRINGGUID szGUID;
  682. WCHAR szRDN [_MAX_PATH];
  683. if (!m_fOpen)
  684. return E_FAIL;
  685. //
  686. // Cant be a NULL guid
  687. //
  688. if (IsNullGuid(pClassDetail->Clsid))
  689. return E_INVALIDARG;
  690. StringFromGUID(pClassDetail->Clsid, szGUID);
  691. //
  692. // Create the RDN for the Class Object
  693. //
  694. // BUGBUG:: attaching package name creates problems.
  695. wsprintf(szRDN, L"CN=%s", szGUID);
  696. hr = m_ADsClassContainer->Create(
  697. CLASS_CS_CLASS,
  698. szRDN,
  699. &pUnknown
  700. );
  701. RETURN_ON_FAILURE(hr);
  702. hr = pUnknown->QueryInterface(
  703. IID_IADs,
  704. (void **)&pADs
  705. );
  706. pUnknown->Release();
  707. hr = SetProperty (pADs, CLASSCLSID, szGUID);
  708. ERROR_ON_FAILURE(hr);
  709. if (pClassDetail->cProgId)
  710. {
  711. hr = SetPropertyList(pADs, PROGIDLIST, pClassDetail->cProgId,
  712. pClassDetail->prgProgId);
  713. ERROR_ON_FAILURE(hr);
  714. }
  715. if (!IsNullGuid(pClassDetail->TreatAs))
  716. {
  717. StringFromGUID(pClassDetail->TreatAs, szGUID);
  718. hr = SetProperty (pADs, TREATASCLSID, szGUID);
  719. ERROR_ON_FAILURE(hr);
  720. }
  721. hr = SetPropertyDW(pADs, CLASSREFCOUNTER, 1);
  722. ERROR_ON_FAILURE(hr);
  723. hr = StoreIt (pADs);
  724. // this does not return an error for an alreay existing entry.
  725. if (hr == E_ADS_LDAP_ALREADY_EXISTS)
  726. {
  727. DWORD refcount = 0;
  728. pADs->Release(); // release the interface pointer already got.
  729. hr = m_ADsClassContainer->GetObject(NULL, // CLASS_CS_CLASS
  730. szRDN,
  731. (IDispatch **)&pADs);
  732. RETURN_ON_FAILURE(hr);
  733. if (pClassDetail->cProgId)
  734. {
  735. hr = SetPropertyListMerge(pADs, PROGIDLIST, pClassDetail->cProgId,
  736. pClassDetail->prgProgId);
  737. ERROR_ON_FAILURE(hr);
  738. }
  739. // increment reference counter.
  740. hr = GetPropertyDW(pADs, CLASSREFCOUNTER, &refcount);
  741. ERROR_ON_FAILURE(hr);
  742. refcount++;
  743. hr = SetPropertyDW(pADs, CLASSREFCOUNTER, refcount);
  744. ERROR_ON_FAILURE(hr);
  745. // No merging of the treatas.
  746. hr = StoreIt(pADs);
  747. }
  748. Error_Cleanup:
  749. pADs->Release();
  750. return hr;
  751. }
  752. #define SCRIPT_IN_DIRECTORY 256
  753. HRESULT CClassContainer::AddPackage(LPOLESTR pszPackageName,
  754. PACKAGEDETAIL *pPackageDetail)
  755. {
  756. HRESULT hr;
  757. IADs *pPackageADs = NULL;
  758. IDispatch *pUnknown = NULL;
  759. WCHAR szRDN [_MAX_PATH];
  760. LPOLESTR *pszGuid, *pszProgId;
  761. DWORD *pdwArch=NULL, count = 0, cPackProgId = 0;
  762. WCHAR Usn[20];
  763. if (!pszPackageName)
  764. return E_INVALIDARG;
  765. if (!pPackageDetail)
  766. return E_INVALIDARG;
  767. if (!IsValidReadPtrIn(pPackageDetail, sizeof(PACKAGEDETAIL)))
  768. return E_INVALIDARG;
  769. LPWSTR pName = pszPackageName;
  770. while (*pName)
  771. {
  772. if ((*pName == L':') ||
  773. (*pName == L',') ||
  774. (*pName == L';') ||
  775. (*pName == L'/') ||
  776. (*pName == L'<') ||
  777. (*pName == L'>') ||
  778. (*pName == L'\\'))
  779. return E_INVALIDARG;
  780. ++pName;
  781. }
  782. // Validating ActivationInfo
  783. if (pPackageDetail->pActInfo)
  784. {
  785. if (!IsValidReadPtrIn(pPackageDetail->pActInfo, sizeof(ACTIVATIONINFO)))
  786. return E_INVALIDARG;
  787. if (!IsValidReadPtrIn(pPackageDetail->pActInfo->pClasses,
  788. sizeof(CLASSDETAIL) * (pPackageDetail->pActInfo->cClasses)))
  789. return E_INVALIDARG;
  790. if (!IsValidReadPtrIn(pPackageDetail->pActInfo->prgShellFileExt,
  791. sizeof(LPOLESTR) * (pPackageDetail->pActInfo->cShellFileExt)))
  792. return E_INVALIDARG;
  793. for (count = 0; count < (pPackageDetail->pActInfo->cShellFileExt); count++)
  794. {
  795. if (!pPackageDetail->pActInfo->prgShellFileExt[count])
  796. return E_INVALIDARG;
  797. }
  798. if (!IsValidReadPtrIn(pPackageDetail->pActInfo->prgPriority,
  799. sizeof(UINT) * (pPackageDetail->pActInfo->cShellFileExt)))
  800. return E_INVALIDARG;
  801. if (!IsValidReadPtrIn(pPackageDetail->pActInfo->prgInterfaceId,
  802. sizeof(IID) * (pPackageDetail->pActInfo->cInterfaces)))
  803. return E_INVALIDARG;
  804. if (!IsValidReadPtrIn(pPackageDetail->pActInfo->prgTlbId,
  805. sizeof(GUID) * (pPackageDetail->pActInfo->cTypeLib)))
  806. return E_INVALIDARG;
  807. }
  808. // Validating InstallInfo
  809. if ((pPackageDetail->pInstallInfo == NULL) ||
  810. (!IsValidReadPtrIn(pPackageDetail->pInstallInfo, sizeof(INSTALLINFO)))
  811. )
  812. return E_INVALIDARG;
  813. if (!IsValidReadPtrIn(pPackageDetail->pInstallInfo->prgUpgradeFlag,
  814. sizeof(DWORD)*(pPackageDetail->pInstallInfo->cUpgrades)))
  815. return E_INVALIDARG;
  816. if (!IsValidReadPtrIn(pPackageDetail->pInstallInfo->prgUpgradeScript,
  817. sizeof(LPOLESTR)*(pPackageDetail->pInstallInfo->cUpgrades)))
  818. return E_INVALIDARG;
  819. for (count = 0; count < (pPackageDetail->pInstallInfo->cUpgrades); count++)
  820. {
  821. if ((!(pPackageDetail->pInstallInfo->prgUpgradeScript[count])) ||
  822. IsBadStringPtr((pPackageDetail->pInstallInfo->prgUpgradeScript[count]), _MAX_PATH))
  823. return E_INVALIDARG;
  824. if ((pPackageDetail->pInstallInfo->prgUpgradeFlag[count] != UPGFLG_Uninstall) &&
  825. (pPackageDetail->pInstallInfo->prgUpgradeFlag[count] != UPGFLG_NoUninstall))
  826. return E_INVALIDARG;
  827. }
  828. // Validating PlatformInfo
  829. if ((pPackageDetail->pPlatformInfo == NULL) ||
  830. (!IsValidReadPtrIn(pPackageDetail->pPlatformInfo, sizeof(PLATFORMINFO)))
  831. )
  832. return E_INVALIDARG;
  833. if (!IsValidReadPtrIn(pPackageDetail->pPlatformInfo->prgPlatform,
  834. sizeof(CSPLATFORM) * (pPackageDetail->pPlatformInfo->cPlatforms)))
  835. return E_INVALIDARG;
  836. if ((pPackageDetail->pPlatformInfo->cLocales == 0) ||
  837. (pPackageDetail->pPlatformInfo->cPlatforms == 0))
  838. return E_INVALIDARG;
  839. if (!IsValidReadPtrIn(pPackageDetail->pPlatformInfo->prgLocale,
  840. sizeof(LCID) * (pPackageDetail->pPlatformInfo->cLocales)))
  841. return E_INVALIDARG;
  842. // Validating other fields in PackageDetail structure
  843. if ((pPackageDetail->pszSourceList == NULL) ||
  844. (!IsValidReadPtrIn(pPackageDetail->pszSourceList,
  845. sizeof(LPOLESTR) * (pPackageDetail->cSources)))
  846. )
  847. return E_INVALIDARG;
  848. for (count = 0; count < (pPackageDetail->cSources); count++)
  849. if (!pPackageDetail->pszSourceList[count])
  850. return E_INVALIDARG;
  851. if (pPackageDetail->rpCategory)
  852. {
  853. if (!IsValidReadPtrIn(pPackageDetail->rpCategory,
  854. sizeof(GUID) * (pPackageDetail->cCategories)))
  855. return E_INVALIDARG;
  856. }
  857. //
  858. // Now we create the package
  859. //
  860. wcscpy (szRDN, L"CN=");
  861. wcscat (szRDN, pszPackageName);
  862. pUnknown = NULL;
  863. hr = m_ADsPackageContainer->Create(
  864. CLASS_CS_PACKAGE,
  865. szRDN,
  866. &pUnknown
  867. );
  868. RETURN_ON_FAILURE(hr);
  869. hr = pUnknown->QueryInterface(
  870. IID_IADs,
  871. (void **)&pPackageADs
  872. );
  873. pUnknown->Release();
  874. // fill in the activation info
  875. if (pPackageDetail->pActInfo)
  876. {
  877. if ((pPackageDetail->pActInfo)->cClasses)
  878. {
  879. pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->pActInfo->cClasses)*sizeof(LPOLESTR));
  880. if (!pszGuid)
  881. {
  882. hr = E_OUTOFMEMORY;
  883. ERROR_ON_FAILURE(hr);
  884. }
  885. for (count = 0; count < pPackageDetail->pActInfo->cClasses; count++)
  886. {
  887. pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR)*STRINGGUIDLEN);
  888. StringFromGUID(pPackageDetail->pActInfo->pClasses[count].Clsid, pszGuid[count]);
  889. cPackProgId += pPackageDetail->pActInfo->pClasses[count].cProgId;
  890. }
  891. hr = SetPropertyList(pPackageADs, PKGCLSIDLIST, (pPackageDetail->pActInfo)->cClasses, pszGuid);
  892. ERROR_ON_FAILURE(hr);
  893. for (count = 0; (count < pPackageDetail->pActInfo->cClasses); count++)
  894. CoTaskMemFree(pszGuid[count]);
  895. CoTaskMemFree(pszGuid);
  896. }
  897. // collecting all the progids from the various clsids.
  898. if (cPackProgId)
  899. {
  900. pszProgId = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*cPackProgId);
  901. if (!pszProgId)
  902. {
  903. hr = E_OUTOFMEMORY;
  904. ERROR_ON_FAILURE(hr);
  905. }
  906. for (count = 0, cPackProgId = 0; count < pPackageDetail->pActInfo->cClasses; count++)
  907. {
  908. DWORD cClassProgId = 0;
  909. for (cClassProgId = 0; cClassProgId < pPackageDetail->pActInfo->pClasses[count].cProgId;
  910. cClassProgId++)
  911. {
  912. pszProgId[cPackProgId++] =
  913. pPackageDetail->pActInfo->pClasses[count].prgProgId[cClassProgId];
  914. }
  915. }
  916. hr = SetPropertyList(pPackageADs, PROGIDLIST, cPackProgId, pszProgId);
  917. CoTaskMemFree(pszProgId);
  918. }
  919. ERROR_ON_FAILURE(hr);
  920. if (pPackageDetail->pActInfo->cShellFileExt)
  921. {
  922. //
  923. // Store a tuple in the format <file ext>:<priority>
  924. //
  925. pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->pActInfo->cShellFileExt) * sizeof(LPOLESTR));
  926. if (!pszGuid)
  927. {
  928. hr = E_OUTOFMEMORY;
  929. ERROR_ON_FAILURE(hr);
  930. }
  931. for (count = 0; count < pPackageDetail->pActInfo->cShellFileExt; count++)
  932. {
  933. pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) *
  934. (wcslen(pPackageDetail->pActInfo->prgShellFileExt[count])+1+2+1));
  935. // format is fileext+:+nn+NULL where nn = 2 digit priority
  936. wsprintf(pszGuid[count], L"%s:%2d",
  937. pPackageDetail->pActInfo->prgShellFileExt[count],
  938. pPackageDetail->pActInfo->prgPriority[count]);
  939. }
  940. hr = SetPropertyList(pPackageADs, PKGFILEEXTNLIST, pPackageDetail->pActInfo->cShellFileExt, pszGuid);
  941. for (count = 0; (count < pPackageDetail->pActInfo->cShellFileExt); count++)
  942. CoTaskMemFree(pszGuid[count]);
  943. CoTaskMemFree(pszGuid);
  944. //
  945. // Now IDS Workaround
  946. // BUGBUG. Remove this when the DS bug is fixed. 130491 in NTDEV
  947. //
  948. hr = SetPropertyList(pPackageADs,
  949. QRYFILEEXT,
  950. pPackageDetail->pActInfo->cShellFileExt,
  951. pPackageDetail->pActInfo->prgShellFileExt);
  952. }
  953. ERROR_ON_FAILURE(hr);
  954. if (pPackageDetail->pActInfo->cInterfaces)
  955. {
  956. pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->pActInfo->cInterfaces)*sizeof(LPOLESTR));
  957. if (!pszGuid)
  958. {
  959. hr = E_OUTOFMEMORY;
  960. ERROR_ON_FAILURE(hr);
  961. }
  962. for (count = 0; (count < (pPackageDetail->pActInfo->cInterfaces)); count++)
  963. {
  964. pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(STRINGGUIDLEN*sizeof(WCHAR));
  965. if (!pszGuid[count])
  966. {
  967. hr = E_OUTOFMEMORY;
  968. ERROR_ON_FAILURE(hr);
  969. }
  970. StringFromGUID((pPackageDetail->pActInfo->prgInterfaceId)[count], pszGuid[count]);
  971. }
  972. hr = SetPropertyList(pPackageADs, PKGIIDLIST, pPackageDetail->pActInfo->cInterfaces,
  973. pszGuid);
  974. ERROR_ON_FAILURE(hr);
  975. for (count = 0; (count < (pPackageDetail->pActInfo->cInterfaces)); count++)
  976. CoTaskMemFree(pszGuid[count]);
  977. CoTaskMemFree(pszGuid);
  978. }
  979. if (pPackageDetail->pActInfo->cTypeLib)
  980. {
  981. pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->pActInfo->cTypeLib)*sizeof(LPOLESTR));
  982. if (!pszGuid)
  983. {
  984. hr = E_OUTOFMEMORY;
  985. ERROR_ON_FAILURE(hr);
  986. }
  987. for (count = 0; (count < (pPackageDetail->pActInfo)->cTypeLib); count++)
  988. {
  989. pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(STRINGGUIDLEN*sizeof(WCHAR));
  990. if (!pszGuid[count])
  991. {
  992. hr = E_OUTOFMEMORY;
  993. ERROR_ON_FAILURE(hr);
  994. }
  995. StringFromGUID((pPackageDetail->pActInfo->prgTlbId)[count], pszGuid[count]);
  996. }
  997. hr = SetPropertyList(pPackageADs, PKGTLBIDLIST, pPackageDetail->pActInfo->cTypeLib,
  998. pszGuid);
  999. ERROR_ON_FAILURE(hr);
  1000. for (count = 0; (count < (pPackageDetail->pActInfo->cTypeLib)); count++)
  1001. CoTaskMemFree(pszGuid[count]);
  1002. CoTaskMemFree(pszGuid);
  1003. }
  1004. }
  1005. // fill in the platforminfo
  1006. // BUGBUG::***os version
  1007. if ((pPackageDetail->pPlatformInfo)->cPlatforms)
  1008. {
  1009. pdwArch = (DWORD *)CoTaskMemAlloc(sizeof(DWORD)*
  1010. ((pPackageDetail->pPlatformInfo)->cPlatforms));
  1011. for (count = 0; (count < (pPackageDetail->pPlatformInfo)->cPlatforms); count++)
  1012. UnpackPlatform (pdwArch+count, ((pPackageDetail->pPlatformInfo)->prgPlatform)+count);
  1013. hr = SetPropertyListDW (pPackageADs, ARCHLIST, (pPackageDetail->pPlatformInfo)->cPlatforms, pdwArch);
  1014. ERROR_ON_FAILURE(hr);
  1015. CoTaskMemFree(pdwArch);
  1016. }
  1017. if ((pPackageDetail->pPlatformInfo)->cLocales)
  1018. {
  1019. hr = SetPropertyListDW (pPackageADs,
  1020. LOCALEID, (pPackageDetail->pPlatformInfo)->cLocales,
  1021. (pPackageDetail->pPlatformInfo)->prgLocale);
  1022. ERROR_ON_FAILURE(hr);
  1023. }
  1024. // fill in the installinfo
  1025. hr = SetProperty(pPackageADs, PACKAGENAME, pszPackageName);
  1026. ERROR_ON_FAILURE(hr);
  1027. hr = SetPropertyDW (pPackageADs, PACKAGETYPE, (DWORD)pPackageDetail->pInstallInfo->PathType);
  1028. ERROR_ON_FAILURE(hr);
  1029. if (pPackageDetail->pInstallInfo->pszScriptPath)
  1030. {
  1031. hr = SetProperty(pPackageADs, SCRIPTPATH, pPackageDetail->pInstallInfo->pszScriptPath);
  1032. ERROR_ON_FAILURE(hr);
  1033. }
  1034. if (pPackageDetail->pInstallInfo->pszSetupCommand)
  1035. {
  1036. hr = SetProperty(pPackageADs, SETUPCOMMAND, pPackageDetail->pInstallInfo->pszSetupCommand);
  1037. ERROR_ON_FAILURE(hr);
  1038. }
  1039. if (pPackageDetail->pInstallInfo->pszUrl)
  1040. {
  1041. hr = SetProperty(pPackageADs, HELPURL, pPackageDetail->pInstallInfo->pszUrl);
  1042. ERROR_ON_FAILURE(hr);
  1043. }
  1044. GetCurrentUsn(&Usn[0]);
  1045. hr = UsnUpd(pPackageADs, PKGUSN, &Usn[0]);
  1046. ERROR_ON_FAILURE(hr);
  1047. hr = SetPropertyDW (pPackageADs, PACKAGEFLAGS, pPackageDetail->pInstallInfo->dwActFlags);
  1048. ERROR_ON_FAILURE(hr);
  1049. hr = SetPropertyDW (pPackageADs, CLASSCTX, pPackageDetail->pInstallInfo->dwComClassContext);
  1050. ERROR_ON_FAILURE(hr);
  1051. hr = SetPropertyDW (pPackageADs, VERSIONHI, pPackageDetail->pInstallInfo->dwVersionHi);
  1052. ERROR_ON_FAILURE(hr);
  1053. hr = SetPropertyDW (pPackageADs, VERSIONLO, pPackageDetail->pInstallInfo->dwVersionLo);
  1054. ERROR_ON_FAILURE(hr);
  1055. hr = SetPropertyDW (pPackageADs, SCRIPTSIZE, pPackageDetail->pInstallInfo->cScriptLen);
  1056. ERROR_ON_FAILURE(hr);
  1057. hr = SetPropertyDW (pPackageADs, UILEVEL, (DWORD)pPackageDetail->pInstallInfo->InstallUiLevel);
  1058. ERROR_ON_FAILURE(hr);
  1059. if (pPackageDetail->pInstallInfo->cUpgrades)
  1060. {
  1061. LPOLESTR *rpszUpgrades;
  1062. rpszUpgrades = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*pPackageDetail->pInstallInfo->cUpgrades);
  1063. for (count = 0; (count < pPackageDetail->pInstallInfo->cUpgrades); count++)
  1064. {
  1065. UINT l = wcslen(pPackageDetail->pInstallInfo->prgUpgradeScript[count]);
  1066. rpszUpgrades[count] = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) *(4+l));
  1067. wsprintf(rpszUpgrades[count], L"%s:%1d",
  1068. pPackageDetail->pInstallInfo->prgUpgradeScript[count],
  1069. pPackageDetail->pInstallInfo->prgUpgradeFlag[count]);
  1070. }
  1071. hr = SetPropertyList(pPackageADs, UPGRADESCRIPTNAMES, pPackageDetail->pInstallInfo->cUpgrades,
  1072. rpszUpgrades);
  1073. ERROR_ON_FAILURE(hr);
  1074. for (count = 0; (count < pPackageDetail->pInstallInfo->cUpgrades); count++)
  1075. CoTaskMemFree(rpszUpgrades[count]);
  1076. CoTaskMemFree(rpszUpgrades);
  1077. }
  1078. // fill in the sources
  1079. if (pPackageDetail->cSources)
  1080. {
  1081. hr = SetPropertyList(pPackageADs, MSIFILELIST, pPackageDetail->cSources,
  1082. pPackageDetail->pszSourceList);
  1083. ERROR_ON_FAILURE(hr);
  1084. }
  1085. // fill in the categories
  1086. if (pPackageDetail->cCategories)
  1087. {
  1088. pszGuid = (LPOLESTR *)CoTaskMemAlloc((pPackageDetail->cCategories) * sizeof(LPOLESTR));
  1089. if (!pszGuid)
  1090. {
  1091. hr = E_OUTOFMEMORY;
  1092. ERROR_ON_FAILURE(hr);
  1093. }
  1094. for (count = 0; (count < pPackageDetail->cCategories); count++)
  1095. {
  1096. pszGuid[count] = (LPOLESTR)CoTaskMemAlloc(STRINGGUIDLEN*sizeof(WCHAR));
  1097. if (!pszGuid[count])
  1098. {
  1099. hr = E_OUTOFMEMORY;
  1100. ERROR_ON_FAILURE(hr);
  1101. }
  1102. StringFromGUID((pPackageDetail->rpCategory)[count], pszGuid[count]);
  1103. }
  1104. hr = SetPropertyList(pPackageADs, PKGCATEGORYLIST, pPackageDetail->cCategories,
  1105. pszGuid);
  1106. ERROR_ON_FAILURE(hr);
  1107. for (count = 0; (count < pPackageDetail->cCategories); count++)
  1108. CoTaskMemFree(pszGuid[count]);
  1109. CoTaskMemFree(pszGuid);
  1110. }
  1111. //
  1112. // Store the script in the directory
  1113. //
  1114. /*
  1115. if ((pPackageDetail->pInstallInfo->dwActFlags & SCRIPT_IN_DIRECTORY) &&
  1116. (pPackageDetail->pInstallInfo->cScriptLen))
  1117. {
  1118. if ((pPackageDetail->pInstallInfo->cScriptLen) &&
  1119. (!IsValidReadPtrIn(pPackageDetail->pInstallInfo->pScript, pPackageDetail->pInstallInfo->cScriptLen)))
  1120. return E_INVALIDARG;
  1121. SAFEARRAYBOUND size; // Get rid of 16
  1122. SAFEARRAY FAR *psa;
  1123. CHAR HUGEP *pArray=NULL;
  1124. LONG dwSLBound = 0;
  1125. LONG dwSUBound = 0;
  1126. VARIANT vData;
  1127. VariantInit(&vData);
  1128. size.cElements = pPackageDetail->pInstallInfo->cScriptLen;
  1129. size.lLbound = 0;
  1130. psa = SafeArrayCreate(VT_UI1, 1, &size);
  1131. if (!psa) {
  1132. return(E_OUTOFMEMORY);
  1133. }
  1134. hr = SafeArrayAccessData( psa, (void HUGEP * FAR *) &pArray );
  1135. RETURN_ON_FAILURE(hr);
  1136. memcpy( pArray, pPackageDetail->pInstallInfo->pScript, size.cElements );
  1137. SafeArrayUnaccessData( psa );
  1138. V_VT(&vData) = VT_ARRAY | VT_UI1;
  1139. V_ARRAY(&vData) = psa;
  1140. hr = pPackageADs->Put(PKGSCRIPT, vData);
  1141. VariantClear(&vData);
  1142. ERROR_ON_FAILURE(hr);
  1143. }
  1144. */
  1145. hr = StoreIt(pPackageADs);
  1146. ERROR_ON_FAILURE(hr);
  1147. if (pPackageDetail->pActInfo)
  1148. {
  1149. for (count = 0; count < pPackageDetail->pActInfo->cClasses; count++)
  1150. {
  1151. hr = NewClass((pPackageDetail->pActInfo->pClasses)+count);
  1152. ERROR_ON_FAILURE(hr);
  1153. }
  1154. }
  1155. Error_Cleanup:
  1156. pPackageADs->Release();
  1157. return hr;
  1158. }
  1159.