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.

1189 lines
29 KiB

  1. //
  2. // Author: DebiM
  3. // Date: March 97
  4. // File: csdrt.cxx
  5. //
  6. // Class Store DRTs
  7. //
  8. // This is the main source file
  9. // The related files are csdrtad.cxx and csdrtgc.cxx
  10. //
  11. // Current DRTs test:
  12. // CClassContainer::IClassAdmin
  13. // CClassAccess::IClassAccess
  14. //
  15. //
  16. // It tests the following Class Store functionality
  17. //
  18. // Admin Interfaces
  19. // Browse Interfaces
  20. // GetAppInfo()
  21. // Tests with multiple class stores
  22. //
  23. //
  24. // To be extended to do:
  25. // 2. ACL tests
  26. // 3. Tests for error scenarios
  27. // 4. More comprehensive
  28. // - large no. of CLSIDs per Package
  29. //
  30. //---------------------------------------------------------------------
  31. #include "csdrt.hxx"
  32. BOOL fBrowseTest;
  33. BOOL fVerbose;
  34. BOOL fAdminTest;
  35. BOOL fClassInfoTest;
  36. BOOL fClassInfoVerify;
  37. BOOL fComprehensive;
  38. BOOL fEmptyTest;
  39. BOOL fRemoveTest;
  40. BOOL fDllTest;
  41. BOOL fStress;
  42. BOOL fRefreshTest;
  43. BOOL fMultiStore;
  44. BOOL fCatTest;
  45. BOOL fLogonPerf = FALSE;
  46. BOOL fLogonPerfInitialize = FALSE;
  47. BOOL fOverwritePath = FALSE;
  48. BOOL fLogon = FALSE;
  49. IClassAccess *pIClassAccess = NULL;
  50. IClassAdmin *pIClassAdmin = NULL;
  51. IClassAdmin *pIClassAdmin2 = NULL;
  52. WCHAR szClassStorePath [2000+1];
  53. WCHAR szContainer [2000+1];
  54. WCHAR szContainer2 [2000+1];
  55. WCHAR szNewContainer [2000+1];
  56. WCHAR szLookupPackageName [_MAX_PATH];
  57. WCHAR szUserName[_MAX_PATH];
  58. WCHAR szPassword[_MAX_PATH];
  59. LPOLESTR pszDomain, pszUser;
  60. UINT cLoops = 100;
  61. STDAPI_(void) UpdateClassStoreSettings(WCHAR *pwszNewPath);
  62. GUID NULLGUID =
  63. { 0x00000000, 0x0000, 0x0000,
  64. { 0x00, 0x00, 0x0, 0x00, 0x0, 0x00, 0x00, 0x00 }
  65. };
  66. void Usage()
  67. {
  68. printf ("Usage is\n");
  69. printf (" csdrt [-p<containerpath>] [-v] [-a] [-b] [-g] [-o]\n");
  70. printf (" OR csdrt [-p<containerpath>] [-v] -e\n");
  71. printf (" OR csdrt [-p<containerpath>] [-v] -c\n");
  72. printf (" OR csdrt [-p<containerpath>] [-v] -s [-b] [-l<loop count>] \n");
  73. printf (" OR csdrt [-p<containerpath>] [-m[<containerpath>]] [-v] -s [-b] [-l<loop count>] \n");
  74. printf (" where:\n");
  75. printf (" <containerpath> is a DNS pathname for a Class container.\n");
  76. printf (" if absent defaults to env var DRT_CLASSSTORE.\n");
  77. printf (" -v : Verbose.\n");
  78. printf (" -a : Test IClassAdmin functionality.\n");
  79. printf (" -b : Test Browse functionality - IEnumPackage.\n");
  80. printf (" -q : Test Comcat functionality \n");
  81. printf (" -g : Test GetPackageInfo(). -gV for verification. Class store has to be clean before this\n");
  82. printf (" -r : Test IClassRefresh.\n");
  83. printf (" -d : Test entry points in csadm.dll.\n");
  84. printf (" -f : perf tests for IClassAccess. \n");
  85. printf (" -t : Perf for logon procedure. Add I if it has to be initialized. have to be run alone\n");
  86. printf (" -e : Empty the Class Store\n");
  87. printf (" -c : A complete test of functionality.\n");
  88. printf (" -m : Run Multi Class Store Tests. Needs env var DRT_CLASSSTORE2. \n");
  89. printf (" -s : Stress Test. Tests GetClassInfo and Optionally Browse. \n");
  90. printf (" -l : Loop count for Stress Test. Default = 100. Number of packages\n");
  91. printf (" -o : overwrite path \n");
  92. printf (" -u : domain\\user. \n");
  93. printf (" -w : password. \n");
  94. }
  95. HRESULT RunComprehensive()
  96. {
  97. HRESULT hr;
  98. VerbosePrint ("Running Comprehensive Suite of Class Store DRTs.\n");
  99. fBrowseTest = fAdminTest = fRemoveTest = fClassInfoTest = fCatTest =
  100. fRefreshTest = TRUE;
  101. hr = RunTests();
  102. CleanUp();
  103. VerbosePrint ("End of Comprehensive Suite of Class Store DRTs.\n");
  104. return hr;
  105. }
  106. HRESULT RunStress()
  107. {
  108. HRESULT hr;
  109. ULONG cCount, cPkgCount, cErrCount = 0, cPrevCount = 0;
  110. DWORD tc = GetTickCount();
  111. pIClassAccess = NULL;
  112. pIClassAdmin = NULL;
  113. pIClassAdmin2 = NULL;
  114. printf ("Started Class Store Stress for %d passes.\n", cLoops);
  115. for (UINT i=0; i < cLoops; ++i)
  116. {
  117. if (i%100 == 0) // Before every hundredth time
  118. {
  119. //
  120. // Get an IClassAdmin interface pointer
  121. //
  122. hr = GetClassAdmin (szContainer, &pIClassAdmin);
  123. if (!SUCCEEDED(hr))
  124. return hr;
  125. //
  126. // Get an IClassAccess interface pointer
  127. //
  128. hr = GetClassAccess ();
  129. if (!SUCCEEDED(hr))
  130. return hr;
  131. hr = DoRemoveTest (&cPkgCount);
  132. hr = DoAdminTest(&cPkgCount);
  133. if (!SUCCEEDED(hr))
  134. ++cErrCount;
  135. }
  136. if (fBrowseTest)
  137. {
  138. hr = DoBrowseTest(pIClassAdmin);
  139. if (!SUCCEEDED(hr))
  140. ++cErrCount;
  141. }
  142. if (fClassInfoTest)
  143. {
  144. hr = DoClassInfoTest();
  145. if (!SUCCEEDED(hr))
  146. ++cErrCount;
  147. }
  148. if ((i+1)%10 == 0) // After every Tenth time
  149. {
  150. //
  151. // Progress Indicator. If errors display a :( else display a :)
  152. //
  153. if (cErrCount > cPrevCount)
  154. {
  155. printf (":( ");
  156. cPrevCount = cErrCount;
  157. }
  158. else
  159. printf (":) ");
  160. }
  161. if ((i+1)%100 == 0) // After every Hundredth time
  162. {
  163. //
  164. // Get rid of the interface pointers
  165. //
  166. CleanUp();
  167. //
  168. // Detail Progress indicator
  169. //
  170. printf ("\n ... %d Stress Passes Completed (with %d Errors).\n",
  171. i+1, cErrCount);
  172. }
  173. }
  174. printf ("End of Class Store Stress for %d passes (%d MilliSec Per Loop) (%d Errors).\n",
  175. cLoops,
  176. (GetTickCount() - tc)/cLoops,
  177. cErrCount);
  178. return S_OK;
  179. }
  180. HRESULT RunTests()
  181. {
  182. HRESULT hr = S_OK;
  183. pIClassAccess = NULL;
  184. pIClassAdmin = NULL;
  185. pIClassAdmin2 = NULL;
  186. //
  187. // Depending on run parameters
  188. // invoke different tests
  189. //
  190. if (fBrowseTest || fAdminTest || fEmptyTest || fCatTest || fLogonPerfInitialize)
  191. {
  192. //
  193. // Get an IClassAdmin interface pointer
  194. //
  195. hr = GetClassAdmin (szContainer, &pIClassAdmin);
  196. if (!SUCCEEDED(hr))
  197. return hr;
  198. if (fMultiStore)
  199. {
  200. hr = GetClassAdmin (szContainer2, &pIClassAdmin2);
  201. if (!SUCCEEDED(hr))
  202. return hr;
  203. }
  204. }
  205. if (fEmptyTest)
  206. {
  207. VerbosePrint("... Empty Container Test Started.\n");
  208. hr = EmptyClassStore (pIClassAdmin);
  209. VerbosePrint("... Empty Container Test Ended.\n");
  210. if (pIClassAdmin2 != NULL)
  211. {
  212. VerbosePrint("... Empty Container Test on Second Class Store Started.\n");
  213. hr = EmptyClassStore(pIClassAdmin2);
  214. VerbosePrint("... Empty Container Test on Second Class Store Ended.\n");
  215. }
  216. if (SUCCEEDED(hr))
  217. printf ("PASSED ---- Empty Container Test Suite.\n");
  218. else
  219. printf ("FAILED ---- Empty Container Test Suite. hr = 0x%x.\n", hr);
  220. }
  221. if (fAdminTest)
  222. {
  223. ULONG cCount, cPkgCount;
  224. VerbosePrint("... Admin Test Started.\n");
  225. hr = DoAdminTest(&cPkgCount);
  226. VerbosePrint("... Admin Test Ended. (Added %d Packages).\n",
  227. cPkgCount);
  228. if (SUCCEEDED(hr))
  229. printf ("PASSED ---- Admin Test Suite.\n");
  230. else
  231. printf ("FAILED ---- Admin Test Suite. hr = 0x%x.\n", hr);
  232. }
  233. if (fCatTest)
  234. {
  235. ULONG cCount, cPkgCount;
  236. VerbosePrint("... Comcat Test Started.\n");
  237. hr = DoCatTests(pIClassAdmin, pIClassAdmin2);
  238. VerbosePrint("... Admin Test Ended. \n");
  239. if (SUCCEEDED(hr))
  240. printf ("PASSED ---- Comcat Test Suite.\n");
  241. else
  242. printf ("FAILED ---- Comcat Test Suite. hr = 0x%x.\n", hr);
  243. }
  244. if (fBrowseTest)
  245. {
  246. VerbosePrint("... Browse Test Started.\n");
  247. hr = DoBrowseTest(pIClassAdmin);
  248. VerbosePrint("... Browse Test Ended.\n");
  249. if (pIClassAdmin2 != NULL)
  250. {
  251. VerbosePrint("... Browse Test on Second Class Store Started.\n");
  252. hr = DoBrowseTest(pIClassAdmin2);
  253. VerbosePrint("... Browse Test on Second Class Store Ended.\n");
  254. }
  255. if (SUCCEEDED(hr))
  256. printf ("PASSED ---- Browse Test Suite.\n");
  257. else
  258. printf ("FAILED ---- Browse Test Suite. hr = 0x%x.\n", hr);
  259. }
  260. if (fClassInfoTest || fRefreshTest)
  261. {
  262. //
  263. // Get an IClassAccess interface pointer
  264. //
  265. hr = GetClassAccess ();
  266. if (!SUCCEEDED(hr))
  267. return hr;
  268. }
  269. if (fLogonPerf)
  270. {
  271. //
  272. // Measure the performance during a std. logon
  273. //
  274. hr = DoLogonPerfTest(fLogonPerfInitialize);
  275. }
  276. if (fRefreshTest)
  277. {
  278. VerbosePrint("... Refresh Test Started.\n");
  279. hr = RefreshTest ();
  280. VerbosePrint("... Refresh Test Ended.\n");
  281. if (SUCCEEDED(hr))
  282. printf ("PASSED ---- Refresh Test Suite.\n");
  283. else
  284. printf ("FAILED ---- Refresh Test Suite. hr = 0x%x.\n", hr);
  285. }
  286. if (fClassInfoTest)
  287. {
  288. VerbosePrint("... CoEnumApps Test Started.\n");
  289. hr = DoCoEnumAppsTest();
  290. VerbosePrint("... CoEnumApps Test Ended.\n");
  291. VerbosePrint("... Class Store Lookup Test Started.\n");
  292. hr = DoClassInfoTest();
  293. VerbosePrint("... Class Store Lookup Test Ended.\n");
  294. if (SUCCEEDED(hr))
  295. printf ("PASSED ---- Class Store Lookup Test Suite.\n");
  296. else
  297. printf ("FAILED ---- Class Store Lookup Test Suite. hr = 0x%x.\n", hr);
  298. }
  299. if (fRemoveTest)
  300. {
  301. ULONG cPkgCount;
  302. VerbosePrint("... Remove Test Started.\n");
  303. hr = DoRemoveTest(&cPkgCount);
  304. VerbosePrint("... Remove Test Ended.(%d Packages).\n",
  305. cPkgCount);
  306. if (SUCCEEDED(hr))
  307. printf ("PASSED ---- Remove Test Suite.\n");
  308. else
  309. printf ("FAILED ---- Remove Test Suite. hr = 0x%x.\n", hr);
  310. }
  311. if (fDllTest)
  312. {
  313. /* BUGBUG. Deleted now. Add later.
  314. IClassAdmin *pClassAdmin = NULL;
  315. extern Sname TestProgId1, TestClassDesc1;
  316. extern GUID TestClsid1;
  317. //
  318. // Test entry points in csadm.dll
  319. //
  320. VerbosePrint("... Dll Test Started.\n");
  321. // 1. Create an empty store
  322. hr = CsCreateClassStore(szNewContainer, L"CN=DrtClassStore");
  323. // 2. Get an IClassAdmin for it.
  324. if (SUCCEEDED(hr))
  325. {
  326. VerbosePrint ("...... New Class Store created.\n");
  327. wcscat (szNewContainer, L"/");
  328. wcscat (szNewContainer, L"CN=DRTClassStore");
  329. hr = CsGetClassStore(szNewContainer, (void **)&pClassAdmin);
  330. }
  331. // 3. Use the IClassAdmin to add a class
  332. if (SUCCEEDED(hr))
  333. {
  334. VerbosePrint ("...... Connected to New Class Store.\n");
  335. CLASSDETAIL ClassDetail;
  336. memset (&ClassDetail, NULL, sizeof (CLASSDETAIL));
  337. memcpy (&ClassDetail.Clsid, &TestClsid1, sizeof (GUID));
  338. ClassDetail.pDefaultProgId = TestProgId1;
  339. ClassDetail.pszDesc = TestClassDesc1;
  340. hr = pClassAdmin->NewClass(&ClassDetail);
  341. if (!SUCCEEDED(hr))
  342. {
  343. printf ("ERROR! NewClass() returned 0x%x.\n", hr);
  344. return hr;
  345. }
  346. VerbosePrint ("...... Added a class definition.\n");
  347. // 4. Then delete the class
  348. hr = pClassAdmin->DeleteClass(TestClsid1);
  349. if (!SUCCEEDED(hr))
  350. {
  351. printf ("ERROR! DeleteClass() returned 0x%x.\n", hr);
  352. return hr;
  353. }
  354. VerbosePrint ("...... Deleted a class definition.\n");
  355. // 5. Release the IClassAdmin
  356. hr = pClassAdmin->Release();
  357. // 6. Delete the Class Store
  358. hr = CsDeleteClassStore(szNewContainer);
  359. if (!SUCCEEDED(hr))
  360. {
  361. printf ("ERROR! Deleting ClassStore.\n", hr);
  362. return hr;
  363. }
  364. VerbosePrint ("...... Deleted the class store.\n");
  365. }
  366. VerbosePrint("... Dll Test Ended.\n");
  367. if (SUCCEEDED(hr))
  368. printf ("PASSED ---- Dll Test Suite.\n");
  369. else
  370. printf ("FAILED ---- Dll Test Suite. hr = 0x%x.\n", hr);
  371. */
  372. }
  373. return hr;
  374. }
  375. void CleanUp()
  376. {
  377. if (pIClassAdmin)
  378. {
  379. pIClassAdmin->Release();
  380. pIClassAdmin = NULL;
  381. }
  382. if (pIClassAdmin2)
  383. {
  384. pIClassAdmin2->Release();
  385. pIClassAdmin2 = NULL;
  386. }
  387. if (pIClassAccess)
  388. {
  389. pIClassAccess->Release();
  390. pIClassAccess = NULL;
  391. }
  392. }
  393. void _cdecl main( int argc, char ** argv )
  394. {
  395. HRESULT hr;
  396. INT i;
  397. LPWSTR szEnvVar;
  398. //
  399. // Check run parameters
  400. //
  401. fBrowseTest = FALSE;
  402. fVerbose = FALSE;
  403. fAdminTest = FALSE;
  404. fClassInfoTest = FALSE;
  405. fComprehensive = FALSE;
  406. fStress = FALSE;
  407. fRemoveTest = FALSE;
  408. fRefreshTest = FALSE;
  409. fMultiStore = FALSE;
  410. fEmptyTest = FALSE;
  411. fDllTest = FALSE;
  412. fCatTest = FALSE;
  413. fLogon = FALSE;
  414. fLogonPerf = FALSE;
  415. fClassInfoVerify = FALSE;
  416. szPassword[0] = NULL;
  417. szContainer[0] = NULL;
  418. szLookupPackageName[0] = NULL;
  419. //
  420. // Check if the env variable CLASSSTORE is defined
  421. // Get the value of the CLASSSTORE environment variable.
  422. //
  423. szEnvVar = _wgetenv(L"DRT_CLASSSTORE");
  424. //
  425. // if so use that as the default path
  426. //
  427. if (szEnvVar != NULL)
  428. {
  429. wcscpy (szContainer, szEnvVar);
  430. }
  431. BOOL fLoop = FALSE;
  432. for (i=1; i < argc; ++i)
  433. {
  434. if (toupper(*argv[i]) != '-')
  435. {
  436. printf ("ERROR! Parameters must start with a hyphen.\n");
  437. Usage();
  438. return;
  439. }
  440. switch (toupper(*(argv[i]+1)))
  441. {
  442. case 'P':
  443. MultiByteToWideChar (
  444. CP_ACP, 0,
  445. (argv[i]+2),
  446. strlen (argv[i]+2) + 1,
  447. szContainer,
  448. _MAX_PATH);
  449. break;
  450. case 'E':
  451. fEmptyTest = TRUE;
  452. break;
  453. case 'B':
  454. fBrowseTest = TRUE;
  455. break;
  456. case 'V':
  457. fVerbose = TRUE;
  458. break;
  459. case 'A':
  460. fAdminTest = TRUE;
  461. break;
  462. case 'O':
  463. fOverwritePath = TRUE;
  464. break;
  465. case 'Q':
  466. fCatTest = TRUE;
  467. break;
  468. case 'G':
  469. fClassInfoTest = TRUE;
  470. if (*(argv[i]+2) == 'V')
  471. fClassInfoVerify = TRUE;
  472. break;
  473. case 'D':
  474. fDllTest = TRUE;
  475. break;
  476. case 'R':
  477. fRefreshTest = TRUE;
  478. break;
  479. case 'M':
  480. fMultiStore = TRUE;
  481. break;
  482. case 'C':
  483. fComprehensive = TRUE;
  484. break;
  485. case 'S':
  486. fStress = TRUE;
  487. break;
  488. case 'L':
  489. cLoops = atoi(argv[i]+2);
  490. fLoop = TRUE;
  491. break;
  492. case 'T':
  493. fLogonPerf = TRUE;
  494. if (*(argv[i]+2) == 'I')
  495. fLogonPerfInitialize = TRUE;
  496. break;
  497. case 'U':
  498. MultiByteToWideChar (
  499. CP_ACP, 0,
  500. (argv[i]+2),
  501. strlen (argv[i]+2) + 1,
  502. szUserName,
  503. _MAX_PATH);
  504. pszDomain = pszUser = &szUserName[0];
  505. while (*pszUser)
  506. {
  507. if (*pszUser == L'\\')
  508. {
  509. *pszUser = NULL;
  510. pszUser++;
  511. break;
  512. }
  513. pszUser++;
  514. }
  515. if (*pszUser == NULL)
  516. {
  517. printf ("ERROR! Incorrect domain\\user specified.\nAborting ...\n");
  518. return;
  519. }
  520. fLogon = TRUE;
  521. break;
  522. case 'W':
  523. MultiByteToWideChar (
  524. CP_ACP, 0,
  525. (argv[i]+2),
  526. strlen (argv[i]+2) + 1,
  527. szPassword,
  528. _MAX_PATH);
  529. break;
  530. default:
  531. Usage();
  532. return;
  533. }
  534. }
  535. if (szContainer[0] == NULL)
  536. {
  537. //
  538. // No default for container and none specified
  539. //
  540. printf ("ERROR! Class Container not specified and DRT_CLASSSTORE not set.\nAborting ...\n");
  541. return;
  542. }
  543. if (fMultiStore)
  544. {
  545. szEnvVar = _wgetenv(L"DRT_CLASSSTORE2");
  546. if (szEnvVar != NULL)
  547. {
  548. wcscpy (szContainer2, szEnvVar);
  549. }
  550. else
  551. {
  552. printf ("ERROR! DRT_CLASSSTORE2 not set. Aborting ...\n");
  553. return;
  554. }
  555. }
  556. if (fDllTest)
  557. {
  558. szEnvVar = _wgetenv(L"DRT_NEWOU");
  559. if (szEnvVar != NULL)
  560. {
  561. wcscpy (szNewContainer, szEnvVar);
  562. }
  563. else
  564. {
  565. printf ("ERROR! DRT_NEWOU not set. Aborting ...\n");
  566. return;
  567. }
  568. }
  569. if (!(fStress || fEmptyTest || fComprehensive ||
  570. fBrowseTest || fClassInfoTest || fAdminTest || fCatTest || fLogonPerf))
  571. {
  572. printf ("ERROR! No Tests specified. Aborting ...\n");
  573. return;
  574. }
  575. if (fStress &&
  576. (fEmptyTest || fComprehensive || fAdminTest || fMultiStore))
  577. {
  578. printf ("ERROR! For 'Stress Test' the only options are -g, -b and -l. \nAborting ...\n");
  579. return;
  580. }
  581. if ((fLogonPerf || fEmptyTest) &&
  582. (fComprehensive || fBrowseTest || fClassInfoTest || fAdminTest))
  583. {
  584. printf ("ERROR! Cant combine Empty or Logon Tests with any other test. \nAborting ...\n");
  585. return;
  586. }
  587. if (fComprehensive &&
  588. (fBrowseTest || fClassInfoTest || fAdminTest))
  589. {
  590. printf ("ERROR! Cant combine 'Comprehensive Test Suite' with any other individual tests. \nAborting ...\n");
  591. return;
  592. }
  593. if (fStress &&
  594. (!(fBrowseTest || fClassInfoTest )))
  595. {
  596. fClassInfoTest = TRUE;
  597. }
  598. if (fLoop)
  599. {
  600. if (!fStress)
  601. {
  602. printf ("ERROR! Loop count applies only to Stress Test. Aborting ...\n");
  603. return;
  604. }
  605. else
  606. {
  607. if (cLoops%100 != 0)
  608. {
  609. printf ("ERROR! Loop count can only be in multiple of 100s. Aborting ...\n");
  610. return;
  611. }
  612. }
  613. }
  614. //
  615. // If test is to be run for a different user,
  616. // do LogonUser
  617. //
  618. if (fLogon)
  619. {
  620. HANDLE hToken;
  621. BOOLEAN fEnable;
  622. NTSTATUS NtStatus;
  623. printf( "Will run test as user: %S, domain: %S.\n", pszUser, pszDomain);
  624. NtStatus = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &fEnable);
  625. if ( NtStatus != STATUS_SUCCESS )
  626. {
  627. printf( "ERROR! In RtlAdjustPrivilege. 0x%x. Aborting ...\n", NtStatus);
  628. return;
  629. }
  630. if (!LogonUser(
  631. pszUser, // string that specifies the user name
  632. pszDomain, // string that specifies the domain or server
  633. szPassword, // string that specifies the password
  634. LOGON32_LOGON_INTERACTIVE, // specifies the type of logon operation
  635. LOGON32_PROVIDER_DEFAULT, // specifies the logon provider
  636. &hToken // pointer to variable to receive token handle
  637. ))
  638. {
  639. printf( "ERROR! Invalid username or password - 0x%x. Aborting ...\n",
  640. GetLastError());
  641. return;
  642. }
  643. if (!ImpersonateLoggedOnUser(hToken))
  644. {
  645. printf( "ERROR! Impersonation failed. Aborting ...\n");
  646. return;
  647. }
  648. CloseHandle(hToken);
  649. }
  650. hr = CoInitialize(NULL);
  651. if( FAILED(hr) )
  652. {
  653. printf( "ERROR! Client CoInitialize failed Ox%x. Aborting ...\n", hr );
  654. return;
  655. }
  656. VerbosePrint ("Using Class Store at:\n %S.\n", szContainer);
  657. if (fMultiStore)
  658. VerbosePrint ("Using Class Store 2 at:\n %S.\n", szContainer2);
  659. if (fOverwritePath)
  660. {
  661. // Flush Class Store Cache and Overwrite Path
  662. UpdateClassStoreSettings(szContainer);
  663. VerbosePrint("... Overwrote Class Store Path.\n");
  664. }
  665. else
  666. {
  667. GetUserClassStore(szClassStorePath);
  668. VerbosePrint ("Profile ClassStore:\n %S.\n", szClassStorePath);
  669. //
  670. // Verify that the Profile matches the input.
  671. //
  672. if (NULL == wcsstr(szClassStorePath, szContainer))
  673. {
  674. printf( "Warning! Class Store is different from Profile.\n");
  675. }
  676. if (NULL == wcsstr(szClassStorePath, szContainer2))
  677. {
  678. printf( "Warning! Second Class Store is different from Profile.\n");
  679. }
  680. }
  681. InitTempNames();
  682. if (fComprehensive)
  683. {
  684. hr = RunComprehensive();
  685. }
  686. else
  687. {
  688. if (fStress)
  689. {
  690. fVerbose = FALSE;
  691. hr = RunStress();
  692. }
  693. else
  694. {
  695. hr = RunTests();
  696. CleanUp();
  697. }
  698. }
  699. CoUninitialize();
  700. }
  701. //
  702. // This routine takes a pathname and binds to a Class container
  703. // and returns an IClassAdmin interface pointer
  704. //
  705. HRESULT GetClassAdmin (LPOLESTR pszPath, IClassAdmin **ppCA)
  706. {
  707. HRESULT hr;
  708. LPOLESTR szPath;
  709. *ppCA = NULL;
  710. if (wcsncmp (pszPath, L"ADCS:", 5) == 0)
  711. {
  712. szPath = pszPath + 5;
  713. }
  714. else
  715. szPath = pszPath;
  716. hr = CsGetClassStore(szPath, (void **)ppCA);
  717. if ( FAILED(hr) )
  718. {
  719. printf("ERROR! Could not get IClassAdmin. Error- 0x%x\n", hr);
  720. return hr;
  721. }
  722. return S_OK;
  723. }
  724. //
  725. // This routine binds to a CClassAccess on the desktop and
  726. // returns an IClassAccess interface pointer
  727. //
  728. HRESULT GetClassAccess ()
  729. {
  730. HRESULT hr;
  731. pIClassAccess = NULL;
  732. hr = CsGetClassAccess (&pIClassAccess);
  733. if ( FAILED(hr) )
  734. {
  735. printf("ERROR! Could not get IClassAccess. Error- 0x%x\n", hr);
  736. return hr;
  737. }
  738. return S_OK;
  739. }
  740. void
  741. GetDefaultPlatform(CSPLATFORM *pPlatform)
  742. {
  743. OSVERSIONINFO VersionInformation;
  744. VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  745. GetVersionEx(&VersionInformation);
  746. pPlatform->dwPlatformId = VersionInformation.dwPlatformId;
  747. pPlatform->dwVersionHi = VersionInformation.dwMajorVersion;
  748. pPlatform->dwVersionLo = VersionInformation.dwMinorVersion;
  749. pPlatform->dwProcessorArch = DEFAULT_ARCHITECTURE;
  750. }
  751. //
  752. // This routine enumerates all classes, packages and
  753. // cleans up the entire Class Container by deleting these objects.
  754. //
  755. HRESULT EmptyClassStore (IClassAdmin *pIClassAdmin)
  756. {
  757. HRESULT hr;
  758. ULONG cCount;
  759. hr = EnumPackagesAndDelete(pIClassAdmin, TRUE, &cCount);
  760. if (!SUCCEEDED(hr))
  761. return hr;
  762. VerbosePrint ("...... Deleted all %d Packages.\n", cCount);
  763. return S_OK;
  764. }
  765. //
  766. // This routine enumerates all classes and packages
  767. //
  768. HRESULT DoBrowseTest (IClassAdmin *pCA)
  769. {
  770. HRESULT hr;
  771. ULONG cCount;
  772. hr = EnumPackagesAndDelete(pCA, FALSE, &cCount);
  773. if (!SUCCEEDED(hr))
  774. return hr;
  775. VerbosePrint ("...... Browsed %d Packages.\n", cCount);
  776. return S_OK;
  777. }
  778. void PrintPackageInfo(PACKAGEDISPINFO *pPackageInfo)
  779. {
  780. SYSTEMTIME SystemTime;
  781. if (fVerbose)
  782. {
  783. FileTimeToSystemTime(
  784. (CONST FILETIME *)(&pPackageInfo->Usn),
  785. &SystemTime);
  786. VerbosePrint("........ Package: %S \n........ Last Update: %d-%d-%d %d:%d:%d\n",
  787. pPackageInfo->pszPackageName,
  788. SystemTime.wMonth,
  789. SystemTime.wDay,
  790. SystemTime.wYear,
  791. SystemTime.wHour,
  792. SystemTime.wMinute,
  793. SystemTime.wSecond);
  794. VerbosePrint("........ Script Size = %d. Path = %S\n",
  795. pPackageInfo->cScriptLen,
  796. pPackageInfo->pszScriptPath);
  797. }
  798. }
  799. void PrintInstallInfo(INSTALLINFO *pInstallInfo)
  800. {
  801. SYSTEMTIME SystemTime;
  802. FileTimeToSystemTime(
  803. (CONST FILETIME *)(&pInstallInfo->Usn),
  804. &SystemTime);
  805. VerbosePrint("........ Script: %S (Size = %d)\n........ Last Update: %d-%d-%d %d:%d:%d\n",
  806. pInstallInfo->pszScriptPath,
  807. pInstallInfo->cScriptLen,
  808. SystemTime.wMonth,
  809. SystemTime.wDay,
  810. SystemTime.wYear,
  811. SystemTime.wHour,
  812. SystemTime.wMinute,
  813. SystemTime.wSecond);
  814. }
  815. /*
  816. void PrintCategoryDetail(CATEGORYINFO *pCatInfo)
  817. {
  818. VerbosePrint("........ Category Description: %S\n", pCatInfo->szDescription);
  819. }
  820. */
  821. HRESULT EnumPackagesAndDelete(IClassAdmin *pIClassAdmin,
  822. BOOL fDelete,
  823. ULONG *pcPackages)
  824. {
  825. ULONG cFetched;
  826. IEnumPackage *pIEnumPackage = NULL;
  827. HRESULT hr;
  828. PACKAGEDISPINFO PackageInfo;
  829. *pcPackages=0;
  830. hr = pIClassAdmin->EnumPackages(
  831. NULL,
  832. NULL,
  833. 0,
  834. NULL,
  835. NULL,
  836. &pIEnumPackage);
  837. if ( FAILED(hr))
  838. {
  839. printf("ERROR! EnumPackages returned 0x%x\n", hr);
  840. return hr;
  841. }
  842. while (TRUE)
  843. {
  844. memset (&PackageInfo, 0, sizeof(PACKAGEDISPINFO));
  845. hr = pIEnumPackage->Next(1, &PackageInfo, &cFetched);
  846. if (FAILED(hr))
  847. {
  848. break;
  849. }
  850. if ((hr == S_FALSE) || (cFetched < 1))
  851. {
  852. hr = S_OK;
  853. break;
  854. }
  855. (*pcPackages)++;
  856. if (fVerbose && !fDelete)
  857. {
  858. PrintPackageInfo(&PackageInfo);
  859. }
  860. if (fDelete)
  861. {
  862. hr = pIClassAdmin->RemovePackage(PackageInfo.pszPackageName, 0);
  863. }
  864. ReleasePackageInfo(&PackageInfo);
  865. }
  866. pIEnumPackage->Release();
  867. if (fVerbose)
  868. {
  869. if (!SUCCEEDED(hr))
  870. printf("ERROR! 0x%x.\n", hr);
  871. }
  872. return hr;
  873. }
  874. /*
  875. HRESULT EnumCategoriesAndDelete (IClassAdmin *pIClassAdmin,
  876. BOOL fDelete,
  877. ULONG *pcCategories)
  878. {
  879. ULONG cFetched;
  880. IEnumCATEGORYINFO *pIEnumCat;
  881. HRESULT hr;
  882. CATEGORYINFO CatInfo;
  883. ICatRegister *pICatReg;
  884. ICatInformation *pICatInfo;
  885. LCID lcid = 0;
  886. *pcCategories = 0;
  887. hr = pIClassAdmin->QueryInterface(IID_ICatRegister, (void **)&pICatReg);
  888. if (FAILED(hr))
  889. {
  890. printf("Error! QI CR hr = 0x%x\n", hr);
  891. return hr;
  892. }
  893. hr = pIClassAccess->QueryInterface(IID_ICatInformation, (void **)&pICatInfo);
  894. if (FAILED(hr))
  895. {
  896. printf("Error! QI CI hr = 0x%x\n", hr);
  897. return hr;
  898. }
  899. hr = pICatInfo->EnumCategories(lcid, &pIEnumCat);
  900. if ( FAILED(hr))
  901. {
  902. return hr;
  903. }
  904. while (TRUE)
  905. {
  906. hr = pIEnumCat->Next(1, &CatInfo, &cFetched);
  907. if (FAILED(hr))
  908. {
  909. break;
  910. }
  911. if ((hr == S_FALSE) || (cFetched < 1))
  912. {
  913. hr = S_OK;
  914. break;
  915. }
  916. (*pcCategories)++;
  917. if (fVerbose && !fDelete)
  918. {
  919. PrintCategoryDetail(&CatInfo);
  920. }
  921. if (fDelete)
  922. {
  923. hr = pICatReg->UnRegisterCategories(1, &(CatInfo.catid));
  924. if (!SUCCEEDED(hr))
  925. break;
  926. }
  927. }
  928. pIEnumCat->Release();
  929. if (fVerbose)
  930. {
  931. if (!SUCCEEDED(hr))
  932. printf("ERROR! 0x%x.\n", hr);
  933. }
  934. pICatReg->Release();
  935. pICatInfo->Release();
  936. return hr;
  937. }
  938. */
  939. void
  940. ReleasePackageDetail(PACKAGEDETAIL *pPackageDetail, BOOL fPartial)
  941. {
  942. if (pPackageDetail->pActInfo)
  943. {
  944. CoTaskMemFree(pPackageDetail->pActInfo->prgShellFileExt);
  945. CoTaskMemFree(pPackageDetail->pActInfo->prgPriority);
  946. CoTaskMemFree(pPackageDetail->pActInfo->prgInterfaceId);
  947. CoTaskMemFree(pPackageDetail->pActInfo->prgTlbId);
  948. CoTaskMemFree(pPackageDetail->pActInfo);
  949. }
  950. if (pPackageDetail->pPlatformInfo)
  951. {
  952. CoTaskMemFree(pPackageDetail->pPlatformInfo->prgPlatform);
  953. CoTaskMemFree(pPackageDetail->pPlatformInfo->prgLocale);
  954. CoTaskMemFree(pPackageDetail->pPlatformInfo);
  955. }
  956. if (pPackageDetail->pInstallInfo)
  957. {
  958. if (!fPartial)
  959. ReleaseInstallInfo(pPackageDetail->pInstallInfo);
  960. CoTaskMemFree(pPackageDetail->pInstallInfo);
  961. }
  962. CoTaskMemFree(pPackageDetail->pszSourceList);
  963. CoTaskMemFree(pPackageDetail->rpCategory);
  964. }
  965. void GetUserClassStore(LPWSTR szPath)
  966. {
  967. LONG lErrorCode;
  968. DWORD dwDataLen = 1000;
  969. DWORD dwType;
  970. HKEY hKey = NULL;
  971. HRESULT hr = S_OK;
  972. *szPath = NULL;
  973. lErrorCode = RegOpenKeyEx(HKEY_CURRENT_USER,
  974. L"Software\\Microsoft\\ClassStore",
  975. NULL,
  976. KEY_ALL_ACCESS,
  977. &hKey);
  978. if ( lErrorCode != ERROR_SUCCESS)
  979. {
  980. return;
  981. }
  982. lErrorCode = RegQueryValueEx(hKey,
  983. L"Path",
  984. NULL,
  985. &dwType,
  986. (LPBYTE)szPath,
  987. &dwDataLen);
  988. RegCloseKey(hKey);
  989. return;
  990. }
  991.