windows-nt/Source/XPSP1/NT/com/ole32/cs/csdrt/csdrt.cxx
2020-09-26 16:20:57 +08:00

1190 lines
29 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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;
}