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.
 
 
 
 
 
 

459 lines
14 KiB

/*++
Copyright (C) Microsoft Corporation
Module Name:
genpage.cpp
Abstract:
This module implements CGeneralPage -- the snapin startup wizard page
Author:
William Hsieh (williamh) created
Revision History:
--*/
#include "devmgr.h"
#include "genpage.h"
UINT g_cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
const DWORD g_a102HelpIDs[]=
{
IDC_GENERAL_SELECT_TEXT, IDH_DISABLEHELP,
IDC_GENERAL_SELECTGROUP, IDH_DISABLEHELP,
IDC_GENERAL_OVERRIDE_MACHINENAME, idh_devmgr_manage_command_line, // Device Manager: "Allo&w the selected computer to be changed when launching from the command line. This only applies if you save the console." (Button)
IDC_GENERAL_LOCALMACHINE, idh_devmgr_manage_local, // Device Manager: "&Local computer: (the computer this console is running on)" (Button)
IDC_GENERAL_OTHERMACHINE, idh_devmgr_manage_remote, // Device Manager: "&Another computer:" (Button)
IDC_GENERAL_MACHINENAME, idh_devmgr_manage_remote_name, // Device Manager: "" (Edit)
IDC_GENERAL_BROWSE_MACHINENAMES, idh_devmgr_manage_remote_browse, // Device Manager: "B&rowse..." (Button)
0, 0
};
CGeneralPage::CGeneralPage() : CPropSheetPage(g_hInstance, IDD_GENERAL_PAGE)
{
m_lConsoleHandle = 0;
m_pstrMachineName = NULL;
m_pct = NULL;
m_MachineName[0] = _T('\0');
m_IsLocalMachine = TRUE;
m_ct = COOKIE_TYPE_SCOPEITEM_DEVMGR;
}
HPROPSHEETPAGE
CGeneralPage::Create(
LONG_PTR lConsoleHandle
)
{
m_lConsoleHandle = lConsoleHandle;
// override PROPSHEETPAGE structure here...
m_psp.lParam = (LPARAM)this;
return CPropSheetPage::CreatePage();
}
BOOL
CGeneralPage::OnInitDialog(
LPPROPSHEETPAGE ppsp
)
{
UNREFERENCED_PARAMETER(ppsp);
ASSERT(m_hDlg);
//
// Intiallly, enable the local machine and disable the
// "Another" machine.
//
::CheckDlgButton(m_hDlg, IDC_GENERAL_LOCALMACHINE, BST_CHECKED);
::CheckDlgButton(m_hDlg, IDC_GENERAL_OTHERMACHINE, BST_UNCHECKED);
::EnableWindow(GetControl(IDC_GENERAL_MACHINENAME), FALSE);
//
// Default is local machine. Since everything is valid at the beginning,
// we have to enable the finish button.
//
::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
::ShowWindow(GetControl(IDC_GENERAL_OVERRIDE_MACHINENAME), SW_HIDE);
::EnableWindow(GetControl(IDC_GENERAL_BROWSE_MACHINENAMES), FALSE);
return TRUE;
}
BOOL
CGeneralPage::OnReset(
void
)
{
m_MachineName[0] = _T('\0');
m_ct = COOKIE_TYPE_SCOPEITEM_DEVMGR;
SetWindowLongPtr(m_hDlg, DWLP_MSGRESULT, 0L);
return FALSE;
}
BOOL
CGeneralPage::OnCommand(
WPARAM wParam,
LPARAM lParam
)
{
switch (LOWORD(wParam)) {
case IDC_GENERAL_LOCALMACHINE:
if (BN_CLICKED == HIWORD(wParam)) {
::EnableWindow(GetControl(IDC_GENERAL_BROWSE_MACHINENAMES), FALSE);
::EnableWindow(GetControl(IDC_GENERAL_MACHINENAME), FALSE);
::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
m_IsLocalMachine = TRUE;
return TRUE;
}
break;
case IDC_GENERAL_OTHERMACHINE:
if (BN_CLICKED == HIWORD(wParam)) {
::EnableWindow(GetControl(IDC_GENERAL_BROWSE_MACHINENAMES), TRUE);
::EnableWindow(GetControl(IDC_GENERAL_MACHINENAME), TRUE);
if (GetWindowTextLength(GetControl(IDC_GENERAL_MACHINENAME))) {
::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
} else {
::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_DISABLEDFINISH);
}
m_IsLocalMachine = FALSE;
return TRUE;
}
break;
case IDC_GENERAL_MACHINENAME:
if (EN_CHANGE == HIWORD(wParam)) {
//
// Edit control change, see if there is any text in the
// control at all. It there is, enable the finish button,
// otherwise, disable it.
//
if (GetWindowTextLength((HWND)lParam)) {
//
// There is some text in the edit control enable the finish
// button
//
::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH);
} else {
//
// No text in the edit control disable the finish button
//
::SendMessage(::GetParent(m_hDlg), PSM_SETWIZBUTTONS, 0, PSWIZB_DISABLEDFINISH);
}
}
break;
case IDC_GENERAL_BROWSE_MACHINENAMES:
DoBrowse();
return TRUE;
break;
}
return FALSE;
}
BOOL
CGeneralPage::OnWizFinish(
void
)
{
BOOL bSuccess = TRUE;
//
// First figure out the machine name
//
m_MachineName[0] = _T('\0');
if (!m_IsLocalMachine)
{
GetWindowText(GetControl(IDC_GENERAL_MACHINENAME), m_MachineName,
ARRAYLEN(m_MachineName));
if (_T('\0') != m_MachineName[0])
{
if (_T('\\') != m_MachineName[0])
{
//
// Insert machine name signature to the fron of the name
//
int len = lstrlen(m_MachineName);
if (len + 2 < ARRAYLEN(m_MachineName))
{
//
// Move the existing string so that we can insert
// the signature in the first two locations.
// the move includes the terminated null char.
// Note: when moving characters two places we need to make
// sure we don't blow out the buffer.
//
for (int i = len + 2; i >= 2; i--) {
m_MachineName[i] = m_MachineName[i - 2];
}
m_MachineName[0] = _T('\\');
m_MachineName[1] = _T('\\');
}
}
//
// Now verify the machine name. If the machine name is invalid
// or can be reached, use the local computer;
//
if (!VerifyMachineName(m_MachineName))
{
String strWarningFormat;
String strWarningMessage;
LPVOID lpLastError = NULL;
bSuccess = FALSE;
if (strWarningFormat.LoadString(g_hInstance, IDS_INVALID_COMPUTER_NAME) &&
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
HRESULT_FROM_SETUPAPI(GetLastError()),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpLastError,
0,
NULL)) {
strWarningMessage.Format((LPTSTR)strWarningFormat,
m_MachineName,
lpLastError);
MessageBox(m_hDlg,
(LPTSTR)strWarningMessage,
(LPCTSTR)g_strDevMgr,
MB_ICONERROR | MB_OK
);
}
if (lpLastError) {
LocalFree(lpLastError);
}
}
}
}
try
{
//
// Only tell the console, or the caller, about the new machine name,
// if we were able to successfully get one, it was valid, and we
// have access to it.
//
if (bSuccess) {
if (m_lConsoleHandle)
{
//
// A console handle is created for the property sheet,
// use the handle to notify the snapin about the new
// startup information.
//
BufferPtr<BYTE> Buffer(sizeof(PROPERTY_CHANGE_INFO) + sizeof(STARTUP_INFODATA));
PPROPERTY_CHANGE_INFO pPCI = (PPROPERTY_CHANGE_INFO)(BYTE*)Buffer;
PSTARTUP_INFODATA pSI = (PSTARTUP_INFODATA)&pPCI->InfoData;
if ((_T('\0') != m_MachineName[0]) &&
FAILED(StringCchCopy(pSI->MachineName, ARRAYLEN(pSI->MachineName), m_MachineName))) {
//
// This shouldn't happen, since everywhere else in this code
// machine names can't be larger than MAX_PATH, but we'll
// assert, and handle this case, just in case.
//
ASSERT(lstrlen(m_MachineName) < ARRAYLEN(pSI->MachineName));
bSuccess = FALSE;
}
if (bSuccess) {
pSI->ct = m_ct;
pSI->Size = sizeof(STARTUP_INFODATA);
pPCI->Type = PCT_STARTUP_INFODATA;
//
// Notify IComponentData about what we have here.
//
MMCPropertyChangeNotify(m_lConsoleHandle, reinterpret_cast<LONG_PTR>(&pPCI));
}
}
else if (m_pstrMachineName && m_pct)
{
//
// No console is provided for the property sheet.
// send the new startup info in the given buffer if it is
// provided.
//
*m_pstrMachineName = m_MachineName;
*m_pct = m_ct;
}
else
{
//
// Nobody is listening to what we have to say. Something must be
// wrong!
//
ASSERT(FALSE);
}
}
}
catch (CMemoryException* e)
{
e->Delete();
MsgBoxParam(m_hDlg, 0, 0, 0);
}
SetWindowLongPtr(m_hDlg, DWLP_MSGRESULT, bSuccess ? 0L : -1L);
return TRUE;
}
BOOL
CGeneralPage::OnHelp(
LPHELPINFO pHelpInfo
)
{
WinHelp((HWND)pHelpInfo->hItemHandle, DEVMGR_HELP_FILE_NAME, HELP_WM_HELP,
(ULONG_PTR)g_a102HelpIDs);
return FALSE;
}
BOOL
CGeneralPage::OnContextMenu(
HWND hWnd,
WORD xPos,
WORD yPos
)
{
UNREFERENCED_PARAMETER(xPos);
UNREFERENCED_PARAMETER(yPos);
WinHelp(hWnd, DEVMGR_HELP_FILE_NAME, HELP_CONTEXTMENU,
(ULONG_PTR)g_a102HelpIDs);
return FALSE;
}
void
CGeneralPage::DoBrowse(
void
)
{
HRESULT hr;
static const int SCOPE_INIT_COUNT = 1;
DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
ZeroMemory(aScopeInit, sizeof(DSOP_SCOPE_INIT_INFO) * SCOPE_INIT_COUNT);
//
// Since we just want computer objects from every scope, combine them
// all in a single scope initializer.
//
aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
aScopeInit[0].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN
| DSOP_SCOPE_TYPE_GLOBAL_CATALOG
| DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
| DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
| DSOP_SCOPE_TYPE_WORKGROUP
| DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
| DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
aScopeInit[0].FilterFlags.Uplevel.flBothModes =
DSOP_FILTER_COMPUTERS;
aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
//
// Put the scope init array into the object picker init array
//
DSOP_INIT_INFO InitInfo;
ZeroMemory(&InitInfo, sizeof(InitInfo));
InitInfo.cbSize = sizeof(InitInfo);
InitInfo.pwzTargetComputer = NULL; // NULL == local machine
InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
InitInfo.aDsScopeInfos = aScopeInit;
//
// Note object picker makes its own copy of InitInfo. Also note
// that Initialize may be called multiple times, last call wins.
//
IDsObjectPicker *pDsObjectPicker = NULL;
IDataObject *pdo = NULL;
bool fGotStgMedium = false;
STGMEDIUM stgmedium =
{
TYMED_HGLOBAL,
NULL,
NULL
};
hr = CoCreateInstance(CLSID_DsObjectPicker,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDsObjectPicker,
(void **) &pDsObjectPicker);
hr = pDsObjectPicker->Initialize(&InitInfo);
hr = pDsObjectPicker->InvokeDialog(m_hDlg, &pdo);
if (hr != S_FALSE)
{
FORMATETC formatetc =
{
(CLIPFORMAT)g_cfDsObjectPicker,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL
};
hr = pdo->GetData(&formatetc, &stgmedium);
fGotStgMedium = true;
PDS_SELECTION_LIST pDsSelList =
(PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
if (pDsSelList)
{
ASSERT(pDsSelList->cItems == 1);
//
// Put the machine name in the edit control
//
::SetDlgItemText(m_hDlg, IDC_GENERAL_MACHINENAME, pDsSelList->aDsSelection[0].pwzName);
GlobalUnlock(stgmedium.hGlobal);
}
}
if (fGotStgMedium)
{
ReleaseStgMedium(&stgmedium);
}
if (pDsObjectPicker)
{
pDsObjectPicker->Release();
}
}