windows-nt/Source/XPSP1/NT/inetsrv/iis/admin/adsi/adsiis/cenumobj.cxx
2020-09-26 16:20:57 +08:00

381 lines
8.5 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1997
//
// File: cenumobj.cxx
//
// Contents: IIS Object Enumeration Code
//
// CIISGenObjectEnum::CIISGenObjectEnum()
// CIISGenObjectEnum::CIISGenObjectEnum
// CIISGenObjectEnum::Create
// CIISGenObjectEnum::GetGenObjects
// CIISGenObjectEnum::EnumGenericObjects
// CIISGenObjectEnum::Next
//
// History: 28-Feb-97 SophiaC Created.
//----------------------------------------------------------------------------
#include "iis.hxx"
#pragma hdrstop
//+---------------------------------------------------------------------------
//
// Function: CIISEnumVariant::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
// History:
//
//----------------------------------------------------------------------------
/* INTRINSA suppress=null_pointers, uninitialized */
HRESULT
CIISGenObjectEnum::Create(
CIISGenObjectEnum FAR* FAR* ppenumvariant,
BSTR ADsPath,
VARIANT var,
CCredentials& Credentials
)
{
HRESULT hr = NOERROR;
CIISGenObjectEnum FAR* penumvariant = NULL;
LPWSTR pszIISPathName = NULL;
DWORD dwStatus = 0;
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = NULL;
CLexer Lexer(ADsPath);
*ppenumvariant = NULL;
penumvariant = new CIISGenObjectEnum();
if (!penumvariant) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
hr = ADsAllocString( ADsPath, &penumvariant->_ADsPath);
BAIL_ON_FAILURE(hr);
//
// Parse the pathname
//
pObjectInfo = &ObjectInfo;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = ADsObject(&Lexer, pObjectInfo);
BAIL_ON_FAILURE(hr);
penumvariant->_Credentials = Credentials;
*ppenumvariant = penumvariant;
//
// Store ServerName
//
penumvariant->_pszServerName = AllocADsStr(pObjectInfo->TreeName);
if (!(penumvariant->_pszServerName)) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
hr = InitServerInfo(penumvariant->_pszServerName,
&(penumvariant->_pAdminBase),
&(penumvariant->_pSchema));
BAIL_ON_FAILURE(hr);
pszIISPathName = AllocADsStr(ADsPath);
if (!pszIISPathName) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
memset(pszIISPathName, 0, sizeof(pszIISPathName));
hr = BuildIISPathFromADsPath(
pObjectInfo,
pszIISPathName
);
BAIL_ON_FAILURE(hr);
penumvariant->_pszMetaBasePath = AllocADsStr(pszIISPathName);
if (!(penumvariant->_pszMetaBasePath)) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
error:
if (FAILED(hr)) {
if (penumvariant) {
delete penumvariant;
*ppenumvariant = NULL;
}
}
if (pszIISPathName) {
FreeADsStr(pszIISPathName);
}
FreeObjectInfo(pObjectInfo);
RRETURN(hr);
}
CIISGenObjectEnum::CIISGenObjectEnum():
_ADsPath(NULL),
_pszServerName(NULL),
_pSchema(NULL),
_pAdminBase(NULL),
_pszMetaBasePath(NULL)
{
_dwObjectCurrentEntry = 0;
}
CIISGenObjectEnum::~CIISGenObjectEnum()
{
if (_ADsPath) {
ADsFreeString(_ADsPath);
}
if (_pszServerName) {
FreeADsStr(_pszServerName);
}
if (_pszMetaBasePath){
FreeADsStr(_pszMetaBasePath);
}
//
// Release everything
//
}
HRESULT
CIISGenObjectEnum::EnumGenericObjects(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
HRESULT hr = S_OK;
IDispatch *pDispatch = NULL;
DWORD i = 0;
while (i < cElements ) {
hr = GetGenObject(&pDispatch);
if (FAILED(hr)) {
continue;
}
if (hr == S_FALSE) {
break;
}
VariantInit(&pvar[i]);
pvar[i].vt = VT_DISPATCH;
pvar[i].pdispVal = pDispatch;
(*pcElementFetched)++;
i++;
}
return(hr);
}
/* #pragma INTRINSA suppress=all */
HRESULT
CIISGenObjectEnum::GetGenObject(
IDispatch ** ppDispatch
)
{
HRESULT hr = S_OK;
WCHAR NameBuf[MAX_PATH];
WCHAR DataBuf[MAX_PATH];
DWORD dwStatus = 0;
DWORD dwReqdBufferLen;
METADATA_HANDLE hObjHandle = NULL;
METADATA_RECORD mdrData;
IADs * pADs = NULL;
*ppDispatch = NULL;
hr = OpenAdminBaseKey(
_pszServerName,
_pszMetaBasePath,
METADATA_PERMISSION_READ,
&_pAdminBase,
&hObjHandle
);
BAIL_ON_FAILURE(hr);
hr = _pAdminBase->EnumKeys(
hObjHandle,
L"",
(LPWSTR)NameBuf,
_dwObjectCurrentEntry
);
BAIL_ON_FAILURE(hr);
//
// Find out Class Name
//
mdrData.dwMDIdentifier = MD_KEY_TYPE;
mdrData.dwMDDataType = STRING_METADATA;
mdrData.dwMDUserType = ALL_METADATA;
mdrData.dwMDAttributes = METADATA_INHERIT;
mdrData.dwMDDataLen = MAX_PATH;
mdrData.pbMDData = (PBYTE)DataBuf;
hr = _pAdminBase->GetData(
hObjHandle,
(LPWSTR)NameBuf,
&mdrData,
&dwReqdBufferLen
);
if (FAILED(hr)) {
if (hr == MD_ERROR_DATA_NOT_FOUND) {
LPWSTR pszIISPath;
pszIISPath = _wcsupr((LPWSTR)_pszMetaBasePath);
if (wcsstr(pszIISPath, L"W3SVC") != NULL) {
memcpy((LPWSTR)DataBuf, WEBDIR_CLASS_W,
SIZEOF_WEBDIR_CLASS_W);
}
else if (wcsstr(pszIISPath, L"MSFTPSVC") != NULL) {
memcpy((LPWSTR)DataBuf, FTPVDIR_CLASS_W,
SIZEOF_FTPVDIR_CLASS_W);
}
else {
memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W,
SIZEOF_DEFAULT_CLASS_W);
}
}
else {
BAIL_ON_FAILURE(hr);
}
}
else {
hr = _pSchema->ValidateClassName((LPWSTR)DataBuf);
if (hr == E_ADS_SCHEMA_VIOLATION) {
memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W,
SIZEOF_DEFAULT_CLASS_W);
}
}
//
// Bump up the object count. The instantiation of this object
// may fail; if we come into this function again, we do not want
// to pick up the same object.
//
_dwObjectCurrentEntry++;
hr = CIISGenObject::CreateGenericObject(
_ADsPath,
(LPWSTR)NameBuf,
(LPWSTR)DataBuf,
_Credentials,
ADS_OBJECT_BOUND,
IID_IDispatch,
(void **)&pADs
);
BAIL_ON_FAILURE(hr);
hr = pADs->QueryInterface(
IID_IDispatch,
(void**)ppDispatch
);
error:
if (_pAdminBase && hObjHandle) {
CloseAdminBaseKey(_pAdminBase, hObjHandle);
}
if (pADs) {
pADs->Release();
}
//
// GetGenObject returns only S_FALSE
//
if (FAILED(hr)) {
hr = S_FALSE;
}
RRETURN(hr);
}
//+---------------------------------------------------------------------------
//
// Function: CIISGenObjectEnum::Next
//
// Synopsis: Returns cElements number of requested NetOle objects in the
// array supplied in pvar.
//
// Arguments: [cElements] -- The number of elements requested by client
// [pvar] -- ptr to array of VARIANTs to for return objects
// [pcElementFetched] -- if non-NULL, then number of elements
// -- actually returned is placed here
//
// Returns: HRESULT -- S_OK if number of elements requested are returned
// -- S_FALSE if number of elements is < requested
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP
CIISGenObjectEnum::Next(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
ULONG cElementFetched = 0;
HRESULT hr = S_OK;
hr = EnumGenericObjects(
cElements,
pvar,
&cElementFetched
);
if (pcElementFetched) {
*pcElementFetched = cElementFetched;
}
RRETURN(hr);
}