You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
596 lines
22 KiB
596 lines
22 KiB
// PropPageExt.cpp : Implementation of CPropPageExt
|
|
#include "stdafx.h"
|
|
#include "DSAdminExt.h"
|
|
#include "PropPageExt.h"
|
|
#include "globals.h"
|
|
#include <crtdbg.h>
|
|
#include "Iads.h"
|
|
#include "adsprop.h"
|
|
#include "Adshlp.h"
|
|
#include "resource.h"
|
|
#include "winable.h"
|
|
|
|
typedef struct
|
|
{
|
|
DWORD dwFlags; // item flags
|
|
DWORD dwProviderFlags; // flags for item provider
|
|
DWORD offsetName; // offset to ADS path of the object
|
|
DWORD offsetClass; // offset to object class name / == 0 not known
|
|
} DSOBJECT, * LPDSOBJECT;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
CLSID clsidNamespace; // namespace identifier (indicates which namespace selection from)
|
|
UINT cItems; // number of objects
|
|
DSOBJECT aObjects[1]; // array of objects
|
|
} DSOBJECTNAMES, * LPDSOBJECTNAMES;
|
|
|
|
#define BYTE_OFFSET(base, offset) (((LPBYTE)base)+offset)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPropPageExt
|
|
|
|
|
|
///////////////////////////////
|
|
// Interface IExtendPropertySheet
|
|
///////////////////////////////
|
|
HRESULT CPropPageExt::CreatePropertyPages(
|
|
/* [in] */ LPPROPERTYSHEETCALLBACK lpProvider,
|
|
/* [in] */ LONG_PTR handle,
|
|
/* [in] */ LPDATAOBJECT lpIDataObject)
|
|
{
|
|
|
|
HRESULT hr = S_FALSE;
|
|
|
|
LPDSOBJECTNAMES pDsObjectNames;
|
|
PWSTR pwzObjName;
|
|
PWSTR pwzClass;
|
|
|
|
|
|
// Unpack the data pointer and create the property page.
|
|
// Register clipboard format
|
|
|
|
FORMATETC fmte = { cfDsObjectNames, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
|
|
|
STGMEDIUM objMedium = {TYMED_NULL};;
|
|
|
|
hr = lpIDataObject->GetData(&fmte, &objMedium);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pDsObjectNames = (LPDSOBJECTNAMES)objMedium.hGlobal;
|
|
|
|
if (pDsObjectNames->cItems < 1)
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
pwzObjName = (PWSTR)BYTE_OFFSET(pDsObjectNames,
|
|
pDsObjectNames->aObjects[0].offsetName);
|
|
pwzClass = (PWSTR)BYTE_OFFSET(pDsObjectNames,
|
|
pDsObjectNames->aObjects[0].offsetClass);
|
|
// Save the ADsPath of object
|
|
m_ObjPath = new WCHAR [wcslen(pwzObjName )+1];
|
|
wcscpy(m_ObjPath,pwzObjName);
|
|
}
|
|
|
|
// Now release the objMedium:
|
|
// If punkForRelease is NULL, the receiver of
|
|
// the medium is responsible for releasing it; otherwise,
|
|
// punkForRelease points to the IUnknown on the appropriate
|
|
// object so its Release method can be called.
|
|
|
|
ReleaseStgMedium(&objMedium);
|
|
|
|
PROPSHEETPAGE psp;
|
|
HPROPSHEETPAGE hPage = NULL;
|
|
|
|
hr = S_OK;
|
|
|
|
//
|
|
// Create a property sheet page object from a dialog box.
|
|
//
|
|
// We store a pointer to our class in the psp.lParam, so we
|
|
// can access our class members from within the DSExtensionPageDlgProc.
|
|
//
|
|
// If the page needs more instance data, you can append
|
|
// arbitrary size of data at the end of this structure,
|
|
// and pass it to the CreatePropSheetPage. In such a case,
|
|
// the size of entire data structure (including page specific
|
|
// data) must be stored in the dwSize field. Note that in
|
|
// general you should NOT need to do this, as you can simply
|
|
// store a pointer to data in the lParam member.
|
|
|
|
psp.dwSize = sizeof(PROPSHEETPAGE);
|
|
psp.dwFlags = PSP_DEFAULT | PSP_USETITLE;
|
|
psp.hInstance = g_hinst;
|
|
psp.pszTemplate = MAKEINTRESOURCE(IDD_DSExtensionPageGen);
|
|
psp.pfnDlgProc = DSExtensionPageDlgProc;
|
|
psp.lParam = reinterpret_cast<LPARAM>(this);
|
|
psp.pszTitle = MAKEINTRESOURCE(IDS_PROPPAGE_TITLE);
|
|
|
|
hPage = CreatePropertySheetPage(&psp);
|
|
_ASSERT(hPage);
|
|
|
|
hr = lpProvider->AddPage(hPage);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CPropPageExt::QueryPagesFor(
|
|
/* [in] */ LPDATAOBJECT lpDataObject)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
BOOL CALLBACK CPropPageExt::DSExtensionPageDlgProc(HWND hDlg,
|
|
UINT uMessage,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
|
|
|
|
static CPropPageExt *pThis = NULL;
|
|
|
|
static bool b_IsDirty = FALSE;
|
|
|
|
switch (uMessage)
|
|
{
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//WM_INITDIALOG handler
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
case WM_INITDIALOG:
|
|
{
|
|
pThis = reinterpret_cast<CPropPageExt *>(reinterpret_cast<PROPSHEETPAGE *>(lParam)->lParam);
|
|
|
|
//Set to value of m_hPropPageWnd to the HWND of the our property page dialog
|
|
pThis->m_hPropPageWnd = hDlg;
|
|
|
|
HRESULT hr;
|
|
|
|
IDirectoryObject* pDirObject = NULL;
|
|
hr = ADsGetObject( pThis->m_ObjPath, IID_IDirectoryObject,(void **)&pDirObject);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//Retrieve some general info about the current user object.
|
|
//We use our IDirectoryObject pointer here.
|
|
|
|
ADS_ATTR_INFO *pAttrInfo=NULL;
|
|
ADS_ATTR_INFO *pAttrInfo1=NULL;
|
|
|
|
DWORD dwReturn, dwReturn1;
|
|
LPWSTR pAttrNames[]={L"employeeID", L"mail", L"physicalDeliveryOfficeName", L"telephoneNumber"};
|
|
LPWSTR pAttrNames1[]={L"allowedAttributesEffective"};
|
|
|
|
DWORD dwNumAttr=sizeof(pAttrNames)/sizeof(LPWSTR);
|
|
DWORD dwNumAttr1=sizeof(pAttrNames1)/sizeof(LPWSTR);
|
|
|
|
/////////////////////////////////////////
|
|
// First get the allowedAttributesEffective
|
|
// attribute value. We use it to determine
|
|
// whether we have the proper permissions
|
|
// to modify the attributes of the current
|
|
// object. If we have the needed
|
|
// permissions, we enable the edit fields.
|
|
// (They're disabled by default.)
|
|
///////////////////////////////////////////
|
|
|
|
bool b_allowEmployeeChange = FALSE;
|
|
bool b_allowMailChange = FALSE;
|
|
bool b_allowOfficeChange = FALSE;
|
|
bool b_allowTelNumberChange = FALSE;
|
|
|
|
hr = pDirObject->GetObjectAttributes( pAttrNames1,
|
|
dwNumAttr1,
|
|
&pAttrInfo1,
|
|
&dwReturn1 );
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
//The call can succeed with no attributes returned if you lack privilege,
|
|
//so check that all attributes are returned.
|
|
if (dwReturn1 && pAttrInfo1 && pAttrInfo1->pszAttrName &&
|
|
_wcsicmp(pAttrInfo1->pszAttrName,L"allowedAttributesEffective")== 0)
|
|
{
|
|
if (ADSTYPE_INVALID != pAttrInfo1->dwADsType)
|
|
{
|
|
//Permissions are per-attribute, so you need to check
|
|
//if the attribute name is in the array of names returned
|
|
//by the read of allowedAttributesEffective.
|
|
|
|
//The attributes we are interested in modifying are:
|
|
//employeeID, mail, physicalDeliveryOfficeName, telephoneNumber
|
|
for (DWORD i = 0; i < pAttrInfo1->dwNumValues; i++)
|
|
{
|
|
if (_tcscmp(L"employeeID", pAttrInfo1->pADsValues[i].CaseIgnoreString) == 0)
|
|
b_allowEmployeeChange = TRUE;
|
|
else if (_tcscmp(L"mail", pAttrInfo1->pADsValues[i].CaseIgnoreString) == 0)
|
|
b_allowMailChange = TRUE;
|
|
else if (_tcscmp(L"physicalDeliveryOfficeName", pAttrInfo1->pADsValues[i].CaseIgnoreString) == 0)
|
|
b_allowOfficeChange = TRUE;
|
|
else if (_tcscmp(L"telephoneNumber", pAttrInfo1->pADsValues[i].CaseIgnoreString) == 0)
|
|
b_allowTelNumberChange = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//For loop for setting default value of text controls
|
|
//This makes use of the fact that the ID values of the
|
|
//text controls are sequential. We use the value of
|
|
//b_allowChanges to determine whether we enable editing or not
|
|
for (int i = IDC_EMPID; i <= IDC_TELNUMBER; i++)
|
|
{
|
|
SetWindowText(GetDlgItem(hDlg,i),L"<not set>");
|
|
if (IDC_EMPID == i && b_allowEmployeeChange)
|
|
EnableWindow(GetDlgItem(hDlg, i), TRUE);
|
|
|
|
else if (IDC_EMAIL == i && b_allowMailChange)
|
|
EnableWindow(GetDlgItem(hDlg, i), TRUE);
|
|
|
|
else if (IDC_OFFICE == i && b_allowOfficeChange)
|
|
EnableWindow(GetDlgItem(hDlg, i), TRUE);
|
|
|
|
else if (IDC_TELNUMBER == i && b_allowTelNumberChange)
|
|
EnableWindow(GetDlgItem(hDlg, i), TRUE);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
// Use FreeADsMem for all memory obtained from the ADSI call.
|
|
/////////////////////////////////////////////////////////////
|
|
if (pAttrInfo1)
|
|
FreeADsMem( pAttrInfo1 );
|
|
|
|
|
|
/////////////////////////////////////////
|
|
// Now get attribute values requested
|
|
// Note: The order is not necessarily the
|
|
// same as requested using pAttrNames.
|
|
///////////////////////////////////////////
|
|
hr = pDirObject->GetObjectAttributes( pAttrNames,
|
|
dwNumAttr,
|
|
&pAttrInfo,
|
|
&dwReturn );
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
//Fill values of text controls with information taken from
|
|
//object attributes
|
|
for(DWORD idx=0; idx < dwReturn;idx++, pAttrInfo++ )
|
|
{
|
|
if (_wcsicmp(pAttrInfo->pszAttrName,L"employeeID") == 0 &&
|
|
pAttrInfo->pADsValues->CaseIgnoreString != '\0')
|
|
{
|
|
SetWindowText(GetDlgItem(hDlg,IDC_EMPID),pAttrInfo->pADsValues->CaseIgnoreString);
|
|
}
|
|
else if (_wcsicmp(pAttrInfo->pszAttrName,L"mail") == 0 &&
|
|
pAttrInfo->pADsValues->CaseIgnoreString != '\0')
|
|
{
|
|
SetWindowText(GetDlgItem(hDlg,IDC_EMAIL),pAttrInfo->pADsValues->CaseIgnoreString);
|
|
}
|
|
else if (_wcsicmp(pAttrInfo->pszAttrName,L"physicalDeliveryOfficeName") == 0 &&
|
|
pAttrInfo->pADsValues->CaseIgnoreString != '\0')
|
|
{
|
|
SetWindowText(GetDlgItem(hDlg,IDC_OFFICE),pAttrInfo->pADsValues->CaseIgnoreString);
|
|
}
|
|
else if (_wcsicmp(pAttrInfo->pszAttrName,L"telephoneNumber") == 0 &&
|
|
pAttrInfo->pADsValues->CaseIgnoreString != '\0')
|
|
{
|
|
SetWindowText(GetDlgItem(hDlg,IDC_TELNUMBER),pAttrInfo->pADsValues->CaseIgnoreString);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Release our IDirectoryObject interface
|
|
pDirObject->Release();
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
// Use FreeADsMem for all memory obtained from the ADSI call.
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
if (pAttrInfo)
|
|
//First subtract pointer increments in the above for loop to our original pAttrInfo
|
|
pAttrInfo = pAttrInfo-(dwReturn);
|
|
|
|
FreeADsMem(pAttrInfo);
|
|
|
|
return TRUE;
|
|
}
|
|
} //WM_INITDIALOG
|
|
|
|
break;
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//WM_NOTIFY handler
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *)lParam)->code)
|
|
{
|
|
//We use this notification to enable the Advanced button on the general page
|
|
case PSN_SETACTIVE:
|
|
if (!pThis->m_hDlgModeless)
|
|
EnableWindow(GetDlgItem(hDlg, IDC_BUTTONADV), TRUE);
|
|
return TRUE;
|
|
break;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//PSN_APPLY handler
|
|
/////////////////////////////////////////////////////////////////
|
|
case PSN_APPLY:
|
|
{
|
|
if(b_IsDirty)
|
|
{
|
|
IDirectoryObject* pDirObject = NULL;
|
|
HRESULT hr = ADsGetObject(pThis->m_ObjPath, IID_IDirectoryObject,(void **)&pDirObject);
|
|
|
|
_ASSERT(SUCCEEDED(hr));
|
|
|
|
//Apply changes user made here
|
|
WCHAR empID[128];
|
|
WCHAR email[128];
|
|
WCHAR office[128];
|
|
WCHAR telnumber[128];
|
|
|
|
DWORD dwReturn;
|
|
ADSVALUE snEmpID, snEmail, snOffice, snTelnumber;
|
|
ADS_ATTR_INFO attrInfo[] = { {L"employeeID",ADS_ATTR_UPDATE,ADSTYPE_CASE_IGNORE_STRING,&snEmpID,1},
|
|
{L"mail",ADS_ATTR_UPDATE,ADSTYPE_CASE_IGNORE_STRING,&snEmail,1},
|
|
{L"physicalDeliveryOfficeName",ADS_ATTR_UPDATE,ADSTYPE_CASE_IGNORE_STRING,&snOffice,1},
|
|
{L"telephoneNumber",ADS_ATTR_UPDATE,ADSTYPE_CASE_IGNORE_STRING,&snTelnumber,1},
|
|
};
|
|
DWORD dwAttrs = 0;
|
|
dwAttrs = sizeof(attrInfo)/sizeof(ADS_ATTR_INFO);
|
|
|
|
GetWindowText(GetDlgItem(hDlg, IDC_EMPID), empID, sizeof(empID));
|
|
GetWindowText(GetDlgItem(hDlg, IDC_EMAIL), email, sizeof(email));
|
|
GetWindowText(GetDlgItem(hDlg, IDC_OFFICE), office, sizeof(office));
|
|
GetWindowText(GetDlgItem(hDlg, IDC_TELNUMBER), telnumber, sizeof(telnumber));
|
|
|
|
snEmpID.dwType=ADSTYPE_CASE_IGNORE_STRING;
|
|
snEmpID.CaseIgnoreString = empID;
|
|
|
|
snEmail.dwType=ADSTYPE_CASE_IGNORE_STRING;
|
|
snEmail.CaseIgnoreString = email;
|
|
|
|
snOffice.dwType=ADSTYPE_CASE_IGNORE_STRING;
|
|
snOffice.CaseIgnoreString = office;
|
|
|
|
snTelnumber.dwType=ADSTYPE_CASE_IGNORE_STRING;
|
|
snTelnumber.CaseIgnoreString = telnumber;
|
|
|
|
hr = pDirObject->SetObjectAttributes(attrInfo, dwAttrs, &dwReturn);
|
|
if (SUCCEEDED(hr))
|
|
MessageBox(hDlg,
|
|
L"Changes accepted",
|
|
L"Changes to Object Attributes",
|
|
MB_OK | MB_ICONEXCLAMATION);
|
|
else
|
|
MessageBox(hDlg,
|
|
L"Some or all changes were rejected\nby the directory service.",
|
|
L"Changes to Object Attributes",
|
|
MB_OK | MB_ICONWARNING);
|
|
|
|
//Release our IDirectoryObject interface
|
|
pDirObject->Release();
|
|
|
|
b_IsDirty = FALSE;
|
|
}
|
|
//No user changes. Property sheet will go down, so
|
|
//first check if our property page's child dialog is open
|
|
else if (pThis->m_hDlgModeless)
|
|
PostMessage(pThis->m_hDlgModeless, WM_CLOSE, wParam, lParam);
|
|
|
|
return TRUE;
|
|
|
|
break; //PSN_APPLY
|
|
}
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//PSN_QUERYCANCEL handler
|
|
/////////////////////////////////////////////////////////////////
|
|
case PSN_QUERYCANCEL:
|
|
if (pThis->m_hDlgModeless)
|
|
//The property page's child window is still open, so
|
|
//we need to close it first.
|
|
PostMessage(pThis->m_hDlgModeless, WM_CLOSE, wParam, lParam);
|
|
|
|
return TRUE;
|
|
break; //PSN_QUERYCANCEL
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
default:
|
|
return FALSE;
|
|
break;
|
|
|
|
} //end switch (((NMHDR FAR *)lParam)->code)
|
|
|
|
break; //WM_NOTIFY
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//WM_COMMAND handler
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
/////////////////////////////////////////////////////////////////
|
|
//IDC_EMPID, IDC_EMPID, IDC_OFFICE, IDC_TELNUMBER handler
|
|
/////////////////////////////////////////////////////////////////
|
|
case IDC_EMPID:
|
|
case IDC_EMAIL:
|
|
case IDC_OFFICE:
|
|
case IDC_TELNUMBER:
|
|
|
|
if (EN_CHANGE == HIWORD(wParam) &&
|
|
SendMessage(GetDlgItem(hDlg, LOWORD(wParam)),EM_GETMODIFY,0,0))
|
|
{
|
|
//Activate Apply button
|
|
SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
|
|
|
|
//Set b_IsDirty to TRUE, indicating that user changes have occurred
|
|
//Used in handling PSN_APPLY
|
|
b_IsDirty = TRUE;
|
|
}
|
|
|
|
return TRUE;
|
|
break;
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//IDC_BUTTONADV handler
|
|
/////////////////////////////////////////////////////////////////
|
|
case IDC_BUTTONADV:
|
|
{
|
|
//Disable Advanced button so that more than one child dialog
|
|
//can't be available at a given time
|
|
EnableWindow(GetDlgItem(hDlg, IDC_BUTTONADV), FALSE);
|
|
|
|
//Create a secondary dialog
|
|
pThis->m_hDlgModeless = CreateDialogParam(g_hinst, MAKEINTRESOURCE(IDD_DSExtensionPage),
|
|
hDlg, AdvDialogProc, reinterpret_cast<LPARAM>(pThis));
|
|
|
|
return TRUE;
|
|
}
|
|
break; //IDC_BUTTONADV
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
} // end switch
|
|
|
|
break; //WM_COMMAND
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//WM_MODELESSDLGCLOSED handler (custom window message)
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
case WM_MODELESSDLGCLOSED:
|
|
//Enable Advanced button again
|
|
EnableWindow(GetDlgItem(hDlg, IDC_BUTTONADV), TRUE);
|
|
return TRUE;
|
|
break;
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//WM_DESTROY handler
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
case WM_DESTROY:
|
|
pThis->m_hPropPageWnd = NULL;
|
|
RemoveProp(hDlg, L"ID");
|
|
return TRUE;
|
|
break;
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
default:
|
|
return FALSE;
|
|
break;
|
|
} //
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CALLBACK CPropPageExt::AdvDialogProc(HWND hDlg,
|
|
UINT uMessage,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
static CPropPageExt *pThis = NULL;
|
|
|
|
switch (uMessage)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//WM_INITDIALOG handler
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
case WM_INITDIALOG:
|
|
{
|
|
BSTR bsResult;
|
|
|
|
pThis = reinterpret_cast<CPropPageExt *>(lParam);
|
|
|
|
HRESULT hr;
|
|
IADs* pIADs = NULL;
|
|
|
|
hr = ADsGetObject( pThis->m_ObjPath, IID_IADs,(void **)&pIADs);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
// Retrieves the GUID for this object- The guid uniquely identifies
|
|
// this directory object. The Guid is globally unique
|
|
// Also the guid is rename/move safe. The ADsPath below returns the
|
|
// CURRENT location of the object- The guid remains constant regardless of
|
|
// name or location of the directory object
|
|
pIADs->get_GUID(&bsResult);
|
|
SetWindowText(GetDlgItem(hDlg,IDC_GUID),bsResult);
|
|
SysFreeString(bsResult);
|
|
|
|
// Retrieves the RDN
|
|
pIADs->get_Name(&bsResult);
|
|
SetWindowText(GetDlgItem(hDlg,IDC_NAME),bsResult);
|
|
SysFreeString(bsResult);
|
|
|
|
// Retrieves the value in the class attribute, that is, group
|
|
pIADs->get_Class(&bsResult);
|
|
SetWindowText(GetDlgItem(hDlg,IDC_CLASS),bsResult);
|
|
SysFreeString(bsResult);
|
|
|
|
// Retrieves the full literal LDAP path for this object.
|
|
// This may be used to re-bind to this object- though for persistent
|
|
// storage (and to be 'move\rename' safe) it is suggested that the
|
|
// guid be used instead of the ADsPath
|
|
pIADs->get_ADsPath(&bsResult);
|
|
SetWindowText(GetDlgItem(hDlg,IDC_ADSPATH),bsResult);
|
|
SysFreeString(bsResult);
|
|
|
|
// Retrieves the LDAP path for the parent\container for this object
|
|
pIADs->get_Parent(&bsResult);
|
|
SetWindowText(GetDlgItem(hDlg,IDC_PARENT),bsResult);
|
|
SysFreeString(bsResult);
|
|
|
|
// Retrieves the LDAP path for the Schema definition of the object returned from
|
|
/// the IADs::get_Schema() member
|
|
pIADs->get_Schema(&bsResult);
|
|
SetWindowText(GetDlgItem(hDlg,IDC_SCHEMA),bsResult);
|
|
SysFreeString(bsResult);
|
|
|
|
pIADs->Release();
|
|
pIADs = NULL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
break;
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//WM_COMMAND handler
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
case WM_COMMAND:
|
|
switch (LOWORD (wParam))
|
|
{
|
|
case IDOK :
|
|
PostMessage(hDlg, WM_CLOSE, wParam, lParam);
|
|
return TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//WM_CLOSE handler
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
case WM_CLOSE:
|
|
DestroyWindow (hDlg);
|
|
SendMessage(pThis->m_hPropPageWnd, WM_MODELESSDLGCLOSED, (WPARAM)hDlg, 0);
|
|
pThis->m_hDlgModeless = NULL;
|
|
return TRUE;
|
|
break;
|
|
|
|
}//end switch (uMessage)
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
return FALSE ;
|
|
}
|
|
|
|
|
|
|