windows-nt/Source/XPSP1/NT/net/tapi/skywalker/rend/rnddo.cpp
2020-09-26 16:20:57 +08:00

335 lines
8 KiB
C++

/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
rnddo.cpp
Abstract:
This module contains implementation of CDirectoryObject object.
--*/
#include "stdafx.h"
#include "rnddo.h"
/////////////////////////////////////////////////////////////////////////////
// ITDirectoryObject
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CDirectoryObject::get_ObjectType(
OUT DIRECTORY_OBJECT_TYPE * pObjectType
)
{
if ( IsBadWritePtr(pObjectType, sizeof(DIRECTORY_OBJECT_TYPE) ) )
{
LOG((MSP_ERROR, "CDirectoryObject.get_ObjectType, invalid pointer"));
return E_POINTER;
}
CLock Lock(m_lock);
*pObjectType = m_Type;
return S_OK;
}
STDMETHODIMP CDirectoryObject::get_SecurityDescriptor(
OUT IDispatch ** ppSecDes
)
{
LOG((MSP_INFO, "CDirectoryObject::get_SecurityDescriptor - enter"));
//
// Check parameters.
//
BAIL_IF_BAD_WRITE_PTR(ppSecDes, E_POINTER);
//
// Do the rest in our lock.
//
CLock Lock(m_lock);
//
// If we don't have an IDispatch security descriptor, convert it. This
// will happen if PutConvertedSecurityDescriptor was called on object
// creation but neither get_SecurityDescriptor nor
// put_SecurityDescriptor have ever been called before on this object.
//
if ( ( m_pIDispatchSecurity == NULL ) && ( m_pSecDesData != NULL ) )
{
HRESULT hr;
hr = ConvertSDToIDispatch( (PSECURITY_DESCRIPTOR) m_pSecDesData,
&m_pIDispatchSecurity);
if ( FAILED(hr) )
{
LOG((MSP_ERROR, "CDirectoryObject::get_SecurityDescriptor - "
"invalid security descriptor - exit 0x%08x", hr));
// make sure we don't return something
*ppSecDes = NULL;
m_pIDispatchSecurity = NULL;
return hr;
}
//
// We keep our own reference to the IDispatch. (ie ref = 1 now)
//
}
//
// Return our IDispatch pointer, (possibly NULL if the object has no
// security descriptor), AddRefing if not NULL.
//
*ppSecDes = m_pIDispatchSecurity;
if (m_pIDispatchSecurity)
{
m_pIDispatchSecurity->AddRef();
}
LOG((MSP_INFO, "CDirectoryObject::get_SecurityDescriptor - exit S_OK"));
return S_OK;
}
STDMETHODIMP CDirectoryObject::put_SecurityDescriptor(
IN IDispatch * pSecDes
)
{
LOG((MSP_INFO, "CDirectoryObject::put_SecurityDescriptor - enter"));
//
// Make sure we are setting a valid interface pointer.
// (We've always done it this way -- it also means that
// you can't put a null security descriptor. The way to
// "turn off" the security descriptor is to construct an
// "empty" one or one granting everyone all access, and put_
// that here.)
//
BAIL_IF_BAD_READ_PTR(pSecDes, E_POINTER);
//
// Do the rest in our critical section.
//
CLock Lock(m_lock);
PSECURITY_DESCRIPTOR pSecDesData;
DWORD dwSecDesSize;
//
// Convert the new security descriptor to a SECURITY_DESCRIPTOR.
//
HRESULT hr;
hr = ConvertObjectToSDDispatch(pSecDes, &pSecDesData, &dwSecDesSize);
if ( FAILED(hr) )
{
LOG((MSP_ERROR, "CDirectoryObject::put_SecurityDescriptor - "
"ConvertObjectToSDDispatch failed - exit 0x%08x", hr));
return hr;
}
//
// Check if the new security descriptor's contents differ from the
// old security descriptor's contents.
//
m_fSecurityDescriptorChanged =
CheckIfSecurityDescriptorsDiffer(m_pSecDesData, m_dwSecDesSize,
pSecDesData, dwSecDesSize);
if (m_pIDispatchSecurity) // need this check because it's initially NULL
{
m_pIDispatchSecurity->Release();
// this was newed on previous ConvertObjectToSDDispatch
// or before PutConvertedSecurityDescriptor
delete m_pSecDesData;
}
m_pIDispatchSecurity = pSecDes;
m_pSecDesData = pSecDesData;
m_dwSecDesSize = dwSecDesSize;
m_pIDispatchSecurity->AddRef();
LOG((MSP_INFO, "CDirectoryObject::put_SecurityDescriptor - exit S_OK"));
return S_OK;
}
/* currently not exposed publicly, but nothing's stopping us from exposing it */
STDMETHODIMP CDirectoryObject::get_SecurityDescriptorIsModified(
OUT VARIANT_BOOL * pfIsModified
)
{
LOG((MSP_INFO, "CDirectoryObject::get_SecurityDescriptorIsModified - "
"enter"));
//
// Check parameters.
//
if ( IsBadWritePtr(pfIsModified, sizeof(VARIANT_BOOL) ) )
{
LOG((MSP_ERROR, "CDirectoryObject::get_SecurityDescriptorIsModified - "
"enter"));
return E_POINTER;
}
if ( m_fSecurityDescriptorChanged )
{
*pfIsModified = VARIANT_TRUE;
}
else
{
*pfIsModified = VARIANT_FALSE;
}
LOG((MSP_INFO, "CDirectoryObject::get_SecurityDescriptorIsModified - "
"exit S_OK"));
return S_OK;
}
// to keep the logic consistent this is not exposed publicly
// this overrules our comparison... it's normally called with VARIANT_FALSE
// to inform us that the object has been successfully written to the server
// or that the previous put_SecurityDescriptor was the one from the server
// rather than from the app.
STDMETHODIMP CDirectoryObject::put_SecurityDescriptorIsModified(
IN VARIANT_BOOL fIsModified
)
{
LOG((MSP_INFO, "CDirectoryObject::put_SecurityDescriptorIsModified - "
"enter"));
if ( fIsModified )
{
m_fSecurityDescriptorChanged = TRUE;
}
else
{
m_fSecurityDescriptorChanged = FALSE;
}
LOG((MSP_INFO, "CDirectoryObject::put_SecurityDescriptorIsModified - "
"exit S_OK"));
return S_OK;
}
HRESULT CDirectoryObject::PutConvertedSecurityDescriptor(
IN char * pSD,
IN DWORD dwSize
)
{
LOG((MSP_INFO, "CDirectoryObject::PutConvertedSecurityDescriptor - "
"enter"));
//
// Return our data. We retain ownership of the pointer;
// the caller must not delete it. (We may delete it later so the caller
// must have newed it.)
//
m_pSecDesData = pSD;
m_dwSecDesSize = dwSize;
LOG((MSP_INFO, "CDirectoryObject::PutConvertedSecurityDescriptor - "
"exit S_OK"));
return S_OK;
}
HRESULT CDirectoryObject::GetConvertedSecurityDescriptor(
OUT char ** ppSD,
OUT DWORD * pdwSize
)
{
LOG((MSP_INFO, "CDirectoryObject::GetConvertedSecurityDescriptor - "
"enter"));
//
// Return our data. We retain ownership of the pointer;
// the caller must not delete it.
//
*ppSD = (char *)m_pSecDesData;
*pdwSize = m_dwSecDesSize;
LOG((MSP_INFO, "CDirectoryObject::GetConvertedSecurityDescriptor - "
"exit S_OK"));
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
void CDirectoryObject::FinalRelease(void)
{
LOG((MSP_INFO, "CDirectoryObject::FinalRelease - "
"enter"));
if ( NULL != m_pIDispatchSecurity )
{
m_pIDispatchSecurity->Release();
m_pIDispatchSecurity = NULL;
}
if ( NULL != m_pSecDesData )
{
delete m_pSecDesData; // newed on last ConvertObjectToSDDispatch
}
if ( m_pFTM )
{
m_pFTM->Release();
}
LOG((MSP_INFO, "CDirectoryObject::FinalRelease - "
"exit S_OK"));
}
HRESULT CDirectoryObject::FinalConstruct(void)
{
LOG((MSP_INFO, "CDirectoryObject::FinalConstruct - enter"));
HRESULT hr = CoCreateFreeThreadedMarshaler( GetControllingUnknown(),
& m_pFTM );
if ( FAILED(hr) )
{
LOG((MSP_INFO, "CDirectoryObject::FinalConstruct - "
"create FTM returned 0x%08x; exit", hr));
return hr;
}
LOG((MSP_INFO, "CDirectoryObject::FinalConstruct - exit S_OK"));
return S_OK;
}
// eof