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
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();
|
|
}
|
|
}
|
|
|