|
|
//
// Author: DebiM
// Date: March 97
// File: csdrt.cxx
//
// Class Store DRTs
//
// This is the main source file
// The related files are csdrtad.cxx and csdrtgc.cxx
//
// Current DRTs test:
// CClassContainer::IClassAdmin
// CClassAccess::IClassAccess
//
//
// It tests the following Class Store functionality
//
// Admin Interfaces
// Browse Interfaces
// GetAppInfo()
// Tests with multiple class stores
//
//
// To be extended to do:
// 2. ACL tests
// 3. Tests for error scenarios
// 4. More comprehensive
// - large no. of CLSIDs per Package
//
//---------------------------------------------------------------------
#include "csdrt.hxx"
BOOL fBrowseTest; BOOL fVerbose; BOOL fAdminTest; BOOL fClassInfoTest; BOOL fClassInfoVerify; BOOL fComprehensive; BOOL fEmptyTest; BOOL fRemoveTest; BOOL fDllTest; BOOL fStress; BOOL fRefreshTest; BOOL fMultiStore; BOOL fCatTest;
BOOL fLogonPerf = FALSE; BOOL fLogonPerfInitialize = FALSE; BOOL fOverwritePath = FALSE; BOOL fLogon = FALSE;
IClassAccess *pIClassAccess = NULL; IClassAdmin *pIClassAdmin = NULL; IClassAdmin *pIClassAdmin2 = NULL;
WCHAR szClassStorePath [2000+1];
WCHAR szContainer [2000+1]; WCHAR szContainer2 [2000+1]; WCHAR szNewContainer [2000+1]; WCHAR szLookupPackageName [_MAX_PATH]; WCHAR szUserName[_MAX_PATH]; WCHAR szPassword[_MAX_PATH];
LPOLESTR pszDomain, pszUser;
UINT cLoops = 100; STDAPI_(void) UpdateClassStoreSettings(WCHAR *pwszNewPath);
GUID NULLGUID = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x0, 0x00, 0x0, 0x00, 0x00, 0x00 } };
void Usage() { printf ("Usage is\n"); printf (" csdrt [-p<containerpath>] [-v] [-a] [-b] [-g] [-o]\n"); printf (" OR csdrt [-p<containerpath>] [-v] -e\n"); printf (" OR csdrt [-p<containerpath>] [-v] -c\n"); printf (" OR csdrt [-p<containerpath>] [-v] -s [-b] [-l<loop count>] \n"); printf (" OR csdrt [-p<containerpath>] [-m[<containerpath>]] [-v] -s [-b] [-l<loop count>] \n"); printf (" where:\n"); printf (" <containerpath> is a DNS pathname for a Class container.\n"); printf (" if absent defaults to env var DRT_CLASSSTORE.\n"); printf (" -v : Verbose.\n"); printf (" -a : Test IClassAdmin functionality.\n"); printf (" -b : Test Browse functionality - IEnumPackage.\n"); printf (" -q : Test Comcat functionality \n"); printf (" -g : Test GetPackageInfo(). -gV for verification. Class store has to be clean before this\n"); printf (" -r : Test IClassRefresh.\n"); printf (" -d : Test entry points in csadm.dll.\n"); printf (" -f : perf tests for IClassAccess. \n"); printf (" -t : Perf for logon procedure. Add I if it has to be initialized. have to be run alone\n"); printf (" -e : Empty the Class Store\n"); printf (" -c : A complete test of functionality.\n"); printf (" -m : Run Multi Class Store Tests. Needs env var DRT_CLASSSTORE2. \n"); printf (" -s : Stress Test. Tests GetClassInfo and Optionally Browse. \n"); printf (" -l : Loop count for Stress Test. Default = 100. Number of packages\n"); printf (" -o : overwrite path \n"); printf (" -u : domain\\user. \n"); printf (" -w : password. \n"); }
HRESULT RunComprehensive() { HRESULT hr;
VerbosePrint ("Running Comprehensive Suite of Class Store DRTs.\n"); fBrowseTest = fAdminTest = fRemoveTest = fClassInfoTest = fCatTest = fRefreshTest = TRUE; hr = RunTests(); CleanUp(); VerbosePrint ("End of Comprehensive Suite of Class Store DRTs.\n"); return hr; }
HRESULT RunStress() { HRESULT hr; ULONG cCount, cPkgCount, cErrCount = 0, cPrevCount = 0; DWORD tc = GetTickCount();
pIClassAccess = NULL; pIClassAdmin = NULL; pIClassAdmin2 = NULL;
printf ("Started Class Store Stress for %d passes.\n", cLoops);
for (UINT i=0; i < cLoops; ++i) { if (i%100 == 0) // Before every hundredth time
{ //
// Get an IClassAdmin interface pointer
//
hr = GetClassAdmin (szContainer, &pIClassAdmin); if (!SUCCEEDED(hr)) return hr; //
// Get an IClassAccess interface pointer
//
hr = GetClassAccess (); if (!SUCCEEDED(hr)) return hr;
hr = DoRemoveTest (&cPkgCount);
hr = DoAdminTest(&cPkgCount); if (!SUCCEEDED(hr)) ++cErrCount; }
if (fBrowseTest) { hr = DoBrowseTest(pIClassAdmin); if (!SUCCEEDED(hr)) ++cErrCount; }
if (fClassInfoTest) { hr = DoClassInfoTest(); if (!SUCCEEDED(hr)) ++cErrCount; }
if ((i+1)%10 == 0) // After every Tenth time
{ //
// Progress Indicator. If errors display a :( else display a :)
//
if (cErrCount > cPrevCount) { printf (":( "); cPrevCount = cErrCount; } else printf (":) "); }
if ((i+1)%100 == 0) // After every Hundredth time
{ //
// Get rid of the interface pointers
//
CleanUp(); //
// Detail Progress indicator
//
printf ("\n ... %d Stress Passes Completed (with %d Errors).\n", i+1, cErrCount); } }
printf ("End of Class Store Stress for %d passes (%d MilliSec Per Loop) (%d Errors).\n", cLoops, (GetTickCount() - tc)/cLoops, cErrCount);
return S_OK; }
HRESULT RunTests() { HRESULT hr = S_OK;
pIClassAccess = NULL; pIClassAdmin = NULL; pIClassAdmin2 = NULL;
//
// Depending on run parameters
// invoke different tests
//
if (fBrowseTest || fAdminTest || fEmptyTest || fCatTest || fLogonPerfInitialize) { //
// Get an IClassAdmin interface pointer
//
hr = GetClassAdmin (szContainer, &pIClassAdmin); if (!SUCCEEDED(hr)) return hr;
if (fMultiStore) { hr = GetClassAdmin (szContainer2, &pIClassAdmin2); if (!SUCCEEDED(hr)) return hr; } }
if (fEmptyTest) {
VerbosePrint("... Empty Container Test Started.\n"); hr = EmptyClassStore (pIClassAdmin); VerbosePrint("... Empty Container Test Ended.\n");
if (pIClassAdmin2 != NULL) { VerbosePrint("... Empty Container Test on Second Class Store Started.\n"); hr = EmptyClassStore(pIClassAdmin2); VerbosePrint("... Empty Container Test on Second Class Store Ended.\n"); } if (SUCCEEDED(hr)) printf ("PASSED ---- Empty Container Test Suite.\n"); else printf ("FAILED ---- Empty Container Test Suite. hr = 0x%x.\n", hr); }
if (fAdminTest) { ULONG cCount, cPkgCount;
VerbosePrint("... Admin Test Started.\n"); hr = DoAdminTest(&cPkgCount); VerbosePrint("... Admin Test Ended. (Added %d Packages).\n", cPkgCount);
if (SUCCEEDED(hr)) printf ("PASSED ---- Admin Test Suite.\n"); else printf ("FAILED ---- Admin Test Suite. hr = 0x%x.\n", hr); }
if (fCatTest) { ULONG cCount, cPkgCount;
VerbosePrint("... Comcat Test Started.\n"); hr = DoCatTests(pIClassAdmin, pIClassAdmin2); VerbosePrint("... Admin Test Ended. \n");
if (SUCCEEDED(hr)) printf ("PASSED ---- Comcat Test Suite.\n"); else printf ("FAILED ---- Comcat Test Suite. hr = 0x%x.\n", hr); }
if (fBrowseTest) { VerbosePrint("... Browse Test Started.\n"); hr = DoBrowseTest(pIClassAdmin); VerbosePrint("... Browse Test Ended.\n");
if (pIClassAdmin2 != NULL) { VerbosePrint("... Browse Test on Second Class Store Started.\n"); hr = DoBrowseTest(pIClassAdmin2); VerbosePrint("... Browse Test on Second Class Store Ended.\n"); }
if (SUCCEEDED(hr)) printf ("PASSED ---- Browse Test Suite.\n"); else printf ("FAILED ---- Browse Test Suite. hr = 0x%x.\n", hr); }
if (fClassInfoTest || fRefreshTest) { //
// Get an IClassAccess interface pointer
//
hr = GetClassAccess (); if (!SUCCEEDED(hr)) return hr; }
if (fLogonPerf) { //
// Measure the performance during a std. logon
//
hr = DoLogonPerfTest(fLogonPerfInitialize);
}
if (fRefreshTest) { VerbosePrint("... Refresh Test Started.\n"); hr = RefreshTest (); VerbosePrint("... Refresh Test Ended.\n"); if (SUCCEEDED(hr)) printf ("PASSED ---- Refresh Test Suite.\n"); else printf ("FAILED ---- Refresh Test Suite. hr = 0x%x.\n", hr); }
if (fClassInfoTest) { VerbosePrint("... CoEnumApps Test Started.\n"); hr = DoCoEnumAppsTest(); VerbosePrint("... CoEnumApps Test Ended.\n");
VerbosePrint("... Class Store Lookup Test Started.\n"); hr = DoClassInfoTest(); VerbosePrint("... Class Store Lookup Test Ended.\n");
if (SUCCEEDED(hr)) printf ("PASSED ---- Class Store Lookup Test Suite.\n"); else printf ("FAILED ---- Class Store Lookup Test Suite. hr = 0x%x.\n", hr); }
if (fRemoveTest) { ULONG cPkgCount; VerbosePrint("... Remove Test Started.\n"); hr = DoRemoveTest(&cPkgCount); VerbosePrint("... Remove Test Ended.(%d Packages).\n", cPkgCount); if (SUCCEEDED(hr)) printf ("PASSED ---- Remove Test Suite.\n"); else printf ("FAILED ---- Remove Test Suite. hr = 0x%x.\n", hr); }
if (fDllTest) { /* BUGBUG. Deleted now. Add later.
IClassAdmin *pClassAdmin = NULL; extern Sname TestProgId1, TestClassDesc1; extern GUID TestClsid1;
//
// Test entry points in csadm.dll
//
VerbosePrint("... Dll Test Started.\n");
// 1. Create an empty store
hr = CsCreateClassStore(szNewContainer, L"CN=DrtClassStore");
// 2. Get an IClassAdmin for it.
if (SUCCEEDED(hr)) { VerbosePrint ("...... New Class Store created.\n"); wcscat (szNewContainer, L"/"); wcscat (szNewContainer, L"CN=DRTClassStore"); hr = CsGetClassStore(szNewContainer, (void **)&pClassAdmin); }
// 3. Use the IClassAdmin to add a class
if (SUCCEEDED(hr)) { VerbosePrint ("...... Connected to New Class Store.\n"); CLASSDETAIL ClassDetail;
memset (&ClassDetail, NULL, sizeof (CLASSDETAIL)); memcpy (&ClassDetail.Clsid, &TestClsid1, sizeof (GUID)); ClassDetail.pDefaultProgId = TestProgId1; ClassDetail.pszDesc = TestClassDesc1;
hr = pClassAdmin->NewClass(&ClassDetail); if (!SUCCEEDED(hr)) { printf ("ERROR! NewClass() returned 0x%x.\n", hr); return hr; }
VerbosePrint ("...... Added a class definition.\n");
// 4. Then delete the class
hr = pClassAdmin->DeleteClass(TestClsid1);
if (!SUCCEEDED(hr)) { printf ("ERROR! DeleteClass() returned 0x%x.\n", hr); return hr; }
VerbosePrint ("...... Deleted a class definition.\n");
// 5. Release the IClassAdmin
hr = pClassAdmin->Release();
// 6. Delete the Class Store
hr = CsDeleteClassStore(szNewContainer); if (!SUCCEEDED(hr)) { printf ("ERROR! Deleting ClassStore.\n", hr); return hr; } VerbosePrint ("...... Deleted the class store.\n"); }
VerbosePrint("... Dll Test Ended.\n");
if (SUCCEEDED(hr)) printf ("PASSED ---- Dll Test Suite.\n"); else printf ("FAILED ---- Dll Test Suite. hr = 0x%x.\n", hr); */ }
return hr; }
void CleanUp() { if (pIClassAdmin) { pIClassAdmin->Release(); pIClassAdmin = NULL; }
if (pIClassAdmin2) { pIClassAdmin2->Release(); pIClassAdmin2 = NULL; }
if (pIClassAccess) { pIClassAccess->Release(); pIClassAccess = NULL; }
}
void _cdecl main( int argc, char ** argv ) { HRESULT hr; INT i; LPWSTR szEnvVar;
//
// Check run parameters
//
fBrowseTest = FALSE; fVerbose = FALSE; fAdminTest = FALSE; fClassInfoTest = FALSE; fComprehensive = FALSE; fStress = FALSE; fRemoveTest = FALSE; fRefreshTest = FALSE; fMultiStore = FALSE; fEmptyTest = FALSE; fDllTest = FALSE; fCatTest = FALSE; fLogon = FALSE; fLogonPerf = FALSE; fClassInfoVerify = FALSE;
szPassword[0] = NULL; szContainer[0] = NULL; szLookupPackageName[0] = NULL; //
// Check if the env variable CLASSSTORE is defined
// Get the value of the CLASSSTORE environment variable.
//
szEnvVar = _wgetenv(L"DRT_CLASSSTORE");
//
// if so use that as the default path
//
if (szEnvVar != NULL) { wcscpy (szContainer, szEnvVar); }
BOOL fLoop = FALSE;
for (i=1; i < argc; ++i) { if (toupper(*argv[i]) != '-') { printf ("ERROR! Parameters must start with a hyphen.\n"); Usage(); return; }
switch (toupper(*(argv[i]+1))) { case 'P': MultiByteToWideChar ( CP_ACP, 0, (argv[i]+2), strlen (argv[i]+2) + 1, szContainer, _MAX_PATH); break; case 'E': fEmptyTest = TRUE; break; case 'B': fBrowseTest = TRUE; break; case 'V': fVerbose = TRUE; break; case 'A': fAdminTest = TRUE; break; case 'O': fOverwritePath = TRUE; break; case 'Q': fCatTest = TRUE; break; case 'G': fClassInfoTest = TRUE; if (*(argv[i]+2) == 'V') fClassInfoVerify = TRUE; break; case 'D': fDllTest = TRUE; break; case 'R': fRefreshTest = TRUE; break; case 'M': fMultiStore = TRUE; break; case 'C': fComprehensive = TRUE; break; case 'S': fStress = TRUE; break; case 'L': cLoops = atoi(argv[i]+2); fLoop = TRUE; break; case 'T': fLogonPerf = TRUE; if (*(argv[i]+2) == 'I') fLogonPerfInitialize = TRUE; break; case 'U': MultiByteToWideChar ( CP_ACP, 0, (argv[i]+2), strlen (argv[i]+2) + 1, szUserName, _MAX_PATH); pszDomain = pszUser = &szUserName[0];
while (*pszUser) { if (*pszUser == L'\\') { *pszUser = NULL; pszUser++; break; } pszUser++; }
if (*pszUser == NULL) { printf ("ERROR! Incorrect domain\\user specified.\nAborting ...\n"); return; }
fLogon = TRUE; break;
case 'W': MultiByteToWideChar ( CP_ACP, 0, (argv[i]+2), strlen (argv[i]+2) + 1, szPassword, _MAX_PATH); break; default: Usage(); return; } }
if (szContainer[0] == NULL) { //
// No default for container and none specified
//
printf ("ERROR! Class Container not specified and DRT_CLASSSTORE not set.\nAborting ...\n"); return; }
if (fMultiStore) { szEnvVar = _wgetenv(L"DRT_CLASSSTORE2"); if (szEnvVar != NULL) { wcscpy (szContainer2, szEnvVar); } else { printf ("ERROR! DRT_CLASSSTORE2 not set. Aborting ...\n"); return; } }
if (fDllTest) { szEnvVar = _wgetenv(L"DRT_NEWOU");
if (szEnvVar != NULL) { wcscpy (szNewContainer, szEnvVar); } else { printf ("ERROR! DRT_NEWOU not set. Aborting ...\n"); return; } }
if (!(fStress || fEmptyTest || fComprehensive || fBrowseTest || fClassInfoTest || fAdminTest || fCatTest || fLogonPerf)) { printf ("ERROR! No Tests specified. Aborting ...\n"); return; }
if (fStress && (fEmptyTest || fComprehensive || fAdminTest || fMultiStore)) { printf ("ERROR! For 'Stress Test' the only options are -g, -b and -l. \nAborting ...\n"); return; }
if ((fLogonPerf || fEmptyTest) && (fComprehensive || fBrowseTest || fClassInfoTest || fAdminTest)) { printf ("ERROR! Cant combine Empty or Logon Tests with any other test. \nAborting ...\n"); return; }
if (fComprehensive && (fBrowseTest || fClassInfoTest || fAdminTest)) { printf ("ERROR! Cant combine 'Comprehensive Test Suite' with any other individual tests. \nAborting ...\n"); return; }
if (fStress && (!(fBrowseTest || fClassInfoTest ))) { fClassInfoTest = TRUE; }
if (fLoop) { if (!fStress) { printf ("ERROR! Loop count applies only to Stress Test. Aborting ...\n"); return; } else { if (cLoops%100 != 0) { printf ("ERROR! Loop count can only be in multiple of 100s. Aborting ...\n"); return; } } }
//
// If test is to be run for a different user,
// do LogonUser
//
if (fLogon) { HANDLE hToken; BOOLEAN fEnable; NTSTATUS NtStatus;
printf( "Will run test as user: %S, domain: %S.\n", pszUser, pszDomain);
NtStatus = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &fEnable);
if ( NtStatus != STATUS_SUCCESS ) { printf( "ERROR! In RtlAdjustPrivilege. 0x%x. Aborting ...\n", NtStatus); return; }
if (!LogonUser( pszUser, // string that specifies the user name
pszDomain, // string that specifies the domain or server
szPassword, // string that specifies the password
LOGON32_LOGON_INTERACTIVE, // specifies the type of logon operation
LOGON32_PROVIDER_DEFAULT, // specifies the logon provider
&hToken // pointer to variable to receive token handle
)) { printf( "ERROR! Invalid username or password - 0x%x. Aborting ...\n", GetLastError()); return; }
if (!ImpersonateLoggedOnUser(hToken)) { printf( "ERROR! Impersonation failed. Aborting ...\n"); return; }
CloseHandle(hToken); }
hr = CoInitialize(NULL);
if( FAILED(hr) ) { printf( "ERROR! Client CoInitialize failed Ox%x. Aborting ...\n", hr ); return; }
VerbosePrint ("Using Class Store at:\n %S.\n", szContainer); if (fMultiStore) VerbosePrint ("Using Class Store 2 at:\n %S.\n", szContainer2);
if (fOverwritePath) { // Flush Class Store Cache and Overwrite Path
UpdateClassStoreSettings(szContainer); VerbosePrint("... Overwrote Class Store Path.\n"); } else { GetUserClassStore(szClassStorePath); VerbosePrint ("Profile ClassStore:\n %S.\n", szClassStorePath);
//
// Verify that the Profile matches the input.
//
if (NULL == wcsstr(szClassStorePath, szContainer)) { printf( "Warning! Class Store is different from Profile.\n"); }
if (NULL == wcsstr(szClassStorePath, szContainer2)) { printf( "Warning! Second Class Store is different from Profile.\n"); }
}
InitTempNames();
if (fComprehensive) { hr = RunComprehensive(); }
else { if (fStress) { fVerbose = FALSE; hr = RunStress(); } else { hr = RunTests(); CleanUp(); } }
CoUninitialize();
}
//
// This routine takes a pathname and binds to a Class container
// and returns an IClassAdmin interface pointer
//
HRESULT GetClassAdmin (LPOLESTR pszPath, IClassAdmin **ppCA) { HRESULT hr; LPOLESTR szPath;
*ppCA = NULL; if (wcsncmp (pszPath, L"ADCS:", 5) == 0) { szPath = pszPath + 5; } else szPath = pszPath;
hr = CsGetClassStore(szPath, (void **)ppCA);
if ( FAILED(hr) ) { printf("ERROR! Could not get IClassAdmin. Error- 0x%x\n", hr); return hr; }
return S_OK;
}
//
// This routine binds to a CClassAccess on the desktop and
// returns an IClassAccess interface pointer
//
HRESULT GetClassAccess () { HRESULT hr; pIClassAccess = NULL; hr = CsGetClassAccess (&pIClassAccess);
if ( FAILED(hr) ) { printf("ERROR! Could not get IClassAccess. Error- 0x%x\n", hr); return hr; } return S_OK; }
void GetDefaultPlatform(CSPLATFORM *pPlatform) { OSVERSIONINFO VersionInformation;
VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&VersionInformation);
pPlatform->dwPlatformId = VersionInformation.dwPlatformId; pPlatform->dwVersionHi = VersionInformation.dwMajorVersion; pPlatform->dwVersionLo = VersionInformation.dwMinorVersion; pPlatform->dwProcessorArch = DEFAULT_ARCHITECTURE; }
//
// This routine enumerates all classes, packages and
// cleans up the entire Class Container by deleting these objects.
//
HRESULT EmptyClassStore (IClassAdmin *pIClassAdmin) { HRESULT hr; ULONG cCount;
hr = EnumPackagesAndDelete(pIClassAdmin, TRUE, &cCount); if (!SUCCEEDED(hr)) return hr; VerbosePrint ("...... Deleted all %d Packages.\n", cCount); return S_OK; }
//
// This routine enumerates all classes and packages
//
HRESULT DoBrowseTest (IClassAdmin *pCA) { HRESULT hr; ULONG cCount;
hr = EnumPackagesAndDelete(pCA, FALSE, &cCount); if (!SUCCEEDED(hr)) return hr;
VerbosePrint ("...... Browsed %d Packages.\n", cCount);
return S_OK; }
void PrintPackageInfo(PACKAGEDISPINFO *pPackageInfo) { SYSTEMTIME SystemTime; if (fVerbose) { FileTimeToSystemTime( (CONST FILETIME *)(&pPackageInfo->Usn), &SystemTime); VerbosePrint("........ Package: %S \n........ Last Update: %d-%d-%d %d:%d:%d\n", pPackageInfo->pszPackageName, SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond); VerbosePrint("........ Script Size = %d. Path = %S\n", pPackageInfo->cScriptLen, pPackageInfo->pszScriptPath); } }
void PrintInstallInfo(INSTALLINFO *pInstallInfo) { SYSTEMTIME SystemTime;
FileTimeToSystemTime( (CONST FILETIME *)(&pInstallInfo->Usn), &SystemTime);
VerbosePrint("........ Script: %S (Size = %d)\n........ Last Update: %d-%d-%d %d:%d:%d\n", pInstallInfo->pszScriptPath, pInstallInfo->cScriptLen, SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond); }
/*
void PrintCategoryDetail(CATEGORYINFO *pCatInfo) { VerbosePrint("........ Category Description: %S\n", pCatInfo->szDescription); } */
HRESULT EnumPackagesAndDelete(IClassAdmin *pIClassAdmin, BOOL fDelete, ULONG *pcPackages) { ULONG cFetched; IEnumPackage *pIEnumPackage = NULL; HRESULT hr; PACKAGEDISPINFO PackageInfo;
*pcPackages=0;
hr = pIClassAdmin->EnumPackages( NULL, NULL, 0, NULL, NULL, &pIEnumPackage);
if ( FAILED(hr)) { printf("ERROR! EnumPackages returned 0x%x\n", hr); return hr; }
while (TRUE) { memset (&PackageInfo, 0, sizeof(PACKAGEDISPINFO)); hr = pIEnumPackage->Next(1, &PackageInfo, &cFetched); if (FAILED(hr)) { break; } if ((hr == S_FALSE) || (cFetched < 1)) { hr = S_OK; break; } (*pcPackages)++;
if (fVerbose && !fDelete) { PrintPackageInfo(&PackageInfo); }
if (fDelete) { hr = pIClassAdmin->RemovePackage(PackageInfo.pszPackageName, 0); }
ReleasePackageInfo(&PackageInfo); }
pIEnumPackage->Release(); if (fVerbose) { if (!SUCCEEDED(hr)) printf("ERROR! 0x%x.\n", hr); }
return hr; }
/*
HRESULT EnumCategoriesAndDelete (IClassAdmin *pIClassAdmin, BOOL fDelete, ULONG *pcCategories) { ULONG cFetched; IEnumCATEGORYINFO *pIEnumCat; HRESULT hr; CATEGORYINFO CatInfo; ICatRegister *pICatReg; ICatInformation *pICatInfo; LCID lcid = 0;
*pcCategories = 0; hr = pIClassAdmin->QueryInterface(IID_ICatRegister, (void **)&pICatReg); if (FAILED(hr)) { printf("Error! QI CR hr = 0x%x\n", hr); return hr; } hr = pIClassAccess->QueryInterface(IID_ICatInformation, (void **)&pICatInfo); if (FAILED(hr)) { printf("Error! QI CI hr = 0x%x\n", hr); return hr; }
hr = pICatInfo->EnumCategories(lcid, &pIEnumCat); if ( FAILED(hr)) { return hr; }
while (TRUE) { hr = pIEnumCat->Next(1, &CatInfo, &cFetched); if (FAILED(hr)) { break; } if ((hr == S_FALSE) || (cFetched < 1)) { hr = S_OK; break; } (*pcCategories)++;
if (fVerbose && !fDelete) { PrintCategoryDetail(&CatInfo); }
if (fDelete) { hr = pICatReg->UnRegisterCategories(1, &(CatInfo.catid)); if (!SUCCEEDED(hr)) break; }
}
pIEnumCat->Release(); if (fVerbose) { if (!SUCCEEDED(hr)) printf("ERROR! 0x%x.\n", hr); }
pICatReg->Release(); pICatInfo->Release();
return hr; } */
void ReleasePackageDetail(PACKAGEDETAIL *pPackageDetail, BOOL fPartial) { if (pPackageDetail->pActInfo) { CoTaskMemFree(pPackageDetail->pActInfo->prgShellFileExt); CoTaskMemFree(pPackageDetail->pActInfo->prgPriority); CoTaskMemFree(pPackageDetail->pActInfo->prgInterfaceId); CoTaskMemFree(pPackageDetail->pActInfo->prgTlbId); CoTaskMemFree(pPackageDetail->pActInfo); }
if (pPackageDetail->pPlatformInfo) { CoTaskMemFree(pPackageDetail->pPlatformInfo->prgPlatform); CoTaskMemFree(pPackageDetail->pPlatformInfo->prgLocale); CoTaskMemFree(pPackageDetail->pPlatformInfo); }
if (pPackageDetail->pInstallInfo) { if (!fPartial) ReleaseInstallInfo(pPackageDetail->pInstallInfo); CoTaskMemFree(pPackageDetail->pInstallInfo); }
CoTaskMemFree(pPackageDetail->pszSourceList); CoTaskMemFree(pPackageDetail->rpCategory); }
void GetUserClassStore(LPWSTR szPath) { LONG lErrorCode; DWORD dwDataLen = 1000; DWORD dwType; HKEY hKey = NULL; HRESULT hr = S_OK;
*szPath = NULL;
lErrorCode = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\ClassStore", NULL, KEY_ALL_ACCESS, &hKey);
if ( lErrorCode != ERROR_SUCCESS) { return; }
lErrorCode = RegQueryValueEx(hKey, L"Path", NULL, &dwType, (LPBYTE)szPath, &dwDataLen);
RegCloseKey(hKey);
return;
}
|