|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 2001
//
// File: cwebservice.cxx
//
// Contents: Contains methods for CIISWebService object
//
// History: 01-15-2001 BrentMid Created.
//
//----------------------------------------------------------------------------
#include "iisext.hxx"
#include <initguid.h>
#include "iwamreg.h"
#include "sitecreator.h"
#include "secconlib.h"
#pragma hdrstop
// Class CIISWebService
DEFINE_IPrivateDispatch_Implementation(CIISWebService) DEFINE_DELEGATING_IDispatch_Implementation(CIISWebService) DEFINE_CONTAINED_IADs_Implementation(CIISWebService) DEFINE_IADsExtension_Implementation(CIISWebService)
CIISWebService::CIISWebService(): _pUnkOuter(NULL), _pADs(NULL), _pszServerName(NULL), _pszMetaBasePath(NULL), _pAdminBase(NULL), _pDispMgr(NULL), _fDispInitialized(FALSE) { ENLIST_TRACKING(CIISWebService); }
HRESULT CIISWebService::CreateWebService( IUnknown *pUnkOuter, REFIID riid, void **ppvObj ) { CCredentials Credentials; CIISWebService FAR * pWebService = NULL; HRESULT hr = S_OK; BSTR bstrAdsPath = NULL; OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer * pLexer = NULL; LPWSTR pszIISPathName = NULL;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = AllocateWebServiceObject(pUnkOuter, Credentials, &pWebService); BAIL_ON_FAILURE(hr);
//
// get ServerName and pszPath
//
hr = pWebService->_pADs->get_ADsPath(&bstrAdsPath); BAIL_ON_FAILURE(hr);
pLexer = new CLexer(); hr = pLexer->Initialize(bstrAdsPath); BAIL_ON_FAILURE(hr);
//
// Parse the pathname
//
hr = ADsObject(pLexer, pObjectInfo); BAIL_ON_FAILURE(hr);
pszIISPathName = AllocADsStr(bstrAdsPath); if (!pszIISPathName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
*pszIISPathName = L'\0'; hr = BuildIISPathFromADsPath( pObjectInfo, pszIISPathName ); BAIL_ON_FAILURE(hr);
hr = pWebService->InitializeWebServiceObject( pObjectInfo->TreeName, pszIISPathName ); BAIL_ON_FAILURE(hr);
//
// pass non-delegating IUnknown back to the aggregator
//
*ppvObj = (INonDelegatingUnknown FAR *) pWebService;
if (bstrAdsPath) { ADsFreeString(bstrAdsPath); }
if (pLexer) { delete pLexer; }
if (pszIISPathName ) { FreeADsStr( pszIISPathName ); }
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
error:
if (bstrAdsPath) { ADsFreeString(bstrAdsPath); }
if (pLexer) { delete pLexer; }
if (pszIISPathName ) { FreeADsStr( pszIISPathName ); }
FreeObjectInfo( &ObjectInfo );
*ppvObj = NULL;
delete pWebService;
RRETURN(hr);
}
CIISWebService::~CIISWebService( ) { if (_pszServerName) { FreeADsStr(_pszServerName); }
if (_pszMetaBasePath) { FreeADsStr(_pszMetaBasePath); }
delete _pDispMgr; }
STDMETHODIMP CIISWebService::QueryInterface( REFIID iid, LPVOID FAR* ppv ) { HRESULT hr = S_OK; hr = _pUnkOuter->QueryInterface(iid,ppv);
RRETURN(hr); }
HRESULT CIISWebService::AllocateWebServiceObject( IUnknown *pUnkOuter, CCredentials& Credentials, CIISWebService ** ppWebService ) { CIISWebService FAR * pWebService = NULL; IADs FAR * pADs = NULL; CAggregateeDispMgr FAR * pDispMgr = NULL; HRESULT hr = S_OK;
pWebService = new CIISWebService(); if (pWebService == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregateeDispMgr; if (pDispMgr == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr);
hr = pDispMgr->LoadTypeInfoEntry( LIBID_IISExt, IID_IISWebService, (IISWebService *)pWebService, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
//
// Store the IADs Pointer, but again do NOT ref-count
// this pointer - we keep the pointer around, but do
// a release immediately.
//
hr = pUnkOuter->QueryInterface(IID_IADs, (void **)&pADs); pADs->Release(); pWebService->_pADs = pADs;
//
// Store the pointer to the pUnkOuter object
// AND DO NOT add ref this pointer
//
pWebService->_pUnkOuter = pUnkOuter; pWebService->_Credentials = Credentials; pWebService->_pDispMgr = pDispMgr; *ppWebService = pWebService;
RRETURN(hr);
error:
delete pDispMgr; delete pWebService;
RRETURN(hr); }
HRESULT CIISWebService::InitializeWebServiceObject( LPWSTR pszServerName, LPWSTR pszPath ) { HRESULT hr = S_OK;
if (pszServerName) { _pszServerName = AllocADsStr(pszServerName);
if (!_pszServerName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } }
if (pszPath) { _pszMetaBasePath = AllocADsStr(pszPath);
if (!_pszMetaBasePath) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } }
hr = InitServerInfo(pszServerName, &_pAdminBase); BAIL_ON_FAILURE(hr);
error:
RRETURN(hr); }
STDMETHODIMP CIISWebService::ADSIInitializeDispatchManager( long dwExtensionId ) { HRESULT hr = S_OK;
if (_fDispInitialized) {
RRETURN(E_FAIL); }
hr = _pDispMgr->InitializeDispMgr(dwExtensionId);
if (SUCCEEDED(hr)) { _fDispInitialized = TRUE; }
RRETURN(hr); }
STDMETHODIMP CIISWebService::ADSIInitializeObject( THIS_ BSTR lpszUserName, BSTR lpszPassword, long lnReserved ) { CCredentials NewCredentials(lpszUserName, lpszPassword, lnReserved);
_Credentials = NewCredentials;
RRETURN(S_OK); }
STDMETHODIMP CIISWebService::ADSIReleaseObject() { delete this; RRETURN(S_OK); }
STDMETHODIMP CIISWebService::NonDelegatingQueryInterface( REFIID iid, LPVOID FAR* ppv ) { ASSERT(ppv); if (IsEqualIID(iid, IID_IISWebService)) {
*ppv = (IADsUser FAR *) this;
} else if (IsEqualIID(iid, IID_IADsExtension)) {
*ppv = (IADsExtension FAR *) this; } else if (IsEqualIID(iid, IID_IUnknown)) { //
// probably not needed since our 3rd party extension does not stand
// alone and provider does not ask for this, but to be safe
//
*ppv = (INonDelegatingUnknown FAR *) this;
} else { *ppv = NULL; return E_NOINTERFACE; }
//
// Delegating AddRef to aggregator for IADsExtesnion and IISWebService.
// AddRef on itself for IPrivateUnknown. (both tested.)
//
((IUnknown *) (*ppv)) -> AddRef();
return S_OK; }
//
// IADsExtension::Operate()
//
STDMETHODIMP CIISWebService::Operate( THIS_ DWORD dwCode, VARIANT varUserName, VARIANT varPassword, VARIANT varFlags ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISWebService::EnableApplication( BSTR bstrAppName ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.EnableApplication(bstrAppName, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::RemoveApplication( BSTR bstrAppName ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.RemoveApplication(bstrAppName, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::QueryGroupIDStatus( BSTR bstrGroupID, VARIANT FAR* pvBuffer ) { HRESULT hr = S_OK;
DWORD dwBufSize = 0; WCHAR* pBuffer = NULL;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.QueryGroupIDStatus( _pszMetaBasePath, bstrGroupID, &pBuffer, &dwBufSize); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringArray( (LPWSTR)pBuffer, pvBuffer); BAIL_ON_FAILURE(hr);
error: if (pBuffer) { delete [] pBuffer; }
return hr; } STDMETHODIMP CIISWebService::ListApplications( VARIANT FAR* pvBuffer ) { HRESULT hr = S_OK;
DWORD dwBufSize = 0; WCHAR* pBuffer = NULL;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.ListApplications( _pszMetaBasePath, &pBuffer, &dwBufSize); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringArray( (LPWSTR)pBuffer, pvBuffer); BAIL_ON_FAILURE(hr);
error: if (pBuffer) { delete [] pBuffer; }
return hr; }
STDMETHODIMP CIISWebService::AddDependency( BSTR bstrApplication, BSTR bstrGroupID ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.AddDependency(bstrApplication, bstrGroupID, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::RemoveDependency( BSTR bstrApplication, BSTR bstrGroupID ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.RemoveDependency(bstrApplication, bstrGroupID, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::EnableWebServiceExtension( BSTR bstrExtension ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.EnableWebServiceExtension(bstrExtension, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::DisableWebServiceExtension( BSTR bstrExtension ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.DisableWebServiceExtension(bstrExtension, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::ListWebServiceExtensions( VARIANT FAR* pvBuffer ) { HRESULT hr = S_OK;
DWORD dwBufSize = 0; WCHAR* pBuffer = NULL;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.ListWebServiceExtensions( _pszMetaBasePath, &pBuffer, &dwBufSize); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringArray( (LPWSTR)pBuffer, pvBuffer); BAIL_ON_FAILURE(hr);
error: if (pBuffer) { delete [] pBuffer; }
return hr; }
STDMETHODIMP CIISWebService::EnableExtensionFile( BSTR bstrExtensionFile ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.EnableExtensionFile(bstrExtensionFile, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::DisableExtensionFile( BSTR bstrExtensionFile ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.DisableExtensionFile(bstrExtensionFile, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::AddExtensionFile( BSTR bstrExtensionFile, VARIANT bAccess, BSTR bstrGroupID, VARIANT bCanDelete, BSTR bstrDescription ) { HRESULT hr = S_OK; bool boolCanDelete = false; bool boolAccess = false;
if (bCanDelete.vt == VT_BOOL) { if (bCanDelete.boolVal == VARIANT_TRUE) { boolCanDelete = true; } else { boolCanDelete = false; } }
if (bAccess.vt == VT_BOOL) { if (bAccess.boolVal == VARIANT_TRUE) { boolAccess = true; } else { boolAccess = false; } }
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.AddExtensionFile(bstrExtensionFile, boolAccess, bstrGroupID, boolCanDelete, bstrDescription, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::DeleteExtensionFileRecord( BSTR bstrExtensionFile ) { HRESULT hr = S_OK;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.DeleteExtensionFileRecord(bstrExtensionFile, _pszMetaBasePath);
return hr; }
STDMETHODIMP CIISWebService::ListExtensionFiles( VARIANT FAR* pvBuffer ) { HRESULT hr = S_OK;
DWORD dwBufSize = 0; WCHAR* pBuffer = NULL;
CSecConLib consoleHelper(_pAdminBase); hr = consoleHelper.ListExtensionFiles( _pszMetaBasePath, &pBuffer, &dwBufSize); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringArray( (LPWSTR)pBuffer, pvBuffer); BAIL_ON_FAILURE(hr);
error: if (pBuffer) { delete [] pBuffer; }
return hr; }
STDMETHODIMP CIISWebService::CreateNewSite( BSTR bstrServerComment, VARIANT *pvServerBindings, BSTR bstrRootVDirPath, VARIANT vServerID, VARIANT *pvActualID ) { HRESULT hr = S_OK; DWORD dwSiteID = 0; DWORD * pdwSiteID = &dwSiteID; DWORD dwNewSiteID = 0; IIISApplicationAdmin * pAppAdmin = NULL; COSERVERINFO csiName; COSERVERINFO *pcsiParam = &csiName; IClassFactory * pcsfFactory = NULL; CSiteCreator SiteCreator(_pAdminBase); VARIANT vVar; WCHAR* wszServerBindings = NULL; WCHAR* pIndex = NULL; VARIANT * pVarArray = NULL; DWORD dwNumValues = 0;
memset(pcsiParam, 0, sizeof(COSERVERINFO));
//
// special case to handle "localhost" to work-around ole32 bug
//
if (_pszServerName == NULL || _wcsicmp(_pszServerName,L"localhost") == 0) { pcsiParam->pwszName = NULL; } else { pcsiParam->pwszName = _pszServerName; }
csiName.pAuthInfo = NULL; pcsiParam = &csiName;
// call VariantChangeType here to convert to VT_I4 and plug into vServerID
hr = VariantChangeType(&vServerID, &vServerID, 0, VT_I4); BAIL_ON_FAILURE(hr);
if ((vServerID.vt == VT_I4) && (vServerID.lVal != 0)) { *pdwSiteID = vServerID.lVal; } else { pdwSiteID = NULL; }
hr = CoGetClassObject( CLSID_WamAdmin, CLSCTX_SERVER, pcsiParam, IID_IClassFactory, (void**) &pcsfFactory );
BAIL_ON_FAILURE(hr);
hr = pcsfFactory->CreateInstance( NULL, IID_IIISApplicationAdmin, (void **) &pAppAdmin ); BAIL_ON_FAILURE(hr); VariantInit(&vVar);
hr = VariantCopyInd(&vVar, pvServerBindings); BAIL_ON_FAILURE(hr);
if ( VT_DISPATCH == V_VT(&vVar) ) // JScript Array
{ // Output here is VT_BSTR, of format: "str_1,str_2,str_3, ... str_n\0"
hr = VariantChangeType( &vVar, &vVar, 0, VT_BSTR ); BAIL_ON_FAILURE(hr);
wszServerBindings = new WCHAR [wcslen(vVar.bstrVal) + 2]; // 1 for NULL, 1 for extra NULL
if (!wszServerBindings) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
wcscpy(wszServerBindings, vVar.bstrVal);
// change VT_BSTR to MULTISZ format: "str_1\0str_2\0str_3\0 ... str_n\0"
pIndex = wszServerBindings; while ( *pIndex != 0 ) { if ( *pIndex == L',' ) { *pIndex = 0; }
pIndex++; } *(++pIndex) = 0; } else if ( (VT_ARRAY | VT_VARIANT) == V_VT(&vVar) ) // VBS Array = SafeArray
{ // Allocates wszServerBindings and puts in MULTISZ format
hr = ConvertArrayToMultiSZ( vVar, &wszServerBindings ); BAIL_ON_FAILURE(hr); } else { hr = E_INVALIDARG; BAIL_ON_FAILURE(hr); }
hr = SiteCreator.CreateNewSite2(SC_W3SVC, bstrServerComment, wszServerBindings, bstrRootVDirPath, pAppAdmin, &dwNewSiteID, pdwSiteID); BAIL_ON_FAILURE(hr); VariantInit( pvActualID );
pvActualID->vt = VT_I4; pvActualID->lVal = dwNewSiteID;
error: if (pcsfFactory) { pcsfFactory->Release(); } if (pAppAdmin) { pAppAdmin->Release(); }
if (wszServerBindings) { delete [] wszServerBindings; }
RRETURN(hr); }
HRESULT CIISWebService::ConvertArrayToMultiSZ( VARIANT varSafeArray, WCHAR **pszServerBindings ) { HRESULT hr = S_OK; DWORD dwSLBound = 0; DWORD dwSUBound = 0; DWORD i = 0; SAFEARRAY * pArray = NULL; DWORD dwLen = 0; DWORD dwNumVariants = 0; VARIANT * pVarArray = NULL; VARIANT pElem; WCHAR* wszServerBindings = NULL;
if(!(V_ISARRAY(&varSafeArray))) RRETURN(E_FAIL);
//
// This handles by-ref and regular SafeArrays.
//
if (V_VT(&varSafeArray) & VT_BYREF) pArray = *(V_ARRAYREF(&varSafeArray)); else pArray = V_ARRAY(&varSafeArray);
//
// Check that there is only one dimension in this array
//
if (pArray && pArray->cDims != 1) { hr = E_FAIL; BAIL_ON_FAILURE(hr); }
//
// Check that there is at least one element in this array
//
if (!pArray || ( pArray->rgsabound[0].cElements == 0) ) {
wszServerBindings = new WCHAR [2]; wszServerBindings[0] = 0; wszServerBindings[1] = 1; } else {
//
// We know that this is a valid single dimension array
//
hr = SafeArrayGetLBound(pArray, 1, (long FAR *)&dwSLBound ); BAIL_ON_FAILURE(hr);
hr = SafeArrayGetUBound(pArray, 1, (long FAR *)&dwSUBound ); BAIL_ON_FAILURE(hr);
dwNumVariants = dwSUBound - dwSLBound + 1; dwLen = 0;
pVarArray = (PVARIANT)AllocADsMem( sizeof(VARIANT)*dwNumVariants ); if (!pVarArray) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } for (i = dwSLBound; i <= dwSUBound; i++) {
VariantInit(&pElem); hr = SafeArrayGetElement(pArray, (long FAR *)&i, &pElem ); BAIL_ON_FAILURE(hr); hr = VariantChangeType(&pElem, &pElem, 0, VT_BSTR); BAIL_ON_FAILURE(hr);
dwLen = dwLen + wcslen(pElem.bstrVal) + 1; pVarArray[i] = pElem; }
wszServerBindings = new WCHAR [dwLen + 1];
WCHAR * pServerBindings = wszServerBindings;
for (i = dwSLBound; i <= dwSUBound; i++) { wcscpy(pServerBindings, pVarArray[i].bstrVal); while (*pServerBindings != 0) { pServerBindings++; }
pServerBindings++; }
*pServerBindings = 0;
}
*pszServerBindings = wszServerBindings;
error: if (pVarArray) { FreeADsMem(pVarArray); }
RRETURN(hr); }
STDMETHODIMP CIISWebService::GetCurrentMode( VARIANT FAR* pvServerMode ) { HRESULT hr = S_OK; DWORD dwServerMode = 0; COSERVERINFO csiName; COSERVERINFO *pcsiParam = &csiName; IClassFactory * pcsfFactory = NULL; IWamAdmin * pWamAdmin = NULL; IIISApplicationAdmin * pAppAdmin = NULL;
memset(pcsiParam, 0, sizeof(COSERVERINFO));
//
// special case to handle "localhost" to work-around ole32 bug
//
if (_pszServerName == NULL || _wcsicmp(_pszServerName,L"localhost") == 0) { pcsiParam->pwszName = NULL; } else { pcsiParam->pwszName = _pszServerName; }
csiName.pAuthInfo = NULL; pcsiParam = &csiName;
hr = CoGetClassObject( CLSID_WamAdmin, CLSCTX_SERVER, pcsiParam, IID_IClassFactory, (void**) &pcsfFactory );
BAIL_ON_FAILURE(hr);
hr = pcsfFactory->CreateInstance( NULL, IID_IWamAdmin, (void **) &pWamAdmin ); BAIL_ON_FAILURE(hr);
// test here for 5.1 compat
hr = pWamAdmin->QueryInterface( IID_IIISApplicationAdmin, (void **)&pAppAdmin );
BAIL_ON_FAILURE(hr);
// Call GetProcessMode - it's returning GetCurrentMode
// after it checks to make sure the W3SVC is running.
hr = pAppAdmin->GetProcessMode( &dwServerMode );
BAIL_ON_FAILURE(hr);
VariantInit( pvServerMode );
pvServerMode->vt = VT_I4; pvServerMode->lVal = dwServerMode;
error: if (pcsfFactory) { pcsfFactory->Release(); } if (pWamAdmin) { pWamAdmin->Release(); } if (pAppAdmin) { pAppAdmin->Release(); }
RRETURN(hr); }
|