windows-nt/Source/XPSP1/NT/windows/winstate/cobra/app/scanstate/scanstate.c
2020-09-26 16:20:57 +08:00

983 lines
26 KiB
C

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
scanstate.c
Abstract:
Implements the app layer of the v1 compatibility app.
Author:
Jim Schmidt (jimschm) 14-Mar-2000
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include "ism.h"
#include "modules.h"
#include "trans.h"
#include "v2app.h"
#include <lm.h>
#ifdef DEBUG
#include <shellapi.h>
#endif
#include "logmsg.h"
#include "common.h"
#define DBG_SCANSTATE "ScanState"
//
// Strings
//
// None
//
// Constants
//
#define LOG_VERBOSE_BIT 0x01
#define LOG_UNUSED_BIT 0x02 // for v1 compatibility, do not use
#define LOG_STATUS_BIT 0x04
#define LOG_DEBUGGER_BIT 0x08
#define LOG_UPDATE_BIT 0x10
#define SCANSTATE_SAVE 0x00000001
#define SCANSTATE_COMPLETED 0x00000002
#define RETURN_SUCCESS 0
#define RETURN_FATAL_ERROR 1
#define RETURN_ERROR 2
//
// Macros
//
// None
//
// Types
//
typedef NET_API_STATUS(WINAPI NETWKSTAGETINFO)(PWSTR, DWORD, PBYTE *);
typedef NETWKSTAGETINFO *PNETWKSTAGETINFO;
typedef NET_API_STATUS(WINAPI NETAPIBUFFERFREE)(PVOID);
typedef NETAPIBUFFERFREE *PNETAPIBUFFERFREE;
//
// Globals
//
BOOL g_OverwriteImage = FALSE;
BOOL g_ContinueOnError = FALSE;
DWORD g_ReturnCode = RETURN_SUCCESS;
TCHAR g_JournalPath[MAX_PATH_PLUS_NUL];
BOOL g_Break;
BOOL g_TestMode;
//
// Macro expansion list
//
#define REQUIRED_INFS \
DEFMAC(OSFILES, TEXT("USMTDef.inf")) \
//
// Private function prototypes
//
#ifdef PRERELEASE
MESSAGECALLBACK pSaveMsgCallback;
#endif
//
// Macro expansion definition
//
//
// This is the structure used for required infs
//
typedef struct {
PCTSTR InfId;
PCTSTR InfName;
} REQUIREDINF_STRUCT, *PREQUIREDINF_STRUCT;
//
// Declare a global array of required infs
//
#define DEFMAC(infid,infname) {TEXT(#infid),infname},
static REQUIREDINF_STRUCT g_RequiredInfs[] = {
REQUIRED_INFS
{NULL, NULL}
};
#undef DEFMAC
//
// Code
//
VOID
pHelpAndExit (
VOID
)
{
PrintMsgOnConsole (MSG_HELP);
#ifdef PRERELEASE
printf ("\nAdditional PRERELEASE options:\n\n"
"/tf Uses full transport instead of v1 transport\n"
"/tc Enable compression\n"
"/ta Enable automatic capability (for homenet transport)\n"
"/ti:<tag> Specify an identity tag for the homenet transport\n"
" Default is user name\n"
"/t:<name> Specifies transport to use\n"
);
#endif
TerminateAppCommon();
UtTerminate ();
exit (1);
}
VOID
pCleanUpApp (
VOID
)
{
IsmTerminate();
if (g_JournalPath[0]) {
DeleteFile (g_JournalPath);
g_JournalPath[0] = 0;
}
}
BOOL
WINAPI
CtrlCRoutine (
IN DWORD ControlSignal
)
{
PrintMsgOnConsole (MSG_EXITING);
LOG ((LOG_WARNING, (PCSTR) MSG_TOOL_STOPPED));
g_Break = TRUE;
IsmSetCancel();
while (IsmCurrentlyExecuting()) {
Sleep (1000);
}
pCleanUpApp();
printf ("\n");
exit (1);
}
ULONG_PTR
pSaveMsgCallback (
UINT Message,
ULONG_PTR Arg
)
{
PTRANSCOPY_ERROR transCopyError;
#ifdef PRERELEASE
PRMEDIA_EXTRADATA extraData;
#endif
switch (Message) {
case TRANSPORTMESSAGE_IMAGE_EXISTS:
return g_OverwriteImage;
case TRANSPORTMESSAGE_SRC_COPY_ERROR:
transCopyError = (PTRANSCOPY_ERROR) Arg;
if (transCopyError) {
if (StringIMatch (transCopyError->ObjectType, TEXT("File"))) {
if ((transCopyError->Error == ERROR_FILE_NOT_FOUND) ||
(transCopyError->Error == ERROR_PATH_NOT_FOUND) ||
(transCopyError->Error == ERROR_ACCESS_DENIED) ||
(transCopyError->Error == ERROR_INVALID_NAME)
) {
return APPRESPONSE_IGNORE;
}
}
}
return APPRESPONSE_FAIL;
#ifdef PRERELEASE
case TRANSPORTMESSAGE_RMEDIA_SAVE:
extraData = (PRMEDIA_EXTRADATA) Arg;
if (!extraData) {
return (MessageBox (
NULL,
TEXT("Please insert the next media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
}
if (extraData->MediaNumber == 1) {
switch (extraData->LastError) {
case RMEDIA_ERR_NOERROR:
return TRUE;
case RMEDIA_ERR_WRONGMEDIA:
return (MessageBox (
NULL,
TEXT("You have inserted the wrong media.\n\nPlease insert the first media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
case RMEDIA_ERR_DISKFULL:
return (MessageBox (
NULL,
TEXT("The media you inserted does not have enough free space.\n\nPlease insert the first media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
case RMEDIA_ERR_WRITEPROTECT:
return (MessageBox (
NULL,
TEXT("The media you inserted is write protected.\n\nPlease insert the first media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
case RMEDIA_ERR_NOTREADY:
return (MessageBox (
NULL,
TEXT("The drive is not ready for use. Please check the drive and make sure that a disk is inserted and that the drive door is closed."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
case RMEDIA_ERR_CRITICAL:
return FALSE;
default:
return (MessageBox (
NULL,
TEXT("Your media is toast.\n\nPlease insert the first media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
}
} else {
switch (extraData->LastError) {
case RMEDIA_ERR_NOERROR:
return TRUE;
case RMEDIA_ERR_WRONGMEDIA:
return (MessageBox (
NULL,
TEXT("You have inserted the wrong media.\n\nPlease insert the next media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
case RMEDIA_ERR_DISKFULL:
return (MessageBox (
NULL,
TEXT("The media you inserted does not have enough free space.\n\nPlease insert the next media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
case RMEDIA_ERR_WRITEPROTECT:
return (MessageBox (
NULL,
TEXT("The media you inserted is write protected.\n\nPlease insert the next media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
case RMEDIA_ERR_NOTREADY:
return (MessageBox (
NULL,
TEXT("The drive is not ready for use. Please check the drive and make sure that a disk is inserted and that the drive door is closed."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
case RMEDIA_ERR_CRITICAL:
return FALSE;
default:
return (MessageBox (
NULL,
TEXT("Your media is toast.\n\nPlease insert the next media in your drive."),
TEXT("ScanState"),
MB_OKCANCEL
) == IDOK);
}
}
#endif
}
return FALSE;
}
VOID
pMyLogCallback (
IN PLOGARG LogArg
)
{
if (LogArg->Debug) {
DEBUGDIRECT (LogArg->Type, LogArg->FormattedMessage);
} else {
if (StringIMatchA (LogArg->Type, LOG_ERROR)) {
if (g_ReturnCode == RETURN_SUCCESS) {
g_ReturnCode = RETURN_ERROR;
}
if (!g_ContinueOnError) {
IsmSetCancel();
}
} else if (StringIMatchA (LogArg->Type, LOG_FATAL_ERROR) ||
StringIMatchA (LogArg->Type, LOG_MODULE_ERROR)) {
g_ReturnCode = RETURN_FATAL_ERROR;
}
LOGDIRECT (LogArg->Type, LogArg->FormattedMessage);
}
}
#ifdef DEBUG
VOID
pStopAndDisplayInfs (
IN PGROWBUFFER InputInfs,
IN BOOL Begin
)
{
MULTISZ_ENUM infEnum;
if (MessageBox (
NULL,
TEXT("ScanState stopped. Do you want to display all loaded INFs?"),
Begin?TEXT("ScanState-Begin"):TEXT("ScanState-End"),
MB_YESNO
) == IDYES) {
//
// now let's open append all INF files and pass the HINF to
// everybody.
//
if (EnumFirstMultiSz (&infEnum, (PCTSTR)InputInfs->Buf)) {
do {
ShellExecute (NULL, TEXT("open"), infEnum.CurrentString, NULL, NULL, SW_SHOWNORMAL);
} while (EnumNextMultiSz (&infEnum));
}
MessageBox (NULL, TEXT("Press OK to continue..."), TEXT("ScanState-Begin"), MB_OK);
}
}
#endif
BOOL
pIsIE4Installed (
VOID
)
{
LONG hResult;
REGSAM prevMode;
HKEY ieKey = NULL;
DWORD valueType = REG_SZ;
DWORD valueSize = 0;
PTSTR valueData = NULL;
PTSTR numPtr = NULL;
PTSTR dotPtr = NULL;
INT major = 0;
INT minor = 0;
TCHAR saved;
BOOL result = FALSE;
prevMode = SetRegOpenAccessMode (KEY_READ);
ieKey = OpenRegKeyStr (TEXT("HKLM\\Software\\Microsoft\\Internet Explorer"));
SetRegOpenAccessMode (prevMode);
if (ieKey) {
hResult = RegQueryValueEx (ieKey, TEXT("Version"), NULL, &valueType, NULL, &valueSize);
if ((hResult == ERROR_SUCCESS) || (hResult == ERROR_MORE_DATA)) {
valueData = (PTSTR)HeapAlloc (GetProcessHeap (), 0, valueSize * 2);
if (valueData) {
hResult = RegQueryValueEx (ieKey, TEXT("Version"), NULL, &valueType, (PBYTE)valueData, &valueSize);
if ((hResult == ERROR_SUCCESS) && (valueType == REG_SZ)) {
// let's see if it the version is the correct one
numPtr = valueData;
dotPtr = _tcschr (numPtr, TEXT('.'));
if (dotPtr) {
saved = *dotPtr;
*dotPtr = 0;
major = _ttoi (numPtr);
*dotPtr = saved;
} else {
major = _ttoi (numPtr);
}
if (dotPtr) {
numPtr = _tcsinc (dotPtr);
dotPtr = _tcschr (numPtr, TEXT('.'));
if (dotPtr) {
saved = *dotPtr;
*dotPtr = 0;
minor = _ttoi (numPtr);
*dotPtr = saved;
} else {
minor = _ttoi (numPtr);
}
}
if ((major >= 5) ||
((major == 4) && (minor >= 71))
) {
result = TRUE;
}
}
HeapFree (GetProcessHeap (), 0, valueData);
valueData = NULL;
}
}
CloseRegKey (ieKey);
}
return result;
}
BOOL
pCheckSystemRequirements (
VOID
)
{
HKEY domainLogonKey;
PDWORD data;
BOOL result = TRUE;
TCHAR userName[MAX_USER_NAME];
DWORD size;
NET_API_STATUS rc;
PWKSTA_INFO_102 buffer;
HANDLE netApi32Lib;
PNETWKSTAGETINFO netWkstaGetInfo;
PNETAPIBUFFERFREE netApiBufferFree;
BYTE sid[256];
DWORD sidSize = 256;
WCHAR domain[256];
DWORD domainSize = 256;
SID_NAME_USE use;
if (!ISNT()) {
//
// Require the Log On To Domain setting to be checked
//
SetLastError (ERROR_SUCCESS);
domainLogonKey = OpenRegKeyStr (TEXT("HKLM\\Network\\Logon"));
if (!domainLogonKey) {
LOG ((LOG_ERROR, (PCSTR) MSG_NETWORK_LOGON_KEY));
return FALSE;
}
data = (PDWORD) GetRegValueBinary (domainLogonKey, TEXT("LMLogon"));
if (!data) {
LOG ((LOG_ERROR, (PCSTR) MSG_NETWORK_LMLOGON_KEY));
result = FALSE;
} else {
if (!(*data)) {
LOG ((LOG_ERROR, (PCSTR) MSG_NO_DOMAIN_LOGON));
result = FALSE;
}
FreeAlloc (data);
}
CloseRegKey (domainLogonKey);
} else {
//
// Require domain membership
//
netApi32Lib = LoadLibrary (TEXT("netapi32.dll"));
if (netApi32Lib) {
netWkstaGetInfo = (PNETWKSTAGETINFO) GetProcAddress (netApi32Lib, "NetWkstaGetInfo");
netApiBufferFree = (PNETAPIBUFFERFREE) GetProcAddress (netApi32Lib, "NetApiBufferFree");
} else {
netWkstaGetInfo = NULL;
netApiBufferFree = NULL;
}
if (!netWkstaGetInfo || !netApiBufferFree) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_LOAD_NETAPI32));
result = FALSE;
} else {
rc = netWkstaGetInfo (NULL, 102, (PBYTE *) &buffer);
if (rc == NO_ERROR) {
result = buffer->wki102_langroup && (buffer->wki102_langroup[0] != 0);
if (result) {
DEBUGMSGW ((DBG_SCANSTATE, "Getting account type of %s", buffer->wki102_langroup));
sidSize = ARRAYSIZE(sid);
domainSize = ARRAYSIZE(domain);
result = LookupAccountNameW (
NULL,
buffer->wki102_langroup,
sid,
&sidSize,
domain,
&domainSize,
&use
);
DEBUGMSG ((DBG_SCANSTATE, "Account type result is %u (use=%u)", result, use));
LOG_IF ((!result, LOG_ERROR, (PCSTR) MSG_NOT_JOINED_TO_DOMAIN));
}
ELSE_DEBUGMSG ((DBG_SCANSTATE, "No langroup specified"));
netApiBufferFree (buffer);
} else {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_GET_WORKSTATION_PROPS));
result = FALSE;
}
}
if (netApi32Lib) {
FreeLibrary (netApi32Lib);
}
}
// let's check to see if IE4 is installed on this machine
if (result && !pIsIE4Installed ()) {
LOG ((LOG_ERROR, (PCSTR) MSG_NEED_IE4));
return FALSE;
}
//
// Make sure a user name is specified
//
if (result) {
size = ARRAYSIZE(userName);
if (!GetUserName (userName, &size)) {
result = FALSE;
} else if (*userName == 0) {
result = FALSE;
}
LOG_IF ((!result, LOG_ERROR, (PCSTR) MSG_LOGGED_ON_USER_REQUIRED));
}
return result;
}
VOID
__cdecl
_tmain (
IN INT Argc,
IN PCTSTR Argv[]
)
{
TCHAR appPath[MAX_PATH_PLUS_NUL];
TCHAR ismPath[MAX_PATH_PLUS_NUL];
PTSTR p;
MIG_TRANSPORTID transportId;
MIG_TRANSPORTSTORAGEID transportStorageId;
MULTISZ_ENUM infEnum;
HINF infHandle = INVALID_HANDLE_VALUE;
ENVENTRY_STRUCT infHandleStruct;
INT numInfs = 0;
PTSTR buffer;
MULTISZ_ENUM e;
DWORD appStatus;
BOOL skipExecute = FALSE;
BOOL storagePathIsValid = FALSE;
BOOL imageExists = FALSE;
BOOL terminateIsm = FALSE;
BOOL logEnabled = FALSE;
PCTSTR msg;
PCTSTR argArray[1];
TOOLARGS args;
BOOL fail;
ZeroMemory (&args, sizeof (args));
SET_RESETLOG();
UtInitialize (NULL);
InitAppCommon();
SuppressAllLogPopups (TRUE);
PrintMsgOnConsole (MSG_RUNNING);
// initialize app journal path
g_JournalPath[0] = 0;
if (GetWindowsDirectory (g_JournalPath, ARRAYSIZE (g_JournalPath))) {
StringCopy (AppendWack (g_JournalPath), TEXT("SCANSTATE.JRN"));
}
GetModuleFileName (NULL, appPath, ARRAYSIZE(appPath));
p = _tcsrchr (appPath, TEXT('\\'));
if (p) {
*p = 0;
}
//
// Parse the command line
//
fail = TRUE;
switch (ParseToolCmdLine (TRUE, &args, Argc, Argv)) {
case PARSE_SUCCESS:
fail = FALSE;
break;
case PARSE_MULTI_LOG:
PrintMsgOnConsole (MSG_MULTI_LOG);
g_ReturnCode = RETURN_FATAL_ERROR;
goto END;
case PARSE_BAD_LOG:
argArray[0] = args.LogFile;
msg = ParseMessageID (MSG_CANT_OPEN_LOG, argArray);
if (msg) {
_tprintf (TEXT("%s"), msg);
FreeStringResource (msg);
}
g_ReturnCode = RETURN_FATAL_ERROR;
goto END;
default:
break;
}
if (fail) {
pHelpAndExit();
}
g_TestMode = args.TestMode;
g_OverwriteImage = args.OverwriteImage;
g_ContinueOnError = args.ContinueOnError;
#ifdef DEBUG
{
if (DoesFileExist (TEXT("C:\\SCANSTATE.BEGIN"))) {
pStopAndDisplayInfs (&args.InputInf, TRUE);
}
}
#endif
LogReInit (NULL, NULL, (args.LogFile ? args.LogFile : TEXT("scanstate.log")), NULL);
logEnabled = TRUE;
//
// Check requirements
//
if (args.BadInfs.End || args.MultiInfs.End) {
SetLastError (ERROR_BAD_COMMAND);
if (EnumFirstMultiSz (&e, (PCTSTR) args.BadInfs.Buf)) {
do {
LOG ((LOG_ERROR, (PCSTR) MSG_INF_FILE_NOT_FOUND, e.CurrentString));
} while (EnumNextMultiSz (&e));
}
if (EnumFirstMultiSz (&e, (PCTSTR) args.MultiInfs.Buf)) {
do {
LOG ((LOG_ERROR, (PCSTR) MSG_INF_SPECIFIED_MORE_THAN_ONE, e.CurrentString));
} while (EnumNextMultiSz (&e));
}
g_ReturnCode = RETURN_FATAL_ERROR;
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_CMD_LINE_ERROR));
goto END;
}
if (!GetFilePath (TEXT("migism.inf"), ismPath, ARRAYSIZE(ismPath))) {
g_ReturnCode = RETURN_FATAL_ERROR;
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_ISM_INF_MISSING));
goto END;
}
if (!g_TestMode) {
if (!pCheckSystemRequirements()) {
g_ReturnCode = RETURN_FATAL_ERROR;
goto END;
}
}
//
// Initialize ISM
//
if (!IsmInitialize (ismPath, pSaveMsgCallback, pMyLogCallback)) {
g_ReturnCode = RETURN_FATAL_ERROR;
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_CANT_START_ISM));
goto END;
}
terminateIsm = TRUE;
SetLogVerbosity (args.VerboseLevel);
SetConsoleCtrlHandler (CtrlCRoutine, TRUE);
IsmSetPlatform (PLATFORM_SOURCE);
// upload environment variables
UploadEnvVars (PLATFORM_SOURCE);
infHandle = InitRequiredInfs (appPath, (PCSTR) MSG_CANT_OPEN_REQUIRED_FILE);
if (args.InputInf.Buf) {
IsmSetEnvironmentData (
PLATFORM_SOURCE,
NULL,
S_INF_FILE_MULTISZ,
args.InputInf.Buf,
(WORD) args.InputInf.End
);
//
// now let's open append all INF files and pass the HINF to
// everybody.
//
if (EnumFirstMultiSz (&infEnum, (PCTSTR)args.InputInf.Buf)) {
buffer = DuplicateTextEx (NULL, S_INF_OBJECT_NAME, 2, &p); // Up to 2 digits of numbers
do {
if (infHandle == INVALID_HANDLE_VALUE) {
infHandle = SetupOpenInfFile (infEnum.CurrentString, NULL, INF_STYLE_WIN4 | INF_STYLE_OLDNT, NULL);
if (infHandle == INVALID_HANDLE_VALUE) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_FILE, infEnum.CurrentString));
}
} else {
if (!SetupOpenAppendInfFile (infEnum.CurrentString, infHandle, NULL)) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_FILE, infEnum.CurrentString));
}
}
// Save Inf for right side use
if (numInfs < 100) {
numInfs++;
_stprintf(p, TEXT("%d"), numInfs);
IsmAddControlFile (buffer, infEnum.CurrentString);
}
} while (EnumNextMultiSz (&infEnum));
FreeText (buffer);
}
}
if (infHandle != INVALID_HANDLE_VALUE) {
infHandleStruct.Type = ENVENTRY_BINARY;
infHandleStruct.EnvBinaryData = (PVOID)(&infHandle);
infHandleStruct.EnvBinaryDataSize = sizeof (HINF);
IsmSetEnvironmentValue (PLATFORM_SOURCE, NULL, S_GLOBAL_INF_HANDLE, &infHandleStruct);
}
if (args.UserOn) {
IsmSetEnvironmentFlag (PLATFORM_SOURCE, NULL, S_ENV_HKCU_V1);
IsmSetEnvironmentFlag (PLATFORM_SOURCE, NULL, S_ENV_HKCU_ON);
}
if (args.FilesOn) {
IsmSetEnvironmentFlag (PLATFORM_SOURCE, NULL, S_ENV_ALL_FILES);
}
//
// Start ETM modules
//
if (!IsmStartEtmModules ()) {
if (!IsmCheckCancel()) {
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_CANT_START_ETMS));
}
goto END;
}
//
// Initialize transport
//
if (!IsmStartTransport ()) {
if (!IsmCheckCancel()) {
LOG ((LOG_FATAL_ERROR, "Can't start the transport."));
}
goto END;
}
transportStorageId = IsmRegisterTransport (args.TransportName);
if (args.FullTransport) {
transportId = IsmSelectTransport (transportStorageId, TRANSPORTTYPE_FULL, args.Capabilities);
} else {
transportId = IsmSelectTransport (transportStorageId, TRANSPORTTYPE_LIGHT, args.Capabilities);
}
if (!args.TransportNameSpecified) {
BfCreateDirectory (args.StoragePath);
}
if (!transportId) {
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_TRANSPORT_UNAVAILABLE));
goto END;
}
#ifdef PRERELEASE
IsmSetEnvironmentString (PLATFORM_SOURCE, NULL, TRANSPORT_ENVVAR_HOMENET_TAG, args.Tag);
#endif
if (!IsmSetTransportStorage (
PLATFORM_SOURCE,
transportId,
transportStorageId,
args.Capabilities,
args.StoragePath,
&storagePathIsValid,
&imageExists
) || storagePathIsValid == FALSE
) {
if (!IsmCheckCancel()) {
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_TRANSPORT_STORAGE_INVALID, args.StoragePath));
}
goto END;
}
#ifdef PRERELEASE
if (args.Capabilities & CAPABILITY_AUTOMATED) {
if (!imageExists) {
LOG ((
LOG_FATAL_ERROR,
"Can't select %s as the transport; need to run loadstate first.",
args.TransportName
));
goto END;
}
}
#endif
appStatus = ReadAppStatus (g_JournalPath);
if (appStatus == SCANSTATE_SAVE) {
skipExecute = IsmResumeSave ();
}
if (!skipExecute) {
//
// Execute the preparsing to populate the components
//
if (IsmExecute (args.FullTransport?EXECUTETYPE_EXECUTESOURCE_PARSING:EXECUTETYPE_VIRTUALCOMPUTER_PARSING)) {
IsmSelectMasterGroup (MASTERGROUP_ALL, TRUE);
if (!args.SystemOn) {
IsmSelectMasterGroup (MASTERGROUP_SYSTEM, FALSE);
IsmSelectMasterGroup (MASTERGROUP_USER, FALSE);
IsmSelectMasterGroup (MASTERGROUP_APP, FALSE);
}
SelectComponentsViaInf (infHandle);
//
// Enumerate the system, gather data and analyze
//
if (IsmExecute (args.FullTransport?EXECUTETYPE_EXECUTESOURCE:EXECUTETYPE_VIRTUALCOMPUTER)) {
//
// Display report
//
//
// Save the state
//
// write the app status
WriteAppStatus (g_JournalPath, SCANSTATE_SAVE);
if (!IsmSave ()) {
if (!IsmCheckCancel()) {
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_CANT_SAVE));
}
}
// write the app status
WriteAppStatus (g_JournalPath, SCANSTATE_COMPLETED);
} else {
if (!IsmCheckCancel()) {
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_CANT_EXECUTE_SOURCE));
}
}
} else {
if (!IsmCheckCancel()) {
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_CANT_EXECUTE_SOURCE));
}
}
}
//
// We're done!
//
SetupCloseInfFile (infHandle);
#ifdef DEBUG
{
if (DoesFileExist (TEXT("C:\\SCANSTATE.END"))) {
pStopAndDisplayInfs (&args.InputInf, FALSE);
}
}
#endif
END:
if (terminateIsm) {
if (!g_Break) {
pCleanUpApp();
}
}
GbFree (&args.BadInfs);
GbFree (&args.MultiInfs);
GbFree (&args.InputInf);
if (!g_Break) {
if (g_ReturnCode != RETURN_SUCCESS) {
if (logEnabled) {
PrintMsgOnConsole (MSG_FAILED_WITH_LOG);
} else {
PrintMsgOnConsole (MSG_FAILED_NO_LOG);
}
} else {
PrintMsgOnConsole (MSG_SUCCESS);
}
}
TerminateAppCommon();
UtTerminate ();
while (g_Break) {
// infinite loop, because we'll get terminated in the ctrl+c handler
Sleep (50);
}
exit (g_ReturnCode);
}