windows-nt/Source/XPSP1/NT/ds/security/services/ca/certmmc/chooser.cpp
2020-09-26 16:20:57 +08:00

439 lines
13 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: chooser.cpp
//
//--------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////
// Chooser.cpp
//
// Dialog to choose a machine name.
//
// PURPOSE
// What you have to do is to copy all the files from the
// snapin\chooser\ directory into your project (you may add
// \nt\private\admin\snapin\chooser\ to your include directory if
// you prefer not copying the code).
// If you decide to copy the code to your project, please send mail
// to Dan Morin (T-DanM) and cc to Jon Newman (JonN) so we can
// mail you when we have updates available. The next update will
// be the "Browse" button to select a machine name.
//
//
// DYNALOADED LIBRARIES
//
// HISTORY
// 13-May-1997 t-danm Creation.
// 23-May-1997 t-danm Checkin into public tree. Comments updates.
// 25-May-1997 t-danm Added MMCPropPageCallback().
// 31-Oct-1997 mattt Added dynaload, fixed user <CANCEL> logic
// 1-Oct-1998 mattt Removed reliance on MFC, changed default look to enable certsvr picker
//
/////////////////////////////////////////////////////////////////////
#include <stdafx.h>
#include "chooser.h"
#include "csdisp.h" // certsrv picker
#ifdef _DEBUG
#undef THIS_FILE
#define THIS_FILE __FILE__
#endif
#ifndef INOUT
// The following defines are found in \nt\private\admin\snapin\filemgmt\stdafx.h
#define INOUT
#define Endorse(f) // Dummy macro
#define LENGTH(x) (sizeof(x)/sizeof(x[0]))
#define Assert(f) ASSERT(f)
#endif
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// Replacement for BEGIN_MESSAGE_MAP
BOOL CAutoDeletePropPage::OnCommand(WPARAM wParam, LPARAM lParam)
{
/*
switch(LOWORD(wParam))
{
}
*/
return FALSE;
}
/////////////////////////////////////////////////////////////////////
// Constructor
CAutoDeletePropPage::CAutoDeletePropPage(UINT uIDD) : PropertyPage(uIDD)
{
m_prgzHelpIDs = NULL;
m_autodeleteStuff.cWizPages = 1; // Number of pages in wizard
m_autodeleteStuff.pfnOriginalPropSheetPageProc = m_psp.pfnCallback;
m_psp.dwFlags |= PSP_USECALLBACK;
m_psp.pfnCallback = S_PropSheetPageProc;
m_psp.lParam = reinterpret_cast<LPARAM>(this);
}
CAutoDeletePropPage::~CAutoDeletePropPage()
{
}
/////////////////////////////////////////////////////////////////////
void CAutoDeletePropPage::SetCaption(LPCTSTR pszCaption)
{
m_strCaption = pszCaption; // Copy the caption
m_psp.pszTitle = m_strCaption; // Set the title
m_psp.dwFlags |= PSP_USETITLE;
}
/////////////////////////////////////////////////////////////////////
void CAutoDeletePropPage::SetCaption(UINT uStringID)
{
VERIFY(m_strCaption.LoadString(uStringID));
SetCaption(m_strCaption);
}
/////////////////////////////////////////////////////////////////////
void CAutoDeletePropPage::SetHelp(LPCTSTR szHelpFile, const DWORD rgzHelpIDs[])
{
m_strHelpFile = szHelpFile;
m_prgzHelpIDs = rgzHelpIDs;
}
/////////////////////////////////////////////////////////////////////
void CAutoDeletePropPage::EnableDlgItem(INT nIdDlgItem, BOOL fEnable)
{
Assert(IsWindow(::GetDlgItem(m_hWnd, nIdDlgItem)));
::EnableWindow(::GetDlgItem(m_hWnd, nIdDlgItem), fEnable);
}
/////////////////////////////////////////////////////////////////////
BOOL CAutoDeletePropPage::OnSetActive()
{
HWND hwndParent = ::GetParent(m_hWnd);
Assert(IsWindow(hwndParent));
::PropSheet_SetWizButtons(hwndParent, PSWIZB_FINISH);
return PropertyPage::OnSetActive();
}
/////////////////////////////////////////////////////////////////////
void CAutoDeletePropPage::OnHelp(LPHELPINFO pHelpInfo)
{
if (m_prgzHelpIDs == NULL || m_strHelpFile.IsEmpty())
return;
if (pHelpInfo != NULL && pHelpInfo->iContextType == HELPINFO_WINDOW)
{
// Display context help for a control
::WinHelp((HWND)pHelpInfo->hItemHandle, m_strHelpFile,
HELP_WM_HELP, (ULONG_PTR)(LPVOID)m_prgzHelpIDs);
}
return;
}
/////////////////////////////////////////////////////////////////////
void CAutoDeletePropPage::OnContextHelp(HWND hwnd)
{
if (m_prgzHelpIDs == NULL || m_strHelpFile.IsEmpty())
return;
Assert(IsWindow(hwnd));
::WinHelp(hwnd, m_strHelpFile, HELP_CONTEXTMENU, (ULONG_PTR)(LPVOID)m_prgzHelpIDs);
return;
}
/////////////////////////////////////////////////////////////////////
// S_PropSheetPageProc()
//
// Static member function used to delete the CAutoDeletePropPage object
// when wizard terminates
//
UINT CALLBACK CAutoDeletePropPage::S_PropSheetPageProc(
HWND hwnd,
UINT uMsg,
LPPROPSHEETPAGE ppsp)
{
Assert(ppsp != NULL);
CAutoDeletePropPage * pThis;
pThis = reinterpret_cast<CAutoDeletePropPage*>(ppsp->lParam);
Assert(pThis != NULL);
BOOL fDefaultRet;
switch (uMsg)
{
case PSPCB_RELEASE:
fDefaultRet = FALSE;
if (--(pThis->m_autodeleteStuff.cWizPages) <= 0)
{
// Remember callback on stack since "this" will be deleted
LPFNPSPCALLBACK pfnOrig = pThis->m_autodeleteStuff.pfnOriginalPropSheetPageProc;
delete pThis;
if (pfnOrig)
return (pfnOrig)(hwnd, uMsg, ppsp);
else
return fDefaultRet;
}
break;
case PSPCB_CREATE:
fDefaultRet = TRUE;
// do not increase refcount, PSPCB_CREATE may or may not be called
// depending on whether the page was created. PSPCB_RELEASE can be
// depended upon to be called exactly once per page however.
break;
} // switch
if (pThis->m_autodeleteStuff.pfnOriginalPropSheetPageProc)
return (pThis->m_autodeleteStuff.pfnOriginalPropSheetPageProc)(hwnd, uMsg, ppsp);
else
return fDefaultRet;
} // CAutoDeletePropPage::S_PropSheetPageProc()
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// Replacement for BEGIN_MESSAGE_MAP
BOOL CChooseMachinePropPage::OnCommand(WPARAM wParam, LPARAM lParam)
{
switch(LOWORD(wParam))
{
case IDC_CHOOSER_RADIO_LOCAL_MACHINE:
OnRadioLocalMachine();
break;
case IDC_CHOOSER_RADIO_SPECIFIC_MACHINE:
OnRadioSpecificMachine();
break;
case IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES:
OnBrowse();
break;
default:
return FALSE;
break;
}
return TRUE;
}
#ifdef _DEBUG
static void AssertValidDialogTemplate(HWND hwnd)
{
ASSERT(::IsWindow(hwnd));
// Mandatory controls for a valid dialog template
static const UINT rgzidDialogControl[] =
{
IDC_CHOOSER_RADIO_LOCAL_MACHINE,
IDC_CHOOSER_RADIO_SPECIFIC_MACHINE,
IDC_CHOOSER_EDIT_MACHINE_NAME,
0
};
for (int i = 0; rgzidDialogControl[i] != 0; i++)
{
ASSERT(NULL != GetDlgItem(hwnd, rgzidDialogControl[i]) &&
"Control ID not found in dialog template.");
}
} // AssertValidDialogTemplate()
#else
#define AssertValidDialogTemplate(hwnd)
#endif // ~_DEBUG
/////////////////////////////////////////////////////////////////////
// Constructor
CChooseMachinePropPage::CChooseMachinePropPage(UINT uIDD) : CAutoDeletePropPage(uIDD)
{
m_fIsRadioLocalMachine = TRUE;
m_fEnableMachineBrowse = FALSE;
m_pstrMachineNameOut = NULL;
m_pstrMachineNameEffectiveOut = NULL;
m_pdwFlags = NULL;
}
/////////////////////////////////////////////////////////////////////
CChooseMachinePropPage::~CChooseMachinePropPage()
{
}
/////////////////////////////////////////////////////////////////////
// Load the initial state of CChooseMachinePropPage
void CChooseMachinePropPage::InitMachineName(LPCTSTR pszMachineName)
{
m_strMachineName = pszMachineName;
m_fIsRadioLocalMachine = m_strMachineName.IsEmpty();
}
/////////////////////////////////////////////////////////////////////
// SetOutputBuffers()
//
// - Set the pointer to the CString object to store the machine name.
// - Set the pointer to the boolean flag for command line override.
// - Set the pointer pointer to store the overriden machine name.
//
void CChooseMachinePropPage::SetOutputBuffers(
OUT CString * pstrMachineNamePersist, // Machine name the user typed. Empty string == local machine.
OUT CString * pstrMachineNameEffective,
OUT DWORD* pdwFlags)
{
Assert(pstrMachineNamePersist != NULL && "Invalid output buffer");
// point members at params
m_pstrMachineNameOut = pstrMachineNamePersist;
m_pstrMachineNameEffectiveOut = pstrMachineNameEffective;
m_pdwFlags = pdwFlags;
*m_pdwFlags = 0;
}
/////////////////////////////////////////////////////////////////////
// Replacement for DoDataExchange
BOOL CChooseMachinePropPage::UpdateData(BOOL fSuckFromDlg /*= TRUE*/)
{
if (fSuckFromDlg)
{
m_strMachineName.FromWindow(GetDlgItem(m_hWnd, IDC_CHOOSER_EDIT_MACHINE_NAME));
int iCheck = (int)SendMessage(GetDlgItem(m_hWnd, IDC_CHOOSER_MACHINE_OVERRIDE), BM_GETCHECK, 0, 0);
if (iCheck == BST_CHECKED)
*m_pdwFlags |= CCOMPDATAIMPL_FLAGS_ALLOW_MACHINE_OVERRIDE;
else
*m_pdwFlags &= ~CCOMPDATAIMPL_FLAGS_ALLOW_MACHINE_OVERRIDE;
}
else
{
m_strMachineName.ToWindow(GetDlgItem(m_hWnd, IDC_CHOOSER_EDIT_MACHINE_NAME));
int iCheck;
iCheck = (*m_pdwFlags & CCOMPDATAIMPL_FLAGS_ALLOW_MACHINE_OVERRIDE) ? BST_CHECKED : BST_UNCHECKED;
SendMessage(GetDlgItem(m_hWnd, IDC_CHOOSER_MACHINE_OVERRIDE), BM_SETCHECK, iCheck, 0);
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////
BOOL CChooseMachinePropPage::OnInitDialog()
{
AssertValidDialogTemplate(m_hWnd);
CAutoDeletePropPage::OnInitDialog();
InitChooserControls();
PropSheet_SetWizButtons(GetParent(), PSWIZB_FINISH);
return TRUE;
}
/////////////////////////////////////////////////////////////////////
BOOL CChooseMachinePropPage::OnWizardFinish()
{
if (!UpdateData()) // Do the data exchange to collect data
return FALSE; // don't destroy on error
if (m_fIsRadioLocalMachine)
m_strMachineName.Empty();
else
if (m_strMachineName.IsEmpty())
{
DisplayCertSrvErrorWithContext(m_hWnd, S_OK, IDS_MUST_CHOOSE_MACHINE);
return FALSE;
}
if (m_pstrMachineNameOut != NULL)
{
// Store the machine name into its output buffer
*m_pstrMachineNameOut = m_strMachineName;
if (m_pstrMachineNameEffectiveOut != NULL)
{
*m_pstrMachineNameEffectiveOut = m_strMachineName;
} // if
}
else
Assert(FALSE && "FYI: You have not specified any output buffer to store the machine name.");
return CAutoDeletePropPage::OnWizardFinish();
}
void CChooseMachinePropPage::InitChooserControls()
{
SendDlgItemMessage(IDC_CHOOSER_RADIO_LOCAL_MACHINE, BM_SETCHECK, m_fIsRadioLocalMachine);
SendDlgItemMessage(IDC_CHOOSER_RADIO_SPECIFIC_MACHINE, BM_SETCHECK, !m_fIsRadioLocalMachine);
EnableDlgItem(IDC_CHOOSER_EDIT_MACHINE_NAME, !m_fIsRadioLocalMachine);
PCCRYPTUI_CA_CONTEXT pCAContext = NULL;
DWORD dwCACount;
HRESULT hr = myGetConfigFromPicker(
m_hWnd,
NULL, //sub title
NULL, //title
NULL,
TRUE, //use ds
TRUE, // count only
&dwCACount,
&pCAContext);
if (S_OK != hr && HRESULT_FROM_WIN32(ERROR_CANCELLED) != hr)
{
_PrintError(hr, "myGetConfigFromPicker");
goto done;
}
m_fEnableMachineBrowse = (0 == dwCACount) ? FALSE : TRUE;
if (NULL != pCAContext)
{
CryptUIDlgFreeCAContext(pCAContext);
}
done:
EnableDlgItem(IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES,
!m_fIsRadioLocalMachine && m_fEnableMachineBrowse);
}
void CChooseMachinePropPage::OnRadioLocalMachine()
{
m_fIsRadioLocalMachine = TRUE;
EnableDlgItem(IDC_CHOOSER_EDIT_MACHINE_NAME, FALSE);
EnableDlgItem(IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES, FALSE);
}
void CChooseMachinePropPage::OnRadioSpecificMachine()
{
m_fIsRadioLocalMachine = FALSE;
EnableDlgItem(IDC_CHOOSER_EDIT_MACHINE_NAME, TRUE);
EnableDlgItem(IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES, m_fEnableMachineBrowse);
}
void CChooseMachinePropPage::OnBrowse()
{
HRESULT hr;
WCHAR *szConfig = NULL;
CWaitCursor cwait;
// UNDONE: expand config picker to non-published (DS chooser dlg)
hr = myGetConfigStringFromPicker(m_hWnd,
NULL, //use default prompt
NULL, //use default title
NULL, //use default shared folder
TRUE, //use DS
&szConfig);
if (hr == S_OK)
{
LPWSTR szWhack = wcschr(szConfig, L'\\');
if (szWhack != NULL)
szWhack[0] = L'\0';
m_strMachineName = szConfig;
LocalFree(szConfig);
}
// push result back to ui
UpdateData(FALSE);
}