windows-nt/Source/XPSP1/NT/ds/adsi/winnt/cschema.cxx
2020-09-26 16:20:57 +08:00

1999 lines
46 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996
//
// File: cschema.cxx
//
// Contents: Windows NT 3.51
//
//
// History: 01-09-96 yihsins Created.
//
//----------------------------------------------------------------------------
#include "winnt.hxx"
#pragma hdrstop
/******************************************************************/
/* Class CWinNTSchema
/******************************************************************/
DEFINE_IDispatch_Delegating_Implementation(CWinNTSchema)
DEFINE_IADsExtension_Implementation(CWinNTSchema)
DEFINE_IADs_Implementation(CWinNTSchema)
CWinNTSchema::CWinNTSchema()
{
VariantInit( &_vFilter );
ENLIST_TRACKING(CWinNTSchema);
}
CWinNTSchema::~CWinNTSchema()
{
VariantClear( &_vFilter );
delete _pDispMgr;
}
HRESULT
CWinNTSchema::CreateSchema(
BSTR bstrParent,
BSTR bstrName,
DWORD dwObjectState,
REFIID riid,
CWinNTCredentials& Credentials,
void **ppvObj
)
{
CWinNTSchema FAR *pSchema = NULL;
HRESULT hr = S_OK;
hr = AllocateSchemaObject( &pSchema );
BAIL_ON_FAILURE(hr);
hr = pSchema->InitializeCoreObject(
bstrParent,
bstrName,
SCHEMA_CLASS_NAME,
NO_SCHEMA,
CLSID_WinNTSchema,
dwObjectState );
BAIL_ON_FAILURE(hr);
pSchema->_Credentials = Credentials;
// check if the call is from UMI
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
//
// we do not pass riid to InitUmiObject below. This is because UMI object
// does not support IDispatch. There are several places in ADSI code where
// riid passed into this function is defaulted to IID_IDispatch -
// IADsContainer::Create for example. To handle these cases, we always
// request IID_IUnknown from the UMI object. Subsequent code within UMI
// will QI for the appropriate interface.
//
if(2 == pSchema->_dwNumComponents) {
pSchema->_CompClasses[0] = L"Computer";
pSchema->_CompClasses[1] = L"Schema";
}
else
BAIL_ON_FAILURE(hr = UMI_E_FAIL);
hr = pSchema->InitUmiObject(
pSchema->_Credentials,
SchemaClass,
g_dwSchemaClassTableSize,
NULL,
(IUnknown *) (INonDelegatingUnknown *) pSchema,
NULL,
IID_IUnknown,
ppvObj
);
BAIL_ON_FAILURE(hr);
//
// UMI object was created and the interface was obtained successfully.
// UMI object now has a reference to the inner unknown of IADs, since
// the call to Release() below is not going to be made in this case.
//
RRETURN(hr);
}
hr = pSchema->QueryInterface( riid, ppvObj );
BAIL_ON_FAILURE(hr);
pSchema->Release();
RRETURN(hr);
error:
delete pSchema;
RRETURN_EXP_IF_ERR(hr);
}
//----------------------------------------------------------------------------
// Function: QueryInterface
//
// Synopsis: If this object is aggregated within another object, then
// all calls will delegate to the outer object. Otherwise, the
// non-delegating QI is called
//
// Arguments:
//
// iid interface requested
// ppInterface Returns pointer to interface requested. NULL if interface
// is not supported.
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: *ppInterface to return interface pointer
//
//----------------------------------------------------------------------------
STDMETHODIMP CWinNTSchema::QueryInterface(
REFIID iid,
LPVOID *ppInterface
)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->QueryInterface(
iid,
ppInterface
));
RRETURN(NonDelegatingQueryInterface(
iid,
ppInterface
));
}
//----------------------------------------------------------------------------
// Function: AddRef
//
// Synopsis: IUnknown::AddRef. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating AddRef is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTSchema::AddRef(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->AddRef());
RRETURN(NonDelegatingAddRef());
}
//----------------------------------------------------------------------------
// Function: Release
//
// Synopsis: IUnknown::Release. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating Release is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTSchema::Release(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->Release());
RRETURN(NonDelegatingRelease());
}
//----------------------------------------------------------------------------
STDMETHODIMP
CWinNTSchema::NonDelegatingQueryInterface(REFIID iid, LPVOID FAR* ppv)
{
if (ppv == NULL) {
RRETURN(E_POINTER);
}
if (IsEqualIID(iid, IID_IUnknown))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_IDispatch))
{
*ppv = (IADs FAR *)this;
}
else if (IsEqualIID(iid, IID_ISupportErrorInfo))
{
*ppv = (ISupportErrorInfo FAR *)this;
}
else if (IsEqualIID(iid, IID_IADs))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_IADsContainer))
{
*ppv = (IADsContainer FAR *) this;
}
else if( (_pDispatch != NULL) &&
IsEqualIID(iid, IID_IADsExtension) )
{
*ppv = (IADsExtension *) this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
/* ISupportErrorInfo method */
STDMETHODIMP
CWinNTSchema::InterfaceSupportsErrorInfo(
THIS_ REFIID riid
)
{
if (IsEqualIID(riid, IID_IADs) ||
IsEqualIID(riid, IID_IADsContainer)) {
RRETURN(S_OK);
} else {
RRETURN(S_FALSE);
}
}
/* IADs methods */
STDMETHODIMP
CWinNTSchema::SetInfo(THIS)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTSchema::GetInfo(THIS)
{
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTSchema::ImplicitGetInfo(THIS)
{
RRETURN(S_OK);
}
/* IADsContainer methods */
STDMETHODIMP
CWinNTSchema::get_Count(long FAR* retval)
{
HRESULT hr;
if ( !retval )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*retval = g_cWinNTClasses + g_cWinNTSyntax;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTSchema::get_Filter(THIS_ VARIANT FAR* pVar)
{
HRESULT hr;
if ( !pVar )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
VariantInit( pVar );
hr = VariantCopy( pVar, &_vFilter );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTSchema::put_Filter(THIS_ VARIANT Var)
{
HRESULT hr;
hr = VariantCopy( &_vFilter, &Var );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTSchema::get_Hints(THIS_ VARIANT FAR* pVar)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTSchema::put_Hints(THIS_ VARIANT Var)
{
RRETURN_EXP_IF_ERR( E_NOTIMPL);
}
STDMETHODIMP
CWinNTSchema::GetObject(
THIS_ BSTR ClassName,
BSTR RelativeName,
IDispatch * FAR* ppObject)
{
TCHAR szBuffer[MAX_PATH];
DWORD dwLength = 0;
HRESULT hr = S_OK;
if (!RelativeName || !*RelativeName) {
RRETURN_EXP_IF_ERR(E_ADS_UNKNOWN_OBJECT);
}
//
// Make sure we are not going to overflow the string buffer.
// +2 for / and \0
//
dwLength = wcslen(_ADsPath) + wcslen(RelativeName) + 2;
if (dwLength > MAX_PATH) {
BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER);
}
wcscpy(szBuffer, _ADsPath);
wcscat(szBuffer, L"/");
wcscat(szBuffer, RelativeName);
if (ClassName) {
//
// +1 for the ",".
//
dwLength += wcslen(ClassName) + 1;
if (dwLength > MAX_PATH) {
BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER);
}
wcscat(szBuffer,L",");
wcscat(szBuffer, ClassName);
}
hr = ::GetObject(szBuffer, (LPVOID *)ppObject, _Credentials);
BAIL_ON_FAILURE(hr);
error:
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTSchema::get__NewEnum(THIS_ IUnknown * FAR* retval)
{
HRESULT hr;
IEnumVARIANT *penum = NULL;
if ( !retval )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*retval = NULL;
//
// Create new enumerator for items currently
// in collection and QI for IUnknown
//
hr = CWinNTSchemaEnum::Create( (CWinNTSchemaEnum **)&penum,
_ADsPath,
_Name,
_vFilter,
_Credentials);
BAIL_ON_FAILURE(hr);
hr = penum->QueryInterface( IID_IUnknown, (VOID FAR* FAR*)retval );
BAIL_ON_FAILURE(hr);
if ( penum )
penum->Release();
RRETURN(hr);
error:
if ( penum )
delete penum;
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTSchema::Create(
THIS_ BSTR ClassName,
BSTR RelativeName,
IDispatch * FAR* ppObject)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTSchema::Delete(THIS_ BSTR SourceName, BSTR Type)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTSchema::CopyHere(THIS_ BSTR SourceName,
BSTR NewName,
IDispatch * FAR* ppObject)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTSchema::MoveHere(THIS_ BSTR SourceName,
BSTR NewName,
IDispatch * FAR* ppObject)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
HRESULT
CWinNTSchema::AllocateSchemaObject(CWinNTSchema FAR * FAR * ppSchema)
{
CWinNTSchema FAR *pSchema = NULL;
CAggregatorDispMgr FAR *pDispMgr = NULL;
HRESULT hr = S_OK;
pSchema = new CWinNTSchema();
if ( pSchema == NULL )
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregatorDispMgr;
if ( pDispMgr == NULL )
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr,
LIBID_ADs,
IID_IADs,
(IADs *) pSchema,
DISPID_REGULAR );
BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr,
LIBID_ADs,
IID_IADsContainer,
(IADsContainer *) pSchema,
DISPID_NEWENUM );
BAIL_ON_FAILURE(hr);
pSchema->_pDispMgr = pDispMgr;
*ppSchema = pSchema;
RRETURN(hr);
error:
delete pDispMgr;
delete pSchema;
RRETURN_EXP_IF_ERR(hr);
}
/******************************************************************/
/* Class CWinNTClass
/******************************************************************/
DEFINE_IDispatch_Delegating_Implementation(CWinNTClass)
DEFINE_IADsExtension_Implementation(CWinNTClass)
DEFINE_IADs_Implementation(CWinNTClass)
CWinNTClass::CWinNTClass()
: _pDispMgr( NULL ),
_aPropertyInfo( NULL ),
_cPropertyInfo( 0 ),
_bstrCLSID( NULL ),
_bstrOID( NULL ),
_bstrPrimaryInterface( NULL ),
_fAbstract( FALSE ),
_fContainer( FALSE ),
_bstrHelpFileName( NULL ),
_lHelpFileContext( 0 )
{
VariantInit( &_vMandatoryProperties );
VariantInit( &_vOptionalProperties );
VariantInit( &_vPossSuperiors );
VariantInit( &_vContainment );
VariantInit( &_vFilter );
ENLIST_TRACKING(CWinNTClass);
}
CWinNTClass::~CWinNTClass()
{
if ( _bstrCLSID ) {
ADsFreeString( _bstrCLSID );
}
if ( _bstrOID ) {
ADsFreeString( _bstrOID );
}
if ( _bstrPrimaryInterface ) {
ADsFreeString( _bstrPrimaryInterface );
}
if ( _bstrHelpFileName ) {
ADsFreeString( _bstrHelpFileName );
}
VariantClear( &_vMandatoryProperties );
VariantClear( &_vOptionalProperties );
VariantClear( &_vPossSuperiors );
VariantClear( &_vContainment );
VariantClear( &_vFilter );
delete _pDispMgr;
}
HRESULT
CWinNTClass::CreateClass(
BSTR bstrParent,
CLASSINFO *pClassInfo,
DWORD dwObjectState,
REFIID riid,
CWinNTCredentials& Credentials,
void **ppvObj
)
{
CWinNTClass FAR *pClass = NULL;
HRESULT hr = S_OK;
BSTR bstrTmp = NULL;
hr = AllocateClassObject( &pClass );
BAIL_ON_FAILURE(hr);
pClass->_aPropertyInfo = pClassInfo->aPropertyInfo;
pClass->_cPropertyInfo = pClassInfo->cPropertyInfo;
pClass->_lHelpFileContext = pClassInfo->lHelpFileContext;
pClass->_fContainer = (VARIANT_BOOL)pClassInfo->fContainer;
pClass->_fAbstract = (VARIANT_BOOL)pClassInfo->fAbstract;
hr = StringFromCLSID( (REFCLSID) *(pClassInfo->pPrimaryInterfaceGUID),
&bstrTmp );
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( bstrTmp,
&pClass->_bstrPrimaryInterface);
BAIL_ON_FAILURE(hr);
CoTaskMemFree(bstrTmp);
bstrTmp = NULL;
hr = StringFromCLSID( (REFCLSID) *(pClassInfo->pCLSID),
&bstrTmp );
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( bstrTmp,
&pClass->_bstrCLSID );
BAIL_ON_FAILURE(hr);
CoTaskMemFree(bstrTmp);
bstrTmp = NULL;
hr = ADsAllocString( pClassInfo->bstrOID, &pClass->_bstrOID);
BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrMandatoryProperties,
&(pClass->_vMandatoryProperties));
BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrOptionalProperties,
&(pClass->_vOptionalProperties));
BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrPossSuperiors,
&(pClass->_vPossSuperiors));
BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrContainment,
&(pClass->_vContainment));
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( pClassInfo->bstrHelpFileName,
&pClass->_bstrHelpFileName);
BAIL_ON_FAILURE(hr);
hr = pClass->InitializeCoreObject(
bstrParent,
pClassInfo->bstrName,
CLASS_CLASS_NAME,
NO_SCHEMA,
CLSID_WinNTClass,
dwObjectState );
BAIL_ON_FAILURE(hr);
pClass->_Credentials = Credentials;
// check if the call is from UMI
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
//
// we do not pass riid to InitUmiObject below. This is because UMI object
// does not support IDispatch. There are several places in ADSI code where
// riid passed into this function is defaulted to IID_IDispatch -
// IADsContainer::Create for example. To handle these cases, we always
// request IID_IUnknown from the UMI object. Subsequent code within UMI
// will QI for the appropriate interface.
//
if(3 == pClass->_dwNumComponents) {
pClass->_CompClasses[0] = L"Computer";
pClass->_CompClasses[1] = L"Schema";
pClass->_CompClasses[2] = L"Class";
}
else
BAIL_ON_FAILURE(hr = UMI_E_FAIL);
hr = pClass->InitUmiObject(
pClass->_Credentials,
SchClassClass,
g_dwSchClassClassTableSize,
NULL,
(IUnknown *)(INonDelegatingUnknown *) pClass,
NULL,
IID_IUnknown,
ppvObj,
pClassInfo
);
BAIL_ON_FAILURE(hr);
//
// UMI object was created and the interface was obtained successfully.
// UMI object now has a reference to the inner unknown of IADs, since
// the call to Release() below is not going to be made in this case.
//
RRETURN(hr);
}
hr = pClass->QueryInterface( riid, ppvObj );
BAIL_ON_FAILURE(hr);
pClass->Release();
RRETURN(hr);
error:
if ( bstrTmp != NULL )
CoTaskMemFree(bstrTmp);
delete pClass;
RRETURN_EXP_IF_ERR(hr);
}
// called by implicit GetInfo from property cache
STDMETHODIMP
CWinNTClass::GetInfo(
THIS_ DWORD dwApiLevel,
BOOL fExplicit
)
{
RRETURN(S_OK);
}
//----------------------------------------------------------------------------
// Function: QueryInterface
//
// Synopsis: If this object is aggregated within another object, then
// all calls will delegate to the outer object. Otherwise, the
// non-delegating QI is called
//
// Arguments:
//
// iid interface requested
// ppInterface Returns pointer to interface requested. NULL if interface
// is not supported.
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: *ppInterface to return interface pointer
//
//----------------------------------------------------------------------------
STDMETHODIMP CWinNTClass::QueryInterface(
REFIID iid,
LPVOID *ppInterface
)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->QueryInterface(
iid,
ppInterface
));
RRETURN(NonDelegatingQueryInterface(
iid,
ppInterface
));
}
//----------------------------------------------------------------------------
// Function: AddRef
//
// Synopsis: IUnknown::AddRef. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating AddRef is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTClass::AddRef(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->AddRef());
RRETURN(NonDelegatingAddRef());
}
//----------------------------------------------------------------------------
// Function: Release
//
// Synopsis: IUnknown::Release. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating Release is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTClass::Release(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->Release());
RRETURN(NonDelegatingRelease());
}
//----------------------------------------------------------------------------
STDMETHODIMP
CWinNTClass::NonDelegatingQueryInterface(REFIID iid, LPVOID FAR* ppv)
{
if (ppv == NULL) {
RRETURN(E_POINTER);
}
if (IsEqualIID(iid, IID_IUnknown))
{
*ppv = (IADsClass FAR * ) this;
}
else if (IsEqualIID(iid, IID_IDispatch))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_ISupportErrorInfo))
{
*ppv = (ISupportErrorInfo FAR *)this;
}
else if (IsEqualIID(iid, IID_IADs))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_IADsClass))
{
*ppv = (IADsClass FAR *) this;
}
else if( (_pDispatch != NULL) &&
IsEqualIID(iid, IID_IADsExtension) )
{
*ppv = (IADsExtension *) this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
/* ISupportErrorInfo method */
STDMETHODIMP
CWinNTClass::InterfaceSupportsErrorInfo(
THIS_ REFIID riid
)
{
if (IsEqualIID(riid, IID_IADs) ||
IsEqualIID(riid, IID_IADsClass)) {
RRETURN(S_OK);
} else {
RRETURN(S_FALSE);
}
}
/* IADs methods */
STDMETHODIMP
CWinNTClass::SetInfo(THIS)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTClass::GetInfo(THIS)
{
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTClass::ImplicitGetInfo(THIS)
{
RRETURN(S_OK);
}
/* IADsClass methods */
STDMETHODIMP
CWinNTClass::get_PrimaryInterface( THIS_ BSTR FAR *pbstrGUID )
{
HRESULT hr;
if ( !pbstrGUID )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
hr = ADsAllocString( _bstrPrimaryInterface, pbstrGUID );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::get_CLSID( THIS_ BSTR FAR *pbstrCLSID )
{
HRESULT hr;
if ( !pbstrCLSID )
RRETURN(E_ADS_BAD_PARAMETER);
hr = ADsAllocString( _bstrCLSID, pbstrCLSID );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::put_CLSID( THIS_ BSTR bstrCLSID )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_OID( THIS_ BSTR FAR *pbstrOID )
{
HRESULT hr;
if ( !pbstrOID )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
hr = ADsAllocString( _bstrOID, pbstrOID );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::put_OID( THIS_ BSTR bstrOID )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_Abstract( THIS_ VARIANT_BOOL FAR *pfAbstract )
{
if ( !pfAbstract )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*pfAbstract = _fAbstract? VARIANT_TRUE : VARIANT_FALSE;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTClass::put_Abstract( THIS_ VARIANT_BOOL fAbstract )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_Auxiliary( THIS_ VARIANT_BOOL FAR *pfAuxiliary)
{
if ( !pfAuxiliary )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*pfAuxiliary = VARIANT_FALSE;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTClass::put_Auxiliary( THIS_ VARIANT_BOOL fAuxiliary )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_MandatoryProperties( THIS_ VARIANT FAR *pvMandatoryProperties )
{
HRESULT hr;
VariantInit( pvMandatoryProperties );
hr = VariantCopy( pvMandatoryProperties, &_vMandatoryProperties );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::put_MandatoryProperties( THIS_ VARIANT vMandatoryProperties )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_DerivedFrom( THIS_ VARIANT FAR *pvDerivedFrom )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::put_DerivedFrom( THIS_ VARIANT vDerivedFrom )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_AuxDerivedFrom( THIS_ VARIANT FAR *pvAuxDerivedFrom )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::put_AuxDerivedFrom( THIS_ VARIANT vAuxDerivedFrom )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_PossibleSuperiors( THIS_ VARIANT FAR *pvPossSuperiors )
{
HRESULT hr;
VariantInit( pvPossSuperiors );
hr = VariantCopy( pvPossSuperiors, &_vPossSuperiors );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::put_PossibleSuperiors( THIS_ VARIANT vPossSuperiors )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_Containment( THIS_ VARIANT FAR *pvContainment )
{
HRESULT hr;
VariantInit( pvContainment );
hr = VariantCopy( pvContainment, &_vContainment );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::put_Containment( THIS_ VARIANT vContainment )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_Container( THIS_ VARIANT_BOOL FAR *pfContainer )
{
if ( !pfContainer )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*pfContainer = _fContainer? VARIANT_TRUE : VARIANT_FALSE;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTClass::put_Container( THIS_ VARIANT_BOOL fContainer )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_HelpFileName( THIS_ BSTR FAR *pbstrHelpFileName )
{
HRESULT hr;
if ( !pbstrHelpFileName )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
hr = ADsAllocString( _bstrHelpFileName, pbstrHelpFileName );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::put_HelpFileName( THIS_ BSTR bstrHelpFile )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::get_HelpFileContext( THIS_ long FAR *plHelpContext )
{
if ( !plHelpContext )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*plHelpContext = _lHelpFileContext;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTClass::put_HelpFileContext( THIS_ long lHelpContext )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTClass::Qualifiers(THIS_ IADsCollection FAR* FAR* ppQualifiers)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
HRESULT
CWinNTClass::AllocateClassObject(CWinNTClass FAR * FAR * ppClass)
{
CWinNTClass FAR *pClass = NULL;
CAggregatorDispMgr FAR *pDispMgr = NULL;
HRESULT hr = S_OK;
pClass = new CWinNTClass();
if ( pClass == NULL )
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregatorDispMgr;
if ( pDispMgr == NULL )
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr,
LIBID_ADs,
IID_IADs,
(IADs *) pClass,
DISPID_REGULAR );
BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr,
LIBID_ADs,
IID_IADsClass,
(IADsClass *) pClass,
DISPID_REGULAR );
BAIL_ON_FAILURE(hr);
pClass->_pDispMgr = pDispMgr;
*ppClass = pClass;
RRETURN(hr);
error:
delete pDispMgr;
delete pClass;
RRETURN(hr);
}
/******************************************************************/
/* Class CWinNTProperty
/******************************************************************/
DEFINE_IDispatch_Delegating_Implementation(CWinNTProperty)
DEFINE_IADsExtension_Implementation(CWinNTProperty)
DEFINE_IADs_Implementation(CWinNTProperty)
CWinNTProperty::CWinNTProperty()
: _pDispMgr( NULL ),
_bstrOID( NULL ),
_bstrSyntax( NULL ),
_lMaxRange( 0 ),
_lMinRange( 0 ),
_fMultiValued( FALSE )
{
ENLIST_TRACKING(CWinNTProperty);
}
CWinNTProperty::~CWinNTProperty()
{
if ( _bstrOID ) {
ADsFreeString( _bstrOID );
}
if ( _bstrSyntax ) {
ADsFreeString( _bstrSyntax );
}
delete _pDispMgr;
}
HRESULT
CWinNTProperty::CreateProperty(
BSTR bstrParent,
PROPERTYINFO *pPropertyInfo,
DWORD dwObjectState,
REFIID riid,
CWinNTCredentials& Credentials,
void **ppvObj
)
{
CWinNTProperty FAR * pProperty = NULL;
HRESULT hr = S_OK;
hr = AllocatePropertyObject( &pProperty );
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( pPropertyInfo->bstrOID, &pProperty->_bstrOID);
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( pPropertyInfo->bstrSyntax, &pProperty->_bstrSyntax);
BAIL_ON_FAILURE(hr);
pProperty->_lMaxRange = pPropertyInfo->lMaxRange;
pProperty->_lMinRange = pPropertyInfo->lMinRange;
pProperty->_fMultiValued = (VARIANT_BOOL)pPropertyInfo->fMultiValued;
hr = pProperty->InitializeCoreObject(
bstrParent,
pPropertyInfo->szPropertyName,
PROPERTY_CLASS_NAME,
NO_SCHEMA,
CLSID_WinNTProperty,
dwObjectState );
BAIL_ON_FAILURE(hr);
pProperty->_Credentials = Credentials;
// check if the call is from UMI
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
//
// we do not pass riid to InitUmiObject below. This is because UMI object
// does not support IDispatch. There are several places in ADSI code where
// riid passed into this function is defaulted to IID_IDispatch -
// IADsContainer::Create for example. To handle these cases, we always
// request IID_IUnknown from the UMI object. Subsequent code within UMI
// will QI for the appropriate interface.
//
if(3 == pProperty->_dwNumComponents) {
pProperty->_CompClasses[0] = L"Computer";
pProperty->_CompClasses[1] = L"Schema";
pProperty->_CompClasses[2] = L"Property";
}
else
BAIL_ON_FAILURE(hr = UMI_E_FAIL);
hr = pProperty->InitUmiObject(
pProperty->_Credentials,
PropertyClass,
g_dwPropertyClassTableSize,
NULL,
(IUnknown *)(INonDelegatingUnknown *) pProperty,
NULL,
IID_IUnknown,
ppvObj
);
BAIL_ON_FAILURE(hr);
//
// UMI object was created and the interface was obtained successfully.
// UMI object now has a reference to the inner unknown of IADs, since
// the call to Release() below is not going to be made in this case.
//
RRETURN(hr);
}
hr = pProperty->QueryInterface( riid, ppvObj );
BAIL_ON_FAILURE(hr);
pProperty->Release();
RRETURN(hr);
error:
delete pProperty;
RRETURN_EXP_IF_ERR(hr);
}
// called by implicit GetInfo from property cache
STDMETHODIMP
CWinNTProperty::GetInfo(
THIS_ DWORD dwApiLevel,
BOOL fExplicit
)
{
RRETURN(S_OK);
}
//----------------------------------------------------------------------------
// Function: QueryInterface
//
// Synopsis: If this object is aggregated within another object, then
// all calls will delegate to the outer object. Otherwise, the
// non-delegating QI is called
//
// Arguments:
//
// iid interface requested
// ppInterface Returns pointer to interface requested. NULL if interface
// is not supported.
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: *ppInterface to return interface pointer
//
//----------------------------------------------------------------------------
STDMETHODIMP CWinNTProperty::QueryInterface(
REFIID iid,
LPVOID *ppInterface
)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->QueryInterface(
iid,
ppInterface
));
RRETURN(NonDelegatingQueryInterface(
iid,
ppInterface
));
}
//----------------------------------------------------------------------------
// Function: AddRef
//
// Synopsis: IUnknown::AddRef. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating AddRef is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTProperty::AddRef(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->AddRef());
RRETURN(NonDelegatingAddRef());
}
//----------------------------------------------------------------------------
// Function: Release
//
// Synopsis: IUnknown::Release. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating Release is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTProperty::Release(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->Release());
RRETURN(NonDelegatingRelease());
}
//----------------------------------------------------------------------------
STDMETHODIMP
CWinNTProperty::NonDelegatingQueryInterface(REFIID iid, LPVOID FAR* ppv)
{
if (ppv == NULL) {
RRETURN(E_POINTER);
}
if (IsEqualIID(iid, IID_IUnknown))
{
*ppv = (IADsProperty FAR *) this;
}
else if (IsEqualIID(iid, IID_IDispatch))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_ISupportErrorInfo))
{
*ppv = (ISupportErrorInfo FAR *)this;
}
else if (IsEqualIID(iid, IID_IADs))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_IADsProperty))
{
*ppv = (IADsProperty FAR *) this;
}
else if( (_pDispatch != NULL) &&
IsEqualIID(iid, IID_IADsExtension) )
{
*ppv = (IADsExtension *) this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
/* ISupportErrorInfo method */
STDMETHODIMP
CWinNTProperty::InterfaceSupportsErrorInfo(
THIS_ REFIID riid
)
{
if (IsEqualIID(riid, IID_IADs) ||
IsEqualIID(riid, IID_IADsProperty)) {
RRETURN(S_OK);
} else {
RRETURN(S_FALSE);
}
}
/* IADs methods */
STDMETHODIMP
CWinNTProperty::SetInfo(THIS)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTProperty::GetInfo(THIS)
{
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTProperty::ImplicitGetInfo(THIS)
{
RRETURN(S_OK);
}
/* IADsProperty methods */
STDMETHODIMP
CWinNTProperty::get_OID( THIS_ BSTR FAR *pbstrOID )
{
HRESULT hr;
if ( !pbstrOID )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
hr = ADsAllocString( _bstrOID, pbstrOID );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTProperty::put_OID( THIS_ BSTR bstrOID )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTProperty::get_Syntax( THIS_ BSTR FAR *pbstrSyntax )
{
HRESULT hr;
if ( !pbstrSyntax )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
hr = ADsAllocString( _bstrSyntax, pbstrSyntax );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTProperty::put_Syntax( THIS_ BSTR bstrSyntax )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTProperty::get_MaxRange( THIS_ long FAR *plMaxRange )
{
if ( !plMaxRange )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*plMaxRange = _lMaxRange;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTProperty::put_MaxRange( THIS_ long lMaxRange )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTProperty::get_MinRange( THIS_ long FAR *plMinRange )
{
if ( !plMinRange )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*plMinRange = _lMinRange;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTProperty::put_MinRange( THIS_ long lMinRange )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTProperty::get_MultiValued( THIS_ VARIANT_BOOL FAR *pfMultiValued )
{
if ( !pfMultiValued )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*pfMultiValued = _fMultiValued? VARIANT_TRUE : VARIANT_FALSE;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTProperty::put_MultiValued( THIS_ VARIANT_BOOL fMultiValued )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CWinNTProperty::Qualifiers(THIS_ IADsCollection FAR* FAR* ppQualifiers)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
HRESULT
CWinNTProperty::AllocatePropertyObject(CWinNTProperty FAR * FAR * ppProperty)
{
CWinNTProperty FAR *pProperty = NULL;
CAggregatorDispMgr FAR *pDispMgr = NULL;
HRESULT hr = S_OK;
pProperty = new CWinNTProperty();
if ( pProperty == NULL )
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregatorDispMgr;
if ( pDispMgr == NULL )
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr,
LIBID_ADs,
IID_IADs,
(IADs *) pProperty,
DISPID_REGULAR );
BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr,
LIBID_ADs,
IID_IADsProperty,
(IADsProperty *) pProperty,
DISPID_REGULAR );
BAIL_ON_FAILURE(hr);
pProperty->_pDispMgr = pDispMgr;
*ppProperty = pProperty;
RRETURN(hr);
error:
delete pDispMgr;
delete pProperty;
RRETURN(hr);
}
/******************************************************************/
/* Class CWinNTSyntax
/******************************************************************/
DEFINE_IDispatch_Delegating_Implementation(CWinNTSyntax)
DEFINE_IADsExtension_Implementation(CWinNTSyntax)
DEFINE_IADs_Implementation(CWinNTSyntax)
CWinNTSyntax::CWinNTSyntax()
{
ENLIST_TRACKING(CWinNTSyntax);
}
CWinNTSyntax::~CWinNTSyntax()
{
delete _pDispMgr;
}
HRESULT
CWinNTSyntax::CreateSyntax(
BSTR bstrParent,
SYNTAXINFO *pSyntaxInfo,
DWORD dwObjectState,
REFIID riid,
CWinNTCredentials& Credentials,
void **ppvObj
)
{
CWinNTSyntax FAR *pSyntax = NULL;
HRESULT hr = S_OK;
hr = AllocateSyntaxObject( &pSyntax );
BAIL_ON_FAILURE(hr);
hr = pSyntax->InitializeCoreObject(
bstrParent,
pSyntaxInfo->bstrName,
SYNTAX_CLASS_NAME,
NO_SCHEMA,
CLSID_WinNTSyntax,
dwObjectState );
BAIL_ON_FAILURE(hr);
pSyntax->_lOleAutoDataType = pSyntaxInfo->lOleAutoDataType;
pSyntax->_Credentials = Credentials;
// check if the call is from UMI
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
//
// we do not pass riid to InitUmiObject below. This is because UMI object
// does not support IDispatch. There are several places in ADSI code where
// riid passed into this function is defaulted to IID_IDispatch -
// IADsContainer::Create for example. To handle these cases, we always
// request IID_IUnknown from the UMI object. Subsequent code within UMI
// will QI for the appropriate interface.
//
if(3 == pSyntax->_dwNumComponents) {
pSyntax->_CompClasses[0] = L"Computer";
pSyntax->_CompClasses[1] = L"Schema";
pSyntax->_CompClasses[2] = L"Syntax";
}
else
BAIL_ON_FAILURE(hr = UMI_E_FAIL);
hr = pSyntax->InitUmiObject(
pSyntax->_Credentials,
SyntaxClass,
g_dwSyntaxTableSize,
NULL,
(IUnknown *)(INonDelegatingUnknown *) pSyntax,
NULL,
IID_IUnknown,
ppvObj
);
BAIL_ON_FAILURE(hr);
//
// UMI object was created and the interface was obtained successfully.
// UMI object now has a reference to the inner unknown of IADs, since
// the call to Release() below is not going to be made in this case.
//
RRETURN(hr);
}
hr = pSyntax->QueryInterface( riid, ppvObj );
BAIL_ON_FAILURE(hr);
pSyntax->Release();
RRETURN(hr);
error:
delete pSyntax;
RRETURN_EXP_IF_ERR(hr);
}
// called by implicit GetInfo from property cache
STDMETHODIMP
CWinNTSyntax::GetInfo(
THIS_ DWORD dwApiLevel,
BOOL fExplicit
)
{
RRETURN(S_OK);
}
//----------------------------------------------------------------------------
// Function: QueryInterface
//
// Synopsis: If this object is aggregated within another object, then
// all calls will delegate to the outer object. Otherwise, the
// non-delegating QI is called
//
// Arguments:
//
// iid interface requested
// ppInterface Returns pointer to interface requested. NULL if interface
// is not supported.
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: *ppInterface to return interface pointer
//
//----------------------------------------------------------------------------
STDMETHODIMP CWinNTSyntax::QueryInterface(
REFIID iid,
LPVOID *ppInterface
)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->QueryInterface(
iid,
ppInterface
));
RRETURN(NonDelegatingQueryInterface(
iid,
ppInterface
));
}
//----------------------------------------------------------------------------
// Function: AddRef
//
// Synopsis: IUnknown::AddRef. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating AddRef is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTSyntax::AddRef(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->AddRef());
RRETURN(NonDelegatingAddRef());
}
//----------------------------------------------------------------------------
// Function: Release
//
// Synopsis: IUnknown::Release. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating Release is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTSyntax::Release(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->Release());
RRETURN(NonDelegatingRelease());
}
//----------------------------------------------------------------------------
STDMETHODIMP
CWinNTSyntax::NonDelegatingQueryInterface(REFIID iid, LPVOID FAR* ppv)
{
if (ppv == NULL) {
RRETURN(E_POINTER);
}
if (IsEqualIID(iid, IID_IUnknown))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_IDispatch))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_ISupportErrorInfo))
{
*ppv = (ISupportErrorInfo FAR *) this;
}
else if (IsEqualIID(iid, IID_IADs))
{
*ppv = (IADs FAR *) this;
}
else if (IsEqualIID(iid, IID_IADsSyntax))
{
*ppv = (IADsSyntax FAR *) this;
}
else if( (_pDispatch != NULL) &&
IsEqualIID(iid, IID_IADsExtension) )
{
*ppv = (IADsExtension *) this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
/* ISupportErrorInfo method */
STDMETHODIMP
CWinNTSyntax::InterfaceSupportsErrorInfo(
THIS_ REFIID riid
)
{
if (IsEqualIID(riid, IID_IADs) ||
IsEqualIID(riid, IID_IADsSyntax)) {
RRETURN(S_OK);
} else {
RRETURN(S_FALSE);
}
}
/* IADs methods */
STDMETHODIMP
CWinNTSyntax::SetInfo(THIS)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTSyntax::GetInfo(THIS)
{
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTSyntax::ImplicitGetInfo(THIS)
{
RRETURN(S_OK);
}
HRESULT
CWinNTSyntax::AllocateSyntaxObject(CWinNTSyntax FAR * FAR * ppSyntax)
{
CWinNTSyntax FAR *pSyntax = NULL;
CAggregatorDispMgr FAR *pDispMgr = NULL;
HRESULT hr = S_OK;
pSyntax = new CWinNTSyntax();
if ( pSyntax == NULL )
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregatorDispMgr;
if ( pDispMgr == NULL )
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr,
LIBID_ADs,
IID_IADsSyntax,
(IADsSyntax *) pSyntax,
DISPID_REGULAR );
BAIL_ON_FAILURE(hr);
pSyntax->_pDispMgr = pDispMgr;
*ppSyntax = pSyntax;
RRETURN(hr);
error:
delete pDispMgr;
delete pSyntax;
RRETURN(hr);
}
STDMETHODIMP
CWinNTSyntax::get_OleAutoDataType( THIS_ long FAR *plOleAutoDataType )
{
if ( !plOleAutoDataType )
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
*plOleAutoDataType = _lOleAutoDataType;
RRETURN(S_OK);
}
STDMETHODIMP
CWinNTSyntax::put_OleAutoDataType( THIS_ long lOleAutoDataType )
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
/******************************************************************/
/* Misc Helpers
/******************************************************************/
HRESULT
MakeVariantFromStringList(
BSTR bstrList,
VARIANT *pvVariant
)
{
HRESULT hr = S_OK;
SAFEARRAY *aList = NULL;
SAFEARRAYBOUND aBound;
BSTR pszTempList = NULL;
if ( bstrList != NULL )
{
long i = 0;
long nCount = 1;
TCHAR c;
BSTR pszSrc;
hr = ADsAllocString( bstrList, &pszTempList );
BAIL_ON_FAILURE(hr);
while ( c = pszTempList[i] )
{
if ( c == TEXT(','))
{
pszTempList[i] = 0;
nCount++;
}
i++;
}
aBound.lLbound = 0;
aBound.cElements = nCount;
aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
if ( aList == NULL )
{
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
pszSrc = pszTempList;
for ( i = 0; i < nCount; i++ )
{
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_BSTR;
hr = ADsAllocString( pszSrc, &(V_BSTR(&v)));
BAIL_ON_FAILURE(hr);
hr = SafeArrayPutElement( aList,
&i,
&v );
VariantClear(&v);
BAIL_ON_FAILURE(hr);
pszSrc += _tcslen( pszSrc ) + 1;
}
VariantInit( pvVariant );
V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
V_ARRAY(pvVariant) = aList;
ADsFreeString( pszTempList );
pszTempList = NULL;
}
else
{
aBound.lLbound = 0;
aBound.cElements = 0;
aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
if ( aList == NULL )
{
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
VariantInit( pvVariant );
V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
V_ARRAY(pvVariant) = aList;
}
RRETURN(S_OK);
error:
if ( pszTempList )
ADsFreeString( pszTempList );
if ( aList )
SafeArrayDestroy( aList );
return hr;
}
STDMETHODIMP
CWinNTClass::get_OptionalProperties( THIS_ VARIANT FAR *retval )
{
HRESULT hr;
VariantInit( retval );
hr = VariantCopy( retval, &_vOptionalProperties );
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::put_OptionalProperties( THIS_ VARIANT vOptionalProperties )
{
HRESULT hr = E_NOTIMPL;
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CWinNTClass::get_NamingProperties( THIS_ VARIANT FAR *retval )
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CWinNTClass::put_NamingProperties( THIS_ VARIANT vNamingProperties )
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}