|
|
/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation **/ /**********************************************************************/
/*
helper.h This file defines the following macros helper classes and functions:
Macros to check HRESULT CDlgHelper -- helper class to Enable/Check dialog Item, CManagedPage -- helper class for PropertyPage, It manages ReadOnly, SetModified, and ContextHelp CStrArray -- an array of pointer to CString It does NOT duplicate the string upon Add and It deletes the pointer during destruction It imports and exports SAFEARRAY
CReadWriteLock -- class for share read or exclusive write lock
CStrBox -- wrapper class for CListBox and CComboBox
CIPAddress -- wrapper for IPAddress
CFramedRoute -- Wrapper for FramedRoute CStrParse -- parses string for TimeOfDay
FILE HISTORY:
*/ // helper functions for dialog and dialog items
#ifndef _DLGHELPER_
#define _DLGHELPER_
#include "iastrace.h"
#define SAYOK { return S_OK;}
#define NOIMP { return E_NOTIMPL;}
// to reduce the step to set VARIANT
#define V__BOOL(v, v1)\
V_VT(v) = VT_BOOL, V_BOOL(v) = (v1)
#define V__I4(v, v1)\
V_VT(v) = VT_I4, V_I4(v) = (v1)
#define V__I2(v, v1)\
V_VT(v) = VT_I2, V_I2(v) = (v1)
#define V__UI1(v, v1)\
V_VT(v) = VT_UI1, V_UI1(v) = (v1)
#define V__BSTR(v, v1)\
V_VT(v) = VT_BSTR, V_BSTR(v) = (v1)
#define V__ARRAY(v, v1)\
V_VT(v) = VT_ARRAY, V_ARRAY(v) = (v1)
#define REPORT_ERROR(hr) \
IASTracePrintf("**** ERROR RETURN <%s @line %d> -> %08lx", \ __FILE__, __LINE__, hr)); \ ReportError(hr, 0, 0);
#ifdef _DEBUG
#define CHECK_HR(hr)\
{if(!CheckADsError(hr, FALSE, __FILE__, __LINE__)){goto L_ERR;}} #else
#define CHECK_HR(hr)\
if FAILED(hr) goto L_ERR #endif
#ifdef _DEBUG
#define NOTINCACHE(hr)\
(CheckADsError(hr, TRUE, __FILE__, __LINE__)) #else
#define NOTINCACHE(hr)\
(E_ADS_PROPERTY_NOT_FOUND == (hr)) #endif
BOOL CheckADsError(HRESULT hr, BOOL fIgnoreAttrNotFound, PSTR file, int line);
#ifdef _DEBUG
#define TRACEAfxMessageBox(id) {\
IASTracePrintf("AfxMessageBox <%s @line %d> ID: %d", \ __FILE__, __LINE__, id); \ AfxMessageBox(id);}\
#else
#define TRACEAfxMessageBox(id) AfxMessageBox(id)
#endif
// change string Name to CN=Name
void DecorateName(LPWSTR outString, LPCWSTR inString);
// find name from DN for example LDAP://CN=userA,CN=users... returns userA
void FindNameByDN(LPWSTR outString, LPCWSTR inString);
class CDlgHelper { public: static void EnableDlgItem(CDialog* pDialog, int id, bool bEnable = true); static int GetDlgItemCheck(CDialog* pDialog, int id); static void SetDlgItemCheck(CDialog* pDialog, int id, int nCheck); };
// class CPageManager and CManagedPage together handle the situation when
// the property sheet need to do some processing when OnApply function is called
// on some of the pages
class CPageManager { public: CPageManager(){ m_bModified = FALSE; m_bReadOnly = FALSE;}; BOOL GetModified(){ return m_bModified;}; void SetModified(BOOL bModified){ m_bModified = bModified;}; void SetReadOnly(BOOL bReadOnly){ m_bReadOnly = bReadOnly;}; BOOL GetReadOnly(){ return m_bReadOnly;}; virtual BOOL OnApply() { if (!GetModified()) return FALSE;
SetModified(FALSE); // prevent from doing this more than once
return TRUE; }; // to be implemented by the propertysheet
protected: BOOL m_bModified; BOOL m_bReadOnly; };
class CManagedPage : public CPropertyPage // talk back to property sheet
{ DECLARE_DYNCREATE(CManagedPage) public: CManagedPage() : CPropertyPage(){ m_bModified = FALSE; m_bNeedToSave = FALSE; m_pManager = NULL; };
CManagedPage(UINT nIDTemplate) : CPropertyPage(nIDTemplate) { m_bModified = FALSE; m_bNeedToSave = FALSE; m_pManager = NULL; };
void SetModified( BOOL bModified = TRUE ) { ASSERT(m_pManager); if(!m_pManager->GetReadOnly()) // if NOT readonly
{ m_bModified = bModified; m_bNeedToSave= bModified; CPropertyPage::SetModified(bModified);
// only set change
if(bModified) m_pManager->SetModified(TRUE); } };
BOOL GetModified() { return m_bModified;};
BOOL OnApply() { m_bModified = FALSE; BOOL b = TRUE; if(m_pManager->GetModified()) // prevent from entering more than once
b= m_pManager->OnApply(); return (b && CPropertyPage::OnApply()); };
// a page has three states: not dirty, dirty and need to save, and not dirty but need to save
// m_bModified == dirty flag
// m_bNeedToSave == need to save flag
// When m_bNeedToSave && !m_bModified is detected upon on saved failure, the modified flag of the page is set
BOOL OnSaved(BOOL bSaved) { if(bSaved) { m_bModified = FALSE; m_bNeedToSave = FALSE; } else if(m_bNeedToSave && !m_bModified) SetModified(TRUE);
return TRUE; };
void SetManager(CPageManager* pManager) { m_pManager = pManager;}; CPageManager* GetManager() { return m_pManager;};
protected:
// help info process
BOOL OnHelpInfo(HELPINFO* pHelpInfo); void OnContextMenu(CWnd* pWnd, ::CPoint point);
void SetHelpTable(const DWORD* pTable) { m_pHelpTable = pTable;}; int MyMessageBox(UINT ids, UINT nType = MB_OK); int MyMessageBox1(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK);
protected: CPageManager* m_pManager; BOOL m_bModified; BOOL m_bNeedToSave;
const DWORD* m_pHelpTable; };
#include <afxtempl.h>
class CStrArray : public CArray< ::CString*, ::CString* > { public: CStrArray(SAFEARRAY* pSA = NULL); CStrArray(const CStrArray& sarray); int Find(const ::CString& Str) const; int DeleteAll(); virtual ~CStrArray(); operator SAFEARRAY*(); CStrArray& operator = (const CStrArray& sarray); bool AppendSA(SAFEARRAY* pSA); int AddDuplicate(const ::CString& Str); void DeleteAt(int nIndex); };
class CDWArray : public CArray< DWORD, DWORD > { public: CDWArray(const CDWArray& dwarray); int Find(const DWORD dw) const; int DeleteAll(){ RemoveAll(); return 0;}; virtual ~CDWArray(){RemoveAll();}; CDWArray& operator = (const CDWArray& dwarray); operator SAFEARRAY*(); bool AppendSA(SAFEARRAY* pSA); CDWArray(SAFEARRAY* pSA = NULL); };
class CBYTEArray : public CArray< BYTE, BYTE > { public: CBYTEArray(const CBYTEArray& bytearray); int Find(const BYTE byte) const; int DeleteAll(){ RemoveAll(); return 0;}; virtual ~CBYTEArray(){RemoveAll();}; CBYTEArray& operator = (const CBYTEArray& bytearray); operator SAFEARRAY*(); bool AppendSA(SAFEARRAY* pSA); HRESULT AssignBlob(PBYTE pByte, DWORD size); HRESULT GetBlob(PBYTE pByte, DWORD* pSize);
CBYTEArray(SAFEARRAY* pSA = NULL); };
// a lock to allow multiple read access exclusive or only one write access
class CReadWriteLock // sharable read, exclusive write
{ public: CReadWriteLock() : m_nRead(0) { #ifdef _DEBUG
d_bWrite = false; #endif
}; void EnterRead() { IASTraceString("Entering Read Lock ..."); m_csRead.Lock(); if (!m_nRead++) m_csWrite.Lock(); m_csRead.Unlock(); IASTraceString("Entered Read Lock"); };
void LeaveRead() { IASTraceString("Leaving Read Lock ..."); m_csRead.Lock(); ASSERT(m_nRead > 0); if (!--m_nRead) m_csWrite.Unlock(); m_csRead.Unlock(); IASTraceString("Left Read Lock"); };
void EnterWrite() { IASTraceString("Entering Write Lock ..."); m_csWrite.Lock(); IASTraceString("Entered Write Lock"); #ifdef _DEBUG
d_bWrite = true; #endif
}; void LeaveWrite() { #ifdef _DEBUG
d_bWrite = false; #endif
m_csWrite.Unlock(); IASTraceString("Left Write Lock"); };
public: #ifdef _DEBUG
bool d_bWrite; #endif
protected: CCriticalSection m_csRead; CCriticalSection m_csWrite; int m_nRead; };
// to manage a list box/ combo box
template <class CBox> class CStrBox { public: CStrBox(CDialog* pDialog, int id, CStrArray& Strings) : m_Strings(Strings), m_id(id) { m_pDialog = pDialog; m_pBox = NULL; };
int Fill() { m_pBox = (CBox*)m_pDialog->GetDlgItem(m_id); ASSERT(m_pBox); m_pBox->ResetContent();
int count = (int)m_Strings.GetSize(); int index; for(int i = 0; i < count; i++) { index = m_pBox->AddString(*m_Strings[(INT_PTR)i]); m_pBox->SetItemDataPtr(index, m_Strings[(INT_PTR)i]); } return count; };
int DeleteSelected() { int index; ASSERT(m_pBox); index = m_pBox->GetCurSel();
// if there is any selected
if( index != LB_ERR ) { CString* pStr; pStr = (CString*)m_pBox->GetItemDataPtr(index); // remove the entry from the box
m_pBox->DeleteString(index);
// find the string in the String array
int count = static_cast<int>(m_Strings.GetSize()); for(int i = 0; i < count; i++) { if (m_Strings[(INT_PTR)i] == pStr) break; } ASSERT(i < count); // remove the string from the string array
m_Strings.RemoveAt(i); index = i; delete pStr; } return index; };
int AddString(::CString* pStr) // the pStr needs to dynamically allocated
{ int index; ASSERT(m_pBox && pStr); index = m_pBox->AddString(*pStr); m_pBox->SetItemDataPtr(index, pStr); return m_Strings.Add(pStr); };
int Select(int arrayindex) // the pStr needs to dynamically allocated
{ ASSERT(arrayindex < m_Strings.GetSize()); return m_pBox->SelectString(0, *m_Strings[(INT_PTR)arrayindex]); };
void Enable(BOOL b) // the pStr needs to dynamically allocated
{ ASSERT(m_pBox); m_pBox->EnableWindow(b); };
int GetSelected() // it returns the index where the
{ int index; ASSERT(m_pBox); index = m_pBox->GetCurSel();
// if there is any selected
if( index != LB_ERR ) { ::CString* pStr; pStr = (::CString*)m_pBox->GetItemDataPtr(index);
// find the string in the String array
int count = (int)m_Strings.GetSize(); for(int i = 0; i < count; i++) { if (m_Strings[(INT_PTR)i] == pStr) break; } ASSERT(i < count); index = i; } return index; };
CBox* m_pBox; protected: int m_id; CStrArray& m_Strings; CDialog* m_pDialog; };
// class to take care of ip address
class CIPAddress { public: CIPAddress(DWORD address = 0) { m_dwAddress = address; };
operator DWORD() { return m_dwAddress;}; operator ::CString() { ::CString str; WORD hi = HIWORD(m_dwAddress); WORD lo = LOWORD(m_dwAddress); str.Format(_T("%-d.%-d.%-d.%d"), HIBYTE(hi), LOBYTE(hi), HIBYTE(lo), LOBYTE(lo)); return str; };
DWORD m_dwAddress; };
// format of framedroute: mask dest metric ; mask and dest in dot format
class CFramedRoute { public: void SetRoute(::CString* pRoute) { m_pStrRoute = pRoute; m_pStrRoute->TrimLeft(); m_pStrRoute->TrimRight(); m_iFirstSpace = m_pStrRoute->Find(_T(' ')) ; m_iLastSpace = m_pStrRoute->ReverseFind(_T(' ')) ; };
::CString& GetDest(::CString& dest) const { int i = m_pStrRoute->Find(_T('/')); if(i == -1) i = m_iFirstSpace;
dest = m_pStrRoute->Left(i); return dest; };
::CString& GetNextStop(::CString& nextStop) const { nextStop = m_pStrRoute->Mid(m_iFirstSpace + 1, m_iLastSpace - m_iFirstSpace -1 ); return nextStop; };
::CString& GetPrefixLength(::CString& prefixLength) const { int i = m_pStrRoute->Find(_T('/'));
if( i != -1) { prefixLength = m_pStrRoute->Mid(i + 1, m_iFirstSpace - i - 1); } else prefixLength = _T("");
return prefixLength; };
::CString& GetMask(::CString& mask) const { int i = m_pStrRoute->Find(_T('/')); DWORD dwMask = 0; DWORD dwBit = 0x80000000; DWORD dwPrefixLen;
if( i != -1) { mask = m_pStrRoute->Mid(i + 1, m_iFirstSpace - i - 1); dwPrefixLen = _ttol((LPCTSTR)mask);
while(dwPrefixLen--) { dwMask |= dwBit; dwBit >>= 1; } } else dwMask = 0;
WORD hi1, lo1; hi1 = HIWORD(dwMask); lo1 = LOWORD(dwMask); mask.Format(_T("%-d.%-d.%d.%d"), HIBYTE(hi1), LOBYTE(hi1), HIBYTE(lo1), LOBYTE(lo1));
return mask; };
::CString& GetMetric(::CString& metric) const { metric = m_pStrRoute->Mid(m_iLastSpace + 1); return metric; };
protected:
// WARNING: the string is not copied, so user need to make sure the origin is valid
::CString* m_pStrRoute; int m_iFirstSpace; int m_iLastSpace; };
class CStrParser { public: CStrParser(LPCTSTR pStr = NULL) : m_pStr(pStr) { }
// get the current string position
LPCTSTR GetStr() const { return m_pStr;};
void SetStr(LPCTSTR pStr) { m_pStr = pStr;};
// find a unsigned interger and return it, -1 == not found
int GetUINT() { UINT ret = 0; while((*m_pStr < _T('0') || *m_pStr > _T('9')) && *m_pStr != _T('\0')) m_pStr++;
if(*m_pStr == _T('\0')) return -1;
while(*m_pStr >= _T('0') && *m_pStr <= _T('9')) { ret = ret * 10 + *m_pStr - _T('0'); m_pStr++; }
return ret; };
// find c and skip it
int GotoAfter(TCHAR c) { int ret = 0; // go until find c or end of string
while(*m_pStr != c && *m_pStr != _T('\0')) m_pStr++, ret++;
// if found
if(*m_pStr == c) m_pStr++, ret++; else ret = -1; return ret; };
// skip blank characters space tab
void SkipBlank() { while((*m_pStr == _T(' ') || *m_pStr == _T('\t')) && *m_pStr != _T('\0')) m_pStr++; };
// check to see if the first character is '0'-'6' for Monday(0) to Sunday(6)
int DayOfWeek() { SkipBlank(); if(*m_pStr >= _T('0') && *m_pStr <= _T('6')) return (*m_pStr++ - _T('0')); else return -1; // not day of week
};
protected: LPCTSTR m_pStr; private: ::CString _strTemp; };
void ReportError(HRESULT hr, int nStr, HWND hWnd);
// number of characters
void AFXAPI DDV_MinChars(CDataExchange* pDX, ::CString const& value, int nChars);
/*!--------------------------------------------------------------------------
IsStandaloneServer Returns S_OK if the machine name passed in is a standalone server, or if pszMachineName is S_FALSE.
Returns S_FALSE otherwise. Author: WeiJiang ---------------------------------------------------------------------------*/ HRESULT HrIsStandaloneServer(LPCTSTR pszMachineName);
HRESULT HrIsNTServer(LPCWSTR pMachineName);
class CBSTR { public: CBSTR() : m_bstr(NULL) {}; CBSTR(LPCSTR cstr) : m_bstr(NULL) { USES_CONVERSION; m_bstr = A2BSTR(cstr); }; CBSTR(LPCWSTR wstr) : m_bstr(NULL) { USES_CONVERSION; m_bstr = W2BSTR(wstr); };
BSTR AssignBlob(const char* pByte, UINT size) { SysFreeString(m_bstr); m_bstr = SysAllocStringByteLen(pByte, size);
return m_bstr; };
BSTR AssignBSTR(const BSTR bstr) { return AssignBlob((const char *)bstr, SysStringByteLen(bstr)); };
UINT ByteLen() { UINT n = 0; if(m_bstr) n = SysStringByteLen(m_bstr); return n; };
operator BSTR() { return m_bstr;};
void Clean() { SysFreeString(m_bstr); m_bstr = NULL; };
~CBSTR() { Clean(); };
BSTR m_bstr; };
template<class T> class CNetDataPtr { public: CNetDataPtr():m_pData(NULL){};
~CNetDataPtr() { NetApiBufferFree(m_pData); };
T** operator&() { return &m_pData; };
operator T*() { return m_pData; };
T* operator ->() { return m_pData; };
T* m_pData; };
/*!--------------------------------------------------------------------------
EnableChildControls Use this function to enable/disable/hide/show all child controls on a page (actually it will work with any child windows, the parent does not have to be a property page). Author: KennT ---------------------------------------------------------------------------*/ HRESULT EnableChildControls(HWND hWnd, DWORD dwFlags); #define PROPPAGE_CHILD_SHOW 0x00000001
#define PROPPAGE_CHILD_HIDE 0x00000002
#define PROPPAGE_CHILD_ENABLE 0x00000004
#define PROPPAGE_CHILD_DISABLE 0x00000008
/*---------------------------------------------------------------------------
Struct: AuthProviderData
This structure is used to hold information for Authentication AND Accounting providers. ---------------------------------------------------------------------------*/ struct AuthProviderData { // The following fields will hold data for ALL auth/acct/EAP providers
::CString m_stTitle; ::CString m_stConfigCLSID; // CLSID for config object
::CString m_stProviderTypeGUID; // GUID for the provider type
// These fields are used by auth/acct providers.
::CString m_stGuid; // the identifying guid
// This flag is used for EAP providers
::CString m_stKey; // name of registry key (for this provider)
BOOL m_fSupportsEncryption; // used by EAP provider data
::CString m_stServerTitle; // Title displayed on server.
};
typedef CArray<AuthProviderData, AuthProviderData&> AuthProviderArray;
#ifndef IASAPI
#define IASAPI __declspec(dllimport)
#endif
HRESULT IASAPI GetEapProviders( LPCWSTR machineName, AuthProviderArray *pProvList );
#endif
|