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.
735 lines
20 KiB
735 lines
20 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
asr_dlg.cpp
|
|
|
|
Abstract:
|
|
|
|
Top level code to backup and restore information about the volumes on
|
|
a system. This module handles the main application dialogue, including
|
|
parsing the command-line, and updating the progress bar and UI status
|
|
text.
|
|
|
|
|
|
Authors:
|
|
|
|
Steve DeVos (Veritas) (v-stevde) 15-May-1998
|
|
Guhan Suriyanarayanan (guhans) 21-Aug-1999
|
|
|
|
Environment:
|
|
|
|
User-mode only.
|
|
|
|
Revision History:
|
|
|
|
15-May-1998 v-stevde Initial creation
|
|
21-Aug-1999 guhans Cleaned up and re-wrote this module.
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
#include "asr_fmt.h"
|
|
#include "asr_dlg.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
BOOLEAN g_bQuickFormat = FALSE;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CAsr_fmtDlg dialog
|
|
|
|
CAsr_fmtDlg::CAsr_fmtDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CAsr_fmtDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CAsr_fmtDlg)
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
void CAsr_fmtDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CAsr_fmtDlg)
|
|
DDX_Control(pDX, IDC_PROGRESS, m_Progress);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CAsr_fmtDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CAsr_fmtDlg)
|
|
//}}AFX_MSG_MAP
|
|
|
|
// manually added message handlers (for user-defined messages) should be added OUTSIDE
|
|
// the AFX_MSG_MAP part above
|
|
|
|
ON_MESSAGE(WM_WORKER_THREAD_DONE, OnWorkerThreadDone)
|
|
ON_MESSAGE(WM_UPDATE_STATUS_TEXT, OnUpdateStatusText)
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CAsr_fmtDlg message handlers
|
|
// ON_BN_CLICKED(IDOK, OnWorkerThreadDone)
|
|
|
|
BOOL CAsr_fmtDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
// initialize the progress range and start posiiton
|
|
m_Progress.SetRange(0, 100);
|
|
m_Progress.SetPos(0);
|
|
m_ProgressPosition = 0;
|
|
|
|
// Launch the worker thread.
|
|
CreateThread(NULL, // no sid
|
|
0, // no initial stack size
|
|
(LPTHREAD_START_ROUTINE) CAsr_fmtDlg::DoWork,
|
|
this, // parameter
|
|
0, // no flags
|
|
NULL // no thread ID
|
|
);
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
}
|
|
|
|
LRESULT
|
|
CAsr_fmtDlg::OnWorkerThreadDone(
|
|
WPARAM wparam,
|
|
LPARAM lparam
|
|
)
|
|
{
|
|
EndDialog(m_dwEndStatus);
|
|
return 0;
|
|
}
|
|
|
|
|
|
LRESULT
|
|
CAsr_fmtDlg::OnUpdateStatusText(
|
|
WPARAM wparam,
|
|
LPARAM lparam
|
|
)
|
|
{
|
|
SetDlgItemText(IDC_STATUS_TEXT, m_strStatusText);
|
|
m_Progress.SetPos(m_ProgressPosition);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
Name: DoWork()
|
|
|
|
Description: This function runs as a thread launched form the Init
|
|
of the dialog. This function determines what needs to be done, then
|
|
calls the appropraite function to do the work.
|
|
|
|
Modified: 8/31/1998
|
|
|
|
Returns: TRUE
|
|
|
|
Notes: If an error occurs EndDialog will be called with the
|
|
exit status.
|
|
|
|
Declaration:
|
|
|
|
**/
|
|
long
|
|
CAsr_fmtDlg::DoWork(
|
|
CAsr_fmtDlg *_this
|
|
)
|
|
{
|
|
ASRFMT_CMD_OPTION cmdOption = cmdUndefined;
|
|
|
|
cmdOption = _this->ParseCommandLine();
|
|
((CAsr_fmtDlg *)_this)->m_AsrState = NULL;
|
|
|
|
_this->m_dwEndStatus = ERROR_SUCCESS;
|
|
|
|
switch (cmdOption) {
|
|
|
|
case cmdBackup: {
|
|
|
|
if (!(_this->BackupState())) {
|
|
_this->m_dwEndStatus = GetLastError();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case cmdRestore: {
|
|
if (!(_this->RestoreState())) {
|
|
_this->m_dwEndStatus = GetLastError();
|
|
}
|
|
break;
|
|
}
|
|
|
|
case cmdDisplayHelp: {
|
|
_this->m_dwEndStatus = ERROR_INVALID_FUNCTION; // display help ...
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if (ERROR_INVALID_FUNCTION != _this->m_dwEndStatus) { // display help ...
|
|
_this->PostMessage(WM_WORKER_THREAD_DONE, 0, 0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
Name: BackupState()
|
|
|
|
Description: This function reads the current state file to get
|
|
the current data for the sections to modify. It then updates
|
|
[VOLUMES], [REMOVABLEMEDIA] and [COMMANDS] sections.
|
|
|
|
|
|
Notes: If an error occurs an Error message popup is provided to
|
|
the user.
|
|
|
|
Declaration:
|
|
|
|
**/
|
|
|
|
BOOL
|
|
CAsr_fmtDlg::BackupState()
|
|
{
|
|
BOOL result = FALSE;
|
|
HANDLE hHeap = GetProcessHeap();
|
|
int i = 0;
|
|
|
|
CString strPleaseWait;
|
|
strPleaseWait.LoadString(IDS_PLEASE_WAIT_BACKUP);
|
|
SetDlgItemText(IDC_PROGRESS_TEXT, strPleaseWait);
|
|
|
|
m_AsrState = (PASRFMT_STATE_INFO) HeapAlloc(
|
|
hHeap,
|
|
HEAP_ZERO_MEMORY,
|
|
sizeof (ASRFMT_STATE_INFO)
|
|
);
|
|
|
|
|
|
//
|
|
// The only purpose of the for loops below are to slow down the
|
|
// UI and make the progress bar proceed smoothly, so that the user
|
|
// can read the dialogue box on screen.
|
|
//
|
|
m_strStatusText.LoadString(IDS_QUERY_SYS_FOR_INFO);
|
|
for (i = 3; i < 15; i++) {
|
|
|
|
m_ProgressPosition = i;
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
Sleep(50);
|
|
|
|
}
|
|
|
|
if (m_AsrState) {
|
|
result = BuildStateInfo(m_AsrState);
|
|
}
|
|
if (!result) {
|
|
goto EXIT;
|
|
}
|
|
|
|
//
|
|
// The only purpose of the for loops below are to slow down the
|
|
// UI and make the progress bar proceed smoothly, so that the user
|
|
// can read the dialogue box on screen.
|
|
//
|
|
m_strStatusText.LoadString(IDS_QUERY_SYS_FOR_INFO);
|
|
for (i = 15; i < 45; i++) {
|
|
|
|
m_ProgressPosition = i;
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
Sleep(50);
|
|
|
|
}
|
|
|
|
//
|
|
// Pretend we're doing something else (change UI text)
|
|
//
|
|
m_strStatusText.LoadString(IDS_BUILDING_VOL_LIST);
|
|
for (i = 45; i < 80; i++) {
|
|
|
|
m_ProgressPosition = i;
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
Sleep(50);
|
|
|
|
}
|
|
|
|
m_strStatusText.LoadString(IDS_WRITING_TO_SIF);
|
|
for (i = 80; i < 90; i++) {
|
|
m_ProgressPosition = i;
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
Sleep(50);
|
|
}
|
|
|
|
|
|
result = WriteStateInfo(m_dwpAsrContext, m_AsrState);
|
|
|
|
if (!result) {
|
|
goto EXIT;
|
|
}
|
|
m_strStatusText.LoadString(IDS_WRITING_TO_SIF);
|
|
|
|
for (i = 90; i < 101; i++) {
|
|
m_ProgressPosition = i;
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
Sleep(50);
|
|
}
|
|
|
|
EXIT:
|
|
FreeStateInfo(&m_AsrState);
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Name: RestoreState()
|
|
|
|
Description: This function restores the state found in the [VOLUMES]
|
|
section of the asr.sif file. The state restored includs:
|
|
the drive letter.
|
|
If drive is inaccessible it is formated.
|
|
the volume label.
|
|
|
|
Notes: If an error occurs an Error message popup is provided to
|
|
the user.
|
|
|
|
|
|
**/
|
|
BOOL
|
|
CAsr_fmtDlg::RestoreState()
|
|
{
|
|
|
|
BOOL bErrorsEncountered = FALSE,
|
|
result = TRUE;
|
|
|
|
CString strPleaseWait;
|
|
strPleaseWait.LoadString(IDS_PLEASE_WAIT_RESTORE);
|
|
|
|
|
|
SetDlgItemText(IDC_PROGRESS_TEXT, strPleaseWait);
|
|
|
|
m_ProgressPosition = 0;
|
|
m_strStatusText.LoadString(IDS_READING_SIF);
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
|
|
AsrfmtpInitialiseErrorFile(); // in case we need to log error messages
|
|
|
|
//
|
|
// 1. Read the state file
|
|
//
|
|
result = ReadStateInfo( (LPCTSTR)m_strSifPath, &m_AsrState);
|
|
if (!result || !m_AsrState) {
|
|
DWORD status = GetLastError();
|
|
|
|
CString strErrorTitle;
|
|
CString strErrorMessage;
|
|
CString strErrorFormat;
|
|
|
|
strErrorTitle.LoadString(IDS_ERROR_TITLE);
|
|
strErrorFormat.LoadString(IDS_ERROR_NO_DRSTATE);
|
|
|
|
strErrorMessage.Format(strErrorFormat, (LPCTSTR)m_strSifPath, status);
|
|
|
|
AsrfmtpLogErrorMessage(_SeverityWarning, (LPCTSTR)strErrorMessage);
|
|
AsrfmtpCloseErrorFile();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// 2. Loop through all the volumes listed in the state file.
|
|
//
|
|
PASRFMT_VOLUME_INFO pVolume = m_AsrState->pVolume;
|
|
PASRFMT_REMOVABLE_MEDIA_INFO pMedia = m_AsrState->pRemovableMedia;
|
|
UINT driveType = DRIVE_UNKNOWN;
|
|
PWSTR lpDrive = NULL; // Display string, of the form \DosDevices\C: or \??\Volume{Guid}
|
|
DWORD cchVolumeGuid = 0;
|
|
WCHAR szVolumeGuid[MAX_PATH + 1];
|
|
int sizeIncrement = 0, i = 0;
|
|
BOOL first = TRUE, isIntact = FALSE, isLabelIntact = TRUE;
|
|
|
|
//
|
|
// We need to first set all the guids a volume has, then try setting the drive
|
|
// letters. Also, we need to go through the guid loop twice, to handle this case:
|
|
//
|
|
// Consider a sif where we had the entries
|
|
// ... \vol1, \vol2
|
|
// ... \vol1, \x:
|
|
// ... \vol1, \vol3
|
|
//
|
|
// where vol1, vol2 and vol3 are volume guids (\??\Volume{Guid}),
|
|
// and x: is the drive letter (\DosDevices\X:)
|
|
//
|
|
// Now, our list will contain three nodes:
|
|
// -->(vol1, vol3)-->(vol1, x:)-->(vol1, vol2)-->/
|
|
//
|
|
// The problem is, the partition could currently have the guid vol2. (since
|
|
// it is free to have any one of the three guids).
|
|
//
|
|
// If we only went through the loop once, we'll try to map vol1 to vol3, or
|
|
// vice-versa if vol1 doesn't exist. Since neither exist yet, we would've
|
|
// complained to the user.
|
|
//
|
|
// The advantage to doing it twice is this: the first time, since neither vol1
|
|
// nor vol3 exist yet, we'll skip that node. Then we'll skip the drive letter for
|
|
// now (since we're only doing guids), and eventually we'll map vol2 to vol1.
|
|
//
|
|
// The second time, we'll find vol1 exists (mapped to vol2), and we'll be
|
|
// able to map vol1 to vol3. In a later loop, vol1 will also get the drive
|
|
// letter X, and all's well.
|
|
//
|
|
// By the way, we could optimise this by creating a better data structure,
|
|
// but it's too late in the game now for that. If the performance is
|
|
// really bad, we could come back to this.
|
|
//
|
|
|
|
if (m_AsrState->countVolume > 1) {
|
|
sizeIncrement = 50 / (m_AsrState->countVolume - 1);
|
|
}
|
|
else {
|
|
sizeIncrement = 100;
|
|
}
|
|
|
|
m_ProgressPosition = 0;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
pVolume = m_AsrState->pVolume;
|
|
|
|
while (pVolume) {
|
|
|
|
m_ProgressPosition += sizeIncrement;
|
|
m_strStatusText.Format(IDS_REST_SYM_LINKS, pVolume->szGuid);
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
|
|
if ((!pVolume->IsDosPathAssigned) &&
|
|
ASRFMT_LOOKS_LIKE_VOLUME_GUID(pVolume->szDosPath, (wcslen(pVolume->szDosPath) * sizeof(WCHAR)))
|
|
) {
|
|
pVolume->IsDosPathAssigned = SetDosName(pVolume->szGuid, pVolume->szDosPath);
|
|
|
|
if (!pVolume->IsDosPathAssigned) {
|
|
pVolume->IsDosPathAssigned = SetDosName(pVolume->szDosPath, pVolume->szGuid);
|
|
}
|
|
}
|
|
|
|
pVolume = pVolume->pNext;
|
|
}
|
|
}
|
|
|
|
pVolume = m_AsrState->pVolume;
|
|
FormatInitialise();
|
|
while (pVolume) {
|
|
lpDrive = ((wcslen(pVolume->szDosPath) > 0) ? pVolume->szDosPath : pVolume->szGuid);
|
|
//
|
|
// Check if the drive is accessible. If not, we log an error message
|
|
// and continue. GetDriveType requires the name in the DOS name space, so we
|
|
// convert our GUID (NT name space) to the required format first
|
|
//
|
|
cchVolumeGuid = wcslen(pVolume->szGuid);
|
|
if (cchVolumeGuid >= MAX_PATH) {
|
|
cchVolumeGuid = MAX_PATH - 1;
|
|
}
|
|
wcsncpy(szVolumeGuid, pVolume->szGuid, cchVolumeGuid);
|
|
|
|
szVolumeGuid[1] = L'\\';
|
|
szVolumeGuid[cchVolumeGuid] = L'\\'; // Trailing back-slash
|
|
szVolumeGuid[cchVolumeGuid+1] = L'\0';
|
|
|
|
driveType = GetDriveType(szVolumeGuid);
|
|
|
|
if (DRIVE_NO_ROOT_DIR == driveType) {
|
|
CString strErrorTitle;
|
|
CString strErrorMessage;
|
|
CString strErrorFormat;
|
|
|
|
strErrorTitle.LoadString(IDS_ERROR_TITLE);
|
|
strErrorFormat.LoadString(IDS_ERROR_MISSING_VOL);
|
|
|
|
strErrorMessage.Format(strErrorFormat, (PWSTR) pVolume->szGuid);
|
|
AsrfmtpLogErrorMessage(_SeverityWarning, (LPCTSTR)strErrorMessage);
|
|
|
|
bErrorsEncountered = TRUE;
|
|
}
|
|
|
|
if (DRIVE_FIXED != driveType) {
|
|
//
|
|
// Strange. The volumes section should have only listed the drives that
|
|
// were fixed (At backup time). This could probably mean that a volume that
|
|
// used to be on a fixed drive is now on a removable drive?!
|
|
//
|
|
pVolume = pVolume->pNext;
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Set the drive letter of the volume
|
|
//
|
|
result = TRUE;
|
|
if (!pVolume->IsDosPathAssigned){
|
|
m_ProgressPosition = 0;
|
|
m_strStatusText.Format(IDS_REST_DRIVE_LETTER, lpDrive);
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
|
|
result = SetDosName(pVolume->szGuid, pVolume->szDosPath);
|
|
}
|
|
|
|
if (!result) {
|
|
CString strErrorTitle;
|
|
CString strErrorMessage;
|
|
CString strErrorFormat;
|
|
|
|
strErrorTitle.LoadString(IDS_ERROR_TITLE);
|
|
strErrorFormat.LoadString(IDS_ERROR_MOUNTING);
|
|
|
|
strErrorMessage.Format(strErrorFormat, (PWSTR) pVolume->szDosPath, (PWSTR) pVolume->szGuid);
|
|
AsrfmtpLogErrorMessage(_SeverityWarning, (LPCTSTR)strErrorMessage);
|
|
|
|
bErrorsEncountered = TRUE;
|
|
|
|
pVolume = pVolume->pNext;
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check if the volume needs to be formatted
|
|
//
|
|
m_ProgressPosition = 0;
|
|
m_strStatusText.Format(IDS_CHECKING_VOLUME, lpDrive);
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
|
|
isIntact = IsFsTypeOkay(pVolume, &isLabelIntact);
|
|
if (isIntact) {
|
|
isIntact = IsVolumeIntact(pVolume);
|
|
}
|
|
|
|
//
|
|
// Format the volume if needed
|
|
//
|
|
if (!isIntact && FormatVolume(pVolume)) {
|
|
isLabelIntact = FALSE;
|
|
m_ProgressPosition = 0;
|
|
m_strStatusText.Format(IDS_FORMATTING_VOLUME, lpDrive);
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
//
|
|
// FormatVolume is asynchronous.
|
|
//
|
|
first = TRUE;
|
|
while (g_bFormatInProgress) {
|
|
|
|
if (g_iFormatPercentComplete >= 100) {
|
|
if (first) {
|
|
m_ProgressPosition = 100;
|
|
m_strStatusText.Format(IDS_CREATING_FS_STRUCT, lpDrive);
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
first = FALSE;
|
|
}
|
|
}
|
|
else {
|
|
m_Progress.SetPos(g_iFormatPercentComplete);
|
|
}
|
|
|
|
Sleep(100);
|
|
}
|
|
|
|
if (!g_bFormatSuccessful) {
|
|
CString strErrorTitle;
|
|
CString strErrorMessage;
|
|
CString strErrorFormat;
|
|
|
|
strErrorTitle.LoadString(IDS_ERROR_TITLE);
|
|
strErrorFormat.LoadString(IDS_ERROR_FORMATTING);
|
|
|
|
strErrorMessage.Format(strErrorFormat, (PWSTR) lpDrive);
|
|
AsrfmtpLogErrorMessage(_SeverityWarning, (LPCTSTR)strErrorMessage);
|
|
|
|
bErrorsEncountered = TRUE;
|
|
pVolume = pVolume->pNext;
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Force the file-system to be mounted
|
|
//
|
|
MountFileSystem(pVolume);
|
|
|
|
}
|
|
|
|
//
|
|
// Set the volume label if it isn't intact
|
|
//
|
|
if (!isLabelIntact) {
|
|
m_ProgressPosition = 0;
|
|
m_strStatusText.Format(IDS_REST_VOL_LABEL, lpDrive);
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
|
|
if ((wcslen(pVolume->szFsName) > 0) &&
|
|
!SetVolumeLabel(szVolumeGuid, pVolume->szLabel)) {
|
|
|
|
bErrorsEncountered = TRUE;
|
|
|
|
pVolume = pVolume->pNext;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
pVolume = pVolume->pNext;
|
|
}
|
|
FormatCleanup();
|
|
|
|
|
|
while (pMedia) {
|
|
lpDrive = ((wcslen(pMedia->szDosPath) > 0) ? pMedia->szDosPath : pMedia->szVolumeGuid);
|
|
|
|
//
|
|
// set the drive letter
|
|
//
|
|
m_ProgressPosition = 0;
|
|
m_strStatusText.Format(IDS_REST_DRIVE_LETTER, lpDrive);
|
|
PostMessage(WM_UPDATE_STATUS_TEXT);
|
|
|
|
result = SetRemovableMediaGuid(pMedia->szDevicePath, pMedia->szVolumeGuid);
|
|
if (result) {
|
|
result = SetDosName(pMedia->szVolumeGuid, pMedia->szDosPath);
|
|
}
|
|
|
|
if (!result) {
|
|
CString strErrorTitle;
|
|
CString strErrorMessage;
|
|
CString strErrorFormat;
|
|
|
|
strErrorTitle.LoadString(IDS_ERROR_TITLE);
|
|
strErrorFormat.LoadString(IDS_ERROR_MOUNTING);
|
|
|
|
strErrorMessage.Format(IDS_ERROR_MOUNTING, (PWSTR) pMedia->szDosPath, (PWSTR) pMedia->szVolumeGuid);
|
|
AsrfmtpLogErrorMessage(_SeverityWarning, (LPCTSTR)strErrorMessage);
|
|
|
|
// ignore failures setting drive letter on CD.
|
|
// bErrorsEncountered = TRUE;
|
|
}
|
|
|
|
pMedia = pMedia->pNext;
|
|
}
|
|
|
|
AsrfmtpCloseErrorFile();
|
|
return (bErrorsEncountered ? FALSE : TRUE);
|
|
}
|
|
|
|
|
|
inline
|
|
BOOL
|
|
IsGuiModeAsr()
|
|
{
|
|
WCHAR szAsrFlag[20];
|
|
|
|
//
|
|
// If (and only if) this is GUI-mode ASR, the ASR_C_CONTEXT
|
|
// environment variable is set to "AsrInProgress"
|
|
//
|
|
return (GetEnvironmentVariable(L"ASR_C_CONTEXT", szAsrFlag, 20) &&
|
|
!wcscmp(szAsrFlag, L"AsrInProgress"));
|
|
}
|
|
|
|
/**
|
|
|
|
Name: ParseCommandLine()
|
|
|
|
Description: This function reads the comand line and looks for the
|
|
"backup" or "restore" options.
|
|
|
|
Modified: 8/31/1998
|
|
|
|
Returns: cmdBackup, cmdRestore, or cmdDisplayHelp.
|
|
|
|
Notes: If neither backup or restore are found, then the usage
|
|
is displayed in the error box.
|
|
|
|
Declaration:
|
|
|
|
**/
|
|
ASRFMT_CMD_OPTION
|
|
CAsr_fmtDlg::ParseCommandLine()
|
|
{
|
|
CString cmd;
|
|
m_dwpAsrContext = 0;
|
|
|
|
cmd = GetCommandLine();
|
|
cmd.MakeLower();
|
|
if (cmd.Find(TEXT("/backup")) != -1) {
|
|
|
|
int pos = cmd.Find(TEXT("/context="));
|
|
if (pos > -1) {
|
|
#ifdef _IA64_
|
|
_stscanf(cmd.Mid(pos, cmd.GetLength() - pos + 1), TEXT("/context=%I64u"), &m_dwpAsrContext);
|
|
#else
|
|
_stscanf(cmd.Mid(pos, cmd.GetLength() - pos + 1), TEXT("/context=%lu"), &m_dwpAsrContext);
|
|
#endif
|
|
return cmdBackup;
|
|
}
|
|
|
|
|
|
} else if (cmd.Find(TEXT("/restore")) != -1) {
|
|
|
|
if (cmd.Find(TEXT("/full")) != -1) {
|
|
g_bQuickFormat = FALSE;
|
|
}
|
|
else if (cmd.Find(TEXT("/quick")) != -1) {
|
|
g_bQuickFormat = TRUE;
|
|
}
|
|
else if (IsGuiModeAsr()) {
|
|
g_bQuickFormat = FALSE;
|
|
}
|
|
else {
|
|
g_bQuickFormat = TRUE;
|
|
}
|
|
|
|
|
|
int pos = cmd.Find(TEXT("/sifpath="));
|
|
if (pos > -1) {
|
|
_stscanf(cmd.Mid(pos, cmd.GetLength() - pos + 1), TEXT("/sifpath=%ws"), m_strSifPath.GetBuffer(1024));
|
|
m_strSifPath.ReleaseBuffer();
|
|
return cmdRestore;
|
|
}
|
|
}
|
|
|
|
CString strErrorTitle;
|
|
CString strErrorMessage;
|
|
INT space_offset;
|
|
|
|
strErrorTitle.LoadString(IDS_ERROR_TITLE);
|
|
strErrorMessage.LoadString(IDS_ERROR_USAGE);
|
|
|
|
space_offset = cmd.Find(' ');
|
|
if (space_offset >0) {
|
|
cmd = cmd.Left(cmd.Find(' '));
|
|
}
|
|
|
|
SetDlgItemText(IDC_PROGRESS_TEXT, strErrorMessage);
|
|
|
|
CWnd *pText = GetDlgItem(IDC_STATUS_TEXT);
|
|
pText->ShowWindow(SW_HIDE);
|
|
|
|
CButton *pButton = (CButton*)GetDlgItem(IDOK);
|
|
pButton->ShowWindow(SW_SHOW);
|
|
pButton->SetState(TRUE);
|
|
pButton->SetCheck(TRUE);
|
|
|
|
CWnd *pBar = GetDlgItem(IDC_PROGRESS);
|
|
pBar->ShowWindow(SW_HIDE);
|
|
|
|
return cmdDisplayHelp;
|
|
}
|
|
|
|
|