windows-nt/Source/XPSP1/NT/net/config/shell/netsetup/wfinish.cpp
2020-09-26 16:20:57 +08:00

1140 lines
34 KiB
C++

#include "pch.h"
#pragma hdrstop
#include <shlobj.h>
#include "ncatlui.h"
#include "ncnetcon.h"
#include "ncreg.h"
#include "ncui.h"
#include "resource.h"
#include "shortcut.h"
#include "wizard.h"
#include "ncstl.h"
#include "foldinc.h"
static const WCHAR c_szNetConUserPath[] = NETCON_HKEYCURRENTUSERPATH;
static const WCHAR c_szFinishShortCut[] = NETCON_DESKTOPSHORTCUT;
static const WCHAR c_szNewRasConn[] = L"NewRasCon";
static const WCHAR c_szAdvancedPath[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced";
static const WCHAR c_szCascadeNetworkConnections[] = L"CascadeNetworkConnections";
static const WCHAR c_szYES[] = L"YES";
static const WCHAR c_szShellMenu[] = L"ShellMenu";
struct HFONTS
{
HFONT hFontBold;
HFONT hFontBoldLarge;
HFONT hMarlettFont;
};
//
// Function: HrFinishPageSaveConnection
//
// Purpose: Take the name from the dialog and call the provider to
// create the new connection
//
// Parameters: hwndDlg [IN] - Handle to the Finish dialog
// pWizard [IN] - Ptr to a wizard instance
// ppConn [OUT] - Ptr to the newly created connection
//
// Returns: HRESULT
//
HRESULT HrFinishPageSaveConnection(HWND hwndDlg, CWizard * pWizard,
INetConnection ** ppConn,
BOOL * pfRetry)
{
TraceFileFunc(ttidGuiModeSetup);
HRESULT hr;
HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
INetConnection * pConn = NULL;
Assert(pfRetry);
*pfRetry = TRUE;
CWizProvider * pWizProvider = pWizard->GetCurrentProvider();
Assert(NULL != pWizProvider);
Assert(NULL != pWizProvider->PWizardUi());
if (IsPostInstall(pWizard))
{
// Set the connections name from the edit control data
//
Assert(0 < GetWindowTextLength(hwndEdit));
Assert(NETCON_MAX_NAME_LEN >= GetWindowTextLength(hwndEdit));
WCHAR szName[NETCON_MAX_NAME_LEN + 10];
*ppConn = NULL;
GetWindowText(hwndEdit, szName, NETCON_MAX_NAME_LEN);
szName[NETCON_MAX_NAME_LEN] = 0;
hr = (pWizProvider->PWizardUi())->SetConnectionName(szName);
}
else
{
hr = S_OK;
}
BOOL fFirewallErrorDlg = FALSE;
if (SUCCEEDED(hr))
{
// Create the connection if it's not already set
//
hr = (pWizProvider->PWizardUi())->GetNewConnection(&pConn);
TraceHr(ttidWizard, FAL, hr, FALSE, "FinishPageSaveConnection - Failed to GetNewConnection");
if (SUCCEEDED(hr))
{
// Stash the new connection away
//
*ppConn = pConn;
}
else
{
// Don't let user retry as RAS will AV (#333893)
*pfRetry = FALSE;
}
DWORD dwWizFlags;
NETCON_MEDIATYPE MediaType;
hr = (pWizProvider->PWizardUi())->GetNewConnectionInfo(&dwWizFlags, &MediaType);
if (SUCCEEDED(hr))
{
if (dwWizFlags & NCWF_FIREWALLED)
{
CComPtr<IHNetCfgMgr> pHNetCfgMgr;
CComPtr<IHNetConnection> pHNConn;
CComPtr<IHNetFirewalledConnection> pFWConn;
hr = CoCreateInstance(
CLSID_HNetCfgMgr,
NULL,
CLSCTX_ALL,
IID_IHNetCfgMgr,
reinterpret_cast<void**>(&pHNetCfgMgr)
);
if (SUCCEEDED(hr))
{
hr = pHNetCfgMgr->GetIHNetConnectionForINetConnection(pConn, &pHNConn);
if (SUCCEEDED(hr))
{
hr = pHNConn->Firewall(&pFWConn);
}
}
fFirewallErrorDlg = TRUE;
}
}
}
if (FAILED(hr) && IsPostInstall(pWizard))
{
if (fFirewallErrorDlg)
{
LPWSTR szFirewallError;
LPWSTR pszError;
if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
(PWSTR)&pszError, 0, NULL))
{
if (DwFormatStringWithLocalAlloc(SzLoadIds(IDS_E_FIREWALL_FAILED), &szFirewallError, pszError))
{
if (MessageBox(GetParent(hwndDlg), szFirewallError, SzLoadIds(IDS_SETUP_CAPTION), MB_OK | MB_ICONEXCLAMATION))
{
hr = S_OK;
}
LocalFree(szFirewallError);
}
LocalFree(pszError);
}
}
if (FAILED(hr))
{
INT idsErr = IDS_E_CREATECONNECTION;
if (HRESULT_FROM_WIN32(ERROR_DUP_NAME) == hr)
idsErr = IDS_E_DUP_NAME;
else
if (HRESULT_FROM_WIN32(ERROR_INVALID_NAME) == hr)
idsErr = IDS_E_INVALID_NAME;
// Tell the user what went wrong
//
NcMsgBox(GetParent(hwndDlg), IDS_SETUP_CAPTION, idsErr, MB_OK);
}
return hr;
}
return hr;
}
BOOL ConnListDuplicateNameCheck(IN CIntelliName *pIntelliName, IN LPCTSTR szName, NETCON_MEDIATYPE *pncm, NETCON_SUBMEDIATYPE *pncms)
{
HRESULT hr = S_OK;
BOOL fDupFound = FALSE;
Assert(pncm);
Assert(pncms);
ConnListEntry cleDup;
hr = g_ccl.HrFindConnectionByName(szName, cleDup);
if (S_OK == hr)
{
fDupFound = TRUE;
*pncm = cleDup.ccfe.GetNetConMediaType();
NETCON_MEDIATYPE ncmPseudo;
hr = pIntelliName->HrGetPseudoMediaTypes(cleDup.ccfe.GetGuidID(), &ncmPseudo, pncms);
if (FAILED(hr))
{
AssertSz(FALSE, "Could not obtain Pseudo Media type");
fDupFound = FALSE;
if (*pncm == NCM_LAN)
{
Assert(ncmPseudo == NCM_LAN);
}
}
}
else
{
fDupFound = FALSE;
}
return fDupFound;
}
// ISSUE: guidAdapter can be GUID_NULL
VOID GenerateUniqueConnectionName(REFGUID guidAdapter, tstring * pstr, CWizProvider * pWizProvider)
{
TraceFileFunc(ttidGuiModeSetup);
HRESULT hr = S_OK;
Assert(pstr);
Assert(pWizProvider);
CIntelliName IntelliName(_Module.GetResourceInstance(), ConnListDuplicateNameCheck);
NETCON_MEDIATYPE ncm;
DWORD dwFlags;
hr = (pWizProvider->PWizardUi())->GetNewConnectionInfo(&dwFlags, &ncm);
Assert(SUCCEEDED(hr));
if (FAILED(hr))
{
return;
}
tstring szConnNameHint;
PWSTR pszSuggested;
hr = (pWizProvider->PWizardUi())->GetSuggestedConnectionName(&pszSuggested);
if (SUCCEEDED(hr))
{
szConnNameHint = pszSuggested;
CoTaskMemFree(pszSuggested);
}
DWORD dwNCCF = 0;
if (dwFlags & NCWF_INCOMINGCONNECTION)
{
dwNCCF |= NCCF_INCOMING_ONLY;
}
DWORD dwTries = 0;
do
{
LPWSTR szName;
if (szConnNameHint.empty())
{
hr = IntelliName.GenerateName(guidAdapter, ncm, dwNCCF, NULL, &szName);
}
else
{
hr = IntelliName.GenerateName(guidAdapter, ncm, dwNCCF, szConnNameHint.c_str(), &szName);
}
if (SUCCEEDED(hr))
{
hr = (pWizProvider->PWizardUi())->SetConnectionName(szName);
*pstr = szName;
CoTaskMemFree(szName);
}
AssertSz(dwTries < 64, "Something is wrong. GenerateName should have by now generated a unique name!");
dwTries++;
}
while ( (dwTries < 64) && (HRESULT_FROM_WIN32(ERROR_DUP_NAME) == hr) );
// This can only happens if somebody else created a duplicated name at this EXACT instance. So try again a few times.
}
VOID FinishGenerateUniqueNameInUI(HWND hwndDlg, CWizard * pWizard)
{
TraceFileFunc(ttidGuiModeSetup);
tstring str;
HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
WCHAR szName[NETCON_MAX_NAME_LEN + 10] = {0};
CWizProvider * pWizProvider = pWizard->GetCurrentProvider();
Assert(NULL != pWizProvider);
Assert(NULL != pWizProvider->PWizardUi());
// Populate the Edit control if it's empty
DWORD Flags = 0;
NETCON_MEDIATYPE MediaType;
HRESULT hr = (pWizProvider->PWizardUi())->GetNewConnectionInfo(&Flags, &MediaType);
if (SUCCEEDED(hr) & (Flags & NCWF_RENAME_DISABLE))
{
LPWSTR szSuggestedName;
hr = (pWizProvider->PWizardUi())->GetSuggestedConnectionName(&szSuggestedName);
if (SUCCEEDED(hr))
{
str = szSuggestedName;
CoTaskMemFree(szSuggestedName);
}
else
{
GenerateUniqueConnectionName(GUID_NULL, &str, pWizProvider);
}
}
else
{
GenerateUniqueConnectionName(GUID_NULL, &str, pWizProvider);
}
// reset provider changed flag
pWizard->ClearProviderChanged();
SetWindowText(hwndEdit, str.c_str());
}
BOOL FCheckAllUsers(NETCON_PROPERTIES* pConnProps)
{
TraceFileFunc(ttidGuiModeSetup);
Assert(NULL != pConnProps);
if ((NCM_LAN != pConnProps->MediaType) &&
(NCCF_ALL_USERS & pConnProps->dwCharacter))
{
return TRUE;
}
return FALSE;
}
//
// Function: OnFinishPageNext
//
// Purpose: Handle the pressing of the Next button
//
// Parameters: hwndDlg [IN] - Handle to the finish dialog
//
// Returns: BOOL, TRUE
//
BOOL OnFinishPageNext(HWND hwndDlg)
{
TraceFileFunc(ttidGuiModeSetup);
HCURSOR hOldCursor = NULL;
INetConnection * pConn = NULL;
// Retrieve the CWizard instance from the dialog
CWizard * pWizard =
reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
Assert(NULL != pWizard);
HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
HRESULT hr;
WCHAR szConnName[NETCON_MAX_NAME_LEN + 1];
int cchText = GetWindowText(hwndEdit, reinterpret_cast<PWSTR>(&szConnName),
NETCON_MAX_NAME_LEN);
if (IsPostInstall(pWizard))
{
if (!FIsValidConnectionName(szConnName))
{
SendMessage(hwndEdit, EM_SETSEL, 0, -1);
SetFocus(hwndEdit);
MessageBox(GetParent(hwndDlg), SzLoadIds(IDS_E_INVALID_NAME),
SzLoadIds(IDS_SETUP_CAPTION), MB_OK | MB_ICONSTOP);
::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
return TRUE;
}
}
hOldCursor = BeginWaitCursor();
BOOL fRetry;
hr = HrFinishPageSaveConnection(hwndDlg, pWizard, &pConn, &fRetry);
if (IsPostInstall(pWizard) && FAILED(hr))
{
EndWaitCursor(hOldCursor);
if (fRetry)
{
// Don't leave the page
::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
}
else
{
// Jump to the Exit page
PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0,
(LPARAM)pWizard->GetPageHandle(IDD_Exit));
}
EndWaitCursor(hOldCursor);
return TRUE;
}
// If it's post install cache the connection
if (IsPostInstall(pWizard))
{
DWORD dwDisposition;
HKEY hkey = NULL;
hr = HrRegCreateKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
&hkey, &dwDisposition);
if (SUCCEEDED(hr))
{
DWORD dw;
// Have we ever created a connection with this wizard before
//
hr = HrRegQueryDword (hkey, c_szNewRasConn, &dw);
if (FAILED(hr))
{
HKEY hkeyAdvanced = NULL;
// First time, retain the fact we created a RAS connection
//
(VOID)HrRegSetDword (hkey, c_szNewRasConn, 1);
// Update the Start Menu to cascade the folder auto-magically
//
hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szAdvancedPath,
KEY_WRITE, &hkeyAdvanced);
if (SUCCEEDED(hr))
{
(VOID)HrRegSetSz(hkeyAdvanced,
c_szCascadeNetworkConnections,
c_szYES);
RegCloseKey(hkeyAdvanced);
ULONG_PTR lres = 0;
LRESULT lr = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL,
reinterpret_cast<LPARAM>(c_szShellMenu), SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG,
30 * 1000, &lres);
if (lr == 0)
{
if (GetLastError() == 0)
{
TraceError("SendMessageTimeout timed out sending WM_SETTINGCHANGE broadcast message", E_FAIL);
}
else
{
TraceError("SendMessageTimeout failed", HRESULT_FROM_WIN32(GetLastError()));
}
}
}
hr = S_OK;
}
}
// If the Shortcut check box is visible we might need to create a shortcut
//
if (IsWindowVisible(GetDlgItem(hwndDlg, CHK_CREATE_SHORTCUT)))
{
// Retain the shortcut "check" state for future invocations
//
BOOL fCreateShortcut = (BST_CHECKED ==
IsDlgButtonChecked(hwndDlg, CHK_CREATE_SHORTCUT));
if (hkey)
{
(VOID)HrRegSetDword (hkey, c_szFinishShortCut,
(fCreateShortcut) ? 1 : 0);
}
// If the shortcut box is checked, try to create a shortcut
//
if (fCreateShortcut && (NULL != pConn))
{
NETCON_PROPERTIES* pConnProps = NULL;
hr = pConn->GetProperties(&pConnProps);
if (SUCCEEDED(hr))
{
BOOL fAllUsers = FCheckAllUsers(pConnProps);
(VOID)HrCreateStartMenuShortCut(GetParent(hwndDlg),
fAllUsers,
pConnProps->pszwName,
pConn);
FreeNetconProperties(pConnProps);
}
}
}
RegCloseKey(hkey);
// Save the Connection so we can hand it back to the connections folder
pWizard->CacheConnection(pConn);
pConn = NULL;
}
// Release the object since we don't need it any more
ReleaseObj(pConn);
// Whack the text so we requery it the next time around
SetWindowText(hwndEdit, c_szEmpty);
// On PostInstall there is no need to request the "Next" adapter as
// the wizard is a one time through entity
if (IsPostInstall(pWizard))
{
if (pWizard->FProcessLanPages())
{
(VOID)HrCommitINetCfgChanges(GetParent(hwndDlg), pWizard);
}
// Jump to the Exit page
PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0,
(LPARAM)pWizard->GetPageHandle(IDD_Exit));
EndWaitCursor(hOldCursor);
return TRUE;
}
else
{
// Do one of the following (as appropriate):
// Process the next adapter if it exists
// Jump to the join page (!IsPostInstall)
// Jump to the exit page
//
EndWaitCursor(hOldCursor);
return OnProcessNextAdapterPageNext(hwndDlg, FALSE);
}
}
//
// Function: OnFinishPageBack
//
// Purpose: Handle the BACK notification on the finish page
//
// Parameters: hwndDlg [IN] - Handle to the finish dialog
//
// Returns: BOOL, TRUE
//
BOOL OnFinishPageBack(HWND hwndDlg)
{
TraceFileFunc(ttidGuiModeSetup);
UINT nCnt = 0;
HPROPSHEETPAGE hPage = NULL;
// Retrieve the CWizard instance from the dialog
CWizard * pWizard =
reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
Assert(NULL != pWizard);
if (IsWindowVisible(GetDlgItem(hwndDlg, CHK_CREATE_SHORTCUT)))
{
// Retain the shortcut "check" state
DWORD dw;
HKEY hKey = NULL;
BOOL fCreateShortcut = IsDlgButtonChecked(hwndDlg, CHK_CREATE_SHORTCUT);
if (fCreateShortcut == BST_CHECKED)
{
dw = 1;
}
else
{
dw = 0;
}
HRESULT hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
KEY_WRITE, &hKey);
if (SUCCEEDED(hr))
{
HrRegSetValueEx(hKey, c_szFinishShortCut, REG_DWORD, (BYTE *)&dw, sizeof(DWORD));
RegCloseKey(hKey);
}
}
HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
SetWindowText(hwndEdit, _T(""));
// Goto the guard page of the current provider
AppendGuardPage(pWizard, pWizard->GetCurrentProvider(),
&hPage, &nCnt);
Assert(nCnt);
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
// Goto to the guard page of the current provider
PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0,
(LPARAM)(HPROPSHEETPAGE)hPage);
::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
return TRUE;
}
VOID FinishUpdateButtons(HWND hwndDlg)
{
TraceFileFunc(ttidGuiModeSetup);
// Retrieve the CWizard instance from the dialog
CWizard * pWizard =
reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
Assert(NULL != pWizard);
// Only play with the UI when the page is shown postinstall
if (IsPostInstall(pWizard))
{
LPARAM lFlags = PSWIZB_BACK | PSWIZB_FINISH;
PropSheet_SetWizButtons(GetParent(hwndDlg), lFlags);
}
}
//
// Function: OnFinishPageActivate
//
// Purpose: Handle the page activation
//
// Parameters: hwndDlg [IN] - Handle to the finish dialog
//
// Returns: BOOL, TRUE
//
BOOL OnFinishPageActivate(HWND hwndDlg)
{
TraceFileFunc(ttidGuiModeSetup);
HRESULT hr;
HWND hwndEdit = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
HWND hwndChkShortCut = GetDlgItem(hwndDlg, CHK_CREATE_SHORTCUT);
CWizard* pWizard =
reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
Assert(NULL != pWizard);
TraceTag(ttidWizard, "Entering finish page...");
::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0);
if (IsPostInstall(pWizard))
{
FinishGenerateUniqueNameInUI(hwndDlg, pWizard);
FinishUpdateButtons(hwndDlg);
const DWORD MAXDLG_FINISH_CONTROLS = 4;
UINT uiCtls[MAXDLG_FINISH_CONTROLS];
uiCtls[0] = EDT_FINISH_TYPE1;
uiCtls[1] = EDT_FINISH_TYPE2;
uiCtls[2] = EDT_FINISH_TYPE3;
uiCtls[3] = EDT_FINISH_TYPE4;
UINT uiLbls[MAXDLG_FINISH_CONTROLS];
uiLbls[0] = IDC_FINISH_CHK1;
uiLbls[1] = IDC_FINISH_CHK2;
uiLbls[2] = IDC_FINISH_CHK3;
uiLbls[3] = IDC_FINISH_CHK4;
DWORD dwCurrentControl = 0;
CWizProvider * pProv = pWizard->GetCurrentProvider();
if (NULL != pProv)
{
DWORD dwWizFlags;
BOOL fAllowShortCut = FALSE;
BOOL fCheckShortCut = FALSE;
NETCON_MEDIATYPE MediaType;
Assert(NULL != pProv->PWizardUi());
hr = (pProv->PWizardUi())->GetNewConnectionInfo(&dwWizFlags, &MediaType);
if (SUCCEEDED(hr))
{
fAllowShortCut = !!(dwWizFlags & NCWF_SHORTCUT_ENABLE);
if (dwWizFlags & NCWF_DEFAULT)
{
SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_DEFAULT));
}
if (dwWizFlags & NCWF_FIREWALLED)
{
SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_FIREWALLED));
}
if (dwWizFlags & NCWF_ALLUSER_CONNECTION)
{
SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_ALLUSER_CONNECTION));
}
if (dwWizFlags & NCWF_GLOBAL_CREDENTIALS)
{
SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_GLOBAL_CREDENTIALS));
}
// if (dwWizFlags & NCWF_SHARED)
// {
// SetDlgItemText(hwndDlg, uiCtls[dwCurrentControl++], SzLoadIds(IDS_NCWF_SHARED));
// }
}
Assert(dwCurrentControl <= MAXDLG_FINISH_CONTROLS);
for (DWORD x = 0; x < MAXDLG_FINISH_CONTROLS; x++)
{
HWND hwndCtrl = GetDlgItem(hwndDlg, uiCtls[x]);
if (hwndCtrl)
{
if (x < dwCurrentControl)
{
EnableWindow(hwndCtrl, TRUE);
ShowWindow(hwndCtrl, SW_SHOW);
}
else
{
EnableWindow(hwndCtrl, FALSE);
ShowWindow(hwndCtrl, SW_HIDE);
}
}
else
{
AssertSz(FALSE, "Could not load type edit control");
}
hwndCtrl = GetDlgItem(hwndDlg, uiLbls[x]);
if (hwndCtrl)
{
if (x < dwCurrentControl)
{
EnableWindow(hwndCtrl, TRUE);
ShowWindow(hwndCtrl, SW_SHOW);
}
else
{
EnableWindow(hwndCtrl, FALSE);
ShowWindow(hwndCtrl, SW_HIDE);
}
}
else
{
AssertSz(FALSE, "Could not load bullet control");
}
}
// Disable the connection name edit control if the connection type
// does not support renaming
ShowWindow(hwndChkShortCut, fAllowShortCut ? SW_SHOW : SW_HIDE);
EnableWindow(hwndChkShortCut, fAllowShortCut);
// Check the registry for the last setting of the checkbox state
// if shortcuts are allowed
//
if (fAllowShortCut)
{
// Default Shortcut state (if allowed) is on.
//
fCheckShortCut = FALSE;
DWORD dw;
HKEY hkey = NULL;
hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
KEY_READ, &hkey);
if (SUCCEEDED(hr))
{
hr = HrRegQueryDword (hkey, c_szFinishShortCut, &dw);
if (SUCCEEDED(hr))
{
fCheckShortCut = (1==dw);
}
RegCloseKey(hkey);
}
}
CheckDlgButton(hwndDlg, CHK_CREATE_SHORTCUT, fCheckShortCut);
}
}
else
{
Assert(pWizard->FProcessLanPages());
OnFinishPageNext(hwndDlg);
// Temporarily briefly accept focus
::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0);
}
return TRUE;
}
// ***************************************************************************
//
// Function: OnFinishInitDialog
//
// Purpose: Handle WM_INITDIALOG message
//
// Parameters: hwndDlg [IN] - Handle to the finish dialog
// lParam [IN] - LPARAM value from the WM_INITDIALOG message
//
// Returns: FALSE - Accept default control activation
//
BOOL OnFinishInitDialog(HWND hwndDlg, LPARAM lParam)
{
TraceFileFunc(ttidGuiModeSetup);
// Initialize our pointers to property sheet info.
PROPSHEETPAGE* psp = (PROPSHEETPAGE*)lParam;
Assert(psp->lParam);
::SetWindowLongPtr(hwndDlg, DWLP_USER, psp->lParam);
CWizard * pWizard = reinterpret_cast<CWizard *>(psp->lParam);
Assert(NULL != pWizard);
HFONTS *phFonts = NULL;
if (IsPostInstall(pWizard))
{
pWizard->SetPageData(IDD_Finish, (LPARAM)NULL);
// Set up the Welcome font
HFONT hBoldFontLarge = NULL;
SetupFonts(hwndDlg, &hBoldFontLarge, TRUE);
if (NULL != hBoldFontLarge)
{
phFonts = new HFONTS;
ZeroMemory(phFonts, sizeof(HFONTS));
phFonts->hFontBoldLarge = hBoldFontLarge;
pWizard->SetPageData(IDD_Finish, (LPARAM)phFonts);
HWND hwndCtl = GetDlgItem(hwndDlg, IDC_WELCOME_CAPTION);
if (hwndCtl)
{
if (pWizard->FProcessLanPages())
SetWindowText(hwndCtl, SzLoadIds(IDS_LAN_FINISH_CAPTION));
SetWindowFont(hwndCtl, hBoldFontLarge, TRUE);
}
}
// Get the bold font for the radio buttons
HFONT hBoldFont = NULL;
SetupFonts(hwndDlg, &hBoldFont, FALSE);
if (NULL != hBoldFont)
{
if (!phFonts)
{
phFonts = new HFONTS;
ZeroMemory(phFonts, sizeof(HFONTS));
pWizard->SetPageData(IDD_Finish, (LPARAM)hBoldFont);
}
phFonts->hFontBold = hBoldFont;
HWND hwndCtl = GetDlgItem(hwndDlg, EDT_FINISH_NAME);
if (hwndCtl)
{
SetWindowFont(hwndCtl, hBoldFont, TRUE);
}
}
// Create the Marlett font. In the Marlett font the "i" is a bullet.
// Code borrowed from Add Hardware Wizard.
HFONT hFontCurrent;
HFONT hFontCreated;
LOGFONT LogFont;
hFontCurrent = (HFONT)SendMessage(GetDlgItem(hwndDlg, IDC_FINISH_CHK1), WM_GETFONT, 0, 0);
GetObject(hFontCurrent, sizeof(LogFont), &LogFont);
LogFont.lfCharSet = SYMBOL_CHARSET;
LogFont.lfPitchAndFamily = FF_DECORATIVE | DEFAULT_PITCH;
lstrcpy(LogFont.lfFaceName, L"Marlett");
hFontCreated = CreateFontIndirect(&LogFont);
if (hFontCreated)
{
if (phFonts)
{
phFonts->hMarlettFont = hFontCreated;
}
//
// An "i" in the marlett font is a small bullet.
//
SetWindowText(GetDlgItem(hwndDlg, IDC_FINISH_CHK1), L"i");
SetWindowFont(GetDlgItem(hwndDlg, IDC_FINISH_CHK1), hFontCreated, TRUE);
SetWindowText(GetDlgItem(hwndDlg, IDC_FINISH_CHK2), L"i");
SetWindowFont(GetDlgItem(hwndDlg, IDC_FINISH_CHK2), hFontCreated, TRUE);
SetWindowText(GetDlgItem(hwndDlg, IDC_FINISH_CHK3), L"i");
SetWindowFont(GetDlgItem(hwndDlg, IDC_FINISH_CHK3), hFontCreated, TRUE);
SetWindowText(GetDlgItem(hwndDlg, IDC_FINISH_CHK4), L"i");
SetWindowFont(GetDlgItem(hwndDlg, IDC_FINISH_CHK4), hFontCreated, TRUE);
}
HKEY hKey;
HRESULT hrT = HrRegCreateKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
&hKey, NULL);
if (SUCCEEDED(hrT))
{
RegCloseKey(hKey);
}
}
// Clear the shortcut flag in the registry
HKEY hKey;
DWORD dw = 0;
HRESULT hr = HrRegOpenKeyEx(HKEY_CURRENT_USER, c_szNetConUserPath,
KEY_WRITE, &hKey);
if (SUCCEEDED(hr))
{
HrRegSetValueEx(hKey, c_szFinishShortCut, REG_DWORD, (BYTE *)&dw, sizeof(DWORD));
RegCloseKey(hKey);
}
return FALSE; // Accept default control focus
}
//
// Function: dlgprocFinish
//
// Purpose: Dialog Procedure for the Finish wizard page
//
// Parameters: standard dlgproc parameters
//
// Returns: INT_PTR
//
INT_PTR CALLBACK dlgprocFinish( HWND hwndDlg, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{
TraceFileFunc(ttidGuiModeSetup);
BOOL frt = FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
frt = OnFinishInitDialog(hwndDlg, lParam);
break;
case WM_COMMAND:
if ((EN_CHANGE == HIWORD(wParam)) &&
(GetDlgItem(hwndDlg, EDT_FINISH_NAME) == (HWND)lParam))
{
FinishUpdateButtons(hwndDlg);
}
break;
case WM_NOTIFY:
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch (pnmh->code)
{
// propsheet notification
case PSN_HELP:
break;
case PSN_SETACTIVE:
frt = OnFinishPageActivate(hwndDlg);
break;
case PSN_APPLY:
break;
case PSN_KILLACTIVE:
break;
case PSN_RESET:
break;
case PSN_WIZBACK:
frt = OnFinishPageBack(hwndDlg);
break;
case PSN_WIZFINISH:
{
// This page isn't displayed during setup.
// Finish Processing in setup is done in wupgrade.cpp
CWizard * pWizard =
reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg,
DWLP_USER));
Assert(NULL != pWizard);
if (IsPostInstall(pWizard))
{
frt = OnFinishPageNext(hwndDlg);
}
}
break;
case PSN_WIZNEXT:
frt = OnFinishPageNext(hwndDlg);
break;
default:
break;
}
}
break;
default:
break;
}
return( frt );
}
//
// Function: FinishPageCleanup
//
// Purpose: As a callback function to allow any page allocated memory
// to be cleaned up, after the page will no longer be accessed.
//
// Parameters: pWizard [IN] - The wizard against which the page called
// register page
// lParam [IN] - The lParam supplied in the RegisterPage call
//
// Returns: nothing
//
VOID FinishPageCleanup(CWizard *pWizard, LPARAM lParam)
{
TraceFileFunc(ttidGuiModeSetup);
if (IsPostInstall(pWizard))
{
HFONTS *phFonts = (HFONTS *)pWizard->GetPageData(IDD_Finish);
if (NULL != phFonts)
{
if (phFonts->hFontBold)
{
DeleteObject(phFonts->hFontBold);
}
if (phFonts->hFontBoldLarge)
{
DeleteObject(phFonts->hFontBoldLarge);
}
if (phFonts->hMarlettFont)
{
DeleteObject(phFonts->hMarlettFont);
}
delete phFonts;
}
}
}
//
// Function: CreateFinishPage
//
// Purpose: To determine if the Finish page needs to be shown, and to
// to create the page if requested. Note the Finish page is
// responsible for initial installs also.
//
// Parameters: pWizard [IN] - Ptr to a Wizard instance
// pData [IN] - Context data to describe the world in
// which the Wizard will be run
// fCountOnly [IN] - If True, only the maximum number of
// pages this routine will create need
// be determined.
// pnPages [IN] - Increment by the number of pages
// to create/created
//
// Returns: HRESULT, S_OK on success
//
HRESULT HrCreateFinishPage(CWizard *pWizard, PINTERNAL_SETUP_DATA pData,
BOOL fCountOnly, UINT *pnPages)
{
TraceFileFunc(ttidGuiModeSetup);
HRESULT hr = S_OK;
UINT nId = 0;
(*pnPages)++;
// If not only counting, create and register the page
if (!fCountOnly)
{
HPROPSHEETPAGE hpsp;
PROPSHEETPAGE psp;
TraceTag(ttidWizard, "Creating Finish Page");
psp.dwSize = sizeof( PROPSHEETPAGE );
if (!IsPostInstall(pWizard))
{
nId = IDD_FinishSetup;
psp.dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
psp.pszHeaderTitle = SzLoadIds(IDS_T_Finish);
psp.pszHeaderSubTitle = SzLoadIds(IDS_ST_Finish);
}
else
{
nId = IDD_Finish;
psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
}
Assert (nId);
psp.pszTemplate = MAKEINTRESOURCE( nId );
psp.hInstance = _Module.GetResourceInstance();
psp.hIcon = NULL;
psp.pfnDlgProc = dlgprocFinish;
psp.lParam = reinterpret_cast<LPARAM>(pWizard);
hpsp = CreatePropertySheetPage( &psp );
if (hpsp)
{
pWizard->RegisterPage(nId, hpsp,
FinishPageCleanup, NULL);
}
else
{
hr = E_OUTOFMEMORY;
}
}
TraceHr(ttidWizard, FAL, hr, FALSE, "HrCreateFinishPage");
return hr;
}
//
// Function: AppendFinishPage
//
// Purpose: Add the Finish page, if it was created, to the set of pages
// that will be displayed.
//
// Parameters: pWizard [IN] - Ptr to Wizard Instance
// pahpsp [IN,OUT] - Array of pages to add our page to
// pcPages [IN,OUT] - Count of pages in pahpsp
//
// Returns: Nothing
//
VOID AppendFinishPage(CWizard *pWizard, HPROPSHEETPAGE* pahpsp, UINT *pcPages)
{
TraceFileFunc(ttidGuiModeSetup);
UINT idd;
if (!IsPostInstall(pWizard))
idd = IDD_FinishSetup;
else
idd = IDD_Finish;
HPROPSHEETPAGE hPage = pWizard->GetPageHandle(idd);
Assert(hPage);
pahpsp[*pcPages] = hPage;
(*pcPages)++;
}