windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/w95upgnt/initnt/initnt.c
2020-09-26 16:20:57 +08:00

1138 lines
23 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
initnt.c
Abstract:
Code that performs initialization for the NT side of migration, and
also implements workers that syssetup.dll calls.
Author:
Jim Schmidt (jimschm) 01-Oct-1996
Revision History:
jimschm 23-Sep-1998 New commonnt lib
jimschm 31-Dec-1997 Moved here from w95upgnt\dll
jimschm 21-Nov-1997 Updated for NEC98, some cleaned up and
code commenting
--*/
#include "pch.h"
#ifndef UNICODE
#error UNICODE required
#endif
//
// Local prototypes
//
BOOL pReadUserOptions (VOID);
VOID pReadStringMap (VOID);
// Things set by FirstInitRoutine
HANDLE g_hHeap;
HINSTANCE g_hInst;
TCHAR g_DllDir[MAX_TCHAR_PATH];
TCHAR g_WinDir[MAX_TCHAR_PATH];
TCHAR g_WinDrive[MAX_TCHAR_PATH];
TCHAR g_SystemDir[MAX_TCHAR_PATH];
TCHAR g_System32Dir[MAX_TCHAR_PATH];
TCHAR g_ProgramFiles[MAX_TCHAR_PATH];
TCHAR g_ProgramFilesCommon[MAX_TCHAR_PATH];
TCHAR g_Win95Name[MAX_TCHAR_PATH]; // holds Windows 95, Windows 98, etc...
PCTSTR g_AdministratorStr;
TCHAR g_Win9xBootDrivePath[] = TEXT("C:\\");
// Things set by SysSetupInit
HWND g_ParentWnd;
HWND g_ProgressBar;
HINF g_UnattendInf = INVALID_HANDLE_VALUE;
HINF g_WkstaMigInf = INVALID_HANDLE_VALUE;
HINF g_UserMigInf = INVALID_HANDLE_VALUE;
TCHAR g_TempDir[MAX_TCHAR_PATH];
TCHAR g_OurCopyOfSourceDir[MAX_TCHAR_PATH];
PCTSTR g_SourceDir;
POOLHANDLE g_UserOptionPool = NULL;
PCTSTR g_MsgYes;
PCTSTR g_MsgNo;
USEROPTIONS g_ConfigOptions;
PMAPSTRUCT g_StringMap;
//
// Initialization code
//
static int g_LibCount = 0;
typedef BOOL (WINAPI INITROUTINE_PROTOTYPE)(HINSTANCE, DWORD, LPVOID);
typedef INITROUTINE_PROTOTYPE * INITROUTINE;
//
// MigUtil_Entry *must* be first
//
#define LIBLIST \
LIBRARY_NAME(MigUtil_Entry) \
LIBRARY_NAME(Win95Reg_Entry) \
LIBRARY_NAME(MemDb_Entry) \
LIBRARY_NAME(FileEnum_Entry) \
LIBRARY_NAME(CommonNt_Entry) \
LIBRARY_NAME(MigMain_Entry) \
LIBRARY_NAME(Merge_Entry) \
LIBRARY_NAME(RuleHlpr_Entry) \
LIBRARY_NAME(DosMigNt_Entry) \
LIBRARY_NAME(Ras_Entry) \
LIBRARY_NAME(Tapi_Entry) \
#define LIBRARY_NAME(x) INITROUTINE_PROTOTYPE x;
LIBLIST
#undef LIBRARY_NAME
#define LIBRARY_NAME(x) x,
static INITROUTINE g_InitRoutine[] = {LIBLIST /*,*/ NULL};
//
// Buffer for persistent strings used for the life of the DLL
//
static PGROWBUFFER g_PersistentStrings;
//
// Implementation
//
BOOL
FirstInitRoutine (
HINSTANCE hInstance
)
/*++
Routine Description:
FirstInitRoutine is the very first function called during the
initialization of the DLL. It sets up globals such as the heap
pointer and instance handle. This routine must be called before
any library entry point is called.
Arguments:
hInstance - (OS-supplied) instance handle for the DLL
Return Value:
Returns TRUE if the global variables could be initialized, or FALSE
if an error occurred.
--*/
{
PTSTR p;
//
// Get the process heap & instance handle
//
g_hHeap = HeapCreate (0, 0x20000, 0);
if (!g_hHeap) {
LOG ((LOG_ERROR, "Cannot create a private heap."));
g_hHeap = GetProcessHeap();
}
g_hInst = hInstance;
// No DLL_THREAD_ATTACH or DLL_THREAD_DETECH needed
DisableThreadLibraryCalls (hInstance);
// Init common controls
InitCommonControls();
// Get DLL path and strip directory
GetModuleFileName (hInstance, g_DllDir, MAX_TCHAR_PATH);
p = _tcsrchr (g_DllDir, TEXT('\\'));
MYASSERT (p);
*p = 0;
// Set g_WinDir
if (!GetWindowsDirectory (g_WinDir, sizeof (g_WinDir) / sizeof (g_WinDir[0]))) {
return FALSE;
}
// Set g_WinDrive
_tsplitpath (g_WinDir, g_WinDrive, NULL, NULL, NULL);
// Set g_SystemDir
wsprintf (g_SystemDir, TEXT("%s\\%s"), g_WinDir, TEXT("system"));
// Set g_System32Dir
GetSystemDirectory (g_System32Dir, sizeof (g_System32Dir) / sizeof (g_System32Dir[0]));
return TRUE;
}
BOOL
InitLibs (
HINSTANCE hInstance,
DWORD dwReason,
LPVOID lpReserved
)
/*++
Routine Description:
InitLibs calls all library entry points in the g_InitRoutine array.
If an entry point fails, all libraries are unloaded in reverse order
and InitLibs returns FALSE.
Arguments:
hInstance - (OS-supplied) instance handle for the DLL
dwReason - (OS-supplied) indicates attach or detatch from process or
thread -- in this case always DLL_PROCESS_ATTACH
lpReserved - (OS-supplied) unused
Return Value:
Returns TRUE if all libraries successfully initialized, or FALSE if
a library could not initialize. If TRUE is returned, TerminateLibs
must be called for the DLL_PROCESS_DETACH message.
--*/
{
if(!pSetupInitializeUtils()) {
return FALSE;
}
SET_RESETLOG();
//
// Init each LIB
//
for (g_LibCount = 0 ; g_InitRoutine[g_LibCount] ; g_LibCount++) {
if (!g_InitRoutine[g_LibCount] (hInstance, dwReason, lpReserved)) {
TerminateLibs (hInstance, DLL_PROCESS_DETACH, lpReserved);
return FALSE;
}
}
return TRUE;
}
BOOL
FinalInitRoutine (
VOID
)
/*++
Routine Description:
FinalInitRoutine completes all initialization that requires completely
initialized libraries.
Arguments:
none
Return Value:
TRUE if initialization completed successfully, or FALSE if an error occurred.
--*/
{
PCTSTR TempStr;
//
// Load common message strings
//
g_PersistentStrings = CreateAllocTable();
if (!g_PersistentStrings) {
return FALSE;
}
// Get Administrator account name
g_AdministratorStr = GetStringResourceEx (g_PersistentStrings, MSG_ADMINISTRATOR_ACCOUNT);
if (!g_AdministratorStr) {
g_AdministratorStr = S_EMPTY;
}
if(ISPC98()){
//
// Update the boot drive letter (set by migutil) to the system partition
//
g_BootDriveLetterW = g_BootDriveLetterA = (int)g_System32Dir[0];
*((PSTR) g_BootDrivePathA) = g_BootDriveLetterA;
*((PWSTR) g_BootDrivePathW) = g_BootDriveLetterW;
}
// Set Program Files directory
TempStr = (PTSTR) GetStringResource (MSG_PROGRAM_FILES_DIR);
MYASSERT (TempStr);
StringCopy (g_ProgramFiles, TempStr);
g_ProgramFiles [0] = g_WinDir [0];
FreeStringResource (TempStr);
StringCopy (g_ProgramFilesCommon, g_ProgramFiles);
StringCat (g_ProgramFilesCommon, TEXT("\\"));
StringCat (g_ProgramFilesCommon, S_COMMONDIR);
return TRUE;
}
VOID
FirstCleanupRoutine (
VOID
)
/*++
Routine Description:
FirstCleanupRoutine is called to perform any cleanup that requires
libraries to still be loaded.
Arguments:
none
Return Value:
none
--*/
{
TCHAR buffer[MEMDB_MAX];
//
// Terminate progress bar table
//
TerminateProcessingTable();
//
// If Win9x Side saved a LOGSAVETO location into memdb, then we need to save the
// debugnt log to that location.
//
MemDbGetEndpointValueEx(MEMDB_CATEGORY_LOGSAVETO,NULL,NULL,buffer);
AppendWack(buffer);
StringCat(buffer,TEXT("debugnt.log"));
CopyFile(TEXT("debugnt.log"),buffer,FALSE);
//
// Clean up persistent strings
//
if (g_PersistentStrings) {
DestroyAllocTable (g_PersistentStrings);
}
}
VOID
TerminateLibs (
HINSTANCE hInstance,
DWORD dwReason,
LPVOID lpReserved
)
/*++
Routine Description:
TerminateLibs is called to unload all libraries in the reverse order
that they were initialized. Each entry point of successfully
initialized library is called.
Arguments:
hInstance - (OS-supplied) instance handle for the DLL
dwReason - (OS-supplied) indicates attach or detatch from process or
thread -- in this case always DLL_PROCESS_DETACH
lpReserved - (OS-supplied) unused
Return Value:
none
--*/
{
INT i;
for (i = g_LibCount - 1 ; i >= 0 ; i--) {
g_InitRoutine[i] (hInstance, dwReason, lpReserved);
}
g_LibCount = 0;
pSetupUninitializeUtils();
}
VOID
FinalCleanupRoutine (
VOID
)
/*++
Routine Description:
FinalCleanupRoutine is after all library entry points have been
called for cleanup. This routine cleans up all resources that a
library will not clean up.
Arguments:
none
Return Value:
none
--*/
{
// Nothing to do now
}
BOOL
pGetInfVal (
PCTSTR Section,
PCTSTR Key,
PTSTR Buffer,
DWORD BufferSize
)
{
INFCONTEXT ic;
if (!SetupFindFirstLine (g_UnattendInf, Section, Key, &ic))
return FALSE;
if (!SetupGetStringField (&ic, 1, Buffer, BufferSize, NULL))
return FALSE;
return TRUE;
}
typedef BOOL (OPTIONHANDLERFUN)(PTSTR, PVOID * Option, PTSTR Value);
typedef OPTIONHANDLERFUN * POPTIONHANDLERFUN;
BOOL pHandleBoolOption (PTSTR, PVOID *, PTSTR);
BOOL pHandleIntOption (PTSTR, PVOID *, PTSTR);
BOOL pHandleTriStateOption (PTSTR, PVOID *, PTSTR);
BOOL pHandleMultiSzOption (PTSTR, PVOID *, PTSTR);
BOOL pHandleStringOption (PTSTR, PVOID *, PTSTR);
BOOL pHandleSaveReportTo (PTSTR, PVOID *, PTSTR);
BOOL pHandleBoot16 (PTSTR, PVOID *, PTSTR);
BOOL pGetDefaultPassword (PTSTR, PVOID *, PTSTR);
typedef struct {
PTSTR OptionName;
PVOID Option;
POPTIONHANDLERFUN DefaultHandler;
POPTIONHANDLERFUN SpecialHandler;
PVOID Default;
} OPTIONSTRUCT, *POPTIONSTRUCT;
#define INT_MAX_NUMBER_OF_DIGIT 11
PTSTR pGetIntStrForOption(INT Value)
{
PTSTR strIntDefaultValue = AllocText(INT_MAX_NUMBER_OF_DIGIT + 1);
if(strIntDefaultValue)
_itot(Value, strIntDefaultValue, 10);
return strIntDefaultValue;
}
#define BOOLOPTION(o,h,d) {TEXT(#o), &(g_ConfigOptions.##o), pHandleBoolOption, (h), (PVOID) (BOOL) (d) ? S_YES : S_NO},
#define INTOPTION(o,h,d) {TEXT(#o), &(g_ConfigOptions.##o), pHandleIntOption, (h), (PVOID)(d)},
#define TRISTATEOPTION(o,h,d) {TEXT(#o), &(g_ConfigOptions.##o), pHandleTriStateOption, (h), (PVOID) (INT) (d == TRISTATE_AUTO)? S_AUTO: (d == TRISTATE_YES)? S_YES : S_NO},
#define MULTISZOPTION(o,h,d) {TEXT(#o), &(g_ConfigOptions.##o), pHandleMultiSzOption, (h), (PVOID) (d)},
#define STRINGOPTION(o,h,d) {TEXT(#o), &(g_ConfigOptions.##o), pHandleStringOption, (h), (PVOID) (d)},
OPTIONSTRUCT g_OptionsList[] = {OPTION_LIST /*,*/ {NULL,NULL,NULL,NULL}};
PVOID g_OptionsTable = NULL;
#define HANDLEOPTION(Os,Value) {Os->SpecialHandler ? \
Os->SpecialHandler (Os->OptionName,Os->Option,Value) : \
Os->DefaultHandler (Os->OptionName,Os->Option,Value); \
}
POPTIONSTRUCT
pFindOption (
PTSTR OptionName
)
{
POPTIONSTRUCT rOption = NULL;
UINT rc;
//
// find the matching option struct for this, and
// call the handler.
//
rc = pSetupStringTableLookUpStringEx (
g_OptionsTable,
OptionName,
STRTAB_CASE_INSENSITIVE,
(PBYTE) &rOption,
sizeof (POPTIONSTRUCT)
);
DEBUGMSG_IF ((rc == -1, DBG_WARNING, "Unknown option found: %s", OptionName));
return rOption;
}
VOID
pInitUserOptionsTable (
VOID
)
{
POPTIONSTRUCT os;
LONG rc;
os = g_OptionsList;
while (os->OptionName) {
//
// Add the option struct to a string table for quick retrieval.
//
rc = pSetupStringTableAddStringEx (
g_OptionsTable,
os->OptionName,
STRTAB_CASE_INSENSITIVE,
(PBYTE) &os,
sizeof (POPTIONSTRUCT)
);
if (rc == -1) {
LOG ((LOG_ERROR, "User Options: Can't add to string table"));
break;
}
os++;
}
}
BOOL
pHandleBoolOption (
IN PTSTR Name,
IN PVOID * OptionVar,
IN PTSTR Value
)
{
BOOL rSuccess = TRUE;
BOOL *option = (BOOL *) OptionVar;
if (StringIMatch (Value, S_YES) ||
StringIMatch (Value, S_ONE) ||
StringIMatch (Value, TEXT("TRUE"))) {
*option = TRUE;
}
else {
*option = FALSE;
}
return rSuccess;
}
BOOL
pHandleIntOption (
IN PTSTR Name,
IN PVOID * OptionVar,
IN PTSTR Value
)
{
BOOL rSuccess = TRUE;
PINT option = (PINT) OptionVar;
MYASSERT(Name && OptionVar);
if (!Value) {
Value = TEXT("0");
}
*option = _ttoi((PCTSTR)Value);
return rSuccess;
}
BOOL
pHandleTriStateOption (
IN PTSTR Name,
IN PVOID * OptionVar,
IN PTSTR Value
)
{
BOOL rSuccess = TRUE;
PINT option = (PINT) OptionVar;
MYASSERT(Name && OptionVar);
if (!Value) {
Value = S_AUTO;
}
if (StringIMatch (Value, S_YES) ||
StringIMatch (Value, S_ONE) ||
StringIMatch (Value, S_TRUE) ||
StringIMatch (Value, S_REQUIRED)) {
*option = TRISTATE_YES;
}
else {
if(StringIMatch (Value, S_NO) ||
StringIMatch (Value, S_STR_FALSE) ||
StringIMatch (Value, S_ZERO)) {
*option = TRISTATE_NO;
}
else {
*option = TRISTATE_AUTO;
}
}
return rSuccess;
}
BOOL
pHandleMultiSzOption (
IN PTSTR Name,
IN PVOID * OptionVar,
IN PTSTR Value
)
{
BOOL rSuccess = TRUE;
if (Value) {
*OptionVar = PoolMemDuplicateMultiSz (g_UserOptionPool, Value);
}
ELSE_DEBUGMSG ((DBG_WHOOPS, "Multi-Sz config option has nul value"));
return rSuccess;
}
BOOL
pHandleStringOption (
IN PTSTR Name,
IN PVOID * OptionVar,
IN PTSTR Value
)
{
if (!Value) {
*OptionVar = S_EMPTY;
}
else {
*OptionVar = PoolMemDuplicateMultiSz (g_UserOptionPool, Value);
}
return TRUE;
}
BOOL
pHandleSaveReportTo (
IN PTSTR Name,
IN PVOID * OptionVar,
IN PTSTR Value
)
{
return pHandleStringOption (Name, OptionVar, Value);
}
BOOL
pHandleBoot16 (
IN PTSTR Name,
IN PVOID * OptionVar,
IN PTSTR Value
)
{
BOOL rSuccess = TRUE;
PTSTR * option = (PTSTR *) OptionVar;
if (!Value ||
StringIMatch (Value, S_YES) ||
StringIMatch (Value, S_TRUE) ||
StringIMatch (Value, S_ONE)) {
*option = S_YES;
g_Boot16 = BOOT16_YES;
}
else if (Value &&
(StringIMatch (Value, S_BOOT16_UNSPECIFIED) ||
StringIMatch (Value, S_BOOT16_AUTOMATIC))) {
*option = S_BOOT16_AUTOMATIC;
g_Boot16 = BOOT16_AUTOMATIC;
}
else {
g_Boot16 = BOOT16_NO;
*option = S_NO;
}
return rSuccess;
}
BOOL
pGetDefaultPassword (
IN PTSTR Name,
IN PVOID * OptionVar,
IN PTSTR Value
)
{
return pHandleStringOption (Name, OptionVar, Value);
}
BOOL
pReadUserOptions (
VOID
)
{
PTSTR curParameter;
PTSTR curValue;
BOOL rSuccess = TRUE;
POPTIONSTRUCT os;
INFSTRUCT is = INITINFSTRUCT_GROWBUFFER;
ZeroMemory(&g_ConfigOptions,sizeof(USEROPTIONS));
g_OptionsTable = pSetupStringTableInitializeEx (sizeof (POPTIONSTRUCT), 0);
if (!g_OptionsTable) {
LOG ((LOG_ERROR, "User Options: Unable to initialize string table."));
return FALSE;
}
pInitUserOptionsTable ();
if (InfFindFirstLine(g_UnattendInf,S_WIN9XUPGUSEROPTIONS,NULL,&is)) {
//
// There is at least one item. Loop through all user options, processing each.
//
do {
//
// Get the parameter and value from this line and pass it on.
//
curParameter = InfGetStringField (&is, 0);
if (curParameter) {
curParameter = PoolMemDuplicateString (g_UserOptionPool, curParameter);
}
curValue = InfGetMultiSzField (&is, 1);
if (curValue) {
curValue = PoolMemDuplicateMultiSz (g_UserOptionPool, curValue);
}
if (curParameter) {
os = pFindOption (curParameter);
if (os) {
HANDLEOPTION (os, curValue);
}
}
else {
//
// If we couldn't get the current parameter, it is a serious enough error
// to abort processing of the unattend file user options.
//
LOG ((LOG_ERROR,"An error occurred while attempting to read user options from the unattend file."));
rSuccess = FALSE;
}
} while (rSuccess && InfFindNextLine(&is));
}
else {
LOG ((LOG_ERROR,"No win9xupgrade section in unattend script file."));
}
InfCleanUpInfStruct (&is);
if (g_ConfigOptions.DoLog) {
SET_DOLOG();
}
pSetupStringTableDestroy (g_OptionsTable);
return rSuccess;
}
BOOL
SysSetupInit (
IN HWND ProgressBar,
IN PCWSTR UnattendFile,
IN PCWSTR SourceDir
)
{
HINF hUnattendInf;
BOOL b = FALSE;
//
// This routine is called after the DLL initialization routines
// have completed.
//
#ifdef PRERELEASE
{
TCHAR Buf[32];
STARTUPINFO si;
BOOL ProcessStarted;
ZeroMemory (&si, sizeof (si));
si.cb = sizeof (si);
if (GetPrivateProfileString (
TEXT("Debug"),
TEXT("Debug"),
TEXT("0"),
Buf,
32,
ISPC98() ? TEXT("a:\\debug.inf") : TEXT("c:\\debug.inf")
)
) {
if (_ttoi (Buf)) {
ProcessStarted = WinExec ("cmd.exe", SW_SHOW) > 31;
if (ProcessStarted) {
MessageBox (NULL, TEXT("Ready to debug."), TEXT("Debug"), MB_OK|MB_SETFOREGROUND);
//CloseHandle (pi.hProcess);
} else {
DEBUGMSG ((DBG_ERROR, "Could not start cmd.exe, GLE=%u", GetLastError()));
}
}
}
}
#endif
//
// Open the answer file and keep it open until SysSetupTerminate is called
//
hUnattendInf = InfOpenInfFile (UnattendFile);
if (hUnattendInf == INVALID_HANDLE_VALUE) {
LOG ((LOG_ERROR, "InitNT: Cannot open %s", UnattendFile));
return FALSE;
}
//
// Create a pool for user options.
//
g_UserOptionPool = PoolMemInitNamedPool ("User Option Pool - NT Side");
if (!g_UserOptionPool) {
DEBUGMSG((DBG_ERROR,"Cannot initialize user option pool."));
return FALSE;
}
//
// Open wkstamig.inf for general use
//
g_WkstaMigInf = InfOpenInfFile (S_WKSTAMIG_INF);
if (g_WkstaMigInf == INVALID_HANDLE_VALUE) {
LOG ((LOG_ERROR, "InitNT: Unable to open %s", S_WKSTAMIG_INF));
return FALSE;
}
//
// Open usermig.inf for general use
//
g_UserMigInf = InfOpenInfFile (S_USERMIG_INF);
if (g_UserMigInf == INVALID_HANDLE_VALUE) {
LOG ((LOG_ERROR, "InitNT: Unable to open %s", S_USERMIG_INF));
return FALSE;
}
//
// Initialize our globals
//
g_UnattendInf = hUnattendInf;
StringCopy (g_OurCopyOfSourceDir, SourceDir);
g_SourceDir = g_OurCopyOfSourceDir;
g_ParentWnd = GetParent (ProgressBar);
LogReInit (&g_ParentWnd, NULL);
g_ProgressBar = ProgressBar;
if (ISPC98()) {
TCHAR win9xBootDrive[6];
//
// Get g_Win9xBootDrive from answer file's [Data] section
//
if (pGetInfVal (
WINNT_DATA,
WINNT_D_WIN9XBOOTDRIVE,
win9xBootDrive,
sizeof (win9xBootDrive) / sizeof (TCHAR)
)) {
g_Win9xBootDrivePath[0] = win9xBootDrive[0];
} else {
LOG ((LOG_ERROR, "InitNT: Cannot retrieve %s in [%s] of %s",
WINNT_DATA, WINNT_D_WIN9XBOOTDRIVE, UnattendFile));
}
}
//
// Get g_TempDir from answer file's [Data] section
//
if (!pGetInfVal (
WINNT_DATA,
WINNT_D_MIGTEMPDIR,
g_TempDir,
sizeof (g_TempDir) / sizeof (TCHAR)
)) {
LOG ((LOG_ERROR, "InitNT: Cannot retrieve %s in [%s] of %s",
WINNT_DATA, WINNT_D_MIGTEMPDIR, UnattendFile));
goto cleanup;
}
//
// Get user settings from command line
//
pReadUserOptions();
//
// Read [String Map] section and put pairs in the corresponding map
//
pReadStringMap ();
// Done!
b = TRUE;
cleanup:
if (!b) {
SysSetupTerminate();
}
return b;
}
VOID
SysSetupTerminate (
VOID
)
{
//
// Close the answer file
//
if (g_UnattendInf != INVALID_HANDLE_VALUE) {
InfCloseInfFile (g_UnattendInf);
g_UnattendInf = INVALID_HANDLE_VALUE;
}
//
// Close wkstamig.inf
//
if (g_WkstaMigInf != INVALID_HANDLE_VALUE) {
InfCloseInfFile (g_WkstaMigInf);
g_WkstaMigInf = INVALID_HANDLE_VALUE;
}
if (g_UserMigInf != INVALID_HANDLE_VALUE) {
InfCloseInfFile (g_UserMigInf);
g_UserMigInf = INVALID_HANDLE_VALUE;
}
//
// Clean up user option pool.
//
if (g_UserOptionPool) {
PoolMemDestroyPool(g_UserOptionPool);
}
//
// Set current directory to the root of C:
//
SetCurrentDirectory (g_BootDrivePath);
#ifdef PRERELEASE
{
TCHAR Buf[32];
if (GetPrivateProfileString (
TEXT("Debug"),
TEXT("GuiModePause"),
TEXT("0"),
Buf,
32,
ISPC98() ? TEXT("a:\\debug.inf") : TEXT("c:\\debug.inf")
)
) {
if (_ttoi (Buf)) {
MessageBox (NULL, TEXT("Paused."), TEXT("Debug"), MB_OK|MB_SETFOREGROUND);
}
}
}
#endif
}
BOOL
PerformMigration (
IN HWND Unused,
IN PCWSTR UnattendFile,
IN PCWSTR SourceDir // i.e. f:\i386
)
{
BOOL rSuccess = TRUE;
//
// Initialize Migmain.
//
if (!MigMain_Init()) {
LOG ((LOG_ERROR, "W95UpgNt_Migrate: MigMain_Init failed"));
rSuccess = FALSE;
}
//
// Do the migration!
//
else if (!MigMain_Migrate()) {
LOG ((LOG_ERROR, "W95UpgNt_Migrate: MigMain_Migrate failed"));
rSuccess = FALSE;
}
//
// If we were unsuccessful anywhere along the way, Migration could be in big
// trouble. Inform the user.
//
if (!rSuccess) {
LOG ((LOG_ERROR, (PCSTR)MSG_MIGRATION_IS_TOAST, g_Win95Name));
}
ELSE_DEBUGMSG((DBG_VERBOSE, "W95UpgNt_Migrate: Successful completion..."));
return rSuccess;
}
VOID
pReadStringMap (
VOID
)
{
INFSTRUCT is = INITINFSTRUCT_POOLHANDLE;
PTSTR Key, Value;
INT SubstringMatch;
PTSTR ExpKey, ExpValue;
MYASSERT (g_WkstaMigInf);
if (InfFindFirstLine (g_WkstaMigInf, S_STRINGMAP, NULL, &is)) {
do {
Key = InfGetStringField (&is, 0);
if (!Key) {
continue;
}
Value = InfGetStringField (&is, 1);
if (!Value) {
continue;
}
if (!InfGetIntField (&is, 2, &SubstringMatch)) {
SubstringMatch = 0;
}
ExpKey = ExpandEnvironmentText (Key);
ExpValue = ExpandEnvironmentText (Value);
AddStringMappingPair (
SubstringMatch ? g_SubStringMap : g_CompleteMatchMap,
ExpKey,
ExpValue
);
FreeText (ExpKey);
FreeText (ExpValue);
} while (InfFindNextLine (&is));
}
InfCleanUpInfStruct (&is);
}