1190 lines
29 KiB
C++
1190 lines
29 KiB
C++
//
|
||
// 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;
|
||
|
||
}
|
||
|
||
|