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.
443 lines
14 KiB
443 lines
14 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1999 - 1999
|
|
//
|
|
// File: queryui.cpp
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#include <SnapBase.h>
|
|
#include <shlobj.h>
|
|
#include <dsclient.h> // Browse for container dialog
|
|
|
|
#include <cmnquery.h> // IPersistQuery
|
|
#include <dsquery.h> // DSFind dialog
|
|
|
|
#include "resource.h"
|
|
#include "editor.h"
|
|
#include "queryui.h"
|
|
|
|
#ifdef DEBUG_ALLOCATOR
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
#endif
|
|
|
|
BEGIN_MESSAGE_MAP(CADSIEditQueryDialog, CDialog)
|
|
//{{AFX_MSG_MAP(CADsObjectDialog)
|
|
ON_EN_CHANGE(IDC_EDIT_QUERY_STRING, OnEditQueryString)
|
|
ON_EN_CHANGE(IDC_EDIT_QUERY_NAME, OnEditNameString)
|
|
ON_BN_CLICKED(IDC_RADIO_ONELEVEL, OnOneLevel)
|
|
ON_BN_CLICKED(IDC_RADIO_SUBTREE, OnSubtree)
|
|
ON_BN_CLICKED(IDC_BUTTON_BROWSE_CONTAINER, OnBrowse)
|
|
ON_BN_CLICKED(IDC_BUTTON_EDIT_QUERY, OnEditQuery)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
CADSIEditQueryDialog::CADSIEditQueryDialog(CString& szServer,
|
|
CString& sName,
|
|
CString& sFilter,
|
|
CString& sPath,
|
|
CString& sConnectPath,
|
|
BOOL bOneLevel,
|
|
CCredentialObject* pCredObject)
|
|
: CDialog(IDD_QUERY_DIALOG)
|
|
|
|
{
|
|
m_bOneLevel = bOneLevel;
|
|
m_sFilter = sFilter;
|
|
m_sName = sName;
|
|
m_sRootPath = sPath;
|
|
m_sConnectPath = sConnectPath;
|
|
m_szServer = szServer;
|
|
|
|
m_pCredObject = pCredObject;
|
|
}
|
|
|
|
CADSIEditQueryDialog::CADSIEditQueryDialog(CString& szServer,
|
|
CString& sConnectPath,
|
|
CCredentialObject* pCredObject)
|
|
: CDialog(IDD_QUERY_DIALOG)
|
|
{
|
|
m_bOneLevel = FALSE;
|
|
m_sConnectPath = sConnectPath;
|
|
m_szServer = szServer;
|
|
m_pCredObject = pCredObject;
|
|
}
|
|
|
|
CADSIEditQueryDialog::~CADSIEditQueryDialog()
|
|
{
|
|
}
|
|
|
|
|
|
BOOL CADSIEditQueryDialog::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
CEdit* pEditName = (CEdit*)GetDlgItem(IDC_EDIT_QUERY_NAME);
|
|
CEdit* pEditQueryString = (CEdit*)GetDlgItem(IDC_EDIT_QUERY_STRING);
|
|
CEdit* pEditPath = (CEdit*)GetDlgItem(IDC_EDIT_ROOT_PATH);
|
|
CButton* pOneLevelButton = (CButton*)GetDlgItem(IDC_RADIO_ONELEVEL);
|
|
CButton* pSubtreeButton = (CButton*)GetDlgItem(IDC_RADIO_SUBTREE);
|
|
CButton* pOkButton = (CButton*)GetDlgItem(IDOK);
|
|
|
|
if (m_sRootPath != L"")
|
|
{
|
|
CString sDisplayPath;
|
|
GetDisplayPath(sDisplayPath);
|
|
pEditPath->SetWindowText(sDisplayPath);
|
|
}
|
|
|
|
pEditName->SetWindowText(m_sName);
|
|
pEditName->SetLimitText(256); // REVEIW_JEFFJON : Hardcoded length
|
|
pEditQueryString->SetWindowText(m_sFilter);
|
|
pEditQueryString->FmtLines(FALSE);
|
|
pEditQueryString->SetLimitText(256); // REVIEW_JEFFJON : Hardcoded length
|
|
if (pEditQueryString->GetWindowTextLength() > 0 && pEditName->GetWindowTextLength() > 0)
|
|
{
|
|
pOkButton->EnableWindow(TRUE);
|
|
}
|
|
else
|
|
{
|
|
pOkButton->EnableWindow(FALSE);
|
|
}
|
|
pOneLevelButton->SetCheck(m_bOneLevel);
|
|
pSubtreeButton->SetCheck(!m_bOneLevel);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CADSIEditQueryDialog::OnEditQueryString()
|
|
{
|
|
CEdit* pEditName = (CEdit*)GetDlgItem(IDC_EDIT_QUERY_NAME);
|
|
CEdit* pEditQueryString = (CEdit*)GetDlgItem(IDC_EDIT_QUERY_STRING);
|
|
CEdit* pEditPath = (CEdit*)GetDlgItem(IDC_EDIT_ROOT_PATH);
|
|
CButton* pOkButton = (CButton*)GetDlgItem(IDOK);
|
|
|
|
if (pEditQueryString->GetWindowTextLength() > 0 &&
|
|
pEditName->GetWindowTextLength() > 0 &&
|
|
pEditPath->GetWindowTextLength() > 0)
|
|
{
|
|
pEditQueryString->GetWindowText(m_sFilter);
|
|
pOkButton->EnableWindow(TRUE);
|
|
}
|
|
else
|
|
{
|
|
pEditQueryString->GetWindowText(m_sFilter);
|
|
pOkButton->EnableWindow(FALSE);
|
|
}
|
|
}
|
|
|
|
void CADSIEditQueryDialog::OnEditNameString()
|
|
{
|
|
CEdit* pEditName = (CEdit*)GetDlgItem(IDC_EDIT_QUERY_NAME);
|
|
CEdit* pEditQueryString = (CEdit*)GetDlgItem(IDC_EDIT_QUERY_STRING);
|
|
CEdit* pEditPath = (CEdit*)GetDlgItem(IDC_EDIT_ROOT_PATH);
|
|
CButton* pOkButton = (CButton*)GetDlgItem(IDOK);
|
|
|
|
if (pEditQueryString->GetWindowTextLength() > 0 &&
|
|
pEditName->GetWindowTextLength() > 0 &&
|
|
pEditPath->GetWindowTextLength() > 0)
|
|
{
|
|
pEditName->GetWindowText(m_sName);
|
|
pOkButton->EnableWindow(TRUE);
|
|
}
|
|
else
|
|
{
|
|
pEditName->GetWindowText(m_sName);
|
|
pOkButton->EnableWindow(FALSE);
|
|
}
|
|
}
|
|
|
|
void CADSIEditQueryDialog::OnOneLevel()
|
|
{
|
|
CButton* pOneLevelButton = (CButton*)GetDlgItem(IDC_RADIO_ONELEVEL);
|
|
|
|
m_bOneLevel = pOneLevelButton->GetCheck();
|
|
}
|
|
|
|
void CADSIEditQueryDialog::OnSubtree()
|
|
{
|
|
CButton* pOneLevelButton = (CButton*)GetDlgItem(IDC_RADIO_ONELEVEL);
|
|
|
|
m_bOneLevel = pOneLevelButton->GetCheck();
|
|
}
|
|
|
|
void CADSIEditQueryDialog::OnBrowse()
|
|
{
|
|
HRESULT hr = S_OK, hCredResult;
|
|
DWORD result;
|
|
CString strTitle;
|
|
strTitle.LoadString (IDS_QUERY_BROWSE_TITLE);
|
|
|
|
DSBROWSEINFO dsbi;
|
|
::ZeroMemory( &dsbi, sizeof(dsbi) );
|
|
|
|
TCHAR szPath[2 * MAX_PATH+1];
|
|
CString str;
|
|
str.LoadString(IDS_MOVE_TARGET);
|
|
|
|
dsbi.hwndOwner = GetSafeHwnd();
|
|
dsbi.cbStruct = sizeof (DSBROWSEINFO);
|
|
dsbi.pszCaption = (LPWSTR)((LPCWSTR)strTitle); // this is actually the caption
|
|
dsbi.pszTitle = (LPWSTR)((LPCWSTR)str);
|
|
dsbi.pszRoot = m_sConnectPath;
|
|
dsbi.pszPath = szPath;
|
|
dsbi.cchPath = ((2 * MAX_PATH + 1) / sizeof(TCHAR));
|
|
dsbi.dwFlags = DSBI_INCLUDEHIDDEN | DSBI_RETURN_FORMAT;
|
|
dsbi.pfnCallback = NULL;
|
|
dsbi.lParam = 0;
|
|
dsbi.dwReturnFormat = ADS_FORMAT_X500;
|
|
|
|
// Specify credentials
|
|
CString sUserName;
|
|
EncryptedString password;
|
|
WCHAR* cleartext = NULL;
|
|
|
|
// NOTICE-NTRAID#NTBUG9-563071-2002/04/17-artm Password buffer should not be allocated on stack.
|
|
// I've rewritten the password code to use encrypted string. See bug
|
|
// for details.
|
|
|
|
if (m_pCredObject->UseCredentials())
|
|
{
|
|
m_pCredObject->GetUsername(sUserName);
|
|
password = m_pCredObject->GetPassword();
|
|
|
|
// This should never happen, but let's be paranoid.
|
|
ASSERT(password.GetLength() <= MAX_PASSWORD_LENGTH);
|
|
|
|
cleartext = password.GetClearTextCopy();
|
|
|
|
// If we're out of memory our clear text is null.
|
|
// Let the user know that bad things are happening
|
|
// and abort.
|
|
if (NULL == cleartext)
|
|
{
|
|
password.DestroyClearTextCopy(cleartext);
|
|
ADSIEditErrorMessage(E_OUTOFMEMORY);
|
|
return;
|
|
}
|
|
|
|
dsbi.dwFlags |= DSBI_HASCREDENTIALS;
|
|
dsbi.pUserName = sUserName;
|
|
dsbi.pPassword = cleartext;
|
|
}
|
|
|
|
result = DsBrowseForContainer( &dsbi );
|
|
|
|
// Clean up any clear text copies we have.
|
|
if (m_pCredObject->UseCredentials())
|
|
{
|
|
password.DestroyClearTextCopy(cleartext);
|
|
}
|
|
|
|
if ( result == IDOK )
|
|
{ // returns -1, 0, IDOK or IDCANCEL
|
|
// get path from BROWSEINFO struct, put in text edit field
|
|
TRACE(_T("returned from DS Browse successfully with:\n %s\n"),
|
|
dsbi.pszPath);
|
|
m_sRootPath = dsbi.pszPath;
|
|
|
|
CEdit* pEditPath = (CEdit*)GetDlgItem(IDC_EDIT_ROOT_PATH);
|
|
|
|
CString sDisplay;
|
|
GetDisplayPath(sDisplay);
|
|
pEditPath->SetWindowText(sDisplay);
|
|
}
|
|
|
|
OnEditNameString(); // to check to see if the ok button should be enabled
|
|
|
|
}
|
|
|
|
void CADSIEditQueryDialog::GetDisplayPath(CString& sDisplay)
|
|
{
|
|
CComPtr<IADsPathname> pIADsPathname;
|
|
HRESULT hr = ::CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IADsPathname, (PVOID *)&(pIADsPathname));
|
|
ASSERT((S_OK == hr) && ((pIADsPathname) != NULL));
|
|
|
|
hr = pIADsPathname->Set(CComBSTR(m_sRootPath), ADS_SETTYPE_FULL);
|
|
if (FAILED(hr))
|
|
{
|
|
TRACE(_T("Set failed. %s"), hr);
|
|
}
|
|
|
|
// Get the leaf name
|
|
CString sDN;
|
|
BSTR bstrPath = NULL;
|
|
hr = pIADsPathname->Retrieve(ADS_FORMAT_X500_DN, &bstrPath);
|
|
if (FAILED(hr))
|
|
{
|
|
TRACE(_T("Failed to get element. %s"), hr);
|
|
sDN = L"";
|
|
}
|
|
else
|
|
{
|
|
sDN = bstrPath;
|
|
}
|
|
|
|
sDisplay = sDN;
|
|
|
|
}
|
|
|
|
// respone to the Edit Query... button
|
|
void CADSIEditQueryDialog::OnEditQuery()
|
|
{
|
|
CLIPFORMAT cfDsQueryParams = (CLIPFORMAT)::RegisterClipboardFormat(CFSTR_DSQUERYPARAMS);
|
|
|
|
// create a query object
|
|
HRESULT hr;
|
|
CComPtr<ICommonQuery> spCommonQuery;
|
|
hr = ::CoCreateInstance(CLSID_CommonQuery, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_ICommonQuery, (PVOID *)&spCommonQuery);
|
|
if (FAILED(hr))
|
|
return;
|
|
|
|
// setup structs to make the query
|
|
DSQUERYINITPARAMS dqip;
|
|
OPENQUERYWINDOW oqw;
|
|
ZeroMemory(&dqip, sizeof(DSQUERYINITPARAMS));
|
|
ZeroMemory(&oqw, sizeof(OPENQUERYWINDOW));
|
|
|
|
dqip.cbStruct = sizeof(dqip);
|
|
dqip.dwFlags = DSQPF_NOSAVE | DSQPF_SHOWHIDDENOBJECTS |
|
|
DSQPF_ENABLEADMINFEATURES;
|
|
|
|
CString szUsername;
|
|
EncryptedString password;
|
|
WCHAR* cleartext = NULL;
|
|
|
|
// Get the username and password if we are impersonating credentials
|
|
if (m_pCredObject->UseCredentials())
|
|
{
|
|
// NOTICE-NTRAID#NTBUG9-563071-2002/04/17-artm Password buffer should not
|
|
// be allocated on stack.
|
|
//
|
|
// I rewrote this to use encrypted string class so that the buffer is not
|
|
// on the stack and to help manage the lifetime of the password. See bug
|
|
// for more information.
|
|
|
|
m_pCredObject->GetUsername(szUsername);
|
|
password = m_pCredObject->GetPassword();
|
|
|
|
// This shouldn't happen, but let's be paranoid.
|
|
ASSERT(password.GetLength() <= MAX_PASSWORD_LENGTH);
|
|
|
|
cleartext = password.GetClearTextCopy();
|
|
|
|
// If we run out of memory our clear text is null.
|
|
// Let the user know that bad things are happening
|
|
// and abort operation.
|
|
if (NULL == cleartext)
|
|
{
|
|
password.DestroyClearTextCopy(cleartext);
|
|
ADSIEditErrorMessage(E_OUTOFMEMORY);
|
|
return;
|
|
}
|
|
|
|
dqip.pUserName = (LPWSTR)(LPCWSTR)szUsername;
|
|
dqip.pPassword = cleartext;
|
|
dqip.dwFlags |= DSQPF_HASCREDENTIALS;
|
|
}
|
|
|
|
if (!m_szServer.IsEmpty())
|
|
{
|
|
dqip.pServer = (LPWSTR)(LPCWSTR)m_szServer;
|
|
dqip.dwFlags |= DSQPF_HASCREDENTIALS;
|
|
}
|
|
dqip.pDefaultScope = NULL;
|
|
|
|
|
|
oqw.cbStruct = sizeof(oqw);
|
|
oqw.dwFlags = OQWF_OKCANCEL | OQWF_DEFAULTFORM | OQWF_REMOVEFORMS |
|
|
OQWF_REMOVESCOPES | OQWF_SAVEQUERYONOK | OQWF_HIDEMENUS | OQWF_HIDESEARCHUI;
|
|
|
|
oqw.clsidHandler = CLSID_DsQuery;
|
|
oqw.pHandlerParameters = &dqip;
|
|
oqw.clsidDefaultForm = CLSID_DsFindAdvanced;
|
|
|
|
// Get the HWND of the current dialog
|
|
HWND hWnd = GetSafeHwnd();
|
|
|
|
// make the call to get the query displayed
|
|
CComPtr<IDataObject> spQueryResultDataObject;
|
|
hr = spCommonQuery->OpenQueryWindow(hWnd, &oqw, &spQueryResultDataObject);
|
|
|
|
// Clean up any clear text copies.
|
|
if (m_pCredObject->UseCredentials())
|
|
{
|
|
password.DestroyClearTextCopy(cleartext);
|
|
cleartext = NULL;
|
|
}
|
|
|
|
if (spQueryResultDataObject == NULL)
|
|
{
|
|
if (FAILED(hr))
|
|
{
|
|
// no query available, reset to no data
|
|
m_sFilter = L"";
|
|
}
|
|
|
|
// user hit cancel
|
|
return;
|
|
}
|
|
|
|
// retrieve the query string from the data object
|
|
FORMATETC fmte = {cfDsQueryParams, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
|
STGMEDIUM medium = {TYMED_NULL, NULL, NULL};
|
|
hr = spQueryResultDataObject->GetData(&fmte, &medium);
|
|
|
|
if (SUCCEEDED(hr)) // we have data
|
|
{
|
|
// get the query string
|
|
LPDSQUERYPARAMS pDsQueryParams = (LPDSQUERYPARAMS)medium.hGlobal;
|
|
LPWSTR pwszFilter = (LPWSTR)ByteOffset(pDsQueryParams, pDsQueryParams->offsetQuery);
|
|
m_sFilter = pwszFilter;
|
|
::ReleaseStgMedium(&medium);
|
|
|
|
// REVIEW_MARCOC: this is a hack waiting for Diz to fix it...
|
|
// the query string should be a well formed expression. Period
|
|
// the query string is in the form (<foo>)(<bar>)...
|
|
// if more of one token, need to wrap as (& (<foo>)(<bar>)...)
|
|
WCHAR* pChar = (WCHAR*)(LPCWSTR)m_sFilter;
|
|
int nLeftPar = 0;
|
|
while (*pChar != NULL)
|
|
{
|
|
if (*pChar == TEXT('('))
|
|
{
|
|
nLeftPar++;
|
|
if (nLeftPar > 1)
|
|
break;
|
|
}
|
|
pChar++;
|
|
}
|
|
if (nLeftPar > 1)
|
|
{
|
|
CString s;
|
|
s.Format(_T("(&%s)"), (LPCTSTR)m_sFilter);
|
|
m_sFilter = s;
|
|
}
|
|
TRACE(_T("m_sFilter = %s\n"), (LPCTSTR)m_sFilter);
|
|
CEdit* pEditQueryString = (CEdit*)GetDlgItem(IDC_EDIT_QUERY_STRING);
|
|
pEditQueryString->SetWindowText(m_sFilter);
|
|
OnEditQueryString();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void CADSIEditQueryDialog::GetResults(CString& sName,
|
|
CString& sFilter,
|
|
CString& sPath,
|
|
BOOL* pOneLevel)
|
|
{
|
|
sName = m_sName;
|
|
sFilter = m_sFilter;
|
|
sPath = m_sRootPath;
|
|
*pOneLevel = m_bOneLevel;
|
|
}
|