//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1998 - 1999 // // File: util.h // //-------------------------------------------------------------------------- #ifndef _UTIL_H__ #define _UTIL_H__ #include #include "stlutil.h" /////////////////////////////////////////////////////////////////////// // MACROS // flags to interpret the DSSEC.DAT file values (from JeffreyS) #define IDC_CLASS_NO_CREATE 0x00000001 #define IDC_CLASS_NO_DELETE 0x00000002 #define IDC_CLASS_NO_INHERIT 0x00000004 #define IDC_PROP_NO_READ 0x00000001 #define IDC_PROP_NO_WRITE 0x00000002 // derived flags #define IDC_CLASS_NO (IDC_CLASS_NO_CREATE | IDC_CLASS_NO_DELETE | IDC_CLASS_NO_INHERIT) #define IDC_PROP_NO (IDC_PROP_NO_READ | IDC_PROP_NO_WRITE) /////////////////////////////////////////////////////////////////////// // strings // special classes extern PWSTR g_wzRootDSE; extern PWSTR g_wzSchemaNamingContext; extern PWSTR g_wzLDAPAbstractSchemaFormat; // fwd decl class CAdsiObject; class CErrorMessageHandlerBase; /////////////////////////////////////////////////////////////////////// // CWString class CWString : public wstring { public: operator LPCWSTR() { return c_str(); } CWString& operator=(LPCWSTR lpsz) { if (lpsz == NULL) lpsz = L""; *((wstring*)this) = lpsz; return *this; } BOOL LoadFromResource(UINT uID); }; /////////////////////////////////////////////////////////////////////// // GLOBAL FUNCTIONS BOOL LoadStringHelper(UINT uID, LPTSTR lpszBuffer, int nBufferMax); BOOL GetStringFromHRESULTError(HRESULT hr, CWString& szErrorString, BOOL bTryADsIErrors = TRUE); BOOL GetStringFromWin32Error(DWORD dwErr, CWString& CWString); inline HRESULT ADsOpenObjectHelper(LPCWSTR lpszPathName, REFIID riid, void** ppObject) { return ADsOpenObject((LPWSTR)lpszPathName, NULL, //LPWSTR lpszUserName, NULL, //LPWSTR lpszPassword, ADS_SECURE_AUTHENTICATION, //DWORD dwReserved, riid, ppObject ); } HRESULT InitCheckAccess( HWND hwndParent, LPCWSTR pszObjectLADPPath ); // functions to access DSSEC.DAT ULONG GetClassFlags(LPCWSTR lpszClassName); ULONG GetAttributeFlags(LPCWSTR lpszClassName, LPCWSTR lpszAttr); void BuildLdapPathHelper(LPCWSTR lpszServerName, LPCWSTR lpszNamingContext, CWString& szLdapPath); void BuildWin32PathHelper(LPCWSTR lpszServerName, LPCWSTR lpszNamingContext, CWString& szWin32Path); HRESULT GetCanonicalNameFromNamingContext(LPCWSTR lpszNamingContext, CWString& szCanonicalName); HRESULT GetGlobalNamingContexts(LPCWSTR lpszServerName, CWString& szPhysicalSchemaNamingContext, CWString& szConfigurationNamingContext); HRESULT GetSchemaClassName(LPCWSTR lpszServerName, LPCWSTR lpszPhysicalSchemaNamingContext, LPCWSTR lpszClassLdapDisplayName, // e.g. "organizationalUnit" CWString& szClassName // e.g. "Organizational-Unit" ); extern LPCWSTR g_lpszSummaryIdent; extern LPCWSTR g_lpszSummaryNewLine; void WriteSummaryTitleLine(CWString& szSummary, UINT nTitleID, LPCWSTR lpszNewLine); void WriteSummaryLine(CWString& szSummary, LPCWSTR lpsz, LPCWSTR lpszIdent, LPCWSTR lpszNewLine); DWORD AddObjectRightInAcl(IN PSID pSid, IN ULONG uAccess, IN const GUID* pRightGUID, IN const GUID* pInheritGUID, IN OUT PACL* ppAcl); /////////////////////////////////////////////////////////////////////// //////////////////////////// HELPER CLASSES /////////////////////////// /////////////////////////////////////////////////////////////////////// // CWaitCursor class CWaitCursor { public: CWaitCursor() { m_hCurrentCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT)); } ~CWaitCursor() { ::SetCursor(m_hCurrentCursor); } private: HCURSOR m_hCurrentCursor; }; BOOL FormatStringGUID(LPWSTR lpszBuf, UINT nBufSize, const GUID* pGuid); BOOL GuidFromString(GUID* pGuid, LPCWSTR lpszGuidString); /////////////////////////////////////////////////////////////////////// // CFilterBase class CFilterBase { public: virtual BOOL CanAdd(LPCWSTR lpsz, ULONG* pFilterFlags) = 0; }; /////////////////////////////////////////////////////////////////////// // CSidHolder class CSidHolder { public: CSidHolder() { _Init(); } ~CSidHolder() { _Free(); } PSID Get() { return m_pSID; } BOOL Copy(PSID p) { _Free(); return _Copy(p); } void Attach(PSID p, BOOL bLocalAlloc) { _Free(); m_pSID = p; m_bLocalAlloc = bLocalAlloc; } private: void _Init() { m_pSID = NULL; m_bLocalAlloc = TRUE; } void _Free() { if (m_pSID != NULL) { if (m_bLocalAlloc) ::LocalFree(m_pSID); else ::FreeSid(m_pSID); _Init(); } } BOOL _Copy(PSID p) { if ( (p == NULL) || !::IsValidSid(p) ) return FALSE; DWORD dwLen = ::GetLengthSid(p); PSID pNew = ::LocalAlloc(LPTR, dwLen); if(!pNew) return FALSE; if (!::CopySid(dwLen, pNew, p)) { ::LocalFree(pNew); return FALSE; } m_bLocalAlloc = TRUE; m_pSID = pNew; ASSERT(dwLen == ::GetLengthSid(m_pSID)); ASSERT(memcmp(p, m_pSID, dwLen) == 0); return TRUE; } PSID m_pSID; BOOL m_bLocalAlloc; }; /////////////////////////////////////////////////////////////////////// // CPrincipal class CPrincipal { public: CPrincipal() { m_hClassIcon = NULL; } HRESULT Initialize(PDS_SELECTION pDsSelection, HICON hClassIcon); HRESULT Initialize (PSID psid); BOOL IsEqual(CPrincipal* p); PSID GetSid() { return m_sidHolder.Get(); } LPCWSTR GetClass() { return m_szClass; } HICON GetClassIcon() { return m_hClassIcon; } LPCWSTR GetDisplayName() { return m_szDisplayName; } private: void _ComposeDisplayName(); // names CWString m_szName; // e.g. "JoeB" CWString m_szADsPath; //e.g. "WINNT://FOODOM/JoeB" CWString m_szUPN; // e.g. "JoeB@foo.com." CWString m_szClass; // e.g. "user" CWString m_szDisplayName; // generated, to be shown into the UI // other data HICON m_hClassIcon; // icon handle CSidHolder m_sidHolder; // PSID holder }; /////////////////////////////////////////////////////////////////////// // CPrincipalList class CPrincipalList : public CPtrList { public: CPrincipalList(BOOL bOwnMem = TRUE) : CPtrList(bOwnMem) { } BOOL AddIfNotPresent(CPrincipal* p); void WriteSummaryInfo(CWString& szSummary, LPCWSTR lpszIdent, LPCWSTR lpszNewLine); }; /////////////////////////////////////////////////////////////////////// // CBasicRightInfo class CBasicRightInfo { public: CBasicRightInfo() { m_fAccess = 0x0; m_bSelected = FALSE; } LPCWSTR GetDisplayName() { return m_szDisplayName; } ULONG GetAccess() { return m_fAccess; } BOOL IsSelected() { return m_bSelected; } void Select(BOOL b) { m_bSelected = b; } protected: CWString m_szDisplayName; ULONG m_fAccess; private: BOOL m_bSelected; }; /////////////////////////////////////////////////////////////////////// // CAccessRightInfo class CTemplateAccessPermissionsHolder; // fwd decl class CCustomAccessPermissionsHolder; // fwd decl class CAccessRightInfo : public CBasicRightInfo { friend class CTemplateAccessPermissionsHolder; friend class CCustomAccessPermissionsHolder; }; /////////////////////////////////////////////////////////////////////// // CAccessRightInfoArray class CAccessRightInfoArray : public CGrowableArr { }; /////////////////////////////////////////////////////////////////////// // CControlRightInfo class CControlRightInfoArray; //fwd decl class CControlRightInfo : public CBasicRightInfo { public: CControlRightInfo() { ZeroMemory(&m_rightsGUID, sizeof (GUID)); } const GUID* GetRightsGUID() { return &m_rightsGUID;} LPCWSTR GetLdapDisplayName() { return m_szLdapDisplayName; } LPCWSTR GetLocalizedName() { return m_szLocalizedName; } BOOL IsPropertySet() { return ((m_fAccess & (ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP)) != 0); } void SetLocalizedName(UINT nLocalizationDisplayId, HMODULE hModule); private: GUID m_rightsGUID; CWString m_szLdapDisplayName; // this is from the schema, not localized CWString m_szLocalizedName; // this is obtained from NTMARTA friend class CControlRightInfoArray; }; /////////////////////////////////////////////////////////////////////// // CControlRightInfoArray class CControlRightInfoArray : public CGrowableArr { public: HRESULT InitFromDS(CAdsiObject* pADSIObj, const GUID* pSchemaIDGUID); }; /////////////////////////////////////////////////////////////////////// // CSchemaObjectInfo class CSchemaObjectInfo { public: CSchemaObjectInfo(LPCWSTR lpszName) { m_bFilter = FALSE; if (lpszName != NULL) m_szName = lpszName; ZeroMemory(&m_schemaIDGUID, sizeof(GUID)); } virtual ~CSchemaObjectInfo() { } void SetDisplayName(LPCWSTR lpszDisplayName) { //TRACE(_T("SetDisplayName(%s)\n"),lpszDisplayName); m_szDisplayName = (lpszDisplayName != NULL) ? lpszDisplayName : m_szName; //TRACE(_T("m_szDisplayName = (%s)\n"),m_szDisplayName.c_str()); } LPCWSTR GetName() { return (m_szName.data()[0] == NULL) ? NULL : m_szName.c_str(); } LPCWSTR GetDisplayName() { //TRACE(_T("GetDisplayName() m_szName = (%s) m_szDisplayName = (%s)\n"), // m_szName.c_str(), m_szDisplayName.c_str()); return (m_szDisplayName.data()[0] == NULL) ? NULL : m_szDisplayName.c_str(); } const GUID* GetSchemaGUID() { return &m_schemaIDGUID; } bool operator<(CSchemaObjectInfo& x) { if ((GetDisplayName() == NULL) || (x.GetDisplayName() == NULL)) return false; return (_wcsicmp(GetDisplayName(), x.GetDisplayName()) < 0); } void SetFiltered() { m_bFilter = TRUE;} BOOL IsFiltered() { return m_bFilter;} protected: BOOL m_bFilter; CWString m_szName; CWString m_szDisplayName; GUID m_schemaIDGUID; }; ////////////////////////////////////////////////////////////////////// // CPropertyRightInfo class CPropertyRightInfoArray; // fwd decl class CPropertyRightInfo : public CSchemaObjectInfo { public: CPropertyRightInfo(ULONG filterFlags, LPCWSTR lpszName) : CSchemaObjectInfo(lpszName) { //TRACE(_T("CPropertyRightInfo(0x%x, %s)\n"),filterFlags, lpszName); m_FilterFlags = filterFlags; m_nRightCount = m_nRightCountMax; if (m_FilterFlags & IDC_PROP_NO_READ) m_nRightCount--; if (m_FilterFlags & IDC_PROP_NO_WRITE) m_nRightCount--; ASSERT(m_nRightCount > 0); m_Access = 0x0; } ~CPropertyRightInfo() {} static const ULONG m_nRightCountMax; static const ULONG m_nReadIndex; static const ULONG m_nWriteIndex; LPCWSTR GetRightDisplayString(ULONG iRight); void SetRight(ULONG iRight, BOOL b); ULONG GetRight(ULONG iRight); BOOL IsRightSelected(ULONG iRight); ULONG GetAccess() { return m_Access;} void AddAccessRight(ULONG uRight) { m_Access |= uRight;} ULONG GetRightCount() { return m_nRightCount;} private: ULONG m_nRightCount; ULONG m_FilterFlags; ULONG m_Access; friend class CPropertyRightInfoArray; }; ////////////////////////////////////////////////////////////////////// // CPropertyRightInfoArray class CPropertyRightInfoFilter : public CFilterBase { public: virtual BOOL CanAdd(LPCWSTR lpsz, ULONG* pFilterFlags) { *pFilterFlags = ::GetAttributeFlags(m_szClassName, lpsz); if (*pFilterFlags == 0) return TRUE; // have no info, so add anyway if ((*pFilterFlags & IDC_PROP_NO) == IDC_PROP_NO) return FALSE; // have all the hide flags set return TRUE; // some of the hide flags not set } void SetClassName(LPCWSTR lpszClassName) { if (lpszClassName == NULL) m_szClassName = L""; else m_szClassName = lpszClassName; } private: CWString m_szClassName; }; class CPropertyRightInfoArray : public CGrowableArr { public: HRESULT InitFromSchema(CAdsiObject* pADSIObj, IADsClass* pDsSchemaClass, LPCWSTR lpszClassName, BOOL bUseFilter); }; ////////////////////////////////////////////////////////////////////// // CClassRightInfo class CClassRightInfoArray; // fwd decl. class CClassRightInfo : public CSchemaObjectInfo { public: CClassRightInfo(ULONG filterFlags, LPCWSTR lpszName) : CSchemaObjectInfo(lpszName) { //TRACE(_T("CClassRightInfo(0x%x, %s)\n"),filterFlags, lpszName); m_FilterFlags = filterFlags; m_nRightCount = m_nRightCountMax; if (m_FilterFlags & IDC_CLASS_NO_CREATE) m_nRightCount--; if (m_FilterFlags & IDC_CLASS_NO_DELETE) m_nRightCount--; // REVIEW_MARCOC: do we need this? //if (m_FilterFlags & IDC_CLASS_NO_INHERIT) // m_nRightCount--; ASSERT(m_nRightCount > 0); m_Access = 0x0; } ~CClassRightInfo() {} static const ULONG m_nRightCountMax; static const ULONG m_nCreateIndex; static const ULONG m_nDeleteIndex; LPCWSTR GetRightDisplayString(ULONG iRight); void SetRight(ULONG iRight, BOOL b); ULONG GetRight(ULONG iRight); BOOL IsRightSelected(ULONG iRight); ULONG GetAccess() { return m_Access;} void AddAccessRight(ULONG uRight) { m_Access |= uRight;} ULONG GetRightCount() { return m_nRightCount;} private: ULONG m_nRightCount; ULONG m_FilterFlags; ULONG m_Access; friend class CClassRightInfoArray; }; ////////////////////////////////////////////////////////////////////// // CClassRightInfoArray class CClassRightInfoFilter : public CFilterBase { public: virtual BOOL CanAdd(LPCWSTR lpsz, ULONG* pFilterFlags) { *pFilterFlags = ::GetClassFlags(lpsz); if (*pFilterFlags == 0) return TRUE; // have no info, so add anyway if ((*pFilterFlags & IDC_CLASS_NO) == IDC_CLASS_NO) return FALSE; // have all the hide flags set return TRUE; // some of the hide flags not set } }; class CClassRightInfoArray : public CGrowableArr { public: HRESULT InitFromSchema(CAdsiObject* pADSIObj, IADsClass* pDsSchemaClass, BOOL bUseFilter); }; /////////////////////////////////////////////////////////////////////// // CSchemaClassInfo #define CHILD_CLASS_NOT_EXIST 1 #define CHILD_CLASS_EXIST 2 #define CHILD_CLASS_NOT_CALCULATED 3 class CSchemaClassInfo : public CSchemaObjectInfo { public: CSchemaClassInfo(LPCWSTR lpszName, LPCWSTR lpszSchemaClassName, const GUID* pSchemaIDGUID) : CSchemaObjectInfo(lpszName) { m_szSchemaClassName = lpszSchemaClassName; m_schemaIDGUID = *pSchemaIDGUID; m_dwChildClass = CHILD_CLASS_NOT_CALCULATED; m_bSelected = FALSE; m_bAux = FALSE; } ~CSchemaClassInfo() { } VOID SetAux(){m_bAux=TRUE;} BOOL IsAux(){return m_bAux;} BOOL m_bSelected; DWORD m_dwChildClass; LPCWSTR GetSchemaClassName() { return m_szSchemaClassName; } private: CWString m_szSchemaClassName; BOOL m_bAux; }; //////////////////////////////////////////////////////////////////////// // CRigthsListViewItem class CRigthsListViewItem { public: enum rightType { access, ctrl, prop, subobj }; CRigthsListViewItem(ULONG iIndex, ULONG iRight, rightType type) { m_type = type; m_iIndex = iIndex; m_iRight = iRight; } public: rightType m_type; ULONG m_iIndex; ULONG m_iRight; }; typedef CGrowableArr CRigthsListViewItemArray; /////////////////////////////////////////////////////////////////////// // CAccessPermissionsHolderBase class CAccessPermissionsHolderBase { public: CAccessPermissionsHolderBase(BOOL bUseFilter); virtual ~CAccessPermissionsHolderBase(); void Clear(); // entry manipulation functions size_t GetTotalCount() { return m_accessRightInfoArr.GetCount() + m_controlRightInfoArr.GetCount() + m_propertyRightInfoArray.GetCount() + m_classRightInfoArray.GetCount(); } BOOL HasPermissionSelected(); // backend DS operations HRESULT ReadDataFromDS(CAdsiObject* pADSIObj, LPCWSTR lpszObjectNamingContext, LPCWSTR lpszClassName, const GUID* pSchemaIDGUID, BOOL bChildClass, BOOL bHideListObject = FALSE); DWORD UpdateAccessList( CPrincipal* pPrincipal, CSchemaClassInfo* pClassInfo, LPCWSTR lpszServerName, LPCWSTR lpszPhysicalSchemaNamingContext, PACL* ppAcl); protected: // standard access rigths CAccessRightInfoArray m_accessRightInfoArr; virtual HRESULT _LoadAccessRightInfoArrayFromTable( BOOL bCreateDeleteChild,BOOL bHideListObject) = 0; // extended access rigths CControlRightInfoArray m_controlRightInfoArr; // array of property rights CPropertyRightInfoArray m_propertyRightInfoArray; // array of class rights CClassRightInfoArray m_classRightInfoArray; // array of selections in the UI BOOL* m_pbSelectedArr; // selected? private: BOOL m_bUseFilter; HRESULT _ReadClassInfoFromDS(CAdsiObject* pADSIObj, LPCWSTR lpszClassName); DWORD _UpdateAccessListHelper(PSID pSid, const GUID* pClassGUID, PACL *ppAcl, BOOL bChildClass); }; /////////////////////////////////////////////////////////////////////// // CCustomAccessPermissionsHolder // bitfields to keep track of the filtering state #define FILTER_EXP_GEN 0x1 #define FILTER_EXP_PROP 0x2 #define FILTER_EXP_SUBOBJ 0x4 #define FILTER_EXP_GEN_DISABLED 0x8 class CCheckListViewHelper; // fwd decl class CCustomAccessPermissionsHolder : public CAccessPermissionsHolderBase { public: CCustomAccessPermissionsHolder(); virtual ~CCustomAccessPermissionsHolder(); void Clear(); // entry manipulation functions void Select(IN CRigthsListViewItem* pItem, IN BOOL bSelect, OUT ULONG* pnNewFilterState); void FillAccessRightsListView( CCheckListViewHelper* pListViewHelper, ULONG nFilterState); void UpdateAccessRightsListViewSelection( CCheckListViewHelper* pListViewHelper, ULONG nFilterState); // display finish page summary info void WriteSummary(CWString& szSummary, LPCWSTR lpszIdent, LPCWSTR lpszNewLine); protected: virtual HRESULT _LoadAccessRightInfoArrayFromTable(BOOL bCreateDeleteChild,BOOL bHideListObject); private: // helper functions to do selection and deselection void _SelectAllRigths(); void _SelectAllPropertyRigths(ULONG fAccessPermission); void _SelectAllSubObjectRigths(ULONG fAccessPermission); void _DeselectAssociatedRights(ULONG fAccessPermission); // array of listview items, for indexing CRigthsListViewItemArray m_listViewItemArr; }; /////////////////////////////////////////////////////////////////////// // CCheckListViewHelper class CCheckListViewHelper { public: static BOOL CheckChanged(NM_LISTVIEW* pNMListView); static BOOL IsChecked(NM_LISTVIEW* pNMListView); CCheckListViewHelper() { m_hWnd = NULL; } BOOL Initialize(UINT nID, HWND hParent); int InsertItem(int iItem, LPCTSTR lpszText, LPARAM lParam, BOOL bCheck); BOOL SetItemCheck(int iItem, BOOL bCheck); void SetCheckAll(BOOL bCheck); LPARAM GetItemData(int iItem); BOOL IsItemChecked(int iItem); int GetCheckCount(); void GetCheckedItems(int nCheckCount, int* nCheckArray); BOOL GetCheckState(int iItem) { return ListView_GetCheckState(m_hWnd,iItem); } int GetItemCount() { return ListView_GetItemCount(m_hWnd); } BOOL DeleteAllItems() { return ListView_DeleteAllItems(m_hWnd); } void EnableWindow(BOOL bEnable) { ::EnableWindow(m_hWnd, bEnable); } private: HWND m_hWnd; }; //////////////////////////////////////////////////////////////////////////// // CNamedSecurityInfo /* class CNamedSecurityInfo { public: CNamedSecurityInfo() { m_pAuditList = NULL; m_pOwner = NULL; m_pGroup = NULL; m_pAccessList = NULL; } ~CNamedSecurityInfo() { Reset(); } DWORD Get(); DWORD Set(); void Reset(); private: CWString m_szObjectName; // name of the object // the following varables are just read and written back // i.e. no modification PACTRL_AUDIT m_pAuditList; LPWSTR m_pOwner; LPWSTR m_pGroup; // list to be edited and written back PACTRL_ACCESS m_pAccessList; }; */ //////////////////////////////////////////////////////////////////////////// // CAdsPathNameObj class CAdsPathNameObj { public: CAdsPathNameObj(){} ~CAdsPathNameObj(){ m_spADsPath = NULL;} HRESULT SkipPrefix(LPCWSTR pwzObj, BSTR* pBstr) { HRESULT hr = _Create(); if (FAILED(hr)) return hr; hr = m_spADsPath->Set((PWSTR)pwzObj, ADS_SETTYPE_FULL); if (FAILED(hr)) return hr; hr = m_spADsPath->Retrieve(ADS_FORMAT_X500_DN, pBstr); return hr; } HRESULT SkipPrefix(LPCWSTR pwzObj, CWString& str) { CComBSTR b; HRESULT hr = SkipPrefix(pwzObj, &b); if (FAILED(hr)) { str = L""; } else { str = b; } return hr; } HRESULT GetProvider(LPCWSTR pwzObj, BSTR* pBstr) { HRESULT hr = _Create(); if (FAILED(hr)) return hr; hr = m_spADsPath->Set((PWSTR)pwzObj, ADS_SETTYPE_FULL); if (FAILED(hr)) return hr; hr = m_spADsPath->Retrieve(ADS_FORMAT_PROVIDER, pBstr); return hr; } private: CComPtr m_spADsPath; HRESULT _Create() { HRESULT hr = S_OK; if (m_spADsPath == NULL) { hr = ::CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (PVOID *)&m_spADsPath); } return hr; } }; //////////////////////////////////////////////////////////////////////////// // CAdsiObject class CAdsiObject { public: CAdsiObject():m_iListObjectEnforced(-1) { _Clear(); } virtual ~CAdsiObject(){} virtual HRESULT Bind(LPCWSTR lpszLdapPath); BOOL IsBound() { return m_spIADs != NULL; } HRESULT QuerySchemaClasses(CGrowableArr* pSchemaClassesInfoArray, BOOL bGetAttributes = FALSE); // accessor functions LPCWSTR GetLdapPath() { return m_szLdapPath; } LPCWSTR GetServerName() { return m_szServerName; } LPCWSTR GetNamingContext() { return m_szNamingContext; } LPCWSTR GetCanonicalName() { return m_szCanonicalName; } LPCWSTR GetClass() { return m_szClass; } LPCWSTR GetPhysicalSchemaNamingContext() { return m_szPhysicalSchemaNamingContext;} LPCWSTR GetConfigurationNamingContext() { return m_szConfigurationNamingContext;} // methods to access display specifiers HICON GetClassIcon(LPCWSTR lpszObjectClass); HRESULT GetFriendlyClassName(LPCWSTR lpszObjectClass, LPWSTR lpszBuffer, int cchBuffer); HRESULT GetFriendlyAttributeName(LPCWSTR lpszObjectClass, LPCWSTR lpszAttributeName, LPWSTR lpszBuffer, int cchBuffer); HRESULT GetClassGuid(LPCWSTR lpszClassLdapDisplayName, BOOL bGetAttribute, GUID& guid); CAdsPathNameObj* GetPathNameObject() { return &m_pathNameObject; } bool GetListObjectEnforced(); protected: CComPtr m_spIADs; // pointer to ADSI object private: int m_iListObjectEnforced; CComPtr m_spIDsDisplaySpecifier; // pointer to Display Specifier Cache CAdsPathNameObj m_pathNameObject; // path cracker object wrapper // cached naming strings CWString m_szServerName; // DNS name the object is bound to ("foo.bar.com.") CWString m_szNamingContext; // naming context (X500) ("cn=xyz,..."); CWString m_szLdapPath; // full LDAP path ("LDAP://foo.bar.com.\cn=xyz,...") CWString m_szCanonicalName; // name in canonical form CWString m_szClass; // class name in abstract schema, corresponding to // LDAPDisplayName attribute in physical schema, // (e.g. "organizationalUnit") // commonly used naming contexts CWString m_szPhysicalSchemaNamingContext; CWString m_szConfigurationNamingContext; void _Clear() { m_spIADs = NULL; m_spIDsDisplaySpecifier = NULL; m_szServerName = L""; m_szLdapPath = L""; m_szCanonicalName = L""; m_szClass = L""; m_szPhysicalSchemaNamingContext = L""; m_szConfigurationNamingContext = L""; } HRESULT _QueryDNSServerName(); HRESULT _InitGlobalNamingContexts(); HRESULT _GetFriendlyClassNames(CGrowableArr* pSchemaClassesInfoArray); }; //////////////////////////////////////////////////////////////////////////////////////// // CAdsiSearch class CAdsiSearch { public: CAdsiSearch() { m_SearchHandle = NULL; } ~CAdsiSearch() { Reset(); } HRESULT Init(LPCWSTR lpszObjectPath) { Reset(); return ::ADsOpenObjectHelper(lpszObjectPath, IID_IDirectorySearch, (void**)&m_spSearchObj); } void Reset() { if (m_spSearchObj != NULL) { if (m_SearchHandle != NULL) { m_spSearchObj->CloseSearchHandle(m_SearchHandle); m_SearchHandle = NULL; } } m_spSearchObj = NULL; } HRESULT SetSearchScope(ADS_SCOPEENUM scope) { if (m_spSearchObj == NULL) return E_ADS_BAD_PATHNAME; ADS_SEARCHPREF_INFO aSearchPref; aSearchPref.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; aSearchPref.vValue.dwType = ADSTYPE_INTEGER; aSearchPref.vValue.Integer = scope; return m_spSearchObj->SetSearchPreference(&aSearchPref, 1); } HRESULT DoQuery(LPCWSTR lpszFilter, LPCWSTR* pszAttribsArr, const int cAttrs); HRESULT GetNextRow() { if (m_spSearchObj == NULL) return E_ADS_BAD_PATHNAME; return m_spSearchObj->GetNextRow(m_SearchHandle); } HRESULT GetColumn(LPCWSTR lpszAttribute, PADS_SEARCH_COLUMN pColumnData) { if (m_spSearchObj == NULL) return E_ADS_BAD_PATHNAME; return m_spSearchObj->GetColumn(m_SearchHandle, (LPWSTR)lpszAttribute, pColumnData); } HRESULT FreeColumn(PADS_SEARCH_COLUMN pColumnData) { if (m_spSearchObj == NULL) return E_ADS_BAD_PATHNAME; return m_spSearchObj->FreeColumn(pColumnData); } HRESULT GetColumnString(LPCWSTR lpszAttribute, CWString& szData) { ADS_SEARCH_COLUMN ColumnData; ::ZeroMemory (&ColumnData, sizeof (ADS_SEARCH_COLUMN)); HRESULT hr = GetColumn(lpszAttribute, &ColumnData); if (SUCCEEDED(hr)) { if (ColumnData.dwADsType == ADSTYPE_CASE_IGNORE_STRING) szData = ColumnData.pADsValues->CaseIgnoreString; else { szData = L""; hr = E_INVALIDARG; } FreeColumn(&ColumnData); } return hr; } HRESULT GetColumnOctectStringGUID(LPCWSTR lpszAttribute, GUID& guid) { ADS_SEARCH_COLUMN ColumnData; ::ZeroMemory (&ColumnData, sizeof (ADS_SEARCH_COLUMN)); HRESULT hr = GetColumn(lpszAttribute, &ColumnData); if (SUCCEEDED(hr)) { if ( (ColumnData.dwADsType == ADSTYPE_OCTET_STRING) && (ColumnData.pADsValues->OctetString.dwLength == 16) ) { // we have a blob containing a GUID in binary form memcpy(&guid, ColumnData.pADsValues->OctetString.lpValue, sizeof(GUID)); } else { guid = GUID_NULL; hr = E_INVALIDARG; } FreeColumn(&ColumnData); } return hr; } HRESULT GetColumnOctectStringGUID(LPCWSTR lpszAttribute, CWString& szData) { GUID guid; szData = L""; HRESULT hr = GetColumnOctectStringGUID(lpszAttribute, guid); if (SUCCEEDED(hr)) { WCHAR szBuf[128]; if (FormatStringGUID(szBuf, 128, &guid)) { szData = szBuf; } else { szData = L""; hr = E_INVALIDARG; } } return hr; } HRESULT GetColumnInteger(LPCWSTR lpszAttribute, ULONG& uVal) { ADS_SEARCH_COLUMN ColumnData; ::ZeroMemory (&ColumnData, sizeof (ADS_SEARCH_COLUMN)); HRESULT hr = GetColumn(lpszAttribute, &ColumnData); if (SUCCEEDED(hr)) { if (ColumnData.dwADsType == ADSTYPE_INTEGER) uVal = ColumnData.pADsValues->Integer; else hr = E_INVALIDARG; FreeColumn(&ColumnData); } return hr; } private: CComPtr m_spSearchObj; ADS_SEARCH_HANDLE m_SearchHandle; }; /////////////////////////////////////////////////////////////////////// // CErrorMessageHandlerBase class CErrorMessageHandlerBase { public: CErrorMessageHandlerBase() {} virtual ~CErrorMessageHandlerBase() {} virtual void ReportHRESULTError(LPCWSTR lpszMsg, HRESULT hr) { UNREFERENCED_PARAMETER (lpszMsg); UNREFERENCED_PARAMETER (hr); } virtual void ReportHRESULTError(UINT nStringID, HRESULT hr) { UNREFERENCED_PARAMETER (nStringID); UNREFERENCED_PARAMETER (hr); } }; DWORD FormatStringID(LPTSTR *ppszResult, UINT idStr , ...); #endif // _UTIL_H__