mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
705 lines
15 KiB
705 lines
15 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
// 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"
|
|
|
|
#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;
|
|
|
|
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
|
|
//
|
|
|
|
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
|
|
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::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;
|
|
|
|
if (vServerID.vt == VT_I4) {
|
|
*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);
|
|
}
|