mirror of https://github.com/tongzx/nt5src
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.
1310 lines
46 KiB
1310 lines
46 KiB
#include "migeng.h"
|
|
#include "migutil.h"
|
|
#include "miginf.h"
|
|
|
|
extern "C" {
|
|
#include "log.h"
|
|
}
|
|
|
|
|
|
// Globals
|
|
HINF g_GlobalScriptHandle = INVALID_HANDLE_VALUE;
|
|
TCHAR g_HTMLLog[MAX_PATH] = TEXT("");
|
|
TCHAR g_HTMLAppList[MAX_PATH] = TEXT("");
|
|
|
|
extern MigrationWizard* g_migwiz;
|
|
|
|
HRESULT _Engine_UploadVars (MIG_PLATFORMTYPEID idPlatform)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
PCTSTR envVars = NULL;
|
|
PCTSTR envString;
|
|
PTSTR envStringCopy;
|
|
PTSTR p;
|
|
|
|
envVars = (PCTSTR) GetEnvironmentStrings();
|
|
|
|
if (envVars) {
|
|
|
|
envString = envVars;
|
|
|
|
while (*envString)
|
|
{
|
|
p = _tcschr (envString, 0);
|
|
|
|
if (p)
|
|
{
|
|
envStringCopy = (PTSTR) IsmGetMemory (((UINT)(p - envString + 1)) * sizeof (TCHAR));
|
|
|
|
_tcscpy (envStringCopy, envString);
|
|
|
|
p = _tcschr (envStringCopy, TEXT('='));
|
|
|
|
//
|
|
// Get rid of empty environment strings or the dummy env string starting
|
|
// with '='
|
|
//
|
|
if (p && p != envStringCopy)
|
|
{
|
|
*p = 0;
|
|
p = _tcsinc (p);
|
|
|
|
if (p) {
|
|
IsmSetEnvironmentString (idPlatform, S_SYSENVVAR_GROUP, envStringCopy, p);
|
|
}
|
|
}
|
|
IsmReleaseMemory (envStringCopy);
|
|
}
|
|
envString = _tcschr (envString, 0);
|
|
envString ++;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL
|
|
pGetCurrentUser (
|
|
OUT PCTSTR *UserName,
|
|
OUT PCTSTR *UserDomain
|
|
)
|
|
{
|
|
HANDLE token;
|
|
PTOKEN_USER tokenUser = NULL;
|
|
SID_NAME_USE dontCare;
|
|
DWORD bytesRequired;
|
|
TCHAR userName[256];
|
|
DWORD nameSize;
|
|
TCHAR userDomain[256];
|
|
DWORD domainSize;
|
|
|
|
//
|
|
// Open the process token.
|
|
//
|
|
if (!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &token)) {
|
|
return FALSE;
|
|
}
|
|
|
|
bytesRequired = 0;
|
|
if (GetTokenInformation (token, TokenUser, NULL, 0, &bytesRequired)) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) {
|
|
return FALSE;
|
|
}
|
|
|
|
tokenUser = (PTOKEN_USER) IsmGetMemory (bytesRequired);
|
|
|
|
if (!GetTokenInformation (token, TokenUser, tokenUser, bytesRequired, &bytesRequired)) {
|
|
IsmReleaseMemory (tokenUser);
|
|
return FALSE;
|
|
}
|
|
|
|
nameSize = ARRAYSIZE (userName);
|
|
domainSize = ARRAYSIZE (userDomain);
|
|
|
|
ZeroMemory (userName, nameSize);
|
|
ZeroMemory (userDomain, domainSize);
|
|
|
|
LookupAccountSid (
|
|
NULL,
|
|
tokenUser->User.Sid,
|
|
userName,
|
|
&nameSize,
|
|
userDomain,
|
|
&domainSize,
|
|
&dontCare
|
|
);
|
|
|
|
if (UserName) {
|
|
*UserName = IsmDuplicateString (userName);
|
|
}
|
|
|
|
if (UserDomain) {
|
|
*UserDomain = IsmDuplicateString (userDomain);
|
|
}
|
|
|
|
if (tokenUser) {
|
|
IsmReleaseMemory (tokenUser);
|
|
tokenUser = NULL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
pIsUserAdmin (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns TRUE if the caller's process is a member of the
|
|
Administrators local group.
|
|
|
|
Caller is NOT expected to be impersonating anyone and IS expected to be
|
|
able to open their own process and process token.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE - Caller has Administrators local group.
|
|
|
|
FALSE - Caller does not have Administrators local group.
|
|
|
|
--*/
|
|
|
|
{
|
|
HANDLE token;
|
|
DWORD bytesRequired;
|
|
PTOKEN_GROUPS groups;
|
|
BOOL b;
|
|
DWORD i;
|
|
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
|
|
PSID administratorsGroup;
|
|
|
|
//
|
|
// Open the process token.
|
|
//
|
|
if (!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &token)) {
|
|
return FALSE;
|
|
}
|
|
|
|
b = FALSE;
|
|
groups = NULL;
|
|
|
|
//
|
|
// Get group information.
|
|
//
|
|
if (!GetTokenInformation (token, TokenGroups, NULL, 0, &bytesRequired) &&
|
|
GetLastError() == ERROR_INSUFFICIENT_BUFFER
|
|
) {
|
|
|
|
groups = (PTOKEN_GROUPS) HeapAlloc (GetProcessHeap (), 0, bytesRequired);
|
|
b = GetTokenInformation (token, TokenGroups, groups, bytesRequired, &bytesRequired);
|
|
}
|
|
|
|
if (b) {
|
|
|
|
b = AllocateAndInitializeSid (
|
|
&ntAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&administratorsGroup
|
|
);
|
|
|
|
if (b) {
|
|
|
|
//
|
|
// See if the user has the administrator group.
|
|
//
|
|
b = FALSE;
|
|
for (i = 0 ; i < groups->GroupCount ; i++) {
|
|
if (EqualSid (groups->Groups[i].Sid, administratorsGroup)) {
|
|
b = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FreeSid (administratorsGroup);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Clean up and return.
|
|
//
|
|
|
|
if (groups) {
|
|
HeapFree (GetProcessHeap (), 0, groups);
|
|
}
|
|
|
|
CloseHandle (token);
|
|
|
|
return b;
|
|
}
|
|
|
|
typedef BOOL (WINAPI GETDISKFREESPACEEX)(
|
|
LPCTSTR lpDirectoryName,
|
|
PULARGE_INTEGER lpFreeBytesAvailable,
|
|
PULARGE_INTEGER lpTotalNumberOfBytes,
|
|
PULARGE_INTEGER lpTotalNumberOfFreeBytes
|
|
);
|
|
typedef GETDISKFREESPACEEX *PGETDISKFREESPACEEX;
|
|
|
|
BOOL
|
|
pMightHaveDiskSpaceProblem (
|
|
VOID
|
|
)
|
|
{
|
|
TCHAR tempStorage[MAX_PATH];
|
|
PTSTR tempPtr = NULL;
|
|
ULARGE_INTEGER thisMediaMaxSize;
|
|
ULARGE_INTEGER dummy1, dummy2;
|
|
PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
|
|
DWORD sectPerClust;
|
|
DWORD bytesPerSect;
|
|
DWORD freeClusters;
|
|
DWORD totalClusters;
|
|
|
|
if (IsmGetTempStorage (tempStorage, ARRAYSIZE(tempStorage))) {
|
|
|
|
if (tempStorage [0] == TEXT('\\')) {
|
|
// this is a UNC path
|
|
_tcscat (tempStorage, TEXT("\\"));
|
|
tempPtr = _tcschr (tempStorage, TEXT('\\'));
|
|
if (tempPtr) {
|
|
tempPtr = _tcschr (tempStorage, TEXT('\\'));
|
|
if (tempPtr) {
|
|
tempPtr = _tcschr (tempStorage, TEXT('\\'));
|
|
if (tempPtr) {
|
|
tempPtr = _tcschr (tempStorage, TEXT('\\'));
|
|
if (tempPtr) {
|
|
tempPtr ++;
|
|
*tempPtr = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// this is a normal path
|
|
tempPtr = _tcschr (tempStorage, TEXT('\\'));
|
|
if (tempPtr) {
|
|
tempPtr ++;
|
|
*tempPtr = 0;
|
|
}
|
|
}
|
|
|
|
// Find out if GetDiskFreeSpaceEx is supported
|
|
#ifdef UNICODE
|
|
pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress( GetModuleHandle (TEXT("kernel32.dll")), "GetDiskFreeSpaceExW");
|
|
#else
|
|
pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress( GetModuleHandle (TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
|
|
#endif
|
|
if (pGetDiskFreeSpaceEx) {
|
|
if (!pGetDiskFreeSpaceEx (tempStorage, &dummy1, &dummy2, &thisMediaMaxSize)) {
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
if (GetDiskFreeSpace (tempStorage, §PerClust, &bytesPerSect, &freeClusters, &totalClusters)) {
|
|
thisMediaMaxSize.QuadPart = Int32x32To64 ((sectPerClust * bytesPerSect), freeClusters);
|
|
} else {
|
|
DWORD err = GetLastError ();
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if ((thisMediaMaxSize.HighPart == 0) &&
|
|
(thisMediaMaxSize.LowPart < 1024 * 1024)
|
|
) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
pAddExtensions (
|
|
VOID
|
|
)
|
|
{
|
|
HKEY rootKey = NULL;
|
|
LONG result;
|
|
|
|
// open the root key
|
|
result = RegOpenKeyEx (HKEY_CLASSES_ROOT, TEXT(""), 0, KEY_READ, &rootKey);
|
|
|
|
if (result == ERROR_SUCCESS) {
|
|
|
|
UINT index = 0;
|
|
TCHAR extName [MAX_PATH + 1];
|
|
|
|
// enumerate all subkeys
|
|
while (result == ERROR_SUCCESS) {
|
|
|
|
result = RegEnumKey (rootKey, index, extName, MAX_PATH + 1);
|
|
if (result == ERROR_SUCCESS) {
|
|
|
|
// see if this is an extension
|
|
if (_tcsnextc (extName) == TEXT('.')) {
|
|
|
|
HKEY subKey = NULL;
|
|
PCTSTR extNamePtr = NULL;
|
|
|
|
extNamePtr = _tcsinc (extName);
|
|
|
|
if (extNamePtr) {
|
|
|
|
BOOL foundExtension = FALSE;
|
|
INFCONTEXT context;
|
|
|
|
if (SetupFindFirstLine (g_hMigWizInf, TEXT("EXT.Include"), extNamePtr, &context)) {
|
|
foundExtension = TRUE;
|
|
} else if (SetupFindFirstLine (g_hMigWizInf, TEXT("EXT.Exclude"), extNamePtr, &context)) {
|
|
foundExtension = FALSE;
|
|
} else {
|
|
|
|
// open it
|
|
result = RegOpenKeyEx (rootKey, extName, 0, KEY_READ, &subKey);
|
|
if (result == ERROR_SUCCESS) {
|
|
|
|
TCHAR progIdName [MAX_PATH + 1];
|
|
DWORD regType;
|
|
DWORD size = (MAX_PATH + 1) * sizeof (TCHAR);
|
|
|
|
// let's find the ProgId (query the default value)
|
|
result = RegQueryValueEx (subKey, NULL, NULL, ®Type, (PBYTE)progIdName, &size);
|
|
if ((result == ERROR_SUCCESS) && (regType == REG_SZ)) {
|
|
|
|
HKEY progIdKey = NULL;
|
|
|
|
// let's open the prog ID key
|
|
result = RegOpenKeyEx (rootKey, progIdName, 0, KEY_READ, &progIdKey);
|
|
if (result == ERROR_SUCCESS) {
|
|
|
|
HKEY shellKey = NULL;
|
|
|
|
// open the shell subkey
|
|
result = RegOpenKeyEx (progIdKey, TEXT("shell"), 0, KEY_READ, &shellKey);
|
|
if (result == ERROR_SUCCESS) {
|
|
|
|
UINT shellIdx = 0;
|
|
TCHAR cmdName [MAX_PATH + 1];
|
|
|
|
// enumerate all subkeys
|
|
while (result == ERROR_SUCCESS) {
|
|
|
|
result = RegEnumKey (shellKey, shellIdx, cmdName, MAX_PATH + 1);
|
|
if (result == ERROR_SUCCESS) {
|
|
|
|
if ((_tcsicmp (cmdName, TEXT("open")) == 0) ||
|
|
(_tcsicmp (cmdName, TEXT("play")) == 0)
|
|
) {
|
|
|
|
HKEY cmdKey = NULL;
|
|
|
|
// open it
|
|
result = RegOpenKeyEx (shellKey, cmdName, 0, KEY_READ, &cmdKey);
|
|
if (result == ERROR_SUCCESS) {
|
|
|
|
HKEY actionKey = NULL;
|
|
|
|
// open the "command" subkey
|
|
result = RegOpenKeyEx (cmdKey, TEXT("command"), 0, KEY_READ, &actionKey);
|
|
if (result == ERROR_SUCCESS) {
|
|
|
|
TCHAR commandLine [MAX_PATH + 1];
|
|
DWORD size = (MAX_PATH + 1) * sizeof (TCHAR);
|
|
|
|
// let's find the actual command line (query the default value)
|
|
result = RegQueryValueEx (actionKey, NULL, NULL, ®Type, (PBYTE)commandLine, &size);
|
|
if ((result == ERROR_SUCCESS) && ((regType == REG_SZ) || (regType == REG_EXPAND_SZ))) {
|
|
|
|
TCHAR exePath [MAX_PATH + 1];
|
|
PTSTR exeStart = NULL;
|
|
PTSTR exeStop = NULL;
|
|
PTSTR exePtr = NULL;
|
|
INFCONTEXT context;
|
|
BOOL doubleCheck = FALSE;
|
|
|
|
// now we have the command line. Let's see if the module that handle this command
|
|
// is in our IGNORE list
|
|
if (_tcsnextc (commandLine) == TEXT('\"')) {
|
|
exeStart = _tcsinc (commandLine);
|
|
if (exeStart) {
|
|
exeStop = _tcschr (exeStart, TEXT('\"'));
|
|
}
|
|
} else {
|
|
doubleCheck = TRUE;
|
|
exeStart = commandLine;
|
|
exeStop = _tcschr (exeStart, TEXT(' '));
|
|
if (!exeStop) {
|
|
exeStop = _tcschr (exeStart, 0);
|
|
}
|
|
}
|
|
|
|
if (exeStart && exeStop) {
|
|
CopyMemory (exePath, exeStart, (exeStop - exeStart) * sizeof (TCHAR));
|
|
exePath [exeStop - exeStart] = 0;
|
|
|
|
exePtr = _tcsrchr (exePath, TEXT('\\'));
|
|
if (exePtr) {
|
|
exePtr = _tcsinc (exePtr);
|
|
}
|
|
|
|
if (exePtr && !SetupFindFirstLine (g_hMigWizInf, TEXT("EXT.IgnoreEXE"), exePtr, &context)) {
|
|
foundExtension = TRUE;
|
|
}
|
|
}
|
|
if (foundExtension && doubleCheck) {
|
|
exeStop = NULL;
|
|
exeStart = _tcsrchr (commandLine, TEXT('\\'));
|
|
if (exeStart) {
|
|
exeStart = _tcsinc (exeStart);
|
|
if (exeStart) {
|
|
exeStop = _tcschr (exeStart, TEXT(' '));
|
|
if (!exeStop) {
|
|
exeStop = _tcschr (exeStart, 0);
|
|
}
|
|
}
|
|
}
|
|
if (exeStart && exeStop) {
|
|
CopyMemory (exePath, exeStart, (exeStop - exeStart) * sizeof (TCHAR));
|
|
exePath [exeStop - exeStart] = 0;
|
|
|
|
exePtr = _tcsrchr (exePath, TEXT('\\'));
|
|
if (exePtr) {
|
|
exePtr = _tcsinc (exePtr);
|
|
} else {
|
|
exePtr = exePath;
|
|
}
|
|
|
|
if (exePtr && SetupFindFirstLine (g_hMigWizInf, TEXT("EXT.IgnoreEXE"), exePtr, &context)) {
|
|
foundExtension = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RegCloseKey (actionKey);
|
|
}
|
|
RegCloseKey (cmdKey);
|
|
}
|
|
}
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
shellIdx ++;
|
|
}
|
|
RegCloseKey (shellKey);
|
|
}
|
|
RegCloseKey (progIdKey);
|
|
}
|
|
}
|
|
RegCloseKey (subKey);
|
|
}
|
|
}
|
|
if (foundExtension) {
|
|
|
|
//
|
|
// Add the component to the engine, unless it already exists
|
|
//
|
|
// Check if it is already in the tree
|
|
if (!IsmIsComponentSelected (extName + 1, COMPONENT_EXTENSION)) {
|
|
|
|
// Not in the tree; select it if it exists as a component
|
|
if (!IsmSelectComponent (extName + 1, COMPONENT_EXTENSION, TRUE)) {
|
|
|
|
// Not a component; add the component
|
|
IsmAddComponentAlias (
|
|
NULL,
|
|
MASTERGROUP_FILES_AND_FOLDERS,
|
|
extName + 1,
|
|
COMPONENT_EXTENSION,
|
|
FALSE
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
result = ERROR_SUCCESS;
|
|
}
|
|
index ++;
|
|
}
|
|
RegCloseKey (rootKey);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT Engine_Initialize (PCTSTR ptszInfPath,
|
|
BOOL fSource,
|
|
BOOL fNetworkSupport,
|
|
LPTSTR pszUsername,
|
|
PMESSAGECALLBACK pMessageCallback,
|
|
PBOOL pfNetworkDetected)
|
|
{
|
|
static HRESULT hr = E_FAIL;
|
|
static BOOL fDidThis = FALSE;
|
|
ERRUSER_EXTRADATA errExtraData;
|
|
PTSTR iconLibRoot = NULL;
|
|
TCHAR iconLibSrc[MAX_PATH] = TEXT("");
|
|
TCHAR iconLibDest[MAX_PATH] = TEXT("");
|
|
HANDLE iconLibHandle = INVALID_HANDLE_VALUE;
|
|
BOOL iconLibFound = FALSE;
|
|
DWORD err;
|
|
PCTSTR userName = NULL;
|
|
PCTSTR userDomain = NULL;
|
|
PCTSTR currUserName = NULL;
|
|
PCTSTR currUserDomain = NULL;
|
|
ROLLBACK_USER_ERROR rollbackError;
|
|
|
|
if (fDidThis) {
|
|
return hr;
|
|
}
|
|
|
|
__try
|
|
{
|
|
TCHAR szLogPath[MAX_PATH];
|
|
TCHAR szFullLogFile[MAX_PATH];
|
|
DWORD dwLength;
|
|
HRESULT hResult;
|
|
PTSTR pszAppData;
|
|
|
|
fDidThis = TRUE;
|
|
|
|
LogDeleteOnNextInit();
|
|
|
|
pszAppData = GetShellFolderPath (CSIDL_LOCAL_APPDATA, TEXT("LocalAppData"), FALSE, NULL);
|
|
if (pszAppData) {
|
|
wsprintf (szFullLogFile, TEXT("%s\\FASTWiz.log"), pszAppData);
|
|
LogReInit (NULL, NULL, szFullLogFile, NULL );
|
|
wsprintf (g_HTMLLog, TEXT("%s\\FASTWiz.html"), pszAppData);
|
|
wsprintf (g_HTMLAppList, TEXT("%s\\FASTApp.html"), pszAppData);
|
|
LocalFree (pszAppData);
|
|
} else {
|
|
dwLength = GetEnvironmentVariable (TEXT("USERPROFILE"), szLogPath, ARRAYSIZE(szLogPath));
|
|
if (dwLength > 0 && dwLength < (MAX_PATH - 13) )
|
|
{
|
|
wsprintf (szFullLogFile, TEXT("%s\\FASTWiz.log"), szLogPath);
|
|
LogReInit (NULL, NULL, szFullLogFile, NULL );
|
|
wsprintf (g_HTMLLog, TEXT("%s\\FASTWiz.html"), szLogPath);
|
|
wsprintf (g_HTMLAppList, TEXT("%s\\FASTApp.html"), szLogPath);
|
|
}
|
|
else if (g_migwiz->GetWin9X() && GetWindowsDirectory(szLogPath, ARRAYSIZE(szLogPath)))
|
|
{
|
|
wsprintf (szFullLogFile, TEXT("%s\\FASTWiz.log"), szLogPath);
|
|
LogReInit (NULL, NULL, szFullLogFile, NULL);
|
|
wsprintf (g_HTMLLog, TEXT("%s\\FASTWiz.html"), szLogPath);
|
|
wsprintf (g_HTMLAppList, TEXT("%s\\FASTApp.html"), szLogPath);
|
|
}
|
|
else
|
|
{
|
|
LogReInit (NULL, NULL, TEXT("FASTWiz.log"), NULL);
|
|
if (GetCurrentDirectory(ARRAYSIZE(g_HTMLLog), g_HTMLLog))
|
|
{
|
|
PathAppend(g_HTMLLog, TEXT("FASTWiz.html"));
|
|
PathAppend(g_HTMLAppList, TEXT("FASTApp.html"));
|
|
}
|
|
else
|
|
{
|
|
_tcscpy (g_HTMLLog, TEXT("FASTWiz.html"));
|
|
_tcscpy (g_HTMLAppList, TEXT("FASTApp.html"));
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifndef DEBUG
|
|
SuppressAllLogPopups (TRUE);
|
|
#endif
|
|
|
|
if (!IsmInitialize (ptszInfPath, pMessageCallback, NULL))
|
|
{
|
|
__leave;
|
|
}
|
|
|
|
hr = _Engine_UploadVars (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION);
|
|
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
__leave;
|
|
}
|
|
|
|
hr = E_FAIL;
|
|
|
|
if (!IsmSetPlatform (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION))
|
|
{
|
|
__leave;
|
|
}
|
|
|
|
if (!fSource)
|
|
{
|
|
// we will try to copy iconlib.dll from our directory into "Common AppData" directory
|
|
// If we don't succeed, we will try to copy it to "Local AppData". If this one does
|
|
// not succeed we will not set the S_ENV_ICONLIB env variable
|
|
|
|
iconLibSrc [0] = 0;
|
|
GetSystemDirectory (iconLibSrc, ARRAYSIZE(iconLibSrc));
|
|
_tcscat (iconLibSrc, TEXT("\\usmt\\iconlib.dll"));
|
|
|
|
iconLibFound = FALSE;
|
|
|
|
iconLibRoot = GetShellFolderPath (CSIDL_COMMON_APPDATA, TEXT("AppData"), FALSE, NULL);
|
|
if (iconLibRoot) {
|
|
__try {
|
|
_tcscpy (iconLibDest, iconLibRoot);
|
|
_tcscat (iconLibDest, TEXT("\\Microsoft"));
|
|
if (!CreateDirectory (iconLibDest, NULL)) {
|
|
err = GetLastError ();
|
|
if (err != ERROR_ALREADY_EXISTS) {
|
|
__leave;
|
|
}
|
|
}
|
|
_tcscat (iconLibDest, TEXT("\\USMT"));
|
|
if (!CreateDirectory (iconLibDest, NULL)) {
|
|
err = GetLastError ();
|
|
if (err != ERROR_ALREADY_EXISTS) {
|
|
__leave;
|
|
}
|
|
}
|
|
_tcscat (iconLibDest, TEXT("\\iconlib.dll"));
|
|
if (!CopyFile (iconLibSrc, iconLibDest, TRUE)) {
|
|
err = GetLastError ();
|
|
if (err != ERROR_FILE_EXISTS) {
|
|
__leave;
|
|
}
|
|
// we found an iconlib.dll there. The only question now is: can we access it?
|
|
// Let's try to open the file with write mode.
|
|
iconLibHandle = CreateFile (
|
|
iconLibDest,
|
|
GENERIC_READ|GENERIC_WRITE,
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if (iconLibHandle == INVALID_HANDLE_VALUE) {
|
|
// something is wrong, we can't access this file
|
|
err = GetLastError ();
|
|
__leave;
|
|
}
|
|
CloseHandle (iconLibHandle);
|
|
}
|
|
iconLibFound = TRUE;
|
|
}
|
|
__finally {
|
|
LocalFree (iconLibRoot);
|
|
iconLibRoot = NULL;
|
|
}
|
|
}
|
|
|
|
if (!iconLibFound) {
|
|
iconLibRoot = GetShellFolderPath (CSIDL_LOCAL_APPDATA, TEXT("Local AppData"), TRUE, NULL);
|
|
if (iconLibRoot) {
|
|
__try {
|
|
_tcscpy (iconLibDest, iconLibRoot);
|
|
_tcscat (iconLibDest, TEXT("\\Microsoft"));
|
|
if (!CreateDirectory (iconLibDest, NULL)) {
|
|
err = GetLastError ();
|
|
if (err != ERROR_ALREADY_EXISTS) {
|
|
__leave;
|
|
}
|
|
}
|
|
_tcscat (iconLibDest, TEXT("\\USMT"));
|
|
if (!CreateDirectory (iconLibDest, NULL)) {
|
|
err = GetLastError ();
|
|
if (err != ERROR_ALREADY_EXISTS) {
|
|
__leave;
|
|
}
|
|
}
|
|
_tcscat (iconLibDest, TEXT("\\iconlib.dll"));
|
|
if (!CopyFile (iconLibSrc, iconLibDest, TRUE)) {
|
|
err = GetLastError ();
|
|
if (err != ERROR_FILE_EXISTS) {
|
|
__leave;
|
|
}
|
|
}
|
|
iconLibFound = TRUE;
|
|
}
|
|
__finally {
|
|
LocalFree (iconLibRoot);
|
|
iconLibRoot = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the icon lib data
|
|
if (iconLibFound) {
|
|
IsmSetEnvironmentString (PLATFORM_DESTINATION, NULL, S_ENV_ICONLIB, iconLibDest);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Enable HKR migration
|
|
//
|
|
IsmSetEnvironmentFlag (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, S_ENV_HKCU_ON);
|
|
|
|
//
|
|
// Enable files migration
|
|
//
|
|
IsmSetEnvironmentFlag (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, S_ENV_ALL_FILES);
|
|
|
|
//
|
|
// Start ETM modules
|
|
//
|
|
if (!IsmStartEtmModules ()) {
|
|
__leave;
|
|
}
|
|
|
|
// Set up the username
|
|
if (pszUsername)
|
|
{
|
|
IsmSetEnvironmentString (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, TRANSPORT_ENVVAR_HOMENET_TAG, pszUsername);
|
|
}
|
|
|
|
//
|
|
// Start the transport modules
|
|
//
|
|
if (!IsmStartTransport ()) {
|
|
__leave;
|
|
}
|
|
|
|
// If we're network-enabled, start appropriate network stuff
|
|
if (fNetworkSupport)
|
|
{
|
|
// try to detect another machine on network
|
|
MIG_TRANSPORTSTORAGEID transportStorageId = IsmRegisterTransport (S_HOME_NETWORK_TRANSPORT);
|
|
MIG_TRANSPORTID transportId = IsmSelectTransport (transportStorageId, TRANSPORTTYPE_FULL, 0);
|
|
if (!transportId)
|
|
{
|
|
// Network is not supported
|
|
fNetworkSupport = FALSE;
|
|
}
|
|
else
|
|
{
|
|
BOOL fNetworkDetected = FALSE;
|
|
if (!IsmSetTransportStorage (
|
|
fSource ? PLATFORM_SOURCE : PLATFORM_DESTINATION,
|
|
transportId,
|
|
transportStorageId,
|
|
CAPABILITY_AUTOMATED,
|
|
NULL,
|
|
NULL,
|
|
pfNetworkDetected
|
|
))
|
|
{
|
|
// Network is not supported
|
|
fNetworkSupport = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
if (!fSource) {
|
|
// now let's take care of the rollback if necessary
|
|
__try {
|
|
// get the current user name and domain
|
|
if ((!pGetCurrentUser (&currUserName, &currUserDomain)) ||
|
|
(!currUserName) ||
|
|
(!currUserDomain)
|
|
) {
|
|
__leave;
|
|
}
|
|
|
|
if (IsmSetRollbackJournalType (TRUE)) {
|
|
if (IsmDoesRollbackDataExist (&userName, &userDomain, NULL, NULL, NULL)) {
|
|
if ((StrCmpI (userName, currUserName) == 0) &&
|
|
(StrCmpI (userDomain, currUserDomain) == 0)
|
|
) {
|
|
// disable cancel, write the UNDO message in the UI
|
|
DisableCancel ();
|
|
PostMessageForWizard (WM_USER_ROLLBACK, 0, 0);
|
|
IsmRollback ();
|
|
__leave;
|
|
}
|
|
if (pIsUserAdmin ()) {
|
|
// disable cancel, write the UNDO message in the UI
|
|
DisableCancel ();
|
|
PostMessageForWizard (WM_USER_ROLLBACK, 0, 0);
|
|
IsmRollback ();
|
|
__leave;
|
|
}
|
|
// display the message, we can't run
|
|
rollbackError.UserName = userName;
|
|
rollbackError.UserDomain = userDomain;
|
|
IsmSendMessageToApp (ISMMESSAGE_EXECUTE_ROLLBACK, (ULONG_PTR)&rollbackError);
|
|
IsmPreserveJournal (TRUE);
|
|
hr = E_FAIL;
|
|
__leave;
|
|
}
|
|
}
|
|
|
|
if (IsmSetRollbackJournalType (FALSE)) {
|
|
if (IsmDoesRollbackDataExist (NULL, NULL, NULL, NULL, NULL)) {
|
|
// disable cancel, write the UNDO message in the UI
|
|
DisableCancel ();
|
|
PostMessageForWizard (WM_USER_ROLLBACK, 0, 0);
|
|
IsmRollback ();
|
|
__leave;
|
|
}
|
|
}
|
|
}
|
|
__finally {
|
|
if (currUserName) {
|
|
IsmReleaseMemory (currUserName);
|
|
currUserName = NULL;
|
|
}
|
|
|
|
if (currUserDomain) {
|
|
IsmReleaseMemory (currUserDomain);
|
|
currUserDomain = NULL;
|
|
}
|
|
|
|
if (userName) {
|
|
IsmReleaseMemory (userName);
|
|
userName = NULL;
|
|
}
|
|
if (userDomain) {
|
|
IsmReleaseMemory (userDomain);
|
|
userDomain = NULL;
|
|
}
|
|
}
|
|
|
|
// finally let's find a place for the rollback journal
|
|
if (SUCCEEDED(hr)) {
|
|
if ((!IsmSetRollbackJournalType (TRUE)) ||
|
|
(!IsmCanWriteRollbackJournal ())
|
|
) {
|
|
if ((!IsmSetRollbackJournalType (FALSE)) ||
|
|
(!IsmCanWriteRollbackJournal ())
|
|
) {
|
|
// log a warning - we can't create a rollback journal
|
|
// BUGBUG - log the warning
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr)) {
|
|
if (fSource) {
|
|
pAddExtensions ();
|
|
}
|
|
}
|
|
}
|
|
__finally
|
|
{
|
|
// Empty
|
|
}
|
|
|
|
if (FAILED(hr)) {
|
|
if (pMightHaveDiskSpaceProblem ()) {
|
|
errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
|
|
} else {
|
|
errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
|
|
}
|
|
errExtraData.ErrorArea = ERRUSER_AREA_INIT;
|
|
errExtraData.ObjectTypeId = 0;
|
|
errExtraData.ObjectName = NULL;
|
|
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
|
|
Engine_Terminate();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT Engine_RegisterProgressBarCallback(PROGRESSBARFN pProgressCallback, ULONG_PTR pArg)
|
|
{
|
|
static HRESULT hr = E_FAIL;
|
|
if (FAILED(hr)) // only register once
|
|
{
|
|
hr = IsmRegisterProgressBarCallback(pProgressCallback, pArg) ? S_OK : E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT Engine_AppendScript(BOOL fSource, PCTSTR ptszInfPath)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
ENVENTRY_STRUCT infHandleStruct;
|
|
|
|
if (g_GlobalScriptHandle == INVALID_HANDLE_VALUE)
|
|
{
|
|
g_GlobalScriptHandle = SetupOpenInfFile (ptszInfPath, NULL, INF_STYLE_WIN4 | INF_STYLE_OLDNT, NULL);
|
|
if (g_GlobalScriptHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (SetupOpenAppendInfFile (ptszInfPath, g_GlobalScriptHandle, NULL))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IsmAppendEnvironmentMultiSz (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, S_INF_FILE_MULTISZ, ptszInfPath);
|
|
infHandleStruct.Type = ENVENTRY_BINARY;
|
|
infHandleStruct.EnvBinaryData = (PBYTE)(&g_GlobalScriptHandle);
|
|
infHandleStruct.EnvBinaryDataSize = sizeof (HINF);
|
|
IsmSetEnvironmentValue (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, S_GLOBAL_INF_HANDLE, &infHandleStruct);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL _LocalPathIsRoot(LPTSTR pszPath)
|
|
{
|
|
return (PathIsRoot(pszPath) ||
|
|
((2 == lstrlen(pszPath)) &&
|
|
((pszPath[0] >= TEXT('A') && pszPath[0] <= TEXT('Z')) || (pszPath[0] >= TEXT('a') && pszPath[0] <= TEXT('z'))) &&
|
|
(pszPath[1] == TEXT(':'))));
|
|
}
|
|
|
|
HRESULT Engine_StartTransport (BOOL fSource, LPTSTR pszPath, PBOOL ImageIsValid, PBOOL ImageExists)
|
|
{
|
|
ERRUSER_EXTRADATA errExtraData;
|
|
HRESULT hr = E_FAIL;
|
|
MIG_TRANSPORTID transportId;
|
|
MIG_TRANSPORTSTORAGEID transportStorageId;
|
|
LPTSTR pszStoragePath;
|
|
TCHAR szRootPath[4] = TEXT("A:\\");
|
|
PTSTR lpExpStore = NULL;
|
|
BOOL retryTrans = TRUE;
|
|
BOOL tryUncFirst = (!fSource);
|
|
TCHAR szSerialStr[] = TEXT("COM");
|
|
TCHAR szParallelStr[] = TEXT("LPT");
|
|
|
|
if (ImageIsValid) {
|
|
*ImageIsValid = FALSE;
|
|
}
|
|
if (ImageExists) {
|
|
*ImageExists = FALSE;
|
|
}
|
|
|
|
__try
|
|
{
|
|
if (pszPath) {
|
|
|
|
//
|
|
// Normal transport
|
|
//
|
|
|
|
//
|
|
// Pick the specified transport
|
|
//
|
|
|
|
lpExpStore = (PTSTR)IsmExpandEnvironmentString (PLATFORM_SOURCE, S_SYSENVVAR_GROUP, pszPath, NULL);
|
|
|
|
if (!lpExpStore) {
|
|
// BUGBUG - fatal error
|
|
__leave;
|
|
}
|
|
|
|
while (retryTrans) {
|
|
if (_IsRemovableOrCDDrive(lpExpStore[0]) && _LocalPathIsRoot(lpExpStore) && (!tryUncFirst))
|
|
{
|
|
transportStorageId = IsmRegisterTransport (S_REMOVABLE_MEDIA_TRANSPORT);
|
|
szRootPath[0] = lpExpStore[0];
|
|
pszStoragePath = szRootPath;
|
|
}
|
|
else if ((_tcsnicmp (pszPath, szSerialStr, (sizeof (szSerialStr) / sizeof (TCHAR)) - 1) == 0) ||
|
|
(_tcsnicmp (pszPath, szParallelStr, (sizeof (szParallelStr) / sizeof (TCHAR)) - 1) == 0)
|
|
)
|
|
{
|
|
transportStorageId = IsmRegisterTransport (S_DIRECT_CABLE_TRANSPORT);
|
|
pszStoragePath = lpExpStore;
|
|
}
|
|
else
|
|
{
|
|
transportStorageId = IsmRegisterTransport (S_RELIABLE_STORAGE_TRANSPORT);
|
|
pszStoragePath = lpExpStore;
|
|
}
|
|
|
|
transportId = IsmSelectTransport (transportStorageId, TRANSPORTTYPE_FULL, 0);
|
|
if (!transportId)
|
|
{
|
|
// BUGBUG - fatal error
|
|
__leave;
|
|
}
|
|
|
|
if (!IsmSetTransportStorage (
|
|
fSource ? PLATFORM_SOURCE : PLATFORM_DESTINATION,
|
|
transportId,
|
|
transportStorageId,
|
|
CAPABILITY_COMPRESSED,
|
|
pszStoragePath,
|
|
ImageIsValid,
|
|
ImageExists
|
|
))
|
|
{
|
|
if (tryUncFirst) {
|
|
tryUncFirst = FALSE;
|
|
continue;
|
|
}
|
|
// BUGBUG - fatal error
|
|
__leave;
|
|
}
|
|
if ((!fSource && ImageIsValid && !(*ImageIsValid)) ||
|
|
(!fSource && ImageExists && !(*ImageExists))
|
|
) {
|
|
if (tryUncFirst) {
|
|
tryUncFirst = FALSE;
|
|
continue;
|
|
}
|
|
}
|
|
retryTrans = FALSE;
|
|
}
|
|
|
|
IsmReleaseMemory (lpExpStore);
|
|
lpExpStore = NULL;
|
|
|
|
} else {
|
|
// network transport
|
|
transportStorageId = IsmRegisterTransport (S_HOME_NETWORK_TRANSPORT);
|
|
transportId = IsmSelectTransport (transportStorageId, TRANSPORTTYPE_FULL, 0);
|
|
if (!transportId)
|
|
{
|
|
// BUGBUG - fatal error
|
|
__leave;
|
|
}
|
|
if (!IsmSetTransportStorage (
|
|
fSource ? PLATFORM_SOURCE : PLATFORM_DESTINATION,
|
|
transportId,
|
|
transportStorageId,
|
|
CAPABILITY_AUTOMATED,
|
|
NULL,
|
|
ImageIsValid,
|
|
ImageExists
|
|
))
|
|
{
|
|
// BUGBUG - fatal error
|
|
__leave;
|
|
}
|
|
|
|
}
|
|
hr = S_OK;
|
|
}
|
|
__finally
|
|
{
|
|
if (lpExpStore) {
|
|
IsmReleaseMemory (lpExpStore);
|
|
lpExpStore = NULL;
|
|
}
|
|
}
|
|
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
if (pMightHaveDiskSpaceProblem ()) {
|
|
errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
|
|
} else {
|
|
errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
|
|
}
|
|
errExtraData.ErrorArea = ERRUSER_AREA_SAVE;
|
|
errExtraData.ObjectTypeId = 0;
|
|
errExtraData.ObjectName = NULL;
|
|
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT Engine_Parse ()
|
|
{
|
|
ERRUSER_EXTRADATA errExtraData;
|
|
|
|
//
|
|
// Execute the preparsing
|
|
//
|
|
if (!IsmExecute (EXECUTETYPE_EXECUTESOURCE_PARSING))
|
|
{
|
|
if (pMightHaveDiskSpaceProblem ()) {
|
|
errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
|
|
} else {
|
|
errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
|
|
}
|
|
errExtraData.ErrorArea = ERRUSER_AREA_GATHER;
|
|
errExtraData.ObjectTypeId = 0;
|
|
errExtraData.ObjectName = NULL;
|
|
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT Engine_SelectComponentSet (UINT uSelectionGroup)
|
|
{
|
|
MIG_COMPONENT_ENUM mce;
|
|
BOOL bSelected;
|
|
BOOL bDefaultSetting;
|
|
BOOL bDefaultFile;
|
|
BOOL bCallIsm;
|
|
TCHAR szComponentToSelect[256];
|
|
UINT uGroupInUi;
|
|
|
|
// uSelectionGroup is either
|
|
// MIGINF_SELECT_OOBE
|
|
// MIGINF_SELECT_SETTINGS
|
|
// MIGINF_SELECT_FILES
|
|
// MIGINF_SELECT_BOTH
|
|
|
|
//
|
|
// Enable all components for the type. Use the migwiz.inf to identify components
|
|
// that are part of the single floppy or multi floppy configuration. Remove all
|
|
// customized components.
|
|
//
|
|
// This loop pings the component name (such as RAS) or the alias name (such as DOC)
|
|
// to determine if the component should be selected. It is optimized to stop pinging
|
|
// after the component becomes selected (because a component might have many aliases).
|
|
// We rely on the mce.Instance member, which will always be sequential, and will
|
|
// always be 1 for the first alias of a component.
|
|
//
|
|
|
|
IsmRemoveAllUserSuppliedComponents();
|
|
|
|
IsmSelectMasterGroup (MASTERGROUP_ALL, FALSE);
|
|
|
|
if (IsmEnumFirstComponent (&mce, COMPONENTENUM_ALL_ALIASES, 0))
|
|
{
|
|
|
|
bSelected = FALSE;
|
|
|
|
do {
|
|
|
|
bCallIsm = FALSE;
|
|
|
|
if (mce.GroupId == COMPONENT_EXTENSION) {
|
|
bSelected = IsComponentEnabled (uSelectionGroup, TEXT("EXTENSIONS"));
|
|
bCallIsm = bSelected;
|
|
} else {
|
|
if (mce.Instance == 1)
|
|
{
|
|
bSelected = IsComponentEnabled (uSelectionGroup, mce.ComponentString);
|
|
bCallIsm = bSelected;
|
|
}
|
|
if (!bSelected)
|
|
{
|
|
bSelected = IsComponentEnabled (uSelectionGroup, mce.LocalizedAlias);
|
|
bCallIsm = bSelected;
|
|
}
|
|
}
|
|
if (bCallIsm)
|
|
{
|
|
IsmSelectComponent (mce.LocalizedAlias, mce.GroupId, bSelected);
|
|
mce.SkipToNextComponent = TRUE;
|
|
}
|
|
|
|
} while (IsmEnumNextComponent (&mce));
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT Engine_Execute(BOOL fSource)
|
|
{
|
|
ERRUSER_EXTRADATA errExtraData;
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
__try {
|
|
if (fSource)
|
|
{
|
|
//
|
|
// Enumerate the system, gather data and analyze
|
|
//
|
|
if (!IsmExecute (EXECUTETYPE_EXECUTESOURCE))
|
|
{
|
|
if (pMightHaveDiskSpaceProblem ()) {
|
|
errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
|
|
} else {
|
|
errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
|
|
}
|
|
errExtraData.ErrorArea = ERRUSER_AREA_GATHER;
|
|
errExtraData.ObjectTypeId = 0;
|
|
errExtraData.ObjectName = NULL;
|
|
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// Finally, save the data
|
|
//
|
|
if (!IsmSave ()) {
|
|
if (pMightHaveDiskSpaceProblem ()) {
|
|
errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
|
|
} else {
|
|
errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
|
|
}
|
|
errExtraData.ErrorArea = ERRUSER_AREA_SAVE;
|
|
errExtraData.ObjectTypeId = 0;
|
|
errExtraData.ObjectName = NULL;
|
|
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
|
|
__leave;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Try and retrieve the data
|
|
//
|
|
if (!IsmLoad ()) {
|
|
if (pMightHaveDiskSpaceProblem ()) {
|
|
errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
|
|
} else {
|
|
errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
|
|
}
|
|
errExtraData.ErrorArea = ERRUSER_AREA_LOAD;
|
|
errExtraData.ObjectTypeId = 0;
|
|
errExtraData.ObjectName = NULL;
|
|
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// Apply saved state
|
|
//
|
|
if (!IsmExecute (EXECUTETYPE_EXECUTEDESTINATION)) {
|
|
if (pMightHaveDiskSpaceProblem ()) {
|
|
errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
|
|
} else {
|
|
errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
|
|
}
|
|
errExtraData.ErrorArea = ERRUSER_AREA_RESTORE;
|
|
errExtraData.ObjectTypeId = 0;
|
|
errExtraData.ObjectName = NULL;
|
|
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
|
|
IsmRollback();
|
|
__leave;
|
|
}
|
|
|
|
DisableCancel();
|
|
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
__finally {
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT Engine_Cancel ()
|
|
{
|
|
IsmSetCancel();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT Engine_Terminate ()
|
|
{
|
|
static BOOL fDidThis = FALSE;
|
|
|
|
if (fDidThis) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
fDidThis = TRUE;
|
|
|
|
IsmTerminate();
|
|
|
|
if (g_GlobalScriptHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
SetupCloseInfFile (g_GlobalScriptHandle);
|
|
g_GlobalScriptHandle = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|