Leaked source code of windows server 2003
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

//+-------------------------------------------------------------------------
//
// 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;
}