windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/w95upgnt/migmain/migdlls.c

1156 lines
27 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
migdlls.c
Abstract:
The functions in this module are used to support migration DLLs.
Author:
Jim Schmidt (jimschm) 04-Feb-1997
Revision History:
jimschm 23-Sep-1998 Changed to use new IPC mechanism
jimschm 22-Apr-1998 Added USERPROFILE environment variable to MigrateUserNT
jimschm 08-Jan-1997 Added alive event, giving certain DLLs up to 30 minutes
to complete their work.
jimschm 08-Dec-1997 Added support for domains (MigrateUserNT's user name
param is multi-sz)
--*/
#include "pch.h"
#include "migmainp.h"
#ifndef UNICODE
#error UNICODE required
#endif
HANDLE g_AliveEvent;
BOOL
pConnectToDll (
VOID
);
VOID
pDisconnectFromDll (
VOID
);
DWORD
pRunMigrationDll (
VOID
);
DWORD
pCallInitializeNt (
IN PCTSTR WorkingDir,
IN PCTSTR *SourceDirArray,
IN PVOID Reserved,
IN DWORD ReservedBytes
);
DWORD
pCallMigrateUserNt (
IN PCTSTR WorkingDir,
IN PCTSTR UnattendFile,
IN PCTSTR RootKey,
IN PCTSTR Win9xUserName,
IN PCTSTR UserDomain,
IN PCTSTR FixedUserName,
IN PVOID Reserved,
IN DWORD ReservedBytes
);
DWORD
pCallMigrateSystemNt (
IN PCTSTR WorkingDir,
IN PCTSTR UnattendFile,
IN PVOID Reserved,
IN DWORD ReservedBytes
);
static
VOID
pSetCwd (
OUT PTSTR SavedWorkDir,
IN PCTSTR NewWorkDir
);
static TCHAR g_DllPath[MAX_TCHAR_PATH];
static TCHAR g_WorkingDir[MAX_TCHAR_PATH];
static TCHAR g_DllDesc[MAX_TCHAR_PATH];
static VENDORINFOW g_VendorInfo;
static TCHAR g_FixedUser[MAX_USER_NAME];
static TCHAR g_UserOnWin9x[MAX_USER_NAME];
static HINSTANCE g_hLibrary;
P_INITIALIZE_NT InitializeNT;
P_MIGRATE_USER_NT MigrateUserNT;
P_MIGRATE_SYSTEM_NT MigrateSystemNT;
VOID
pLogDllFailure (
IN HWND Parent,
IN UINT MessageId
)
/*++
Routine Description:
pLogDllFailure prepares arguments for the specified MessageId, and then
displays a popup and adds a log entry. This function gives the user
information on what to do when the DLL fails.
Arguments:
Parent - Specifies the parent window handle of the popup, or NULL if no
popup is to be displayed.
MessageId - Specifies the message ID for the error.
Return Value:
None.
--*/
{
PCTSTR FixupPhone;
PCTSTR FixupUrl;
PCTSTR FixupInstructions;
PCTSTR LineBreak = S_EMPTY;
PCTSTR ArgArray[1];
//
// Generate fixup strings
//
if (g_VendorInfo.SupportNumber[0]) {
ArgArray[0] = g_VendorInfo.SupportNumber;
FixupPhone = ParseMessageID (MSG_MIGDLL_SUPPORT_PHONE_FIXUP, ArgArray);
LineBreak = TEXT("\n");
} else {
FixupPhone = S_EMPTY;
}
if (g_VendorInfo.SupportUrl[0]) {
ArgArray[0] = g_VendorInfo.SupportUrl;
FixupUrl = ParseMessageID (MSG_MIGDLL_SUPPORT_URL_FIXUP, ArgArray);
LineBreak = TEXT("\n");
} else {
FixupUrl = S_EMPTY;
}
if (g_VendorInfo.InstructionsToUser[0]) {
ArgArray[0] = g_VendorInfo.InstructionsToUser;
FixupInstructions = ParseMessageID (MSG_MIGDLL_INSTRUCTIONS_FIXUP, ArgArray);
LineBreak = TEXT("\n");
} else {
FixupInstructions = S_EMPTY;
}
//
// Display popup and log the error
//
LOG ((
LOG_ERROR,
(PCSTR) MessageId,
g_DllDesc,
g_VendorInfo.CompanyName,
FixupPhone,
FixupUrl,
FixupInstructions,
LineBreak
));
}
VOID
pSetCwd (
OUT PTSTR SavedWorkDir,
IN PCTSTR NewWorkDir
)
{
GetCurrentDirectory (MAX_TCHAR_PATH, SavedWorkDir);
SetCurrentDirectory (NewWorkDir);
}
BOOL
pCreateEnvironment (
PVOID *BlockPtr
)
{
return CreateEnvironmentBlock (BlockPtr, NULL, FALSE);
}
VOID
pSetEnvironmentBlock (
PVOID Block
)
{
DEBUGMSG ((DBG_VERBOSE, "Block: %s", Block));
}
DWORD
ProcessMigrationDLLs (
DWORD Request
)
{
MEMDB_ENUM e;
DWORD rc;
DWORD Ticks = 0;
if (Request == REQUEST_QUERYTICKS) {
if (MemDbEnumItems (&e, MEMDB_CATEGORY_MIGRATION_DLL)) {
do {
Ticks += TICKS_MIGRATION_DLL;
} while (MemDbEnumNextValue (&e));
}
return Ticks;
}
#ifdef PRERELEASE
if (g_ConfigOptions.DiffMode) {
TakeSnapShot();
}
#endif
if (MemDbEnumItems (&e, MEMDB_CATEGORY_MIGRATION_DLL)) {
do {
//
// Retrieve DLL location and settings
//
// Obtain the DLL name and working directory
if (!MemDbGetEndpointValueEx (
MEMDB_CATEGORY_MIGRATION_DLL,
e.szName,
MEMDB_FIELD_DLL,
g_DllPath)
) {
LOG ((LOG_ERROR, "DLL path for %s is not listed in memdb; DLL not processed", e.szName));
continue; // not expected
}
// Obtain the working directory
if (!MemDbGetEndpointValueEx (
MEMDB_CATEGORY_MIGRATION_DLL,
e.szName,
MEMDB_FIELD_WD,
g_WorkingDir)
) {
LOG ((LOG_ERROR, "Working Directory for %s is not listed in memdb; DLL not processed", e.szName));
continue; // not expected
}
// Obtain a description
if (!MemDbGetEndpointValueEx (
MEMDB_CATEGORY_MIGRATION_DLL,
e.szName,
MEMDB_FIELD_DESC,
g_DllDesc
)) {
StringCopy (g_DllDesc, GetString (MSG_DEFAULT_MIGDLL_DESC));
}
ZeroMemory (&g_VendorInfo, sizeof (g_VendorInfo));
MemDbGetEndpointValueEx (
MEMDB_CATEGORY_MIGRATION_DLL,
e.szName,
MEMDB_FIELD_COMPANY_NAME,
g_VendorInfo.CompanyName
);
MemDbGetEndpointValueEx (
MEMDB_CATEGORY_MIGRATION_DLL,
e.szName,
MEMDB_FIELD_SUPPORT_PHONE,
g_VendorInfo.SupportNumber
);
MemDbGetEndpointValueEx (
MEMDB_CATEGORY_MIGRATION_DLL,
e.szName,
MEMDB_FIELD_SUPPORT_URL,
g_VendorInfo.SupportUrl
);
MemDbGetEndpointValueEx (
MEMDB_CATEGORY_MIGRATION_DLL,
e.szName,
MEMDB_FIELD_SUPPORT_INSTRUCTIONS,
g_VendorInfo.InstructionsToUser
);
//
// Establish connection with migisol.exe
//
if (!pConnectToDll()) {
continue;
}
//
// Tell migisol.exe to load migration DLL and call NT functions
//
rc = pRunMigrationDll();
//
// If not success, return a setup failure
//
if (rc != ERROR_SUCCESS) {
SetLastError (rc);
pLogDllFailure (g_ParentWnd, MSG_MIGDLL_ERROR);
}
//
// Disconnect from migisol.exe and kill the potentially
// stalled process
//
pDisconnectFromDll();
TickProgressBarDelta (TICKS_MIGRATION_DLL);
} while (MemDbEnumNextValue (&e));
} /* if */
#ifdef PRERELEASE
if (g_ConfigOptions.DiffMode) {
CHAR szMigdllDifPath[] = "c:\\migdll.dif";
if (ISPC98()) {
szMigdllDifPath[0] = (CHAR)g_System32Dir[0];
}
GenerateDiffOutputA (szMigdllDifPath, NULL, TRUE);
}
#endif
return ERROR_SUCCESS;
} /* ProcessMigrationDLLs */
BOOL
pConnectToDll (
VOID
)
{
BOOL b = TRUE;
TCHAR MigIsolPath[MAX_TCHAR_PATH];
g_AliveEvent = CreateEvent (NULL, FALSE, FALSE, TEXT("MigDllAlive"));
DEBUGMSG_IF ((!g_AliveEvent, DBG_WHOOPS, "Could not create MigDllAlive event"));
if (!g_ConfigOptions.TestDlls) {
//
// Establish IPC connection
//
wsprintf (MigIsolPath, TEXT("%s\\%s"), g_System32Dir, S_MIGISOL_EXE);
b = OpenIpc (FALSE, MigIsolPath, g_DllPath, g_System32Dir);
if (!b) {
LOG ((LOG_WARNING, "Can't establish IPC connection for %s, wd=%s", g_DllPath, g_System32Dir));
pLogDllFailure (g_ParentWnd, MSG_CREATE_PROCESS_ERROR);
}
} else {
g_hLibrary = LoadLibrary (g_DllPath);
// If it fails, assume the DLL does not want to be loaded
if (!g_hLibrary) {
LOG ((LOG_ERROR, "Cannot load %s", g_DllPath));
return FALSE;
}
// Get proc addresses for NT-side functions
InitializeNT = (P_INITIALIZE_NT) GetProcAddress (g_hLibrary, PLUGIN_INITIALIZE_NT);
MigrateUserNT = (P_MIGRATE_USER_NT) GetProcAddress (g_hLibrary, PLUGIN_MIGRATE_USER_NT);
MigrateSystemNT = (P_MIGRATE_SYSTEM_NT) GetProcAddress (g_hLibrary, PLUGIN_MIGRATE_SYSTEM_NT);
if (!InitializeNT || !MigrateUserNT || !MigrateSystemNT) {
b = FALSE;
}
}
return b;
}
VOID
pDisconnectFromDll (
VOID
)
{
if (g_AliveEvent) {
CloseHandle (g_AliveEvent);
g_AliveEvent = NULL;
}
if (!g_ConfigOptions.TestDlls) {
CloseIpc();
}
else {
if (g_hLibrary) {
FreeLibrary (g_hLibrary);
g_hLibrary = NULL;
}
}
}
BOOL
pGetUserFromIndex (
DWORD Index
)
{
USERPOSITION up;
DWORD rc;
g_UserOnWin9x[0] = 0;
if (Index == INDEX_DEFAULT_USER) {
StringCopy (g_FixedUser, g_DefaultUserName);
} else if (Index == INDEX_LOGON_PROMPT) {
StringCopy (g_FixedUser, S_DOT_DEFAULT);
} else if (Index == INDEX_ADMINISTRATOR) {
StringCopy (g_FixedUser, g_AdministratorStr);
} else {
rc = Win95RegGetFirstUser (&up, g_FixedUser);
if (rc != ERROR_SUCCESS) {
LOG ((LOG_ERROR, "Get User From Index: Win95RegGetFirstUser failed"));
return FALSE;
}
for (Index -= INDEX_MAX ; Win95RegHaveUser(&up) && Index > 0 ; Index--) {
Win95RegGetNextUser (&up, g_FixedUser);
}
if (!Win95RegHaveUser(&up)) {
return FALSE;
}
StringCopy (g_UserOnWin9x, g_FixedUser);
GetFixedUserName (g_FixedUser);
}
if (!g_UserOnWin9x[0]) {
StringCopy (g_UserOnWin9x, g_FixedUser);
}
return TRUE;
}
DWORD
pRunMigrationDll (
VOID
)
{
DWORD rc;
BOOL AbortThisDll;
BOOL UnloadRegKey;
TCHAR UnattendFile[MAX_TCHAR_PATH];
TCHAR RootKey[MAX_REGISTRY_KEY];
TCHAR HiveFile[MAX_TCHAR_PATH];
DWORD Index;
BOOL IsLogonPromptAccount;
PCTSTR SourceDirArray[2];
PCTSTR I386SourceDir;
PCTSTR p;
TCHAR Domain[MAX_USER_NAME];
BOOL Env;
PVOID Block;
HKEY NewHkcu;
LONG MapResult;
//
// Initialize unattend file and root key
//
wsprintf (UnattendFile, TEXT("%s\\system32\\$winnt$.inf"), g_WinDir);
//
// Call InitializeNT
//
if (ISPC98()) {
I386SourceDir = JoinPaths (g_SourceDir, TEXT("NEC98"));
} else {
I386SourceDir = JoinPaths (g_SourceDir, TEXT("I386"));
}
if (!I386SourceDir) {
return GetLastError();
}
SourceDirArray[0] = I386SourceDir;
SourceDirArray[1] = NULL;
rc = pCallInitializeNt (g_WorkingDir, SourceDirArray, NULL, 0);
if (rc != ERROR_SUCCESS) {
return rc;
}
FreePathString (I386SourceDir);
//
// The user loop
//
// For each user, call DLL's MigrateUser function
AbortThisDll = FALSE;
Index = 0;
while (!AbortThisDll) {
if (Index == INDEX_LOGON_PROMPT) {
wsprintf (RootKey, TEXT("HKU\\%s"), S_DOT_DEFAULT);
IsLogonPromptAccount = TRUE;
} else {
wsprintf (RootKey, TEXT("HKU\\%s"), S_TEMP_USER_KEY);
IsLogonPromptAccount = FALSE;
}
if (!pGetUserFromIndex (Index)) {
break;
}
Index++;
//
// If the following lookup fails, it is because the user isn't supposed to
// migrate, or migration failed.
//
if (!IsLogonPromptAccount) {
if (-1 == pSetupStringTableLookUpStringEx (
g_HiveTable,
g_FixedUser,
STRTAB_CASE_INSENSITIVE,
HiveFile,
sizeof (HiveFile)
)
) {
DEBUGMSG ((
DBG_VERBOSE,
"pRunMigrationDll: pSetupStringTableLookUpStringEx could not find name of hive for user %s",
g_FixedUser
));
continue;
}
}
//
// Load NT user hive
//
UnloadRegKey = FALSE;
Env = FALSE;
NewHkcu = NULL;
MapResult = 0;
if (!AbortThisDll) {
// Don't load .default
if (!IsLogonPromptAccount) {
rc = RegUnLoadKey (HKEY_USERS, S_TEMP_USER_KEY);
if (rc != ERROR_SUCCESS) {
DumpOpenKeys ();
SetLastError (rc);
DEBUGMSG_IF ((rc != ERROR_INVALID_PARAMETER, DBG_ERROR, "Error unloading regkey!"));
}
rc = RegLoadKey (HKEY_USERS, S_TEMP_USER_KEY, HiveFile);
if (rc != ERROR_SUCCESS) {
SetLastError(rc);
LOG ((
LOG_ERROR,
"Run Migration Dll: RegLoadKey could not load user hive for %s (%s)",
g_FixedUser,
HiveFile
));
AbortThisDll = TRUE;
} else {
UnloadRegKey = TRUE;
}
}
}
if (!AbortThisDll) {
NewHkcu = OpenRegKeyStr (RootKey);
if (NewHkcu) {
MapResult = RegOverridePredefKey (HKEY_CURRENT_USER, NewHkcu);
if (MapResult != ERROR_SUCCESS) {
LOG ((LOG_ERROR, "Can't override HKCU"));
}
}
Env = pCreateEnvironment (&Block);
if (Env) {
pSetEnvironmentBlock (&Block);
DestroyEnvironmentBlock (&Block);
}
}
// Call loaded DLL's MigrateUser function
if (!AbortThisDll) {
if (g_DomainUserName) {
p = _tcschr (g_DomainUserName, TEXT('\\'));
} else {
p = NULL;
}
if (p) {
StringCopyAB (Domain, g_DomainUserName, p);
} else {
Domain[0] = 0;
}
rc = pCallMigrateUserNt (
g_WorkingDir,
UnattendFile,
RootKey,
IsLogonPromptAccount ? TEXT("") : g_UserOnWin9x,
Domain,
IsLogonPromptAccount ? TEXT("") : g_FixedUser,
NULL,
0
);
if (rc != ERROR_SUCCESS) {
AbortThisDll = TRUE;
}
}
// Restore predefined key
if (NewHkcu && MapResult == ERROR_SUCCESS) {
MapResult = RegOverridePredefKey (HKEY_CURRENT_USER, NULL);
if (MapResult != ERROR_SUCCESS) {
LOG ((LOG_ERROR, "Can't restore HKCU"));
}
CloseRegKey (NewHkcu);
}
// Unload temporary key
if (UnloadRegKey) {
UnloadRegKey = FALSE;
rc = RegUnLoadKey (HKEY_USERS, S_TEMP_USER_KEY);
if (rc != ERROR_SUCCESS) {
DumpOpenKeys ();
SetLastError (rc);
DEBUGMSG_IF ((rc != ERROR_INVALID_PARAMETER, DBG_ERROR, "Error unloading regkey (second case)!"));
}
}
} /* while */
//
// System processing
//
Env = pCreateEnvironment (&Block);
if (Env) {
pSetEnvironmentBlock (&Block);
DestroyEnvironmentBlock (&Block);
}
// Call MigrateSystemNT
if (!AbortThisDll) {
rc = pCallMigrateSystemNt (
g_WorkingDir,
UnattendFile,
NULL,
0
);
if (rc != ERROR_SUCCESS) {
AbortThisDll = TRUE;
}
}
return rc;
}
DWORD
pFinishHandshake (
IN PCTSTR FunctionName
)
{
DWORD TechnicalLogId;
DWORD GuiLogId;
DWORD rc = ERROR_SUCCESS;
BOOL b;
UINT Count = 40; // about 5 minutes
UINT AliveAllowance = 10; // about 30 minutes
do {
//
// No OUT parameters on the NT side, so we don't care
// about the return data
//
b = GetIpcCommandResults (
IPC_GET_RESULTS_NT,
NULL,
NULL,
&rc,
&TechnicalLogId,
&GuiLogId
);
//
// If error code is returned, stuff it in setupact.log
//
if (b && rc != ERROR_SUCCESS) {
LOG ((
LOG_WARNING,
"Migration DLL %s returned %u (0x%08X) in %s",
g_DllDesc,
rc,
rc,
FunctionName
));
}
//
// Loop if no data received, but process is alive
//
if (!b) {
if (!IsIpcProcessAlive()) {
rc = ERROR_NOACCESS;
break;
}
// continue if command was not sent yet but exe is still OK
Count--;
if (Count == 0) {
if (WaitForSingleObject (g_AliveEvent, 0) == WAIT_OBJECT_0) {
DEBUGMSG ((DBG_WARNING, "Alive allowance given to migration DLL"));
AliveAllowance--;
if (AliveAllowance) {
Count = 24; // about 3 minutes
}
}
if (Count == 0) {
rc = ERROR_SEM_TIMEOUT;
break;
}
}
}
} while (!b);
if (b) {
//
// Recognize log messages
//
if (TechnicalLogId) {
//
// LOG message with three args: DllDesc, DllPath, User
//
LOG ((
LOG_ERROR,
(PCSTR) TechnicalLogId,
g_DllDesc,
g_DllPath,
g_FixedUser
));
}
if (GuiLogId) {
LOG ((
LOG_ERROR,
(PCSTR) GuiLogId,
g_DllDesc,
g_DllPath,
g_FixedUser
));
}
}
return rc;
}
DWORD
pCallInitializeNt (
IN PCTSTR WorkingDir,
IN PCTSTR *SourceDirArray,
IN PVOID Reserved,
IN DWORD ReservedBytes
)
{
DWORD rc = ERROR_SUCCESS;
GROWBUFFER GrowBuf = GROWBUF_INIT;
INT Count;
PBYTE BufPtr;
PDWORD ReservedBytesPtr;
TCHAR SavedCwd [MAX_TCHAR_PATH];
if (!g_ConfigOptions.TestDlls) {
__try {
MultiSzAppend (&GrowBuf, WorkingDir);
//
// Prepare multi-sz directory list
//
for (Count = 0 ; SourceDirArray[Count] ; Count++) {
MultiSzAppend (&GrowBuf, SourceDirArray[Count]);
}
MultiSzAppend (&GrowBuf, S_EMPTY);
ReservedBytesPtr = (PDWORD) GrowBuffer (&GrowBuf, sizeof (ReservedBytes));
*ReservedBytesPtr = ReservedBytes;
if (ReservedBytes) {
BufPtr = GrowBuffer (&GrowBuf, ReservedBytes);
CopyMemory (BufPtr, Reserved, ReservedBytes);
}
if (!SendIpcCommand (
IPC_INITIALIZE,
GrowBuf.Buf,
GrowBuf.End
)) {
LOG ((LOG_ERROR, "Call InitializeNT failed to send command"));
rc = GetLastError();
__leave;
}
rc = pFinishHandshake (TEXT("InitializeNT"));
if (rc != ERROR_SUCCESS) {
LOG ((
LOG_ERROR,
"Call InitializeNT failed to complete handshake, rc=%u",
rc
));
}
}
__finally {
FreeGrowBuffer (&GrowBuf);
}
}
else {
pSetCwd (
SavedCwd, // old
WorkingDir // new
);
__try {
//
// Prepare multi-sz directory list
//
for (Count = 0 ; SourceDirArray[Count] ; Count++) {
MultiSzAppend (&GrowBuf, SourceDirArray[Count]);
}
MultiSzAppend (&GrowBuf, S_EMPTY);
rc = InitializeNT (WorkingDir, (PCTSTR) GrowBuf.Buf, Reserved);
FreeGrowBuffer (&GrowBuf);
}
__finally {
SetCurrentDirectory (SavedCwd);
}
}
return rc;
}
DWORD
pCallMigrateUserNt (
IN PCTSTR WorkingDir,
IN PCTSTR UnattendFile,
IN PCTSTR RootKey,
IN PCTSTR Win9xUserName,
IN PCTSTR UserDomain,
IN PCTSTR FixedUserName,
IN PVOID Reserved,
IN DWORD ReservedBytes
)
{
DWORD rc = ERROR_SUCCESS;
GROWBUFFER GrowBuf = GROWBUF_INIT;
PDWORD ReservedBytesPtr;
PVOID BufPtr;
TCHAR SavedCwd [MAX_TCHAR_PATH];
TCHAR UserBuf[MAX_USER_NAME * 3];
PTSTR p;
TCHAR OrgUserProfilePath[MAX_TCHAR_PATH];
TCHAR UserProfilePath[MAX_TCHAR_PATH];
if (FixedUserName[0]) {
GetUserProfilePath (FixedUserName, &p);
StackStringCopy (UserProfilePath, p);
FreePathString (p);
DEBUGMSG ((DBG_VERBOSE, "Profile path for %s is %s", FixedUserName, UserProfilePath));
} else {
UserProfilePath[0] = 0;
}
GetEnvironmentVariable (S_USERPROFILE, OrgUserProfilePath, MAX_TCHAR_PATH);
SetEnvironmentVariable (S_USERPROFILE, UserProfilePath);
if (!g_ConfigOptions.TestDlls) {
__try {
MultiSzAppend (&GrowBuf, UnattendFile);
MultiSzAppend (&GrowBuf, RootKey);
MultiSzAppend (&GrowBuf, Win9xUserName);
MultiSzAppend (&GrowBuf, UserDomain);
MultiSzAppend (&GrowBuf, FixedUserName);
MultiSzAppend (&GrowBuf, UserProfilePath);
ReservedBytesPtr = (PDWORD) GrowBuffer (&GrowBuf, sizeof (ReservedBytes));
*ReservedBytesPtr = ReservedBytes;
if (ReservedBytes) {
BufPtr = GrowBuffer (&GrowBuf, ReservedBytes);
CopyMemory (BufPtr, Reserved, ReservedBytes);
}
if (!SendIpcCommand (
IPC_MIGRATEUSER,
GrowBuf.Buf,
GrowBuf.End
)) {
LOG ((LOG_ERROR, "Call MigrateUserNT failed to send command"));
rc = GetLastError();
__leave;
}
rc = pFinishHandshake (TEXT("MigrateUserNT"));
if (rc != ERROR_SUCCESS) {
LOG ((
LOG_ERROR,
"Call MigrateUserNT failed to complete handshake, rc=%u",
rc
));
}
}
__finally {
FreeGrowBuffer (&GrowBuf);
}
} else {
pSetCwd (
SavedCwd, // old
WorkingDir // new
);
__try {
HINF UnattendHandle;
HKEY UserRegHandle;
UnattendHandle = InfOpenInfFile (UnattendFile);
if (UnattendHandle == INVALID_HANDLE_VALUE) {
__leave;
}
UserRegHandle = OpenRegKeyStr (RootKey);
if (!UserRegHandle) {
rc = GetLastError();
InfCloseInfFile (UnattendHandle);
__leave;
}
//
// Transfer user, user domain and fixed name to a buffer
//
if (Win9xUserName) {
StringCopy (UserBuf, Win9xUserName);
} else {
UserBuf[0] = 0;
}
p = GetEndOfString (UserBuf) + 1;
if (UserDomain) {
StringCopy (p, UserDomain);
} else {
p[0] = 0;
}
p = GetEndOfString (p) + 1;
if (UserDomain) {
StringCopy (p, FixedUserName);
} else {
p[0] = 0;
}
//
// Call the entry point
//
rc = MigrateUserNT (
UnattendHandle,
UserRegHandle,
UserBuf[0] ? UserBuf : NULL,
Reserved
);
CloseRegKey (UserRegHandle);
InfCloseInfFile (UnattendHandle);
}
__finally {
SetCurrentDirectory (SavedCwd);
}
}
SetEnvironmentVariable (S_USERPROFILE, OrgUserProfilePath);
return rc;
}
DWORD
pCallMigrateSystemNt (
IN PCTSTR WorkingDir,
IN PCTSTR UnattendFile,
IN PVOID Reserved,
IN DWORD ReservedBytes
)
{
DWORD rc = ERROR_SUCCESS;
GROWBUFFER GrowBuf = GROWBUF_INIT;
PDWORD ReservedBytesPtr;
PVOID BufPtr;
TCHAR SavedCwd [MAX_TCHAR_PATH];
if (!g_ConfigOptions.TestDlls) {
__try {
MultiSzAppend (&GrowBuf, UnattendFile);
ReservedBytesPtr = (PDWORD) GrowBuffer (&GrowBuf, sizeof (ReservedBytes));
*ReservedBytesPtr = ReservedBytes;
if (ReservedBytes) {
BufPtr = GrowBuffer (&GrowBuf, ReservedBytes);
CopyMemory (BufPtr, Reserved, ReservedBytes);
}
if (!SendIpcCommand (IPC_MIGRATESYSTEM, GrowBuf.Buf, GrowBuf.End)) {
LOG ((LOG_ERROR, "Call MigrateSystemNT failed to send command"));
rc = GetLastError();
__leave;
}
rc = pFinishHandshake (TEXT("MigrateSystemNT"));
if (rc != ERROR_SUCCESS) {
LOG ((
LOG_ERROR,
"Call MigrateSystemNT failed to complete handshake, rc=%u",
rc
));
}
}
__finally {
FreeGrowBuffer (&GrowBuf);
}
}
else {
pSetCwd (
SavedCwd, // old
WorkingDir // new
);
__try {
HINF UnattendHandle;
UnattendHandle = InfOpenInfFile (UnattendFile);
if (UnattendHandle == INVALID_HANDLE_VALUE) {
rc = GetLastError();
__leave;
}
rc = MigrateSystemNT (UnattendHandle, Reserved);
InfCloseInfFile (UnattendHandle);
}
__finally {
SetCurrentDirectory (SavedCwd);
}
}
return rc;
}