/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/ /**********************************************************************/ /* AcsData.cpp Implement DataObject classes used in ACS FILE HISTORY: 11/11/97 Wei Jiang Created */ #include "stdafx.h" #include "resource.h" // main symbol definition #include "helper.h" #include "acsdata.h" #include "acshand.h" /////////////////////////////////////////////////////////////////////////////// // // CDSIDataObject // // unsigned int CDSIDataObject::m_cfDsObjectNames = RegisterClipboardFormat(CFSTR_DSOBJECTNAMES); //+---------------------------------------------------------------------------- // // Method: CDSIDataObject::IDataObject::GetData // // Synopsis: Returns data, in this case the Prop Page format data. // //----------------------------------------------------------------------------- STDMETHODIMP CDSIDataObject::GetData(FORMATETC * pFormatEtc, STGMEDIUM * pMedium) { HRESULT hr = S_OK; TRACE(_T("CDSIDataObject::GetData\n")); USES_CONVERSION; if (IsBadWritePtr(pMedium, sizeof(STGMEDIUM))) { return E_INVALIDARG; } if (!(pFormatEtc->tymed & TYMED_HGLOBAL)) { return DV_E_TYMED; } if (pFormatEtc->cfFormat == m_cfDsObjectNames) { if(!m_bstrADsPath || !m_bstrClass) return DV_E_FORMATETC; // Return the object name and class. // LPCTSTR szPath = W2T(m_bstrADsPath); LPCTSTR szClass = W2T(m_bstrClass); int cbPath = sizeof(TCHAR) * (_tcslen(szPath) + 1); int cbClass = sizeof(TCHAR) * (_tcslen(szClass) + 1); int cbStruct = sizeof(DSOBJECTNAMES); LPDSOBJECTNAMES pDSObj; pDSObj = (LPDSOBJECTNAMES)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, cbStruct + cbPath + cbClass); if (pDSObj == NULL) { return STG_E_MEDIUMFULL; } pDSObj->clsidNamespace = CLSID_MicrosoftDS; pDSObj->cItems = 1; pDSObj->aObjects[0].offsetName = cbStruct; pDSObj->aObjects[0].offsetClass = cbStruct + cbPath; _tcscpy((LPTSTR)((BYTE *)pDSObj + cbStruct), szPath); _tcscpy((LPTSTR)((BYTE *)pDSObj + cbStruct + cbPath), szClass); pMedium->hGlobal = (HGLOBAL)pDSObj; hr = S_OK; } else hr = CDataObject::GetData(pFormatEtc, pMedium); return S_OK; } /////////////////////////////////////////////////////////////////////////////// // // CDSObject // // CDSObject::CDSObject(bool bNoRefCountOnContainer) : m_bstrADsPath(NULL), m_bstrClass(NULL), m_bstrName(NULL), m_bNewCreated(false), m_bOpened(false), m_pHandle(NULL), m_dwState(0), m_bNoRefCountOnContainer(bNoRefCountOnContainer) { m_dwAttributeFlags[ATTR_FLAG_LOAD] = 0; m_dwAttributeFlags[ATTR_FLAG_SAVE] = 0; } CDSObject::~CDSObject() { Close(); if(m_bNoRefCountOnContainer) m_spContainer.p = NULL; else m_spContainer.Release(); SysFreeString(m_bstrClass); m_bstrClass = NULL; SysFreeString(m_bstrName); m_bstrName = NULL; } //+---------------------------------------------------------------------------- // // Method: CDSObject::Delete // // Synopsis: Delete the object from DS // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::Delete() { HRESULT hr = S_OK; BSTR strThisRDN = NULL; BSTR strThisCls = NULL; CComPtr spContainer; CComPtr spContainerIADs; if(!(CDSObject*)m_spContainer) return S_FALSE; AFX_MANAGE_STATE(AfxGetStaticModuleState()); CHECK_HR(hr = Reopen()); hr = m_spIADs->QueryInterface(IID_IADsContainer, (void**)&spContainer); if(hr == S_OK) // it's a container { CComPtr spEnum; CComPtr spChild; CComPtr spDisp; CComObject* pDSObj = NULL; CComPtr spDSObj; VARIANT var; VariantInit(&var); CHECK_HR(hr = ADsBuildEnumerator(spContainer, &spEnum)); while(S_OK == (hr = ADsEnumerateNext(spEnum, 1, &var, NULL))) { spDisp = var.pdispVal; spChild.Release(); // make sure spChild is NULL CHECK_HR(hr = spDisp->QueryInterface(IID_IADs, (VOID **)&spChild)); // if this object is a profile object // create the object spDSObj.Release(); // make sure it's NULL CHECK_HR(hr = CComObject::CreateInstance(&pDSObj)); // with 0 reference count spDSObj = pDSObj; CHECK_HR(hr = spDSObj->Attach(this, spChild)); // delete spDSObj->Delete(); } spContainer.Release(); } CHECK_HR(hr = m_spIADs->get_Name (&strThisRDN)); CHECK_HR(hr = m_spIADs->get_Class (&strThisCls)); m_spIADs.Release(); m_spContainer->GetIADs(&spContainerIADs); CHECK_HR(hr = spContainerIADs->QueryInterface(IID_IADsContainer, (void**)&spContainer)); ASSERT((IADsContainer*)spContainer); CHECK_HR(hr = spContainer->Delete(strThisCls, strThisRDN)); m_spContainer->RemoveChild(this); L_ERR: SysFreeString(strThisRDN); SysFreeString(strThisCls); return hr; } //+---------------------------------------------------------------------------- // // Method: CDSObject::Rename // // Synopsis: Rename the object within the save container // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::Rename(LPCWSTR szName) { HRESULT hr = S_OK; DWORD result; CString AttrName; CString str; CComPtr spDispObj; CComPtr spADs; CComPtr spIContainer; // if we didn't create it, we don't delete it if(!(CDSObject*)m_spContainer) return S_FALSE; AttrName = L"cn="; AttrName += szName; TRACE(_T("CDSObject::Rename: Attributed name is %s.\n"), AttrName); m_spIADs.Release(); // get container's IADs interface CHECK_HR(hr = m_spContainer->GetIADs(&spADs)); // get containers's IADsContainer interface CHECK_HR(hr = spADs->QueryInterface(IID_IADsContainer, (void**)&spIContainer)); ASSERT((IADsContainer*)spIContainer); CHECK_HR(hr = Reopen()); // make sure m_bADsPath is set str = m_bstrADsPath; CHECK_HR(hr = Close()); // close it before rename CHECK_HR(hr = spIContainer->MoveHere((LPWSTR)(LPCWSTR)str, (LPWSTR)(LPCWSTR)AttrName, &spDispObj)); CHECK_HR(hr = spDispObj->QueryInterface (IID_IADs, (void **)&m_spIADs)); ASSERT((IADs*)m_spIADs); SysFreeString(m_bstrName); CHECK_HR(hr = m_spIADs->get_Name(&m_bstrName)); m_spIADs.Release(); L_ERR: return hr; } //+---------------------------------------------------------------------------- // // Method: CDSObject::Save // // Synopsis: Save the object to DS // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::Save(DWORD dwAttrFlags) { HRESULT hr; if((IADs*)m_spIADs) { CHECK_HR(hr = OnSave(dwAttrFlags)); // any additional processing before save CHECK_HR(hr = m_spIADs->SetInfo()); // save other things CHECK_HR(hr = SaveAttributes(dwAttrFlags)); // save attributes } else hr = S_FALSE; L_ERR: return hr; } //+---------------------------------------------------------------------------- // // Method: CDSObject::SetInfo // // Synopsis: Set necessary information for Reopen // //----------------------------------------------------------------------------- //?? STDMETHODIMP CDSObject::SetInfo ( CDSObject* pContainer, // container, when NULL, objName is fullpath LPCWSTR clsName, // class name LPCWSTR objName // object name, ignored when container == NULL ) { HRESULT hr = S_OK; if(m_bNoRefCountOnContainer) m_spContainer.p = pContainer; else m_spContainer = pContainer; try{ SysFreeString(m_bstrClass); m_bstrClass = NULL; m_bstrClass = SysAllocString(clsName); CString cnName = L"cn="; cnName += objName; SysFreeString(m_bstrName); m_bstrName = NULL; m_bstrName = SysAllocString(cnName); }catch(CMemoryException&){ CHECK_HR(hr = E_OUTOFMEMORY); } L_ERR: return hr; } //+---------------------------------------------------------------------------- // // Method: CDSObject::Open // // Synopsis: Open an object in DS, create one when necessary // //----------------------------------------------------------------------------- //?? STDMETHODIMP CDSObject::Open ( CDSObject* pContainer, // container, when NULL, objName is fullpath LPCWSTR clsName, // class name LPCWSTR objName, // object name, ignored when container == NULL bool bCreateIfNonExist, // [in, out] if create bool bPersistWhenCreate ) { HRESULT hr = S_OK; CComPtr spIADs; CComPtr spIDisp; CComPtr spIContainer; bool bCallSave = false; DWORD dwAttrFlags = 0; if(!pContainer) // if container is not specified { CHECK_HR(hr = ADsOpenObject((LPWSTR)objName, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_USE_SIGNING | ADS_USE_SEALING, IID_IADs, (void**)&spIADs)); ASSERT((IADs*)spIADs); } else // open/create within container { // get container's ADSI CHECK_HR(hr = pContainer->GetIADs(&spIADs)); ASSERT((IADs*)spIADs); CHECK_HR(spIADs->QueryInterface(IID_IADsContainer, (void**)&spIContainer)); ASSERT((IADsContainer*)spIContainer); CString cnName = objName; cnName.TrimLeft(); // if cn= is already in the string if(cnName.GetLength() < 4 || cnName[2] != _T('=') || (cnName[0] != _T('c') && cnName[0] != _T('C')) || (cnName[1] != _T('n') && cnName[1] != _T('N'))) { cnName = _T("cn="); cnName += objName; } // if it cannot open hr = spIContainer->GetObject((LPWSTR)clsName, (LPWSTR)(LPCWSTR)cnName, &spIDisp); spIADs.Release(); if(S_OK == hr) { ASSERT((IDispatch*)spIDisp); spIDisp->QueryInterface(IID_IADs, (void**)&spIADs); ASSERT((IADs*)spIADs); } else // the object cannot be open { if(!bCreateIfNonExist) goto L_ERR; // create one if not exist CHECK_HR(spIContainer->Create((LPWSTR)clsName,(LPWSTR)(LPCWSTR)cnName, &spIDisp)); ASSERT((IDispatch*)spIDisp); spIDisp->QueryInterface(IID_IADs, (void**)&spIADs); ASSERT((IADs*)spIADs); CHECK_HR(hr = OnCreate(&dwAttrFlags)); // callback function to do something for open // persist the object if(bPersistWhenCreate) bCallSave = true; m_bNewCreated = true; } } if(m_bNoRefCountOnContainer) m_spContainer.p = pContainer; else m_spContainer = pContainer; m_spIADs = (IADs*)spIADs; SysFreeString(m_bstrADsPath); m_bstrADsPath = NULL; CHECK_HR(hr = m_spIADs->get_ADsPath(&m_bstrADsPath)); SysFreeString(m_bstrClass); m_bstrClass = NULL; CHECK_HR(hr = m_spIADs->get_Class(&m_bstrClass)); SysFreeString(m_bstrName); m_bstrName = NULL; CHECK_HR(hr = m_spIADs->get_Name(&m_bstrName)); // if new created and need to save if(bCallSave) CHECK_HR(hr = Save(dwAttrFlags)); CHECK_HR(hr = OnOpen()); // callback function to do something for open CHECK_HR(hr = LoadAttributes()); // loadin attributes m_bOpened = true; L_ERR: return hr; } //+---------------------------------------------------------------------------- // // Method: CDSObject::Reopen // // Synopsis: Reopen an object in DS // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::Reopen() { HRESULT hr = S_OK; CComPtr spIDisp; CComPtr spIADs; CComPtr spIContainer; // this must be pre opened, or created ASSERT((CDSObject*)m_spContainer); ASSERT(m_bstrName); ASSERT(m_bstrClass); // close it, if the object was representing another DS object Close(); // get container's ADSI CHECK_HR(hr = m_spContainer->GetIADs(&spIADs)); ASSERT((IADs*)spIADs); CHECK_HR(spIADs->QueryInterface(IID_IADsContainer, (void**)&spIContainer)); ASSERT((IADsContainer*)spIContainer); // if it cannot open CHECK_HR(hr = spIContainer->GetObject((LPWSTR)m_bstrClass, m_bstrName, &spIDisp)); ASSERT((IDispatch*)spIDisp); if(!(IADs*)m_spIADs) spIDisp->QueryInterface(IID_IADs, (void**)&m_spIADs); ASSERT((IADs*)m_spIADs); CHECK_HR(hr = m_spIADs->get_ADsPath(&m_bstrADsPath)); CHECK_HR(hr = OnOpen()); // callback function to do something for open CHECK_HR(hr = LoadAttributes()); // loadin attributes m_bOpened = true; L_ERR: return hr; } //+---------------------------------------------------------------------------- // // Method: CDSObject::Attach // // Synopsis: Open an object in DS, create one when necessary // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::Attach ( CDSObject* pContainer, // container, when NULL, objName is fullpath IADs* pIObject // adsi interface for this object ) { ASSERT(pIObject); // no joke HRESULT hr = S_OK; ASSERT(!m_bstrName); // the object should never be opened before if(m_bNoRefCountOnContainer) m_spContainer.p = pContainer; else m_spContainer = pContainer; m_spIADs = pIObject; CHECK_HR(hr = OnOpen()); // callback function to do something for open CHECK_HR(hr = LoadAttributes()); // loadin attributes CHECK_HR(hr = m_spIADs->get_ADsPath(&m_bstrADsPath)); CHECK_HR(hr = m_spIADs->get_Class(&m_bstrClass)); CHECK_HR(hr = m_spIADs->get_Name(&m_bstrName)); m_bOpened = true; L_ERR: return hr; } //+---------------------------------------------------------------------------- // // Method: CDSObject::Close // // Synopsis: Release pointers, free space // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::Close() { m_spIADs.Release(); SysFreeString(m_bstrADsPath); m_bstrADsPath = NULL; m_bOpened = false; return S_OK; } //+---------------------------------------------------------------------------- // // Method: CDSObject::GetString // // Synopsis: GetIADs of the object, reference is increased by 1 // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::GetString(CString& str, int nCol) { USES_CONVERSION; switch(nCol) { case 0: // name field str = GetName(); return S_OK; default: str = _T(" "); return S_OK; } } //+---------------------------------------------------------------------------- // // Method: CDSObject::GetIADs // // Synopsis: GetIADs of the object, reference is increased by 1 // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::GetIADs(IADs** ppIADs) { HRESULT hr = S_OK; bool bNeedClose = false; if(!(IADs*)m_spIADs) { CHECK_HR(hr = Reopen()); bNeedClose = true; ASSERT((IADs*)m_spIADs); } *ppIADs = (IADs*)m_spIADs; if(*ppIADs) (*ppIADs)->AddRef(); if(bNeedClose) CHECK_HR(hr = Close()); L_ERR: return hr; } //+---------------------------------------------------------------------------- // // Method: CDSObject::SaveAttributes // // Synopsis: Save attributes to DS according to the flags // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::SaveAttributes(DWORD dwAttrFlags) { CDSAttribute* pAttr = GetAttributes(); if(!pAttr) return S_OK; // when no attribute to save HRESULT hr = S_OK; CDSAttributeInfo* pInfo; CComPtr spDirObj; ADS_ATTR_INFO aADsAttrInfos[MAX_ATTRIBUTES]; ADSVALUE aADsValues[MAX_ATTRIBUTES]; ZeroMemory(aADsAttrInfos, sizeof(aADsAttrInfos)); ZeroMemory(aADsValues, sizeof(aADsValues)); DWORD count = 0; while(pAttr->pInfo) { ASSERT(count < MAX_ATTRIBUTES); // make sure it's in the range if(dwAttrFlags & pAttr->pInfo->flag) // if the attribute should be saved { pInfo = pAttr->pInfo; // clear this attribute -- remove it if(GetFlags(ATTR_FLAG_SAVE, pInfo->flag) == 0) { // when need to delete if(GetFlags(ATTR_FLAG_LOAD, pInfo->flag) != 0) { SetFlags(ATTR_FLAG_LOAD, pInfo->flag, false); aADsAttrInfos[count].pszAttrName = pInfo->name; aADsAttrInfos[count].dwADsType = pInfo->type; aADsAttrInfos[count].dwNumValues = 0; aADsAttrInfos[count].dwControlCode = ADS_ATTR_CLEAR; aADsAttrInfos[count].pADsValues = NULL; count++; } // else doesn't exist in DS, need to do nothing } else // need to save it { SetFlags(ATTR_FLAG_LOAD, pInfo->flag, true); aADsAttrInfos[count].pszAttrName = pInfo->name; aADsAttrInfos[count].dwADsType = pInfo->type; aADsAttrInfos[count].dwNumValues = 1; aADsAttrInfos[count].dwControlCode = ADS_ATTR_UPDATE; aADsAttrInfos[count].pADsValues = aADsValues + count; aADsValues[count].dwType = pInfo->type; switch(pInfo->type) { case ADSTYPE_BOOLEAN: aADsValues[count].Boolean = *(ADS_BOOLEAN*)pAttr->pBuffer; break; case ADSTYPE_INTEGER: aADsValues[count].Integer = *(ADS_INTEGER*)pAttr->pBuffer; break; case ADSTYPE_LARGE_INTEGER: aADsValues[count].LargeInteger = *(ADS_LARGE_INTEGER*)pAttr->pBuffer; break; case ADSTYPE_CASE_IGNORE_STRING: case ADSTYPE_CASE_EXACT_STRING: case ADSTYPE_PRINTABLE_STRING: if(pInfo->ifMultiValued) // expect the buffer to be a StrArray pointer { // with current set of attributes, only one is possible CStrArray* pArray = (CStrArray*)(pAttr->pBuffer); ASSERT(pArray); // must be some mistake in code, types don't match ADSVALUE* pValue; aADsAttrInfos[count].dwNumValues = pArray->GetSize(); ASSERT(aADsAttrInfos[count].dwNumValues); if(aADsAttrInfos[count].dwNumValues > 1) { try{ aADsAttrInfos[count].pADsValues = (ADSVALUE*)_alloca(sizeof(ADSVALUE) * aADsAttrInfos[count].dwNumValues); } catch(...) { CHECK_HR(hr = E_OUTOFMEMORY); } } pValue = aADsAttrInfos[count].pADsValues; // when need to support REAL multi-valued attribute, the way how aADsAttrInfos is allocated needs to change for(int i = 0; i < pArray->GetSize(); i++, pValue++) { pValue->CaseIgnoreString = T2W((LPTSTR)(LPCTSTR)*(pArray->GetAt(i))); pValue->dwType = pInfo->type; } } else // NOT multivalued CString pointer { CString* pStr = NULL; pStr = (CString*)(pAttr->pBuffer); ASSERT(pStr); if(pStr && pStr->GetLength()) aADsValues[count].CaseIgnoreString = T2W((LPTSTR)(LPCTSTR)*pStr); else aADsValues[count].CaseIgnoreString = NULL; } break; default: // other types are not supported // need to make some changes when adding new types ASSERT(0); break; } count++; } } pAttr++; }; if (!count) // there is no attribute to load return hr; // load the attributes ASSERT((IADs*)m_spIADs); CHECK_HR( hr = m_spIADs->QueryInterface(IID_IDirectoryObject, (void**)&spDirObj)); ASSERT((IDirectoryObject*)spDirObj); CHECK_HR(hr = spDirObj->SetObjectAttributes(aADsAttrInfos, count, &count)); L_ERR: return hr; } HRESULT CDSObject::SetState(DWORD state) { if(state == m_dwState) return S_OK; m_dwState = state; if(m_pHandle) return m_pHandle->ShowState(state); else return S_OK; }; //+---------------------------------------------------------------------------- // // Method: CDSObject::LoadAttributes // // Synopsis: Load attributes from DS and set flags to indicate the presence // //----------------------------------------------------------------------------- STDMETHODIMP CDSObject::LoadAttributes() { CDSAttribute* pAttr = GetAttributes(); if(!pAttr) return S_OK; // when no attribute to read HRESULT hr = S_OK; CDSAttributeInfo* pInfo; CComPtr spDirObj; LPWSTR aAttriNames[MAX_ATTRIBUTES]; ADS_ATTR_INFO* pADsAttrInfo = NULL; DWORD count = 0; while(pAttr->pInfo) { pInfo = pAttr->pInfo; // clear the flag of this attribute SetFlags(ATTR_FLAG_LOAD, pInfo->flag, false); ASSERT(count < MAX_ATTRIBUTES); // make sure it's in the range aAttriNames[count++] = pInfo->name; pAttr++; } if (!count) // there is no attribute to load return hr; // load the attributes ASSERT((IADs*)m_spIADs); CHECK_HR( hr = m_spIADs->QueryInterface(IID_IDirectoryObject, (void**)&spDirObj)); ASSERT((IDirectoryObject*)spDirObj); CHECK_HR(hr = spDirObj->GetObjectAttributes(aAttriNames, count, &pADsAttrInfo, &count)); while(count--) { pAttr = GetAttributes(); ASSERT(pAttr); // since we got it last time, we should get the same this time while(pAttr->pInfo) { pInfo = pAttr->pInfo; if(_wcsicmp(pADsAttrInfo[count].pszAttrName, pInfo->name) == 0) break; else pAttr++; }; ASSERT(pAttr->pInfo); // muse be found ASSERT(pInfo->type == pADsAttrInfo[count].dwADsType); // type must match SetFlags(ATTR_FLAG_LOAD, pInfo->flag, true); switch(pInfo->type) { case ADSTYPE_BOOLEAN: *(ADS_BOOLEAN*)pAttr->pBuffer = pADsAttrInfo[count].pADsValues[0].Boolean; break; case ADSTYPE_INTEGER: *(ADS_INTEGER*)pAttr->pBuffer = pADsAttrInfo[count].pADsValues[0].Integer; break; case ADSTYPE_LARGE_INTEGER: *(ADS_LARGE_INTEGER*)pAttr->pBuffer = pADsAttrInfo[count].pADsValues[0].LargeInteger; break; case ADSTYPE_CASE_IGNORE_STRING: case ADSTYPE_CASE_EXACT_STRING: case ADSTYPE_PRINTABLE_STRING: if(!pInfo->ifMultiValued) // CString is used { *(CString*)(pAttr->pBuffer) = pADsAttrInfo[count].pADsValues[0].CaseIgnoreString; } else // for multi-valued, CStrArray is used { CString* pStr = NULL; CStrArray* pArray = (CStrArray*)(pAttr->pBuffer); // clear the existing content of the array pArray->DeleteAll(); for(int i = 0; i< pADsAttrInfo[count].dwNumValues; i++) { try{ pStr = new CString(pADsAttrInfo[count].pADsValues[i].CaseIgnoreString); } catch(...) { CHECK_HR(hr = E_OUTOFMEMORY); } pArray->Add(pStr); } } break; default: // other types are not supported // need to make some changes when adding new types ASSERT(0); break; } } L_ERR: FreeADsMem(pADsAttrInfo); // This is to deal with a bug related to GetAttribute function of ADS , which returns error when no attribute is found // code to be cleaned, once the bug is fixed, this should be removed if(hr == 0x80005210) hr = S_OK; return hr; } /////////////////////////////////////////////////////////////////////////////// // // CACSGlobalObject // // //+---------------------------------------------------------------------------- // // Method: CACSGlobalObject::Open // // Synopsis: // //----------------------------------------------------------------------------- STDMETHODIMP CACSGlobalObject::Open() { HRESULT hr = S_OK; CString adsPath; int i, j; // try to get the object to see if the object is already there // profile container pointer IADs* pIADs = NULL; VARIANT var; BSTR bstrConfigPath = NULL; if(IfOpened()) return S_OK; m_nOpenErrorId = 0; VariantInit(&var); // get ROOTDSE CHECK_HR(hr = ADsOpenObject(ACS_DSP_ROOTDSE, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_USE_SIGNING | ADS_USE_SEALING,IID_IADs, (void**)&pIADs)); ASSERT(pIADs); // the name of the domain CHECK_HR(hr = pIADs->Get(ACS_DSA_DEFAULTCONTEXT, &var)); m_strDomainName = V_BSTR(&var); i = m_strDomainName.Find(_T('=')); if(i != -1) i++; j = m_strDomainName.Find(_T(',')); m_strDomainName = m_strDomainName.Mid(i, j - i); VariantClear(&var); CHECK_HR(hr = pIADs->Get(ACS_DSA_CONFIGCONTEXT, &var)); bstrConfigPath = V_BSTR(&var); pIADs->Release(); pIADs = NULL; try{ adsPath = LDAP_LEADING; adsPath += ACS_RPATH_ACS_INCONFIG; adsPath += bstrConfigPath; }catch(CMemoryException&){ hr = E_OUTOFMEMORY; } CHECK_HR(hr); if FAILED(hr = CDSObject::Open(NULL, NULL, T2W((LPTSTR)(LPCTSTR)adsPath), false, false)) // assume because of it doesn't exist { adsPath = LDAP_LEADING; adsPath += ACS_RPATH_ACS_PARENT_INCOFIG; adsPath += bstrConfigPath; CComObject* pParentObj = NULL; CHECK_HR(hr = CComObject::CreateInstance(&pParentObj)); // with 0 reference count // open it's parent -- this must be exist in DS CHECK_HR(hr = pParentObj->Open(NULL, NULL, T2W((LPTSTR)(LPCTSTR)adsPath), false, false)); // create it within it's parent hr = CDSObject::Open(pParentObj, ACS_CLS_CONTAINER, ACS_NAME_ACS, true, true); if(FAILED(hr)) m_nOpenErrorId = IDS_ERR_ROOTNODE; } L_ERR: VariantClear(&var); return hr; } STDMETHODIMP CACSGlobalObject::OnOpen() { if (!IfNewCreated()) return S_OK; HRESULT hr = S_OK; // create default and unknown policies CComObject* pDSObj = NULL; CComPtr spObj; // create the object in DS CHECK_HR(hr = CComObject::CreateInstance(&pDSObj)); // ref == 0 spObj = pDSObj; // ref == 1 if((CACSPolicyElement*)spObj) { // set default attributes and set the flags to save it spObj->SetFlags(ATTR_FLAG_SAVE, spObj->SetGlobalDefault(), true); } CHECK_HR(hr = spObj->Open(this, ACS_CLS_POLICY, ACSPOLICY_DEFAULT, true, true)); spObj->ClearFlags(ATTR_FLAG_SAVE); // clear the saving flags CHECK_HR(hr = spObj->Close()); // unknown_User -- make sure it exists spObj.Release(); // create the object in DS CHECK_HR(hr = CComObject::CreateInstance(&pDSObj)); // ref == 0 spObj = pDSObj; // ref == 1 if((CACSPolicyElement*)spObj) { // set attribute and flag for global unknown spObj->SetFlags(ATTR_FLAG_SAVE, spObj->SetGlobalUnknown(), true); } CHECK_HR(hr = spObj->Open(this, ACS_CLS_POLICY, ACSPOLICY_UNKNOWN, true, true)); spObj->ClearFlags(ATTR_FLAG_SAVE); // clear the saving flags CHECK_HR(hr = spObj->Close()); L_ERR: return hr; } /////////////////////////////////////////////////////////////////////////////// // // CACSSubnetsObject // // //+---------------------------------------------------------------------------- // // Method: CACSSubnetsObject::Open // // Synopsis: // //----------------------------------------------------------------------------- STDMETHODIMP CACSSubnetsObject::Open() { HRESULT hr = S_OK; CString adsPath; int i, j; // try to get the object to see if the object is already there // profile container pointer IADs* pIADs = NULL; VARIANT var; BSTR bstrConfigPath = NULL; if(IfOpened()) return S_OK; VariantInit(&var); // get ROOTDSE CHECK_HR(hr = ADsOpenObject(ACS_DSP_ROOTDSE, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_USE_SIGNING | ADS_USE_SEALING, IID_IADs, (void**)&pIADs)); ASSERT(pIADs); // configuration folder VariantClear(&var); CHECK_HR(hr = pIADs->Get(ACS_DSA_CONFIGCONTEXT, &var)); bstrConfigPath = V_BSTR(&var); pIADs->Release(); pIADs = NULL; try{ adsPath = LDAP_LEADING; adsPath += ACS_RPATH_SUBNETS_INCONFIG; adsPath += bstrConfigPath; }catch(CMemoryException&){ hr = E_OUTOFMEMORY; } CHECK_HR(hr); hr = CDSObject::Open(NULL, NULL, T2W((LPTSTR)(LPCTSTR)adsPath), false, false); L_ERR: VariantClear(&var); return hr; } //============================================ // attribute info of policy element CDSAttributeInfo CACSPolicyElement::m_aPolicyAttributeInfo[] = { {ACS_PAI_TIMEOFDAY , ACS_PAN_TIMEOFDAY , ACS_PAT_TIMEOFDAY , ACS_PAM_TIMEOFDAY , ACS_PAF_TIMEOFDAY }, {ACS_PAI_DIRECTION , ACS_PAN_DIRECTION , ACS_PAT_DIRECTION , ACS_PAM_DIRECTION , ACS_PAF_DIRECTION }, {ACS_PAI_PF_TOKENRATE , ACS_PAN_PF_TOKENRATE , ACS_PAT_PF_TOKENRATE , ACS_PAM_PF_TOKENRATE , ACS_PAF_PF_TOKENRATE }, {ACS_PAI_PF_PEAKBANDWIDTH , ACS_PAN_PF_PEAKBANDWIDTH , ACS_PAT_PF_PEAKBANDWIDTH , ACS_PAM_PF_PEAKBANDWIDTH , ACS_PAF_PF_PEAKBANDWIDTH }, {ACS_PAI_PF_DURATION , ACS_PAN_PF_DURATION , ACS_PAT_PF_DURATION , ACS_PAM_PF_DURATION , ACS_PAF_PF_DURATION }, {ACS_PAI_SERVICETYPE , ACS_PAN_SERVICETYPE , ACS_PAT_SERVICETYPE , ACS_PAM_SERVICETYPE , ACS_PAF_SERVICETYPE }, {ACS_PAI_PRIORITY , ACS_PAN_PRIORITY , ACS_PAT_PRIORITY , ACS_PAM_PRIORITY , ACS_PAF_PRIORITY }, {ACS_PAI_PERMISSIONBITS , ACS_PAN_PERMISSIONBITS , ACS_PAT_PERMISSIONBITS , ACS_PAM_PERMISSIONBITS , ACS_PAF_PERMISSIONBITS }, {ACS_PAI_TT_FLOWS , ACS_PAN_TT_FLOWS , ACS_PAT_TT_FLOWS , ACS_PAM_TT_FLOWS , ACS_PAF_TT_FLOWS }, {ACS_PAI_TT_TOKENRATE , ACS_PAN_TT_TOKENRATE , ACS_PAT_TT_TOKENRATE , ACS_PAM_TT_TOKENRATE , ACS_PAF_TT_TOKENRATE }, {ACS_PAI_TT_PEAKBANDWIDTH , ACS_PAN_TT_PEAKBANDWIDTH , ACS_PAT_TT_PEAKBANDWIDTH , ACS_PAM_TT_PEAKBANDWIDTH , ACS_PAF_TT_PEAKBANDWIDTH }, {ACS_PAI_IDENTITYNAME , ACS_PAN_IDENTITYNAME , ACS_PAT_IDENTITYNAME , ACS_PAM_IDENTITYNAME , ACS_PAF_IDENTITYNAME }, {ACS_PAI_INVALID, NULL, ADSTYPE_INVALID, false, 0} }; //============================================ // attribute info of subnet config object CDSAttributeInfo CACSSubnetConfig::m_aSubnetAttributeInfo[] = { {ACS_SCAI_ALLOCABLERSVPBW, ACS_SCAN_ALLOCABLERSVPBW ,ACS_SCAT_ALLOCABLERSVPBW ,ACS_SCAM_ALLOCABLERSVPBW ,ACS_SCAF_ALLOCABLERSVPBW }, {ACS_SCAI_MAXPEAKBW, ACS_SCAN_MAXPEAKBW ,ACS_SCAT_MAXPEAKBW ,ACS_SCAM_MAXPEAKBW ,ACS_SCAF_MAXPEAKBW }, {ACS_SCAI_ENABLERSVPMESSAGELOGGING, ACS_SCAN_ENABLERSVPMESSAGELOGGING ,ACS_SCAT_ENABLERSVPMESSAGELOGGING ,ACS_SCAM_ENABLERSVPMESSAGELOGGING ,ACS_SCAF_ENABLERSVPMESSAGELOGGING }, {ACS_SCAI_EVENTLOGLEVEL, ACS_SCAN_EVENTLOGLEVEL ,ACS_SCAT_EVENTLOGLEVEL ,ACS_SCAM_EVENTLOGLEVEL ,ACS_SCAF_EVENTLOGLEVEL }, {ACS_SCAI_ENABLEACSSERVICE, ACS_SCAN_ENABLEACSSERVICE ,ACS_SCAT_ENABLEACSSERVICE ,ACS_SCAM_ENABLEACSSERVICE ,ACS_SCAF_ENABLEACSSERVICE }, {ACS_SCAI_MAX_PF_TOKENRATE, ACS_SCAN_MAX_PF_TOKENRATE ,ACS_SCAT_MAX_PF_TOKENRATE ,ACS_SCAM_MAX_PF_TOKENRATE ,ACS_SCAF_MAX_PF_TOKENRATE }, {ACS_SCAI_MAX_PF_PEAKBW, ACS_SCAN_MAX_PF_PEAKBW ,ACS_SCAT_MAX_PF_PEAKBW ,ACS_SCAM_MAX_PF_PEAKBW ,ACS_SCAF_MAX_PF_PEAKBW }, {ACS_SCAI_MAX_PF_DURATION, ACS_SCAN_MAX_PF_DURATION ,ACS_SCAT_MAX_PF_DURATION ,ACS_SCAM_MAX_PF_DURATION ,ACS_SCAF_MAX_PF_DURATION }, {ACS_SCAI_RSVPLOGFILESLOCATION, ACS_SCAN_RSVPLOGFILESLOCATION ,ACS_SCAT_RSVPLOGFILESLOCATION ,ACS_SCAM_RSVPLOGFILESLOCATION ,ACS_SCAF_RSVPLOGFILESLOCATION }, {ACS_SCAI_DESCRIPTION, ACS_SCAN_DESCRIPTION ,ACS_SCAT_DESCRIPTION ,ACS_SCAM_DESCRIPTION ,ACS_SCAF_DESCRIPTION }, {ACS_SCAI_MAXNOOFLOGFILES, ACS_SCAN_MAXNOOFLOGFILES ,ACS_SCAT_MAXNOOFLOGFILES ,ACS_SCAM_MAXNOOFLOGFILES ,ACS_SCAF_MAXNOOFLOGFILES }, {ACS_SCAI_MAXSIZEOFRSVPLOGFILE, ACS_SCAN_MAXSIZEOFRSVPLOGFILE ,ACS_SCAT_MAXSIZEOFRSVPLOGFILE ,ACS_SCAM_MAXSIZEOFRSVPLOGFILE ,ACS_SCAF_MAXSIZEOFRSVPLOGFILE }, {ACS_SCAI_DSBMPRIORITY, ACS_SCAN_DSBMPRIORITY ,ACS_SCAT_DSBMPRIORITY ,ACS_SCAM_DSBMPRIORITY ,ACS_SCAF_DSBMPRIORITY }, {ACS_SCAI_DSBMREFRESH, ACS_SCAN_DSBMREFRESH ,ACS_SCAT_DSBMREFRESH ,ACS_SCAM_DSBMREFRESH ,ACS_SCAF_DSBMREFRESH }, {ACS_SCAI_DSBMDEADTIME, ACS_SCAN_DSBMDEADTIME ,ACS_SCAT_DSBMDEADTIME ,ACS_SCAM_DSBMDEADTIME ,ACS_SCAF_DSBMDEADTIME }, {ACS_SCAI_CACHETIMEOUT, ACS_SCAN_CACHETIMEOUT ,ACS_SCAT_CACHETIMEOUT ,ACS_SCAM_CACHETIMEOUT ,ACS_SCAF_CACHETIMEOUT }, {ACS_SCAI_NONRESERVEDTXLIMIT, ACS_SCAN_NONRESERVEDTXLIMIT ,ACS_SCAT_NONRESERVEDTXLIMIT ,ACS_SCAM_NONRESERVEDTXLIMIT ,ACS_SCAF_NONRESERVEDTXLIMIT }, // accounting {ACS_SCAI_ENABLERSVPMESSAGEACCOUNTING, ACS_SCAN_ENABLERSVPMESSAGEACCOUNTING ,ACS_SCAT_ENABLERSVPMESSAGELOGGING ,ACS_SCAM_ENABLERSVPMESSAGEACCOUNTING ,ACS_SCAF_ENABLERSVPMESSAGEACCOUNTING }, {ACS_SCAI_RSVPACCOUNTINGFILESLOCATION, ACS_SCAN_RSVPACCOUNTINGFILESLOCATION ,ACS_SCAT_RSVPLOGFILESLOCATION ,ACS_SCAM_RSVPACCOUNTINGFILESLOCATION ,ACS_SCAF_RSVPACCOUNTINGFILESLOCATION }, {ACS_SCAI_MAXNOOFACCOUNTINGFILES, ACS_SCAN_MAXNOOFACCOUNTINGFILES ,ACS_SCAT_MAXNOOFLOGFILES ,ACS_SCAM_MAXNOOFACCOUNTINGFILES ,ACS_SCAF_MAXNOOFACCOUNTINGFILES }, {ACS_SCAI_MAXSIZEOFRSVPACCOUNTINGFILE, ACS_SCAN_MAXSIZEOFRSVPACCOUNTINGFILE ,ACS_SCAT_MAXSIZEOFRSVPLOGFILE ,ACS_SCAM_MAXSIZEOFRSVPACCOUNTINGFILE ,ACS_SCAF_MAXSIZEOFRSVPACCOUNTINGFILE }, // server list {ACS_SCAI_SERVERLIST, ACS_SCAN_SERVERLIST ,ACS_SCAT_SERVERLIST ,ACS_SCAM_SERVERLIST ,ACS_SCAF_SERVERLIST }, {ACS_PAI_INVALID, NULL, ADSTYPE_INVALID, false, 0} }; //============================================ // attribute info of subnet service limit object CDSAttributeInfo CACSSubnetServiceLimits::m_aSubnetServiceLimitsAttributeInfo[] = { {ACS_SSLAI_ALLOCABLERSVPBW, ACS_SSLAN_ALLOCABLERSVPBW ,ACS_SSLAT_ALLOCABLERSVPBW ,ACS_SSLAM_ALLOCABLERSVPBW ,ACS_SSLAF_ALLOCABLERSVPBW }, {ACS_SSLAI_MAXPEAKBW, ACS_SSLAN_MAXPEAKBW ,ACS_SSLAT_MAXPEAKBW ,ACS_SSLAM_MAXPEAKBW ,ACS_SSLAF_MAXPEAKBW }, {ACS_SSLAI_MAX_PF_TOKENRATE,ACS_SSLAN_MAX_PF_TOKENRATE ,ACS_SSLAT_MAX_PF_TOKENRATE ,ACS_SSLAM_MAX_PF_TOKENRATE ,ACS_SSLAF_MAX_PF_TOKENRATE }, {ACS_SSLAI_MAX_PF_PEAKBW, ACS_SSLAN_MAX_PF_PEAKBW ,ACS_SSLAT_MAX_PF_PEAKBW ,ACS_SSLAM_MAX_PF_PEAKBW ,ACS_SSLAF_MAX_PF_PEAKBW }, {ACS_SSLAI_SERVICETYPE, ACS_SSLAN_SERVICETYPE ,ACS_SSLAT_SERVICETYPE ,ACS_SSLAM_SERVICETYPE ,ACS_SSLAF_SERVICETYPE }, {ACS_PAI_INVALID, NULL, ADSTYPE_INVALID, false, 0} }; bool CACSPolicyElement::IsConflictInContainer() { CACSPolicyContainer* pCont = dynamic_cast((CDSObject*)m_spContainer); return pCont->IsConflictWithExisting(this); } void CACSPolicyElement::InvalidateConflictState() { CACSPolicyContainer* pCont = dynamic_cast((CDSObject*)m_spContainer); pCont->SetChildrenConflictState(); } STDMETHODIMP CACSPolicyElement::GetString(CString& str, int nCol) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); USES_CONVERSION; Reopen(); str.Empty(); switch(nCol) { case 0: // name field if(m_bUseName_NewPolicy) { str.LoadString(IDS_NEWACSPOLICY); } else if(m_strArrayIdentityName.GetSize()) { int offset; int id = GetIdentityType(&offset); switch(id){ case 0: if(m_strDefaultUser.IsEmpty()) str.LoadString(IDS_ANYAUTHENTICATEDUSER); break; case 1: if(m_strUnknownUser.IsEmpty()) str.LoadString(IDS_NONAUTHENTICATEDUSER); break; default: str = m_strArrayIdentityName[(INT_PTR)0]->Mid(offset); break; } } break; case 1: // direction if(GetFlags(ATTR_FLAG_LOAD, ACS_PAF_DIRECTION)) { switch(m_dwDirection) { case ACS_DIRECTION_SEND: if(m_strDirectionSend.IsEmpty()) m_strDirectionSend.LoadString(IDS_SEND); str = m_strDirectionSend; break; case ACS_DIRECTION_RECEIVE: if(m_strDirectionReceive.IsEmpty()) m_strDirectionReceive.LoadString(IDS_RECEIVE); str = m_strDirectionReceive; break; case ACS_DIRECTION_BOTH: if(m_strDirectionBoth.IsEmpty()) m_strDirectionBoth.LoadString(IDS_SENDRECEIVE); str = m_strDirectionBoth; break; default: ASSERT(0); } } break; case 2: // Service Level if(GetFlags(ATTR_FLAG_LOAD, ACS_PAF_SERVICETYPE)) { switch(m_dwServiceType) { case ACS_SERVICETYPE_BESTEFFORT: if(m_strServiceTypeBestEffort.IsEmpty()) m_strServiceTypeBestEffort.LoadString(IDS_BESTEFFORT); str = m_strServiceTypeBestEffort; break; case ACS_SERVICETYPE_CONTROLLEDLOAD: if(m_strServiceTypeControlledLoad.IsEmpty()) m_strServiceTypeControlledLoad.LoadString(IDS_CONTROLLEDLOAD); str = m_strServiceTypeControlledLoad; break; case ACS_SERVICETYPE_GUARANTEEDSERVICE: if(m_strServiceTypeGuaranteedService.IsEmpty()) m_strServiceTypeGuaranteedService.LoadString(IDS_GUARANTEEDSERVICE); str = m_strServiceTypeGuaranteedService; break; case ACS_SERVICETYPE_ALL: if(m_strServiceTypeAll.IsEmpty()) m_strServiceTypeAll.LoadString(IDS_ALL); str = m_strServiceTypeAll; break; case ACS_SERVICETYPE_DISABLED: if(m_strServiceTypeDisabled.IsEmpty()) m_strServiceTypeDisabled.LoadString(IDS_SERVICETYPE_DISABLED); str = m_strServiceTypeDisabled; break; default: // invalid value ASSERT(0); // message box } } break; case 3: // date rate if(GetFlags(ATTR_FLAG_LOAD, ACS_PAF_PF_TOKENRATE)) { if (IS_LARGE_UNLIMIT(m_ddPFTokenRate)) { str.LoadString(IDS_RESOURCELIMITED); } else { str.Format(_T("%d"), TOKBS(m_ddPFTokenRate.LowPart)); } } break; case 4: // peak rate if(GetFlags(ATTR_FLAG_LOAD, ACS_PAF_PF_PEAKBANDWIDTH)) { if (IS_LARGE_UNLIMIT(m_ddPFPeakBandWidth)) { str.LoadString(IDS_RESOURCELIMITED); } else { str.Format(_T("%d"), TOKBS(m_ddPFPeakBandWidth.LowPart)); } } break; default: break; } if(str.IsEmpty()) str = _T("-"); return S_OK; } // string for direction CString CACSPolicyElement::m_strDirectionSend; CString CACSPolicyElement::m_strDirectionReceive; CString CACSPolicyElement::m_strDirectionBoth; // string for service type CString CACSPolicyElement::m_strServiceTypeAll; CString CACSPolicyElement::m_strServiceTypeBestEffort; CString CACSPolicyElement::m_strServiceTypeControlledLoad; CString CACSPolicyElement::m_strServiceTypeGuaranteedService; CString CACSPolicyElement::m_strServiceTypeDisabled; // identity display name CString CACSPolicyElement::m_strDefaultUser; CString CACSPolicyElement::m_strUnknownUser; HRESULT CACSSubnetObject::GetString(CString& str, int nCol) { USES_CONVERSION; switch(nCol) { case 0: // name field ASSERT((CDSObject*)m_spContainer); str = m_spContainer->GetName(); break; default: if(!m_spConfigObject.p) // the ACS object is not created { Reopen(); if(!m_spConfigObject.p) { str = _T("-"); return S_OK; } } return m_spConfigObject->GetString(str, nCol); break; } return S_OK; } HRESULT CACSSubnetConfig::GetString(CString& str, int nCol) { USES_CONVERSION; if(!m_bOpened) Reopen(); str.Empty(); switch(nCol) { case 0: ASSERT(0); // should not come here, it should be covered by its case 1: // name field str = m_strDESCRIPTION; break; case 2: // date rate if(GetFlags(ATTR_FLAG_LOAD, ACS_SCAF_MAX_PF_TOKENRATE)) str.Format(_T("%d"), TOKBS(m_ddMAX_PF_TOKENRATE.LowPart)); break; case 3: // peak rate if(GetFlags(ATTR_FLAG_LOAD, ACS_SCAF_MAX_PF_PEAKBW)) str.Format(_T("%d"), TOKBS(m_ddMAX_PF_PEAKBW.LowPart)); break; default: ASSERT(0); } if(str.IsEmpty()) str = _T("-"); return S_OK; } /////////////////////