Joseph Dadzie
Microsoft Corporation
October 1997
There are two sets of sample source code that accompany this article. The first, pview, migrates pview.exe from Windows 9x to Windows NT 5.0. The second, scrnsave, migrates the Windows 95 screen savers, such as Flying Windows and Marquee. Both packages include heavily commented source code for the Migration DLLs.
Click to view or copy the PVIEW sample source code that accompanies this article.
Click to view or copy the SCRNSAVE sample source code that accompanies this article.
Many applications work identically under Miclrosoft®Windows® 9x and Windows NT® 5.0. Your application may operate differently under the different versions. If so, if your users decide to move from Windows 9x to Windows NT, they will be unable to use your application. To prevent this, Microsoft provides the Migration Extension Interface.
If applications do not work properly, users have to reinstall them. Individual reinstallation of applications is an irritation at any level. In corporate environments, where large-scale deployments are automated, reinstalling applications is prohibitive, since it increases deployment costs. For most non-corporate environments, users may not have the original installation media readily available to reinstall their applications.
The Migration Extension Interface is an extension to the Setup API that enables you to ensure that your application will operate correctly after Windows NT is installed over Windows 9x. To make use of the Migration Extension Interface, you must write a migration DLL (MIGRATE.DLL) that the Setup program can use to make the necessary changes that will enable your application to work correctly under the new operating system.
This reference is divided into the following major sections:
Provides more details on why you would implement a migration DLL for your application
Describes the overall structure and processing order of the essential DLL functions
Details a number of important issues you must consider when you choose to implement a migration DLL
Outlines the steps you should take to determine if you need a migration DLL
Details the MIGRATE.DLL functions
Details the information file your DLL will use to pass information to the Windows NT Setup program
Most users expect that all their installed applications will function properly after they decide to upgrade from Windows 9x to Windows NT. However, it is almost impossible to guarantee that an existing application will work properly after Windows NT Setup completes installation of the new operating system. While Windows NT Setup attempts to adhere to the ideal behavior, there are certain problems with some applications that it cannot handle. These include problems caused by applications that:
As the developer of your application, you are the only one who can resolve these issues. You can use the Migration Extension Interface to interact with the upgrade process and correct inconsistencies like these before they become problems.
The Migration Extension Interface is designed to fit into the upgrade process as follows:
HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\Migration DLLs
Value name: <ProductID string >
Value: <path to MIGRATE.DLL>
Note The ProductID must match the string returned by the QueryVersion function described later on in this document.
Note Support for the digital certificate requirement and specification of the location of MIGRATE.DLL if installed on the user’s hard disk will be fully implemented for Windows NT 5.0 Beta 2.
The migration DLL is a standard Win32®-based DLL you create. It is called by Windows NT 5.0 Setup at different times during the upgrade process to perform a custom migration of your otherwise incompatible application. Setup relies on migration DLLs to identify unknown software components and to either migrate their settings to Windows NT, or to remove the components that will never work properly after an upgrade.
At a minimum, a migration DLL must have the following Setup-defined exported functions.
Your migration DLL can contain additional functions, as well. But if any of these seven functions is missing from a migration DLL, Setup will not load and process it, and your application will not migrate.
This section describes the order in which the functions in the migration DLL are called and a brief description of each function. Note that if any of the required seven functions is not present, Setup will skip your MIGRATE.DLL, and your application will not be migrated to the new system.
During the initial portion of Windows NT Setup (that is, while Windows 9x is still running), the following MIGRATE.DLL functions are called in their listed order.
Function | Caller | Reason for Call |
DllMain (DLL_PROCESS_ATTACH) | Windows 9x | Standard call to load the migration DLL from the installation media. |
QueryVersion | Setup | Obtain application identification information (such as the product ID and version number) and determine if further processing is necessary. After successful processing, the relevant files are copied to the user’s hard disk. |
DllMain (DLL_PROCESS_DETACH) | Windows 9x | The system unloads the migration DLL. |
DllMain (DLL_PROCESS_ATTACH) | Windows 9x | The system loads the migration DLL from its new location on the local hard disk. |
Initialize9x | Setup | MIGRATE.DLL prepares itself for the migration process. It detects its target application component locations. Then it provides the working and source directories to Windows NT Setup. |
MigrateUser9x | Setup | Setup calls the MigrateUser9x function once for each Windows 9x user account on the computer being upgraded as well as for the Windows NT Administrator account (that is, the active user account becomes the NT Administrator account after migration). The migration DLL detects the users that have installed its target application. Setup also calls MigrateUser9x for the default user account if necessary. If the application is installed for the given user name, the DLL gathers user-specific application information to be used during the MigrateUserNT function call. |
MigrateSystem9x | Setup | The DLL gathers system-wide information concerning its target application, and saves private data to be used during the MigrateSystemNT function call. |
DllMain (DLL_PROCESS_DETACH) | Windows 9x | The system unloads the migration DLL. |
During the second portion of Windows NT Setup (that is, when the newly installed Windows NT is running), the following MIGRATE.DLL functions are called in their listed order.
Function | Caller | Reason for Call |
DllMain (DLL_PROCESS_ATTACH) | Windows NT | The system loads the migration DLL. |
InitializeNT | Setup | Windows NT Setup provides the migration DLL with its working directory, specified during the earlier call to Initialize9x. |
MigrateUserNT | Setup | Setup calls MigrateUserNT once per user. It enables the migration DLL to make changes to a user’s application settings. Note that the number of calls may be less than the number made to MigrateUser9x, since some user accounts may not migrate. For example, the default user account may not migrate if that account has never been accessed. As such, a DLL must store its private data on a per-user basis. |
MigrateSystemNT | Setup | The migration DLL makes changes to the system’s application settings based on the information obtained during the call to MigrateSystem9x. |
DllMain (DLL_PROCESS_DETACH) | Windows NT | The system unloads the migration DLL. |
By the time the system calls the DllMain (DLL_PROCESS_ATTACH) function, Setup has done the following:
%windir%\system
to %windir%\system32.
HKU\User\Software
and HKLM\Software
that contain full paths to files that exist in a new location on Windows NT. Note In the Windows NT phase of the upgrade process, each DLL function has 60 seconds to complete its processing. If it takes longer, Setup will terminate it.
Since a migration DLL is a standard Win32 DLL, writing one should be fairly straightforward. However, the following sections describe some specific development issues to consider.
Migration Function Processing Order
Run Time DLLs Included with Windows NT 5.0
Manipulating a User’s Registry Settings
Handling Special String Characters
Deferring Application Migration
You can place your migration DLL in a network location, on a floppy disc, or on a compact disc.
A user may place migration DLLs on a network share and specify the location during Setup, or, if Setup is running in unattended mode, specify the location in the Setup answer file. Each migration DLL must be placed in its own subdirectory (along with any other files required for migrating the target application).
Note If the Win95upg
subdirectory exists before Setup runs, Setup will delete it and create a new one into which the specified files will be copied.
Setup provides users with the option to supply a floppy or compact disc that contains migration DLLs for their target applications. Setup searches the provided media for MIGRATE.DLL files. For each DLL it finds, it copies the directory containing the DLL (as well as all other files and subdirectories in that directory) to a unique subdirectory.
Note The Windows NT 5.0 compact disc also contains migration DLLs.
There is no guaranteed processing order for migration DLLs. Therefore, do not allow one of your migration DLLs to be dependent on the migration DLL for another application.
Before running any migration extensions on the Windows 9x system, Setup will copy the following files from the Windows NT compact disc to the Windows 9x System directory:
Setup
Visual C Run time
Visual C 4.0 Run time
Microsoft Foundation Class Library 4.0
Microsoft Foundation Class Library 4.2
For international environments, Setup copies the appropriate localized DLLs. For example, Setup copies MFC40JPN.DLL and MFC42JPN.DLL for a Japanese installation.
Debug versions of the run-time DLLs are not copied, nor can Setup guarantee that other run-time versions of an application will migrate correctly.
This list of files is not exhaustive. Setup may also install newer versions if they become available. However, if your migration extension needs a run-time DLL that is not installed by Windows NT, you must ship it with your migration DLL, and use the migration DLLs functionality to ensure the run-time DLL is installed.
Setup runs in a logged-on user context on Windows 9x, but does not run in a logged-on user context under Windows NT. Rather, it runs in the local system account context. As such, your migration DLL should not try to query or modify the HKEY_CURRENT_USER registry key directly. Instead, it should query the UserRegKey handles passed to it through the MigrateUser9x and MigrateUserNT functions.
You can use SYSDIFF.EXE to determine registry entry differences between an application on a newly installed Windows NT 5.0 computer and an upgraded Windows 9x one. SYSDIFF.EXE is available from the Microsoft Windows NT 4.0 Workstation Resource Kit. This utility is useful when you are not familiar with the application registry differences between the two versions of your application.
To use SYSDIFF.EXE to determine the registry entries made by an application on a Windows NT computer:
sysdiff /snap [/log:<logfile1>] <snap_file>
logfile1 and snap_file are valid filenames. The /log parameter is optional. SYSDIFF.EXE will create both files.
Note SYSDIFF.EXE records all system changes. Install your application only.
sysdiff /diff [/log:<logfile2>] <snap_file> <diff_file>
logfile2 and diff_file are valid filenames. The /log parameter is optional. SYSDIFF.EXE will create both files. snap_file is the filename you specified in the previous call to SYSDIFF.EXE.
From the Command Prompt, run
sysdiff /dump <diff_file> <dump_file>
dump_file is a valid filename. SYSDIFF.EXE will create it. diff_file is the filename you specified in the previous call to SYSDIFF.EXE.
When SYSDIFF.EXE completes, dump_file is a plain text file containing a list of file, .INI file and registry changes made to the system by the target application. Now you are ready to get the upgrade registry entries.
To determine registry entry differences between an upgraded computer (from Windows 9x to Windows NT 5.0) and a newly installed Windows NT 5.0 computer:
Note This procedure is different because SYSDIFF does not work across platforms.
The network is not available to Setup during the Windows 9x phase of the upgrade process, but it will not be available during the Windows NT phase. Your migration DLL must not try to access the network during the Windows NT portion of the migration.
Your migration DLL should not have a user interface. A parent window handle is provided only for the extreme case where a user interface is unavoidable. If Setup provides a NULL parent window handle, the DLL must never display any windows, dialogs, popups, or messages boxes. The migration DLL must never display a user interface on the Windows NT side of Setup.
This is extremely important when Setup is running in unattended mode. You can determine the Setup mode by testing the value of the ParentWnd parameter in either MigrateUser9x or MigrateSystem9x.
The installation process should be as hassle-free as possible. If the User Interface is required at any point during an attended installation, consider the usability implications when someone must load multiple migration DLLs.
Each migration DLL is copied to unique working directory. Your migration DLL may store private Windows 9x configuration information in this directory, as well as other run-time or data files required for the migration.
This directory is the only location to which your migration DLL should write when it is running on Windows 9x. Setup deletes this working directory after all migration DLLs have completed, and after Windows NT is successfully installed.
When writing messages, paths, and registry locations to an INF file, your migration DLL may need to pass certain characters that have special meanings to Setup and to the operating system. When writing messages or paths, the string must be enclosed in double-quotes if it contains any of the following:
"
%
,
;
[
]
In addition, embedded percent and double quote characters must be formatted properly before the string is written to the INF file. For example,
This "example" illustrates how to escape the percent (%) symbol
Must appear in an INF file as
"This ""example"" illustrates how to escape the percent (%%) symbol"
When writing registry locations to an INF file, you must replace the characters listed below as well as all characters with ASCII values greater than 127 (including double-byte characters) with their hexadecimal values enclosed in tilde (~).
Character | Hex value |
" |
0x22 |
% |
0x25 |
, |
0x2C |
; |
0x3B |
[ |
0x5B |
] |
0x5D |
~ |
0x7E |
For example, replace a semicolon (;
) with the string ~3B~ .
Setup passes the location of its answer file (UNATTEND.TXT) to your migration DLL in the MigrateUser9x, MigrateSystem9x, MigrateUserNT, and MigrateSystemNT functions.
Your migration DLL can modify this answer file during the Windows 9x portion of the upgrade process by using the Win32 profile APIs (such as WritePrivateProfileString). Your DLL is permitted to change standard answer file settings and create private sections for its own use. Note that it may not modify the following sections of the UNATTEND.TXT file.
[Unattended]]
[MassStorageDrivers]
[DisplayDrivers]
[KeyboardDrivers]
[PointingDeviceDrivers]
[OemBootFiles]
[OEM_Ads]
[GuiUnattended]
[UserData]
[LicenseFilePrintData]
[Display]
[Modem]
Note This list will change before Beta 2. See the win95upg.inf (Answer File Restrictions) on the Windows NT CD.
For a detailed description of answer file parameters, search the Microsoft Knowledge Base database at http://www.microsoft.com/kb/.
If you require a private section, your DLL should build the section name from the working directory passed to it by the Initialize9x function. The private section name may only contain alphanumeric characters (A-Z and 0-9). Spaces and other characters are not permitted because they prevent Windows NT Setup from starting the text-only portion of the installation.
During the Windows NT portion of the upgrade, your migration DLL must treat the UNATTEND.TXT file as a read-only file. You must not modify the answer file in any way.
To support the Migration Extension Interface, the Windows 9x Upgrade section has been added to the UNATTEND.TXT answer file. (Note that this is subject to change before Beta 2.)
Attended = [Yes|No]
Default value is Yes. Attended specifies if the upgrade is running in attended mode or not. When set to No, Setup assumes default values for the rest of the Windows 9x Upgrade section parameters:
MigrationDllPath = <path>
Specifies a local or UNC path to migration DLLs. Setup will search this directory and its subdirectories for migration DLLs.
ReportOnly = [No|Yes]
Default value is No. This parameter forces Setup to generate a compatibility report and then terminate without upgrading the computer.
SaveReportTo = <path>
Default is the local computer system drive (generally C:\). Specifies a local or UNC path (not a file name) to the desired location of Setup’s compatibility report files (HARDWARE.TXT and SOFTWARE.TXT). HARDWARE.TXT contains the hardware compatibility report. SOFTWARE.TXT contains the software compatibility report.
AppendComputerNameToPaths = [No|Yes]
Default value is No. This key is used to specify whether the computer name should be appended to the path to which the compatibility reports are to be saved. The directory is created if it does not already exist. For example, if SaveReportTo = C:\reports and the computer name is Testcomp, the reports would be saved to C:\reports\Testcomp.
If your application is network-based, it may not be practical for your migration DLL to copy your migration files from a network location to every local computer that has installed the Windows 9x version.
Instead, your migration DLL can redirect the application’s shell links to a new executable. This way, when a user launches the application, the new executable runs instead. This executable is responsible for completing the migration from the network location to that user's local machine in the user’s logged-on, network-accessible context on Windows NT. If you choose this approach, all your migration DLL needs to do is to copy the new executable to the local hard disk, and redirect all shell links from the original target application to this new executable. (You accomplish this through an entry in the [Moved]
section of MIGRATE.INF).
The new executable must complete the migration when a user runs it on Windows NT. It must restore the original shell links, delete itself, and then run the newly migrated application. For more details on how to replace links, see the Shell Link documentation in the Win32 SDK.
See Also: [Moved] Section
Windows NT Setup automatically logs errors returned by your migration DLL code. To log the errors your migration DLL detects, you must use the new Setup API function SetupLogError:
BOOL
SetupLogError (
IN LPCTSTR MessageString,
IN LogSeverity ErrorSeverity
);
MessageString
Error message string to be saved to Windows NT Setup’s action log (saved to %Windir%SETUPACT.LOG
).
ErrorSeverity
Specifies the severity of the error to be logged. The error can have one of the following values, listed in increasing order of severity.
If ErrorSeverity level is any one of LogSevWarning, LogSevError, or LogSevFatalError, a copy of the error message will also be saved to the %Windir%SETUPERR.LOG
file.
Before logging an error, the log file must be opened using SetupOpenLog. SetupCloseLog must be used to close it after the error is written.
Note Opening and closing a log file can be done in the DLLMain function of a migration DLL. See the sample source code for examples.
The Win32 Profile APIs (GetPrivateProfileString and WritePrivateProfileString) use a separate cache than the one used by SetupOpenInfFile. Therefore, if you open MIGRATE.INF using SetupOpenInfFile and then (before closing it) modify the file using WritePrivateProfileString, your changes will not appear in SetupOpenInfFile’s cache.
As such, care must be taken when using both the Win32 Profile APIs and the Setup APIs. Ideally, their use must be separated.
If you modify MIGRATE.INF using WritePrivateProfileString, you must call WritePrivateProfileString again with all NULL parameters to force the file to be written to disk before you open it again using SetupOpenInfFile.
If a file has already been opened with SetupOpenInfFile is already open, do not call WritePrivateProfileString to modify the same file.
The GUI-mode portion of Windows NT Setup may be restarted in case of a critical interruption (such as a power failure) during the upgrade. Your migration DLL should be prepared to handle this scenario. For example, before moving files, the DLL must check to see if the file has already been moved. Of course, this is standard programming practice, and the extent of your fail-safe functionality is mostly determined by the complexity of your migration process.
Applications that do not survive migration from one version of Windows to another will not comply with Windows logo requirements. Your migration DLL can help to preserve your logo compliance.
The Setup program attempts to detect conflicts that arise from implementing your application under the new operating system. It may or may not succeed in identifying inconsistencies. Because of this, you should test your application extensively under various migration scenarios.
The migration functionality is provided to enable you to ensure that your customer base can use your application under the new operating system. You should test how your application behaves under different versions of Windows. Ideally, it behaves the same under different versions.
If conflicts exist, you have two options. You can either correct the intrinsic problem so that no problems occur during migration, or you can create a migration DLL. If you do not take advantage of the Migration Extension Interface, your customers will need to reinstall your application for it to run correctly under the newly installed system.
Migration DLLs must be thoroughly tested before being distributed to end users by means of the Web or other media. The following procedures outline the minimal process you should undertake during your test. Note that you should repeat the tests for multiple user account scenarios (default, roaming, workgroup, and domain users). The scenarios should also cover combinations of these user accounts.
To test your migration DLL under an attended upgrade:
To test your migration DLL under an unattended upgrade:
%windir%\setup\win95upg
.Setup uses QueryVersion to determine if further processing of the DLL is necessary.
LONG
CALLBACK
QueryVersion (
OUT LPCSTR *ProductID,
OUT LPUINT DllVersion,
OUT LPINT *CodePageArray, OPTIONAL
OUT LPCSTR *ExeNamesBuf, OPTIONAL
OUT PVENDORINFO *VendorInfo
);
*ProductID
Points to a string that identifies the DLL and its target application. To ensure uniqueness, the string must contain the name of the manufacturer, the product name, and the version number of the application the DLL will migrate. The length of the string must not exceed MAX_PATH bytes (as defined within your migration DLL). Setup ignores excess characters. The ProductID string is also used for error messages generated during DLL processing.
Note Your migration DLL is responsible for allocating and freeing the ProductID string buffer.
DllVersion
Points to a non-zero unsigned integer that specifies the version number of your migration DLL. Setup looks for duplications by comparing ProductID strings from other migration DLLs. If two or more DLLs have identical ProductID strings, Setup uses the DLL with the highest DllVersion number and ignores the other duplicates.
Note DllVersion is not intended to be the DLL’s binary version number.
CodePageArray
Points to an array of integers containing all the code pages supported by the migration DLL. The last element of the array must be -1. If your migration DLL does not support the system code page, Setup skips your migration DLL and your application will not migrate to the new operating system.
If this pointer is NULL, Setup processes all the required functions in the DLL regardless of the installed Windows 9x code pages. Set this pointer to NULL if the DLL has no language dependencies.
Note Your DLL is responsible for the allocating and freeing memory used by this array.
ExeNamesBuf
Points to a multi-sz string buffer containing a list of filenames (not paths), that your migration DLL wants Setup to locate. Setup locates all instances of the listed files and returns the list of full file paths to your migration DLL via the MIGRATE.INF file. Paths to files located on network, substituted, or compressed drives will not be returned to the DLL, because Setup does not search those drives. Other directories on the computer not related to the active Windows 9x installation may also be excluded.
Set this parameter to NULL if you do not want Setup to search for any particular files.
Note Your migration DLL is responsible for allocating and freeing the ExeNamesBuf string buffer.
VendorInfo
Points to a data structure that contains your company name, contact information (phone number), web address and instructions you want to provide to the user. Setup will display this information to the user in the migration report and in error cases. The VendorInfo data structure is of the form:
typedef struct {
CHAR CompanyName[256];
CHAR SupportNumber[256];
CHAR SupportUrl[256];
CHAR InstructionsToUser[1024];
} VENDORINFO, *PVENDORINFO;
Strings returned to Setup must be localized for the language version of Windows 9x running on the computer.
Note The VendorInfo field will only be enforced for Beta 2 and beyond. A migration DLL written for Beta 2 will still run on Beta 1.
Your migration DLL must also return ERROR_SUCCESS if it does not attempt to detect installed components in QueryVersion.
All other return values (Win32 error values) are considered initialization errors. Setup will report the error to the user, clean up your migration DLL’s files, and ask the user to continue or cancel the Windows NT installation process.
An exception generated by a migration DLL causes Setup to report RPC error messages. Setup will provide more information in SETUPERR.LOG.
Setup uses QueryVersion to determine if further processing of the DLL is necessary. During this call, your migration DLL (located on a floppy, compact disc, or network share) must provide Setup with the ProductID, DllVersion, CodePageArray and ExeNamesBuf information. At this point your migration DLL cannot make any changes to the system.
Your migration DLL should try to determine if the target application is installed on the computer, and then return the appropriate result from QueryVersion. The system unloads the migration DLL after QueryVersion returns. Setup copies it to the local hard disk and calls Initialize9x only if QueryVersion returns ERROR_SUCCESS.
During the call to QueryVersion, Setup finds all occurrences of files listed in the ExeNamesBuf string (if not NULL) and writes their locations to the [Migration Paths] section of MIGRATE.INF. These paths are then available to the other functions in your migration DLL.
Setup detects duplicate migration DLLs by comparing the ProductID strings of supplied DLLs. It only processes the DLL with the highest DLLVersion number. The user is not be notified of duplicates found.
Important: DllVersion number zero (0) is reserved for Windows NT Setup–provided migration DLLs. DLLs not supplied by Microsoft Windows NT with the Windows NT 5.0 compact disc must not use this value.
Setup calls Initialize9x after relocating the migration DLL to the local hard disk.
LONG
CALLBACK
Initialize9x (
IN LPCSTR WorkingDirectory,
IN LPCSTR SourceDirectories,
LPVOID Reserved
);
WorkingDirectory
Points to the path of a Setup-supplied directory your migration DLL can use to store its private temporary data. This directory will contain MIGRATE.DLL and all associated files. Your migration DLL must write to this directory if it needs temporary data storage. Setup provides this directory again during the Windows NT phase of the upgrade process, and automatically deletes it after the upgrade is complete.
SourceDirectories
Points to the path of the Windows NT installation files. This path is a multi-sz string to enable you to specify multiple source directories. Normally, this directory is D:\I386 where D:\ is the CD-ROM drive on the computer.
Note Compressed files on the Windows NT installation compact disc can be decompressed by using the Setup API functions SetupGetFileCompressionInfo and SetupDecompressOrCopyFile.
Reserved
Reserved for future use.
All other return values (Win32 error values) are considered initialization errors. Setup reports the error to the user, cleans up your migration DLL’s files and asks the user to abort or continue the Windows NT installation process.
Exceptions generated by your migration DLL cause Setup to report RPC error messages. Setup provides more information in SETUPERR.LOG.
Setup calls Initialize9x after relocating your migration DLL to the local hard disk. During this call, your DLL should try to detect its new installation. It should return ERROR_SUCCESS if it is ready to be called by Setup during the Windows NT portion of the upgrade. If the DLL returns ERROR_NOT_INSTALLED, Setup will stop processing it.
The current directory is set to the working directory and will not be changed by Setup during the processing of a migration DLL.
Gathers information concerning the users, and saves private data to be used during the later call to MigrateUserNT.
LONG
CALLBACK
MigrateUser9x (
IN HWND ParentWnd,
IN LPCSTR AnswerFile,
IN HKEY UserRegKey,
IN LPCSTR UserName,
LPVOID Reserved
);
ParentWnd
Specifies a handle to the parent window for any dialog boxes or windows that you may want your migration DLL to display.
Note You should not display a user interface unless absolutely necessary.
If this parameter is NULL, Setup is running in an unattended mode and your DLL must not display user interface elements or prompt the user for input.
AnswerFile
Points to a copy of the Windows NT Setup answer file (typically UNATTEND.TXT) which is used to automate the installation of Windows NT. You can access this file using the Win32 profile APIs (for example, GetPrivateProfileString and WritePrivateProfileString). Some sections of this answer file cannot be modified by your DLL. For more information, see Using the Setup Answer File.
UserRegKey
Provides a registry handle to the user hive of the Windows 9x user specified in the UserName parameter. This user hive is equivalent to the user’s HKEY_CURRENT_USER (HKCU) when that user logs on. This handle is valid only within the scope of MigrateUser9x and is provided for user-specific information gathering purposes.
UserName
Provides the user name (e.g. “username”) for the Windows 9x user whose registry information is supplied through the UserRegKey parameter. A value of NULL refers to the default Windows 9x user account (the account used when a user accesses the system by skipping the logon process). UserName may also be “Administrator” even though Windows 9x does not have an administrator account. This allows a migration DLL to collect information for the Windows NT Administrator account to be created later.
Reserved
Reserved for future use.
ERROR_SUCCESS if the target application is installed for the specified user. Also return ERROR_SUCCESS if your migration DLL needs further processing during the Windows NT phase.
ERROR_NOT_INSTALLED if your target application is not installed for the specified user account and that user’s registry does not require any processing. However, Setup will continue to call MigrateUser9x for the rest of the users, and MigrateSystem9x if this function returns ERROR_NOT_INSTALLED.
ERROR_CANCELLED if the user wants to exit Setup. You should specify this return value only if ParentWnd is not set to NULL.
All other return values (Win32 error values) are considered initialization errors. Setup reports the error to the user and prompts to abort or continue the upgrade.
Exceptions generated by your migration DLL cause Setup to report RPC error messages. Setup provides more information in SETUPERR.LOG.
A DLL must always check for the value of ParentWnd in MigrateUser9x before proceeding since its value determines whether UI can be displayed to the user.
Do not use the MigrateUser9x function for user account modification. Use it only for information gathering about user accounts. To modify user-specific settings, save the data collected to your provided working directory and then use the MigrateUserNT function to perform the modifications.
Use the DLL working directory provided by the Initialize9x WorkingDirectory parameter to store any user-specific configuration information you may want to keep track of. Remember to use the UserName parameter to differentiate the information about the various users.
Gathers system-wide information concerning the target application, and saves private data to be used during the later call to MigrateSystemNT.
LONG
CALLBACK
MigrateSystem9x (
IN HWND ParentWnd,
IN LPCSTR AnswerFile,
LPVOID Reserved
);
ParentWnd
Specifies a handle to the parent window for any dialog boxes or windows that your migration DLL may want to display.
Note You should not display a user interface unless absolutely necessary.
If this parameter value is NULL, Setup is running in an unattended mode and your DLL must not prompt the user for input. Therefore, the ParentWnd value determines whether ERROR_CANCELLED can be returned from this function.
AnswerFile
Points to a copy of the Windows NT Setup answer file, UNATTEND.TXT. This file is used to automate the installation of Windows NT and can be accessed using the Win32 profile APIs, such as GetPrivateProfileString and WritePrivateProfileString. For more information, see Using the Setup Answer File.
Reserved
Reserved for future use.
All other return values (Win32 error values) are considered initialization errors. Setup reports the error to the user and asks to abort or continue the upgrade.
Exceptions generated by your migration DLL cause Setup to report RPC error messages. Setup provides more information in SETUPERR.LOG.
Your DLL must always check for the value in ParentWnd before proceeding, since its value determines whether user interface elements can be displayed to the user.
Do not use this function to modify the system. Use it for system-wide information gathering only. To modify system-wide settings, save any private data collected in your migration DLLs working directory (specified in an earlier call to Initialize9x). Use MigrateSystemNT to perform the modifications during the Windows NT portion of the upgrade.
This function is called during Windows NT GUI Mode Setup when the Windows NT phase of the upgrade is ready to start.
LONG
CALLBACK
InitializeNT (
IN LPCWSTR WorkingDirectory,
IN LPCWSTR SourceDirectories,
LPVOID Reserved
);
WorkingDirectory
Points to the path of the Setup-supplied working directory. This value is the value that your migration DLL used for storing its private temporary data and files during the Windows 9x phase of the upgrade.
SourceDirectories
Points to the path of the Windows NT installation files. This path is a multi-sz because multiple source directories can be provided. Normally this directory is D:\I386 or C:\$WIN_NT$.~LS\I386 where D:\ is the CD-ROM drive on the computer and C:\$WIN_NT$.~LS\I386 is Setup’s temporary source directory.
Reserved
Reserved for future use.
ERROR_SUCCESS if your migration DLL initializes properly within the Windows NT environment.
All other return values (Win32 error values) are considered critical errors. Setup reports the error to the user and then cancels processing your migration DLL. However, Setup will not continue the upgrade. Any errors or logs generated will include the ProductID string specified in QueryVersion to identify your DLL.
Exceptions generated by your migration DLL cause Setup to report RPC error messages. Setup provides more information in SETUPERR.LOG.
InitializeNT is called during Windows NT GUI Mode Setup, when the Windows NT phase of application migration is ready to start. When this function is called, the current directory is set to the DLL’s working directory.
Your migration DLL must not display user messages in its InitializeNT function.
Migrate the user accounts that port from Windows 9x to Windows NT.
LONG
CALLBACK
MigrateUserNT (
IN HINF AnswerFileHandle,
IN HKEY UserRegKey,
IN LPCWSTR UserName,
LPVOID Reserved
);
AnswerFileHandle
INF handle to the answer file being used for the upgrade process. This file contains settings generated by Setup, the attending user, and all migration DLLs. You can access the file referenced by this handle using the Setup functions. Do not close this handle at any time.
UserRegKey
A registry handle to the private registry settings of the Windows 9x user specified in UserName. This handle is equivalent to HKEY_CURRENT_USER (HKCU) when that user is logged on. The handle is only valid within the scope of MigrateUserNT. Do not close this handle at any time.
UserName
The user name for the user whose registry information is supplied through the UserRegKey parameter. If this value is NULL, Setup is referring to the Windows NT logon account. The Windows NT logon account is used for creating the desktop settings for the Windows NT logon prompt and as a template for creating new Windows NT users.
Reserved
Reserved for future use.
Other error codes will terminate the processing of your migration DLL. However, Windows NT Setup will proceed. Ideally, only critical problems (such as a hardware failure) should generate terminating error codes.
Exceptions generated by your migration DLL cause Setup to report RPC error messages. Setup provides more information in SETUPERR.LOG.
The order in which user names are passed to your migration DLL during the call to MigrateUserNT may be different than the order in which they were passed during the call to MigrateUser9x.
Setup may disable migration of one or more user accounts if errors occur. For this reason, the number of user names passed to MigrateUserNT may be less than the number passed to MigrateUser9x.
Your migration DLL is responsible for managing its private data created and stored during MigrateUser9x and processed during MigrateUserNT.
Your migration DLL must not display user messages within its MigrateUserNT function.
LONG
CALLBACK
MigrateSystemNT (
IN HINF AnswerFileHandle,
LPVOID Reserved
);
AnswerFileHandle
INF handle to the answer file being used for the upgrade process. This file contains settings generated by Setup, the attending user, and all migration DLLs. You can access the file referenced by this handle using the Setup functions. Do not close this handle at any time.
Reserved
Reserved for future use.
Other error codes will terminate the processing of your migration DLL. However, Windows NT Setup will proceed. Ideally, only critical problems (such as a hardware failure) should generate terminating error codes.
Exceptions generated by your migration DLL cause Setup to report RPC error messages. Setup provides more information in SETUPERR.LOG.
Your migration DLL is responsible for managing its private data created and stored during MigrateSystem9x and processed during MigrateSystemNT.
Your migration DLL must not display user messages in its MigrateSystemNT function.
During the Windows 9x phase of the upgrade, Windows NT Setup creates and uses MIGRATE.INF files to collect file information from all migration DLLs. During the Windows NT portion of the upgrade, Setup uses this same file to provide that information back to the submitting migration DLL.
Each working directory passed to a migration DLL has a MIGRATE.INF file in it. The sections are:
Section | Description |
[Version] | This is a generic section required for every Windows 9x-style INF. It contains information about the version of Windows NT being used for the upgrade. Setup writes to this section. |
[Migration Paths] | This section contains a list of Win32 paths to files requested by your migration DLL through the QueryVersion function ExeNamesBuf parameter. Each line represents the full path to a file. Setup writes to this section. |
[Excluded Paths] | This section contains a list of paths not part of the active Windows 9x system configuration. Setup does not search through any of these paths or their subdirectories. Excluded paths include directories on the system drive used by other operating systems, network drives, and substituted or compressed drives. Setup writes to this section. |
[Handled] | You use this section to inform Windows NT Setup about files, directories and registry entries in the active Windows 9x installation you intend to migrate using your migration DLL. Setup assumes that files, directories, and registry entries listed here are compatible with Windows NT 5.0. Therefore, users will not be warned about incompatibilities associated with these components. All file names, directories, and registry entries listed in this section must be valid on the active Windows 9x system. You can use the WritePrivateProfileString function for adding lines to this section. |
[Moved] | You use this section to inform Windows NT Setup about files and directories you plan to move, rename, or delete during the migration. This enables Setup to adjust the relevant Windows NT Explorer shell links. You can use the WritePrivateProfileString function for adding lines to this section. |
[Incompatible Messages] | You use this section to present messages to a user through the Setup incompatibility report (displayed during the Windows 9x phase of the upgrade process). The report is presented to the user before any changes are made to the computer, and is useful when you intend to change the behavior of an application, or when you plan to remove application components. |
[<Message Object Section>] | A message object section provides a mechanism for you to associate one or more message objects (file, directory, and registry location) with a message specified in the [Incompatible Messages] section. |
[NT Disk Space Requirements] | You use this section to specify the amount of disk space (on a per drive basis) your migration DLL requires during the Windows NT phase of the upgrade. Setup uses this information to calculate the total amount of space required for the upgrade. If sufficient space is unavailable, Setup informs the user accordingly during the Windows 9x phase of the upgrade. |
This is a generic section required for every Windows 9x-style INF. It contains information about the version of Windows NT being used for the upgrade. Your DLL cannot modify it.
Signature = <File Signature>
The signature of the file. For example, $Windows NT$. This is the default.
SetupOS = <OS Identifier>
OS Identifier specifies the operating system. For the upgrade, this value is Microsoft® Windows NT® Operating System.
SetupPlatform = <Platform Identifier>
Platform Identifier specifies the object Windows NT platform upgrade. The value can be either Workstation or Server.
SetupBuild = <Build Identifier>
Build Identifier specifies the object Windows NT build upgrade. This value will be 1382 or higher (depending on the build).
See the Win32 SDK for details on the non-migration information that may be contained in the [Version] section of Windows 9x-style INFs.
This section contains a list of Win32 paths to files requested by your migration DLL through the QueryVersion function ExeNamesBuf parameter. Each line represents the full path to a file. Setup writes to this section.
Your migration DLL can read the file paths listed here using the Setup API functions SetupGetLineCount and SetupGetLineText.
If multiple copies of a particular file name are found (such as versions installed by other applications), multiple paths to the file name will be listed in this section. When this happens, it is up to your migration DLL to determine which executables are valid for migrating your application.
If a file is not found in the active Windows 9x system, it will not be listed.
This section contains a list of paths that are not part of the active Windows 9x system configuration. Setup does not search through any of these paths or their subdirectories. Excluded paths include directories on the system drive used by other operating systems, network drives, and substituted or compressed drives. Setup writes to this section.
If your application is installed in any one of the paths listed in this section, your DLL must consider the application as not installed and must return ERROR_NOT_INSTALLED when initializing.
Your migration DLL can read the paths listed in this section using the Setup API SetupGetLineCount and SetupGetLineText functions. You can then use string matching to determine if a path you need is excluded. Your DLL must never make changes to the directories listed in this section.
You use this section to inform Windows NT Setup about files, directories, and registry entries in the active Windows 9x installation you intend to migrate using your migration DLL.
Setup assumes that files, directories, and registry entries listed here are compatible with Windows NT 5.0. Therefore, it shall not warn users about incompatibilities associated with these components, nor will any processing be performed. For example, specifying a file path to a file in the system directory will cause it not to be moved to system32. Similarly, "handled" registry entries will not be copied to NT.
All file names, directories and registry entries listed in this section must be valid on the active Windows 9x system.
You can use the WritePrivateProfileString function to add lines to this section.
The syntax for lines in this section is:
<Identifier Object> = <Identifier Type>
where:
Identifier Object
Specifies the name or path to a Windows 9x file, directory or registry location. Files and directories are in long file name format. Registry paths are of the form:
<Root>\<SubKey>\<SubKey>\<…> [<Value Name>]
where:
Root
Specifies the registry root. It can be any one of HKEY_LOCAL_MACHINE, HKLM, HKEY_ROOT, or HKR (migration DLLs can only handle a registry key for ALL users, not for individual users).
SubKey
Specifies one or more registry keys separated by back slashes (\).
Value Name
(Optional) Specifies a registry value name enclosed in square brackets. An empty square bracket ([ ]) specifies the default value for the specified key name.
Registry keys or value names themselves may contain square brackets ([ ]), tildes (~) or characters with values greater than 127. You must enclose hexadecimal value for these characters in tildes (~) when writing them as registry values to the [Handled] section. For more information, see Handling Special String Characters.
Identifier Type
Identifies the type of <Identifier Object> to be handled. It must be one of the following three values:
File
The object specified refers to a long file name (including the full path to the file). This must be a full path, without environment variables, and without short versions of long file names.
Directory
The object specified refers to a directory (including the full path to the directory).
Registry
The object specified refers to a registry key (including the full path to that key).
Use this section to inform Windows NT Setup about files and directories you plan to move, rename, or delete during the migration. This enables Setup to adjust the relevant Windows NT Explorer shell links.
You can use the WritePrivateProfileString function for adding lines to this section. Listing a file here will keep it from being processed in any other way, just as it was in the [Handled] section.
The syntax for this section is:
<OldPath> = <NewPath>
where:
OldPath
Specifies the filename or path of a Windows 9x file or directory to be moved or deleted. Filenames and paths are in long file name format.
NewPath
Specifies the new filename or path, again in long file name format. If NewPath is empty or not specified, Setup will delete OldPath.
Use this section to present messages to a user through the Setup incompatibility report (displayed during the Windows 9x phase of the upgrade process). The report is presented to the user before any changes are made to the computer, and is useful when you intend to change the behavior of an application, or when you plan to remove application components.
The syntax for this section is:
<Message Object Section> = <Message>
where:
Message Object Section
Specifies the name of a custom section (defined by your migration DLL) that contains a list of message objects, such as files, directories, and registry entries. The name may be any combination of uppercase and lower case letters, numbers, and spaces. It may not start or end with a space. By listing one or more message objects in a separate section, your DLL can associate several message objects with a single message. The value for Message Object Section is used as the component string in the compatibility report presented to the end user.
Message
A string describing the details of the incompatibility or message to be displayed to the user. The user will see the text in a multi-line, scrollable, read-only edit control.
For example, this incompatibility section may contain the following line:
MyAppMsg = "The DOS and Real-mode portions of Myapp.exe are not supported on Windows NT"
Where MyAppMsg refers to another section containing the list of files, directories and registry entries associated with the message string.
When you write an entry to the [Incompatible Messages] section, a Message Object Section must provide one or more objects associated with the message.
Your migration DLL is responsible for managing the code page and language dependencies of the messages listed in this section. In particular, the text in the [Incompatible Messages] section must be in the same language as the active Windows 9x system. Your DLL must not write messages to this section if it does not support the active operating system language.
The user has an option to view, print, or save the incompatibility report generated. This report will associate the ProductID with each Message.
A message object section provides a mechanism for you to associate one or more message objects (file, directory, and registry location) with a message specified in the [Incompatible Messages] section. The [Handled] section describes how to specify a message object.
The section name is defined by your migration DLL. Each line has the following syntax:
<Message Object> = <Identifier Type>
where:
Message Object
Specifies a Windows 9x file, path or registry entry. A file or path must be specified in long filename format.
Identifier Type
Identifies the type of <Message Object>. It can only have one of the following three values:
File
The object specified refers to a long file name (including the full path to the file).
Directory
The object specified refers to a directory (including the full path to the directory).
Registry
The object specified refers to a registry key (including the full path to that key).
Setup uses the value for Message Object Section to develop a hierarchy for incompatibility messages. The use of the section name enables your migration DLL to organize multiple incompatibility messages in the same format that Setup uses. Setup processes the section name in one of two ways:
Using the section name in this way achieves unique children for each migration DLL, organized under a single item at the root. Because ObjectSection is used for display purposes, your DLL must provide localized strings.
Setup treats all objects in a section as a set. If every object in the set is found in any [Handled] section (including ones provided by other vendors), no incompatibility message will be displayed for the particular object, even if the message is listed in [Incompatible Messages]. If only some or none of the objects are handled, the message will be displayed.
You use this section to specify the amount of disk space (on a per-drive basis) your migration DLL requires during the Windows NT phase of the upgrade. Setup uses this information to calculate the total amount of space required for the upgrade. If insufficient space is available, Setup informs the user accordingly during the Windows 9x phase of the upgrade.
The syntax for this section is:
<DriveLetter> = <Space Required>
where:
DriveLetter
Specifies the drive/partition (single letter without a colon or backslash) in which a migration DLL requires space for its private data. Setup will ignore drives/partitions that are also listed in the [Excluded Paths] section.
Space Required
Is an integer that indicates the amount of disk space in (bytes) required by a migration DLL during the Windows NT phase of Setup. When calculating space requirements, the amount of space lost from directory and cluster use must be taken into account. The number does not include the files copied into the working directory during the Windows 9x phase.
If this section is not present, or if no drives or partitions are specified, Setup assumes that the migration DLL requires no additional hard disk space to migrate the target application.
Important: Be sure to specify the correct disk space requirement data. If you cannot calculate disk space requirements accurately, you should provide a liberal estimate of the space required.
;
; Sample migrate.inf file
;
[Version]
Signature = $Windows NT$
SetupOS = Microsoft(R) Windows NT(R) Operating System
SetupPlatform = Workstation
SetupBuild = 1610
[Migration Paths]
"c:\windows\foo.exe"
"c:\temp\foo.exe"
"C:\program files\foo\bar.exe"
"C:\foofiles\bar.exe"
[Excluded Paths]
"c:\winnt40"
"f:\"
[Handled]
"C:\windows\foo.exe"=File
"C:\windows\foo.dll"=File
"c:\Program Files\foo"=Path
"HKLM\Software\Foo-Bar, Inc."=Registry
[Moved]
;moved
"c:\dir\boo.exe"="c:\dir\nt\boo.exe"
;moved and replaced
"c:\Windows\foo.exe"="c:\Windows\foo\foo_nt.exe"
;deleted
"c:\Windows\foo\Win9x"=""
[Incompatible Messages]
;the message must be on one line, but can be long
Foo-Bar ="The application Foo-Bar does not support the DOS component 'boo' on Windows NT."
[Foo-Bar]
"C:\dir\boo.exe"=File
"C:\dir\boo.dll"=File
[NT Disk Space Requirements]
c=104096
d=16384