1220 lines
29 KiB
C
1220 lines
29 KiB
C
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// 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__
|