windows-nt/Source/XPSP1/NT/admin/extens/common/util.h

1220 lines
29 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: util.h
//
//--------------------------------------------------------------------------
#ifndef _UTIL_H__
#define _UTIL_H__
#include <dsclient.h>
#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<CPrincipal*>
{
public:
CPrincipalList(BOOL bOwnMem = TRUE) : CPtrList<CPrincipal*>(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<CAccessRightInfo>
{
};
///////////////////////////////////////////////////////////////////////
// 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<CControlRightInfo>
{
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<CPropertyRightInfo>
{
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<CClassRightInfo>
{
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<CRigthsListViewItem> 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<IADsPathname> 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<CSchemaClassInfo>* 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<IADs> m_spIADs; // pointer to ADSI object
private:
int m_iListObjectEnforced;
CComPtr<IDsDisplaySpecifier> 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<CSchemaClassInfo>* 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<IDirectorySearch> 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__