|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: qryfrm.cpp
//
//--------------------------------------------------------------------------
// QryFrm.cpp : Implementation of CRRASQueryForm
#include "stdafx.h"
#include <cmnquryp.h>
#include "QryFrm.h"
#include "dlggen.h"
#include "dlgadv.h"
COLUMNINFO RRASColumn[] = { {0, 40, IDS_QRY_COL_CN, 0, ATTR_NAME_DN}, {0, 30, IDS_QRY_COL_OBJECTCLASS, 1, ATTR_NAME_OBJECTCLASS}, {0, 30, IDS_QRY_COL_RRASATTRIBUTE, 2, ATTR_NAME_RRASATTRIBUTE}, };
int cRRASColumn = 3;
/////////////////////////////////////////////////////////////////////////////
// CRRASQueryForm
//=========================================================================
// IQueryForm methods
HRESULT PageProc(LPCQPAGE pPage, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); HRESULT GetQueryParams(HWND hWnd, LPDSQUERYPARAMS* ppDsQueryParams);
STDMETHODIMP CRRASQueryForm::Initialize(HKEY hkForm) { // This method is called to initialize the query form object, it is called before
// any pages are added. hkForm should be ignored, in the future however it
// will be a way to persist form state.
HRESULT hr = S_OK;
return hr; }
STDMETHODIMP CRRASQueryForm::AddForms(LPCQADDFORMSPROC pAddFormsProc, LPARAM lParam) { CQFORM cqf; AFX_MANAGE_STATE(AfxGetStaticModuleState());
// This method is called to allow the form handler to register its query form(s),
// each form is identifiered by a CLSID and registered via the pAddFormProc. Here
// we are going to register a test form.
// When registering a form which is only applicable to a specific task, eg. Find a Domain
// object, it is advised that the form be marked as hidden (CQFF_ISNEVERLISTED) which
// will cause it not to appear in the form picker control. Then when the
// client wants to use this form, they specify the form identifier and ask for the
// picker control to be hidden.
if ( !pAddFormsProc ) return E_INVALIDARG;
cqf.cbStruct = sizeof(cqf); cqf.dwFlags = CQFF_NOGLOBALPAGES | CQFF_ISNEVERLISTED; cqf.clsid = CLSID_RRASQueryForm; cqf.hIcon = NULL;
CString title; title.LoadString(IDS_QRY_TITLE_RRASQUERYFORM); cqf.pszTitle = (LPCTSTR)title;
return pAddFormsProc(lParam, &cqf); }
STDMETHODIMP CRRASQueryForm::AddPages(LPCQADDPAGESPROC pAddPagesProc, LPARAM lParam) { HRESULT hr = S_OK; CQPAGE cqp; AFX_MANAGE_STATE(AfxGetStaticModuleState());
// AddPages is called after AddForms, it allows us to add the pages for the
// forms we have registered. Each page is presented on a seperate tab within
// the dialog. A form is a dialog with a DlgProc and a PageProc.
//
// When registering a page the entire structure passed to the callback is copied,
// the amount of data to be copied is defined by the cbStruct field, therefore
// a page implementation can grow this structure to store extra information. When
// the page dialog is constructed via CreateDialog the CQPAGE strucuture is passed
// as the create param.
if ( !pAddPagesProc ) return E_INVALIDARG;
cqp.cbStruct = sizeof(cqp); cqp.dwFlags = 0x0; cqp.pPageProc = PageProc; cqp.hInstance = _Module.m_hInst; cqp.idPageName = IDS_QRY_TITLE_GENERALPAGE; cqp.idPageTemplate = IDD_QRY_GENERAL; cqp.pDlgProc = DlgProc; cqp.lParam = (LPARAM)new CDlgGeneral();
hr = pAddPagesProc(lParam, CLSID_RRASQueryForm, &cqp);
if(hr != S_OK) return hr;
cqp.dwFlags = 0x0; cqp.pPageProc = PageProc; cqp.hInstance = _Module.m_hInst; cqp.idPageName = IDS_QRY_TITLE_ADVANCEDPAGE; cqp.idPageTemplate = IDD_QRY_ADVANCED; cqp.pDlgProc = DlgProc; cqp.lParam = (LPARAM)new CDlgAdvanced();
return pAddPagesProc(lParam, CLSID_RRASQueryForm, &cqp);
}
/*---------------------------------------------------------------------------*/
// The PageProc is used to perform general house keeping and communicate between
// the frame and the page.
//
// All un-handled, or unknown reasons should result in an E_NOIMPL response
// from the proc.
//
// In:
// pPage -> CQPAGE structure (copied from the original passed to pAddPagesProc)
// hwnd = handle of the dialog for the page
// uMsg, wParam, lParam = message parameters for this event
//
// Out:
// HRESULT
//
// uMsg reasons:
// ------------
// CQPM_INIIIALIZE
// CQPM_RELEASE
// These are issued as a result of the page being declared or freed, they
// allow the caller to AddRef, Release or perform basic initialization
// of the form object.
//
// CQPM_ENABLE
// Enable is when the query form needs to enable or disable the controls
// on its page. wParam contains TRUE/FALSE indicating the state that
// is required.
//
// CQPM_GETPARAMETERS
// To collect the parameters for the query each page on the active form
// receives this event. lParam is an LPVOID* which is set to point to the
// parameter block to pass to the handler, if the pointer is non-NULL
// on entry the form needs to appened its query information to it. The
// parameter block is handler specific.
//
// Returning S_FALSE from this event causes the query to be canceled.
//
// CQPM_CLEARFORM
// When the page window is created for the first time, or the user clicks
// the clear search the page receives a CQPM_CLEARFORM notification, at
// which point it needs to clear out the edit controls it has and
// return to a default state.
//
// CQPM_PERSIST:
// When loading of saving a query, each page is called with an IPersistQuery
// interface which allows them to read or write the configuration information
// to save or restore their state. lParam is a pointer to the IPersistQuery object,
// and wParam is TRUE/FALSE indicating read or write accordingly.
HRESULT PageProc(LPCQPAGE pQueryPage, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HRESULT hr = S_OK; AFX_MANAGE_STATE(AfxGetStaticModuleState());
CQryDialog* pDialog = (CQryDialog*)pQueryPage->lParam;
ASSERT(pDialog);
switch ( uMsg ) { // Initialize so AddRef the object we are associated with so that
// we don't get unloaded.
case CQPM_INITIALIZE: break;
// Changed from qform sample to detach the hwnd, and delete the CDialog
// ensure correct destruction etc.
case CQPM_RELEASE: pDialog->Detach(); SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM)0); delete pDialog; break;
// Enable so fix the state of our two controls within the window.
case CQPM_ENABLE: break;
// Fill out the parameter structure to return to the caller, this is
// handler specific. In our case we constructure a query of the CN
// and objectClass properties, and we show a columns displaying both
// of these. For further information about the DSQUERYPARAMs structure
// see dsquery.h
case CQPM_GETPARAMETERS: hr = pDialog->GetQueryParams((LPDSQUERYPARAMS*)lParam); break;
// Clear form, therefore set the window text for these two controls
// to zero.
case CQPM_CLEARFORM: hr = pDialog->ClearForm(); break; // persistance is not currently supported by this form.
case CQPM_PERSIST: { BOOL fRead = (BOOL)wParam; IPersistQuery* pPersistQuery = (IPersistQuery*)lParam;
if ( !pPersistQuery ) return E_INVALIDARG;
hr = pDialog->Persist(pPersistQuery, fRead); break; }
default: hr = E_NOTIMPL; break; }
return hr; }
/*---------------------------------------------------------------------------*/
// The DlgProc is a standard Win32 dialog proc associated with the form
// window.
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPCQPAGE pQueryPage; CQryDialog* pDialog;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if ( uMsg == WM_INITDIALOG ) { // changed from qForm sample to save CDialog pointer
// in the DWL_USER field of the dialog box instance.
pQueryPage = (LPCQPAGE)lParam; pDialog = (CQryDialog*)pQueryPage->lParam; pDialog->Attach(hwnd);
SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM)pDialog);
return pDialog->OnInitDialog();
} else { // CDialog pointer is stored in DWL_USER
// dialog structure, note however that in some cases this will
// be NULL as it is set on WM_INITDIALOG.
pDialog = (CQryDialog*)GetWindowLongPtr(hwnd, DWLP_USER); }
if(!pDialog) return FALSE; else return AfxCallWndProc(pDialog, hwnd, uMsg, wParam, lParam); }
/*---------------------------------------------------------------------------*/
// Build a parameter block to pass to the query handler. Each page is called
// with a pointer to a pointer which it must update with the revised query
// block. For the first page this pointer is NULL, for subsequent pages
// the pointer is non-zero and the page must append its data into the
// allocation.
//
// Returning either and error or S_FALSE stops the query. An error is
// reported to the user, S_FALSE stops silently.
HRESULT BuildQueryParams(LPDSQUERYPARAMS* ppDsQueryParams, LPWSTR pQuery) { ASSERT(pQuery); if(*ppDsQueryParams) return QueryParamsAddQueryString(ppDsQueryParams, pQuery);
else return QueryParamsAlloc(ppDsQueryParams, pQuery, cRRASColumn, RRASColumn);
}
/*-----------------------------------------------------------------------------
/ QueryParamsAlloc / ---------------- / Construct a block we can pass to the DS query handler which contains / all the parameters for the query. / / In: / ppDsQueryParams -> receives the parameter block / pQuery -> LDAP query string to be used / iColumns = number of columns / pColumnInfo -> column info structure to use / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT QueryParamsAlloc(LPDSQUERYPARAMS* ppDsQueryParams, LPWSTR pQuery, LONG iColumns, LPCOLUMNINFO aColumnInfo) { HRESULT hr; LPDSQUERYPARAMS pDsQueryParams = NULL; LONG cbStruct; LONG i;
ASSERT(!*ppDsQueryParams);
TRACE(L"QueryParamsAlloc");
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if ( !pQuery || !iColumns || !ppDsQueryParams ) ExitGracefully(hr, E_INVALIDARG, "Failed to build query parameter block");
// Compute the size of the structure we need to be using
cbStruct = sizeof(DSQUERYPARAMS) + (sizeof(DSCOLUMN)*iColumns); cbStruct += StringByteSizeW(pQuery);
for ( i = 0 ; i < iColumns ; i++ ) { if ( aColumnInfo[i].pPropertyName ) cbStruct += StringByteSizeW(aColumnInfo[i].pPropertyName); }
pDsQueryParams = (LPDSQUERYPARAMS)CoTaskMemAlloc(cbStruct);
if ( !pDsQueryParams ) ExitGracefully(hr, E_OUTOFMEMORY, "Failed to allocate parameter block");
// Structure allocated so lets fill it with data
pDsQueryParams->cbStruct = cbStruct; pDsQueryParams->dwFlags = 0; pDsQueryParams->hInstance = _Module.m_hInst; pDsQueryParams->iColumns = iColumns; pDsQueryParams->dwReserved = 0;
cbStruct = sizeof(DSQUERYPARAMS) + (sizeof(DSCOLUMN)*iColumns);
pDsQueryParams->offsetQuery = cbStruct; StringByteCopyW(pDsQueryParams, cbStruct, pQuery); cbStruct += StringByteSizeW(pQuery);
for ( i = 0 ; i < iColumns ; i++ ) { pDsQueryParams->aColumns[i].dwFlags = 0; pDsQueryParams->aColumns[i].fmt = aColumnInfo[i].fmt; pDsQueryParams->aColumns[i].cx = aColumnInfo[i].cx; pDsQueryParams->aColumns[i].idsName = aColumnInfo[i].idsName; pDsQueryParams->aColumns[i].dwReserved = 0;
if ( aColumnInfo[i].pPropertyName ) { pDsQueryParams->aColumns[i].offsetProperty = cbStruct; StringByteCopyW(pDsQueryParams, cbStruct, aColumnInfo[i].pPropertyName); cbStruct += StringByteSizeW(aColumnInfo[i].pPropertyName); } else { pDsQueryParams->aColumns[i].offsetProperty = aColumnInfo[i].iPropertyIndex; } }
hr = S_OK; // success
exit_gracefully:
if ( FAILED(hr) && pDsQueryParams ) { CoTaskMemFree(pDsQueryParams); pDsQueryParams = NULL; }
*ppDsQueryParams = pDsQueryParams;
return hr; }
/*-----------------------------------------------------------------------------
/ QueryParamsAddQueryString / ------------------------- / Given an existing DS query block appened the given LDAP query string into / it. We assume that the query block has been allocated by IMalloc (or CoTaskMemAlloc). / / In: / ppDsQueryParams -> receives the parameter block / pQuery -> LDAP query string to be appended / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT QueryParamsAddQueryString(LPDSQUERYPARAMS* ppDsQueryParams, LPWSTR pQuery) { HRESULT hr; LPWSTR pOriginalQuery = NULL; LPDSQUERYPARAMS pDsQuery = *ppDsQueryParams; INT cbQuery, i; LPVOID pv;
ASSERT(*ppDsQueryParams); TRACE(_T("QueryParamsAddQueryString"));
if ( pQuery ) { if ( !pDsQuery ) ExitGracefully(hr, E_INVALIDARG, "No query to append to");
// Work out the size of the bits we are adding, take a copy of the
// query string and finally re-alloc the query block (which may cause it
// to move).
cbQuery = StringByteSizeW(pQuery) + StringByteSizeW(L"(&)"); TRACE(_T("DSQUERYPARAMS being resized by %d bytes"));
i = (wcslen((LPWSTR)ByteOffset(pDsQuery, pDsQuery->offsetQuery)) + 1) * sizeof(WCHAR); pOriginalQuery = (WCHAR*)_alloca(i); lstrcpyW(pOriginalQuery, (LPWSTR)ByteOffset(pDsQuery, pDsQuery->offsetQuery)); pv = CoTaskMemRealloc(*ppDsQueryParams, pDsQuery->cbStruct+cbQuery); if ( pv == NULL ) ExitGracefully(hr, E_OUTOFMEMORY, "Failed to re-alloc control block");
*ppDsQueryParams = (LPDSQUERYPARAMS) pv;
pDsQuery = *ppDsQueryParams; // if may have moved
// Now move everything above the query string up, and fix all the
// offsets that reference those items (probably the property table),
// finally adjust the size to reflect the change
MoveMemory(ByteOffset(pDsQuery, pDsQuery->offsetQuery+cbQuery), ByteOffset(pDsQuery, pDsQuery->offsetQuery), (pDsQuery->cbStruct - pDsQuery->offsetQuery)); for ( i = 0 ; i < pDsQuery->iColumns ; i++ ) { if ( pDsQuery->aColumns[i].offsetProperty > pDsQuery->offsetQuery ) { pDsQuery->aColumns[i].offsetProperty += cbQuery; } }
wcscpy((LPWSTR)ByteOffset(pDsQuery, pDsQuery->offsetQuery), L"(&"); wcscat((LPWSTR)ByteOffset(pDsQuery, pDsQuery->offsetQuery), pOriginalQuery); wcscat((LPWSTR)ByteOffset(pDsQuery, pDsQuery->offsetQuery), pQuery); wcscat((LPWSTR)ByteOffset(pDsQuery, pDsQuery->offsetQuery), L")");
pDsQuery->cbStruct += cbQuery; }
hr = S_OK;
exit_gracefully:
return hr; }
// Get the list of values in the dictionary, the variant is expected to be SARRY
HRESULT QueryRRASAdminDictionary(VARIANT* pVar) { ASSERT(pVar); USES_CONVERSION;
CString str, str1;
IADs* pIADs = NULL; // enumerate EAP list
// retieve the list of EAPTypes in the DS
// get ROOTDSE
HRESULT hr = S_OK; CHECK_HR(hr = ADsGetObject(L"LDAP://RootDSE", IID_IADs, (void**)&pIADs));
ASSERT(pIADs);
VariantClear(pVar); CHECK_HR(hr = pIADs->Get(L"configurationNamingContext", pVar)); str1 = V_BSTR(pVar);
pIADs->Release(); pIADs = NULL;
str = L"LDAP://"; str += CN_DICTIONARY; str += str1;
// Dictionary Object
CHECK_HR(hr = ADsGetObject(T2W((LPTSTR)(LPCTSTR)str), IID_IADs, (void**)&pIADs)); ASSERT(pIADs); VariantClear(pVar); CHECK_HR(hr = pIADs->GetEx(ATTR_NAME_RRASDICENTRY, pVar));
goto L_EXIT;
L_ERR: VariantClear(pVar); L_EXIT:
if(pIADs) pIADs->Release();
return hr; }
HRESULT GetGeneralPageAttributes(CStrArray& array) { HRESULT hr = S_OK;
CString* pStr = NULL;
/*
#define ATTR_VAL_LANtoLAN L"311:6:601"
#define ATTR_VAL_RAS L"311:6:602"
#define ATTR_VAL_DEMANDDIAL L"311:6:603"
*/ try { pStr = new CString(ATTR_VAL_LANtoLAN); array.Add(pStr); pStr = new CString(ATTR_VAL_RAS); array.Add(pStr);
pStr = new CString(ATTR_VAL_DEMANDDIAL); array.Add(pStr); } catch(CMemoryException&) { hr = E_OUTOFMEMORY; }
return hr; }
|