621 lines
15 KiB
C++
621 lines
15 KiB
C++
//+--------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1994 - 1996.
|
|
//
|
|
// File: complete.cxx
|
|
//
|
|
// Contents: Task wizard completion (final) property page implementation.
|
|
//
|
|
// Classes: CCompletionPage
|
|
//
|
|
// History: 4-28-1997 DavidMun Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include "..\pch\headers.hxx"
|
|
#pragma hdrstop
|
|
#include "myheaders.hxx"
|
|
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CCompletionPage::CCompletionPage
|
|
//
|
|
// Synopsis: ctor
|
|
//
|
|
// Arguments: [ptszFolderPath] - full path to tasks folder with dummy
|
|
// filename appended
|
|
// [phPSP] - filled with prop page handle
|
|
//
|
|
// History: 4-28-1997 DavidMun Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
CCompletionPage::CCompletionPage(
|
|
CTaskWizard *pParent,
|
|
LPTSTR ptszFolderPath,
|
|
HPROPSHEETPAGE *phPSP):
|
|
CWizPage(MAKEINTRESOURCE(IDD_COMPLETION), ptszFolderPath)
|
|
{
|
|
TRACE_CONSTRUCTOR(CCompletionPage);
|
|
|
|
_pParent = pParent;
|
|
_hIcon = NULL;
|
|
_pJob = NULL;
|
|
|
|
#ifdef WIZARD97
|
|
m_psp.dwFlags |= PSP_HIDEHEADER;
|
|
#endif // WIZARD97
|
|
|
|
*phPSP = CreatePropertySheetPage(&m_psp);
|
|
|
|
if (!*phPSP)
|
|
{
|
|
DEBUG_OUT_LASTERROR;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CCompletionPage::~CCompletionPage
|
|
//
|
|
// Synopsis: dtor
|
|
//
|
|
// History: 4-28-1997 DavidMun Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
CCompletionPage::~CCompletionPage()
|
|
{
|
|
TRACE_DESTRUCTOR(CCompletionPage);
|
|
|
|
if (_pJob)
|
|
{
|
|
_pJob->Release();
|
|
}
|
|
|
|
if (_hIcon)
|
|
{
|
|
VERIFY(DestroyIcon(_hIcon));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
//
|
|
// CWizPage overrides
|
|
//
|
|
//===========================================================================
|
|
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CCompletionPage::_OnInitDialog
|
|
//
|
|
// Synopsis: Perform initialization that should only occur once.
|
|
//
|
|
// Arguments: [lParam] - LPPROPSHEETPAGE used to create this page
|
|
//
|
|
// Returns: TRUE (let windows set focus)
|
|
//
|
|
// History: 5-20-1997 DavidMun Created
|
|
// 4-14-1998 CameronE Added Policy Support
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
LRESULT
|
|
CCompletionPage::_OnInitDialog(
|
|
LPARAM lParam)
|
|
{
|
|
TRACE_METHOD(CCompletionPage, _OnInitDialog);
|
|
|
|
//
|
|
// Policy Support - remove "open advanced" checkbox if
|
|
// we find a registry key for that policy
|
|
//
|
|
|
|
if (RegReadPolicyKey(TS_KEYPOLICY_DISABLE_ADVANCED))
|
|
{
|
|
DEBUG_OUT((DEB_ITRACE, "Policy DISABLE_ADVANCED active to remove checkbox\n"));
|
|
EnableWindow(_hCtrl(complete_advanced_ckbox), FALSE);
|
|
ShowWindow(_hCtrl(complete_advanced_ckbox), SW_HIDE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CCompletionPage::_OnPSNSetActive
|
|
//
|
|
// Synopsis: Create a task object (in-memory only) and update the
|
|
// summary information on this page.
|
|
//
|
|
// Arguments: [lParam] - LPNMHDR (unused)
|
|
//
|
|
// Returns: TRUE
|
|
//
|
|
// History: 5-20-1997 DavidMun Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
LRESULT
|
|
CCompletionPage::_OnPSNSetActive(
|
|
LPARAM lParam)
|
|
{
|
|
TRACE_METHOD(CCompletionPage, _OnPSNSetActive);
|
|
|
|
HRESULT hr = S_OK;
|
|
LPWSTR pwszTrigger = NULL;
|
|
|
|
do
|
|
{
|
|
//
|
|
// Update the summary info to reflect the user's latest
|
|
// choices.
|
|
//
|
|
|
|
CSelectProgramPage *pSelProg = GetSelectProgramPage(_pParent);
|
|
CSelectTriggerPage *pSelTrig = GetSelectTriggerPage(_pParent);
|
|
|
|
HICON hIcon;
|
|
|
|
hIcon = pSelProg->GetSelectedAppIcon();
|
|
|
|
SendDlgItemMessage(Hwnd(),
|
|
complete_task_icon,
|
|
STM_SETICON,
|
|
(WPARAM) hIcon,
|
|
0L);
|
|
if (_hIcon)
|
|
{
|
|
VERIFY(DestroyIcon(_hIcon));
|
|
}
|
|
_hIcon = hIcon;
|
|
|
|
Static_SetText(_hCtrl(complete_taskname_lbl), pSelTrig->GetTaskName());
|
|
Static_SetText(_hCtrl(complete_trigger_lbl), TEXT(""));
|
|
|
|
//
|
|
// Create the task object so we can ask it for its trigger string.
|
|
// The object won't be persisted until the user hits the Finish
|
|
// button.
|
|
//
|
|
|
|
hr = _UpdateTaskObject();
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
_SetWizButtons(PSWIZB_BACK | PSWIZB_DISABLEDFINISH);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// _pJob is now valid, so enable the finish button.
|
|
//
|
|
|
|
_SetWizButtons(PSWIZB_BACK | PSWIZB_FINISH);
|
|
|
|
//
|
|
// Put the trigger string in the ui so the user can see a
|
|
// description of when the task will run.
|
|
//
|
|
|
|
hr = _pJob->GetTriggerString(0, &pwszTrigger);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
DEBUG_OUT_HRESULT(hr);
|
|
break;
|
|
}
|
|
|
|
#if defined(UNICODE)
|
|
Static_SetText(_hCtrl(complete_trigger_lbl), pwszTrigger);
|
|
#else
|
|
TCHAR tszTrigger[SCH_XBIGBUF_LEN];
|
|
hr = UnicodeToAnsi(tszTrigger, pwszTrigger, ARRAYLEN(tszTrigger));
|
|
Static_SetText(_hCtrl(complete_trigger_lbl), tszTrigger);
|
|
#endif // defined(UNICODE)
|
|
|
|
} while (0);
|
|
|
|
CoTaskMemFree(pwszTrigger);
|
|
return CPropPage::_OnPSNSetActive(lParam);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CCompletionPage::_OnWizBack
|
|
//
|
|
// Synopsis: Set the current page to the one that should precede this.
|
|
//
|
|
// Returns: -1
|
|
//
|
|
// History: 5-20-1997 DavidMun Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
LRESULT
|
|
CCompletionPage::_OnWizBack()
|
|
{
|
|
TRACE_METHOD(CCompletionPage, _OnWizBack);
|
|
|
|
#if defined(_CHICAGO_)
|
|
ULONG iddPage = GetSelectTriggerPage(_pParent)->GetSelectedTriggerPageID();
|
|
SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, iddPage);
|
|
#else
|
|
SetWindowLongPtr(Hwnd(), DWLP_MSGRESULT, IDD_PASSWORD);
|
|
#endif // defined(_CHICAGO_)
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CCompletionPage::_OnWizFinish
|
|
//
|
|
// Synopsis: Persist the task object.
|
|
//
|
|
// Returns: 0
|
|
//
|
|
// History: 5-20-1997 DavidMun Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
LRESULT
|
|
CCompletionPage::_OnWizFinish()
|
|
{
|
|
TRACE_METHOD(CCompletionPage, _OnWizFinish);
|
|
|
|
HRESULT hr = S_OK;
|
|
LPCTSTR ptszJob = NULL;
|
|
CSelectTriggerPage *pSelTrig = GetSelectTriggerPage(_pParent);
|
|
#if !defined(_CHICAGO_)
|
|
CPasswordPage *pPasswdPage = GetPasswordPage(_pParent);
|
|
#endif // !defined(_CHICAGO_)
|
|
BOOL fSaveSucceeded = FALSE;
|
|
|
|
do
|
|
{
|
|
if (!_pJob)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Persist the new job object.
|
|
//
|
|
|
|
ptszJob = pSelTrig->GetJobObjectFullPath();
|
|
CWaitCursor HourGlass;
|
|
|
|
if (FileExists((LPTSTR)ptszJob))
|
|
{
|
|
if (!DeleteFile(ptszJob))
|
|
{
|
|
//
|
|
// Complain but leave hr alone so we don't pop up a second
|
|
// error
|
|
//
|
|
|
|
DEBUG_OUT_LASTERROR;
|
|
SchedUIErrorDialog(Hwnd(),
|
|
IDS_CANT_DELETE_EXISTING,
|
|
(LPTSTR) pSelTrig->GetTaskName());
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
hr = _pJob->Save(ptszJob, TRUE);
|
|
#else
|
|
WCHAR wszBuf[MAX_PATH];
|
|
hr = AnsiToUnicode(wszBuf, ptszJob, MAX_PATH);
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
hr = _pJob->Save(wszBuf, TRUE);
|
|
#endif
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
fSaveSucceeded = TRUE;
|
|
|
|
#if !defined(_CHICAGO_)
|
|
//
|
|
// (NT only) set the account information. Caller must ensure
|
|
// service is running.
|
|
//
|
|
|
|
hr = _pJob->SetAccountInformation(pPasswdPage->GetAccountName(),
|
|
pPasswdPage->GetPassword());
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
hr = _pJob->Save(NULL, FALSE);
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
#endif // !defined(_CHICAGO_)
|
|
} while (0);
|
|
|
|
#if !defined(_CHICAGO_)
|
|
//
|
|
// Don't leave account name & password in memory
|
|
//
|
|
|
|
pPasswdPage->ZeroCredentials();
|
|
#endif // !defined(_CHICAGO_)
|
|
|
|
//
|
|
// If advanced checkbox is checked, indicate to DoTaskWizard. Also,
|
|
// give it a reference to the job object so it can do any terminal
|
|
// processing necessary (e.g., displaying the property pages).
|
|
//
|
|
|
|
if (fSaveSucceeded)
|
|
{
|
|
BOOL fAdvanced = IsDlgButtonChecked(Hwnd(), complete_advanced_ckbox);
|
|
|
|
_pParent->SetAdvancedMode(fAdvanced);
|
|
|
|
_pJob->AddRef();
|
|
_pParent->SetTaskObject(_pJob);
|
|
|
|
_pParent->SetJobObjectPath(ptszJob);
|
|
}
|
|
|
|
//
|
|
// Notify the user if anything went wrong.
|
|
//
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
if (fSaveSucceeded)
|
|
{
|
|
SchedUIErrorDialog(Hwnd(), IDS_WIZFINISH_NONFATAL, hr);
|
|
}
|
|
else
|
|
{
|
|
SchedUIErrorDialog(Hwnd(), IDS_WIZFINISH_FATAL, hr);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CCompletionPage::_UpdateTaskObject
|
|
//
|
|
// Synopsis: Create a task object in memory that matches all the
|
|
// settings the user made on previous pages.
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 5-20-1997 DavidMun Created
|
|
//
|
|
// Notes: If a task object already exists, it is freed and replaced
|
|
// with a new one.
|
|
//
|
|
// The task object is not persisted until the user hits the
|
|
// finish button.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
HRESULT
|
|
CCompletionPage::_UpdateTaskObject()
|
|
{
|
|
TRACE_METHOD(CCompletionPage, _CreateTaskObject);
|
|
|
|
HRESULT hr = S_OK;
|
|
ITaskTrigger *pTrigger = NULL;
|
|
CSelectTriggerPage *pSelTrig = GetSelectTriggerPage(_pParent);
|
|
CSelectProgramPage *pSelProg = GetSelectProgramPage(_pParent);
|
|
|
|
do
|
|
{
|
|
//
|
|
// If there's already a task object, get rid of it. This would
|
|
// be the case if the user got to the finish page, then hit
|
|
// the back button.
|
|
//
|
|
|
|
if (_pJob)
|
|
{
|
|
_pJob->Release();
|
|
_pJob = NULL;
|
|
}
|
|
|
|
//
|
|
// Create the task object
|
|
//
|
|
|
|
_pJob = CJob::Create();
|
|
|
|
if (_pJob == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
DEBUG_OUT_HRESULT(hr);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Add default flags
|
|
//
|
|
|
|
DWORD dwAddFlags = TASK_FLAG_DONT_START_IF_ON_BATTERIES |
|
|
TASK_FLAG_KILL_IF_GOING_ON_BATTERIES;
|
|
|
|
hr = _pJob->SetFlags(dwAddFlags);
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
//
|
|
// Fill in the trigger struct
|
|
//
|
|
|
|
TASK_TRIGGER Trigger;
|
|
|
|
ZeroMemory(&Trigger, sizeof(Trigger));
|
|
Trigger.cbTriggerSize = sizeof(Trigger);
|
|
|
|
CTriggerPage *pTriggerPage = pSelTrig->GetSelectedTriggerPage();
|
|
|
|
if (pTriggerPage)
|
|
{
|
|
pTriggerPage->FillInTrigger(&Trigger);
|
|
}
|
|
else
|
|
{
|
|
ULONG idTrigger = pSelTrig->GetSelectedTriggerType();
|
|
|
|
switch (idTrigger)
|
|
{
|
|
case seltrig_startup_rb:
|
|
Trigger.TriggerType = TASK_EVENT_TRIGGER_AT_SYSTEMSTART;
|
|
break;
|
|
|
|
case seltrig_logon_rb:
|
|
Trigger.TriggerType = TASK_EVENT_TRIGGER_AT_LOGON;
|
|
break;
|
|
|
|
default:
|
|
DEBUG_ASSERT(FALSE);
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
SYSTEMTIME stStart;
|
|
GetSystemTime(&stStart);
|
|
|
|
Trigger.wBeginYear = stStart.wYear;
|
|
Trigger.wBeginMonth = stStart.wMonth;
|
|
Trigger.wBeginDay = stStart.wDay;
|
|
}
|
|
|
|
//
|
|
// Create a trigger object and init it with the struct
|
|
//
|
|
|
|
WORD iTrigger = (WORD)-1;
|
|
|
|
hr = _pJob->CreateTrigger(&iTrigger, &pTrigger);
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
DEBUG_ASSERT(iTrigger == 0);
|
|
|
|
hr = pTrigger->SetTrigger(&Trigger);
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
//
|
|
// Set the application name
|
|
//
|
|
|
|
TCHAR tszExeFullPath[MAX_PATH + 1];
|
|
|
|
pSelProg->GetExeFullPath(tszExeFullPath, ARRAYLEN(tszExeFullPath));
|
|
|
|
#ifdef UNICODE
|
|
hr = _pJob->SetApplicationName(tszExeFullPath);
|
|
#else
|
|
WCHAR wszBuf[MAX_PATH + 1];
|
|
|
|
hr = AnsiToUnicode(wszBuf, tszExeFullPath, ARRAYLEN(wszBuf));
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
hr = _pJob->SetApplicationName(wszBuf);
|
|
#endif
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
//
|
|
// Set the arguments
|
|
//
|
|
|
|
#ifdef UNICODE
|
|
hr = _pJob->SetParameters(pSelProg->GetArgs());
|
|
#else
|
|
//
|
|
// Since unicode is not defined, we're running on chicago, which
|
|
// means that the app chosen might be sage-aware. If it is,
|
|
// it will need a /sagerun:n argument.
|
|
//
|
|
// BUGBUG if the wizard is made remotable then this will need
|
|
// to be performed while running on nt if the target is win9x.
|
|
//
|
|
|
|
TCHAR tszExeName[MAX_PATH + 1];
|
|
int iSageParam;
|
|
|
|
pSelProg->GetExeName(tszExeName, ARRAYLEN(tszExeName));
|
|
|
|
LPCTSTR ptzArgs = pSelProg->GetArgs();
|
|
|
|
if (IsSageAware(tszExeName, ptzArgs, &iSageParam) &&
|
|
MAX_CCH_SAGERUN_PARAM + lstrlen(ptzArgs) < ARRAYLEN(wszBuf))
|
|
{
|
|
TCHAR tszBuf[MAX_PATH + 1];
|
|
|
|
wsprintf(tszBuf,
|
|
TEXT("%s %s%u"),
|
|
pSelProg->GetArgs(),
|
|
SAGERUN_PARAM,
|
|
iSageParam);
|
|
|
|
hr = AnsiToUnicode(wszBuf, tszBuf, ARRAYLEN(wszBuf));
|
|
|
|
CreateSageRunKey(tszExeName, iSageParam);
|
|
}
|
|
else
|
|
{
|
|
hr = AnsiToUnicode(wszBuf, ptzArgs, ARRAYLEN(wszBuf));
|
|
}
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
hr = _pJob->SetParameters(wszBuf);
|
|
#endif
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
//
|
|
// Set the working directory
|
|
//
|
|
|
|
TCHAR tszWorkingDir[MAX_PATH + 1];
|
|
|
|
pSelProg->GetExeDir(tszWorkingDir, ARRAYLEN(tszWorkingDir));
|
|
|
|
#ifdef UNICODE
|
|
hr = _pJob->SetWorkingDirectory(tszWorkingDir);
|
|
#else
|
|
|
|
hr = AnsiToUnicode(wszBuf, tszWorkingDir, ARRAYLEN(wszBuf));
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
|
|
hr = _pJob->SetWorkingDirectory(wszBuf);
|
|
#endif
|
|
BREAK_ON_FAIL_HRESULT(hr);
|
|
} while (0);
|
|
|
|
if (pTrigger)
|
|
{
|
|
pTrigger->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|