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.
1118 lines
24 KiB
1118 lines
24 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1997
|
|
//
|
|
// File: ctree.cxx
|
|
//
|
|
// Contents: Microsoft ADs IIS Provider Tree Object
|
|
//
|
|
// History: 25-Feb-97 SophiaC Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#include "iis.hxx"
|
|
#pragma hdrstop
|
|
|
|
// Class CIISTree
|
|
|
|
DEFINE_IDispatch_Implementation(CIISTree)
|
|
DEFINE_IADs_Implementation(CIISTree)
|
|
|
|
|
|
CIISTree::CIISTree():
|
|
_pAdminBase(NULL),
|
|
_pSchema(NULL),
|
|
_pPropertyCache(NULL)
|
|
{
|
|
|
|
VariantInit(&_vFilter);
|
|
|
|
ENLIST_TRACKING(CIISTree);
|
|
}
|
|
|
|
/* #pragma INTRINSA suppress=all */
|
|
HRESULT
|
|
CIISTree::CreateServerObject(
|
|
BSTR bstrADsPath,
|
|
CCredentials& Credentials,
|
|
DWORD dwObjectState,
|
|
REFIID riid,
|
|
void **ppvObj
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LPWSTR pszADsParent = NULL;
|
|
WCHAR szCommonName[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
|
|
|
|
pszADsParent = AllocADsStr(bstrADsPath);
|
|
|
|
if (!pszADsParent) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
*pszADsParent = L'\0';
|
|
|
|
//
|
|
// Determine the parent and rdn name
|
|
//
|
|
|
|
hr = BuildADsParentPath(
|
|
bstrADsPath,
|
|
pszADsParent,
|
|
szCommonName
|
|
);
|
|
|
|
//
|
|
// call the helper function
|
|
//
|
|
|
|
hr = CIISTree::CreateServerObject(
|
|
pszADsParent,
|
|
szCommonName,
|
|
L"user",
|
|
Credentials,
|
|
dwObjectState,
|
|
riid,
|
|
ppvObj
|
|
);
|
|
|
|
error:
|
|
|
|
if (pszADsParent) {
|
|
FreeADsStr(pszADsParent);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CIISTree::CreateServerObject(
|
|
BSTR Parent,
|
|
BSTR CommonName,
|
|
BSTR ClassName,
|
|
CCredentials& Credentials,
|
|
DWORD dwObjectState,
|
|
REFIID riid,
|
|
void **ppvObj
|
|
)
|
|
{
|
|
CIISTree FAR * pTree = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = AllocateTree(Credentials, &pTree);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pTree->InitializeCoreObject(
|
|
Parent,
|
|
CommonName,
|
|
ClassName,
|
|
L"",
|
|
CLSID_IISTree,
|
|
dwObjectState
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pTree->_pPropertyCache->InitializePropertyCache( CommonName );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pTree->QueryInterface(riid, ppvObj);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pTree->Release();
|
|
|
|
RRETURN(hr);
|
|
|
|
error:
|
|
|
|
delete pTree;
|
|
RRETURN(hr);
|
|
}
|
|
|
|
CIISTree::~CIISTree( )
|
|
{
|
|
VariantClear(&_vFilter);
|
|
|
|
delete _pDispMgr;
|
|
|
|
delete _pPropertyCache;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::QueryInterface(REFIID iid, LPVOID FAR* ppv)
|
|
{
|
|
if (IsEqualIID(iid, IID_IUnknown))
|
|
{
|
|
*ppv = (IADs FAR *) this;
|
|
}
|
|
else if (IsEqualIID(iid, IID_IADsContainer))
|
|
{
|
|
*ppv = (IADsContainer FAR *) this;
|
|
}
|
|
else if (IsEqualIID(iid, IID_IADs))
|
|
{
|
|
*ppv = (IADs FAR *) this;
|
|
}
|
|
else if (IsEqualIID(iid, IID_IDispatch))
|
|
{
|
|
*ppv = (IADs FAR *) this;
|
|
}
|
|
else
|
|
{
|
|
*ppv = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT
|
|
CIISTree::SetInfo()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (GetObjectState() == ADS_OBJECT_UNBOUND) {
|
|
|
|
hr = IISCreateObject();
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// If the create succeded, set the object type to bound
|
|
//
|
|
|
|
SetObjectState(ADS_OBJECT_BOUND);
|
|
|
|
}else {
|
|
|
|
hr = IISSetObject();
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
error:
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CIISTree::IISSetObject()
|
|
{
|
|
DWORD dwStatus = 0L;
|
|
LPWSTR pszIISPathName = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
hr = BuildIISPathFromADsPath(
|
|
_ADsPath,
|
|
&pszIISPathName
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// Add Set functionality: sophiac
|
|
//
|
|
|
|
|
|
error:
|
|
|
|
|
|
if (pszIISPathName) {
|
|
|
|
FreeADsStr(pszIISPathName);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT
|
|
CIISTree::IISCreateObject()
|
|
{
|
|
DWORD dwStatus = 0L;
|
|
LPWSTR pszIISParentName = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
hr = BuildIISPathFromADsPath(
|
|
_Parent,
|
|
&pszIISParentName
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// Add Create functionality: sophiac
|
|
//
|
|
|
|
error:
|
|
|
|
|
|
if (pszIISParentName) {
|
|
|
|
FreeADsStr(pszIISParentName);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT
|
|
CIISTree::GetInfo()
|
|
{
|
|
RRETURN(GetInfo(TRUE));
|
|
}
|
|
|
|
HRESULT
|
|
CIISTree::GetInfo(
|
|
BOOL fExplicit
|
|
)
|
|
{
|
|
DWORD dwStatus = 0L;
|
|
HANDLE hObject = NULL;
|
|
LPWSTR pszIISPathName = NULL;
|
|
HRESULT hr;
|
|
|
|
if (GetObjectState() == ADS_OBJECT_UNBOUND) {
|
|
hr = E_ADS_OBJECT_UNBOUND;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = BuildIISPathFromADsPath(
|
|
_ADsPath,
|
|
&pszIISPathName
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// Add get functionality : sophiac
|
|
//
|
|
|
|
error:
|
|
|
|
|
|
if (pszIISPathName) {
|
|
|
|
FreeADsStr(pszIISPathName);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
/* IADsContainer methods */
|
|
|
|
STDMETHODIMP
|
|
CIISTree::get_Count(long FAR* retval)
|
|
{
|
|
RRETURN(E_NOTIMPL);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::get_Filter(THIS_ VARIANT FAR* pVar)
|
|
{
|
|
VariantInit(pVar);
|
|
RRETURN(VariantCopy(pVar, &_vFilter));
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::put_Filter(THIS_ VARIANT Var)
|
|
{
|
|
RRETURN(VariantCopy(&_vFilter, &Var));
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::put_Hints(THIS_ VARIANT Var)
|
|
{
|
|
RRETURN( E_NOTIMPL);
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CIISTree::get_Hints(THIS_ VARIANT FAR* pVar)
|
|
{
|
|
RRETURN(E_NOTIMPL);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::GetObject(
|
|
BSTR ClassName,
|
|
BSTR RelativeName,
|
|
IDispatch * FAR* ppObject
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = ::RelativeGetObject(
|
|
_ADsPath,
|
|
ClassName,
|
|
RelativeName,
|
|
_Credentials,
|
|
ppObject,
|
|
FALSE
|
|
);
|
|
|
|
RRETURN(hr);
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::get__NewEnum(
|
|
THIS_ IUnknown * FAR* retval
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
IUnknown FAR* punkEnum=NULL;
|
|
IEnumVARIANT * penum = NULL;
|
|
|
|
|
|
*retval = NULL;
|
|
|
|
hr = CIISTreeEnum::Create(
|
|
(CIISTreeEnum **)&penum,
|
|
_ADsPath,
|
|
_vFilter,
|
|
_Credentials
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = penum->QueryInterface(
|
|
IID_IUnknown,
|
|
(VOID FAR* FAR*)retval
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (penum) {
|
|
penum->Release();
|
|
}
|
|
|
|
RRETURN(NOERROR);
|
|
|
|
error:
|
|
|
|
if (penum) {
|
|
delete penum;
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CIISTree::Create(
|
|
THIS_ BSTR ClassName,
|
|
BSTR RelativeName,
|
|
IDispatch * FAR* ppObject
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IADs * pADs = NULL;
|
|
DWORD dwSyntaxId = 0;
|
|
OBJECTINFO ObjectInfo;
|
|
POBJECTINFO pObjectInfo = &ObjectInfo;
|
|
//
|
|
// Validate if this class really exists in the schema
|
|
// and validate that this object can be created in this
|
|
// container
|
|
//
|
|
|
|
CLexer Lexer(_ADsPath);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
|
|
hr = ADsObject(&Lexer, pObjectInfo);
|
|
BAIL_ON_FAILURE(hr);
|
|
hr = InitServerInfo(_Credentials, pObjectInfo->TreeName, &_pAdminBase, &_pSchema);
|
|
BAIL_ON_FAILURE(hr);
|
|
hr = _pSchema->ValidateClassName(ClassName);
|
|
BAIL_ON_FAILURE(hr);
|
|
hr = CIISGenObject::CreateGenericObject(
|
|
_ADsPath,
|
|
RelativeName,
|
|
ClassName,
|
|
_Credentials,
|
|
ADS_OBJECT_UNBOUND,
|
|
IID_IDispatch,
|
|
(void **)ppObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
RRETURN(hr);
|
|
|
|
error:
|
|
RRETURN(hr);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::Delete(
|
|
THIS_ BSTR bstrClassName,
|
|
BSTR bstrRelativeName
|
|
)
|
|
{
|
|
LPWSTR pszIISPathName = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = BuildIISPathFromADsPath(
|
|
_ADsPath,
|
|
&pszIISPathName
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
//
|
|
// Add delete functionality : sophiac
|
|
//
|
|
|
|
error:
|
|
|
|
if (pszIISPathName) {
|
|
FreeADsStr(pszIISPathName);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::CopyHere(
|
|
THIS_ BSTR SourceName,
|
|
BSTR NewName,
|
|
IDispatch * FAR* ppObject
|
|
)
|
|
{
|
|
RRETURN(E_NOTIMPL);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CIISTree::MoveHere(
|
|
THIS_ BSTR SourceName,
|
|
BSTR NewName,
|
|
IDispatch * FAR* ppObject
|
|
)
|
|
{
|
|
RRETURN(E_NOTIMPL);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CIISTree::AllocateTree(
|
|
CCredentials& Credentials,
|
|
CIISTree ** ppTree
|
|
)
|
|
{
|
|
CIISTree FAR * pTree = NULL;
|
|
CAggregatorDispMgr FAR * pDispMgr = NULL;
|
|
CPropertyCache FAR * pPropertyCache = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
pTree = new CIISTree();
|
|
if (pTree == NULL) {
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pDispMgr = new CAggregatorDispMgr;
|
|
if (pDispMgr == NULL) {
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pDispMgr->LoadTypeInfoEntry(
|
|
LIBID_ADs,
|
|
IID_IADs,
|
|
(IADs *)pTree,
|
|
DISPID_REGULAR
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pDispMgr->LoadTypeInfoEntry(
|
|
LIBID_ADs,
|
|
IID_IADsContainer,
|
|
(IADsContainer *)pTree,
|
|
DISPID_NEWENUM
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = CPropertyCache::createpropertycache(
|
|
(CCoreADsObject FAR *)pTree,
|
|
&pPropertyCache
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
|
|
|
|
pTree->_Credentials = Credentials;
|
|
pTree->_pPropertyCache = pPropertyCache;
|
|
pTree->_pDispMgr = pDispMgr;
|
|
*ppTree = pTree;
|
|
|
|
RRETURN(hr);
|
|
|
|
error:
|
|
if (pDispMgr)
|
|
{
|
|
delete pDispMgr;
|
|
}
|
|
|
|
if (pTree)
|
|
{
|
|
delete pTree;
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
/* INTRINSA suppress=null_pointers, uninitialized */
|
|
STDMETHODIMP
|
|
CIISTree::Get(
|
|
THIS_ BSTR bstrName,
|
|
VARIANT FAR* pvProp
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSyntaxId;
|
|
DWORD dwSyntax;
|
|
DWORD dwNumValues = 0;
|
|
LPIISOBJECT pIISSrcObjects = NULL;
|
|
WCHAR wchName[MAX_PATH];
|
|
|
|
//
|
|
// check if property is a supported property
|
|
//
|
|
|
|
hr = _pSchema->LookupSyntaxID(bstrName, &dwSyntax);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// check if property is BITMASK type;
|
|
// if BITMASK type, get corresponding DWORD flag property
|
|
//
|
|
|
|
if (dwSyntax == IIS_SYNTAX_ID_BOOL_BITMASK || dwSyntax == IIS_SYNTAX_ID_BINARY) {
|
|
hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
//
|
|
// retrieve data object from cache; if one exists
|
|
//
|
|
|
|
if (dwSyntax == IIS_SYNTAX_ID_BOOL_BITMASK || dwSyntax == IIS_SYNTAX_ID_BINARY)
|
|
{
|
|
hr = _pPropertyCache->getproperty(
|
|
wchName,
|
|
&dwSyntaxId,
|
|
&dwNumValues,
|
|
&pIISSrcObjects
|
|
);
|
|
}
|
|
else
|
|
{
|
|
hr = _pPropertyCache->getproperty(
|
|
bstrName,
|
|
&dwSyntaxId,
|
|
&dwNumValues,
|
|
&pIISSrcObjects
|
|
);
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// reset it to its syntax id if BITMASK type
|
|
//
|
|
|
|
pIISSrcObjects->IISType = dwSyntax;
|
|
|
|
//
|
|
// translate the IIS objects to variants
|
|
//
|
|
|
|
if (dwNumValues == 1) {
|
|
|
|
hr = IISTypeToVarTypeCopy(
|
|
_pSchema,
|
|
bstrName,
|
|
pIISSrcObjects,
|
|
pvProp,
|
|
FALSE
|
|
);
|
|
}else {
|
|
|
|
hr = IISTypeToVarTypeCopyConstruct(
|
|
_pSchema,
|
|
bstrName,
|
|
pIISSrcObjects,
|
|
dwNumValues,
|
|
pvProp,
|
|
FALSE
|
|
);
|
|
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
error:
|
|
if (pIISSrcObjects) {
|
|
|
|
IISTypeFreeIISObjects(
|
|
pIISSrcObjects,
|
|
dwNumValues
|
|
);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
/* INTRINSA suppress=null_pointers, uninitialized */
|
|
STDMETHODIMP
|
|
CIISTree::GetEx(
|
|
THIS_ BSTR bstrName,
|
|
VARIANT FAR* pvProp
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSyntaxId;
|
|
DWORD dwSyntax;
|
|
DWORD dwNumValues = 0;
|
|
LPIISOBJECT pIISSrcObjects = NULL;
|
|
WCHAR wchName[MAX_PATH];
|
|
|
|
//
|
|
// check if property is a supported property
|
|
//
|
|
|
|
hr = _pSchema->LookupSyntaxID(bstrName, &dwSyntax);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// check if property is BITMASK type;
|
|
// if BITMASK type, get corresponding DWORD flag property
|
|
//
|
|
|
|
if (dwSyntax == IIS_SYNTAX_ID_BOOL_BITMASK || dwSyntax == IIS_SYNTAX_ID_BINARY) {
|
|
hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
//
|
|
// retrieve data object from cache; if one exists
|
|
//
|
|
|
|
if (dwSyntax == IIS_SYNTAX_ID_BOOL_BITMASK || dwSyntax == IIS_SYNTAX_ID_BINARY)
|
|
{
|
|
hr = _pPropertyCache->getproperty(
|
|
wchName,
|
|
&dwSyntaxId,
|
|
&dwNumValues,
|
|
&pIISSrcObjects
|
|
);
|
|
}
|
|
else
|
|
{
|
|
hr = _pPropertyCache->getproperty(
|
|
bstrName,
|
|
&dwSyntaxId,
|
|
&dwNumValues,
|
|
&pIISSrcObjects
|
|
);
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// reset it to its syntax id if BITMASK type
|
|
//
|
|
|
|
pIISSrcObjects->IISType = dwSyntax;
|
|
|
|
//
|
|
// translate the IIS objects to variants
|
|
//
|
|
|
|
hr = IISTypeToVarTypeCopyConstruct(
|
|
_pSchema,
|
|
bstrName,
|
|
pIISSrcObjects,
|
|
dwNumValues,
|
|
pvProp,
|
|
TRUE
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
error:
|
|
if (pIISSrcObjects) {
|
|
|
|
IISTypeFreeIISObjects(
|
|
pIISSrcObjects,
|
|
dwNumValues
|
|
);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CIISTree::Put(
|
|
THIS_ BSTR bstrName,
|
|
VARIANT vProp
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSyntaxId = 0;
|
|
DWORD dwIndex = 0;
|
|
LPIISOBJECT pIISDestObjects = NULL;
|
|
DWORD dwNumValues = 0;
|
|
|
|
VARIANT * pVarArray = NULL;
|
|
VARIANT * pvProp = NULL;
|
|
WCHAR wchName[MAX_PATH];
|
|
|
|
//
|
|
// Issue: How do we handle multi-valued support
|
|
//
|
|
|
|
if ((V_VT(&vProp) & VT_VARIANT) && V_ISARRAY(&vProp)) {
|
|
if(V_ISBYREF(&vProp)) {
|
|
|
|
hr = ConvertByRefSafeArrayToVariantArray(
|
|
vProp,
|
|
&pVarArray,
|
|
&dwNumValues
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
pvProp = pVarArray;
|
|
}
|
|
else {
|
|
|
|
hr = ConvertSafeArrayToVariantArray(
|
|
vProp,
|
|
&pVarArray,
|
|
&dwNumValues
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
pvProp = pVarArray;
|
|
}
|
|
}
|
|
else {
|
|
|
|
dwNumValues = 1;
|
|
pvProp = &vProp;
|
|
}
|
|
|
|
//
|
|
// Check if this is a legal property and it syntax ID
|
|
//
|
|
|
|
hr = _pSchema->LookupSyntaxID( bstrName, &dwSyntaxId);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// check if the variant maps to the syntax of this property
|
|
//
|
|
|
|
hr = VarTypeToIISTypeCopyConstruct(
|
|
dwSyntaxId,
|
|
pvProp,
|
|
dwNumValues,
|
|
&pIISDestObjects,
|
|
FALSE
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// check if property is BITMASK type;
|
|
// if BITMASK type, get corresponding DWORD flag property
|
|
//
|
|
if (dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) {
|
|
VARIANT vGetProp;
|
|
DWORD dwMask;
|
|
DWORD dwFlagValue;
|
|
|
|
hr = _pSchema->LookupBitMask(bstrName, &dwMask);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// get its corresponding DWORD flag value
|
|
//
|
|
|
|
hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
VariantInit(&vGetProp);
|
|
hr = Get(wchName, &vGetProp);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
dwFlagValue = V_I4(&vGetProp);
|
|
|
|
if (pIISDestObjects->IISValue.value_1.dwDWORD) {
|
|
dwFlagValue |= dwMask;
|
|
}
|
|
else {
|
|
dwFlagValue &= ~dwMask;
|
|
}
|
|
|
|
pIISDestObjects->IISValue.value_1.dwDWORD = dwFlagValue;
|
|
pIISDestObjects->IISType = IIS_SYNTAX_ID_DWORD;
|
|
bstrName = wchName;
|
|
}
|
|
|
|
if (dwSyntaxId == IIS_SYNTAX_ID_BINARY)
|
|
{
|
|
hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName);
|
|
BAIL_ON_FAILURE(hr);
|
|
bstrName = wchName;
|
|
}
|
|
|
|
//
|
|
// Find this property in the cache
|
|
//
|
|
|
|
hr = _pPropertyCache->findproperty(
|
|
bstrName,
|
|
&dwIndex
|
|
);
|
|
|
|
//
|
|
// If this property does not exist in the
|
|
// cache, add this property into the cache.
|
|
//
|
|
|
|
if (FAILED(hr)) {
|
|
hr = _pPropertyCache->addproperty(
|
|
bstrName,
|
|
dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK ?
|
|
IIS_SYNTAX_ID_DWORD : dwSyntaxId,
|
|
dwNumValues,
|
|
pIISDestObjects
|
|
);
|
|
//
|
|
// If the operation fails for some reason
|
|
// move on to the next property
|
|
//
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}
|
|
|
|
//
|
|
// Now update the property in the cache
|
|
//
|
|
|
|
hr = _pPropertyCache->putproperty(
|
|
bstrName,
|
|
CACHE_PROPERTY_MODIFIED,
|
|
dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK ?
|
|
IIS_SYNTAX_ID_DWORD : dwSyntaxId,
|
|
dwNumValues,
|
|
pIISDestObjects
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
error:
|
|
|
|
if (pIISDestObjects) {
|
|
IISTypeFreeIISObjects(
|
|
pIISDestObjects,
|
|
dwNumValues
|
|
);
|
|
|
|
}
|
|
|
|
if (pVarArray) {
|
|
|
|
DWORD i = 0;
|
|
|
|
for (i = 0; i < dwNumValues; i++) {
|
|
VariantClear(pVarArray + i);
|
|
}
|
|
FreeADsMem(pVarArray);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CIISTree::PutEx(
|
|
THIS_ long lnControlCode,
|
|
BSTR bstrName,
|
|
VARIANT vProp
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSyntaxId = 0;
|
|
DWORD dwIndex = 0;
|
|
LPIISOBJECT pIISDestObjects = NULL;
|
|
DWORD dwNumValues = 0;
|
|
DWORD dwFlags = 0;
|
|
|
|
VARIANT * pVarArray = NULL;
|
|
VARIANT * pvProp = NULL;
|
|
WCHAR wchName[MAX_PATH];
|
|
|
|
switch (lnControlCode) {
|
|
case ADS_PROPERTY_CLEAR:
|
|
dwFlags = CACHE_PROPERTY_CLEARED;
|
|
|
|
pIISDestObjects = NULL;
|
|
dwNumValues = 0;
|
|
|
|
break;
|
|
|
|
case ADS_PROPERTY_UPDATE:
|
|
dwFlags = CACHE_PROPERTY_MODIFIED;
|
|
|
|
//
|
|
// Now begin the rest of the processing
|
|
//
|
|
|
|
if ((V_VT(&vProp) & VT_VARIANT) && V_ISARRAY(&vProp)) {
|
|
if (V_ISBYREF(&vProp)) {
|
|
hr = ConvertByRefSafeArrayToVariantArray(
|
|
vProp,
|
|
&pVarArray,
|
|
&dwNumValues
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
else {
|
|
hr = ConvertSafeArrayToVariantArray(
|
|
vProp,
|
|
&pVarArray,
|
|
&dwNumValues
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
pvProp = pVarArray;
|
|
|
|
}else {
|
|
|
|
hr = E_FAIL;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
//
|
|
// check if the variant maps to the syntax of this property
|
|
//
|
|
|
|
hr = VarTypeToIISTypeCopyConstruct(
|
|
dwSyntaxId,
|
|
pvProp,
|
|
dwNumValues,
|
|
&pIISDestObjects,
|
|
TRUE
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
break;
|
|
|
|
default:
|
|
RRETURN(hr = E_ADS_BAD_PARAMETER);
|
|
|
|
}
|
|
|
|
//
|
|
// check if property is BITMASK type;
|
|
// if BITMASK type, get corresponding DWORD flag property
|
|
//
|
|
|
|
if (dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) {
|
|
VARIANT vGetProp;
|
|
DWORD dwMask;
|
|
DWORD dwFlagValue;
|
|
|
|
hr = _pSchema->LookupBitMask(bstrName, &dwMask);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// get its corresponding DWORD flag value
|
|
//
|
|
|
|
hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
VariantInit(&vGetProp);
|
|
hr = Get(wchName, &vGetProp);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
dwFlagValue = V_I4(&vGetProp);
|
|
|
|
if (pIISDestObjects->IISValue.value_1.dwDWORD) {
|
|
dwFlagValue |= dwMask;
|
|
}
|
|
else {
|
|
dwFlagValue &= ~dwMask;
|
|
}
|
|
|
|
pIISDestObjects->IISValue.value_1.dwDWORD = dwFlagValue;
|
|
pIISDestObjects->IISType = IIS_SYNTAX_ID_DWORD;
|
|
bstrName = wchName;
|
|
}
|
|
|
|
if (dwSyntaxId == IIS_SYNTAX_ID_BINARY)
|
|
{
|
|
hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName);
|
|
BAIL_ON_FAILURE(hr);
|
|
bstrName = wchName;
|
|
}
|
|
|
|
//
|
|
// Find this property in the cache
|
|
//
|
|
|
|
hr = _pPropertyCache->findproperty(
|
|
bstrName,
|
|
&dwIndex
|
|
);
|
|
|
|
//
|
|
// If this property does not exist in the
|
|
// cache, add this property into the cache.
|
|
//
|
|
|
|
if (FAILED(hr)) {
|
|
hr = _pPropertyCache->addproperty(
|
|
bstrName,
|
|
dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK ?
|
|
IIS_SYNTAX_ID_DWORD : dwSyntaxId,
|
|
dwNumValues,
|
|
pIISDestObjects
|
|
);
|
|
//
|
|
// If the operation fails for some reason
|
|
// move on to the next property
|
|
//
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}
|
|
|
|
//
|
|
// Now update the property in the cache
|
|
//
|
|
|
|
hr = _pPropertyCache->putproperty(
|
|
bstrName,
|
|
dwFlags,
|
|
dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK ?
|
|
IIS_SYNTAX_ID_DWORD : dwSyntaxId,
|
|
dwNumValues,
|
|
pIISDestObjects
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
error:
|
|
|
|
if (pIISDestObjects) {
|
|
IISTypeFreeIISObjects(
|
|
pIISDestObjects,
|
|
dwNumValues
|
|
);
|
|
|
|
}
|
|
|
|
|
|
if (pVarArray) {
|
|
|
|
DWORD i = 0;
|
|
|
|
for (i = 0; i < dwNumValues; i++) {
|
|
VariantClear(pVarArray + i);
|
|
}
|
|
FreeADsMem(pVarArray);
|
|
}
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|