/*********************************************************************** File: execute.cpp Description: this thing holds all the Execute functions for all the classes ***********************************************************************/ #include "clsCommand.h" #include "iiisext.h" #include 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:] [ []]\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; } //************************************************************