|
|
#include "pch.h"
#include <SnapBase.h>
#include "resource.h"
#include "query.h"
#include "attrres.h"
#include "editui.h"
#include "common.h"
#include "attrqry.h"
#include "editorui.h"
////////////////////////////////////////////////////////////////////////////
// this is used to fill in the attributes for RootDSE
//
typedef struct tagRootDSEAttr { LPCWSTR lpszAttr; LPCWSTR lpszSyntax; BOOL bMulti; } SYNTAXMAP;
extern SYNTAXMAP g_ldapRootDSESyntax[];
// Helper function to delete a set of ADSVALUEs
void DeleteADsValues(PADSVALUE pADsValue, DWORD valueCount) { if (!pADsValue) { return; }
for (DWORD idx = 0; idx < valueCount; ++idx) { switch (pADsValue[idx].dwType) { case ADSTYPE_DN_STRING: if (pADsValue[idx].DNString) { delete[] pADsValue[idx].DNString; } break;
case ADSTYPE_CASE_EXACT_STRING: if (pADsValue[idx].CaseExactString) { delete[] pADsValue[idx].CaseExactString; } break;
case ADSTYPE_CASE_IGNORE_STRING: if (pADsValue[idx].CaseIgnoreString) { delete[] pADsValue[idx].CaseIgnoreString; } break;
case ADSTYPE_PRINTABLE_STRING: if (pADsValue[idx].PrintableString) { delete[] pADsValue[idx].PrintableString; } break;
case ADSTYPE_NUMERIC_STRING: if (pADsValue[idx].NumericString) { delete[] pADsValue[idx].NumericString; } break;
case ADSTYPE_OCTET_STRING: if (pADsValue[idx].OctetString.lpValue) { delete[] pADsValue[idx].OctetString.lpValue; } break;
case ADSTYPE_DN_WITH_STRING: if (pADsValue[idx].pDNWithString) { if (pADsValue[idx].pDNWithString->pszStringValue) { delete[] pADsValue[idx].pDNWithString->pszStringValue; }
if (pADsValue[idx].pDNWithString->pszDNString) { delete[] pADsValue[idx].pDNWithString->pszDNString; }
delete pADsValue[idx].pDNWithString; } break;
case ADSTYPE_BOOLEAN: case ADSTYPE_INTEGER: case ADSTYPE_UTC_TIME: case ADSTYPE_LARGE_INTEGER: case ADSTYPE_CASEIGNORE_LIST: case ADSTYPE_OCTET_LIST: case ADSTYPE_PATH: case ADSTYPE_POSTALADDRESS: case ADSTYPE_TIMESTAMP: case ADSTYPE_BACKLINK: case ADSTYPE_TYPEDNAME: case ADSTYPE_HOLD: case ADSTYPE_NETADDRESS: case ADSTYPE_REPLICAPOINTER: case ADSTYPE_FAXNUMBER: case ADSTYPE_EMAIL: case ADSTYPE_DN_WITH_BINARY: default: // Do nothing, we didn't allocate any memory for these other types
break; } }
if (valueCount < 2) { delete pADsValue; } else { delete[] pADsValue; } }
///////////////////////////////////////////////////////////////////////////////////////
// CValueEditDialog
BEGIN_MESSAGE_MAP(CValueEditDialog, CDialog) END_MESSAGE_MAP()
HRESULT CValueEditDialog::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
m_pOldADsValue = pAttributeEditorInfo->pADsValue; m_dwOldNumValues = pAttributeEditorInfo->dwNumValues; m_szClass = pAttributeEditorInfo->lpszClass; m_szAttribute = pAttributeEditorInfo->lpszAttribute; m_bMultivalued = pAttributeEditorInfo->bMultivalued; m_bReadOnly = pAttributeEditorInfo->bReadOnly; m_pfnBindingFunction = pAttributeEditorInfo->lpfnBind; m_lParam = pAttributeEditorInfo->lParam;
return hr; }
HRESULT CValueEditDialog::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
*ppADsValue = NULL; *pdwNumValues = 0; return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CSingleStringEditor
CValueEditDialog* CreateSingleStringEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CSingleStringEditor; }
BEGIN_MESSAGE_MAP(CSingleStringEditor, CValueEditDialog) ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClear) END_MESSAGE_MAP()
BOOL CSingleStringEditor::OnInitDialog() { //
// Initialize the static control with the attribute name
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Initialize the edit box with the value
//
if (m_szOldValue.IsEmpty()) { CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET)); SetDlgItemText(IDC_VALUE_EDIT, szNotSet); } else { SetDlgItemText(IDC_VALUE_EDIT, m_szOldValue); }
//
// Select the text in the edit box
//
SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETSEL, 0, -1);
if (m_bReadOnly) { SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETREADONLY, TRUE, 0); }
return CDialog::OnInitDialog(); }
void CSingleStringEditor::OnOK() { GetDlgItemText(IDC_VALUE_EDIT, m_szNewValue);
CDialog::OnOK(); }
HRESULT CSingleStringEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { switch (pAttributeEditorInfo->pADsValue->dwType) { case ADSTYPE_CASE_IGNORE_STRING: m_szOldValue = pAttributeEditorInfo->pADsValue->CaseIgnoreString; break;
case ADSTYPE_CASE_EXACT_STRING: m_szOldValue = pAttributeEditorInfo->pADsValue->CaseExactString; break;
case ADSTYPE_PRINTABLE_STRING: m_szOldValue = pAttributeEditorInfo->pADsValue->PrintableString; break;
case ADSTYPE_DN_STRING: m_szOldValue = pAttributeEditorInfo->pADsValue->DNString; break;
default: ASSERT(FALSE); break; } } } return hr; }
void CSingleStringEditor::OnClear() { //
// Change the text in the edit box to "<not set>"
//
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET)); SetDlgItemText(IDC_VALUE_EDIT, szNotSet);
//
// Change the focus to the edit box
//
GetDlgItem(IDC_VALUE_EDIT)->SetFocus();
//
// Select the text in the edit box
//
SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETSEL, 0, -1); }
HRESULT CSingleStringEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET));
if (m_szNewValue == szNotSet) { *ppADsValue = NULL; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE; if (*ppADsValue != NULL) { *pdwNumValues = 1; (*ppADsValue)->dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_CASE_IGNORE_STRING: (*ppADsValue)->CaseIgnoreString = new WCHAR[wcslen(m_szNewValue) + 1]; if ((*ppADsValue)->CaseIgnoreString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)->CaseIgnoreString, m_szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
case ADSTYPE_CASE_EXACT_STRING: (*ppADsValue)->CaseExactString = new WCHAR[wcslen(m_szNewValue) + 1]; if ((*ppADsValue)->CaseExactString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)->CaseExactString, m_szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
case ADSTYPE_PRINTABLE_STRING: (*ppADsValue)->PrintableString = new WCHAR[wcslen(m_szNewValue) + 1]; if ((*ppADsValue)->PrintableString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)->PrintableString, m_szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
case ADSTYPE_DN_STRING: (*ppADsValue)->DNString = new WCHAR[wcslen(m_szNewValue) + 1]; if ((*ppADsValue)->DNString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)->DNString, m_szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } } else { *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CMultiStringEditor
CValueEditDialog* CreateMultiStringEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CMultiStringEditor; }
BEGIN_MESSAGE_MAP(CMultiStringEditor, CValueEditDialog) ON_BN_CLICKED(IDC_ATTR_ADD_BUTTON, OnAddButton) ON_BN_CLICKED(IDC_ATTR_REMOVE_BUTTON, OnRemoveButton) ON_LBN_SELCHANGE(IDC_VALUE_LIST, OnListSelChange) ON_EN_CHANGE(IDC_VALUE_EDIT, OnEditChange) END_MESSAGE_MAP()
BOOL CMultiStringEditor::OnInitDialog() { CDialog::OnInitDialog();
//
// Set the attribute name static
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Fill the list box with the current values
//
POSITION pos = m_szOldValueList.GetHeadPosition(); while (pos != NULL) { CString szValue = m_szOldValueList.GetNext(pos); if (!szValue.IsEmpty()) { SendDlgItemMessage(IDC_VALUE_LIST, LB_ADDSTRING, 0, (LPARAM)(LPCWSTR)szValue); } }
//
// The remove button should be disabled until something is selected in the listbox
//
GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_VALUE_EDIT)->SetFocus();
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent();
if (m_bReadOnly) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE); SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETREADONLY, TRUE, 0); }
//
// NOTE: I have explicitly set the focus so return 0
//
return FALSE; }
void CMultiStringEditor::OnOK() { if (!m_bReadOnly) { //
// Get the values out of the list box
//
m_szNewValueList.RemoveAll();
CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCount = pListBox->GetCount(); for (int idx = 0; idx < iCount; idx++) { CString szNewValue; pListBox->GetText(idx, szNewValue);
m_szNewValueList.AddTail(szNewValue); } } } CDialog::OnOK(); }
void CMultiStringEditor::OnAddButton() { if (!m_bReadOnly) { //
// Add the value to the list box and clear the edit field
//
CString szNewValue; GetDlgItemText(IDC_VALUE_EDIT, szNewValue);
if (!szNewValue.IsEmpty()) { LRESULT lFind = SendDlgItemMessage(IDC_VALUE_LIST, LB_FINDSTRING, (WPARAM)-1, (LPARAM)(PCWSTR)szNewValue); if (lFind != LB_ERR) { //
// Ask them if they really want to add the duplicate value
//
UINT nResult = ADSIEditMessageBox(IDS_ATTREDIT_DUPLICATE_VALUE, MB_YESNO); lFind = (nResult == IDYES) ? LB_ERR : 1; }
if (lFind == LB_ERR) { SendDlgItemMessage(IDC_VALUE_LIST, LB_ADDSTRING, 0, (LPARAM)(LPCWSTR)szNewValue); } }
SetDlgItemText(IDC_VALUE_EDIT, L"");
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiStringEditor::OnRemoveButton() { if (!m_bReadOnly) { CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCurSel = pListBox->GetCurSel(); if (iCurSel != LB_ERR) { //
// Put the old value into the edit box
//
CString szOldValue; pListBox->GetText(iCurSel, szOldValue); SetDlgItemText(IDC_VALUE_EDIT, szOldValue);
//
// Delete the item from the list box
//
pListBox->DeleteString(iCurSel); } }
//
// Manage Button States
//
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiStringEditor::ManageButtonStates() { if (m_bReadOnly) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE); } else { //
// Change the default button to the Add button
//
CString szValue; GetDlgItemText(IDC_VALUE_EDIT, szValue);
if (szValue.IsEmpty()) { //
// Set the default button to OK
//
SendMessage(DM_SETDEFID, (WPARAM)IDOK, 0); SendDlgItemMessage(IDC_ATTR_ADD_BUTTON, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); } else { //
// Set the default button to the Add button
//
SendMessage(DM_SETDEFID, (WPARAM)IDC_ATTR_ADD_BUTTON, 0); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDC_ATTR_ADD_BUTTON, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); }
LRESULT lSelection = SendDlgItemMessage(IDC_VALUE_LIST, LB_GETCURSEL, 0, 0); if (lSelection != LB_ERR) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(TRUE); } else { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); } } }
void CMultiStringEditor::OnListSelChange() { ManageButtonStates(); }
void CMultiStringEditor::OnEditChange() { ManageButtonStates(); }
void CMultiStringEditor::UpdateListboxHorizontalExtent() { int nHorzExtent = 0; CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { CClientDC dc(pListBox); int nItems = pListBox->GetCount(); for (int i=0; i < nItems; i++) { TEXTMETRIC tm; VERIFY(dc.GetTextMetrics(&tm)); CString szBuffer; pListBox->GetText(i, szBuffer); CSize ext = dc.GetTextExtent(szBuffer,szBuffer.GetLength()); nHorzExtent = max(ext.cx ,nHorzExtent); } pListBox->SetHorizontalExtent(nHorzExtent); } }
HRESULT CMultiStringEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { for (int idx = 0; idx < pAttributeEditorInfo->dwNumValues; idx++) { switch (pAttributeEditorInfo->pADsValue[idx].dwType) { case ADSTYPE_CASE_IGNORE_STRING: m_szOldValueList.AddTail(pAttributeEditorInfo->pADsValue[idx].CaseIgnoreString); break;
case ADSTYPE_CASE_EXACT_STRING: m_szOldValueList.AddTail(pAttributeEditorInfo->pADsValue[idx].CaseExactString); break;
case ADSTYPE_PRINTABLE_STRING: m_szOldValueList.AddTail(pAttributeEditorInfo->pADsValue[idx].PrintableString); break;
case ADSTYPE_DN_STRING: m_szOldValueList.AddTail(pAttributeEditorInfo->pADsValue[idx].DNString); break; default: ASSERT(FALSE); break; } } } } return hr; }
// FUTURE-2002/03/05-artm Very similar functionality in CSingleStringEditor
// and CMultiStringEditor classes. Perhaps there is a way to combine the
// classes into a single class....or have one class inherit from the other.
HRESULT CMultiStringEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
int iCount = m_szNewValueList.GetCount(); if (iCount == 0) { *ppADsValue = NULL; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE[iCount]; if (*ppADsValue != NULL) { *pdwNumValues = iCount;
int idx = 0; POSITION pos = m_szNewValueList.GetHeadPosition(); while (pos != NULL) { CString szNewValue = m_szNewValueList.GetNext(pos);
(*ppADsValue)[idx].dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_CASE_IGNORE_STRING: (*ppADsValue)[idx].CaseIgnoreString = new WCHAR[wcslen(szNewValue) + 1]; if ((*ppADsValue)[idx].CaseIgnoreString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)[idx].CaseIgnoreString, szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
case ADSTYPE_CASE_EXACT_STRING: (*ppADsValue)[idx].CaseExactString = new WCHAR[wcslen(szNewValue) + 1]; if ((*ppADsValue)[idx].CaseExactString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)[idx].CaseExactString, szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
case ADSTYPE_PRINTABLE_STRING: (*ppADsValue)[idx].PrintableString = new WCHAR[wcslen(szNewValue) + 1]; if ((*ppADsValue)[idx].PrintableString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)[idx].PrintableString, szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
case ADSTYPE_DN_STRING: (*ppADsValue)[idx].DNString = new WCHAR[wcslen(szNewValue) + 1]; if ((*ppADsValue)[idx].DNString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)[idx].DNString, szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
case ADSTYPE_NUMERIC_STRING: (*ppADsValue)[idx].NumericString = new WCHAR[wcslen(szNewValue) + 1]; if ((*ppADsValue)[idx].NumericString != NULL) { // NOTICE-2002/03/05-artm wcscpy() OK.
// Both args are allocated the same amount of memory.
wcscpy((*ppADsValue)[idx].NumericString, szNewValue); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } idx++; } } else { *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CSingleIntEditor
CValueEditDialog* CreateSingleIntEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CSingleIntEditor; }
BEGIN_MESSAGE_MAP(CSingleIntEditor, CValueEditDialog) ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClear) END_MESSAGE_MAP()
BOOL CSingleIntEditor::OnInitDialog() { //
// Initialize the static control with the attribute name
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Initialize the edit box with the value
//
if (!m_bValueSet) { CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET)); SetDlgItemText(IDC_VALUE_EDIT, szNotSet); } else { SetDlgItemInt(IDC_VALUE_EDIT, m_dwOldValue, TRUE); }
//
// Select the text in the edit box
//
SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETSEL, 0, -1);
//
// Disable IME support on the edit box
//
ImmAssociateContext(::GetDlgItem(GetSafeHwnd(), IDC_VALUE_EDIT), NULL);
if (m_bReadOnly) { SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETREADONLY, TRUE, 0); GetDlgItem(IDC_CLEAR_BUTTON)->EnableWindow(FALSE); }
return CDialog::OnInitDialog(); }
void CSingleIntEditor::OnOK() { if (!m_bReadOnly) { BOOL bTranslated = FALSE; m_dwNewValue = GetDlgItemInt(IDC_VALUE_EDIT, &bTranslated, TRUE);
if (!bTranslated) { // The translation will always fail if we are in the <not set> state
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET));
CString value; GetDlgItemText(IDC_VALUE_EDIT, value);
if (value.CompareNoCase(szNotSet) != 0) { // The user probably entered some non-numeric characters
ADSIEditMessageBox(IDS_ERR_MUST_BE_NUMERIC, MB_OK | MB_ICONEXCLAMATION); } else { CDialog::OnOK(); } } else { m_bValueSet = TRUE; CDialog::OnOK(); } } else { CDialog::OnOK(); } }
HRESULT CSingleIntEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { switch (pAttributeEditorInfo->pADsValue->dwType) { case ADSTYPE_INTEGER: m_dwOldValue = pAttributeEditorInfo->pADsValue->Integer; m_bValueSet = TRUE; break;
default: ASSERT(FALSE); break; } } } return hr; }
// FUTURE-2002/03/05-artm Identical OnClear() functions...
// The OnClear() method for all of the classes that extend CValueEditDialog
// is implemented identically (or so it seems on first glance). Perhaps
// the implementation should be placed in the base class to reduce
// code size, complexity, and maintenance.
void CSingleIntEditor::OnClear() { if (!m_bReadOnly) { //
// Change the text in the edit box to "<not set>"
//
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET)); SetDlgItemText(IDC_VALUE_EDIT, szNotSet);
//
// Change the focus to the edit box
//
GetDlgItem(IDC_VALUE_EDIT)->SetFocus();
//
// Select the text in the edit box
//
SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETSEL, 0, -1);
m_bValueSet = FALSE; } }
HRESULT CSingleIntEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET));
if (!m_bValueSet) { *ppADsValue = NULL; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE; if (*ppADsValue != NULL) { *pdwNumValues = 1; (*ppADsValue)->dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_INTEGER: (*ppADsValue)->Integer = m_dwNewValue; break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } } else { *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CMultiIntEditor
CValueEditDialog* CreateMultiIntEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CMultiIntEditor; }
BEGIN_MESSAGE_MAP(CMultiIntEditor, CValueEditDialog) ON_BN_CLICKED(IDC_ATTR_ADD_BUTTON, OnAddButton) ON_BN_CLICKED(IDC_ATTR_REMOVE_BUTTON, OnRemoveButton) ON_LBN_SELCHANGE(IDC_VALUE_LIST, OnListSelChange) ON_EN_CHANGE(IDC_VALUE_EDIT, OnEditChange) END_MESSAGE_MAP()
BOOL CMultiIntEditor::OnInitDialog() { CDialog::OnInitDialog();
//
// Set the attribute name static
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Disable IME support on the edit box
//
ImmAssociateContext(::GetDlgItem(GetSafeHwnd(), IDC_VALUE_EDIT), NULL);
//
// Fill the list box with the current values
//
POSITION pos = m_oldValueList.GetHeadPosition(); while (pos != NULL) { int value = m_oldValueList.GetNext(pos);
// Convert value to string
CString stringValue; stringValue.Format(L"%d", value);
// Add string to list box
LRESULT index = SendDlgItemMessage( IDC_VALUE_LIST, LB_ADDSTRING, 0, (LPARAM)(LPCWSTR)stringValue);
// Attach the int value to the list box item
if (index != LB_ERR) { SendDlgItemMessage( IDC_VALUE_LIST, LB_SETITEMDATA, (WPARAM)index, (LPARAM)value); } }
//
// The remove button should be disabled until something is selected in the listbox
//
GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_VALUE_EDIT)->SetFocus();
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent();
if (m_bReadOnly) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE); SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETREADONLY, TRUE, 0); }
//
// NOTE: I have explicitly set the focus so return 0
//
return FALSE; }
void CMultiIntEditor::OnOK() { if (!m_bReadOnly) { //
// Get the values out of the list box
//
m_newValueList.RemoveAll();
CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCount = pListBox->GetCount(); for (int idx = 0; idx < iCount; idx++) { int newValue; newValue = static_cast<int>(pListBox->GetItemData(idx));
m_newValueList.AddTail(newValue); } } } CDialog::OnOK(); }
void CMultiIntEditor::OnAddButton() { if (!m_bReadOnly) { //
// Add the value to the list box and clear the edit field
//
int newValue = 0; BOOL trans = FALSE;
newValue = GetDlgItemInt(IDC_VALUE_EDIT, &trans, TRUE);
CString szNewValue; GetDlgItemText(IDC_VALUE_EDIT, szNewValue);
if (trans && !szNewValue.IsEmpty()) { LRESULT lFind = SendDlgItemMessage(IDC_VALUE_LIST, LB_FINDSTRING, (WPARAM)-1, (LPARAM)(PCWSTR)szNewValue); if (lFind != LB_ERR) { //
// Ask them if they really want to add the duplicate value
//
UINT nResult = ADSIEditMessageBox(IDS_ATTREDIT_DUPLICATE_VALUE, MB_YESNO); lFind = (nResult == IDYES) ? LB_ERR : 1; }
if (lFind == LB_ERR) { // Add the string to the list box
LRESULT index = SendDlgItemMessage( IDC_VALUE_LIST, LB_ADDSTRING, 0, (LPARAM)(LPCWSTR)szNewValue);
if (index != LB_ERR) { // Set the item data to the integer value
SendDlgItemMessage( IDC_VALUE_LIST, LB_SETITEMDATA, (WPARAM)index, (LPARAM)newValue); } } SetDlgItemText(IDC_VALUE_EDIT, L""); } else { //
// I was unable to convert the value to an integer so tell
// the user they can only enter digits from 0 to 9 and the
// - (negative) sign
//
ADSIEditMessageBox(IDS_ERR_MUST_BE_NUMERIC, MB_OK); }
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiIntEditor::OnRemoveButton() { if (!m_bReadOnly) { CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCurSel = pListBox->GetCurSel(); if (iCurSel != LB_ERR) { //
// Put the old value into the edit box
//
CString szOldValue; pListBox->GetText(iCurSel, szOldValue); SetDlgItemText(IDC_VALUE_EDIT, szOldValue);
//
// Delete the item from the list box
//
pListBox->DeleteString(iCurSel); } }
//
// Manage Button States
//
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiIntEditor::ManageButtonStates() { if (m_bReadOnly) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE); } else { //
// Change the default button to the Add button
//
int value = 0; BOOL trans = FALSE;
value = GetDlgItemInt(IDC_VALUE_EDIT, &trans, TRUE);
if (!trans) { //
// Set the default button to OK
//
SendMessage(DM_SETDEFID, (WPARAM)IDOK, 0); SendDlgItemMessage(IDC_ATTR_ADD_BUTTON, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); } else { //
// Set the default button to the Add button
//
SendMessage(DM_SETDEFID, (WPARAM)IDC_ATTR_ADD_BUTTON, 0); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDC_ATTR_ADD_BUTTON, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); }
LRESULT lSelection = SendDlgItemMessage(IDC_VALUE_LIST, LB_GETCURSEL, 0, 0); if (lSelection != LB_ERR) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(TRUE); } else { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); } } }
void CMultiIntEditor::OnListSelChange() { ManageButtonStates(); }
void CMultiIntEditor::OnEditChange() { ManageButtonStates(); }
void CMultiIntEditor::UpdateListboxHorizontalExtent() { int nHorzExtent = 0; CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { CClientDC dc(pListBox); int nItems = pListBox->GetCount(); for (int i=0; i < nItems; i++) { TEXTMETRIC tm; VERIFY(dc.GetTextMetrics(&tm)); CString szBuffer; pListBox->GetText(i, szBuffer); CSize ext = dc.GetTextExtent(szBuffer,szBuffer.GetLength()); nHorzExtent = max(ext.cx ,nHorzExtent); } pListBox->SetHorizontalExtent(nHorzExtent); } }
HRESULT CMultiIntEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { for (int idx = 0; idx < pAttributeEditorInfo->dwNumValues; idx++) { switch (pAttributeEditorInfo->pADsValue[idx].dwType) { case ADSTYPE_INTEGER: m_oldValueList.AddTail(pAttributeEditorInfo->pADsValue[idx].Integer); break;
default: ASSERT(FALSE); break; } } } } return hr; }
// FUTURE-2002/03/05-artm Very similar functionality in CSingleIntEditor
// and CMultiStringEditor classes. Perhaps there is a way to combine the
// classes into a single class....or have one class inherit from the other.
HRESULT CMultiIntEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
int iCount = m_newValueList.GetCount(); if (iCount == 0) { *ppADsValue = NULL; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE[iCount]; if (*ppADsValue != NULL) { *pdwNumValues = iCount;
int idx = 0; POSITION pos = m_newValueList.GetHeadPosition(); while (pos != NULL) { int newValue = m_newValueList.GetNext(pos);
(*ppADsValue)[idx].dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_INTEGER: (*ppADsValue)[idx].Integer = newValue; break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } idx++; } } else { *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CSingleLargeIntEditor
CValueEditDialog* CreateSingleLargeIntEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CSingleLargeIntEditor; }
BEGIN_MESSAGE_MAP(CSingleLargeIntEditor, CValueEditDialog) ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClear) END_MESSAGE_MAP()
BOOL CSingleLargeIntEditor::OnInitDialog() { //
// Initialize the static control with the attribute name
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Initialize the edit box with the value
//
if (!m_bValueSet) { CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET)); SetDlgItemText(IDC_VALUE_EDIT, szNotSet); } else { CString szOldValue; litow(m_liOldValue, szOldValue); SetDlgItemText(IDC_VALUE_EDIT, szOldValue); }
//
// Select the text in the edit box
//
SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETSEL, 0, -1);
//
// Disable IME support on the edit box
//
ImmAssociateContext(::GetDlgItem(GetSafeHwnd(), IDC_VALUE_EDIT), NULL);
if (m_bReadOnly) { SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETREADONLY, TRUE, 0); GetDlgItem(IDC_CLEAR_BUTTON)->EnableWindow(FALSE); }
return CDialog::OnInitDialog(); }
void CSingleLargeIntEditor::OnOK() { if (!m_bReadOnly) { CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET));
CString szNewValue; GetDlgItemText(IDC_VALUE_EDIT, szNewValue);
if (szNewValue == szNotSet) { m_bValueSet = FALSE; } else { wtoli(szNewValue, m_liNewValue); m_bValueSet = TRUE; } } CDialog::OnOK(); }
HRESULT CSingleLargeIntEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { switch (pAttributeEditorInfo->pADsValue->dwType) { case ADSTYPE_LARGE_INTEGER: m_liOldValue = pAttributeEditorInfo->pADsValue->LargeInteger; m_bValueSet = TRUE; break;
default: ASSERT(FALSE); break; } } else { m_bValueSet = FALSE; } } return hr; }
void CSingleLargeIntEditor::OnClear() { if (!m_bReadOnly) { //
// Change the text in the edit box to "<not set>"
//
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET)); SetDlgItemText(IDC_VALUE_EDIT, szNotSet);
//
// Change the focus to the edit box
//
GetDlgItem(IDC_VALUE_EDIT)->SetFocus();
//
// Select the text in the edit box
//
SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETSEL, 0, -1);
m_bValueSet = FALSE; } }
HRESULT CSingleLargeIntEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
if (!m_bValueSet) { *ppADsValue = NULL; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE; if (*ppADsValue != NULL) { *pdwNumValues = 1; (*ppADsValue)->dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_LARGE_INTEGER: (*ppADsValue)->LargeInteger = m_liNewValue; break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } } else { *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CSingleBooleanEditor
CValueEditDialog* CreateSingleBooleanEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CSingleBooleanEditor; }
BEGIN_MESSAGE_MAP(CSingleBooleanEditor, CValueEditDialog) END_MESSAGE_MAP()
BOOL CSingleBooleanEditor::OnInitDialog() { //
// Initialize the static control with the attribute name
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Initialize the edit box with the value
//
if (!m_bValueSet) { SendDlgItemMessage(IDC_NOTSET_RADIO, BM_SETCHECK, BST_CHECKED, 0); } else { if (m_bOldValue) { SendDlgItemMessage(IDC_TRUE_RADIO, BM_SETCHECK, BST_CHECKED, 0); } else { SendDlgItemMessage(IDC_FALSE_RADIO, BM_SETCHECK, BST_CHECKED, 0); } }
if (m_bReadOnly) { GetDlgItem(IDC_TRUE_RADIO)->EnableWindow(FALSE); GetDlgItem(IDC_FALSE_RADIO)->EnableWindow(FALSE); } return CDialog::OnInitDialog(); }
void CSingleBooleanEditor::OnOK() { if (!m_bReadOnly) { LRESULT lTrueCheck = SendDlgItemMessage(IDC_TRUE_RADIO, BM_GETCHECK, 0, 0); LRESULT lFalseCheck = SendDlgItemMessage(IDC_FALSE_RADIO, BM_GETCHECK, 0, 0); LRESULT lNotSetCheck = SendDlgItemMessage(IDC_NOTSET_RADIO, BM_GETCHECK, 0, 0);
if (lTrueCheck == BST_CHECKED) { m_bNewValue = TRUE; m_bValueSet = TRUE; }
if (lFalseCheck == BST_CHECKED) { m_bNewValue = FALSE; m_bValueSet = TRUE; }
if (lNotSetCheck == BST_CHECKED) { m_bValueSet = FALSE; } } CDialog::OnOK(); }
HRESULT CSingleBooleanEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { switch (pAttributeEditorInfo->pADsValue->dwType) { case ADSTYPE_BOOLEAN: m_bOldValue = pAttributeEditorInfo->pADsValue->Boolean; m_bValueSet = TRUE; break;
default: ASSERT(FALSE); break; } } else { m_bValueSet = FALSE; } } return hr; }
HRESULT CSingleBooleanEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
if (!m_bValueSet) { *ppADsValue = NULL; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE; if (*ppADsValue != NULL) { *pdwNumValues = 1; (*ppADsValue)->dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_BOOLEAN: (*ppADsValue)->Boolean = m_bNewValue; break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } } else { *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CMultiBooleanEditor
CValueEditDialog* CreateMultiBooleanEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CMultiBooleanEditor; }
BEGIN_MESSAGE_MAP(CMultiBooleanEditor, CValueEditDialog) ON_BN_CLICKED(IDC_ATTR_ADD_BUTTON, OnAddButton) ON_BN_CLICKED(IDC_ATTR_REMOVE_BUTTON, OnRemoveButton) ON_LBN_SELCHANGE(IDC_VALUE_LIST, OnListSelChange) ON_BN_CLICKED(IDC_TRUE_RADIO, OnRadioChange) ON_BN_CLICKED(IDC_FALSE_RADIO, OnRadioChange) END_MESSAGE_MAP()
BOOL CMultiBooleanEditor::OnInitDialog() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CDialog::OnInitDialog();
//
// Set the attribute name static
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Fill the list box with the current values
//
CString szTrue; szTrue.LoadString(IDS_TRUE);
CString szFalse; szFalse.LoadString(IDS_FALSE);
POSITION pos = m_bOldValueList.GetHeadPosition(); while (pos != NULL) { BOOL bValue = m_bOldValueList.GetNext(pos); SendDlgItemMessage(IDC_VALUE_LIST, LB_ADDSTRING, 0, (LPARAM)(LPCWSTR)(bValue ? szTrue : szFalse)); }
//
// The remove button should be disabled until something is selected in the listbox
//
GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE);
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent();
if (m_bReadOnly) { GetDlgItem(IDC_TRUE_RADIO)->EnableWindow(FALSE); GetDlgItem(IDC_FALSE_RADIO)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE); }
//
// NOTE: I have explicitly set the focus so return 0
//
return FALSE; }
void CMultiBooleanEditor::OnOK() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!m_bReadOnly) { //
// Get the values out of the list box
//
m_bNewValueList.RemoveAll();
CString szTrue; szTrue.LoadString(IDS_TRUE);
CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCount = pListBox->GetCount(); for (int idx = 0; idx < iCount; idx++) { CString szNewValue; pListBox->GetText(idx, szNewValue);
if (szNewValue.CompareNoCase(szTrue) == 0) { m_bNewValueList.AddTail(TRUE); } else { m_bNewValueList.AddTail(FALSE); } } } } CDialog::OnOK(); }
void CMultiBooleanEditor::OnAddButton() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!m_bReadOnly) { //
// Add the value to the list box and clear the edit field
//
CString szNewValue; LRESULT result = SendDlgItemMessage(IDC_TRUE_RADIO, BM_GETCHECK, 0, 0); if (result == BST_CHECKED) { szNewValue.LoadString(IDS_TRUE); } else { szNewValue.LoadString(IDS_FALSE); }
SendDlgItemMessage(IDC_VALUE_LIST, LB_ADDSTRING, 0, (LPARAM)(LPCWSTR)szNewValue);
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiBooleanEditor::OnRemoveButton() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!m_bReadOnly) { CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCurSel = pListBox->GetCurSel(); if (iCurSel != LB_ERR) { //
// Put the old value into the radio buttons
//
CString szOldValue; pListBox->GetText(iCurSel, szOldValue); SetDlgItemText(IDC_VALUE_EDIT, szOldValue);
CString szTrue; szTrue.LoadString(IDS_TRUE);
if (szOldValue.CompareNoCase(szTrue) == 0) { SendDlgItemMessage(IDC_TRUE_RADIO, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(IDC_FALSE_RADIO, BM_SETCHECK, BST_UNCHECKED, 0); } else { SendDlgItemMessage(IDC_TRUE_RADIO, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(IDC_FALSE_RADIO, BM_SETCHECK, BST_CHECKED, 0); }
//
// Delete the item from the list box
//
pListBox->DeleteString(iCurSel); } }
//
// Manage Button States
//
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiBooleanEditor::ManageButtonStates() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (m_bReadOnly) { GetDlgItem(IDC_TRUE_RADIO)->EnableWindow(FALSE); GetDlgItem(IDC_FALSE_RADIO)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE); } else { //
// Change the default button to the Add button
//
LRESULT trueResult = SendDlgItemMessage(IDC_TRUE_RADIO, BM_GETCHECK, 0, 0); LRESULT falseResult = SendDlgItemMessage(IDC_FALSE_RADIO, BM_GETCHECK, 0, 0);
if (trueResult != BST_CHECKED && falseResult != BST_CHECKED) { //
// Set the default button to OK
//
SendMessage(DM_SETDEFID, (WPARAM)IDOK, 0); SendDlgItemMessage(IDC_ATTR_ADD_BUTTON, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); } else { //
// Set the default button to the Add button
//
SendMessage(DM_SETDEFID, (WPARAM)IDC_ATTR_ADD_BUTTON, 0); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDC_ATTR_ADD_BUTTON, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); }
LRESULT lSelection = SendDlgItemMessage(IDC_VALUE_LIST, LB_GETCURSEL, 0, 0); if (lSelection != LB_ERR) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(TRUE); } else { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); } } }
void CMultiBooleanEditor::OnListSelChange() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); ManageButtonStates(); }
void CMultiBooleanEditor::OnRadioChange() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); ManageButtonStates(); }
void CMultiBooleanEditor::UpdateListboxHorizontalExtent() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
int nHorzExtent = 0; CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { CClientDC dc(pListBox); int nItems = pListBox->GetCount(); for (int i=0; i < nItems; i++) { TEXTMETRIC tm = {0}; VERIFY(dc.GetTextMetrics(&tm)); CString szBuffer; pListBox->GetText(i, szBuffer); CSize ext = dc.GetTextExtent(szBuffer,szBuffer.GetLength()); nHorzExtent = max(ext.cx ,nHorzExtent); } pListBox->SetHorizontalExtent(nHorzExtent); } }
HRESULT CMultiBooleanEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { for (int idx = 0; idx < pAttributeEditorInfo->dwNumValues; idx++) { switch (pAttributeEditorInfo->pADsValue[idx].dwType) { case ADSTYPE_BOOLEAN: m_bOldValueList.AddTail(pAttributeEditorInfo->pADsValue[idx].Boolean); break;
default: ASSERT(FALSE); break; } } } } return hr; }
HRESULT CMultiBooleanEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
int iCount = m_bNewValueList.GetCount(); if (iCount == 0) { *ppADsValue = NULL; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE[iCount]; if (*ppADsValue != NULL) { *pdwNumValues = iCount;
int idx = 0; POSITION pos = m_bNewValueList.GetHeadPosition(); while (pos != NULL) { BOOL bNewValue = m_bNewValueList.GetNext(pos);
(*ppADsValue)[idx].dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_BOOLEAN: (*ppADsValue)[idx].Boolean = bNewValue; break;
default: ASSERT(FALSE);
DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } idx++; } } else { *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CSingleTimeEditor
CValueEditDialog* CreateSingleTimeEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CSingleTimeEditor; }
BEGIN_MESSAGE_MAP(CSingleTimeEditor, CValueEditDialog) END_MESSAGE_MAP()
BOOL CSingleTimeEditor::OnInitDialog() { //
// Initialize the static control with the attribute name
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
if (m_bValueSet) { SendDlgItemMessage(IDC_DATE_PICKER, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&m_stOldValue); SendDlgItemMessage(IDC_TIME_PICKER, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&m_stOldValue); } else { SendDlgItemMessage(IDC_DATE_PICKER, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&m_stOldValue); SendDlgItemMessage(IDC_TIME_PICKER, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&m_stOldValue); }
if (m_bReadOnly) { GetDlgItem(IDC_DATE_PICKER)->EnableWindow(FALSE); GetDlgItem(IDC_TIME_PICKER)->EnableWindow(FALSE); }
return CDialog::OnInitDialog(); }
void CSingleTimeEditor::OnOK() { if (!m_bReadOnly) { SYSTEMTIME stDateResult = {0}; SYSTEMTIME stTimeResult = {0};
LRESULT lDateRes = SendDlgItemMessage(IDC_DATE_PICKER, DTM_GETSYSTEMTIME, 0, (LPARAM)&stDateResult); LRESULT lTimeRes = SendDlgItemMessage(IDC_TIME_PICKER, DTM_GETSYSTEMTIME, 0, (LPARAM)&stTimeResult);
if (lDateRes == GDT_VALID || lTimeRes == GDT_VALID) { memcpy(&m_stNewValue, &stDateResult, sizeof(SYSTEMTIME)); m_stNewValue.wHour = stTimeResult.wHour; m_stNewValue.wMinute = stTimeResult.wMinute; m_stNewValue.wSecond = stTimeResult.wSecond; m_stNewValue.wMilliseconds = stTimeResult.wMilliseconds; } } CDialog::OnOK(); }
HRESULT CSingleTimeEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { switch (pAttributeEditorInfo->pADsValue->dwType) { case ADSTYPE_UTC_TIME: // NOTICE-2002/03/05-artm memcpy() OK...
// arg1 always valid pointer; arg2 valid ptr if
// pAttributeEditorInfo->pADsValue not NULL
// (which is the case if we've gotten this far)
memcpy(&m_stOldValue, &(pAttributeEditorInfo->pADsValue->UTCTime), sizeof(SYSTEMTIME)); m_bValueSet = TRUE; break;
default: ASSERT(FALSE); // NTRAID#NTBUG9-565760-2002/03/05-artm Release code should return error code,
// not S_OK.
break; } } else { m_bValueSet = FALSE; } } return hr; }
HRESULT CSingleTimeEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
*ppADsValue = new ADSVALUE; if (*ppADsValue != NULL) { *pdwNumValues = 1; (*ppADsValue)->dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_UTC_TIME: memcpy(&((*ppADsValue)->UTCTime), &m_stNewValue, sizeof(SYSTEMTIME)); break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } } else { *pdwNumValues = 0; hr = E_OUTOFMEMORY; } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CMultiTimeEditor
CValueEditDialog* CreateMultiTimeEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CMultiTimeEditor; }
BEGIN_MESSAGE_MAP(CMultiTimeEditor, CValueEditDialog) ON_BN_CLICKED(IDC_ATTR_ADD_BUTTON, OnAddButton) ON_BN_CLICKED(IDC_ATTR_REMOVE_BUTTON, OnRemoveButton) ON_LBN_SELCHANGE(IDC_VALUE_LIST, OnListSelChange) END_MESSAGE_MAP()
BOOL CMultiTimeEditor::OnInitDialog() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CDialog::OnInitDialog();
//
// Set the attribute name static
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Fill the list box with the current values
//
CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST));
POSITION pos = m_stOldValueList.GetHeadPosition(); while (pos != NULL) { SYSTEMTIME* pstValue = m_stOldValueList.GetNext(pos);
CString szValue = GetStringValueFromSystemTime(pstValue); int index = pListBox->AddString(szValue); if (LB_ERR != index) { pListBox->SetItemDataPtr(index, pstValue); } }
//
// The remove button should be disabled until something is selected in the listbox
//
GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE);
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent();
if (m_bReadOnly) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_DATE_PICKER)->EnableWindow(FALSE); GetDlgItem(IDC_TIME_PICKER)->EnableWindow(FALSE); }
//
// NOTE: I have explicitly set the focus so return 0
//
return FALSE; }
void CMultiTimeEditor::OnOK() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!m_bReadOnly) { //
// Get the values out of the list box
//
m_stNewValueList.RemoveAll();
CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCount = pListBox->GetCount(); for (int idx = 0; idx < iCount; idx++) { SYSTEMTIME* pstValue = reinterpret_cast<SYSTEMTIME*>(pListBox->GetItemDataPtr(idx)); m_stNewValueList.AddTail(pstValue); } } } CDialog::OnOK(); }
void CMultiTimeEditor::OnAddButton() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!m_bReadOnly) { //
// Add the value to the list box and clear the edit field
//
SYSTEMTIME stDateResult = {0}; SYSTEMTIME stTimeResult = {0}; SYSTEMTIME* pstFullResult = new SYSTEMTIME; if (!pstFullResult) { return; }
ZeroMemory(pstFullResult, sizeof(SYSTEMTIME));
LRESULT lDateRes = SendDlgItemMessage(IDC_DATE_PICKER, DTM_GETSYSTEMTIME, 0, (LPARAM)&stDateResult); LRESULT lTimeRes = SendDlgItemMessage(IDC_TIME_PICKER, DTM_GETSYSTEMTIME, 0, (LPARAM)&stTimeResult);
if (lDateRes == GDT_VALID || lTimeRes == GDT_VALID) { memcpy(pstFullResult, &stDateResult, sizeof(SYSTEMTIME)); pstFullResult->wHour = stTimeResult.wHour; pstFullResult->wMinute = stTimeResult.wMinute; pstFullResult->wSecond = stTimeResult.wSecond; pstFullResult->wMilliseconds = stTimeResult.wMilliseconds;
// Convert into a string that can be added to the list
CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { CString szValue = GetStringValueFromSystemTime(pstFullResult); int index = pListBox->AddString(szValue); if (LB_ERR != index) { pListBox->SetItemDataPtr(index, pstFullResult); } } }
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiTimeEditor::OnRemoveButton() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!m_bReadOnly) { CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCurSel = pListBox->GetCurSel(); if (iCurSel != LB_ERR) { //
// Delete the item from the list box
//
pListBox->DeleteString(iCurSel); } }
//
// Manage Button States
//
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiTimeEditor::ManageButtonStates() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (m_bReadOnly) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_DATE_PICKER)->EnableWindow(FALSE); GetDlgItem(IDC_TIME_PICKER)->EnableWindow(FALSE); } else { //
// Change the default button to the Add button
//
SYSTEMTIME stDateResult = {0}; SYSTEMTIME stTimeResult = {0};
LRESULT lDateRes = SendDlgItemMessage(IDC_DATE_PICKER, DTM_GETSYSTEMTIME, 0, (LPARAM)&stDateResult); LRESULT lTimeRes = SendDlgItemMessage(IDC_TIME_PICKER, DTM_GETSYSTEMTIME, 0, (LPARAM)&stTimeResult);
if (lDateRes == GDT_VALID && lTimeRes == GDT_VALID) { //
// Set the default button to OK
//
SendMessage(DM_SETDEFID, (WPARAM)IDOK, 0); SendDlgItemMessage(IDC_ATTR_ADD_BUTTON, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); } else { //
// Set the default button to the Add button
//
SendMessage(DM_SETDEFID, (WPARAM)IDC_ATTR_ADD_BUTTON, 0); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDC_ATTR_ADD_BUTTON, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); }
LRESULT lSelection = SendDlgItemMessage(IDC_VALUE_LIST, LB_GETCURSEL, 0, 0); if (lSelection != LB_ERR) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(TRUE); } else { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); } } }
void CMultiTimeEditor::OnListSelChange() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); ManageButtonStates(); }
void CMultiTimeEditor::UpdateListboxHorizontalExtent() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
int nHorzExtent = 0; CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { CClientDC dc(pListBox); int nItems = pListBox->GetCount(); for (int i=0; i < nItems; i++) { TEXTMETRIC tm = {0}; VERIFY(dc.GetTextMetrics(&tm)); CString szBuffer; pListBox->GetText(i, szBuffer); CSize ext = dc.GetTextExtent(szBuffer,szBuffer.GetLength()); nHorzExtent = max(ext.cx ,nHorzExtent); } pListBox->SetHorizontalExtent(nHorzExtent); } }
HRESULT CMultiTimeEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { for (int idx = 0; idx < pAttributeEditorInfo->dwNumValues; idx++) { switch (pAttributeEditorInfo->pADsValue[idx].dwType) { case ADSTYPE_UTC_TIME: m_stOldValueList.AddTail(&(pAttributeEditorInfo->pADsValue[idx].UTCTime)); break;
default: ASSERT(FALSE); break; } } } } return hr; }
HRESULT CMultiTimeEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
int iCount = m_stNewValueList.GetCount(); if (iCount == 0) { *ppADsValue = NULL; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE[iCount]; if (*ppADsValue != NULL) { *pdwNumValues = iCount;
int idx = 0; POSITION pos = m_stNewValueList.GetHeadPosition(); while (pos != NULL) { SYSTEMTIME* pstNewValue = m_stNewValueList.GetNext(pos);
(*ppADsValue)[idx].dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_UTC_TIME: memcpy(&((*ppADsValue)[idx].UTCTime), pstNewValue, sizeof(SYSTEMTIME)); break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = NULL; *pdwNumValues = 0; hr = E_FAIL; break; } idx++; } } else { *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// COctetStringEditor
CValueEditDialog* CreateSingleOctetStringEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new COctetStringEditor; }
BEGIN_MESSAGE_MAP(COctetStringEditor, CValueEditDialog) ON_EN_CHANGE(IDC_PROCESS_EDIT, OnProcessEdit) ON_BN_CLICKED(IDC_ATTR_EDIT_BUTTON, OnEditButton) ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClearButton) END_MESSAGE_MAP()
BOOL COctetStringEditor::OnInitDialog() { //
// Initialize the static control with the attribute name
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
DWORD dwDisplayFlags = BYTE_ARRAY_DISPLAY_HEX | BYTE_ARRAY_DISPLAY_DEC | BYTE_ARRAY_DISPLAY_OCT | BYTE_ARRAY_DISPLAY_BIN;
VERIFY(m_display.Initialize(IDC_VALUE_EDIT, IDC_VIEW_TYPE_COMBO, dwDisplayFlags, BYTE_ARRAY_DISPLAY_HEX, // default display
this, 1024, IDS_OCTET_DISPLAY_SIZE_EXCEEDED)); // Only show 1K of data in the edit box
m_display.SetData(m_pOldValue, m_dwOldLength);
if (m_bReadOnly) { SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETREADONLY, TRUE, 0); GetDlgItem(IDC_CLEAR_BUTTON)->EnableWindow(FALSE);
CString szView; BOOL bResult = szView.LoadString(IDS_VIEW); ASSERT(bResult); SetDlgItemText(IDC_ATTR_EDIT_BUTTON, szView); }
return CDialog::OnInitDialog(); }
void COctetStringEditor::OnOK() { if (!m_bReadOnly) { //
// Retrieve the new values from the control
//
if (m_pNewValue) { delete[] m_pNewValue; m_pNewValue = 0; m_dwNewLength = 0; } m_dwNewLength = m_display.GetData(&m_pNewValue); }
CDialog::OnOK(); }
void COctetStringEditor::OnProcessEdit() { CString szProcess; GetDlgItemText(IDC_PROCESS_EDIT, szProcess); if (szProcess.IsEmpty()) { GetDlgItem(IDC_ATTR_EDIT_BUTTON)->EnableWindow(FALSE);
//
// Set the default button to OK
//
SendMessage(DM_SETDEFID, (WPARAM)IDOK, 0); SendDlgItemMessage(IDC_ATTR_EDIT_BUTTON, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); } else { GetDlgItem(IDC_ATTR_EDIT_BUTTON)->EnableWindow(TRUE);
//
// Set the default button to the Edit button
//
SendMessage(DM_SETDEFID, (WPARAM)IDC_ATTR_EDIT_BUTTON, 0); SendDlgItemMessage(IDOK, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); SendDlgItemMessage(IDC_ATTR_EDIT_BUTTON, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); } }
void COctetStringEditor::OnEditButton() { CString szProcess; GetDlgItemText(IDC_PROCESS_EDIT, szProcess);
//
// Create a temp file and write out the contents of the octet string
//
WCHAR szTempPath[MAX_PATH]; if (!::GetTempPath(MAX_PATH, szTempPath)) { ADSIEditMessageBox(IDS_MSG_FAIL_CREATE_TEMPFILE, MB_OK); return; } CString szDataPath; if (!::GetTempFileName(szTempPath, _T("attredit"), 0x0, szDataPath.GetBuffer(MAX_PATH))) { ADSIEditMessageBox(IDS_MSG_FAIL_CREATE_TEMPFILE, MB_OK); return; } szDataPath.ReleaseBuffer();
//
// Open the temp file so we can write out the data
//
CFile tempDataFile; if (!tempDataFile.Open(szDataPath, CFile::modeCreate | CFile::modeReadWrite |CFile::shareExclusive | CFile::typeBinary)) { //
// Failed to open temp file, display error message
//
ADSIEditMessageBox(IDS_MSG_FAIL_CREATE_TEMPFILE, MB_OK); return; }
//
// Write the byte array to a temp file
//
BYTE* pData = 0; DWORD dwDataLength = m_display.GetData(&pData); if (dwDataLength != 0 && pData) { tempDataFile.Write(pData, dwDataLength); } tempDataFile.Close();
if (pData) { delete[] pData; pData = 0; } dwDataLength = 0;
//
// Construct the command line from the executable and the temp file
//
CString szCommandLine = szProcess + L" " + szDataPath;
//
// Launch the process with the temp file as an argument
//
STARTUPINFO si; PROCESS_INFORMATION pi;
::ZeroMemory(&pi,sizeof(PROCESS_INFORMATION)); ::ZeroMemory(&si,sizeof(STARTUPINFO)); si.cb = sizeof (STARTUPINFO);
// NTRAID#NTBUG9-566011-2002/03/05-artm CreateProcess() incorrectly used.
// Vulnerability exists b/c application name is NULL, meaning that
// the first whitespace delimited token in the command line is the
// executable name. This opens up a hole for trojan programs
// (e.g. C:\Program.exe).
//
// Since we have the process name separate from data path,
// fix is to pass szProcess as first argument and szDataPath
// as command line argument.
//
// I couldn't tell if the program name and data path were
// complete paths or not---but they should be if they are not!
if(CreateProcess( NULL, (LPWSTR)(LPCWSTR)szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) ) { // wait to finish the runing setup process
WaitForSingleObject(pi.hProcess,INFINITE); // close process handle
if (pi.hProcess && pi.hProcess != INVALID_HANDLE_VALUE) { CloseHandle (pi.hProcess) ; } if (pi.hThread && pi.hThread != INVALID_HANDLE_VALUE) { CloseHandle (pi.hThread) ; } } else { ADSIEditMessageBox(IDS_MSG_FAIL_LAUNCH_PROCESS, MB_OK); return; }
if (!m_bReadOnly) { //
// Load the data from the saved temp file
//
if (!LoadFileAsByteArray(szDataPath, &pData, &dwDataLength)) { ADSIEditMessageBox(IDS_MSG_FAIL_RETRIEVE_SAVED_DATA, MB_OK); return; }
//
// Delete temp file after picture is displayed
//
CFile::Remove(szDataPath);
//
// Update the UI with the new data
//
m_display.SetData(pData, dwDataLength); } }
void COctetStringEditor::OnClearButton() { if (!m_bReadOnly) { m_display.ClearData(); } }
HRESULT COctetStringEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue) { switch (pAttributeEditorInfo->pADsValue->dwType) { case ADSTYPE_OCTET_STRING: m_dwOldLength = pAttributeEditorInfo->pADsValue->OctetString.dwLength; m_pOldValue = new BYTE[m_dwOldLength]; if (m_pOldValue) { // NOTICE-2002/03/05-artm memcpy() OK.
// arg1 is same size as lpValue
memcpy(m_pOldValue, pAttributeEditorInfo->pADsValue->OctetString.lpValue, m_dwOldLength); } else { hr = E_OUTOFMEMORY; }
m_bValueSet = TRUE; break;
default: ASSERT(FALSE); break; } } else { m_bValueSet = FALSE; } } return hr; }
HRESULT COctetStringEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
if (m_dwNewLength > 0 && m_pNewValue) { *ppADsValue = new ADSVALUE; if (*ppADsValue) { *pdwNumValues = 1; (*ppADsValue)->dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_OCTET_STRING: (*ppADsValue)->OctetString.dwLength = m_dwNewLength; (*ppADsValue)->OctetString.lpValue = new BYTE[m_dwNewLength]; if ((*ppADsValue)->OctetString.lpValue) { // NOTICE-2002/03/05-artm memcpy() OK.
// arg1 and arg2 both m_dwNewLength in size.
memcpy((*ppADsValue)->OctetString.lpValue, m_pNewValue, m_dwNewLength); } else { hr = E_OUTOFMEMORY; } break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = 0; *pdwNumValues = 0; hr = E_FAIL; break; } } else { *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } else { *ppADsValue = 0; *pdwNumValues = 0; } return hr; }
CValueEditDialog* CreateMultiOctetStringEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CMultiOctetStringEditor; }
BEGIN_MESSAGE_MAP(CMultiOctetStringEditor, CValueEditDialog) ON_BN_CLICKED(IDC_ATTR_ADD_BUTTON, OnAddButton) ON_BN_CLICKED(IDC_ATTR_REMOVE_BUTTON, OnRemoveButton) ON_BN_CLICKED(IDC_EDIT_BUTTON, OnEditButton) ON_LBN_SELCHANGE(IDC_VALUE_LIST, OnListSelChange) END_MESSAGE_MAP()
BOOL CMultiOctetStringEditor::OnInitDialog() { CDialog::OnInitDialog();
//
// Set the attribute name static
//
SetDlgItemText(IDC_ATTRIBUTE_STATIC, m_szAttribute);
//
// Fill the list box with the current values
//
POSITION pos = m_OldValueList.GetHeadPosition(); while (pos) { PADSVALUE pADsValue = m_OldValueList.GetNext(pos); if (pADsValue) { CString szValue; GetStringFromADsValue(pADsValue, szValue, MAX_OCTET_STRING_VALUE_LENGTH); LRESULT lIdx = SendDlgItemMessage(IDC_VALUE_LIST, LB_ADDSTRING, 0, (LPARAM)(LPCWSTR)szValue); if (lIdx != LB_ERR && lIdx != LB_ERRSPACE) { LRESULT lSetData = SendDlgItemMessage(IDC_VALUE_LIST, LB_SETITEMDATA, (WPARAM)lIdx, (LPARAM)pADsValue); if (lSetData == LB_ERR) { ASSERT(lSetData != LB_ERR); continue; } } } }
//
// The remove button should be disabled until something is selected in the listbox
//
GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); SendDlgItemMessage(IDC_VALUE_LIST, LB_SETCURSEL, 0, 0);
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent();
if (m_bReadOnly) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_ATTR_ADD_BUTTON)->EnableWindow(FALSE);
CString szView; BOOL bResult = szView.LoadString(IDS_VIEW); ASSERT(bResult); SetDlgItemText(IDC_EDIT_BUTTON, szView); } //
// NOTE: I have explicitly set the focus so return 0
//
return FALSE; }
void CMultiOctetStringEditor::OnOK() { if (!m_bReadOnly) { //
// Get the values out of the list box
//
m_NewValueList.RemoveAll();
CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCount = pListBox->GetCount(); for (int idx = 0; idx < iCount; idx++) { CString szNewValue; LRESULT lData = SendDlgItemMessage(IDC_VALUE_LIST, LB_GETITEMDATA, (WPARAM)idx, 0); if (lData == LB_ERR) { ASSERT(lData != LB_ERR); continue; }
m_NewValueList.AddTail(reinterpret_cast<PADSVALUE>(lData)); } } } CDialog::OnOK(); }
void CMultiOctetStringEditor::OnEditButton() { CThemeContextActivator activator;
LRESULT lIdx = SendDlgItemMessage(IDC_VALUE_LIST, LB_GETCURSEL, 0, 0); if (lIdx == LB_ERR) { ASSERT(lIdx != LB_ERR); return; }
LRESULT lData = SendDlgItemMessage(IDC_VALUE_LIST, LB_GETITEMDATA, (WPARAM)lIdx, 0); if (lData == LB_ERR) { ASSERT(lIdx != LB_ERR); return; }
PADSVALUE pADsValue = reinterpret_cast<PADSVALUE>(lData); if (!pADsValue) { ASSERT(pADsValue); return; }
DS_ATTRIBUTE_EDITORINFO attrEditInfo; ::ZeroMemory(&attrEditInfo, sizeof(DS_ATTRIBUTE_EDITORINFO));
attrEditInfo.pADsValue = pADsValue; attrEditInfo.dwNumValues = 1; attrEditInfo.lpszClass = (PWSTR)(PCWSTR)m_szClass; attrEditInfo.lpszAttribute = (PWSTR)(PCWSTR)m_szAttribute; attrEditInfo.bMultivalued = FALSE; attrEditInfo.bReadOnly = m_bReadOnly; attrEditInfo.lpfnBind = m_pfnBindingFunction; attrEditInfo.lParam = m_lParam;
COctetStringEditor dlg; HRESULT hr = dlg.Initialize(&attrEditInfo); if (FAILED(hr)) { ADSIEditErrorMessage(hr, IDS_FAILED_INITIALIZE_EDITOR, MB_OK | MB_ICONEXCLAMATION); return; }
if (dlg.DoModal() == IDOK && !m_bReadOnly) { PADSVALUE pNewADsValue = 0; DWORD dwNumNewValues = 0; hr = dlg.GetNewValue(&pNewADsValue, &dwNumNewValues); if (FAILED(hr)) { ADSIEditErrorMessage(hr, IDS_FAILED_GET_NEW_VALUE_EDITOR, MB_OK | MB_ICONEXCLAMATION); return; } ASSERT(pNewADsValue); ASSERT(dwNumNewValues == 1);
CString szNewValue; GetStringFromADsValue(pNewADsValue, szNewValue, MAX_OCTET_STRING_VALUE_LENGTH); ASSERT(!szNewValue.IsEmpty());
LRESULT lNewIdx = SendDlgItemMessage(IDC_VALUE_LIST, LB_INSERTSTRING, lIdx + 1, (LPARAM)(PCWSTR)szNewValue); if (lNewIdx != LB_ERR) { //
// Update the new item and delete the old
//
SendDlgItemMessage(IDC_VALUE_LIST, LB_SETITEMDATA, (WPARAM)lNewIdx, (LPARAM)pNewADsValue); SendDlgItemMessage(IDC_VALUE_LIST, LB_DELETESTRING, (WPARAM)lIdx, 0); } else { //
// Since we had trouble adding the new item just update the old one. The string
// will be incorrect but the value will be fine.
//
SendDlgItemMessage(IDC_VALUE_LIST, LB_SETITEMDATA, (WPARAM)lIdx, (LPARAM)pNewADsValue); } } }
void CMultiOctetStringEditor::OnRemoveButton() { if (!m_bReadOnly) { CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { int iCurSel = pListBox->GetCurSel(); if (iCurSel != LB_ERR) { //
// Delete the item from the list box
//
pListBox->DeleteString(iCurSel); } }
//
// Manage Button States
//
ManageButtonStates();
//
// Update the width of the list box
//
UpdateListboxHorizontalExtent(); } }
void CMultiOctetStringEditor::OnAddButton() { CThemeContextActivator activator;
if (!m_bReadOnly) { DS_ATTRIBUTE_EDITORINFO attrEditInfo; ZeroMemory(&attrEditInfo, sizeof(DS_ATTRIBUTE_EDITORINFO));
attrEditInfo.pADsValue = new ADSVALUE; if (attrEditInfo.pADsValue) { ::ZeroMemory(attrEditInfo.pADsValue, sizeof(ADSVALUE)); } else { // NOTICE-NTRAID#NTBUG9-566088-2002/03/05-artm If mem. allocation fails, short circuit function.
// If we cannot allocate enough memory inform the user and return w/out
// performing the rest of the operation.
ADSIEditErrorMessage(E_OUTOFMEMORY); return; }
attrEditInfo.pADsValue->dwType = ADSTYPE_OCTET_STRING; attrEditInfo.dwNumValues = 0; attrEditInfo.lpszClass = (PWSTR)(PCWSTR)m_szClass; attrEditInfo.lpszAttribute = (PWSTR)(PCWSTR)m_szAttribute; attrEditInfo.bMultivalued = FALSE; attrEditInfo.bReadOnly = m_bReadOnly; attrEditInfo.lpfnBind = m_pfnBindingFunction; attrEditInfo.lParam = m_lParam;
COctetStringEditor dlg; HRESULT hr = dlg.Initialize(&attrEditInfo); if (FAILED(hr)) { ADSIEditErrorMessage(hr, IDS_FAILED_INITIALIZE_EDITOR, MB_OK | MB_ICONEXCLAMATION); return; }
if (dlg.DoModal() == IDOK) { PADSVALUE pNewADsValue = 0; DWORD dwNumNewValues = 0; hr = dlg.GetNewValue(&pNewADsValue, &dwNumNewValues); if (FAILED(hr)) { ADSIEditErrorMessage(hr, IDS_FAILED_GET_NEW_VALUE_EDITOR, MB_OK | MB_ICONEXCLAMATION); return; } ASSERT(pNewADsValue); ASSERT(dwNumNewValues == 1);
CString szNewValue; GetStringFromADsValue(pNewADsValue, szNewValue, MAX_OCTET_STRING_VALUE_LENGTH);
if (!szNewValue.IsEmpty()) { LRESULT lNewIdx = SendDlgItemMessage(IDC_VALUE_LIST, LB_ADDSTRING, 0, (WPARAM)(PCWSTR)szNewValue); if (lNewIdx != LB_ERR) { SendDlgItemMessage(IDC_VALUE_LIST, LB_SETITEMDATA, (WPARAM)lNewIdx, (LPARAM)pNewADsValue); } } } } }
void CMultiOctetStringEditor::ManageButtonStates() { if (m_bReadOnly) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_BUTTON)->EnableWindow(FALSE); } else { LRESULT lSelection = SendDlgItemMessage(IDC_VALUE_LIST, LB_GETCURSEL, 0, 0); if (lSelection != LB_ERR) { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT_BUTTON)->EnableWindow(TRUE); } else { GetDlgItem(IDC_ATTR_REMOVE_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_BUTTON)->EnableWindow(FALSE); } } }
void CMultiOctetStringEditor::OnListSelChange() { ManageButtonStates(); }
void CMultiOctetStringEditor::UpdateListboxHorizontalExtent() { //
// Note if the size passed to SetHorizontalExtent is less than the width of the control
// then the scroll bar will be removed
//
int nHorzExtent = 0; CListBox* pListBox = reinterpret_cast<CListBox*>(GetDlgItem(IDC_VALUE_LIST)); if (pListBox != NULL) { CClientDC dc(pListBox); int nItems = pListBox->GetCount(); for (int i=0; i < nItems; i++) { TEXTMETRIC tm; VERIFY(dc.GetTextMetrics(&tm)); CString szBuffer; pListBox->GetText(i, szBuffer); CSize ext = dc.GetTextExtent(szBuffer,szBuffer.GetLength()); nHorzExtent = max(ext.cx ,nHorzExtent); } pListBox->SetHorizontalExtent(nHorzExtent); } }
HRESULT CMultiOctetStringEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { for (int idx = 0; idx < pAttributeEditorInfo->dwNumValues; idx++) { switch (pAttributeEditorInfo->pADsValue[idx].dwType) { case ADSTYPE_OCTET_STRING: m_OldValueList.AddTail(&(pAttributeEditorInfo->pADsValue[idx])); break;
default: ASSERT(FALSE); break; } } } } return hr; }
HRESULT CMultiOctetStringEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (!ppADsValue || !pdwNumValues) { return E_OUTOFMEMORY; }
int iCount = m_NewValueList.GetCount(); if (iCount == 0) { *ppADsValue = 0; *pdwNumValues = 0; } else { *ppADsValue = new ADSVALUE[iCount]; if (*ppADsValue) { *pdwNumValues = iCount;
int idx = 0; POSITION pos = m_NewValueList.GetHeadPosition(); while (pos) { PADSVALUE pADsValue = m_NewValueList.GetNext(pos);
(*ppADsValue)[idx].dwType = m_pOldADsValue->dwType; switch (m_pOldADsValue->dwType) { case ADSTYPE_OCTET_STRING: (*ppADsValue)[idx].OctetString.dwLength = pADsValue->OctetString.dwLength; (*ppADsValue)[idx].OctetString.lpValue = new BYTE[pADsValue->OctetString.dwLength]; if ((*ppADsValue)[idx].OctetString.lpValue) { // NOTICE-2002/03/05-artm memcpy() OK.
// arg1 and arg2 are both dwLength in size.
memcpy((*ppADsValue)[idx].OctetString.lpValue, pADsValue->OctetString.lpValue, pADsValue->OctetString.dwLength); } else { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = 0; *pdwNumValues = 0; hr = E_OUTOFMEMORY; }
break;
default: ASSERT(FALSE); DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = 0; *pdwNumValues = 0; hr = E_FAIL; break; } if (FAILED(hr)) { return hr; } idx++; } } else { *ppADsValue = NULL; *pdwNumValues = 0; hr = E_OUTOFMEMORY; } } return hr; }
/////////////////////////////////////////////////////////////////
// CDNWithStringEditor
CValueEditDialog* CreateDNWithStringEditor(PCWSTR pszClass, PCWSTR pszAttribute, ADSTYPE adsType, BOOL bMultivalued) { return new CDNWithStringEditor; }
BEGIN_MESSAGE_MAP(CDNWithStringEditor, CValueEditDialog) ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClear) END_MESSAGE_MAP()
BOOL CDNWithStringEditor::OnInitDialog() { CDialog::OnInitDialog();
return TRUE; }
void CDNWithStringEditor::OnOK() { if (!m_bReadOnly) { GetDlgItemText(IDC_VALUE_EDIT, m_NewDNValue); GetDlgItemText(IDC_STRING_VALUE_EDIT, m_NewStringValue); } CDialog::OnOK(); }
HRESULT CDNWithStringEditor::Initialize(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { HRESULT hr = S_OK;
if (SUCCEEDED(CValueEditDialog::Initialize(pAttributeEditorInfo))) { if (pAttributeEditorInfo->dwNumValues > 0 && pAttributeEditorInfo->pADsValue != NULL) { ASSERT(pAttributeEditorInfo->dwNumValues == 1); ASSERT(pAttributeEditorInfo->pADsValue->dwType == ADSTYPE_DN_WITH_STRING);
m_OldDNValue = pAttributeEditorInfo->pADsValue->pDNWithString->pszDNString; m_OldStringValue = pAttributeEditorInfo->pADsValue->pDNWithString->pszStringValue; } } return hr; }
void CDNWithStringEditor::OnClear() { //
// Change the text in the edit box to "<not set>"
//
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET)); SetDlgItemText(IDC_VALUE_EDIT, szNotSet); SetDlgItemText(IDC_STRING_VALUE_EDIT, szNotSet);
//
// Change the focus to the edit box
//
GetDlgItem(IDC_VALUE_EDIT)->SetFocus();
//
// Select the text in the edit box
//
SendDlgItemMessage(IDC_VALUE_EDIT, EM_SETSEL, 0, -1); }
HRESULT CDNWithStringEditor::GetNewValue(PADSVALUE* ppADsValue, DWORD* pdwNumValues) { HRESULT hr = S_OK;
if (ppADsValue == NULL || pdwNumValues == NULL) { return E_OUTOFMEMORY; }
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_NOTSET));
if (m_NewDNValue == szNotSet || m_NewStringValue == szNotSet) { // User is clearing the attribute
*ppADsValue = NULL; *pdwNumValues = 0;
return hr; }
if (!m_NewDNValue.IsEmpty() || !m_NewStringValue.IsEmpty()) { *ppADsValue = new ADSVALUE; if (*ppADsValue) { *pdwNumValues = 1; (*ppADsValue)->dwType = m_pOldADsValue->dwType; ASSERT((*ppADsValue)->dwType == ADSTYPE_DN_WITH_STRING);
(*ppADsValue)->pDNWithString = new ADS_DN_WITH_STRING; if ((*ppADsValue)->pDNWithString) { ZeroMemory((*ppADsValue)->pDNWithString, sizeof (ADS_DN_WITH_STRING));
int length = m_NewStringValue.GetLength(); (*ppADsValue)->pDNWithString->pszStringValue = new WCHAR[length + 1]; if ((*ppADsValue)->pDNWithString->pszStringValue) { ZeroMemory((*ppADsValue)->pDNWithString->pszStringValue, sizeof(WCHAR) * (length + 1));
wcsncpy((*ppADsValue)->pDNWithString->pszStringValue, m_NewStringValue, length);
length = m_NewDNValue.GetLength(); (*ppADsValue)->pDNWithString->pszDNString = new WCHAR[length + 1];
if ((*ppADsValue)->pDNWithString->pszDNString) { ZeroMemory((*ppADsValue)->pDNWithString->pszDNString, sizeof(WCHAR) * (length + 1));
wcsncpy((*ppADsValue)->pDNWithString->pszDNString, m_NewDNValue, length); } else { hr = E_OUTOFMEMORY; } } else { hr = E_OUTOFMEMORY; } } else { hr = E_OUTOFMEMORY; } } else { hr = E_OUTOFMEMORY; } } else { // Set an empty value
*ppADsValue = new ADSVALUE;
if (*ppADsValue) { *pdwNumValues = 1;
(*ppADsValue)->dwType = m_pOldADsValue->dwType; ASSERT((*ppADsValue)->dwType == ADSTYPE_DN_WITH_STRING);
(*ppADsValue)->pDNWithString = new ADS_DN_WITH_STRING; if ((*ppADsValue)->pDNWithString) { ZeroMemory((*ppADsValue)->pDNWithString, sizeof (ADS_DN_WITH_STRING)); } else { hr = E_OUTOFMEMORY; } } else { hr = E_OUTOFMEMORY; } }
if (FAILED(hr)) { DeleteADsValues(*ppADsValue, *pdwNumValues); *ppADsValue = 0; *pdwNumValues = 0; }
return hr; }
///////////////////////////////////////////////////////////////////////////////////////
// CAttributeEditorPropertyPage
BEGIN_MESSAGE_MAP(CAttributeEditorPropertyPage, CPropertyPage) ON_BN_CLICKED(IDC_MANDATORY_CHECK, OnMandatoryCheck) ON_BN_CLICKED(IDC_OPTIONAL_CHECK, OnOptionalCheck) ON_BN_CLICKED(IDC_SET_CHECK, OnValueSetCheck) ON_BN_CLICKED(IDC_ATTR_EDIT_BUTTON,OnEditAttribute) ON_WM_CREATE() ON_WM_DESTROY() ON_NOTIFY(LVN_ITEMACTIVATE, IDC_ATTRIBUTE_LIST, OnNotifyEditAttribute) ON_NOTIFY(LVN_ITEMCHANGED, IDC_ATTRIBUTE_LIST, OnListItemChanged) ON_NOTIFY(LVN_COLUMNCLICK, IDC_ATTRIBUTE_LIST, OnSortList) END_MESSAGE_MAP()
CAttributeEditorPropertyPage::CAttributeEditorPropertyPage(IADs* pIADs, IADsClass* pIADsClass, LPDS_ATTREDITOR_BINDINGINFO pBindingInfo, CADSIEditPropertyPageHolder* pHolder) : CPropertyPage(IDD_ATTRIBUTE_EDITOR_DIALOG) { m_spIADs = pIADs; m_spIADsClass = pIADsClass;
m_bMandatory = TRUE; m_bOptional = TRUE; m_bSet = FALSE;
m_nSortColumn = 0;
ASSERT(pBindingInfo != NULL); ASSERT(pBindingInfo->dwSize == sizeof(DS_ATTREDITOR_BINDINGINFO)); ASSERT(pBindingInfo->lpfnBind != NULL); ASSERT(pBindingInfo->lpszProviderServer != NULL);
m_szPrefix = pBindingInfo->lpszProviderServer; m_pfnBind = pBindingInfo->lpfnBind; m_BindLPARAM = pBindingInfo->lParam; m_dwBindFlags = pBindingInfo->dwFlags;
m_pHolder = pHolder; ASSERT(m_pHolder); }
CAttributeEditorPropertyPage::~CAttributeEditorPropertyPage() { }
BOOL CAttributeEditorPropertyPage::OnInitDialog() { AFX_MANAGE_STATE(AfxGetStaticModuleState());
CWaitCursor cursor;
// Set the hwnd in the property page holder so that we can
// be activated when necessary
m_pHolder->SetSheetWindow(GetParent()->GetSafeHwnd());
((CButton*)GetDlgItem(IDC_MANDATORY_CHECK))->SetCheck(TRUE); ((CButton*)GetDlgItem(IDC_OPTIONAL_CHECK))->SetCheck(TRUE); ((CButton*)GetDlgItem(IDC_SET_CHECK))->SetCheck(FALSE);
GetDlgItem(IDC_ATTR_EDIT_BUTTON)->EnableWindow(FALSE);
HRESULT hr = GetSchemaNamingContext(); ShowListCtrl();
hr = RetrieveAttributes(); if (FAILED(hr)) { TRACE(_T("OnInitDialog() : error returned from RetrieveAttributes() = 0x%x\n"), hr); }
CComBSTR bstr; hr = m_spIADs->get_Class(&bstr); if (FAILED(hr)) { TRACE(_T("OnInitDialog() : error returned from m_pIADs->get_Class() = 0x%x\n"), hr); } else { m_szClass = bstr; }
FillListControl(); return FALSE; }
int CAttributeEditorPropertyPage::OnCreate(LPCREATESTRUCT lpCreateStruct) { m_pHolder->AddRef(); int res = CPropertyPage::OnCreate(lpCreateStruct); ASSERT(res == 0); ASSERT(m_hWnd != NULL); ASSERT(::IsWindow(m_hWnd)); HWND hParent = ::GetParent(m_hWnd); ASSERT(hParent); m_pHolder->SetSheetWindow(hParent); return res; }
void CAttributeEditorPropertyPage::OnDestroy() { ASSERT(m_hWnd != NULL); CPropertyPage::OnDestroy(); m_pHolder->Release(); }
HRESULT CAttributeEditorPropertyPage::GetSchemaNamingContext() { HRESULT hr = S_OK; CComPtr<IADs> spIADs;
CString m_szPath = m_szPrefix + _T("RootDSE"); hr = m_pfnBind(m_szPath, ADS_SECURE_AUTHENTICATION, IID_IADs, (PVOID*)&spIADs, m_BindLPARAM); if (SUCCEEDED(hr)) { CComVariant var; hr = spIADs->Get(CComBSTR(L"schemaNamingContext"), &var); if (SUCCEEDED(hr)) { m_szSchemaNamingContext = var.bstrVal; } } m_szSchemaNamingContext = m_szPrefix + m_szSchemaNamingContext; return hr; }
BOOL CAttributeEditorPropertyPage::OnApply() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CThemeContextActivator activator; if (m_AttrList.HasDirty()) { CComPtr<IDirectoryObject> spDirObject;
// bind to object with authentication
//
HRESULT hr = S_OK; hr = m_spIADs->QueryInterface(IID_IDirectoryObject, (PVOID*) &spDirObject);
if (FAILED(hr)) { AfxMessageBox(L"Failed to QI the IDirectoryObject from the IADs."); return FALSE; }
// Change or add values to ADSI cache that have changed
//
hr = CADSIAttribute::SetValuesInDS(&m_AttrList, spDirObject); if (FAILED(hr)) { ADSIEditErrorMessage(hr);
//
// Instead of removing all the attributes we need to query for the ones that failed
// or something to that effect.
//
// m_AttrList.RemoveAllAttr();
return FALSE; } } return TRUE; }
void CAttributeEditorPropertyPage::OnMandatoryCheck() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); TRACE(_T("OnMandatoryCheck()\n")); m_bMandatory = ((CButton*)GetDlgItem(IDC_MANDATORY_CHECK))->GetCheck();
FillListControl(); }
void CAttributeEditorPropertyPage::OnOptionalCheck() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); TRACE(_T("OnOptionalCheck()\n")); m_bOptional = ((CButton*)GetDlgItem(IDC_OPTIONAL_CHECK))->GetCheck();
FillListControl(); }
void CAttributeEditorPropertyPage::OnValueSetCheck() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); TRACE(_T("OnValueSetCheck()\n")); m_bSet = ((CButton*)GetDlgItem(IDC_SET_CHECK))->GetCheck();
FillListControl(); }
//
// Callback function used by CListCtrl::SortItems the items by the column that was clicked
//
static int CALLBACK CompareAttrColumns(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { CAttributeEditorPropertyPage* pProppage = reinterpret_cast<CAttributeEditorPropertyPage*>(lParamSort); if (!pProppage) { ASSERT(pProppage); return 0; }
UINT nColumn = pProppage->GetSortColumn(); CListCtrl* pListCtrl = (CListCtrl*)pProppage->GetDlgItem(IDC_ATTRIBUTE_LIST); if (!pListCtrl) { ASSERT(pListCtrl); return 0; }
//
// Since lParam1 and lParam2 are pointers to the data we have to search for each item
// in the list and remember their index
//
int iItem1 = -1; int iItem2 = -1;
LVFINDINFO findInfo; ZeroMemory(&findInfo, sizeof(LVFINDINFO)); findInfo.flags = LVFI_PARAM; findInfo.lParam = lParam1; iItem1 = pListCtrl->FindItem(&findInfo);
findInfo.lParam = lParam2; iItem2 = pListCtrl->FindItem(&findInfo);
//
// Put any items with values above those that don't have values
//
int iRetVal = 0; if (iItem1 != -1 && iItem2 == -1) { iRetVal = -1; } else if (iItem1 == -1 && iItem2 != -1) { iRetVal = 1; } else if (iItem1 == -1 && iItem2 == -1) { iRetVal = 0; } else { CString szItem1 = pListCtrl->GetItemText(iItem1, nColumn); CString szItem2 = pListCtrl->GetItemText(iItem2, nColumn);
//
// Have to put this in so that empty strings end up at the bottom
//
if (szItem1.IsEmpty() && !szItem2.IsEmpty()) { iRetVal = 1; } else if (!szItem1.IsEmpty() && szItem2.IsEmpty()) { iRetVal = -1; } else { // NOTICE-2002/03/05-artm _wcsicmp() okay since comparing 2 CStrings.
iRetVal = _wcsicmp(szItem1, szItem2); } } return iRetVal; }
void CAttributeEditorPropertyPage::OnSortList(NMHDR* pNotifyStruct, LRESULT* result) { if (!result || !pNotifyStruct) { return; }
*result = 0;
//
// Get the list view notify struct
//
LPNMLISTVIEW pnmv = (LPNMLISTVIEW)pNotifyStruct; if (!pnmv) { return; }
//
// Right now I only have 3 columns
//
if (pnmv->iSubItem < 0 || pnmv->iSubItem >= 3) { return; }
//
// Store the sort column
//
m_nSortColumn = pnmv->iSubItem;
CListCtrl* pAttrListCtrl = (CListCtrl*)GetDlgItem(IDC_ATTRIBUTE_LIST); ASSERT(pAttrListCtrl); pAttrListCtrl->SortItems(CompareAttrColumns, reinterpret_cast<LPARAM>(this)); } void CAttributeEditorPropertyPage::OnListItemChanged(NMHDR* /*pNotifyStruct*/, LRESULT* result) { if (!result) { return; } *result = 0; SetEditButton(); }
void CAttributeEditorPropertyPage::SetEditButton() { //
// Enable the edit button if something is selected in the ListCtrl
//
BOOL bEnableEdit = FALSE;
CListCtrl* pAttrListCtrl = (CListCtrl*)GetDlgItem(IDC_ATTRIBUTE_LIST); ASSERT(pAttrListCtrl != NULL); int nSelectedItem = pAttrListCtrl->GetNextItem(-1, LVIS_SELECTED);
if (nSelectedItem != -1 && !(m_dwBindFlags & DSATTR_EDITOR_ROOTDSE)) { bEnableEdit = TRUE; } GetDlgItem(IDC_ATTR_EDIT_BUTTON)->EnableWindow(bEnableEdit); }
void CAttributeEditorPropertyPage::OnNotifyEditAttribute(NMHDR* pNotifyStruct, LRESULT* result) { if (result == NULL || pNotifyStruct == NULL) { return; }
// No editing values on RootDSE (for now)
if (m_dwBindFlags & DSATTR_EDITOR_ROOTDSE) { return; }
LPNMITEMACTIVATE pnmia = (LPNMITEMACTIVATE)pNotifyStruct; ASSERT(pnmia != NULL); if (pnmia != NULL) { int iSelectedItem = pnmia->iItem; if (iSelectedItem != -1) { CADSIAttribute* pSelectedAttr = GetAttributeFromList(iSelectedItem); if (pSelectedAttr != NULL) { EditAttribute(pSelectedAttr); } else { //
// REVIEW_JEFFJON : display an appropriate error message
//
} } } *result = 0; }
void CAttributeEditorPropertyPage::OnEditAttribute() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); TRACE(_T("OnEditAttribute()\n"));
CListCtrl* pAttrListCtrl = (CListCtrl*)GetDlgItem(IDC_ATTRIBUTE_LIST); ASSERT(pAttrListCtrl != NULL); int nSelectedItem = pAttrListCtrl->GetNextItem(-1, LVIS_SELECTED);
if (nSelectedItem == -1) { return; }
CADSIAttribute* pSelectedAttr = GetAttributeFromList(nSelectedItem); ASSERT(pSelectedAttr != NULL);
if (m_dwBindFlags & DSATTR_EDITOR_ROOTDSE) { // We have add the value to the attribute holder from
// the RootDSE list
// CString szValue;
// szValue = m_RootDSEValueList.GetAt(m_RootDSEValueList.FindIndex(nSelectedItem));
} EditAttribute(pSelectedAttr); }
void CAttributeEditorPropertyPage::EditAttribute(CADSIAttribute* pSelectedAttr) { HRESULT hr = S_OK;
CThemeContextActivator activator;
//
// Retrieve all necessary info for initializing the appropriate editor
//
LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo = NULL; BOOL bOwnValueMemory = FALSE; hr = GetAttributeInfo(*pSelectedAttr, &pAttributeEditorInfo, &bOwnValueMemory);
if (hr == E_OUTOFMEMORY) { ADSIEditErrorMessage(hr); return; }
if (pAttributeEditorInfo == NULL || FAILED(hr)) { ADSIEditMessageBox(IDS_NO_ATTRIBUTE_INFO, MB_OK); return; } //
// Obtain the editor from the attribute and syntax map
//
CValueEditDialog* pEditorDialog = RetrieveEditor(pAttributeEditorInfo); if (pEditorDialog) { hr = pEditorDialog->Initialize(pAttributeEditorInfo); if (SUCCEEDED(hr)) { if (pEditorDialog->DoModal() == IDOK) { PADSVALUE pNewValue = 0; DWORD dwNumValues = 0; hr = pEditorDialog->GetNewValue(&pNewValue, &dwNumValues); if (SUCCEEDED(hr)) { //
// Do what ever needs done with the new value
//
hr = pSelectedAttr->SetValues(pNewValue, dwNumValues); //
// REVIEW_JEFFJON : what should be done here if that failed?
//
pSelectedAttr->SetDirty(TRUE);
CListCtrl* pAttrListCtrl = (CListCtrl*)GetDlgItem(IDC_ATTRIBUTE_LIST); ASSERT(pAttrListCtrl != NULL); int nSelectedItem = pAttrListCtrl->GetNextItem(-1, LVIS_SELECTED);
if (nSelectedItem != -1) { if (dwNumValues > 0) { //
// Get the new values (limit each individual value to MAX_OCTET_STRING_VALUE_LENGTH characters)
//
CStringList szValuesList; pSelectedAttr->GetValues(szValuesList, MAX_OCTET_STRING_VALUE_LENGTH); CString szCombinedString; POSITION pos = szValuesList.GetHeadPosition(); while (pos != NULL) { CString szTemp = szValuesList.GetNext(pos); szCombinedString += szTemp; if (pos != NULL) { szCombinedString += L";"; } }
VERIFY(-1 != pAttrListCtrl->SetItemText(nSelectedItem, 2, szCombinedString)); } else { CString szNotSet; VERIFY(szNotSet.LoadString(IDS_ATTR_NOTSET));
VERIFY(-1 != pAttrListCtrl->SetItemText(nSelectedItem, 2, szNotSet)); } } SetModified(); } else { //
// REVIEW_JEFFJON : handle the GetNewValue() failure
//
ASSERT(FALSE); ADSIEditErrorMessage(hr); } } } else { //
// REVIEW_JEFFJON : Handle the error Initialize
//
ASSERT(FALSE); ADSIEditErrorMessage(hr); } if (pEditorDialog) { delete pEditorDialog; pEditorDialog = 0; } } else { //
// Unable to retrieve an appropriate editor for this attribute
//
ADSIEditMessageBox(IDS_NO_EDITOR, MB_OK); }
if (pAttributeEditorInfo) { if (pAttributeEditorInfo->lpszAttribute) { delete[] pAttributeEditorInfo->lpszAttribute; }
if (pAttributeEditorInfo->lpszClass) { delete[] pAttributeEditorInfo->lpszClass; }
if (pAttributeEditorInfo->pADsValue && bOwnValueMemory) { delete pAttributeEditorInfo->pADsValue; pAttributeEditorInfo->pADsValue = 0; }
delete pAttributeEditorInfo; pAttributeEditorInfo = 0; } }
CADSIAttribute* CAttributeEditorPropertyPage::GetAttributeFromList(int iSelectedItem) { if (iSelectedItem == -1) { return NULL; }
CListCtrl* pAttrListCtrl = (CListCtrl*)GetDlgItem(IDC_ATTRIBUTE_LIST); ASSERT(pAttrListCtrl != NULL); return (CADSIAttribute*)pAttrListCtrl->GetItemData(iSelectedItem); }
HRESULT CAttributeEditorPropertyPage::GetAttributeInfo(CADSIAttribute& attr, LPDS_ATTRIBUTE_EDITORINFO* ppAttributeEditorInfo, BOOL* pbOwnValueMemory) { HRESULT err = S_OK;
ASSERT(ppAttributeEditorInfo != NULL); ASSERT(pbOwnValueMemory != NULL);
if (!ppAttributeEditorInfo || !pbOwnValueMemory) { return E_POINTER; }
// Temporary variable to hold values that will be passed out of
// function. We use this instead of *ppAttributeEditorInfo to remove
// a level of indirection while we are collecting the information.
LPDS_ATTRIBUTE_EDITORINFO attributeEditorInfo;
// Set initial default (error) values.
attributeEditorInfo = NULL; *pbOwnValueMemory = FALSE;
//
// Set read-only if necessary
//
bool readOnly = false; if ( m_dwBindFlags & DSATTR_EDITOR_ROOTDSE || m_dwBindFlags & DSATTR_EDITOR_GC) { readOnly = true; } //
// Get the attribute to be edited
//
CString szAttribute = _T(""); attr.GetProperty(szAttribute);
//
// Get the type and whether it is multi-valued or not by the syntax
// of the attribute
//
CString szSyntax; BOOL bMultiValued = FALSE; ADSTYPE adsType = RetrieveADsTypeFromSyntax(szAttribute, &bMultiValued, szSyntax);
DWORD dwNumValues = 0; PADSVALUE pADsValue = attr.GetADsValues();
if (!pADsValue) { //
// Value for attribute was not set so we have to
// create an empty ADSVALUE to pass the type
//
pADsValue = new ADSVALUE; if (pADsValue) { ::ZeroMemory(pADsValue, sizeof(ADSVALUE)); pADsValue->dwType = adsType; dwNumValues = 0; *pbOwnValueMemory = TRUE; } else { return E_OUTOFMEMORY; } } else { //
// Get the number of values in the attribute
//
dwNumValues = attr.GetNumValues(); }
//
// Figure out how much space we need
//
DWORD dwStructSize = sizeof(DS_ATTRIBUTE_EDITORINFO); DWORD dwClassSize = m_szClass.GetLength() + 1; DWORD dwAttrSize = szAttribute.GetLength() + 1;
do // false loop
{ attributeEditorInfo = new DS_ATTRIBUTE_EDITORINFO; if (!attributeEditorInfo) { err = E_OUTOFMEMORY; break; }
::ZeroMemory(attributeEditorInfo, sizeof(DS_ATTRIBUTE_EDITORINFO));
// NOTICE-NTRAID#NTBUG9-566199-2002/03/05-artm Check mem. alloc. succeeded.
attributeEditorInfo->lpszClass = new WCHAR[dwClassSize]; if (!attributeEditorInfo->lpszClass) { err = E_OUTOFMEMORY; break; } wcscpy(attributeEditorInfo->lpszClass, m_szClass);
// NOTICE-NTRAID#NTBUG9-566199-2002/03/05-artm Check mem. alloc. succeeded.
attributeEditorInfo->lpszAttribute = new WCHAR[dwAttrSize]; if (!attributeEditorInfo->lpszAttribute) { err = E_OUTOFMEMORY; break; }
wcscpy(attributeEditorInfo->lpszAttribute, szAttribute);
attributeEditorInfo->adsType = adsType; attributeEditorInfo->bMultivalued = bMultiValued; attributeEditorInfo->bReadOnly = readOnly; attributeEditorInfo->dwNumValues = dwNumValues; attributeEditorInfo->pADsValue = pADsValue; attributeEditorInfo->dwSize = sizeof(DS_ATTRIBUTE_EDITORINFO); } while (false); // end false loop
// If we were unable to get all the information, clean up memory.
if (FAILED(err)) { // Only delete the value structure if we allocated it.
if (*pbOwnValueMemory) { delete pADsValue; pADsValue = NULL; *pbOwnValueMemory = FALSE; }
if (attributeEditorInfo) { if (attributeEditorInfo->lpszClass) { delete [] attributeEditorInfo->lpszClass; }
if (attributeEditorInfo->lpszAttribute) { delete [] attributeEditorInfo->lpszAttribute; }
delete attributeEditorInfo; attributeEditorInfo = NULL; } }
*ppAttributeEditorInfo = attributeEditorInfo;
return err; }
void CAttributeEditorPropertyPage::ShowListCtrl() { CListCtrl* pAttrListCtrl = (CListCtrl*)GetDlgItem(IDC_ATTRIBUTE_LIST); ASSERT(pAttrListCtrl != NULL);
// Set full row select
ListView_SetExtendedListViewStyle( pAttrListCtrl->GetSafeHwnd(), LVS_EX_FULLROWSELECT);
//
// Insert the Attribute column
//
CString szAttribute; VERIFY(szAttribute.LoadString(IDS_ATTR_COL_ATTRIBUTE)); int iRet = pAttrListCtrl->InsertColumn(0, szAttribute, LVCFMT_LEFT, 120); if (iRet == -1) { TRACE(_T("Failed to insert the \"Attribute\" column.\n")); }
//
// Insert the Syntax column
// This column will be hidden by default
//
CString szSyntax; VERIFY(szSyntax.LoadString(IDS_ATTR_COL_SYNTAX)); iRet = pAttrListCtrl->InsertColumn(1, szSyntax, LVCFMT_LEFT, 90); if (iRet == -1) { TRACE(_T("Failed to insert the \"Syntax\" column.\n")); }
//
// Insert the Value column
//
CString szValue; VERIFY(szValue.LoadString(IDS_ATTR_COL_VALUE)); iRet = pAttrListCtrl->InsertColumn(2, szValue, LVCFMT_LEFT, 400); if (iRet == -1) { TRACE(_T("Failed to insert the \"Value\" column.\n")); }
}
void CAttributeEditorPropertyPage::FillListControl() { TRACE(_T("FillListControl()\n"));
CListCtrl* pAttrListCtrl = (CListCtrl*)GetDlgItem(IDC_ATTRIBUTE_LIST); ASSERT(pAttrListCtrl != NULL);
CString szNotSet; VERIFY(szNotSet.LoadString(IDS_ATTR_NOTSET));
//
// Clear the list control
//
pAttrListCtrl->DeleteAllItems();
//
// Add the attributes and their values into the list control
//
UINT nState = 0; int nIndex = 0;
POSITION pos = m_AttrList.GetHeadPosition(); while (pos != NULL) { CADSIAttribute* pAttr = m_AttrList.GetNext(pos); ASSERT(pAttr != NULL);
CString szProperty; pAttr->GetProperty(szProperty);
//
// Don't add the nTSecurityDescriptor, we use the ACL UI instead
//
if (szProperty.CompareNoCase(L"nTSecurityDescriptor") == 0) { continue; }
if (m_dwBindFlags & DSATTR_EDITOR_ROOTDSE) { int iNewIndex = pAttrListCtrl->InsertItem(LVIF_TEXT | LVIF_PARAM, nIndex, szProperty, nState, 0, 0, (LPARAM)pAttr); if (iNewIndex != -1) { // Insert the syntax
VERIFY(-1 != pAttrListCtrl->SetItemText(iNewIndex, 1, pAttr->GetSyntax()));
// Insert the value
CString szValue; szValue = m_RootDSEValueList.GetAt(m_RootDSEValueList.FindIndex(nIndex)); if (!szValue.IsEmpty()) { VERIFY(-1 != pAttrListCtrl->SetItemText(iNewIndex, 2, szValue)); } else { VERIFY(-1 != pAttrListCtrl->SetItemText(iNewIndex, 2, szNotSet)); } } nIndex++; } else // not RootDSE
{ if ((m_bMandatory && pAttr->IsMandatory()) || (m_bOptional && !pAttr->IsMandatory())) { if (!m_bSet || (m_bSet && pAttr->IsValueSet())) { int iNewIndex = pAttrListCtrl->InsertItem(LVIF_TEXT | LVIF_PARAM, nIndex, szProperty, nState, 0, 0, (LPARAM)pAttr); if (iNewIndex != -1) { // Insert the syntax
VERIFY(-1 != pAttrListCtrl->SetItemText(iNewIndex, 1, pAttr->GetSyntax()));
// Insert the value
if (pAttr->IsValueSet()) { //
// Retrieve the values
//
CStringList szValuesList; pAttr->GetValues(szValuesList); CString szCombinedString; POSITION posList = szValuesList.GetHeadPosition(); while (posList) { CString szTemp = szValuesList.GetNext(posList); szCombinedString += szTemp; if (posList) { szCombinedString += L";"; } }
VERIFY(-1 != pAttrListCtrl->SetItemText(iNewIndex, 2, szCombinedString)); } else { VERIFY(-1 != pAttrListCtrl->SetItemText(iNewIndex, 2, szNotSet)); } } nIndex++; } } } } TRACE(_T("Added %u properties\n"), nIndex);
//
// Select the first attribute in the list
//
pAttrListCtrl->SetItemState(0, 1, LVIS_SELECTED); SetEditButton(); }
HRESULT CAttributeEditorPropertyPage::RetrieveAttributes() { TRACE(_T("RetrieveAttributes()\n")); HRESULT hr = S_OK;
CWaitCursor cursor;
if (m_dwBindFlags & DSATTR_EDITOR_ROOTDSE) { CStringList sMandList;
m_spIADs->GetInfo();
CComPtr<IADsPropertyList> spPropList; hr = m_spIADs->QueryInterface(IID_IADsPropertyList, (PVOID*)&spPropList); if (SUCCEEDED(hr)) { LONG lCount = 0; hr = spPropList->get_PropertyCount(&lCount); if (SUCCEEDED(hr) && lCount > 0) { CComVariant var; while (hr == S_OK) { hr = spPropList->Next(&var); if (hr == S_OK) { ASSERT(var.vt == VT_DISPATCH); CComPtr<IADsPropertyEntry> spEntry; hr = V_DISPATCH(&var)->QueryInterface(IID_IADsPropertyEntry, (PVOID*)&spEntry); if (SUCCEEDED(hr)) { CComBSTR bstrName; hr = spEntry->get_Name(&bstrName); if (SUCCEEDED(hr)) { sMandList.AddTail(bstrName); } } } } } } hr = CreateAttributeList(sMandList, TRUE); } else { //
// Retrieve mandatory properties
//
CStringList sMandList;
VARIANT varMand; VariantInit(&varMand);
hr = m_spIADsClass->get_MandatoryProperties(&varMand); if (SUCCEEDED(hr)) { VariantToStringList( varMand, sMandList ); } VariantClear(&varMand);
//
// Retrieve optional properties
//
CStringList sOptionalList;
VARIANT varOpt; VariantInit(&varOpt); hr = m_spIADsClass->get_OptionalProperties(&varOpt); if (SUCCEEDED(hr)) { VariantToStringList( varOpt, sOptionalList ); } VariantClear(&varOpt);
hr = CreateAttributeList(sMandList, TRUE); if (FAILED(hr)) { return hr; }
hr = CreateAttributeList(sOptionalList, FALSE); if (FAILED(hr)) { return hr; } } return hr; }
// The function checks to see if the pszAttrName contains ";range="
// If it does that means the attribute contains a range of values.
// We will return the attribute name (without the range), and the start
// and end of the range.
bool CAttributeEditorPropertyPage::IsRangeOfValues(PCWSTR pszAttrName, CString& szAttrBase, DWORD& rangeStart, DWORD& rangeEnd) { bool result = false;
CString szAttrName = pszAttrName; int iFind = szAttrName.Find(L";range="); if (iFind != -1) { // This is a range, get the start and end
result = true; szAttrBase = szAttrName.Left(iFind);
int length = szAttrName.GetLength();
// The range start is the value between the = and -
iFind = szAttrName.ReverseFind(L'='); if (iFind != -1) { CString szStart = szAttrName.Right(length - iFind - 1); long start = _wtol(szStart); rangeStart = static_cast<DWORD>(start); }
// The range end is the last value after the -.
// This could be * so a return value of 0 for this
// means we have the entire range
iFind = szAttrName.ReverseFind(L'-'); if (iFind != -1) { CString szEnd = szAttrName.Right(length - iFind - 1); long end = _wtol(szEnd); rangeEnd = static_cast<DWORD>(end); }
} return result; }
HRESULT CAttributeEditorPropertyPage::CreateAttributeList(CStringList& sAttrList, BOOL bMandatory) { HRESULT hr = S_OK; LPWSTR* lpszAttrArray; UINT nCount = 0; GetStringArrayFromStringList(sAttrList, &lpszAttrArray, &nCount); TRACE(_T("There are %u properties to add\n"), nCount);
for (UINT idx = 0; idx < nCount; idx++) { CADSIAttribute* pNewAttr = new CADSIAttribute(lpszAttrArray[idx]); ASSERT(pNewAttr != NULL);
pNewAttr->SetMandatory(bMandatory);
// Get the syntax
BOOL bMultivalued = FALSE; CString szSyntax; ADSTYPE adstype = RetrieveADsTypeFromSyntax(lpszAttrArray[idx], &bMultivalued, szSyntax); pNewAttr->SetADsType(adstype); pNewAttr->SetMultivalued(bMultivalued); pNewAttr->SetSyntax(szSyntax);
m_AttrList.AddTail(pNewAttr); }
//
// Retrieve the values that are set
//
#define RETRIEVESET
#ifdef RETRIEVESET
if (m_dwBindFlags & DSATTR_EDITOR_ROOTDSE) { //
// Special case RootDSE because it does not support IDirectoryObject
//
hr = m_spIADs->GetInfo(); for (UINT idx = 0; idx < nCount; idx++) {
VARIANT var; hr = m_spIADs->GetEx( CComBSTR(lpszAttrArray[idx]) , &var ); if ( FAILED(hr) ) { m_RootDSEValueList.AddTail(L" "); continue; }
/////////////////////////////////////////
// Convert and populate
///////////////////////////////////////////
CStringList sList; hr = VariantToStringList( var, sList ); if (SUCCEEDED(hr)) { CString szTempValue; POSITION pos = sList.GetHeadPosition(); while (pos != NULL) { CString szValue = sList.GetNext(pos);
if (szTempValue.IsEmpty()) { szTempValue += szValue; } else { szTempValue += L";" + szValue; } } m_RootDSEValueList.AddTail(szTempValue); } } } else { CComPtr<IDirectoryObject> spDirObject;
hr = m_spIADs->QueryInterface(IID_IDirectoryObject, (PVOID*)&spDirObject); if (FAILED(hr)) { return hr; }
PADS_ATTR_INFO pAttrInfo = NULL; DWORD dwReturned = 0;
hr = spDirObject->GetObjectAttributes(lpszAttrArray, nCount, &pAttrInfo, &dwReturned); if (SUCCEEDED(hr)) { //
// Save the attribute info pointer for later deletion
//
if (bMandatory) { m_AttrList.SaveMandatoryValuesPointer(pAttrInfo); } else { m_AttrList.SaveOptionalValuesPointer(pAttrInfo); }
for (DWORD idx = 0; idx < dwReturned; idx++) { POSITION pos = m_AttrList.FindProperty(pAttrInfo[idx].pszAttrName);
if (pos) { CADSIAttribute* pNewAttr = m_AttrList.GetAt(pos); ASSERT(pNewAttr != NULL);
pNewAttr->SetValueSet(TRUE); pNewAttr->SetAttrInfo(&(pAttrInfo[idx])); } else { // See if this is just a range of values for the attribute
CString szAttributeBase; DWORD rangeStart = 0; DWORD rangeEnd = static_cast<DWORD>(-1); CADSIAttribute* pNewAttr = 0;
PADS_ATTR_INFO pCurrentInfo = &(pAttrInfo[idx]); ASSERT(pCurrentInfo);
bool currentInMasterList = true;
// If we were sent only a portion of the values
// we have to loop through and get the rest
while (IsRangeOfValues(pCurrentInfo->pszAttrName, szAttributeBase, rangeStart, rangeEnd)) { if (!pNewAttr) { POSITION rangePos = m_AttrList.FindProperty(szAttributeBase); if (rangePos) { pNewAttr = m_AttrList.GetAt(rangePos); } } ASSERT(pNewAttr);
if (!pNewAttr) { break; } if (pNewAttr->IsValueSet()) { hr = pNewAttr->AppendValues(pCurrentInfo->pADsValues, pCurrentInfo->dwNumValues); } else { pNewAttr->SetValueSet(TRUE); pNewAttr->SetAttrInfo(pCurrentInfo); }
// If the current attribute info was not in the array
// of information from the initial request, release
// it here now that we are done with it.
if (!currentInMasterList) { ::FreeADsMem(pCurrentInfo); pCurrentInfo = NULL; }
if (rangeEnd == 0) { break; }
// Request next batch of values for the attribute.
CString szNextAttribute = szAttributeBase; CString szNextRange; szNextRange.Format(L";range=%ld-*", rangeEnd); szNextAttribute += szNextRange;
DWORD dwNextReturned = 0; PWSTR pszAttrs = (PWSTR)(PCWSTR)szNextAttribute;
hr = spDirObject->GetObjectAttributes(&pszAttrs, 1, &pCurrentInfo, &dwNextReturned); if (FAILED(hr)) { break; }
if (dwNextReturned != 1 || !pCurrentInfo) { ASSERT(dwNextReturned == 1); ASSERT(pCurrentInfo); break; }
// Since this pointer comes from an additional request to ADSI,
// we'll need to free it when we are done with it.
currentInMasterList = false;
rangeEnd = static_cast<DWORD>(-1); } } } TRACE(_T("Added %u properties to the list\nThe list has %u total properties\n"), dwReturned, m_AttrList.GetCount()); } else { ADSIEditErrorMessage(hr, IDS_MSG_FAIL_LOAD_VALUES, MB_OK); }
for (UINT nIndex = 0; nIndex < nCount; nIndex++) { delete lpszAttrArray[nIndex]; lpszAttrArray[nIndex] = NULL; } delete[] lpszAttrArray; lpszAttrArray = NULL; } #endif //RETRIEVESET
return hr; }
ATTR_EDITOR_MAP g_attrEditorMap[] = { // Class, Attribute, ADSTYPE, Multivalued, Creation function
{ NULL, NULL, ADSTYPE_DN_STRING, FALSE, CreateSingleStringEditor }, { NULL, NULL, ADSTYPE_DN_STRING, TRUE, CreateMultiStringEditor }, { NULL, NULL, ADSTYPE_CASE_IGNORE_STRING, FALSE, CreateSingleStringEditor }, { NULL, NULL, ADSTYPE_CASE_IGNORE_STRING, TRUE, CreateMultiStringEditor }, { NULL, NULL, ADSTYPE_CASE_EXACT_STRING, FALSE, CreateSingleStringEditor }, { NULL, NULL, ADSTYPE_CASE_EXACT_STRING, TRUE, CreateMultiStringEditor }, { NULL, NULL, ADSTYPE_PRINTABLE_STRING, FALSE, CreateSingleStringEditor }, { NULL, NULL, ADSTYPE_PRINTABLE_STRING, TRUE, CreateMultiStringEditor }, { NULL, NULL, ADSTYPE_NUMERIC_STRING, FALSE, CreateSingleStringEditor }, { NULL, NULL, ADSTYPE_NUMERIC_STRING, TRUE, CreateMultiStringEditor }, { NULL, NULL, ADSTYPE_OBJECT_CLASS, FALSE, CreateSingleStringEditor }, { NULL, NULL, ADSTYPE_OBJECT_CLASS, TRUE, CreateMultiStringEditor }, { NULL, NULL, ADSTYPE_INTEGER, FALSE, CreateSingleIntEditor }, { NULL, NULL, ADSTYPE_INTEGER, TRUE, CreateMultiIntEditor }, { NULL, NULL, ADSTYPE_LARGE_INTEGER, FALSE, CreateSingleLargeIntEditor }, { NULL, NULL, ADSTYPE_BOOLEAN, FALSE, CreateSingleBooleanEditor }, { NULL, NULL, ADSTYPE_BOOLEAN, TRUE, CreateMultiBooleanEditor }, { NULL, NULL, ADSTYPE_UTC_TIME, FALSE, CreateSingleTimeEditor }, { NULL, NULL, ADSTYPE_UTC_TIME, TRUE, CreateMultiTimeEditor }, { NULL, NULL, ADSTYPE_TIMESTAMP, FALSE, CreateSingleTimeEditor }, { NULL, NULL, ADSTYPE_TIMESTAMP, TRUE, CreateMultiTimeEditor }, { NULL, NULL, ADSTYPE_OCTET_STRING, FALSE, CreateSingleOctetStringEditor }, { NULL, NULL, ADSTYPE_OCTET_STRING, TRUE, CreateMultiOctetStringEditor }, { NULL, NULL, ADSTYPE_DN_WITH_STRING, FALSE, CreateDNWithStringEditor }, };
size_t g_attrEditMapCount = sizeof(g_attrEditorMap)/sizeof(ATTR_EDITOR_MAP);
CValueEditDialog* CAttributeEditorPropertyPage::RetrieveEditor(LPDS_ATTRIBUTE_EDITORINFO pAttributeEditorInfo) { CValueEditDialog* pNewDialog = NULL;
if (pAttributeEditorInfo != NULL) { int iMultivalued = 0; CString szSyntax; ADSTYPE adsType = RetrieveADsTypeFromSyntax(pAttributeEditorInfo->lpszAttribute, &iMultivalued, szSyntax);
for (size_t idx = 0; idx < g_attrEditMapCount; idx++) { //
// REVIEW_JEFFJON : for now I am just looking at ADSTYPE and single/multivalued
//
if (g_attrEditorMap[idx].adsType == adsType && g_attrEditorMap[idx].bMultivalued == pAttributeEditorInfo->bMultivalued) { pNewDialog = g_attrEditorMap[idx].pfnCreateFunc(pAttributeEditorInfo->lpszClass, pAttributeEditorInfo->lpszAttribute, adsType, pAttributeEditorInfo->bMultivalued); break; } } }
return pNewDialog; }
ADSTYPE CAttributeEditorPropertyPage::RetrieveADsTypeFromSyntax(LPCWSTR lpszAttribute, BOOL* pbMulti, CString& szSyntax) { ADSTYPE adsType = ADSTYPE_INVALID;
if (!pbMulti || !lpszAttribute) { ASSERT(pbMulti); ASSERT(lpszAttribute); return adsType; }
if (m_dwBindFlags & DSATTR_EDITOR_ROOTDSE) { int idx=0, iCount = 0;
// NTRAID#NTBUG9-563093-2002/03/05-artm If lpszAttribute not null terminated,
// this will blow up.
iCount = wcslen(lpszAttribute);
while( g_ldapRootDSESyntax[idx].lpszAttr) { // NOTICE-2002/03/05-artm _wcsnicmp() OK.
// arg1 is global var that should be null terminated;
// arg2 is null terminated or we wouldn't have gotten this far.
if ( _wcsnicmp(g_ldapRootDSESyntax[idx].lpszAttr, lpszAttribute, iCount) == 0) { *pbMulti = g_ldapRootDSESyntax[idx].bMulti; szSyntax = g_ldapRootDSESyntax[idx].lpszSyntax; break; } idx++; } adsType = GetADsTypeFromString(szSyntax, szSyntax); } else { CADSIQueryObject schemaSearch;
HRESULT hr = S_OK; CComPtr<IDirectorySearch> spDirSearch;
CString schemaBindPath(m_szSchemaNamingContext);
if (m_dwBindFlags & DSATTR_EDITOR_GC) { // GC by default does not have 'attributeSyntax' or 'isSingleValued'
// in the partial attribute set. To ensure we can get these attributes,
// we'll bind with LDAP instead of GC. This is ok b/c we are searching
// the schema, which is the same on the GC and all DC's.
// NTRAID#NTBUG9-762158-2003/01/15-artm
int numReplaced = schemaBindPath.Replace(L"GC://", L"LDAP://"); if (numReplaced != 1) { ASSERT(numReplaced == 1); // fall back to connecting to the GC, since the path wasn't
// adapted the way we expected
schemaBindPath = m_szSchemaNamingContext; } }
// REVIEW_JEFFJON : this needs to be replaced with proper binding calls
// REVIEW_JEFFJON : maybe this interface pointer should be retained for future use
hr = m_pfnBind(schemaBindPath, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (PVOID*)&spDirSearch, m_BindLPARAM); if (FAILED(hr)) { return ADSTYPE_INVALID; } //
// Initialize search object with IDirectorySearch
//
hr = schemaSearch.Init(spDirSearch); if (FAILED(hr)) { return ADSTYPE_INVALID; }
int cCols = 2; LPWSTR pszAttributes[] = {L"isSingleValued", L"attributeSyntax"}; ADS_SEARCH_COLUMN ColumnData; hr = schemaSearch.SetSearchPrefs(ADS_SCOPE_ONELEVEL); if (FAILED(hr)) { return ADSTYPE_INVALID; }
CString csFilter; csFilter.Format(L"(&(objectClass=attributeSchema)(lDAPDisplayName=%s)(!isDefunct=TRUE))", lpszAttribute); schemaSearch.SetFilterString((LPWSTR)(LPCWSTR)csFilter); schemaSearch.SetAttributeList (pszAttributes, cCols); hr = schemaSearch.DoQuery (); if (SUCCEEDED(hr)) { hr = schemaSearch.GetNextRow(); if (SUCCEEDED(hr)) { hr = schemaSearch.GetColumn(pszAttributes[0], &ColumnData); if (SUCCEEDED(hr)) { TRACE(_T("\t\tisSingleValued: %d\n"), ColumnData.pADsValues->Boolean); *pbMulti = !ColumnData.pADsValues->Boolean; schemaSearch.FreeColumn(&ColumnData); }
hr = schemaSearch.GetColumn(pszAttributes[1], &ColumnData); if (SUCCEEDED(hr)) { TRACE(_T("\t\tattributeSyntax: %s\n"), ColumnData.pADsValues->CaseIgnoreString);
adsType = GetADsTypeFromString(ColumnData.pADsValues->CaseIgnoreString, szSyntax); schemaSearch.FreeColumn(&ColumnData); } } } } return adsType; }
|