|
|
// This is the migration dll for NT5 upgrades.
// As per the Migration Extension Interface of NT5 Setup, this DLL needs to
// implement the folowing six functions:
// QueryVersion
// Initialize9x
// MigrateUser9x (called once for every user)
// MigrateSystem9x
// InitializeNT
// MigrateUserNT (called once for every user)
// MigrateSystemNT
//
// Written : ShabbirS (5/7/99)
// Revision:
//
#include "pch.h"
#include <ole2.h>
#ifdef __cplusplus
extern "C" { #endif
#include <excppkg.h>
#ifdef __cplusplus
} #endif /* __cplusplus */
#include "sdsutils.h"
#include "advpub.h"
#include "migrate.h"
#include "utils.h"
#include "resource.h"
// Constants:
#define CP_USASCII 1252
#define END_OF_CODEPAGES -1
// Globals that are passed back to Setup.
//////////////////////////////////////////
// Vendor Info:
VENDORINFO g_VendorInfo = { "Microsoft Corporation", " ", "http://www.microsoft.com/support", "Please contact Microsoft Technical Support for assistance with this problem. "};
// Product ID:
char g_cszProductID[] = "Microsoft Internet Explorer";
// Version number of this Migration Dll
UINT g_uVersion = 3;
// Array of integers specifying the CodePages we use. (Terminated with -1)
int g_rCodePages[] = {CP_USASCII, END_OF_CODEPAGES};
// Multi-SZ ie double Null terminated list of strings.
char *g_lpNameBuf = NULL; DWORD g_dwNameBufSize = 0; char *g_lpWorkingDir = NULL; char *g_lpSourceDirs = NULL; char *g_lpMediaDir = NULL;
char g_szMigrateInf[MAX_PATH]; char g_szPrivateInf[MAX_PATH];
LONG CALLBACK QueryVersion( OUT LPCSTR *ProductID, OUT LPUINT DllVersion, OUT LPINT *CodePageArray, OPTIONAL OUT LPCSTR *ExeNameBuf, OPTIONAL OUT PVENDORINFO *VendorInfo ) { // NOTE: There is timing restriction on the return from this function
// So keep this as short and sweet as possible.
VENDORINFO myVendorInfo; LONG lRet = ERROR_SUCCESS;
AppendString(&g_lpNameBuf, &g_dwNameBufSize, cszRATINGSFILE); AppendString(&g_lpNameBuf, &g_dwNameBufSize, cszIEXPLOREFILE);
// Pass back to Setup the product name.
*ProductID = g_cszProductID;
// Pass back to Setup the version number of this DLL.
*DllVersion = g_uVersion;
// We will use English messages only but don't specify a code page or
// the migration dll won't run on alternate code pages.
*CodePageArray = NULL;
// Pass back to Setup the list of files we want detected on this system.
*ExeNameBuf = g_lpNameBuf;
// Pass back the VendorInfo.
if (LoadString(g_hInstance, IDS_COMPANY, myVendorInfo.CompanyName, sizeof(myVendorInfo.CompanyName)) == 0) lstrcpy(myVendorInfo.CompanyName, "Microsoft Corporation");
if (LoadString(g_hInstance, IDS_SUPPORTNUMBER, myVendorInfo.SupportNumber, sizeof(myVendorInfo.SupportNumber)) == 0) lstrcpy(myVendorInfo.SupportNumber, " ");
if (LoadString(g_hInstance, IDS_SUPPORTURL, myVendorInfo.SupportUrl, sizeof(myVendorInfo.SupportUrl)) == 0) lstrcpy(myVendorInfo.SupportUrl, "http://www.microsoft.com/support");
if (LoadString(g_hInstance, IDS_INSTRUCTIONS, myVendorInfo.InstructionsToUser, sizeof(myVendorInfo.InstructionsToUser)) == 0) lstrcpy(myVendorInfo.InstructionsToUser, "Please contact Microsoft Technical Support for assistance with this problem. ");
*VendorInfo = &myVendorInfo;
#ifdef DEBUG
char szDebugMsg[MAX_PATH*3]; wsprintf(szDebugMsg,"IE6:ProductID: %s \r\n", *ProductID); SetupLogError(szDebugMsg, LogSevInformation); #endif
return lRet;
}
LONG CALLBACK Initialize9x( IN LPCSTR WorkingDir, IN LPCSTR SourceDirs, IN LPCSTR MediaDirs ) { // Called by NT Setup if QUeryVersion returned SUCCESS
// At this point we have been relocated to some specific location
// on the local drive by the Setup process.
INT len;
// Keep track of our new location (ie. the Working Directory).
// NT Setup will create the "MIGRATE.INF" file in this dir and use that
// to exchange info with us.
// Also we can use this Dir for saving our private stuff. NT Setup will
// ensure this folder stays till end of NT Migration. After that it will
// be cleaned.
len = lstrlen(WorkingDir) + 1; g_lpWorkingDir = (char *) LocalAlloc(LPTR,sizeof(char)*len);
if (!g_lpWorkingDir) { return GetLastError(); }
CopyMemory(g_lpWorkingDir, WorkingDir, len);
len = lstrlen(MediaDirs) + 1; g_lpMediaDir = (char *) LocalAlloc(LPTR,sizeof(char)*len);
if (!g_lpMediaDir) { return GetLastError(); }
CopyMemory(g_lpMediaDir, MediaDirs, len);
// Also keep track of the NT installation files path (ie Sources Dir).
// NOTE: Right now we don't need it, so skip doing it.
// Generate the path names to Migrate.inf and the private files
// (private.inf) that we need
GenerateFilePaths(); // If NT Setup has succeeded in getting path to Ratings.Pol, it implies
// Ratings information exists. Enable our private marker to do the right
// thing in MigrateSystemNT phase.
if (GetRatingsPathFromMigInf(NULL)) { // Put a marker in PRIVATE.INF so that MigrateSystemNT phase knows
// that it has to munge the Rating.
// Private.Inf does not exist at this point so why this check!!!
// if (GetFileAttributes(g_szPrivateInf) != 0xffffffff)
WritePrivateProfileString(cszIEPRIVATE, cszRATINGS, "Yes", g_szPrivateInf); // Flush the cached entries to disk.
WritePrivateProfileString(NULL,NULL,NULL,g_szPrivateInf);
#ifdef DEBUG
SetupLogError("IE6: Created PRIVATE.INF\r\n", LogSevInformation); #endif
}
return ERROR_SUCCESS; }
LONG CALLBACK MigrateUser9x( IN HWND ParentWnd, IN LPCSTR UnattendFile, IN HKEY UserRegKey, IN LPCSTR UserName, LPVOID Reserved ) { // This function is called by NT Setup for each user.
// Currently for the Ratings scenario, we don't need any PerUser action.
#ifdef DEBUG
SetupLogError("IE6: Skipping MigrateUser9x \r\n", LogSevInformation); #endif
return ERROR_SUCCESS;
}
LONG CALLBACK MigrateSystem9x( IN HWND ParentWnd, IN LPCSTR AnswerFile, LPVOID Reserved ) { // This function is called once by NT Setup to let us save System wide info.
//
// we are writing the "incompatibility report here if IE5.5 is installed and
// the user does not have the full migration pack installed.
//
char szCab[MAX_PATH]; WORD wVer[4]; char szBuf[MAX_PATH];
// Check if we have the full exception pack which re-installs IE5.5
// NOTE: g_lpMediaDir is the location where the migration dll was installed/registered
// This is the same location where the INF is.
lstrcpy(szCab, g_lpMediaDir); AddPath(szCab, "ieexinst.inf"); if (GetPrivateProfileString("Info", "Version", "", szBuf , MAX_PATH, szCab) != 0) { // Convert version
ConvertVersionString( szBuf, wVer, '.' );
if ((wVer[0] == 5) && (wVer[1] == 50)) { // We don't have the full exception pack.
// generate the "incompatibility report"
// g_szMigrateInf
lstrcpy(szBuf, g_lpMediaDir); GetParentDir(szBuf);
if (LoadString(g_hInstance, IDS_INCOMPAT_MSG, szCab, sizeof(szCab))) { WritePrivateProfileString(cszMIGINF_INCOMPAT_MSG, g_cszProductID, szCab, g_szMigrateInf); WritePrivateProfileString(g_cszProductID, szBuf, "Report", g_szMigrateInf); WritePrivateProfileString(NULL,NULL,NULL,g_szMigrateInf); } } }
WritePrivateProfileString(cszMIGINF_HANDLED, "HKLM\\Software\\Microsoft\\Active Setup\\ClsidFeature", "Registry", g_szMigrateInf); WritePrivateProfileString(cszMIGINF_HANDLED, "HKLM\\Software\\Microsoft\\Active Setup\\FeatureComponentID", "Registry", g_szMigrateInf); WritePrivateProfileString(cszMIGINF_HANDLED, "HKLM\\Software\\Microsoft\\Active Setup\\MimeFeature", "Registry", g_szMigrateInf); WritePrivateProfileString(NULL,NULL,NULL,g_szMigrateInf); #ifdef DEBUG
SetupLogError("IE6: MigrateSystem9x \r\n", LogSevInformation); #endif
return ERROR_SUCCESS; }
LONG CALLBACK InitializeNT ( IN LPCWSTR WorkingDirectory, IN LPCWSTR SourceDirectories, LPVOID Reserved ) { INT Length; LPCWSTR p;
//
// Save our working directory and source directory. We
// convert UNICODE to ANSI, and we use the system code page.
//
//
// Compute length of source directories
//
p = SourceDirectories; while (*p) { p = wcschr (p, 0) + 1; } p++; Length = (p - SourceDirectories) / sizeof (WCHAR);
//
// Convert the directories from UNICODE to DBCS. This DLL is
// compiled in ANSI.
//
g_lpWorkingDir = (LPSTR) LocalAlloc(LPTR, MAX_PATH); if (!g_lpWorkingDir) { return GetLastError(); }
WideCharToMultiByte ( CP_ACP, 0, WorkingDirectory, -1, g_lpWorkingDir, MAX_PATH, NULL, NULL );
// Also save the SourceDirectories that points to the Windows
// NT media (i.e. e:\i386) and optional directories specified on
// the WINNT32 command line. Not used currently, so skip.
// Now generate the derived file names
GenerateFilePaths();
#ifdef DEBUG
SetupLogError("IE6: Done InitializeNT \r\n", LogSevInformation); #endif
return ERROR_SUCCESS; }
LONG CALLBACK MigrateUserNT ( IN HINF UnattendInfHandle, IN HKEY UserRegKey, IN LPCWSTR UserName, LPVOID Reserved ) { // No per-user settings for Ratings upgrade.
#ifdef DEBUG
SetupLogError("IE6: Skipping MigrateUserNT \r\n", LogSevInformation); #endif
return ERROR_SUCCESS; }
#define PACKAGE_GUID "{89820200-ECBD-11cf-8B85-00AA005B4383}"
#define PACKAGE_DIRECTORY "%windir%\\RegisteredPackages\\"
LONG CALLBACK MigrateSystemNT ( IN HINF UnattendInfHandle, LPVOID Reserved ) { // NOTE: This phase MUST finish in 60 seconds or will be terminated.
// Check if our PRIVATE.INF exists and perform relevant actions based on its contents.
CHAR szBuffer[3+10];
if (GetFileAttributes(g_szPrivateInf) != 0xffffffff) { GetPrivateProfileString(cszIEPRIVATE, cszRATINGS, "", szBuffer, sizeof(szBuffer), g_szPrivateInf); if (lstrcmpi(szBuffer,"Yes")==0) { UpgradeRatings(); SetupLogError("IE Migration: Upgraded Ratings info.\r\n", LogSevInformation); } } else { SetupLogError("IE Migration: No Rating migration. Private.Inf does not exist.\r\n",LogSevInformation); }
#if 0
// Do the W2K IE5.5 migration work here.
// 1. Copy all files from the IE location to the registered migration pack location
// 2. Register the migration pack
SETUP_OS_COMPONENT_DATA ComponentData,cd; SETUP_OS_EXCEPTION_DATA ExceptionData,ed; GUID MyGuid; PWSTR GuidString; PSTR t; BOOL bContinue = FALSE; WCHAR szMsg[1024]; char szPath[MAX_PATH]; LPWSTR pszwPath; WORD wVer[4]; char szBuf[MAX_PATH]; char szInf[MAX_PATH]; char szGUID[MAX_PATH]; char szCab[MAX_PATH]; char szDir[MAX_PATH]; #ifdef DEBUG
char sz[1024]; #endif
HRESULT hr;
char szCabs[1024]; LPSTR pCab = NULL;
// Get the INF which is installed in the W2K folder.
// This INF tells us the info about the IE exception pack.
// g_lpWorkingDir contains all fiels and sub folders which are in the same place
// as the registerd migration dll. Since we install the files in the same folder, we can use it.
lstrcpy(szInf, g_lpWorkingDir); AddPath(szInf, "ieexinst.inf"); #ifdef DEBUG
wsprintf(sz, "IE exception INF :%s:\r\n", szInf); SetupLogError(sz,LogSevInformation); #endif
if (GetFileAttributes(szInf) != (DWORD)-1) { // Get the GUID
if (GetPrivateProfileString("Info", "ComponentId", "", szGUID, sizeof(szGUID), szInf) == 0) lstrcpy(szGUID, PACKAGE_GUID); ExpandEnvironmentStrings( PACKAGE_DIRECTORY, szDir, sizeof(szDir)); if (GetFileAttributes(szDir) == (DWORD)-1) CreateDirectory( szDir, NULL ); AddPath(szDir, szGUID); if (GetFileAttributes(szDir) == (DWORD)-1) CreateDirectory( szDir, NULL ); // BUGBUG:
// The extraction of the CAB file(s) should be done after we found out
// If the user has already a newer exception pack registered.
// This check is done below. Could not change it anymore, because of
// time constrains. Found this in the code review
//
// Extract all CABs into the package fodler.
#ifdef DEBUG
wsprintf(sz, "cab folder :%s:\r\n", g_lpWorkingDir); SetupLogError(sz,LogSevInformation); wsprintf(sz, "extract folder :%s:\r\n", szDir); SetupLogError(sz,LogSevInformation); #endif
if (GetPrivateProfileSection("Cab.List", szCabs, sizeof(szCabs), szInf) != 0) { pCab = szCabs; while (*pCab != '\0') { lstrcpy(szCab, g_lpWorkingDir); AddPath(szCab, pCab); #ifdef DEBUG
wsprintf(sz, "Extract :%s: to :%s:\r\n", szCab, szDir); SetupLogError(sz,LogSevInformation); #endif
hr = ExtractFiles(szCab, szDir, 0, NULL, NULL, 0); pCab += (lstrlen(pCab) + 1); } bContinue = TRUE; } }
if (bContinue) { if (GetPrivateProfileString("Info", "Version", "", szBuf , MAX_PATH, szInf) != 0) { // Convert version
ConvertVersionString( szBuf, wVer, '.' );
ComponentData.SizeOfStruct = sizeof(SETUP_OS_COMPONENT_DATA); ExceptionData.SizeOfStruct = sizeof(SETUP_OS_EXCEPTION_DATA); pszwPath = MakeWideStrFromAnsi(szGUID); if (pszwPath) { IIDFromString( pszwPath, &MyGuid); CoTaskMemFree(pszwPath);
if (SetupQueryRegisteredOsComponent( &MyGuid, &ComponentData, &ExceptionData)) { if ((ComponentData.VersionMajor < wVer[0]) || ((ComponentData.VersionMajor == wVer[0]) && (ComponentData.VersionMinor <= wVer[1])) ) { bContinue = SetupUnRegisterOsComponent(&MyGuid); SetupLogError("IE6: SetupUnRegisterOsComponent.\r\n",LogSevInformation); } // BUGBUG: Missing the below else. Found in code review
// else
// bContinue = FALSE;
} } else bContinue = FALSE; } else bContinue = FALSE; } if (bContinue) { SetupLogError("IE6: Preparing SetupRegisterOsComponent.\r\n",LogSevInformation); ExpandEnvironmentStrings( PACKAGE_DIRECTORY, szPath, sizeof(szPath)); AddPath( szPath, szGUID );
ComponentData.VersionMajor = wVer[0]; ComponentData.VersionMinor = wVer[1]; RtlMoveMemory(&ComponentData.ComponentGuid, &MyGuid,sizeof(GUID));
t = szPath + lstrlen(szPath); *t = '\0'; GetPrivateProfileString("Info", "InfFile", "", szBuf, MAX_PATH, szInf); AddPath( szPath, szBuf);
pszwPath = MakeWideStrFromAnsi(szPath); if (pszwPath) { wcscpy(ExceptionData.ExceptionInfName, pszwPath); CoTaskMemFree(pszwPath); }
*t = '\0'; GetPrivateProfileString("Info", "CatalogFile", "", szBuf, MAX_PATH, szInf); AddPath( szPath, szBuf);
pszwPath = MakeWideStrFromAnsi(szPath); if (pszwPath) { wcscpy(ExceptionData.CatalogFileName, pszwPath); CoTaskMemFree(pszwPath); }
LoadString(g_hInstance, IDS_FRIENDLYNAME, szPath, sizeof(szPath)); pszwPath = MakeWideStrFromAnsi(szPath); if (pszwPath) { wcscpy(ComponentData.FriendlyName, pszwPath); CoTaskMemFree(pszwPath); }
wsprintfW(szMsg, L"IE6: ExceptionData\r\n\tInf: %ws\r\n\tCatalog: %ws\r\n", ExceptionData.ExceptionInfName,ExceptionData.CatalogFileName); SetupLogErrorW(szMsg,LogSevInformation);
if (SetupRegisterOsComponent(&ComponentData, &ExceptionData)) { SetupLogError("IE6: SetupRegisterOsComponent succeeded.\r\n",LogSevInformation); #ifdef DEBUG
cd.SizeOfStruct = sizeof(SETUP_OS_COMPONENT_DATA); ed.SizeOfStruct = sizeof(SETUP_OS_EXCEPTION_DATA); if (SetupQueryRegisteredOsComponent( &MyGuid, &cd, &ed)) { StringFromIID(cd.ComponentGuid, &GuidString); wsprintfW(szMsg, L"IE6: Component Data\r\n\tName: %ws\r\n\tGuid: %ws\r\n\tVersionMajor: %d\r\n\tVersionMinor: %d\r\n", cd.FriendlyName,GuidString,cd.VersionMajor,cd.VersionMinor); SetupLogErrorW(szMsg,LogSevInformation);
wsprintfW(szMsg, L"IE6: ExceptionData\r\n\tInf: %ws\r\n\tCatalog: %ws\r\n", ed.ExceptionInfName,ed.CatalogFileName); SetupLogErrorW(szMsg,LogSevInformation);
CoTaskMemFree( GuidString ); } #endif
} } // In future, check for other settings here and perform necessary upgrade actions.
#endif
#ifdef DEBUG
SetupLogError("IE6: Done MigrateSystemNT \r\n", LogSevInformation); #endif
return ERROR_SUCCESS; }
|