|
|
/******************************************************************************
Copyright (c) 1999-2000 Microsoft Corporation
Module Name: main.cpp
Abstract: This file contains the implementation of WinMain
Revision History: Seong Kook Khang (skkhang) 06/07/99 created Seong Kook Khang (skkhang) 05/10/00 Restructured and cleaned up for Whistler
******************************************************************************/
// Note: Proxy/Stub Information
// To build a separate proxy/stub DLL,
// run nmake -f PCHealthps.mk in the project directory.
#include "stdwin.h"
#include "resource.h" // resource include for this module
#include "rstrpriv.h"
#include "rstrerr.h"
#include "rstrmgr.h"
#include "extwrap.h"
#include "rstrmap.h"
#include "FrmBase.h"
#include <respoint.h>
#include <enumlogs.h>
#include "srrpcapi.h"
#include "NTServMsg.h" // generated from the MC message compiler
#define RSTRUI_RETURN_CODE_SR_DISABLED 1
#define RSTRUI_RETURN_CODE_NO_DISK_SPACE 3
#define RSTRUI_RETURN_CODE_SMFROZEN 4
#define RSTRUI_RETURN_CODE_SMGR_NOT_ALIVE 5
#define SMGR_INIT_TIMEOUT 2000 // 2 seconds to wait after starting Stmgr to let it initialize itself
// try thrice
enum { CMDPARAM_INVALID = 0, // invalid parameter...
// initiating phase
CMDPARAM_NORMAL, // normal UI without any parameter
CMDPARAM_REGSERVER, // register COM server
CMDPARAM_UNREGSERVER, // unregister COM server
CMDPARAM_SILENT, // Silent Restore
// after-boot phase
CMDPARAM_CHECK, // check log file and show result page (normal)
CMDPARAM_INTERRUPTED, // abnormal shutdown, initiate undo
CMDPARAM_HIDERESULT, // do not show success result page for Silent Restore
// commands for debug
CMDPARAM_RESULT_S, // show success result page
CMDPARAM_RESULT_F, // show failure result page
CMDPARAM_RESULT_LD, // show low disk result page
CMDPARAM_SENTINEL };
// Forward declarations for file static functions
DWORD ParseCommandParameter( DWORD *pdwRP ); void ShowErrorMessage(HRESULT hr); BOOL IsFreeSpaceOnWindowsDrive( void );
extern BOOL CheckWininitErr(); extern BOOL ValidateLogFile( BOOL *pfSilent, BOOL *pfUndo );
// Application Instance
HINSTANCE g_hInst = NULL;
// External Wrapper Instance
ISRExternalWrapper *g_pExternal = NULL;
// Main Frame Instance
ISRFrameBase *g_pMainFrm = NULL;
// Restore Manager Instance
CRestoreManager *g_pRstrMgr = NULL;
CSRClientLoader g_CSRClientLoader;
/////////////////////////////////////////////////////////////////////////////
BOOL CancelRestorePoint() { TraceFunctEnter("CancelRestorePoint"); BOOL fRet = TRUE; int nUsedRP;
nUsedRP = g_pRstrMgr->GetNewRP(); if (nUsedRP == -1) // not initialized, see if it's the current one
{ CRestorePoint rp; GetCurrentRestorePoint (rp); if (rp.GetType() == RESTORE) nUsedRP = rp.GetNum(); } DebugTrace(0, "Deleting RP %d", nUsedRP); if ( nUsedRP > 0 ) fRet = g_pExternal->RemoveRestorePoint( nUsedRP );
TraceFunctLeave(); return( fRet ); }
DWORD ProductFeedback (LPWSTR pszString) { TraceFunctEnter("Product Feedback");
HANDLE hFile = INVALID_HANDLE_VALUE; PROCESS_INFORMATION pi; STARTUPINFOW si; DWORD dwErr = ERROR_SUCCESS; DWORD cbWritten = 0; const int MAX_STR = 1024; WCHAR wcsSystem[MAX_PATH]; WCHAR wcsBuffer[MAX_STR]; WCHAR wcsDataFile[MAX_PATH]; const WCHAR c_wcsCommand[] = L"%s\\dwwin.exe -d %s\\%s"; const WCHAR c_wcsManifest[] = L"restore\\rstrdw.txt"; const WCHAR c_wcsData[] = L"restore\\srpfdata.txt"; if (0 == GetSystemDirectoryW (wcsSystem, MAX_PATH)) { dwErr = GetLastError(); goto Err; }
// construct the data file to be uploaded
wsprintf (wcsDataFile, L"%s\\%s", wcsSystem, c_wcsData); hFile = CreateFileW ( wcsDataFile, // file name
GENERIC_WRITE, // file access
0, // share mode
NULL, // SD
CREATE_ALWAYS, // how to create
0, // file attributes
NULL); // handle to template file
if (hFile == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); trace(0, "! CreateFile : %ld", dwErr); goto Err; }
if (FALSE == WriteFile (hFile, (BYTE *) pszString, lstrlenW(pszString)*sizeof(WCHAR), &cbWritten, NULL)) { dwErr = GetLastError(); trace(0, "! WriteFile : %ld", dwErr); goto Err; }
CloseHandle (hFile); hFile = INVALID_HANDLE_VALUE; wsprintf (wcsBuffer, L"%s\\%s", wcsSystem, c_wcsManifest);
hFile = CreateFileW ( wcsBuffer, // file name
GENERIC_WRITE, // file access
0, // share mode
NULL, // SD
CREATE_ALWAYS, // how to create
0, // file attributes
NULL); // handle to template file
if (hFile == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); trace(0, "! CreateFile : %ld", dwErr); goto Err; }
PCHLoadString(IDS_PRODUCTFEEDBACK, wcsBuffer, MAX_STR-1); lstrcat(wcsBuffer, L"DataFiles="); lstrcat(wcsBuffer, wcsDataFile); if (FALSE == WriteFile (hFile, (BYTE *) wcsBuffer, lstrlenW(wcsBuffer)*sizeof(WCHAR), &cbWritten, NULL)) { dwErr = GetLastError(); trace(0, "! WriteFile : %ld", dwErr); goto Err; }
CloseHandle (hFile); hFile = INVALID_HANDLE_VALUE;
wsprintf (wcsBuffer, c_wcsCommand, wcsSystem, wcsSystem, c_wcsManifest);
ZeroMemory (&pi, sizeof(pi)); ZeroMemory (&si, sizeof(si));
if (CreateProcessW (NULL, wcsBuffer, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, wcsSystem, &si, &pi)) { CloseHandle (pi.hThread); CloseHandle (pi.hProcess); }
Err: if (hFile != INVALID_HANDLE_VALUE) CloseHandle (hFile);
TraceFunctLeave(); return dwErr; }
/////////////////////////////////////////////////////////////////////////////
//
extern "C" int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/ ) { HRESULT hr; int nRet = 0; DWORD dwRet=0; LPWSTR szCmdLine; LPCWSTR szToken; const WCHAR cszPrefix[] = L"-/"; int nStartMode = SRASM_NORMAL; BOOL fLoadRes = FALSE; int nTries = 0; BOOL fRebootSystem = FALSE; DWORD dwCmd; DWORD dwRP = 0xFFFFFFFF; BOOL fWasSilent = FALSE; BOOL fWasUndo = FALSE; DWORD dwEventID = 0; DWORD dwDisable = 0; BOOL fSendFeedback = FALSE; WCHAR szPFString[MAX_PATH]; DWORD dwPFID = 0; #if !NOTRACE
InitAsyncTrace(); #endif
TraceFunctEnter("_tWinMain");
g_hInst = hInstance;
// Load SRClient
g_CSRClientLoader.LoadSrClient(); //szCmdLine = ::GetCommandLine(); //this line necessary for _ATL_MIN_CRT
//szToken = ::PathGetArgs( szCmdLine );
// Check credential and set necessary privileges
if ( !::CheckPrivilegesForRestore() ) { ::ShowSRErrDlg( IDS_ERR_LOW_PRIVILEGE ); goto Exit; }
// Parse command line parameter
dwCmd = ParseCommandParameter( &dwRP );
// Initialize class objects
if ( !::CreateSRExternalWrapper( FALSE, &g_pExternal ) ) goto Exit;
if ( !::CreateSRFrameInstance( &g_pMainFrm ) ) goto Exit;
if ( !g_pMainFrm->InitInstance( hInstance ) ) goto Exit;
if ( !::CreateRestoreManagerInstance( &g_pRstrMgr ) ) goto Exit;
// if the registry says that SR is enabled, make sure we are
// enabled correctly (service is started, startup mode is correct)
// if registry says we are enabled, but service start type is disabled
// disable us now
if (::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszSRRegKey, s_cszDisableSR, &dwDisable ) ) { DWORD dwStart; if (0 == dwDisable) { if (ERROR_SUCCESS == GetServiceStartup(s_cszServiceName, &dwStart) && (dwStart == SERVICE_DISABLED || dwStart == SERVICE_DEMAND_START)) { EnableSR(NULL); DisableSR(NULL); } else { EnableSR(NULL); } } }
switch ( dwCmd ) { case CMDPARAM_NORMAL : break;
case CMDPARAM_REGSERVER : dwRet = g_pMainFrm->RegisterServer(); #if DBG==1
if ( dwRet == ERROR_CALL_NOT_IMPLEMENTED ) ::MessageBox(NULL, L"/RegServer is not supported...", L"CommandLine Options", MB_OK); #endif
goto Exit;
case CMDPARAM_UNREGSERVER : dwRet = g_pMainFrm->UnregisterServer(); #if DBG==1
if ( dwRet == ERROR_CALL_NOT_IMPLEMENTED ) ::MessageBox(NULL, L"/UnregServer is not supported", L"CommandLine Options", MB_OK); #endif
goto Exit;
case CMDPARAM_SILENT : g_pRstrMgr->SilentRestore( dwRP ); goto Exit;
case CMDPARAM_CHECK : case CMDPARAM_HIDERESULT : // check result of MoveFileEx, if it's possible...
if ( ValidateLogFile( &fWasSilent, &fWasUndo ) ) { nStartMode = SRASM_SUCCESS; } else { // Cancel restore point of "Restore" type
::CancelRestorePoint(); nStartMode = SRASM_FAIL; }
g_pRstrMgr->SetIsUndo(fWasUndo); break;
case CMDPARAM_INTERRUPTED : // read the log file to get the new restore point
if (ValidateLogFile( &fWasSilent, &fWasUndo )) { nStartMode = SRASM_FAIL; } else { nStartMode = SRASM_FAIL; }
g_pRstrMgr->SetIsUndo(fWasUndo); break;
case CMDPARAM_RESULT_S : // read the log file, but ignore the result
ValidateLogFile( NULL, &fWasUndo ); nStartMode = SRASM_SUCCESS; g_pRstrMgr->SetIsUndo(fWasUndo); break; case CMDPARAM_RESULT_F : // read the log file, but ignore the result
ValidateLogFile( NULL, &fWasUndo ); nStartMode = SRASM_FAIL; g_pRstrMgr->SetIsUndo(fWasUndo); ::CancelRestorePoint(); break; case CMDPARAM_RESULT_LD : // read the log file, but ignore the result
ValidateLogFile( NULL, &fWasUndo ); nStartMode = SRASM_FAILLOWDISK; g_pRstrMgr->SetIsUndo(fWasUndo); ::CancelRestorePoint(); break;
default : // Invalid Parameter, simply invoke regular UI
#if DBG==1
::MessageBox(NULL, L"Unknown Option", L"CommandLine Options", MB_OK); #endif
break; }
// also check to see if the Winlogon key to call restore has been
// removed. In normal circumstances, this key should have been
// deleted during the restore but if the machine was not shutdown
// cleanly, this key can remain causing the machine to again
// initiate restore on the next reboot.
::SHDeleteValue( HKEY_LOCAL_MACHINE, s_cszSRRegKey,s_cszRestoreInProgress);
// if start mode is SRASM_FAIL, check to see if we failed becuase
// of low disk space. If this is the case, show the low disk
// space message. Else check for the interrupted case.
if (nStartMode == SRASM_FAIL) { DWORD dwRestoreStatus = ERROR_INTERNAL_ERROR; ::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszSRRegKey, s_cszRestoreStatus, &dwRestoreStatus ); if (dwRestoreStatus != 0) // interrupted
{ nStartMode = SRASM_FAILINTERRUPTED; } else // Cancel restore point of "Restore" type
{ if (TRUE == CheckForDiskSpaceError()) { nStartMode = SRASM_FAILLOWDISK; } ::CancelRestorePoint(); } } switch ( nStartMode ) { case SRASM_FAIL: dwEventID = EVMSG_RESTORE_FAILED; dwPFID = IDS_PFFAILED; break; case SRASM_FAILLOWDISK: dwEventID = EVMSG_RESTORE_FAILED; dwPFID = IDS_PFFAILEDLOWDISK; break;
case SRASM_FAILINTERRUPTED: dwEventID = EVMSG_RESTORE_INTERRUPTED; dwPFID = IDS_PFINTERRUPTED; break;
case SRASM_SUCCESS: dwEventID = EVMSG_RESTORE_SUCCESS; dwPFID = IDS_PFSUCCESS; break;
default: break; }
if (dwEventID != 0) { WCHAR szUnknownRP [MAX_PATH]; const WCHAR *pwszUsedName = g_pRstrMgr->GetUsedName(); HANDLE hEventSource = RegisterEventSource(NULL, s_cszServiceName); DWORD dwType = g_pRstrMgr->GetUsedType() + 1; WCHAR szRPType[100], szTime1[50], szTime2[50]; if (NULL == pwszUsedName) { PCHLoadString(IDS_UNKNOWN_RP, szUnknownRP, MAX_PATH-1); pwszUsedName = szUnknownRP; } if (hEventSource != NULL) { SRLogEvent (hEventSource, EVENTLOG_INFORMATION_TYPE, dwEventID, NULL, 0, pwszUsedName, NULL, NULL); DeregisterEventSource(hEventSource); }
// construct a string for PF
if (! fWasSilent) { PCHLoadString(IDS_UNKNOWN_RP + dwType, szRPType, sizeof(szRPType)/sizeof(WCHAR)); GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, szTime1, sizeof(szTime1)/sizeof(WCHAR)); GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS, NULL, NULL, szTime2, sizeof(szTime2)/sizeof(WCHAR)); if (SRFormatMessage(szPFString, dwPFID, szTime1, szTime2, pwszUsedName, szRPType, g_pRstrMgr->GetUsedType(), dwPFID-IDS_PFFAILED)) { fSendFeedback = TRUE; } else { trace(0, "! SRFormatMessage"); } } { WCHAR szWMIRepository [MAX_PATH];
GetSystemDirectory (szWMIRepository, MAX_PATH); lstrcatW (szWMIRepository, L"\\Wbem\\Repository.bak"); Delnode_Recurse (szWMIRepository, TRUE, NULL); } }
//
// Before this, perform any necessary bookeeping operations those
// are necessary for both of Normal & Silent Restore
//
if ( fWasSilent ) goto Exit;
// Maybe explicit registration is not really necessary... Doing it here always
// if UI is going to be displayed.
g_pMainFrm->RegisterServer();
// Check if SR is frozen or disabled.
if ( nStartMode == SRASM_NORMAL ) if ( !g_pRstrMgr->CanRunRestore( TRUE ) ) goto Exit;
HWND hwnd; TCHAR szMainWndTitle[MAX_PATH+1];
PCHLoadString(IDS_RESTOREUI_TITLE, szMainWndTitle, MAX_PATH);
// Find Previous Instance.
hwnd = ::FindWindow(CLSNAME_RSTRSHELL, szMainWndTitle); if (hwnd != NULL) { // If exist, activate it.
::ShowWindow(hwnd, SW_SHOWNORMAL); ::SetForegroundWindow(hwnd); } else { if ( g_pMainFrm != NULL ) { nRet = g_pMainFrm->RunUI( szMainWndTitle, nStartMode ); } }
Exit:
//if (fSendFeedback)
// ProductFeedback(szPFString);
if ( g_pRstrMgr != NULL ) { fRebootSystem = g_pRstrMgr->NeedReboot(); g_pRstrMgr->Release(); g_pRstrMgr = NULL; } if ( g_pMainFrm != NULL ) { g_pMainFrm->ExitInstance(); g_pMainFrm->Release(); g_pMainFrm = NULL; }
if ( g_pExternal != NULL ) { if ( !fRebootSystem ) { //
// Since FIFO has been disabled in the UI, if for any reason the UI crashes or
// something bad happens we will come here and give FIFO a chance to resume
//
if ( g_pExternal->EnableFIFO() != ERROR_SUCCESS ) { ErrorTrace(TRACE_ID, "EnableFIFO() failed"); } }
g_pExternal->Release(); }
DebugTrace(0, "Closing rstrui.exe..."); TraceFunctLeave(); #if !NOTRACE
TermAsyncTrace(); #endif
if ( fRebootSystem ) { ::ExitWindowsEx( EWX_REBOOT | EWX_FORCE, 0 ); }
return(nRet); }
/******************************************************************************/
#if HANDLE_FIRST_RP
#define FIRSTRUN_MAX_RETRY 5
#define FIRSTRUN_SLEEP_LEN 2000
BOOL CreateFirstRestorePoint() { TraceFunctEnter("CreateFirstRestorePoint"); BOOL fRet = FALSE; DWORD dwRes; HKEY hKey = NULL; DWORD dwType; char szData[MAX_PATH]; DWORD dwDelay; DWORD cbData; BOOL fDelayDeleted = FALSE; int i; RESTOREPOINTINFO sRPInfo; STATEMGRSTATUS sSmgrStatus;
dwRes = ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, s_cszIDSVXDKEY, 0, NULL, &hKey ); if ( dwRes != ERROR_SUCCESS ) { ErrorTrace(TRACE_ID, "RegOpenKeyEx('%s') failed, ret=%u", s_cszIDSVXDKEY, dwRes ); goto Exit; }
// Check DelayFirstRstpt registry key and delete it if exists
dwType = REG_DWORD; cbData = sizeof(DWORD); dwRes = ::RegQueryValueEx( hKey, s_cszIDSDelayFirstRstpt, NULL, &dwType, (LPBYTE)&dwDelay, &cbData ); if ( dwRes != ERROR_SUCCESS || dwType != REG_DWORD || cbData == 0 ) { DebugTrace(TRACE_ID, "DelayFirstRstpt flag does not exist"); goto Ignored; } if ( dwDelay != 1 ) { DebugTrace(TRACE_ID, "DelayFirstRstpt flag is '%d'", dwDelay); goto Ignored; }
// Check OOBEInProgress registry key and do nothing if it exists
dwType = REG_SZ; cbData = MAX_PATH; dwRes = ::RegQueryValueEx( hKey, s_cszIDSOOBEInProgress, NULL, &dwType, (LPBYTE)szData, &cbData ); if ( dwRes == ERROR_SUCCESS ) { DebugTrace(TRACE_ID, "OOBEInProgress flag exists"); goto Ignored; }
// This should be before deleting DelayFirstRstpt because of the logic of
// SRSetRestorePoint API.
EnsureStateMgr();
// Delete DelayFirstRstpt flag
dwRes = ::RegDeleteValue( hKey, s_cszIDSDelayFirstRstpt ); if ( dwRes == ERROR_SUCCESS ) fDelayDeleted = TRUE; else ErrorTrace(TRACE_ID, "RegSetValueEx('%s') failed, ret=%u", s_cszIDSDelayFirstRstpt, dwRes );
// Now set FirstRun restore point
::ZeroMemory( &sRPInfo, sizeof(sRPInfo) ); sRPInfo.dwEventType = BEGIN_SYSTEM_CHANGE; sRPInfo.dwRestorePtType = FIRSTRUN; ::lstrcpy( sRPInfo.szDescription, "CHECKPOINT" ); for ( i = 0; i < FIRSTRUN_MAX_RETRY; i++ ) { if ( i > 0 ) ::Sleep( FIRSTRUN_SLEEP_LEN );
if ( ::SRSetRestorePoint( &sRPInfo, &sSmgrStatus ) ) { DebugTrace(TRACE_ID, "FirstRun restore point has been created!!!"); break; } DebugTrace(TRACE_ID, "SRSetRestorePoint failed, i=%d, nStatus=%d", i, sSmgrStatus.nStatus); }
Ignored: fRet = TRUE; Exit: if ( hKey != NULL ) { if ( !fDelayDeleted ) { dwRes = ::RegDeleteValue( hKey, s_cszIDSDelayFirstRstpt ); if ( dwRes != ERROR_SUCCESS ) ErrorTrace(TRACE_ID, "RegSetValueEx('%s') failed, ret=%u", s_cszIDSDelayFirstRstpt, dwRes ); } ::RegCloseKey( hKey ); }
TraceFunctLeave(); return( fRet ); } #endif //HANDLE_FIRST_RP
/******************************************************************************/ //
// Note:
// =====
// This function loads the error message from resource only dll
// If the resource only dll could not be loaded, this function must not be
// used to display the error
//
void ShowErrorMessage( HRESULT hr ) { TraceFunctEnter("ShowErrorMessage");
int nErrorMessageID = FALSE ; TCHAR szErrorTitle[MAX_PATH+1]; TCHAR szErrorMessage[MAX_ERROR_STRING_LENGTH+1];
// display error message and shut down gracefully
switch (hr) { default: case E_UNEXPECTED: case E_FAIL: nErrorMessageID = IDS_ERR_RSTR_UNKNOWN; break; case E_OUTOFMEMORY: nErrorMessageID = IDS_ERR_RSTR_OUT_OF_MEMORY; break; case E_RSTR_CANNOT_CREATE_DOMDOC: nErrorMessageID = IDS_ERR_RSTR_CANNOT_CREATE_DOMDOC; break; case E_RSTR_INVALID_CONFIG_FILE: case E_RSTR_NO_PROBLEM_AREAS: case E_RSTR_NO_PROBLEM_AREA_ATTRS: case E_RSTR_NO_REQUIRED_ATTR: nErrorMessageID = IDS_ERR_RSTR_INVALID_CONFIG_FILE; break; }
PCHLoadString(IDS_ERR_RSTR_TITLE, szErrorTitle, MAX_PATH); PCHLoadString(nErrorMessageID, szErrorMessage, MAX_ERROR_STRING_LENGTH);
//
// no owner window (use NULL)
// we could use the GetDesktopWindow() and use that as the owner
// if necessary
//
if ( nErrorMessageID ) { ::MessageBox(NULL, szErrorMessage, szErrorTitle, MB_OK); }
TraceFunctLeave(); }
/////////////////////////////////////////////////////////////////////////////
DWORD ParseCommandParameter( DWORD *pdwRP ) { TraceFunctEnter("ParseCommandParameter"); DWORD dwCmd = CMDPARAM_INVALID; LPCWSTR cszCmd;
cszCmd = ::PathGetArgs( ::GetCommandLine() ); DebugTrace(0, "Cmd='%ls'", cszCmd); if ( ( cszCmd == NULL ) || ( *cszCmd == L'\0' ) ) { dwCmd = CMDPARAM_NORMAL; goto Exit; }
if ( ( *cszCmd == L'-' ) || ( *cszCmd == L'/' ) ) { cszCmd++; DebugTrace(0, "Option='%ls'", cszCmd); if ( *cszCmd != L'\0' ) { if ( ::StrCmpI( cszCmd, L"c" ) == 0 ) dwCmd = CMDPARAM_CHECK; else if ( ::StrCmpI( cszCmd, L"regserver" ) == 0 ) dwCmd = CMDPARAM_REGSERVER; else if ( ::StrCmpI( cszCmd, L"unregserver" ) == 0 ) dwCmd = CMDPARAM_UNREGSERVER; else if ( ::ChrCmpI( *cszCmd, L'v' ) == 0 ) { dwCmd = CMDPARAM_SILENT; cszCmd++; while ( ( *cszCmd != L'\0' ) && ( ( *cszCmd == L' ' ) || ( *cszCmd == L'\t' ) ) ) cszCmd++; if ( *cszCmd >= L'0' && *cszCmd <= L'9' ) *pdwRP = ::StrToInt( cszCmd ); } else if ( ::StrCmpI( cszCmd, L"b" ) == 0 ) dwCmd = CMDPARAM_HIDERESULT; else if ( ::StrCmpNI( cszCmd, L"result:", 7 ) == 0 ) { cszCmd += 7; if ( ::StrCmpIW( cszCmd, L"s" ) == 0 ) dwCmd = CMDPARAM_RESULT_S; else if ( ::StrCmpIW( cszCmd, L"f" ) == 0 ) dwCmd = CMDPARAM_RESULT_F; else if ( ::StrCmpIW( cszCmd, L"ld" ) == 0 ) dwCmd = CMDPARAM_RESULT_LD; } else if ( ::StrCmpI( cszCmd, L"i" ) == 0 ) dwCmd = CMDPARAM_INTERRUPTED; } }
Exit: DebugTrace(0, "m_dwCmd=%d, dwRP=%d", dwCmd, *pdwRP); TraceFunctLeave(); return( dwCmd ); }
// end of file
|