1181 lines
34 KiB
C++
1181 lines
34 KiB
C++
/***********************************************************************
|
|
File: execute.cpp
|
|
Description: this thing holds all the Execute functions for all the classes
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
#include "clsCommand.h"
|
|
#include "iiisext.h"
|
|
#include <fstream.h>
|
|
|
|
int clsCommand::Execute()
|
|
{ // Common startup code
|
|
|
|
HRESULT hresError = 0;
|
|
int iResult = 0;
|
|
|
|
// Class selection
|
|
switch (indicator)
|
|
{ case CMD_ENUM: // ENUM
|
|
{ iResult = objEnum.Execute();
|
|
break;
|
|
}
|
|
case CMD_ENUMALL: // ENUM_ALL
|
|
{ iResult = objEnum.Execute();
|
|
break;
|
|
}
|
|
case CMD_SET: // SET
|
|
{ iResult = objSet.Execute();
|
|
break;
|
|
}
|
|
case CMD_CREATE: // CREATE
|
|
case CMD_CREATEVDIR: // CREATE_VDIR
|
|
case CMD_CREATEVSERV: // CREATE_VSERV
|
|
{ iResult = objCreate.Execute();
|
|
break;
|
|
}
|
|
case CMD_DELETE: // DELETE
|
|
{ iResult = objDelete.Execute();
|
|
break;
|
|
}
|
|
case CMD_GET: // GET
|
|
{ iResult = objGet.Execute();
|
|
break;
|
|
}
|
|
case CMD_COPY: // COPY
|
|
case CMD_MOVE: // MOVE
|
|
{ iResult = objCopyMove.Execute(indicator);
|
|
break;
|
|
}
|
|
case CMD_STARTSERVER: // START_SERVER
|
|
case CMD_STOPSERVER: // STOP_SERVER
|
|
case CMD_PAUSESERVER: // PAUSE_SERVER
|
|
case CMD_CONTINUESERVER: // CONTINUE_SERVER
|
|
{ iResult = objServerCommand.Execute(indicator);
|
|
break;
|
|
}
|
|
case CMD_FIND: // FIND
|
|
{ iResult = objFind.Execute();
|
|
break;
|
|
}
|
|
case CMD_APPCREATEINPROC: // APPCREATEINPROC
|
|
case CMD_APPCREATEOUTPROC: // APPCREATEOUTPROC
|
|
case CMD_APPDELETE: // APPDELETE
|
|
case CMD_APPUNLOAD: // APPUNLOAD
|
|
case CMD_APPGETSTATUS: // APPGETSTATUS
|
|
{ iResult = objApp.Execute(indicator);
|
|
break;
|
|
}
|
|
case CMD_HELP: // HELP
|
|
{ iResult = objHelp.Execute();
|
|
break;
|
|
}
|
|
case CMD_SCRIPT: // SCRIPT
|
|
{ iResult = objScript.Execute();
|
|
break;
|
|
}
|
|
case CMD_APPEND: // APPEND
|
|
{ iResult = objAppend.Execute();
|
|
break;
|
|
}
|
|
case CMD_REMOVE:
|
|
{ iResult = objRemove.Execute();
|
|
break;
|
|
}
|
|
default:
|
|
{ printf("This command is not supported.\n");
|
|
iResult = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Common cleanup code
|
|
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// handles all the Application specific functions
|
|
int clsAPP::Execute(int TheCommand)
|
|
{ HRESULT hresError = 0;
|
|
int iResult = 0;
|
|
|
|
BSTR SuccessMsg;
|
|
BSTR FailureMsg;
|
|
DWORD dwStatus = 0;
|
|
|
|
IISApp *pApp = NULL;
|
|
|
|
// Debug
|
|
IDispatch *pDisp = NULL;
|
|
DISPID dispid;
|
|
OLECHAR* olestrFuncName = L"AppGetStatus";
|
|
|
|
hresError = ADsGetObject(Path, IID_IDispatch, (void**) &pDisp);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{
|
|
printf ("Could not get the dispatch interface\n");
|
|
}
|
|
// End Debug
|
|
|
|
hresError = ADsGetObject(Path, IID_IISApp, (void **) &pApp);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ switch (TheCommand)
|
|
{ case CMD_APPCREATEINPROC: // creates an in process application
|
|
{ hresError = pApp->AppCreate(true);
|
|
SuccessMsg = SysAllocString(L"Application Created.");
|
|
FailureMsg = SysAllocString(L"Error trying to CREATE the application");
|
|
break;
|
|
}
|
|
case CMD_APPCREATEOUTPROC: // creates an out of process application
|
|
{ hresError = pApp->AppCreate(false);
|
|
SuccessMsg = SysAllocString(L"Application Created.");
|
|
FailureMsg = SysAllocString(L"Error trying to CREATE the application");
|
|
break;
|
|
}
|
|
case CMD_APPDELETE: // deletes an application
|
|
{ hresError = pApp->AppDelete();
|
|
SuccessMsg = SysAllocString(L"Application Deleted.");
|
|
FailureMsg = SysAllocString(L"Error trying to DELETE the application");
|
|
break;
|
|
}
|
|
case CMD_APPUNLOAD: // unloads an application
|
|
{ hresError = pApp->AppUnLoad();
|
|
SuccessMsg = SysAllocString(L"Application Unloaded.");
|
|
FailureMsg = SysAllocString(L"Error trying to UNLOAD the application");
|
|
break;
|
|
}
|
|
case CMD_APPGETSTATUS: // gets the status of an application
|
|
{ hresError = pApp->AppGetStatus(&dwStatus);
|
|
FailureMsg = SysAllocString(L"Error trying to retrieve the application STATUS");
|
|
|
|
if (pDisp)
|
|
{
|
|
printf ("\nCalling AppGetStatus using the IDispatchInterface\n");
|
|
hresError = pDisp->GetIDsOfNames (
|
|
IID_NULL,
|
|
&olestrFuncName,
|
|
1,
|
|
GetUserDefaultLCID(),
|
|
&dispid);
|
|
|
|
printf ("Result of calling GetIDsOfNames for AppGetStatus: %u (%#x)\n",
|
|
hresError,
|
|
hresError);
|
|
printf ("Disp ID For AppGetStatus: %u\n",
|
|
dispid);
|
|
|
|
ULONG ulValue = -1;
|
|
ULONG *pulValue = &ulValue;
|
|
//ULONG *pulValue = NULL;
|
|
VARIANTARG varg;
|
|
VariantInit (&varg);
|
|
varg.vt = VT_BYREF | VT_UI4;
|
|
varg.pulVal = pulValue;
|
|
|
|
DISPPARAMS param;
|
|
param.cArgs = 1;
|
|
param.rgvarg = &varg;
|
|
param.cNamedArgs = 0;
|
|
param.rgdispidNamedArgs = NULL;
|
|
|
|
VARIANT *pVarResult = NULL;
|
|
EXCEPINFO *pExcepInfo = NULL;
|
|
UINT *puArgErr = NULL;
|
|
|
|
printf ("ulValue prior to Invoke: %u (%#x)\n",
|
|
ulValue,
|
|
ulValue);
|
|
|
|
hresError = pDisp->Invoke (
|
|
dispid,
|
|
IID_NULL,
|
|
GetUserDefaultLCID(),
|
|
DISPATCH_METHOD,
|
|
¶m,
|
|
pVarResult,
|
|
pExcepInfo,
|
|
puArgErr);
|
|
|
|
printf ("result of calling Invoke:\n"
|
|
" hresError: %u (%#x)\n"
|
|
" pVarResult: %#x\n"
|
|
" pExcepInfo: %#x\n"
|
|
" puArgErr: %#x\n",
|
|
hresError, hresError,
|
|
pVarResult,
|
|
pExcepInfo,
|
|
puArgErr);
|
|
|
|
printf ("Value of argument pulValue:\n"
|
|
" pulValue address: %u (%#x)\n"
|
|
" ulValue address: %u (%#x)\n"
|
|
" ulValue value: %u (%#x)\n",
|
|
pulValue, pulValue,
|
|
&ulValue, &ulValue,
|
|
ulValue, ulValue);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
if (hresError == ERROR_SUCCESS)
|
|
{ if (TheCommand == 20)
|
|
printf("Application status: %u\n", dwStatus);
|
|
else
|
|
printf("%S\n", SuccessMsg);
|
|
iResult = 0;
|
|
}
|
|
else
|
|
{ printf("%S: %S\n", FailureMsg, Path);
|
|
iResult = 1;
|
|
}
|
|
}
|
|
pApp->Release();
|
|
SysFreeString(Path);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// this appends a value to a LIST type property
|
|
int clsAPPEND::Execute()
|
|
{ int iResult = 0;
|
|
HRESULT hresError = 0;
|
|
|
|
BSTR Type;
|
|
|
|
VARIANT varOld; // Holds the array of old values
|
|
VARIANT *OldValues; // the old values
|
|
|
|
// BSTR Value; // Value to append
|
|
|
|
VARIANT varNew; // Holds the array of new values
|
|
SAFEARRAY FAR* NewArray; // the array of new values
|
|
SAFEARRAYBOUND NewArrayBound[1];
|
|
VARIANT *NewValues = NULL; // the new values
|
|
NewArrayBound[0].lLbound = 0;
|
|
|
|
IADs *pADs = NULL;
|
|
IISBaseObject *pBaseObject = NULL;
|
|
|
|
hresError = ADsGetObject(Path, IID_IADs, (void **) &pADs);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
else
|
|
{ hresError = ADsGetObject(Path, IID_IISBaseObject, (void **) &pBaseObject);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not get the base object.\n");
|
|
pADs->Release();
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
}
|
|
// You can find IsSet and GetProperty in common.cpp
|
|
if ((IsSet(pBaseObject, Path, Property) == 1))// && (PROP_OK == IsSpecialProperty(Property)))
|
|
{ GetProperty(pADs, Property, &varOld, &Type);
|
|
if (_wcsicmp(Type, L"list"))
|
|
{// ***** Converts from any type to a list, then appends *****
|
|
|
|
VARIANT varbstr;
|
|
hresError = VariantChangeType(&varbstr, &varOld, 0, VT_BSTR);
|
|
|
|
// Build the new array
|
|
NewArrayBound[0].cElements = 2;
|
|
NewArray = SafeArrayCreate(VT_VARIANT, 1, NewArrayBound);
|
|
if (NewArray == NULL)
|
|
{ iResult = 1;
|
|
goto xit;
|
|
}
|
|
varNew.vt = VT_ARRAY|VT_VARIANT;
|
|
varNew.parray = NewArray;
|
|
NewValues[0].bstrVal = SysAllocString(varbstr.bstrVal);
|
|
// Put the value to append into the new array
|
|
NewValues[1].bstrVal = SysAllocString(Value);
|
|
}
|
|
else
|
|
{// ***** appends an item to a list *****
|
|
// Build the new array
|
|
NewArrayBound[0].cElements = varOld.parray->rgsabound[0].cElements + 1;
|
|
NewArray = SafeArrayCreate(VT_VARIANT, 1, NewArrayBound);
|
|
if (NewArray == NULL)
|
|
{ iResult = 1;
|
|
goto xit;
|
|
}
|
|
varNew.vt = VT_ARRAY|VT_VARIANT;
|
|
varNew.parray = NewArray;
|
|
|
|
// Get a handle on the data for both arrays
|
|
OldValues = (VARIANT*) varOld.parray->pvData;
|
|
NewValues = (VARIANT*) varNew.parray->pvData;
|
|
|
|
// Put all the old values into the new array
|
|
for (unsigned long l = 0; l < varOld.parray->rgsabound[0].cElements; l++)
|
|
{ NewValues[l].vt = VT_BSTR;
|
|
NewValues[l].bstrVal = SysAllocString(OldValues[l].bstrVal);
|
|
}
|
|
// Put the value to append into the new array
|
|
NewValues[varOld.parray->rgsabound[0].cElements].bstrVal = SysAllocString(Value);
|
|
}
|
|
}
|
|
else
|
|
{// ***** does a normal SET for an empty property *****
|
|
varNew.vt = VT_BSTR;
|
|
varNew.bstrVal = SysAllocString(Value);
|
|
}
|
|
|
|
// Put the new property
|
|
hresError = pADs->Put(Property, varNew);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not set \"%S\" to ", Property);
|
|
PrintVariant(varNew);
|
|
printf("\n");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ hresError = pADs->SetInfo();
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not commit changes to the metabase.");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ printf("%-32S: (%S) ", Property, Type);
|
|
PrintVariant(varNew);
|
|
printf("\n");
|
|
iResult = 0;
|
|
}
|
|
}
|
|
pBaseObject->Release();
|
|
pADs->Release();
|
|
xit:
|
|
SysFreeString(Path);
|
|
SysFreeString(Property);
|
|
SysFreeString(Value);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// copies/moves an object in the metabase to some other point
|
|
// in the same metabase
|
|
int clsCOPY_MOVE::Execute(int TheCommand)
|
|
{ HRESULT hresError = 0;
|
|
int iResult = 0;
|
|
|
|
BSTR SuccessMsg;
|
|
|
|
IADsContainer *pADsContainer = NULL;
|
|
IDispatch *pDispatch = NULL;
|
|
|
|
// refer to clsCOPY_MOVE::ParseCommand for an explanation
|
|
// of ParentPath, SrcPath, and DstPath.
|
|
hresError = ADsGetObject(ParentPath, IID_IADsContainer, (void **) &pADsContainer);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not get the base object");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
switch (TheCommand)
|
|
{
|
|
case CMD_COPY: // copies object located at SrcPath to DstPath
|
|
{ hresError = pADsContainer->CopyHere(SrcPath, DstPath, &pDispatch);
|
|
SuccessMsg = SysAllocString(L"Copied");
|
|
break;
|
|
}
|
|
|
|
case CMD_MOVE: // moves object located at SrcPath to DstPath
|
|
{ hresError = pADsContainer->MoveHere(SrcPath, DstPath, &pDispatch);
|
|
SuccessMsg = SysAllocString(L"Moved");
|
|
break;
|
|
}
|
|
}// switch TheCommand
|
|
|
|
if (hresError == ERROR_SUCCESS)
|
|
{ printf("%S from %S to %S\n", SuccessMsg, SrcPath, DstPath);
|
|
pDispatch->Release();
|
|
iResult = 0;
|
|
}
|
|
else
|
|
{ printf("Error %x\n", hresError);
|
|
iResult = 1;
|
|
}
|
|
xit:
|
|
pADsContainer->Release();
|
|
SysFreeString(ParentPath);
|
|
SysFreeString(DstPath);
|
|
SysFreeString(SrcPath);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// this creates just about anything you want
|
|
int clsCREATE::Execute()
|
|
{ HRESULT hresError = 0;
|
|
int iResult = 0;
|
|
|
|
IADsContainer *pADsContainer = NULL;
|
|
IDispatch *pDispatch;
|
|
IADs *pADs = NULL;
|
|
|
|
// Gets the container
|
|
hresError = ADsGetObject(Path, IID_IADsContainer, (void **) &pADsContainer);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
// Creates the object
|
|
hresError = pADsContainer->Create(Type, Property, &pDispatch);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not create %S\n", Property);
|
|
iResult = 1;
|
|
pADsContainer->Release();
|
|
goto xit;
|
|
}
|
|
|
|
// nabs up the Dispatch
|
|
hresError = pDispatch->QueryInterface(IID_IADs, (void **) &pADs);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with QueryInterface.\n");
|
|
iResult = 1;
|
|
pADsContainer->Release();
|
|
pADs->Release();
|
|
goto xit;
|
|
}
|
|
|
|
// commits the changes
|
|
hresError = pADs->SetInfo();
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not update the metabase.\n");
|
|
iResult = 1;
|
|
pADsContainer->Release();
|
|
pDispatch->Release();
|
|
pADs->Release();
|
|
goto xit;
|
|
}
|
|
else
|
|
{ printf("created \"%S\"\n", Property);
|
|
iResult = 0;
|
|
}
|
|
|
|
pADsContainer->Release();
|
|
pDispatch->Release();
|
|
pADs->Release();
|
|
xit:
|
|
SysFreeString(Path);
|
|
// SysFreeString(Property);
|
|
SysFreeString(Type);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// deletes a path or clears a property in the metabase
|
|
int clsDELETE::Execute()
|
|
{ HRESULT hresError = 0;
|
|
int iResult = 0;
|
|
DWORD ConvertResult = 0;
|
|
|
|
IADs *pADs = NULL;
|
|
IADsContainer *pADsContainer = NULL;
|
|
|
|
// this determines if the full path is pointing to a path or a property
|
|
hresError = ADsGetObject(PathProperty, IID_IADs, (void **) &pADs);
|
|
if (hresError != ERROR_SUCCESS) // Delete a property
|
|
{ hresError = ADsGetObject(Path, IID_IADs, (void **) &pADs);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ VARIANT vProp;
|
|
VariantInit(&vProp);
|
|
hresError = pADs->PutEx(1, Property, vProp); // 1 = Clear
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Error deleting the object: %S\n", PathProperty);
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ printf("deleted property \"%S\"\n", Property);
|
|
iResult = 0;
|
|
}
|
|
VariantClear(&vProp);
|
|
}
|
|
}
|
|
else // Delete a path
|
|
{ pADs->Release();
|
|
hresError = ADsGetObject(Path, IID_IADsContainer, (void **) &pADsContainer);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject\n");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ hresError = pADsContainer->Delete(L"IIsObject", Property);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Error deleting the object: %S\n", PathProperty);
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ printf("deleted path \"%S\"\n", PathProperty);
|
|
iResult = 0;
|
|
}
|
|
pADsContainer->Release();
|
|
}
|
|
}
|
|
SysFreeString(Path);
|
|
// SysFreeString(Property);
|
|
SysFreeString(PathProperty);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// This enumerates the properties (optional, mandatory, set, or unset)
|
|
// within a specified path. Will recurse if ENUM_ALL is used
|
|
int clsENUM::Execute()
|
|
{ HRESULT hresError = 0;
|
|
int iResult = 0;
|
|
|
|
unsigned long l;
|
|
unsigned long NumberReturned = 1;
|
|
|
|
IADs *pADs = NULL;
|
|
IADsClass *pADsClass = NULL;
|
|
IISBaseObject *pBaseObject = NULL;
|
|
IDispatch *pDispatch = NULL;
|
|
IEnumVARIANT *pEnumVariant = NULL;
|
|
IADsContainer *pADsContainer = NULL;
|
|
// if the PathOnlyOption is false
|
|
if (PathOnlyOption == false)
|
|
{ // Gets the path as an IADs object
|
|
hresError = ADsGetObject(Path, IID_IADs, (void **) &pADs);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
// Nabs up the schema
|
|
BSTR bstrSchema;
|
|
hresError = pADs->get_Schema(&bstrSchema);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Couldn't get the schema.\n");
|
|
iResult = 1;
|
|
pADs->Release();
|
|
goto xit;
|
|
}
|
|
// gets the Class from the schema
|
|
hresError = ADsGetObject(bstrSchema, IID_IADsClass, (void **) &pADsClass);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Couldn't get the object's schema.\n");
|
|
iResult = 1;
|
|
pADs->Release();
|
|
goto xit;
|
|
}
|
|
// gets the BaseObject from pADs
|
|
hresError = pADs->QueryInterface(IID_IISBaseObject, (void **) &pBaseObject);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not get the base object.\n");
|
|
iResult = 1;
|
|
pADs->Release();
|
|
pADsClass->Release();
|
|
goto xit;
|
|
}
|
|
// some miscellaneous dumps for stuff i use for one line
|
|
VARIANT varProperties;
|
|
SAFEARRAY *PropertyArray;
|
|
VARIANT *varProperty;
|
|
long LowerBound;
|
|
unsigned long UpperBound;
|
|
BSTR Type;
|
|
VARIANT Value;
|
|
VariantInit(&Value);
|
|
//******** Enumerates the mandatory properties
|
|
VariantInit(&varProperties);
|
|
|
|
// puts the mandatory properties into a Variant temporarily
|
|
hresError = pADsClass->get_MandatoryProperties(&varProperties);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Couldn't get the object's mandatory properties.\n");
|
|
}
|
|
else
|
|
{ // Takes the temporary Variant array and makes it a SafeArray
|
|
PropertyArray = varProperties.parray;
|
|
// Calculates the bounds just for style
|
|
LowerBound = PropertyArray->rgsabound[0].lLbound;
|
|
UpperBound = PropertyArray->rgsabound[0].cElements;
|
|
// Creates the official property array
|
|
varProperty = (VARIANT*) PropertyArray->pvData;
|
|
// for each property
|
|
|
|
for (l = LowerBound; l < UpperBound; l++)
|
|
{ if (((IsSet(pBaseObject, Path, varProperty[l].bstrVal) == 1) || (AllDataOption == true)) && (PROP_OK == IsSpecialProperty(varProperty[l].bstrVal)))
|
|
{ GetProperty(pADs, varProperty[l].bstrVal, &Value, &Type);
|
|
printf("%-32S: (%S) ", varProperty[l].bstrVal, Type);
|
|
PrintVariant(Value);
|
|
printf("\n");
|
|
}
|
|
}
|
|
}
|
|
VariantClear(&varProperties);
|
|
//******** and repeat for Optional properties
|
|
VariantInit(&varProperties);
|
|
hresError = pADsClass->get_OptionalProperties(&varProperties);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Couldn't get the object's optional properties.\n");
|
|
}
|
|
else
|
|
{ PropertyArray = varProperties.parray;
|
|
LowerBound = PropertyArray->rgsabound[0].lLbound;
|
|
UpperBound = PropertyArray->rgsabound[0].cElements;
|
|
varProperty = (VARIANT*) PropertyArray->pvData;
|
|
|
|
for (l = LowerBound; l < UpperBound; l++)
|
|
{
|
|
if (((IsSet(pBaseObject, Path, varProperty[l].bstrVal) == 1) || (AllDataOption == true)) && (PROP_OK == IsSpecialProperty(varProperty[l].bstrVal)))
|
|
{
|
|
GetProperty(pADs, varProperty[l].bstrVal, &Value, &Type);
|
|
printf("%-32S: (%S) ", varProperty[l].bstrVal, Type);
|
|
PrintVariant(Value);
|
|
printf("\n");
|
|
}
|
|
|
|
}
|
|
|
|
VariantClear(&varProperties);
|
|
}
|
|
pADs->Release();
|
|
pADsClass->Release();
|
|
pBaseObject->Release();
|
|
} // if !PathOnlyOption
|
|
//******** Enumerate the child nodes and recurse if requested
|
|
|
|
// Gets the container
|
|
hresError = ADsGetObject(Path, IID_IADsContainer, (void **) &pADsContainer);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
// builds the enumerator
|
|
hresError = ADsBuildEnumerator(pADsContainer, &pEnumVariant);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not build the enumerator.\n");
|
|
iResult = 1;
|
|
pADsContainer->Release();
|
|
goto xit;
|
|
}
|
|
|
|
VARIANT varChildren;
|
|
|
|
// while ADsEnumerateNext returns child nodes
|
|
while (NumberReturned > 0)
|
|
{ VariantInit(&varChildren);
|
|
|
|
// get some child nodes
|
|
hresError = ADsEnumerateNext(pEnumVariant, 1, &varChildren, &NumberReturned);
|
|
if (hresError == ERROR_SUCCESS)
|
|
{
|
|
// for each child node returned
|
|
for (l = 0; l < NumberReturned; l++)
|
|
{
|
|
// gets the IDispatch equivalent of the child node
|
|
pDispatch = varChildren.pdispVal;
|
|
|
|
// gets the IADs equivalent of the child node
|
|
hresError = pDispatch->QueryInterface(IID_IADs, (void **) &pADs);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with QueryInterface.\n");
|
|
iResult = 1;
|
|
pDispatch->Release();
|
|
goto xit;
|
|
}
|
|
|
|
// gets the path string from the child node
|
|
// and assigns it to the Path data member of clsENUM
|
|
hresError = pADs->get_ADsPath(&Path);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not get ADsPath.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
// print out the child node's path
|
|
printf("[%S]\n", wcschr(Path + 7, '/'));
|
|
|
|
// if the command was ENUM_ALL then
|
|
if (Recurse == true)
|
|
{ iResult = Execute(); // calls itself, Path has already been modified
|
|
}
|
|
|
|
// more cleanup
|
|
pADs->Release();
|
|
pDispatch->Release();
|
|
|
|
}// for l
|
|
|
|
}// if hreserror
|
|
|
|
}// while numberreturned
|
|
|
|
pADsContainer->Release();
|
|
pEnumVariant->Release();
|
|
xit:
|
|
SysFreeString(Path);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// The user specifies a property within a path, and all child paths
|
|
// that have the same property set are returned. If the property
|
|
// in a path does not exist or is not set, then it's skipped.
|
|
int clsFIND::Execute()
|
|
{ HRESULT hresError;
|
|
int iResult = 0;
|
|
|
|
VARIANT pvPaths;
|
|
IISBaseObject *pBaseObject = NULL;
|
|
SAFEARRAY *PathArray;
|
|
VARIANT *varPath;
|
|
unsigned long l;
|
|
|
|
hresError = ADsGetObject(Path, IID_IISBaseObject, (void **) &pBaseObject);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not get the base object");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
VariantInit(&pvPaths);
|
|
hresError = pBaseObject->GetDataPaths(Property, 0, &pvPaths);
|
|
if (hresError == ERROR_SUCCESS)
|
|
{ printf("Property %S was found at:\n", Property);
|
|
PathArray = pvPaths.parray;
|
|
varPath = (VARIANT*) PathArray->pvData;
|
|
for (l = 0; l < PathArray->rgsabound[0].cElements; l++)
|
|
{ printf(" %S\n", varPath[l].bstrVal);
|
|
}
|
|
iResult = 0;
|
|
}
|
|
else
|
|
{ VariantClear(&pvPaths);
|
|
VariantInit(&pvPaths);
|
|
hresError = pBaseObject->GetDataPaths(Property, 1, &pvPaths);
|
|
if (hresError == ERROR_SUCCESS)
|
|
{ printf("Property %S was found at:\n", Property);
|
|
PathArray = pvPaths.parray;
|
|
varPath = (VARIANT*) PathArray->pvData;
|
|
for (l = 0; l < PathArray->rgsabound[0].cElements; l++)
|
|
{ printf(" %S\n", varPath[l].bstrVal);
|
|
}
|
|
iResult = 0;
|
|
}
|
|
else
|
|
{ printf("Error trying to get a path list (GetDataPaths Failed): %S\n", Path);
|
|
iResult = 1;
|
|
}
|
|
}
|
|
xit:
|
|
VariantClear(&pvPaths);
|
|
pBaseObject->Release();
|
|
SysFreeString(Path);
|
|
SysFreeString(Property);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// Gets the value of a specified property in a specified path
|
|
int clsGET::Execute()
|
|
{ int iResult = 0;
|
|
BSTR Type;
|
|
VARIANT Value;
|
|
|
|
// Get the object specified by adspath
|
|
IADs *pADs = NULL;
|
|
HRESULT hresError = 0;
|
|
IISBaseObject *pBaseObject = NULL;
|
|
|
|
hresError = ADsGetObject(Path, IID_IADs, (void **) &pADs);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
hresError = ADsGetObject(Path, IID_IISBaseObject, (void **) &pBaseObject);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not get the base object.\n");
|
|
iResult = 1;
|
|
pADs->Release();
|
|
goto xit;
|
|
}
|
|
// You can find IsSet and GetProperty in common.cpp
|
|
if ((IsSet(pBaseObject, Path, Property) == 1))// && (PROP_OK == IsSpecialProperty(Property)))
|
|
{ GetProperty(pADs, Property, &Value, &Type);
|
|
printf("%-32S: (%S) ", Property, Type);
|
|
PrintVariant(Value);
|
|
printf("\n");
|
|
VariantClear(&Value);
|
|
SysFreeString(Type);
|
|
}
|
|
else
|
|
{ printf("The property \"%S\" is not set at this node.\n", Property);
|
|
}
|
|
|
|
pBaseObject->Release();
|
|
pADs->Release();
|
|
xit:
|
|
SysFreeString(Path);
|
|
// SysFreeString(Property);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
int clsHELP::Execute()
|
|
{ printf("\n");
|
|
printf("Usage:\n");
|
|
printf(" ADSUTIL.EXE [-s:<server>] <cmd> [<path> [<value>]]\n");
|
|
printf("Description:\n");
|
|
printf("IIS K2 administration utility that enables the manipulation of the metabase with ADSI parameters.\n");
|
|
printf(" adsutil.exe GET path - display chosen parameter\n");
|
|
printf(" adsutil.exe DELETE path - delete given path or property\n");
|
|
printf(" adsutil.exe SET path value ... - assign the new value\n");
|
|
printf(" adsutil.exe CREATE path [KeyType] - create given path and assigns it to the given KeyType\n");
|
|
printf(" adsutil.exe ENUM path [\"/P\" | \"/A\"] - enumerate all properties for given path\n");
|
|
printf("\n");
|
|
printf(" adsutil.exe APPCREATEINPROC w3svc/1/root - Create an in-proc application\n");
|
|
printf(" adsutil.exe APPCREATEOUTPROC w3svc/1/root - Create an in-proc application\n");
|
|
printf(" adsutil.exe APPDELETE w3svc/1/root - Delete the application if there is one\n");
|
|
printf(" adsutil.exe APPUNLOAD w3svc/1/root - Unload an application from w3svc runtime lookup table.\n");
|
|
printf(" adsutil.exe APPGETSTATUS w3svc/1/root - Get the status of the application\n");
|
|
printf("\n");
|
|
printf("Extended ADSUTIL Commands:\n");
|
|
printf(" adsutil.exe APPEND path value - Append a value to a LIST type property\n");
|
|
printf(" adsutil.exe REMOVE path value - Remove a value from a LIST type property\n");
|
|
printf(" adsutil.exe FIND path - find the paths where the given property is set\n");
|
|
printf(" adsutil.exe CREATE_VDIR path - create given path as a Virtual Directory\n");
|
|
printf(" adsutil.exe CREATE_VSERV path - create given path as a Virtual Server\n");
|
|
printf(" adsutil.exe START_SERVER path - starts the given web site\n");
|
|
printf(" adsutil.exe STOP_SERVER path - stops the given web site\n");
|
|
printf(" adsutil.exe PAUSE_SERVER path - pauses the given web site\n");
|
|
printf(" adsutil.exe CONTINUE_SERVER path - continues the given web site\n");
|
|
printf(" adsutil.exe ENUM_ALL path [\"/P\" | \"/A\"] - enumerate all properties for the given path and all subpaths\n");
|
|
printf(" adsutil.exe SCRIPT file - reads given file as a script\n");
|
|
printf("\n");
|
|
printf("\n");
|
|
printf("Samples\n");
|
|
printf(" adsutil.exe GET W3SVC/1/ServerBindings\n");
|
|
printf(" adsutil.exe SET W3SVC/1/ServerBindings \":81:\"\n");
|
|
printf(" adsutil.exe CREATE W3SVC/1/Root/MyVdir \"IIsWebVirtualDir\"\n");
|
|
printf(" adsutil.exe START_SERVER W3SVC/1\n");
|
|
printf(" adsutil.exe ENUM W3SVC /P \n");
|
|
printf(" adsutil.exe ENUM W3SVC /A \n");
|
|
printf(" adsutil.exe -s:MyServer GET w3svc/1/ServerComment\n");
|
|
printf(" adsutil.exe SCRIPT C:\"myscript.txt \n");
|
|
return 0;
|
|
}
|
|
//************************************************************
|
|
// this removes an item from a LIST type property
|
|
int clsREMOVE::Execute()
|
|
{ int iResult = 0;
|
|
HRESULT hresError = 0;
|
|
|
|
BSTR Type;
|
|
|
|
VARIANT varOld; // Holds the array of old values
|
|
VARIANT *OldValues; // the old values
|
|
|
|
// BSTR Value; // Value to append
|
|
|
|
VARIANT varNew; // Holds the array of new values
|
|
SAFEARRAY FAR* NewArray; // the array of new values
|
|
SAFEARRAYBOUND NewArrayBound[1];
|
|
VARIANT *NewValues; // the new values
|
|
NewArrayBound[0].lLbound = 0;
|
|
|
|
IADs *pADs = NULL;
|
|
IISBaseObject *pBaseObject = NULL;
|
|
|
|
hresError = ADsGetObject(Path, IID_IADs, (void **) &pADs);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
hresError = ADsGetObject(Path, IID_IISBaseObject, (void **) &pBaseObject);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not get the base object.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
// You can find IsSet and GetProperty in common.cpp
|
|
if ((IsSet(pBaseObject, Path, Property) == 1))// && (PROP_OK == IsSpecialProperty(Property)))
|
|
{ GetProperty(pADs, Property, &varOld, &Type);
|
|
if (_wcsicmp(Type, L"list"))
|
|
{// ***** Does a normal DELETE *****
|
|
}
|
|
else
|
|
{// ***** appends an item to a list *****
|
|
// Build the new array
|
|
NewArrayBound[0].cElements = varOld.parray->rgsabound[0].cElements - 1;
|
|
NewArray = SafeArrayCreate(VT_VARIANT, 1, NewArrayBound);
|
|
if (NewArray == NULL)
|
|
{
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
varNew.vt = VT_ARRAY|VT_VARIANT;
|
|
varNew.parray = NewArray;
|
|
|
|
// Get a handle on the data for both arrays
|
|
OldValues = (VARIANT*) varOld.parray->pvData;
|
|
NewValues = (VARIANT*) varNew.parray->pvData;
|
|
|
|
// Put all the old values into the new array
|
|
int skip = 0;
|
|
for (unsigned long l = 0; l < varOld.parray->rgsabound[0].cElements; l++)
|
|
{ if (_wcsicmp(OldValues[l].bstrVal, Value))
|
|
{ NewValues[l - skip].vt = VT_BSTR;
|
|
NewValues[l - skip].bstrVal = SysAllocString(OldValues[l].bstrVal);
|
|
}
|
|
else
|
|
{ skip++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ printf("Property \"%S\" is not set at this node.\n", Property);
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
// Put the new property
|
|
hresError = pADs->Put(Property, varNew);
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not set \"%S\" to ", Property);
|
|
PrintVariant(varNew);
|
|
printf("\n");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ hresError = pADs->SetInfo();
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not commit changes to the metabase.");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ printf("%-32S: (%S) ", Property, Type);
|
|
PrintVariant(varNew);
|
|
printf("\n");
|
|
iResult = 0;
|
|
}
|
|
}
|
|
xit:
|
|
pADs->Release();
|
|
pBaseObject->Release();
|
|
SysFreeString(Path);
|
|
SysFreeString(Property);
|
|
SysFreeString(Value);
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// This reads the specified text file, executing each line
|
|
// as an ADSUTIL command line. Looks a lot like main()
|
|
int clsSCRIPT::Execute()
|
|
{ int iResult = 0;
|
|
clsCommand *ScriptCommand = new clsCommand();
|
|
char *NewLine = NULL;
|
|
int LineLength = 480;
|
|
char *CurrentLine = new char[LineLength];
|
|
|
|
// Open the script file if it exists
|
|
ifstream *fin = new ifstream(FileName, ios::nocreate, filebuf::openprot);
|
|
if (NULL == fin)
|
|
{ printf("Could not open %S\n", FileName);
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
fin->getline(CurrentLine, LineLength);
|
|
|
|
// while not end of file
|
|
while (!fin->eof())
|
|
{ // append "adsutil " to the beginning of each line
|
|
// this acts as the first parameter in a normal
|
|
// command line
|
|
NewLine = new char[strlen(CurrentLine) + 9];
|
|
strcpy(NewLine, "adsutil ");
|
|
strcpy(NewLine + strlen(NewLine), CurrentLine);
|
|
// printf("\n");
|
|
// printf(NewLine);
|
|
// printf("\n");
|
|
// the usual ParseCommandLine and Execute
|
|
iResult = ScriptCommand->ParseCommandLine(NewLine);
|
|
delete[] NewLine;
|
|
if ((0 == iResult) && (ScriptCommand->GetIndicator() != CMD_HELP))
|
|
{ iResult = ScriptCommand->Execute();
|
|
}
|
|
// Read the next line
|
|
delete[] CurrentLine;
|
|
CurrentLine = new char[LineLength];
|
|
fin->getline(CurrentLine, LineLength, '\n');
|
|
CurrentLine[strlen(CurrentLine)] = '\0';
|
|
}
|
|
fin->close();
|
|
delete[] CurrentLine;
|
|
delete ScriptCommand;
|
|
xit:
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// This thing handles the starting, stopping, pausing, and continuation of servers
|
|
int clsSERVER_COMMAND::Execute(int TheCommand)
|
|
{ char *SuccessMsg;
|
|
char *ErrorMsg;
|
|
|
|
HRESULT hresError = 0;
|
|
int iResult = 0;
|
|
int iExitCode = 0;
|
|
DWORD ConvertResult = 0;
|
|
|
|
IADsServiceOperations *pADs = NULL;
|
|
|
|
// Get the object specified by adspath
|
|
hresError = ADsGetObject(Path, IID_IADsServiceOperations, (void **) &pADs);
|
|
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
// remind me to change TheCommand from a function argument to a data member
|
|
switch (TheCommand)
|
|
{ case CMD_STARTSERVER: // START_SERVER
|
|
{ SuccessMsg = "Server successfully started.";
|
|
ErrorMsg = "Error trying to start the server.";
|
|
hresError = pADs->Start();
|
|
break;
|
|
}
|
|
case CMD_STOPSERVER: // STOP_SERVER
|
|
{ SuccessMsg = "Server successfully stopped.";
|
|
ErrorMsg = "Error trying to stop the server.";
|
|
hresError = pADs->Stop();
|
|
break;
|
|
}
|
|
case CMD_PAUSESERVER: // PAUSE_SERVER
|
|
{ SuccessMsg = "Server successfully paused.";
|
|
ErrorMsg = "Error trying to pause the server.";
|
|
hresError = pADs->Pause();
|
|
break;
|
|
}
|
|
case CMD_CONTINUESERVER: // CONTINUE_SERVER
|
|
{ SuccessMsg = "Server successfully continued.";
|
|
ErrorMsg = "Error trying to continue the server.";
|
|
hresError = pADs->Continue();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf(ErrorMsg);
|
|
printf("\n");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ printf(SuccessMsg);
|
|
printf("\n");
|
|
iResult = 0;
|
|
}
|
|
xit:
|
|
SysFreeString(Path);
|
|
pADs->Release();
|
|
|
|
return iResult;
|
|
}
|
|
//************************************************************
|
|
// this sets a property
|
|
int clsSET::Execute()
|
|
{ HRESULT hresError = 0;
|
|
int iResult = 0;
|
|
|
|
BSTR Type;
|
|
IADs *pADs = NULL;
|
|
|
|
VARIANT varValues;
|
|
VariantInit(&varValues);
|
|
if (PROP_OK != IsSpecialProperty(Property))
|
|
{ printf("%S can not be set at this time.\n", Property);
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
// Builds the Variant of value(s) needed for the Put function
|
|
if (1 == ValueCount)
|
|
{ varValues.vt = VT_BSTR;
|
|
varValues.bstrVal = SysAllocString(Values[0]);
|
|
Type = SysAllocString(L"STRING");
|
|
}
|
|
else
|
|
{ SAFEARRAY FAR* psa;
|
|
SAFEARRAYBOUND rgsabound[1];
|
|
rgsabound[0].lLbound = 0;
|
|
rgsabound[0].cElements = ValueCount;
|
|
|
|
psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
|
|
if (psa == NULL)
|
|
{ iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
varValues.vt = VT_ARRAY|VT_VARIANT;
|
|
varValues.parray = psa;
|
|
|
|
VARIANT *varValueArray;
|
|
varValueArray = (VARIANT*) varValues.parray->pvData;
|
|
for (int i = 0; i < ValueCount; i++)
|
|
{ varValueArray[i].vt = VT_BSTR;
|
|
varValueArray[i].bstrVal = SysAllocString(Values[i]);
|
|
}
|
|
Type = SysAllocString(L"LIST");
|
|
}
|
|
|
|
// Get the object specified by adspath
|
|
hresError = ADsGetObject(Path, IID_IADs, (void **) &pADs);
|
|
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not open the object with ADsGetObject.\n");
|
|
iResult = 1;
|
|
goto xit;
|
|
}
|
|
|
|
hresError = pADs->Put(Property, varValues);
|
|
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not set \"%S\" to ", Property);
|
|
PrintVariant(varValues);
|
|
printf("\n");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ hresError = pADs->SetInfo();
|
|
if (hresError != ERROR_SUCCESS)
|
|
{ printf("Could not commit changes to the metabase.");
|
|
iResult = 1;
|
|
}
|
|
else
|
|
{ printf("%-32S: (%S) ", Property, Type);
|
|
PrintVariant(varValues);
|
|
printf("\n");
|
|
iResult = 0;
|
|
}
|
|
}
|
|
pADs->Release();
|
|
xit:
|
|
VariantClear(&varValues);
|
|
SysFreeString(Path);
|
|
// SysFreeString(Property);
|
|
delete Values;
|
|
return iResult;
|
|
}
|
|
//************************************************************
|