Leaked source code of windows server 2003
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.
 
 
 
 
 
 

807 lines
22 KiB

////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
//
// TAPIDialer(tm) and ActiveDialer(tm) are trademarks of Active Voice Corporation.
//
// Other brand and product names used herein are trademarks of their respective owners.
//
// The entire program and user interface including the structure, sequence, selection,
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
// by "1" and "2," and each dialog message are protected by copyrights registered in
// the United States and by international treaties.
//
// Protected by one or more of the following United States patents: 5,070,526; 5,488,650;
// 5,434,906; 5,581,604; 5,533,102; 5,568,540, 5,625,676.
//
// Active Voice Corporation
// Seattle, Washington
// USA
//
/////////////////////////////////////////////////////////////////////////////////////////
/* $FILEHEADER
*
* FILE
* ConfInfo.cpp
*
* CLASS
* CConfInfo
*
* RESPONSIBILITIES
* Creates / Gathers info about a conference
*
*/
#include "ConfInfo.h"
#include <limits.h>
#include <mdhcp.h>
#include "winlocal.h"
#include "objsec.h"
#include "rndsec.h"
#include "res.h"
#include "ThreadPub.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
//#define new DEBUG_NEW
#endif
CConfInfo::CConfInfo()
{
// General properties
m_pITRend = NULL;
m_pITConf = NULL;
m_ppDirObject = NULL;
m_pSecDesc = NULL;
m_bSecuritySet = false;
m_bNewConference = false;
m_bDateTimeChange = false;
m_lScopeID = -1; // default is auto-select
m_bUserSelected = false; // the user doesn't select a scope
m_bDateChangeMessage = false; // wasn't show yet the message
// Conference Info
m_bstrName = NULL;
m_bstrDescription = NULL;
m_bstrOwner = NULL;
// Default start time is immediately, default end time is +30m
GetLocalTime( &m_stStartTime );
GetLocalTime( &m_stStopTime );
// Add 30 minutes to current time
DATE dateNow;
SystemTimeToVariantTime( &m_stStopTime, &dateNow );
dateNow += (DATE) (.25 / 12);
VariantTimeToSystemTime( dateNow, &m_stStopTime );
}
CConfInfo::~CConfInfo()
{
SysFreeString(m_bstrName);
SysFreeString(m_bstrDescription);
SysFreeString(m_bstrOwner);
if (m_pSecDesc)
m_pSecDesc->Release();
}
/****************************************************************************
* Init
* Stores the address of the ITRendezvous and ITDirectoryObjectConference interface
* pointers. When creating a new conference the calling function should set pITConf
* to NULL. When editing an existing conference, pITConf should point to the interface
* of the conference COM object.
*
* Return Value
* Returns the HRESULT from the Rendezvous functions
*
* Comments
*****************************************************************************/
HRESULT CConfInfo::Init(ITRendezvous *pITRend, ITDirectoryObjectConference *pITConf, ITDirectoryObject **ppDirObject, bool bNewConf )
{
HRESULT hr = 0;
m_pITRend = pITRend;
m_pITConf = pITConf;
m_bNewConference = (bool) (bNewConf || (m_pITConf == NULL));
// store the pointer to the directory object
m_ppDirObject = ppDirObject;
// Create a conference, or edit an existing one?
if ( m_pITConf )
{
// Start and stop time
m_pITConf->get_StartTime( &m_dateStart );
VariantTimeToSystemTime( m_dateStart, &m_stStartTime );
m_pITConf->get_StopTime( &m_dateStop );
VariantTimeToSystemTime( m_dateStop, &m_stStopTime );
// get the ITSdp interface
ITConferenceBlob *pITConferenceBlob;
if ( SUCCEEDED(hr = m_pITConf->QueryInterface(IID_ITConferenceBlob, (void **) &pITConferenceBlob)) )
{
ITSdp *pITSdp;
if ( SUCCEEDED(hr = pITConferenceBlob->QueryInterface(IID_ITSdp, (void **) &pITSdp)) )
{
pITSdp->get_Name( &m_bstrName );
pITSdp->get_Originator( &m_bstrOwner );
pITSdp->get_Description( &m_bstrDescription );
pITSdp->Release();
}
pITConferenceBlob->Release();
}
if ( SUCCEEDED(hr) )
{
// get the security descriptor for the directory object
if ( SUCCEEDED(hr = m_pITConf->QueryInterface(IID_ITDirectoryObject, (void **) m_ppDirObject)) )
{
hr = (*m_ppDirObject)->get_SecurityDescriptor( (IDispatch**) &m_pSecDesc );
// Clean up
(*m_ppDirObject)->Release();
*m_ppDirObject = NULL;
}
}
}
else
{
// Setup defaults for the new conference
SysFreeString( m_bstrOwner );
m_bstrOwner = NULL;
GetPrimaryUser( &m_bstrOwner );
}
return hr;
}
void CConfInfo::get_Name(BSTR *pbstrName)
{
*pbstrName = SysAllocString( m_bstrName );
}
void CConfInfo::put_Name(BSTR bstrName)
{
SysReAllocString(&m_bstrName, bstrName);
}
void CConfInfo::get_Description(BSTR *pbstrDescription)
{
*pbstrDescription = SysAllocString( m_bstrDescription );
}
void CConfInfo::put_Description(BSTR bstrDescription)
{
SysReAllocString(&m_bstrDescription, bstrDescription);
}
void CConfInfo::get_Originator(BSTR *pbstrOwner)
{
*pbstrOwner = SysAllocString( m_bstrOwner );
}
void CConfInfo::put_Originator(BSTR bstrOwner)
{
SysReAllocString(&m_bstrOwner, bstrOwner);
}
void CConfInfo::GetStartTime(USHORT *nYear, BYTE *nMonth, BYTE *nDay, BYTE *nHour, BYTE *nMinute)
{
*nYear = m_stStartTime.wYear;
*nMonth = (BYTE)m_stStartTime.wMonth;
*nDay = (BYTE)m_stStartTime.wDay;
*nHour = (BYTE)m_stStartTime.wHour;
*nMinute = (BYTE)m_stStartTime.wMinute;
}
void CConfInfo::SetStartTime(USHORT nYear, BYTE nMonth, BYTE nDay, BYTE nHour, BYTE nMinute)
{
m_stStartTime.wYear = nYear;
m_stStartTime.wMonth = nMonth;
m_stStartTime.wDay = nDay;
m_stStartTime.wHour = nHour;
m_stStartTime.wMinute = nMinute;
}
void CConfInfo::GetStopTime(USHORT *nYear, BYTE *nMonth, BYTE *nDay, BYTE *nHour, BYTE *nMinute)
{
*nYear = m_stStopTime.wYear;
*nMonth = (BYTE)m_stStopTime.wMonth;
*nDay = (BYTE)m_stStopTime.wDay;
*nHour = (BYTE)m_stStopTime.wHour;
*nMinute = (BYTE)m_stStopTime.wMinute;
}
void CConfInfo::SetStopTime(USHORT nYear, BYTE nMonth, BYTE nDay, BYTE nHour, BYTE nMinute)
{
m_stStopTime.wYear = nYear;
m_stStopTime.wMonth = nMonth;
m_stStopTime.wDay = nDay;
m_stStopTime.wHour = nHour;
m_stStopTime.wMinute = nMinute;
}
void CConfInfo::GetPrimaryUser(BSTR *pbstrTrustee)
{
HRESULT hr = S_OK;
TOKEN_USER *tokenUser = NULL;
HANDLE tokenHandle = NULL;
DWORD tokenSize = 0;
DWORD sidLength = 0;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
{
ATLTRACE(_T("OpenProcessToken failed\n"));
return;
}
// get the needed size for the tokenUser structure
else
{
GetTokenInformation(tokenHandle, TokenUser, tokenUser, 0, &tokenSize);
if ( tokenSize == 0)
{
CloseHandle( tokenHandle );
ATLTRACE(_T("GetTokenInformation failed"));
return;
}
else
{
// allocate the tokenUser structure
BYTE* pToken = new BYTE[tokenSize];
if( pToken == NULL )
{
ATLTRACE(_T("new tokenUser failed\n"));
CloseHandle( tokenHandle );
return;
}
// initialize the memory
memset( pToken, 0, sizeof(BYTE)*tokenSize);
// cast to the token user
tokenUser = (TOKEN_USER *)pToken;
// get the tokenUser info for the current process
if (!GetTokenInformation(tokenHandle, TokenUser, tokenUser, tokenSize, &tokenSize))
{
CloseHandle( tokenHandle );
delete [] pToken;
pToken = NULL;
tokenUser = NULL;
ATLTRACE(_T("GetTokenInformation failed\n"));
return;
}
else
{
TCHAR domainName [256];
TCHAR userName [256];
DWORD nameLength;
SID_NAME_USE snu;
nameLength = 255;
if (!LookupAccountSid(NULL,
tokenUser->User.Sid,
userName,
&nameLength,
domainName,
&nameLength,
&snu))
{
ATLTRACE(_T("LookupAccountSid failed (0x%08lx)\n"),hr);
}
else
{
USES_CONVERSION;
SysReAllocString(pbstrTrustee, T2OLE(userName));
}
CloseHandle (tokenHandle);
delete [] pToken;
pToken = NULL;
tokenUser = NULL;
}
}
}
}
/****************************************************************************
* Commit
* Creates / Modifies the actual conference.
*
* Return Value
* Returns the HRESULT from the Rendezvous functions
*
* Comments
*****************************************************************************/
HRESULT CConfInfo::CommitGeneral(DWORD& dwCommitError)
{
HRESULT hr = E_FAIL;
dwCommitError = CONF_COMMIT_ERROR_GENERALFAILURE;
bool bNewMDHCP = true;
bool bNewConf = IsNewConference();
HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
// Are we creating a conference from scratch?
if ( !m_pITConf )
{
// Need to create a conference
if ( SUCCEEDED(hr = m_pITRend->CreateDirectoryObject(OT_CONFERENCE, m_bstrName, m_ppDirObject)) && *m_ppDirObject )
{
if ( FAILED(hr = (*m_ppDirObject)->QueryInterface(IID_ITDirectoryObjectConference, (void **) &m_pITConf)) )
ATLTRACE(_T("(*m_ppDirObject)->QueryInterface(IID_ITDirectoryObjectConference... failed (0x%08lx)\n"),hr);
(*m_ppDirObject)->Release();
*m_ppDirObject = NULL;
}
else
{
ATLTRACE(_T("CreateDirectoryObject failed (0x%08lx)\n"),hr);
}
}
// Should we create a new MDHCP IP address lease?
DATE dateStart, dateStop;
SystemTimeToVariantTime( &m_stStartTime, &dateStart );
SystemTimeToVariantTime( &m_stStopTime, &dateStop );
if ( !bNewConf && (dateStart == m_dateStart) && (dateStop == m_dateStop) )
{
ATLTRACE(_T("CConfInfo::CommitGeneral() -- not changing the MDHCP address for the conf.\n"));
bNewMDHCP = false;
}
// set the conference attributes
if ( m_pITConf )
{
ITConferenceBlob *pITConferenceBlob = NULL;
ITSdp *pITSdp = NULL;
DATE vtime;
// Retrieve the owner for the conference
if ( !m_bstrOwner )
GetPrimaryUser( &m_bstrOwner );
// set the conference start time
if (FAILED(hr = SystemTimeToVariantTime(&m_stStartTime, &vtime)))
{
dwCommitError = CONF_COMMIT_ERROR_INVALIDDATETIME;
ATLTRACE(_T("SystemTimeToVariantTime failed (0x%08lx)\n"),hr);
}
else if (FAILED(hr = m_pITConf->put_StartTime(vtime)))
{
dwCommitError = CONF_COMMIT_ERROR_INVALIDDATETIME;
ATLTRACE(_T("put_StartTime failed (0x%08lx)\n"),hr);
}
// set the conference stop time
else if (FAILED(hr = SystemTimeToVariantTime(&m_stStopTime, &vtime)))
{
dwCommitError = CONF_COMMIT_ERROR_INVALIDDATETIME;
ATLTRACE(_T("SystemTimeToVariantTime failed (0x%08lx)\n"),hr);
}
else if (FAILED(hr = m_pITConf->put_StopTime(vtime)))
{
dwCommitError = CONF_COMMIT_ERROR_INVALIDDATETIME;
ATLTRACE(_T("put_StopTime failed (0x%08lx)\n"),hr);
}
// get the ITSdp interface
else if ( SUCCEEDED(hr = m_pITConf->QueryInterface(IID_ITConferenceBlob, (void **) &pITConferenceBlob)) )
{
if ( SUCCEEDED(hr = pITConferenceBlob->QueryInterface(IID_ITSdp, (void **) &pITSdp)) )
{
// set the owner of the conference
if (FAILED(hr = pITSdp->put_Originator(m_bstrOwner)))
{
dwCommitError = CONF_COMMIT_ERROR_INVALIDOWNER;
ATLTRACE(_T("put_Originator failed (0x%08lx)\n"),hr);
}
// set the conference description
else if (FAILED(hr = pITSdp->put_Description(m_bstrDescription)))
{
dwCommitError = CONF_COMMIT_ERROR_INVALIDDESCRIPTION;
ATLTRACE(_T("put_Description failed (0x%08lx)\n"),hr);
}
else if ( bNewMDHCP && FAILED(hr = CreateMDHCPAddress(pITSdp, &m_stStartTime, &m_stStopTime, m_lScopeID, m_bUserSelected)) )
{
dwCommitError = CONF_COMMIT_ERROR_MDHCPFAILED;
ATLTRACE(_T("CreateMDHCPAddress failed (0x%08lx)\n"), hr );
}
// if this was an existing conference then allow for changing the name
else if ( bNewConf )
{
if (FAILED(hr = pITSdp->put_Name(m_bstrName)))
{
dwCommitError = CONF_COMMIT_ERROR_INVALIDNAME;
ATLTRACE(_T("put_Name failed (0x%08lx)\n"),hr);
}
}
pITSdp->Release();
}
pITConferenceBlob->Release();
}
else
{
dwCommitError = CONF_COMMIT_ERROR_GENERALFAILURE;
ATLTRACE(_T("m_pITConf->QueryInterface(IID_ITConferenceBlob... failed (0x%08lx)\n"),hr);
}
}
SetCursor( hCurOld );
return hr;
}
HRESULT CConfInfo::CommitSecurity(DWORD& dwCommitError, bool bCreate)
{
HRESULT hr = E_FAIL;
dwCommitError = CONF_COMMIT_ERROR_GENERALFAILURE;
HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
if ( m_pITConf )
{
if (SUCCEEDED(hr = m_pITConf->QueryInterface(IID_ITDirectoryObject, (void **) m_ppDirObject)) && *m_ppDirObject)
{
// Setup the default conference security
if ( !m_pSecDesc )
{
hr = CoCreateInstance( CLSID_SecurityDescriptor,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsSecurityDescriptor,
(void **) &m_pSecDesc );
// Add default settings if successfully created the ACE
if ( SUCCEEDED(hr) )
hr = AddDefaultACEs( bCreate );
}
// if we created a new security descriptor for the conference, then save it
if ( m_pSecDesc )
{
if (FAILED(hr = (*m_ppDirObject)->put_SecurityDescriptor((IDispatch *)m_pSecDesc)))
{
dwCommitError = CONF_COMMIT_ERROR_INVALIDSECURITYDESCRIPTOR;
ATLTRACE(_T("put_SecurityDescriptor failed (0x%08lx)\n"),hr);
}
}
}
else
{
ATLTRACE(_T("m_pITConf->QueryInterface(IID_ITDirectoryObject... failed (0x%08lx)\n"),hr);
}
}
SetCursor( hCurOld );
return hr;
}
/////////////////////////////////////////////////////////////////////////////////
// MDHCP support
//
bool CConfInfo::PopulateListWithMDHCPScopeDescriptions( HWND hWndList )
{
USES_CONVERSION;
if ( !IsWindow(hWndList) ) return false;
// First create the MDHCP wrapper object
int nScopeCount = 0;
IMcastAddressAllocation *pIMcastAddressAllocation;
HRESULT hr = CoCreateInstance( CLSID_McastAddressAllocation,
NULL,
CLSCTX_INPROC_SERVER,
IID_IMcastAddressAllocation,
(void **) &pIMcastAddressAllocation );
if ( SUCCEEDED(hr) )
{
IEnumMcastScope *pEnum = NULL;
if ( SUCCEEDED(hr = pIMcastAddressAllocation->EnumerateScopes(&pEnum)) )
{
// Clear out list
SendMessage( hWndList, LB_RESETCONTENT, 0, 0 );
IMcastScope *pScope = NULL;
while ( SUCCEEDED(hr) && ((hr = pEnum->Next(1, &pScope, NULL)) == S_OK) && pScope )
{
if ( IsWindow(hWndList) )
{
// Retrieve scope information
long lScopeID;
BSTR bstrDescription = NULL;
pScope->get_ScopeDescription( &bstrDescription );
pScope->get_ScopeID( &lScopeID );
ATLTRACE(_T(".1.CConfInfo::CreateMDHCPAddress() scope ID = %ld, description is %s.\n"), lScopeID, bstrDescription );
// Add information to list box
long nIndex = SendMessage(hWndList, LB_ADDSTRING, 0, (LPARAM) OLE2CT(bstrDescription));
if ( nIndex >= 0 )
{
nScopeCount++;
SendMessage(hWndList, LB_SETITEMDATA, nIndex, (LPARAM) lScopeID );
}
SysFreeString( bstrDescription );
}
else
{
hr = E_ABORT;
}
// Clean up
pScope->Release();
pScope = NULL;
}
pEnum->Release();
}
pIMcastAddressAllocation->Release();
}
// Select first item in the list
if ( SUCCEEDED(hr) && (nScopeCount > 0) )
{
SendMessage( hWndList, LB_SETCURSEL, 0, 0 );
EnableWindow( hWndList, TRUE );
}
else if ( IsWindow(hWndList) )
{
MessageBox(GetParent(hWndList), String(g_hInstLib, IDS_CONFPROP_SCOPEENUMFAILED), NULL, MB_OK | MB_ICONEXCLAMATION );
}
return (bool) (hr == S_OK);
}
HRESULT CConfInfo::CreateMDHCPAddress( ITSdp *pSdp, SYSTEMTIME *pStart, SYSTEMTIME *pStop, long lScopeID, bool bUserSelected )
{
_ASSERT( pSdp && pStart && pStop );
// First create the MDHCP wrapper object
IMcastAddressAllocation *pIMcastAddressAllocation;
HRESULT hr = CoCreateInstance( CLSID_McastAddressAllocation,
NULL,
CLSCTX_INPROC_SERVER,
IID_IMcastAddressAllocation,
(void **) &pIMcastAddressAllocation );
if ( SUCCEEDED(hr) )
{
ITMediaCollection *pMC = NULL;
if ( SUCCEEDED(hr = pSdp->get_MediaCollection(&pMC)) && pMC )
{
long lMCCount = 0;
pMC->get_Count( &lMCCount );
IEnumMcastScope *pEnum = NULL;
if ( SUCCEEDED(hr = pIMcastAddressAllocation->EnumerateScopes(&pEnum)) )
{
hr = E_FAIL;
// Try scopes until you run out or succeed
long lCount = 1;
IMcastScope *pScope = NULL;
while ( FAILED(hr) && ((hr = pEnum->Next(1, &pScope, NULL)) == S_OK) && pScope )
{
// If the scope ID has been specified, make sure that this scope matches
if ( bUserSelected )
{
long lID;
pScope->get_ScopeID(&lID);
if ( lID != lScopeID )
{
hr = E_FAIL;
pScope->Release();
continue;
}
}
DATE dateStart, dateStop;
SystemTimeToVariantTime( pStart, &dateStart );
SystemTimeToVariantTime( pStop, &dateStop );
// Need to assign addresses to all media collections for the conference
while ( SUCCEEDED(hr) && (lCount <= lMCCount) )
{
IMcastLeaseInfo *pInfo = NULL;
hr = pIMcastAddressAllocation->RequestAddress( pScope, dateStart, dateStop, 1, &pInfo );
if ( SUCCEEDED(hr) && pInfo )
{
unsigned char nTTL = 15;
long lTemp;
if ( SUCCEEDED(pInfo->get_TTL(&lTemp)) && (lTemp >= 0) && (lTemp <= UCHAR_MAX) )
nTTL = (unsigned char) nTTL;
IEnumBstr *pEnumAddr = NULL;
if ( SUCCEEDED(hr = pInfo->EnumerateAddresses(&pEnumAddr)) && pEnumAddr )
{
BSTR bstrAddress = NULL;
// Must set addressess for all media types on the conference
if ( SUCCEEDED((hr = pEnumAddr->Next(1, &bstrAddress, NULL))) && bstrAddress && SysStringLen(bstrAddress) )
{
hr = SetMDHCPAddress( pMC, bstrAddress, lCount, nTTL );
lCount++;
}
SysFreeString( bstrAddress );
pEnumAddr->Release();
}
}
}
// Clean up
pScope->Release();
pScope = NULL;
// Try with just one scope
if( FAILED( hr ) &&
(bUserSelected == false) )
break;
}
// Convert to failure
if ( hr == S_FALSE ) hr = E_FAIL;
pEnum->Release();
}
pMC->Release();
}
pIMcastAddressAllocation->Release();
}
return hr;
}
HRESULT CConfInfo::SetMDHCPAddress( ITMediaCollection *pMC, BSTR bstrAddress, long lCount, unsigned char nTTL )
{
_ASSERT( pMC && bstrAddress && (lCount > 0) );
HRESULT hr;
ITMedia *pMedia = NULL;
if ( SUCCEEDED(hr = pMC->get_Item(lCount, &pMedia)) && pMedia )
{
ITConnection *pITConn = NULL;
if ( SUCCEEDED(hr = pMedia->QueryInterface(IID_ITConnection, (void **) &pITConn)) && pITConn )
{
hr = pITConn->SetAddressInfo( bstrAddress, 1, nTTL );
pITConn->Release();
}
pMedia->Release();
}
return hr;
}
HRESULT CConfInfo::AddDefaultACEs( bool bCreate )
{
HRESULT hr = S_OK;
bool bOwner = false, bWorld = false;
PACL pACL = NULL;
PSID pSidWorld = NULL;
DWORD dwAclSize = sizeof(ACL), dwTemp;
BSTR bstrTemp = NULL;
LPWSTR pszTemp = NULL;
HANDLE hToken;
UCHAR *pInfoBuffer = NULL;
DWORD cbInfoBuffer = 512;
// Only create owner ACL if requested
if ( bCreate )
{
if( !OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken) )
{
if( GetLastError() == ERROR_NO_TOKEN )
{
// attempt to open the process token, since no thread token exists
if( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) )
return E_FAIL;
}
else
{
// error trying to get thread token
return E_FAIL;
}
}
// Loop until we have a large enough structure
while ( (pInfoBuffer = new UCHAR[cbInfoBuffer]) != NULL )
{
if ( !GetTokenInformation(hToken, TokenUser, pInfoBuffer, cbInfoBuffer, &cbInfoBuffer) )
{
delete pInfoBuffer;
pInfoBuffer = NULL;
if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
return E_FAIL;
}
else
{
break;
}
}
CloseHandle(hToken);
// Did we get the owner ACL?
if ( pInfoBuffer )
{
INC_ACCESS_ACL_SIZE( dwAclSize, ((PTOKEN_USER) pInfoBuffer)->User.Sid );
bOwner = true;
}
}
// Make SID for "Everyone"
SysReAllocString( &bstrTemp, L"S-1-1-0" );
hr = ConvertStringToSid( bstrTemp, &pSidWorld, &dwTemp, &pszTemp );
if ( SUCCEEDED(hr) )
{
INC_ACCESS_ACL_SIZE( dwAclSize, pSidWorld );
bWorld = true;
}
////////////////////////////////////
// Create the ACL containing the Owner and World ACEs
pACL = (PACL) new BYTE[dwAclSize];
if ( pACL )
{
BAIL_ON_BOOLFAIL( InitializeAcl(pACL, dwAclSize, ACL_REVISION) );
// Add World Rights
if ( bWorld )
{
if ( bOwner )
{
BAIL_ON_BOOLFAIL( AddAccessAllowedAce(pACL, ACL_REVISION, ACCESS_READ, pSidWorld) );
}
else
{
BAIL_ON_BOOLFAIL( AddAccessAllowedAce(pACL, ACL_REVISION, ACCESS_ALL , pSidWorld) );
}
}
// Add Creator rights
if ( bOwner )
BAIL_ON_BOOLFAIL( AddAccessAllowedAce(pACL, ACL_REVISION, ACCESS_ALL, ((PTOKEN_USER) pInfoBuffer)->User.Sid) );
// Set the DACL onto our security descriptor
VARIANT varDACL;
VariantInit( &varDACL );
if ( SUCCEEDED(hr = ConvertACLToVariant((PACL) pACL, &varDACL)) )
{
if ( SUCCEEDED(hr = m_pSecDesc->put_DaclDefaulted(FALSE)) )
hr = m_pSecDesc->put_DiscretionaryAcl( V_DISPATCH(&varDACL) );
}
VariantClear( &varDACL );
}
else
{
hr = E_OUTOFMEMORY;
}
// Clean up
failed:
SysFreeString( bstrTemp );
if ( pACL ) delete pACL;
if ( pSidWorld ) delete pSidWorld;
if ( pInfoBuffer ) delete pInfoBuffer;
return hr;
}