summaryrefslogtreecommitdiffstats
path: root/private/utils/rdisk
diff options
context:
space:
mode:
Diffstat (limited to 'private/utils/rdisk')
-rw-r--r--private/utils/rdisk/config.c908
-rw-r--r--private/utils/rdisk/dialogs.dlg27
-rw-r--r--private/utils/rdisk/dialogs.h10
-rw-r--r--private/utils/rdisk/diamond.c476
-rw-r--r--private/utils/rdisk/floppyop.c888
-rw-r--r--private/utils/rdisk/format.c347
-rw-r--r--private/utils/rdisk/help.c363
-rw-r--r--private/utils/rdisk/help.h78
-rw-r--r--private/utils/rdisk/i386/rdskboot.asm77
-rw-r--r--private/utils/rdisk/i386/readme17
-rw-r--r--private/utils/rdisk/i386/x.bat2
-rw-r--r--private/utils/rdisk/makefile6
-rw-r--r--private/utils/rdisk/precomp.h14
-rw-r--r--private/utils/rdisk/rdisk.c619
-rw-r--r--private/utils/rdisk/rdisk.h65
-rw-r--r--private/utils/rdisk/rdisk.icobin0 -> 1086 bytes
-rw-r--r--private/utils/rdisk/rdskboot.c8
-rw-r--r--private/utils/rdisk/resource.h70
-rw-r--r--private/utils/rdisk/resource.rc74
-rw-r--r--private/utils/rdisk/sources29
20 files changed, 4078 insertions, 0 deletions
diff --git a/private/utils/rdisk/config.c b/private/utils/rdisk/config.c
new file mode 100644
index 000000000..35e493fce
--- /dev/null
+++ b/private/utils/rdisk/config.c
@@ -0,0 +1,908 @@
+/*++
+
+Module Name:
+
+ config.c
+
+Abstract:
+
+ This module contains the functions that save the configuration files
+ into the repair directory, and copy these files to the Emergency
+ Repair disk.
+
+
+Author:
+
+ Jaime Sasson
+
+Environment:
+
+ Windows
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+#define SYSTEM_HIVE (LPWSTR)L"system"
+#define SOFTWARE_HIVE (LPWSTR)L"software"
+#define SECURITY_HIVE (LPWSTR)L"security"
+#define SAM_HIVE (LPWSTR)L"sam"
+#define DEFAULT_USER_HIVE (LPWSTR)L".default"
+#define DEFAULT_USER_HIVE_FILE (LPWSTR)L"default"
+#define NTUSER_HIVE_FILE (LPWSTR)L"ntuser.dat"
+#define REPAIR_DIRECTORY (LPWSTR)L"\\repair"
+#define PROFILES_DIRECTORY (LPWSTR)L"\\profiles"
+#define SETUP_LOG_FILE (LPWSTR)L"setup.log"
+
+#define SYSTEM_COMPRESSED_FILE_NAME ( LPWSTR )L"system._"
+#define SOFTWARE_COMPRESSED_FILE_NAME ( LPWSTR )L"software._"
+#define SOFTWARE_COMPRESSED_FILE_NAME ( LPWSTR )L"software._"
+#define SECURITY_COMPRESSED_FILE_NAME ( LPWSTR )L"security._"
+#define SAM_COMPRESSED_FILE_NAME ( LPWSTR )L"sam._"
+#define DEFAULT_COMPRESSED_FILE_NAME ( LPWSTR )L"default._"
+#define NTUSER_COMPRESSED_FILE_NAME ( LPWSTR )L"ntuser.da_"
+#define AUTOEXEC_NT_FILE_NAME ( LPWSTR )L"autoexec.nt"
+#define CONFIG_NT_FILE_NAME ( LPWSTR )L"config.nt"
+
+
+//
+// Relative costs to perform various actions,
+// to help make the gas gauge mean something.
+//
+#define COST_SAVE_HIVE 3
+#define COST_COMPRESS_HIVE 20
+#define COST_SAVE_VDM_FILE 1
+
+
+typedef enum _OPERATION_TYPE {
+ SaveConfiguration,
+ CopyConfigurationFiles,
+ } OPERATION_TYPE;
+
+typedef struct _PROGRESS_PARAMETERS {
+ OPERATION_TYPE OperationType;
+ WCHAR DriveLetter;
+ } PROGRESS_PARAMETERS, *PPROGRESS_PARAMETERS;
+
+typedef struct _THREAD_ARGUMENTS {
+ HWND hWnd;
+ WCHAR DriveLetter;
+ } THREAD_ARGUMENTS, *PTHREAD_ARGUMENTS;
+
+//
+// Structure used in the array of hives to be saved.
+// This structure contains the predefined key that contains the hive
+// to be saved, and the name of the hive root, and the name of the file
+// where the hive should be saved.
+//
+
+typedef struct _HIVE_INFO {
+ HKEY PredefinedKey;
+ PWSTR HiveName;
+ PWSTR FileName;
+ } HIVE_INFO, *PHIVE_INFO;
+
+
+FCenterDialogOnDesktop(HWND);
+
+BOOL
+NotifyCB(
+ IN PSTR src,
+ IN PSTR dst,
+ IN WORD code
+ )
+{
+ UNREFERENCED_PARAMETER(src);
+ UNREFERENCED_PARAMETER(dst);
+ UNREFERENCED_PARAMETER(code);
+ return(TRUE);
+}
+
+DWORD
+SaveOneHive(
+ IN LPWSTR DirectoryName,
+ IN LPWSTR HiveName,
+ IN HKEY hkey,
+ IN HWND hWnd,
+ IN OUT PDWORD GaugePosition,
+ IN DWORD GaugeDeltaUnit
+ )
+
+/*++
+
+Routine Description:
+
+ Save one registry hive. The way we will do this is to do a RegSaveKey
+ of the hive into a temporary localtion, and then call the LZ apis to
+ compress the file from that temporary location to the floppy.
+
+ LZ must have already been initialized via InitGloablBuffersEx()
+ BEFORE calling this routine.
+
+Arguments:
+
+ DirectoryName - Full path of the directory where the hive will be saved.
+
+ HiveName - base name of the hive file to save. The file will end up
+ compressed on disk with the name <HiveName>._.
+
+ hkey - supplies handle to open key of root of hive to save.
+
+ GaugePosition - in input, supplies current position of the gas gauge.
+ On output, supplies new position of gas gauge.
+
+ GaugeDeltaUnit - supplies cost of one unit of activity.
+
+Return Value:
+
+ DWORD - Return ERROR_SUCCESS if the hive was saved. Otherwise, it returns
+ an error code.
+
+--*/
+
+{
+ DWORD Status;
+ WCHAR SaveFilename[ MAX_PATH + 1 ];
+ WCHAR CompressPath[ MAX_PATH + 1 ];
+ CHAR SaveFilenameAnsi[ MAX_PATH + 1 ];
+ CHAR CompressPathAnsi[ MAX_PATH + 1 ];
+ LPWSTR TempName = ( LPWSTR )L"\\$$hive$$.tmp";
+
+ //
+ // Create the name of the file into which we will save the
+ // uncompressed hive.
+ //
+
+ wsprintf(SaveFilename,L"%ls\\$$hive$$.tmp",DirectoryName);
+ wsprintfA(SaveFilenameAnsi,"%ls\\$$hive$$.tmp",DirectoryName);
+
+ //
+ // Delete the file just in case, because RegSaveKey will fail if the file
+ // already exists.
+ //
+ SetFileAttributes(SaveFilename,FILE_ATTRIBUTE_NORMAL);
+ DeleteFile(SaveFilename);
+
+ //
+ // Save the registry hive into the temporary file.
+ //
+ Status = RegSaveKey(hkey,SaveFilename,NULL);
+
+ //
+ // Update the gas gauge.
+ //
+ *GaugePosition += GaugeDeltaUnit * COST_SAVE_HIVE;
+ SendDlgItemMessage( hWnd,
+ ID_BAR,
+ PBM_SETPOS,
+ *GaugePosition,
+ 0L
+ );
+
+ //
+ // If the hive was saved successfully, then compress it and update
+ // the gas gauge. Otherwise, update the gas gauge and return.
+ //
+
+ if(Status == ERROR_SUCCESS) {
+ //
+ // Form the name of the file into which the saved hive file is
+ // to be compressed.
+ //
+ wsprintf(CompressPath,L"%ls\\%ls._",DirectoryName,HiveName);
+ wsprintfA(CompressPathAnsi,"%ls\\%ls._",DirectoryName,HiveName );
+
+ //
+ // Delete the destination file just in case.
+ //
+ SetFileAttributes(CompressPath,FILE_ATTRIBUTE_NORMAL);
+ DeleteFile(CompressPath);
+
+ //
+ // Compress the hive into the destination file.
+ //
+ Status = DiamondCompressFile(
+ SaveFilenameAnsi,
+ CompressPathAnsi,
+ *GaugePosition,
+ GaugeDeltaUnit * COST_COMPRESS_HIVE,
+ hWnd
+ );
+
+ //
+ // Delete the temporary saved hive.
+ //
+ SetFileAttributes(SaveFilename,FILE_ATTRIBUTE_NORMAL);
+ DeleteFile(SaveFilename);
+ }
+
+ *GaugePosition += GaugeDeltaUnit * COST_COMPRESS_HIVE;
+ SendDlgItemMessage( hWnd,
+ ID_BAR,
+ PBM_SETPOS,
+ *GaugePosition,
+ 0L
+ );
+
+ return(Status);
+}
+
+
+VOID
+SaveConfigurationWorker(
+ IN PTHREAD_ARGUMENTS Arguments
+ )
+
+/*++
+
+Routine Description:
+
+ This routine implements the thread that saves all system configuration
+ files into the repair directory. It first saves and compresses the
+ registry hives, and then it save the VDM configuration files (autoexec.nt
+ and config.nt).
+ If the application is running in the SilentMode (invoked by setup),
+ then system, software, default, security and sam hives will be saved
+ and compressed.
+ If the application was invoked by the user, then only system, software
+ and default will be saved.
+
+ This thread will send messages to the gas gauge dialog prcedure, so that
+ the gas gauge gets updated after each configuration file is saved.
+ This thread will also inform the user about errors that might have
+ occurred during the process of saving the configuration files.
+
+Arguments:
+
+ Arguments - Pointer to a structure that contains the parameters to be passed to
+ thread.
+
+
+Return Value:
+
+ None.
+ However, the this routine will send a message to the dialog procedure
+ that created the thread, informing the outcome the operation.
+
+--*/
+
+{
+ DWORD i;
+ HKEY hkey;
+ BOOL ErrorOccurred;
+ CHAR SourceUserHivePathAnsi[ MAX_PATH + 1 ];
+ CHAR CompressedUserHivePathAnsi[ MAX_PATH + 1 ];
+ WCHAR ProfilesDirectory[ MAX_PATH + 1 ];
+ WCHAR RepairDirectory[ MAX_PATH + 1 ];
+ WCHAR SystemDirectory[ MAX_PATH + 1 ];
+ WCHAR Source[ MAX_PATH + 1 ];
+ WCHAR Target[ MAX_PATH + 1 ];
+ DWORD GaugeDeltaUnit;
+ DWORD GaugePosition;
+ DWORD NumberOfHivesToSave;
+ DWORD NumberOfUserHivesToSave;
+ DWORD NumberOfVdmFiles;
+ HWND hWnd;
+ DWORD Error;
+ DWORD Status;
+ HANDLE Token;
+ BOOL b;
+ TOKEN_PRIVILEGES NewPrivileges;
+ LUID Luid;
+
+ //
+ // The array below contains the location and name of all hives that
+ // we need to save. When the utility is operating on the silent mode,
+ // (invoked from setup), then all hives will be saved. Otherwise, only
+ // system and software will be saved.
+ // For this reason, do not change the order of the hives in the array
+ // below. System and software must be the first elements of
+ // the array.
+ //
+ HIVE_INFO HiveList[] = { { HKEY_LOCAL_MACHINE, SYSTEM_HIVE, SYSTEM_HIVE },
+ { HKEY_LOCAL_MACHINE, SOFTWARE_HIVE, SOFTWARE_HIVE },
+ { HKEY_USERS, DEFAULT_USER_HIVE, DEFAULT_USER_HIVE_FILE },
+ { HKEY_LOCAL_MACHINE, SECURITY_HIVE, SECURITY_HIVE },
+ { HKEY_LOCAL_MACHINE, SAM_HIVE, SAM_HIVE }
+ };
+
+
+ PWSTR VdmFiles[] = {
+ AUTOEXEC_NT_FILE_NAME,
+ CONFIG_NT_FILE_NAME
+ };
+
+
+ Error = ERROR_SUCCESS;
+ hWnd = Arguments->hWnd;
+
+ ErrorOccurred = FALSE;
+ //
+ // Compute the cost of saving the hives and vdm files.
+ // For every hive we save, we have to save a key into a file and then
+ // compress the file. After each of these tasks is completed, we upgrade
+ // the gas gauge by the amount dicated by the COST_xxx values.
+ // The cost of saving the hives depends on the mode that the utility is
+ // running.
+ // In the silent mode we save system, software, security, sam and default.
+ // In the non-silent mode, we save system and software only.
+ //
+ NumberOfHivesToSave = ( _SilentMode )?
+ sizeof( HiveList ) / sizeof( HIVE_INFO ) :
+ (sizeof( HiveList ) / sizeof( HIVE_INFO ))-3;
+ NumberOfUserHivesToSave = 1;
+ NumberOfVdmFiles = sizeof( VdmFiles ) / sizeof( PWSTR );
+
+ GaugeDeltaUnit = GAUGE_BAR_RANGE / ( (COST_SAVE_HIVE * NumberOfHivesToSave)
+ + (COST_COMPRESS_HIVE * NumberOfHivesToSave)
+ + (COST_COMPRESS_HIVE * NumberOfUserHivesToSave)
+ + (COST_SAVE_VDM_FILE * NumberOfVdmFiles));
+
+ GaugePosition = 0;
+
+ //
+ // Enable BACKUP privilege
+ //
+ if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&Token)) {
+
+ if(LookupPrivilegeValue(NULL,SE_BACKUP_NAME,&Luid)) {
+
+ NewPrivileges.PrivilegeCount = 1;
+ NewPrivileges.Privileges[0].Luid = Luid;
+ NewPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ AdjustTokenPrivileges(Token,FALSE,&NewPrivileges,0,NULL,NULL);
+ }
+ }
+
+ GetWindowsDirectory( RepairDirectory, sizeof( RepairDirectory ) / sizeof( WCHAR ) );
+ lstrcpy( ProfilesDirectory, RepairDirectory );
+ lstrcat( RepairDirectory, REPAIR_DIRECTORY );
+ lstrcat( ProfilesDirectory, PROFILES_DIRECTORY );
+
+ GetSystemDirectory( SystemDirectory, sizeof( SystemDirectory ) / sizeof( WCHAR ) );
+
+ //
+ // Make sure that the repair directory already exists.
+ // If it doesn't exist, then create one.
+ //
+ if( CreateDirectory( RepairDirectory, NULL ) ||
+ ( ( Error = GetLastError() ) == ERROR_ALREADY_EXISTS ) ||
+ ( Error == ERROR_ACCESS_DENIED )
+ ) {
+ //
+ // If the repair directory didn't exist and we were able to create it,
+ // or if the repair directory already exists, then save and compress
+ // the hives.
+ //
+
+ Error = ERROR_SUCCESS;
+ for( i=0; i < NumberOfHivesToSave; i++ ) {
+ //
+ // First open the root of the hive to be saved
+ //
+ Status = RegOpenKeyEx( HiveList[i].PredefinedKey,
+ HiveList[i].HiveName,
+ REG_OPTION_RESERVED,
+ READ_CONTROL,
+ &hkey );
+
+ //
+ // If unable to open the key, update the gas gauge to reflect
+ // that the operation on this hive was completed.
+ // Otherwise, save the hive. Note that Save hive will update
+ // the gas gauge, as it saves and compresses the hive.
+ //
+ if(Status != ERROR_SUCCESS) {
+ //
+ // If this is the first error while saving the hives,
+ // then save the error code, so that we can display the
+ // correct error message to the user.
+ //
+ if( Error == ERROR_SUCCESS ) {
+ Error = Status;
+ }
+
+ //
+ // Update the gas gauge
+ //
+ GaugePosition += GaugeDeltaUnit * (COST_SAVE_HIVE + COST_COMPRESS_HIVE);
+ SendMessage( hWnd,
+ AP_UPDATE_GAUGE,
+ GaugePosition,
+ 0L );
+
+ } else {
+ //
+ // Save and compress the hive.
+ // Note that the gas gauge will up be updated by SaveOneHive
+ // Note also that when we save the default user hive, we skip
+ // the first character of the
+ //
+
+ Status = SaveOneHive(RepairDirectory,
+ HiveList[i].FileName,
+ hkey,
+ hWnd,
+ &GaugePosition,
+ GaugeDeltaUnit );
+ //
+ // If this is the first error while saving the hives,
+ // then save the error code, so that we can display the
+ // correct error message to the user.
+ //
+
+ if( Error == ERROR_SUCCESS ) {
+ Error = Status;
+ }
+
+ RegCloseKey(hkey);
+ }
+ }
+
+ //
+ // Save the hive for the Default User
+ //
+
+ wsprintfA(SourceUserHivePathAnsi,"%ls\\%ls\\%ls",ProfilesDirectory,L"Default User",NTUSER_HIVE_FILE);
+ wsprintfA(CompressedUserHivePathAnsi,"%ls\\%ls",RepairDirectory,NTUSER_COMPRESSED_FILE_NAME);
+
+ //
+ // Delete the destination file just in case.
+ //
+ SetFileAttributesA(CompressedUserHivePathAnsi,FILE_ATTRIBUTE_NORMAL);
+ DeleteFileA(CompressedUserHivePathAnsi);
+
+ //
+ // Compress the hive into the destination file.
+ //
+ Status = DiamondCompressFile(
+ SourceUserHivePathAnsi,
+ CompressedUserHivePathAnsi,
+ GaugePosition,
+ GaugeDeltaUnit * COST_COMPRESS_HIVE,
+ hWnd
+ );
+ if( Status != ERROR_SUCCESS ) {
+ if( Error == ERROR_SUCCESS ) {
+ Error = Status;
+ }
+ }
+
+ GaugePosition += GaugeDeltaUnit * COST_COMPRESS_HIVE;
+ SendDlgItemMessage( hWnd,
+ ID_BAR,
+ PBM_SETPOS,
+ GaugePosition,
+ 0L
+ );
+
+
+ //
+ // Now that the hives are saved, save the vdm files
+ //
+
+ for( i = 0; i < NumberOfVdmFiles; i++ ) {
+ wsprintf(Source,L"%ls\\%ls",SystemDirectory,VdmFiles[i]);
+ wsprintf(Target,L"%ls\\%ls",RepairDirectory,VdmFiles[i]);
+ if( !CopyFile( Source, Target, FALSE ) ) {
+ Status = GetLastError();
+ if( Error != ERROR_SUCCESS ) {
+ Error = Status;
+ }
+ }
+ GaugePosition += GaugeDeltaUnit * COST_SAVE_VDM_FILE;
+ SendMessage( ( HWND )hWnd,
+ AP_UPDATE_GAUGE,
+ GaugePosition,
+ 0L );
+
+ }
+ }
+
+
+ //
+ // At this point, the operation was completed (successfully, or not).
+ // So update the gas gauge to 100%
+ //
+ SendMessage(hWnd,AP_UPDATE_GAUGE,GAUGE_BAR_RANGE,0L);
+
+ if( Error != ERROR_SUCCESS && !_SilentMode ) {
+ DisplayMsgBox(hWnd,
+ IDS_CANT_SAVE_CONFIGURATION,
+ MB_OK | MB_ICONEXCLAMATION,
+ _szApplicationName);
+ } else {
+ Sleep( 200 );
+ }
+
+ SendMessage( ( HWND )hWnd,
+ AP_TASK_COMPLETED,
+ (WPARAM)(Error == ERROR_SUCCESS),
+ 0L );
+ ExitThread( 0 );
+}
+
+VOID
+CopyFilesWorker(
+ IN PTHREAD_ARGUMENTS Arguments
+ )
+
+/*++
+
+Routine Description:
+
+ This routine implements the thread that copiess all configuration information
+ from the repair directory to the repair disk.
+
+ This thread will send messages to the gas gauge dialog prcedure, so that
+ the gas gauge gets updated after each configuration file is copied.
+ This thread will also inform the user about errors that might have
+ occurred during the process of saving the configuration files.
+
+
+Arguments:
+
+ Arguments - Pointer to a structure that contains the parameters to be passed to
+ thread.
+
+
+Return Value:
+
+ None.
+ However, the this routine will send a message to the dialog procedure
+ that created the thread, informing the outcome the operation.
+
+--*/
+
+{
+ HWND hWnd;
+ WCHAR Drive;
+ WCHAR Buffer[ MAX_PATH + 1 ];
+ WCHAR Source[ MAX_PATH + 1 ];
+ WCHAR Target[ MAX_PATH + 1 ];
+ DWORD i;
+ DWORD GaugePosition = 0;
+ BOOLEAN AllFilesCopied = TRUE;
+ DWORD Error;
+
+
+ LPWSTR FileNames[] = { SETUP_LOG_FILE,
+ SYSTEM_COMPRESSED_FILE_NAME,
+ SOFTWARE_COMPRESSED_FILE_NAME,
+ SECURITY_COMPRESSED_FILE_NAME,
+ SAM_COMPRESSED_FILE_NAME,
+ DEFAULT_COMPRESSED_FILE_NAME,
+ NTUSER_COMPRESSED_FILE_NAME,
+ AUTOEXEC_NT_FILE_NAME,
+ CONFIG_NT_FILE_NAME
+ };
+
+ DWORD DeltaCompleted = GAUGE_BAR_RANGE / ( sizeof( FileNames )/sizeof( PWSTR ) );
+
+ hWnd = Arguments->hWnd;
+ Drive = Arguments->DriveLetter;
+
+ GetWindowsDirectory( Buffer, sizeof( Buffer ) / sizeof( WCHAR ) );
+ for( i=0;
+ i < ( sizeof( FileNames )/sizeof( PWCHAR ) );
+ i++) {
+
+ wsprintf(Source,L"%ls\\repair\\%ls",Buffer,FileNames[i] );
+ wsprintf(Target,L"%wc:\\%ls",Drive,FileNames[i]);
+
+ if( !CopyFile( Source, Target, FALSE ) ) {
+ AllFilesCopied = FALSE;
+ Error = GetLastError();
+ }
+ GaugePosition += DeltaCompleted;
+ SendMessage( ( HWND )hWnd,
+ AP_UPDATE_GAUGE,
+ GaugePosition,
+ 0L
+ );
+ }
+ SendMessage( ( HWND )hWnd,
+ AP_UPDATE_GAUGE,
+ GAUGE_BAR_RANGE,
+ 0L
+ );
+
+ if( !AllFilesCopied && !_SilentMode ) {
+ DWORD MsgId;
+
+ if( Error == ERROR_FILE_NOT_FOUND ) {
+ MsgId = IDS_FILE_NOT_FOUND;
+ } else if( Error == ERROR_DISK_FULL ) {
+ MsgId = IDS_DISK_FULL;
+ } else {
+ MsgId = IDS_UNABLE_TO_COPY_ALL_FILES;
+ }
+ DisplayMsgBox(hWnd,MsgId,MB_OK | MB_ICONEXCLAMATION,_szApplicationName);
+ } else {
+ Sleep( 200 );
+ }
+ SendMessage( ( HWND )hWnd,
+ AP_TASK_COMPLETED,
+ (WPARAM)AllFilesCopied,
+ 0L
+ );
+
+ ExitThread(0);
+}
+
+BOOL
+Progress2DlgProc(
+ IN HWND hdlg,
+ IN UINT Msg,
+ IN WPARAM wParam,
+ IN LONG lParam
+ )
+/*++
+
+Routine Description:
+
+ Dialog procedure for the dialog that contains the gas gauge that is
+ displayed while the utility is saving the system configuration, and
+ while it is copying the configuration information to the repair disk.
+
+Arguments:
+
+ Standard Windows' Proc parameters.
+
+Return Value:
+
+ long - Returns 0 if the message was handled.
+
+--*/
+
+{
+ static THREAD_ARGUMENTS ThreadArguments;
+
+ switch(Msg) {
+
+ case WM_INITDIALOG:
+ {
+ WCHAR Buffer[MAX_PATH];
+ LPTHREAD_START_ROUTINE StartAddress;
+ DWORD ThreadId;
+ PPROGRESS_PARAMETERS Parameters;
+
+ Parameters = ( PPROGRESS_PARAMETERS )lParam;
+
+ //
+ // set up range for percentage (0-100) display
+ //
+ SendDlgItemMessage(hdlg,ID_BAR,PBM_SETRANGE,0,MAKELPARAM(0,GAUGE_BAR_RANGE));
+
+ //
+ // Set the caption
+ //
+ switch( Parameters->OperationType ) {
+
+ case SaveConfiguration:
+
+ LoadString( _hModule,
+ IDS_SAVING_CONFIGURATION,Buffer,
+ sizeof(Buffer)/sizeof(WCHAR) );
+ StartAddress = ( LPTHREAD_START_ROUTINE )SaveConfigurationWorker;
+ break;
+
+ case CopyConfigurationFiles:
+
+ LoadString( _hModule,
+ IDS_COPYING_FILES,
+ Buffer,sizeof(Buffer)/sizeof(WCHAR) );
+ StartAddress = ( LPTHREAD_START_ROUTINE )CopyFilesWorker;
+ break;
+
+ default:
+ //
+ // Error condition!!
+ // Do something here
+ //
+ break;
+ }
+
+ SetWindowText( hdlg, Buffer);
+
+ //
+ // center the dialog relative to the desk top
+ //
+ FCenterDialogOnDesktop(hdlg);
+
+ ThreadArguments.hWnd = hdlg;
+ ThreadArguments.DriveLetter = Parameters->DriveLetter;
+ CreateThread( NULL,
+ 1024,
+ StartAddress,
+ &ThreadArguments,
+ 0,
+ &ThreadId );
+ break;
+ }
+
+ case AP_UPDATE_GAUGE:
+ SendDlgItemMessage( hdlg,
+ ID_BAR,
+ PBM_SETPOS,
+ wParam,
+ 0L );
+ break;
+
+ case AP_TASK_COMPLETED:
+ {
+ BOOLEAN MessagePosted;
+
+ SendDlgItemMessage( hdlg,
+ ID_BAR,
+ PBM_SETPOS,
+ GAUGE_BAR_RANGE,
+ 0L );
+ MessagePosted = FALSE;
+ while( !MessagePosted ) {
+ MessagePosted = PostMessage( hdlg,
+ AP_TERMINATE_DIALOG,
+ wParam,
+ 0 );
+ }
+ break;
+ }
+
+ case AP_TERMINATE_DIALOG:
+
+ EndDialog(hdlg, wParam);
+ break;
+
+ default:
+
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+
+BOOLEAN
+CopyFilesToRepairDisk(
+ IN WCHAR Drive
+ )
+
+/*++
+
+Routine Description:
+
+ Copy the files in the repair directory, to the emergency repair disk.
+
+Arguments:
+
+ Drive - Drive where the repair disk is.
+
+Return Value:
+
+ BOOLEAN - Returns TRUE if the operation succeeded, or FALSE otherwise.
+
+--*/
+
+{
+ PROGRESS_PARAMETERS Parameters;
+ BOOLEAN Result;
+
+ Parameters.OperationType = CopyConfigurationFiles;
+ Parameters.DriveLetter = Drive;
+
+ Result = (BOOLEAN)DialogBoxParam( _hModule,
+ MAKEINTRESOURCE( IDD_PROGRESS2 ),
+ _hWndMain,
+ ( DLGPROC )Progress2DlgProc,
+ ( LPARAM )&Parameters
+ );
+ return( Result );
+}
+
+
+BOOLEAN
+DetectConfigFilesInRepairDirectory(
+ )
+
+/*++
+
+Routine Description:
+
+ Determine whether or not the the repair directory contains at
+ least one configuration file.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ BOOLEAN - Returns TRUE if at least one configuration file is present.
+ Returns FALSE if no configuration files are present.
+
+
+--*/
+
+{
+ HANDLE Handle;
+ WIN32_FIND_DATA FindData;
+ WCHAR RepairDirectory[ MAX_PATH + 1];
+ WCHAR FileName[ MAX_PATH + 1];
+ DWORD i;
+ BOOLEAN AtLeastOneFilePresent = FALSE;
+
+ LPWSTR ConfigurationFiles[] = { AUTOEXEC_NT_FILE_NAME,
+ CONFIG_NT_FILE_NAME,
+ SYSTEM_COMPRESSED_FILE_NAME,
+ SOFTWARE_COMPRESSED_FILE_NAME,
+ SECURITY_COMPRESSED_FILE_NAME,
+ SAM_COMPRESSED_FILE_NAME,
+ DEFAULT_COMPRESSED_FILE_NAME,
+ NTUSER_COMPRESSED_FILE_NAME
+ };
+
+ GetWindowsDirectory( RepairDirectory, sizeof( RepairDirectory ) / sizeof( WCHAR ) );
+ wcscat( RepairDirectory, REPAIR_DIRECTORY );
+ for( i = 0;
+ i < sizeof( ConfigurationFiles ) / sizeof( PWSTR );
+ i++ ) {
+ wsprintf(FileName,L"%ls\\%ls",RepairDirectory,ConfigurationFiles[i]);
+
+ if( ( Handle = FindFirstFile(FileName, &FindData) ) != INVALID_HANDLE_VALUE ) {
+ AtLeastOneFilePresent = TRUE;
+ FindClose( Handle );
+ break;
+ }
+ }
+ return( AtLeastOneFilePresent );
+}
+
+
+BOOLEAN
+SaveCurrentConfiguration(
+ )
+
+/*++
+
+Routine Description:
+
+ Save all files that contain the current system configuration, into
+ the repair directory.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ BOOLEAN - Returns TRUE if the operation succeeded, or FALSE otherwise.
+
+--*/
+
+
+{
+ PROGRESS_PARAMETERS Parameters;
+ BOOLEAN Result;
+
+ Result = FALSE;
+ if( _SilentMode ||
+ !DetectConfigFilesInRepairDirectory() ||
+ ( DisplayMsgBox( _hWndMain,
+ IDS_CONFIRM_SAVE_CONFIGURATION,
+ MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2 ) == IDYES ) ) {
+
+ Parameters.OperationType = SaveConfiguration;
+ Parameters.DriveLetter = ( WCHAR )'\0';
+
+ Result = (BOOLEAN)DialogBoxParam( _hModule,
+ MAKEINTRESOURCE( IDD_PROGRESS2 ),
+ _hWndMain,
+ ( DLGPROC )Progress2DlgProc,
+ ( LPARAM )&Parameters
+ );
+ }
+ return( Result );
+}
+
diff --git a/private/utils/rdisk/dialogs.dlg b/private/utils/rdisk/dialogs.dlg
new file mode 100644
index 000000000..108f846e8
--- /dev/null
+++ b/private/utils/rdisk/dialogs.dlg
@@ -0,0 +1,27 @@
+1 DLGINCLUDE "dialogs.H"
+#include <commctrl.h>
+
+IDD_PROGRESS2 DIALOG 65, 85, 210, 30
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+STYLE WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "", ID_BAR, PROGRESS_CLASS, 0x0000, 15, 10, 180, 10
+END
+
+
+IDD_REPAIR DIALOG 11, 18, 329, 86
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+STYLE WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Repair Disk Utility"
+FONT 8, "MS Shell Dlg"
+CLASS "Repair"
+BEGIN
+ ICON 200, IDI_MAIN_DLG_ICON, 16, 10, 18, 20
+ LTEXT "This utility updates the repair information saved when you installed the system, and creates an Emergency Repair disk. The repair information is used to recover a bootable system in case of failure. This utility should not be used as a backup tool.",
+ IDT_INFO_LINE, 45, 10, 258, 34
+ DEFPUSHBUTTON "&Update Repair Info", IDB_SAVE_CURRENT_INFO, 11, 63, 70, 14
+ PUSHBUTTON "&Create Repair Disk", IDB_CREATE_DISK, 90, 63, 70, 14
+ PUSHBUTTON "E&xit", IDB_EXIT, 169, 63, 70, 14
+ PUSHBUTTON "&Help", IDB_HELP, 248, 63, 70, 14
+END
diff --git a/private/utils/rdisk/dialogs.h b/private/utils/rdisk/dialogs.h
new file mode 100644
index 000000000..a69534d29
--- /dev/null
+++ b/private/utils/rdisk/dialogs.h
@@ -0,0 +1,10 @@
+#define IDD_PROGRESS2 1000
+#define ID_BAR 1001
+#define IDD_REPAIR 100
+#define IDB_SAVE_CURRENT_INFO 101
+#define IDB_CREATE_DISK 102
+#define IDB_HELP 103
+#define ID_GAS_GAUGE 104
+#define IDT_INFO_LINE 105
+#define IDI_MAIN_DLG_ICON 106
+#define IDB_EXIT 108
diff --git a/private/utils/rdisk/diamond.c b/private/utils/rdisk/diamond.c
new file mode 100644
index 000000000..4e77dae2d
--- /dev/null
+++ b/private/utils/rdisk/diamond.c
@@ -0,0 +1,476 @@
+/*++
+
+Module Name:
+
+ diamond.c
+
+Abstract:
+
+ Diamond compression interface.
+
+ This module contains functions to compress a file using
+ the mszip compression library.
+
+Author:
+
+ Ted Miller
+
+Environment:
+
+ Windows
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+typedef struct _COMPRESS_CONTEXT {
+ DWORD GaugeBasePosition;
+ DWORD GaugeRangeForFile;
+ HWND GaugeWindow;
+ DWORD FileSize;
+ DWORD BytesCompressedSoFar;
+} COMPRESS_CONTEXT, *PCOMPRESS_CONTEXT;
+
+DWORD DiamondLastError;
+
+//
+// Callback functions to perform memory allocation, io, etc.
+// We pass addresses of these functions to diamond.
+//
+int
+DIAMONDAPI
+fciFilePlacedCB(
+ OUT PCCAB Cabinet,
+ IN PSTR FileName,
+ IN LONG FileSize,
+ IN BOOL Continuation,
+ IN PVOID Context
+ )
+
+/*++
+
+Routine Description:
+
+ Callback used by diamond to indicate that a file has been
+ comitted to a cabinet.
+
+ No action is taken and success is returned.
+
+Arguments:
+
+ Cabinet - cabinet structure to fill in.
+
+ FileName - name of file in cabinet
+
+ FileSize - size of file in cabinet
+
+ Continuation - TRUE if this is a partial file, continuation
+ of compression begun in a different cabinet.
+
+ Context - supplies context information.
+
+Return Value:
+
+ 0 (success).
+
+--*/
+
+{
+ UNREFERENCED_PARAMETER(Cabinet);
+ UNREFERENCED_PARAMETER(FileName);
+ UNREFERENCED_PARAMETER(FileSize);
+ UNREFERENCED_PARAMETER(Continuation);
+ UNREFERENCED_PARAMETER(Context);
+
+ return(0);
+}
+
+
+
+PVOID
+DIAMONDAPI
+fciAllocCB(
+ IN ULONG NumberOfBytes
+ )
+
+/*++
+
+Routine Description:
+
+ Callback used by diamond to allocate memory.
+
+Arguments:
+
+ NumberOfBytes - supplies desired size of block.
+
+Return Value:
+
+ Returns pointer to a block of memory or NULL
+ if memory cannot be allocated.
+
+--*/
+
+{
+ return((PVOID)LocalAlloc(LMEM_FIXED,NumberOfBytes));
+}
+
+
+VOID
+DIAMONDAPI
+fciFreeCB(
+ IN PVOID Block
+ )
+
+/*++
+
+Routine Description:
+
+ Callback used by diamond to free a memory block.
+ The block must have been allocated with fciAlloc().
+
+Arguments:
+
+ Block - supplies pointer to block of memory to be freed.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ LocalFree((HLOCAL)Block);
+}
+
+
+
+BOOL
+DIAMONDAPI
+fciTempFileCB(
+ OUT PSTR TempFileName,
+ IN int TempFileNameBufferSize
+ )
+
+/*++
+
+Routine Description:
+
+ Callback used by diamond to request a tempfile name.
+
+Arguments:
+
+ TempFileName - receives temp file name.
+
+ TempFileNameBufferSize - supplies size of memory block
+ pointed to by TempFileName.
+
+Return Value:
+
+ TRUE (success).
+
+--*/
+
+{
+ UNREFERENCED_PARAMETER(TempFileNameBufferSize);
+
+ if(GetTempFileNameA(".","dc",0,TempFileName)) {
+ //
+ // GetTempFileNameA will create the file, causing
+ // FCI to fail when it tries to open it using _O_EXCL.
+ //
+ DeleteFileA(TempFileName);
+ }
+
+ return(TRUE);
+}
+
+
+BOOL
+DIAMONDAPI
+fciNextCabinetCB(
+ OUT PCCAB Cabinet,
+ IN DWORD CabinetSizeEstimate,
+ IN PVOID Context
+ )
+
+/*++
+
+Routine Description:
+
+ Callback used by diamond to request a new cabinet file.
+ This functionality is not used in our implementation as
+ we deal only with single-file cabinets.
+
+Arguments:
+
+ Cabinet - cabinet structure to be filled in.
+
+ CabinetSizeEstimate - estimated size of cabinet.
+
+ Context - supplies context information.
+
+Return Value:
+
+ FALSE (failure).
+
+--*/
+
+{
+ UNREFERENCED_PARAMETER(Cabinet);
+ UNREFERENCED_PARAMETER(CabinetSizeEstimate);
+ UNREFERENCED_PARAMETER(Context);
+
+ return(FALSE);
+}
+
+
+BOOL
+DIAMONDAPI
+fciStatusCB(
+ IN UINT StatusType,
+ IN DWORD Count1,
+ IN DWORD Count2,
+ IN PVOID Context
+ )
+
+/*++
+
+Routine Description:
+
+ Callback used by diamond to give status on file compression
+ and cabinet operations, etc.
+
+ This routine has no effect.
+
+Arguments:
+
+ Status Type - supplies status type.
+
+ 0 = statusFile - compressing block into a folder.
+ Count1 = compressed size
+ Count2 = uncompressed size
+
+ 1 = statusFolder - performing AddFilder.
+ Count1 = bytes done
+ Count2 = total bytes
+
+ Context - supplies context info.
+
+Return Value:
+
+ TRUE (success).
+
+--*/
+
+{
+ PCOMPRESS_CONTEXT context;
+ DWORD delta;
+
+ UNREFERENCED_PARAMETER(Count1);
+
+ context = (PCOMPRESS_CONTEXT)Context;
+
+ if(StatusType == statusFile) {
+
+ //
+ // Update number of bytes compressed so far.
+ //
+ context->BytesCompressedSoFar += Count2;
+
+ //
+ // Calculate the gauge offset from the base position
+ // for this file. We do this carefully to avoid overflow.
+ //
+ delta = (DWORD)( (LONGLONG)context->GaugeRangeForFile
+ * (LONGLONG)context->BytesCompressedSoFar
+ / (LONGLONG)context->FileSize);
+
+ //
+ // Update the gas gauge.
+ //
+ SendDlgItemMessage( context->GaugeWindow,
+ ID_BAR,
+ PBM_SETPOS,
+ context->GaugeBasePosition + delta,
+ 0L
+ );
+ }
+
+ return(TRUE);
+}
+
+
+
+int
+DIAMONDAPI
+fciOpenInfoCB(
+ IN PSTR FileName,
+ OUT WORD *DosDate,
+ OUT WORD *DosTime,
+ OUT WORD *FileAttributes,
+ IN PVOID Context
+ )
+
+/*++
+
+Routine Description:
+
+ Callback used by diamond to open a file and retreive information
+ about it.
+
+Arguments:
+
+ FileName - supplies filename of file about which information
+ is desired.
+
+ DosDate - receives last write date of the file if the file exists.
+
+ DosTime - receives last write time of the file if the file exists.
+
+ FileAttributes - receives file attributes if the file exists.
+
+ Context - supplies context information.
+
+Return Value:
+
+ C runtime handle to open file if success; -1 if file could
+ not be located or opened.
+
+--*/
+
+{
+ int h;
+ WIN32_FIND_DATAA FindData;
+ HANDLE FindHandle;
+ PCOMPRESS_CONTEXT context;
+
+ context = Context;
+
+ FindHandle = FindFirstFileA(FileName,&FindData);
+ if(FindHandle == INVALID_HANDLE_VALUE) {
+ DiamondLastError = GetLastError();
+ return(-1);
+ }
+ FindClose(FindHandle);
+
+ context->FileSize = FindData.nFileSizeLow;
+
+ FileTimeToDosDateTime(&FindData.ftLastWriteTime,DosDate,DosTime);
+ *FileAttributes = (WORD)FindData.dwFileAttributes;
+
+ h = _open(FileName,_O_RDONLY | _O_BINARY);
+ if(h == -1) {
+ DiamondLastError = GetLastError();
+ return(-1);
+ }
+
+ return(h);
+}
+
+
+
+DWORD
+DiamondCompressFile(
+ IN PSTR SourceFile,
+ IN PSTR TargetFile,
+ IN DWORD GaugeBasePosition,
+ IN DWORD GaugeRangeForThisFile,
+ IN HWND GaugeNotifyWindow
+ )
+{
+ BOOL b;
+ PSTR SourceFilenamePart,p;
+ HFCI FciContext;
+ ERF FciError;
+ CCAB ccab;
+ COMPRESS_CONTEXT GaugeContext;
+
+ //
+ // Isolate the filename part of the source file.
+ //
+ if(SourceFilenamePart = strrchr(SourceFile,'\\')) {
+ SourceFilenamePart++;
+ } else {
+ SourceFilenamePart = SourceFile;
+ }
+
+ //
+ // Fill in the cabinet structure.
+ //
+ ZeroMemory(&ccab,sizeof(ccab));
+
+ lstrcpyA(ccab.szCabPath,TargetFile);
+ if(p=strrchr(ccab.szCabPath,'\\')) {
+ lstrcpyA(ccab.szCab,++p);
+ *p = 0;
+ } else {
+ lstrcpyA(ccab.szCab,TargetFile);
+ ccab.szCabPath[0] = 0;
+ }
+
+ DiamondLastError = NO_ERROR;
+
+ GaugeContext.GaugeBasePosition = GaugeBasePosition;
+ GaugeContext.GaugeRangeForFile = GaugeRangeForThisFile;
+ GaugeContext.GaugeWindow = GaugeNotifyWindow;
+ GaugeContext.FileSize = 0;
+ GaugeContext.BytesCompressedSoFar = 0;
+
+ //
+ // Compress the file.
+ //
+ FciContext = FCICreate(
+ &FciError,
+ fciFilePlacedCB,
+ fciAllocCB,
+ fciFreeCB,
+ fciTempFileCB,
+ &ccab
+ );
+
+ if(FciContext) {
+
+ b = FCIAddFile(
+ FciContext,
+ SourceFile, // file to add to cabinet.
+ SourceFilenamePart, // filename part, name to store in cabinet.
+ FALSE, // fExecute on extract
+ fciNextCabinetCB, // routine for next cabinet (always fails)
+ fciStatusCB,
+ fciOpenInfoCB,
+ tcompTYPE_MSZIP,
+ &GaugeContext
+ );
+
+ if(b) {
+
+ b = FCIFlushCabinet(
+ FciContext,
+ FALSE,
+ fciNextCabinetCB,
+ fciStatusCB,
+ &GaugeContext
+ );
+
+ }
+
+ FCIDestroy(FciContext);
+ }
+
+ return(b ? NO_ERROR : ((DiamondLastError == NO_ERROR) ? ERROR_INVALID_FUNCTION : DiamondLastError));
+}
+
+
+#if 0
+#include <stdio.h>
+void __cdecl main(int argc,char *argv[])
+{
+
+ if(argc == 3) {
+ DiamondCompressFile(argv[1],argv[2]);
+ } else {
+ printf("bad args\n");
+ }
+}
+#endif
diff --git a/private/utils/rdisk/floppyop.c b/private/utils/rdisk/floppyop.c
new file mode 100644
index 000000000..1195aab97
--- /dev/null
+++ b/private/utils/rdisk/floppyop.c
@@ -0,0 +1,888 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ restore.c
+
+Abstract:
+
+ Code to handle interfacing with fmifs.dll for formatting and copying
+ floppy disks.
+
+Author:
+
+ Ted Miller (tedm) 28-July-1992
+
+Revision History:
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+VOID
+FmifsThread(
+ IN PVOID Arguments
+ );
+
+
+
+/*
+** Purpose:
+** To center a dialog on the desktop window.
+** Arguments:
+** hdlg: Handle to the dialog being centered
+** Returns:
+** fTrue: Centering succeeded.
+** fFalse: Error condition.
+**
+****************************************************************************/
+
+BOOL
+FCenterDialogOnDesktop(
+ HWND hdlg
+ )
+
+{
+
+ RECT DesktopRect, DlgRect;
+ BOOL bStatus;
+ HWND hwMaster ;
+ POINT pt,
+ ptCtr,
+ ptMax,
+ ptDlgSize ;
+ LONG l ;
+
+ ptMax.x = GetSystemMetrics( SM_CXFULLSCREEN ) ;
+ ptMax.y = GetSystemMetrics( SM_CYFULLSCREEN ) ;
+
+ //
+ // Determine area of shell and of dlg
+ //
+ // Center dialog over the "pseudo parent" if there is one.
+ //
+
+// hwMaster = hwPseudoParent
+// ? hwPseudoParent
+// : GetDesktopWindow() ;
+ hwMaster = GetDesktopWindow() ;
+
+ if ( ! GetWindowRect( hwMaster, & DesktopRect ) )
+ return FALSE ;
+
+ if ( ! GetWindowRect( hdlg, & DlgRect ) )
+ return FALSE ;
+
+ ptDlgSize.x = DlgRect.right - DlgRect.left ;
+ ptDlgSize.y = DlgRect.bottom - DlgRect.top ;
+
+ // Attempt to center our dialog on top of the "master" window.
+
+ ptCtr.x = DesktopRect.left + ((DesktopRect.right - DesktopRect.left) / 2) ;
+ ptCtr.y = DesktopRect.top + ((DesktopRect.bottom - DesktopRect.top) / 2) ;
+ pt.x = ptCtr.x - (ptDlgSize.x / 2) ;
+ pt.y = ptCtr.y - (ptDlgSize.y / 2) ;
+
+ // Force upper left corner back onto screen if necessary.
+
+ if ( pt.x < 0 )
+ pt.x = 0 ;
+ if ( pt.y < 0 )
+ pt.y = 0 ;
+
+ // Now check to see if the dialog is getting clipped
+ // to the right or bottom.
+
+ if ( (l = pt.x + ptDlgSize.x) > ptMax.x )
+ pt.x -= l - ptMax.x ;
+ if ( (l = pt.y + ptDlgSize.y) > ptMax.y )
+ pt.y -= l - ptMax.y ;
+
+ if ( pt.x < 0 )
+ pt.x = 0 ;
+ if ( pt.y < 0 )
+ pt.y = 0 ;
+
+ //
+ // center the dialog window in the shell window. Specify:
+ //
+ // SWP_NOSIZE : To ignore the cx,cy params given
+ // SWP_NOZORDER : To ignore the HwndInsert after parameter and retain the
+ // current z ordering.
+ // SWP_NOACTIVATE : To not activate the window.
+ //
+
+ bStatus = SetWindowPos
+ (
+ hdlg,
+ (HWND) NULL,
+ pt.x,
+ pt.y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE
+ );
+
+ //
+ // return Status of operation
+ //
+
+ return(bStatus);
+
+}
+
+
+typedef enum _FLOPPY_OPERATION {
+ FloppyOpFormat,
+#ifdef FLOPPY_COPY
+ FloppyOpDiskcopy,
+#endif
+ FloppyOpMaximum
+} FLOPPY_OPERATION, *PFLOPPY_OPERATION;
+
+
+typedef struct _FLOPPY_OPERATION_PARAMS {
+
+ FLOPPY_OPERATION Operation;
+ WCHAR DriveLetter;
+ FMIFS_MEDIA_TYPE MediaType;
+ UINT CaptionResId;
+ UINT GeneralFailureResId;
+ UINT SrcDiskPromptResId;
+ UINT DstDiskPromptResId;
+
+} FLOPPY_OPERATION_PARAMS, *PFLOPPY_OPERATION_PARAMS;
+
+
+#define WM_FMIFS_CALLBACK (WM_USER+137)
+
+BOOL
+ProgressDlgProc(
+ IN HWND hdlg,
+ IN UINT Msg,
+ IN WPARAM wParam,
+ IN LONG lParam
+ );
+
+BOOLEAN
+FmifsCallbackRoutine(
+ IN FMIFS_PACKET_TYPE PacketType,
+ IN DWORD PacketLength,
+ IN PVOID PacketAddress
+ );
+
+
+HMODULE FmifsModule;
+
+PFMIFS_FORMAT_ROUTINE FmifsFormat;
+#ifdef FLOPPY_COPY
+PFMIFS_DISKCOPY_ROUTINE FmifsDiskCopy;
+#endif
+PFMIFS_QSUPMEDIA_ROUTINE FmifsQuerySupportedMedia;
+
+HWND ProgressDialog;
+
+BOOL
+InitializeFloppySup(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ Initialize the floppy-disk support package for formatting and diskcopying.
+ Load the fmifs dll.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ TRUE if initialization succeeded. FALSE otherwise. It is the caller's
+ responsibility to put up a msg box informing the user of the error.
+
+--*/
+
+{
+ ProgressDialog = NULL;
+
+ if(FmifsModule) {
+ // already initialized
+ return(TRUE);
+ }
+
+ //
+ // Load the fmifs dll.
+ //
+
+ if((FmifsModule = LoadLibrary(TEXT("fmifs"))) == NULL) {
+
+ return(FALSE);
+ }
+
+ //
+ // Get the addresses of relevent entry points.
+ //
+
+ FmifsFormat = (PFMIFS_FORMAT_ROUTINE)GetProcAddress( FmifsModule,
+ (LPCSTR)"Format"
+ );
+
+#ifdef FLOPPY_COPY
+ FmifsDiskCopy = (PFMIFS_DISKCOPY_ROUTINE)GetProcAddress( FmifsModule,
+ TEXT("DiskCopy")
+ );
+#endif
+
+ FmifsQuerySupportedMedia = (PFMIFS_QSUPMEDIA_ROUTINE)GetProcAddress( FmifsModule,
+ (LPCSTR)"QuerySupportedMedia"
+ );
+
+
+ if((FmifsFormat == NULL)
+#ifdef FLOPPY_COPY
+ || (FmifsDiskCopy == NULL)
+#endif
+ || (FmifsQuerySupportedMedia == NULL))
+ {
+ FreeLibrary(FmifsModule);
+ FmifsModule = NULL;
+
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+
+VOID
+TerminateFloppySup(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ Terminate the floppy-disk support package for formatting and diskcopying.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ FreeLibrary(FmifsModule);
+ FmifsModule = NULL;
+}
+
+
+
+BOOL
+FormatFloppyDisk(
+ IN WCHAR DriveLetter,
+ IN HWND hwndOwner,
+ OUT PBOOL Fatal
+ )
+
+/*++
+
+Routine Description:
+
+ Top-level routine to format a floppy in the given drive. A floppy
+ disk must already be in the drive or this routine will fail.
+
+ This routine also makes sure that the drive can handle 1.2 or 1.44 meg
+ disks (ie fail if low-density drive) and format to one of those two
+ densities (ie, no 20.8 scsi flopticals).
+
+Arguments:
+
+ DriveLetter - supplies drive letter of drive to format, A-Z or a-z.
+
+ hwndOwner - supplies handle of window that is to own the progress dlg.
+
+ Fatal - see below.
+
+Return Value:
+
+ TRUE if the format succeeded.
+ FALSE if not. In this case, the Fatal flag will be filled in
+ appropriately -- the user should be allowed to retry in this case.
+
+--*/
+
+{
+ BOOL Flag;
+ WCHAR WideName[3];
+ DWORD cMediaTypes;
+ PFMIFS_MEDIA_TYPE MediaTypes;
+ FMIFS_MEDIA_TYPE MediaType;
+ FLOPPY_OPERATION_PARAMS FloppyOp;
+
+ *Fatal = TRUE;
+
+ //
+ // Determine which format to use (1.2 or 1.44). First determine how big
+ // we need the array of supported types to be, then allocate an array of
+ // that size and call QuerySupportedMedia.
+ //
+
+ WideName[0] = (WCHAR)DriveLetter; // BUGBUG check this
+ WideName[1] = L':';
+ WideName[2] = 0;
+
+ Flag = FmifsQuerySupportedMedia( WideName,
+ NULL,
+ 0,
+ &cMediaTypes
+ );
+
+ if(Flag == FALSE) {
+ *Fatal = FALSE; //allow retry
+ DisplayMsgBox(hwndOwner,
+ IDS_CANTDETERMINEFLOPTYPE,
+ MB_OK | MB_ICONEXCLAMATION,
+ _szApplicationName);
+ return(FALSE);
+ }
+
+ while((MediaTypes = (PFMIFS_MEDIA_TYPE)LocalAlloc(LMEM_FIXED,cMediaTypes * sizeof(FMIFS_MEDIA_TYPE))) == NULL) {
+ //
+ // BUGBUG -
+ //
+ // if(!FHandleOOM(hwndOwner)) {
+ // return(FALSE);
+ // }
+ }
+
+ Flag = FmifsQuerySupportedMedia( WideName,
+ MediaTypes,
+ cMediaTypes,
+ &cMediaTypes
+ );
+
+ if(Flag == FALSE) {
+ *Fatal = FALSE; //allow retry
+ LocalFree(MediaTypes);
+ DisplayMsgBox(hwndOwner,
+ IDS_CANTDETERMINEFLOPTYPE | MB_ICONEXCLAMATION,
+ MB_OK,
+ _szApplicationName);
+ return(FALSE);
+ }
+
+
+ //
+ // Zeroth entry is the highest capacity
+ //
+
+ switch(*MediaTypes) {
+
+ case FmMediaF5_1Pt2_512: // 5.25", 1.2MB, 512 bytes/sector
+
+ MediaType = FmMediaF5_1Pt2_512;
+ break;
+
+ case FmMediaF3_1Pt44_512: // 3.5", 1.44MB, 512 bytes/sector
+
+ MediaType = FmMediaF3_1Pt44_512;
+ break;
+
+ case FmMediaF3_2Pt88_512: // 3.5", 2.88MB, 512 bytes/sector
+ {
+ WCHAR VolumeNameBuffer[MAX_PATH + 1];
+ DWORD VolumeSerialNumber;
+ DWORD MaximumComponentLength;
+ DWORD FileSystemFlags;
+ WCHAR FileSystemName[128];
+ UINT ErrorMode;
+
+ //
+ // If the disk drive is a 2.88 Mb drive, then find out if the disk is formatted
+ // as a 2.88 Mb disk. If it is, then reformat the disk as a 2.88 Mb disk, otherwise,
+ // reformat it as a 1.44 Mb disk
+ //
+
+ //
+ // Initially, assume that the disk format is 1.44 Mb
+ //
+ MediaType = FmMediaF3_1Pt44_512;
+
+ //
+ // Find out whether or not the floppy should be formatted as a 2.88 Mb disk
+ //
+ ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS );
+ if( GetVolumeInformation( (LPWSTR)L"A:\\",
+ VolumeNameBuffer,
+ sizeof( VolumeNameBuffer ) / sizeof( WCHAR ),
+ &VolumeSerialNumber,
+ &MaximumComponentLength,
+ &FileSystemFlags,
+ FileSystemName,
+ sizeof( FileSystemName ) / sizeof( WCHAR ) ) &&
+ ( _wcsicmp( FileSystemName, (LPWSTR)L"RAW" ) != 0 )
+ ) {
+
+ //
+ // The disk is formatted. Check if it is formatted as a 2.88 Mb disk
+ //
+ DWORD BytesReturned;
+ DISK_GEOMETRY DiskGeometry;
+ HANDLE hDevice;
+
+
+ if( ( hDevice = CreateFile( L"\\\\.\\A:",
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL ) ) != INVALID_HANDLE_VALUE ) {
+ if( DeviceIoControl( hDevice,
+ IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ NULL,
+ 0,
+ &DiskGeometry,
+ sizeof( DISK_GEOMETRY),
+ &BytesReturned,
+ NULL ) &&
+ ( DiskGeometry.MediaType == F3_2Pt88_512 )
+ ) {
+ //
+ // The disk is a 2.88 Mb
+ //
+ MediaType = FmMediaF3_2Pt88_512;
+ }
+ CloseHandle( hDevice );
+ }
+ }
+ SetErrorMode( ErrorMode );
+ }
+ break;
+
+ case FmMediaF3_120M_512: // 3.5", 120M Floppy
+ //
+ // We get this back *only* if there is a 120MB floppy
+ // actually in the drive right now.
+ //
+ // For SUR disallow these.
+ //
+ DisplayMsgBox(hwndOwner,
+ IDS_HUGEFLOPPYNOTSUPPORTED,
+ MB_OK | MB_ICONEXCLAMATION,
+ _szApplicationName);
+
+ LocalFree(MediaTypes);
+ *Fatal = FALSE; //allow retry
+ return(FALSE);
+
+ case FmMediaF3_20Pt8_512: // 3.5", 20.8MB, 512 bytes/sector
+
+#if i386
+ {
+ DWORD i;
+
+ //
+ // Look for a compatibility mode
+ //
+
+ for(i=1; i<cMediaTypes; i++) {
+
+ if((MediaTypes[i] == FmMediaF5_1Pt2_512)
+ || (MediaTypes[i] == FmMediaF3_1Pt44_512))
+ {
+ MediaType = MediaTypes[i];
+ break;
+ }
+ }
+
+ if(i < cMediaTypes) {
+ break;
+ }
+ }
+ // fall through
+
+#else
+ //
+ // On an ARC machine, use whatever floppies the user has since
+ // we aren't required to boot from it.
+ //
+
+ MediaType = *MediaTypes;
+ break;
+#endif
+
+ case FmMediaF5_160_512: // 5.25", 160KB, 512 bytes/sector
+ case FmMediaF5_180_512: // 5.25", 180KB, 512 bytes/sector
+ case FmMediaF5_320_512: // 5.25", 320KB, 512 bytes/sector
+ case FmMediaF5_320_1024: // 5.25", 320KB, 1024 bytes/sector
+ case FmMediaF5_360_512: // 5.25", 360KB, 512 bytes/sector
+ case FmMediaF3_720_512: // 3.5", 720KB, 512 bytes/sector
+ case FmMediaRemovable: // Removable media other than floppy
+ case FmMediaFixed:
+ case FmMediaUnknown:
+ default:
+
+ DisplayMsgBox(hwndOwner,
+ IDS_BADFLOPPYTYPE,
+ MB_OK | MB_ICONEXCLAMATION);
+ LocalFree(MediaTypes);
+
+ //
+ // Unknown can be returned in the case where the drive is an ATAPI floppy
+ // and there's no media in the drive. Allow retry.
+ //
+ if(*MediaTypes == FmMediaUnknown) {
+ *Fatal = FALSE;
+ }
+
+ return(FALSE);
+ }
+
+ LocalFree(MediaTypes);
+
+ //
+ // Start the modal dialog that will display the progress indicator.
+ //
+
+ FloppyOp.MediaType = MediaType;
+ FloppyOp.DriveLetter = (WCHAR)DriveLetter;
+ FloppyOp.Operation = FloppyOpFormat;
+ FloppyOp.CaptionResId = IDS_FORMATTINGDISK;
+ FloppyOp.GeneralFailureResId = IDS_FORMATGENERALFAILURE;
+
+ Flag = DialogBoxParam( GetModuleHandle(NULL),
+ MAKEINTRESOURCE( IDD_PROGRESS2 ), // TEXT("Progress2"),
+ hwndOwner,
+ ProgressDlgProc,
+ (LONG)&FloppyOp
+ );
+
+ *Fatal = FALSE;
+
+ return(Flag);
+}
+
+#ifdef FLOPPY_COPY
+BOOL
+CopyFloppyDisk(
+ IN CHAR DriveLetter,
+ IN HWND hwndOwner,
+ IN DWORD SourceDiskPromptId,
+ IN DWORD TargetDiskPromptId
+ )
+
+/*++
+
+Routine Description:
+
+ Top-level routine to copy a floppy in the given drive (src and dst
+ both in this drive). A floppy disk must already be in the drive or
+ this routine will fail.
+
+Arguments:
+
+ DriveLetter - supplies drive letter of drive to copy (A-Z or a-z)
+
+ hwndOwner - supplies handle of window that is to own the progress dlg.
+
+ SourceDiskPromptId - supplies the resource id of the prompt to display
+ when prompting for the source diskette
+
+ TargetDiskPromptId - supplies the resource id of the prompt to display
+ when prompting for the target diskette
+
+Return Value:
+
+ TRUE if the operation succeeded, FALSE if not.
+
+--*/
+
+{
+ BOOL Flag;
+ FLOPPY_OPERATION_PARAMS FloppyOp;
+
+ FloppyOp.DriveLetter = (WCHAR)DriveLetter;
+ FloppyOp.Operation = FloppyOpDiskcopy;
+ FloppyOp.CaptionResId = IDS_COPYINGDISK;
+ FloppyOp.GeneralFailureResId = IDS_COPYGENERALFAILURE;
+ FloppyOp.SrcDiskPromptResId = SourceDiskPromptId;
+ FloppyOp.DstDiskPromptResId = TargetDiskPromptId;
+
+ Flag = DialogBoxParam( GetModuleHandle(NULL),
+ TEXT("Progress2"),
+ hwndOwner,
+ ProgressDlgProc,
+ (LONG)&FloppyOp
+ );
+
+ return(Flag);
+}
+#endif
+
+BOOL
+ProgressDlgProc(
+ IN HWND hdlg,
+ IN UINT Msg,
+ IN WPARAM wParam,
+ IN LONG lParam
+ )
+{
+ static PFLOPPY_OPERATION_PARAMS FloppyOp;
+ static WCHAR WideDriveName[3];
+ static BOOL OpSucceeded;
+ PVOID PacketAddress;
+ FMIFS_PACKET_TYPE PacketType;
+ WCHAR Buffer[256];
+ DWORD ThreadId;
+
+ switch(Msg) {
+
+ case WM_INITDIALOG:
+
+ FloppyOp = (PFLOPPY_OPERATION_PARAMS)lParam;
+ WideDriveName[0] = FloppyOp->DriveLetter;
+ WideDriveName[1] = L':';
+ WideDriveName[2] = 0;
+
+ ProgressDialog = hdlg;
+
+ //
+ // set up range for percentage (0-100) display
+ //
+ SendDlgItemMessage(hdlg,ID_BAR,PBM_SETRANGE,0,MAKELPARAM(0,GAUGE_BAR_RANGE));
+
+ //
+ // Set the caption
+ //
+
+ LoadString(_hModule,FloppyOp->CaptionResId,Buffer,sizeof(Buffer)/sizeof(WCHAR));
+ SetWindowText(hdlg,Buffer);
+
+ OpSucceeded = TRUE;
+
+ // center the dialog relative to the parent window
+ //
+ // BUGBUG - commented out
+ //
+ FCenterDialogOnDesktop(hdlg);
+
+ CreateThread( NULL,
+ 1024,
+ ( LPTHREAD_START_ROUTINE )FmifsThread,
+ FloppyOp,
+ 0,
+ &ThreadId );
+
+
+
+ break;
+
+ case AP_TASK_COMPLETED:
+
+ SendDlgItemMessage( hdlg,
+ ID_BAR,
+ PBM_SETPOS,
+ GAUGE_BAR_RANGE,
+ 0L
+ );
+ PostMessage( hdlg,
+ AP_TERMINATE_DIALOG,
+ 0,
+ 0 );
+ break;
+
+ case AP_TERMINATE_DIALOG:
+
+ EndDialog(hdlg, OpSucceeded);
+ break;
+
+
+ case WM_FMIFS_CALLBACK:
+
+ //
+ // The callback routine is telling us something.
+ // wParam = packet type
+ // lParam = packet address
+ //
+
+ PacketType = wParam;
+ PacketAddress = (PVOID)lParam;
+
+ switch(PacketType) {
+
+ case FmIfsPercentCompleted:
+
+ //
+ // update gas gauge
+ //
+
+ SendDlgItemMessage( hdlg,
+ ID_BAR,
+ PBM_SETPOS,
+ (GAUGE_BAR_RANGE * ((PFMIFS_PERCENT_COMPLETE_INFORMATION)PacketAddress)->PercentCompleted) / 100,
+ 0L
+ );
+ break;
+
+ case FmIfsFinished:
+
+ {
+ BOOLEAN b;
+
+ //
+ // update gas gauge (100% complete)
+ //
+
+ SendDlgItemMessage( hdlg,
+ ID_BAR,
+ PBM_SETPOS,
+ GAUGE_BAR_RANGE,
+ 0L
+ );
+
+ b = ((PFMIFS_FINISHED_INFORMATION)PacketAddress)->Success;
+
+ //
+ // If the operation failed but the user hasn't already been
+ // informed, inform him.
+ //
+
+ if(OpSucceeded && !b) {
+ OpSucceeded = FALSE;
+ DisplayMsgBox( hdlg,
+ FloppyOp->GeneralFailureResId,
+ MB_OK | MB_ICONEXCLAMATION,
+ _szApplicationName
+ );
+
+ }
+ }
+ break;
+
+ case FmIfsFormatReport: // ignore
+
+ break;
+
+#ifdef FLOPPY_COPY
+ case FmIfsInsertDisk:
+
+ if(FloppyOp->Operation == FloppyOpDiskcopy) {
+ switch(((PFMIFS_INSERT_DISK_INFORMATION)PacketAddress)->DiskType) {
+ case DISK_TYPE_SOURCE:
+ ResId = FloppyOp->SrcDiskPromptResId;
+ break;
+ case DISK_TYPE_TARGET:
+ ResId = FloppyOp->DstDiskPromptResId;
+ break;
+ default:
+ return(TRUE);
+ }
+ xMsgBox(hdlg,IDS_INSERTDISKETTE,ResId,MB_OK,FloppyOp->DriveLetter);
+ }
+ break;
+
+ case FmIfsFormattingDestination:
+
+ // BUGBUG do something
+ break;
+#endif
+
+ case FmIfsMediaWriteProtected:
+
+ DisplayMsgBox(hdlg,IDS_FLOPPYWRITEPROT,MB_OK | MB_ICONEXCLAMATION);
+ OpSucceeded = FALSE;
+ break;
+
+ case FmIfsIoError:
+
+ DisplayMsgBox(hdlg,IDS_FLOPPYIOERR,MB_OK | MB_ICONEXCLAMATION);
+ OpSucceeded = FALSE;
+ break;
+
+ case FmIfsHiddenStatus: // ignore
+
+ break;
+
+ default:
+
+ DisplayMsgBox(hdlg,IDS_FLOPPYUNKERR,MB_OK | MB_ICONEXCLAMATION);
+ OpSucceeded = FALSE;
+ break;
+ }
+ break;
+
+ default:
+
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+
+BOOLEAN
+FmifsCallbackRoutine(
+ IN FMIFS_PACKET_TYPE PacketType,
+ IN DWORD PacketLength,
+ IN PVOID PacketAddress
+ )
+{
+ UNREFERENCED_PARAMETER(PacketLength);
+ //
+ // Package up the callback and send it on to the progress dialog.
+ // wParam = packet type
+ // lParam = packet address
+ //
+
+ SendMessage( ProgressDialog,
+ WM_FMIFS_CALLBACK,
+ PacketType,
+ (LONG)PacketAddress
+ );
+
+ return(TRUE); // keep going
+}
+
+VOID
+FmifsThread(
+ IN PVOID Arguments
+ )
+
+{
+ PFLOPPY_OPERATION_PARAMS FloppyOp;
+ WCHAR WideDriveName[3];
+
+
+ FloppyOp = ( PFLOPPY_OPERATION_PARAMS )Arguments;
+ WideDriveName[0] = FloppyOp->DriveLetter;
+ WideDriveName[1] = L':';
+ WideDriveName[2] = 0;
+
+ FmifsFormat( WideDriveName,
+ FloppyOp->MediaType,
+ L"fat",
+ L"",
+ FALSE, // not quick format
+ FmifsCallbackRoutine
+ );
+
+ SendMessage( ProgressDialog,
+ AP_TASK_COMPLETED,
+ 0,
+ 0L
+ );
+
+ ExitThread(0);
+}
diff --git a/private/utils/rdisk/format.c b/private/utils/rdisk/format.c
new file mode 100644
index 000000000..8530f2f26
--- /dev/null
+++ b/private/utils/rdisk/format.c
@@ -0,0 +1,347 @@
+#include "precomp.h"
+#pragma hdrstop
+
+BOOL
+InitializeFloppySup(
+ VOID
+ );
+
+BOOL
+FormatFloppyDisk(
+ IN WCHAR DriveLetter,
+ IN HWND hwndOwner,
+ OUT PBOOL Fatal
+ );
+
+BOOL
+InsertSpecialBootCode(
+ IN WCHAR Drive
+ );
+
+
+BOOLEAN
+FormatRepairDisk(
+ IN PWCHAR Drive
+ )
+
+/*++
+
+Routine Description:
+
+ Generate the repair diskette on a given drive.
+
+ The set of events that occurs is as follows:
+
+ - Log the registry files (place the hive files in the restore disk inf
+ file's list of files to check)
+
+ - prompt for and format the floppy disk supplied by the user
+
+ - Copy the setup log file to the floppy supplied by the user
+ The rerair inf file will be called restore.inf.
+
+ This operation also closes the log file and ends logging.
+
+Arguments:
+
+ Drive - the first character is the drive letter of the drive containing
+ the restore diskette.
+
+Return Value:
+
+ TRUE if success, FALSE otherwise.
+
+--*/
+
+{
+ HANDLE Handle;
+ WIN32_FIND_DATA FindData;
+
+ BOOL Fatal;
+ BOOL res;
+ WCHAR Warning[256];
+ UINT OldErrorMode;
+ HCURSOR Cursor;
+ WCHAR DriveLetter[3];
+
+ PWSTR SetupFloppyTags[4] = { L"?:\\DISK10?",
+ L"?:\\DISK*.S",
+ L"?:\\DISK*.W",
+ NULL
+ };
+ WCHAR FloppyTag[128];
+
+ unsigned i;
+
+
+ DriveLetter[0] = *Drive;
+ DriveLetter[1] = (WCHAR)':';
+ DriveLetter[2] = (WCHAR)'\0';
+
+ Cursor = DisplayHourGlass();
+
+ if(!InitializeFloppySup()) {
+ DisplayMsgBox(_hWndMain,
+ IDS_CANTINITFLOPPYSUP,
+ MB_OK | MB_ICONEXCLAMATION,
+ _szApplicationName);
+ RestoreCursor( Cursor );
+ return(FALSE);
+ }
+
+ RestoreCursor( Cursor );
+
+ OldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+
+ //
+ // Prompt the user to get a new disk into the drive
+ //
+ LoadString(GetModuleHandle(NULL),IDS_ALLDATAWILLBELOST,Warning,sizeof(Warning)/sizeof(WCHAR));
+ if( DisplayMsgBox( _hWndMain,
+ IDS_FIRSTREPAIRDISKPROMPT,
+ MB_OKCANCEL | MB_DEFBUTTON1 | MB_ICONEXCLAMATION,
+ DriveLetter,
+ Warning) != IDOK ) {
+ return( FALSE );
+ }
+
+ //
+ // Attempt to prevent the user from using a setup floppy
+ // as the repair disk by looking for known tag values on
+ // the floppy the user inserted.
+ //
+ do {
+
+ for(i=0; SetupFloppyTags[i]; i++) {
+ //
+ // Make writable copy of floppy tag before writing into it.
+ //
+ lstrcpy(FloppyTag,SetupFloppyTags[i]);
+ FloppyTag[0] = *Drive;
+
+ if((Handle = FindFirstFile(FloppyTag,&FindData)) != INVALID_HANDLE_VALUE) {
+
+ FindClose(Handle);
+
+ if( DisplayMsgBox( _hWndMain,
+ IDS_SECONDREPAIRDISKPROMPT,
+ MB_OKCANCEL | MB_DEFBUTTON1 | MB_ICONEXCLAMATION,
+ DriveLetter,
+ Warning) != IDOK ) {
+ return( FALSE );
+ }
+
+ break;
+ }
+ }
+
+ } while(Handle != INVALID_HANDLE_VALUE);
+
+ do {
+ if(!(res = FormatFloppyDisk(*Drive,_hWndMain,&Fatal))) {
+
+ if(Fatal) {
+ SetErrorMode(OldErrorMode);
+ return(FALSE);
+ }
+
+ //
+ // Get the user to retry.
+ //
+ if(DisplayMsgBox( _hWndMain,
+ IDS_RETRYFORMATREPAIRDISK,
+ MB_RETRYCANCEL | MB_ICONEXCLAMATION,
+ _szApplicationName,
+ DriveLetter) != IDRETRY) {
+ SetErrorMode(OldErrorMode);
+ return(FALSE);
+ }
+
+
+ }
+ } while(!res);
+
+ //
+ // Cause special boot code to be written to the disk, that makes it
+ // print a message when booted.
+ //
+ InsertSpecialBootCode(*Drive);
+
+ SetErrorMode(OldErrorMode);
+
+ return(TRUE);
+
+}
+
+//
+// Bootcode to be inserted, placed into a C array. See i386\readme.
+//
+#include "rdskboot.c"
+#define DRIVENAME_PREFIX L"\\\\.\\"
+
+BOOL
+InsertSpecialBootCode(
+ IN WCHAR Drive
+ )
+{
+ UCHAR UBuffer[1024];
+ PUCHAR Buffer = (PUCHAR)(((DWORD)UBuffer+512) & ~511);
+ HANDLE Handle;
+ WCHAR DriveName[(sizeof(DRIVENAME_PREFIX)/sizeof(WCHAR)) + 2 + 1];
+ BOOL b;
+ DWORD BytesXferred;
+ DWORD Offset;
+ PUCHAR MsgAddr;
+
+ wsprintf(DriveName,L"%ls%wc:",DRIVENAME_PREFIX,Drive);
+
+ //
+ // Open the drive DASD
+ //
+ Handle = CreateFile(
+ DriveName,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+
+ if(Handle == INVALID_HANDLE_VALUE) {
+ return(FALSE);
+ }
+
+ //
+ // Read and validate the first 512 bytes from the drive.
+ //
+ b = ReadFile(Handle,Buffer,512,&BytesXferred,NULL);
+ if((b == FALSE)
+ || (BytesXferred != 512)
+ || (Buffer[0] != 0xeb)
+ || (Buffer[2] != 0x90)
+ || (Buffer[510] != 0x55)
+ || (Buffer[511] != 0xaa))
+ {
+ CloseHandle(Handle);
+ return(FALSE);
+ }
+
+ //
+ // Determine the offset of the bootcode.
+ //
+ Offset = Buffer[1] + 2;
+ if(Offset + REPAIR_DISK_BOOTSECTOR_SIZE > 510) {
+ CloseHandle(Handle);
+ return(FALSE);
+ }
+
+ //
+ // Wipe the boot code clean and reset the signature.
+ //
+ ZeroMemory(Buffer+Offset,510-Offset);
+
+ //
+ // Copy the new bootcode into the sector.
+ //
+ CopyMemory(
+ Buffer+Offset,
+ REPAIR_DISK_BOOTSECTOR,
+ REPAIR_DISK_BOOTSECTOR_SIZE
+ );
+
+ //
+ // Calculate the offset of the message within the boot sector.
+ //
+ MsgAddr = Buffer+Offset+REPAIR_DISK_BOOTSECTOR_SIZE;
+
+ //
+ // Fetch the boot sector's message from our resources and
+ // place it into the boot sector.
+ //
+ LoadStringA(
+ GetModuleHandle(NULL),
+ IDS_REPAIR_BOOTCODE_MSG,
+ MsgAddr,
+ 510-Offset-REPAIR_DISK_BOOTSECTOR_SIZE
+ );
+
+ Buffer[509] = 0; // just in case.
+
+ //
+ // The string in the resources will be ANSI text; we want OEM text
+ // in the boot sector on the floppy.
+ //
+ CharToOemA(MsgAddr,MsgAddr);
+
+ //
+ // Seek back to the beginning of the disk and
+ // write the bootsector back out to disk.
+ //
+ if(SetFilePointer(Handle,0,NULL,FILE_BEGIN)) {
+ CloseHandle(Handle);
+ return(FALSE);
+ }
+
+ b = WriteFile(Handle,Buffer,512,&BytesXferred,NULL);
+
+ CloseHandle(Handle);
+
+ return((b == TRUE) && (BytesXferred == 512));
+
+}
+
+
+
+BOOLEAN
+CreateRepairDisk(
+ IN BOOLEAN DisplayConfirmCreateDisk
+ )
+
+/*++
+
+Routine Description:
+
+ Create a repair disk on the 'A' drive, if the user wants to do so.
+
+Arguments:
+
+ DisplayConfirmCreateDisk - A flag that indicates whether or not rdisk
+ should ask the user to confirm the creation
+ of the repair disk. The dialog should not be
+ displayed if user selected 'Create Repair Disk'
+ button.
+
+Return Value:
+
+ BOOLEAN - Returns TRUE if the operation succeeded, or FALSE otherwise.
+
+--*/
+
+
+{
+ BOOLEAN Result;
+ WCHAR Drive;
+ PWSTR String;
+ WCHAR StringYou[64];
+
+ Result = FALSE;
+ if( !_SilentMode ) {
+ LoadString(_hModule,IDS_CONFIRM_CREATE_YOU,StringYou,sizeof(StringYou)/sizeof(WCHAR));
+ String = StringYou;
+ } else {
+ String = _szApplicationName;
+ }
+ if( !DisplayConfirmCreateDisk ||
+ DisplayMsgBox( _hWndMain,
+ IDS_CONFIRM_CREATE_DISK,
+ MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1,
+ String
+ ) == IDYES ) {
+
+ Drive = ( WCHAR )'A';
+ Result = FormatRepairDisk( &Drive );
+ }
+
+ return( Result );
+}
diff --git a/private/utils/rdisk/help.c b/private/utils/rdisk/help.c
new file mode 100644
index 000000000..67ec72dd4
--- /dev/null
+++ b/private/utils/rdisk/help.c
@@ -0,0 +1,363 @@
+/*++
+
+Module Name:
+
+ help.c
+
+Abstract:
+
+
+Author:
+
+ Jaime Sasson - 10-Aug-1993
+
+Environment:
+
+ ULIB, Windows
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+
+//
+// Global variables used in the module
+//
+
+HHOOK _hHook;
+INT _HelpContext;
+WCHAR _HelpFile[ MAX_PATH + 1 ];
+
+
+
+LRESULT
+HelpHookProc(
+ IN INT nCode,
+ IN WPARAM wParam,
+ IN LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ Hook proc to detect F1 key presses.
+
+Arguments:
+
+ Standard arguments of a hook procedure.
+
+Return Value:
+
+--*/
+
+{
+ PMSG pmsg = (PMSG)lParam;
+
+ if(nCode < 0) {
+ return( CallNextHookEx( _hHook, nCode, wParam, lParam ) );
+ }
+
+ if(((nCode == MSGF_DIALOGBOX) || (nCode == MSGF_MENU))
+ && (pmsg->message == WM_KEYDOWN)
+ && (LOWORD(pmsg->wParam) == VK_F1))
+ {
+ PostMessage( _hWndMain, AP_HELP_KEY, nCode, 0);
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+
+BOOLEAN
+InitializeHelp(
+ IN PCWSTR HelpFile
+ )
+
+/*++
+
+Routine Description:
+
+ Initialize the help module by initializing its global data.
+
+Arguments:
+
+ HelpFile - Name of the help file to be invoked.
+
+
+Return Value:
+
+ BOOLEAN - Returns TRUE if the initialization succeeded.
+ returns FALSE otherwise.
+
+--*/
+
+{
+
+ wcscpy( _HelpFile, HelpFile );
+
+ _hHook = SetWindowsHookEx( WH_MSGFILTER,
+ HelpHookProc,
+ NULL,
+ GetCurrentThreadId() );
+
+ if( _hHook == NULL ) {
+ return( FALSE );
+ }
+ return( TRUE );
+}
+
+
+VOID
+CleanUpHelp(
+ )
+
+/*++
+
+Routine Description:
+
+ Clean up the HELP object, by unhooking HelpHookProc.
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ UnhookWindowsHookEx( _hHook );
+}
+
+
+
+
+VOID
+DisplayHelp(
+ )
+
+/*++
+
+Routine Description:
+
+ Display context-sensitive help.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ BOOLEAN - Returns TRUE if the operation succeeds. Otherwise, return FALSE.
+
+--*/
+
+{
+ if( _HelpContext != IDH_NONE ) {
+ WinHelp( _hWndMain,
+ _HelpFile,
+ (UINT)HELP_CONTEXT,
+ _HelpContext );
+ DrawMenuBar( _hWndMain );
+ }
+
+
+}
+
+
+
+VOID
+DisplayHelpIndex(
+ )
+
+/*++
+
+Routine Description:
+
+ Invoke winhelp to display the help file index.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ WinHelp( _hWndMain, _HelpFile, (UINT)HELP_INDEX, 0 );
+}
+
+
+VOID
+DisplayHelpOnHelp(
+ )
+
+/*++
+
+Routine Description:
+
+ Invoke winhelp to display help on help.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ WinHelp( _hWndMain, _HelpFile, (UINT)HELP_HELPONHELP, 0 );
+}
+
+
+
+VOID
+DisplayHelpSearch(
+ )
+
+/*++
+
+Routine Description:
+
+ Invoke winhelp so that it prompt the user to enter a key.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ WinHelp( _hWndMain, _HelpFile, (UINT)HELP_PARTIALKEY, (DWORD)"" );
+}
+
+
+VOID
+QuitHelp(
+ )
+
+/*++
+
+Routine Description:
+
+ Inform winhelp that help is no more needed.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ WinHelp( _hWndMain, _HelpFile, (UINT)HELP_QUIT, 0 );
+}
+
+
+INT
+GetHelpContext(
+ )
+
+/*++
+
+Routine Description:
+
+ Return the current help context.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ INT - Ireturns the current help id.
+
+--*/
+
+{
+ return( _HelpContext );
+}
+
+
+
+VOID
+SetHelpContext(
+ IN INT HelpId
+ )
+
+/*++
+
+Routine Description:
+
+ Set the current help context.
+
+Arguments:
+
+ HelpContext - Help context id.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ _HelpContext = HelpId;
+}
+
+
+
+VOID
+SetMenuItemHelpContext(
+ IN WPARAM wParam,
+ IN LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ Routine to set help context based on which menu item is currently
+ selected.
+
+Arguments:
+
+ wParam,lParam - params to window proc in WM_MENUSELECT case
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ if(HIWORD(lParam) == 0) { // menu closed
+ SetHelpContext( IDH_SAVE_REPAIR_INFO );
+
+ } else if (HIWORD(wParam) & MF_POPUP) { // popup selected
+ SetHelpContext( IDH_NONE );
+
+ } else if (HIWORD(wParam) & MF_SYSMENU) { // system menu
+ SetHelpContext( IDH_SYSTEM_MENU );
+
+ } else { // regular old menu item
+ SetHelpContext( IDH_NONE );
+
+ }
+}
diff --git a/private/utils/rdisk/help.h b/private/utils/rdisk/help.h
new file mode 100644
index 000000000..9fe1fb25d
--- /dev/null
+++ b/private/utils/rdisk/help.h
@@ -0,0 +1,78 @@
+/*++
+
+Module Name:
+
+ help.h
+
+Abstract:
+
+ This module contains the class declaration for the HELP class.
+
+Author:
+
+ Jaime Sasson - 16-Aug-1993
+
+Environment:
+
+ ULIB, Windows
+
+--*/
+
+
+#if ! defined( _HELP_ )
+
+#define _HELP_
+
+LRESULT
+HelpHookProc(
+ IN INT nCode,
+ IN WPARAM wParam,
+ IN LPARAM lParam
+ );
+
+BOOLEAN
+InitializeHelp(
+ IN PCWSTR HelpFileName
+ );
+
+VOID
+CleanUpHelp(
+ );
+
+VOID
+DisplayHelp(
+ );
+
+VOID
+DisplayHelpIndex(
+ );
+
+VOID
+DisplayHelpOnHelp(
+ );
+
+VOID
+DisplayHelpSearch(
+ );
+
+VOID
+QuitHelp(
+ );
+
+INT
+GetHelpContext(
+ );
+
+VOID
+SetHelpContext(
+ IN INT HelpId
+ );
+
+VOID
+SetMenuItemHelpContext(
+ IN WPARAM wParam,
+ IN LPARAM lParam
+ );
+
+
+#endif // _HELP_
diff --git a/private/utils/rdisk/i386/rdskboot.asm b/private/utils/rdisk/i386/rdskboot.asm
new file mode 100644
index 000000000..aff397726
--- /dev/null
+++ b/private/utils/rdisk/i386/rdskboot.asm
@@ -0,0 +1,77 @@
+
+ ;
+ ; Program to be inserted on the boot sector of the emergency repair
+ ; disk. Prints out a message and hangs.
+ ;
+ ; The program is designed to be inserted around the existing BPB.
+ ; Whoever puts it in place should read the first three bytes of the
+ ; boot sector to determine the byte offset within the sector where the
+ ; program should be placed.
+ ;
+ ; See setup\src\restore.c.
+ ;
+
+TheSeg segment
+ assume cs:TheSeg,ds:nothing,es:nothing,ss:nothing
+
+ ;
+ ; Make link happy with /tiny by setting org to 100h.
+ ; The program itself is designed to run at 0:7c00h, so
+ ; the org is just a dummy.
+ ;
+ org 100h
+Start:
+
+ ;
+ ; Set up a stack and initialize necessary segment registers.
+ ;
+ xor bx,bx
+ mov ss,bx
+ mov ds,bx
+ mov sp,7c00h
+
+ ;
+ ; Set video mode -- 80x25 text.
+ ;
+ mov ax,3
+ int 10h
+
+ ;
+ ; Make ds:si point at the message to be displayed.
+ ;
+ call @f
+@@: pop si
+ add si,offset cs:msg - @b
+
+ ;
+ ; Print out the string via BIOS calls. Registers ds, si, and bx are
+ ; already set up.
+ ;
+ cld
+ mov ah,0eh
+@@: lodsb
+ or al,al
+ jz @f
+ int 10h
+ jmp @b
+
+ ;
+ ; Done. Hide the cursor and hang.
+ ; Register bh is already set up.
+ ;
+@@: mov ah,2
+ mov dl,bl
+ mov dh,19h
+ int 10h
+ sti
+@@: jmp @b
+
+ ;
+ ; The message to be printed. This will be inserted by setup from its
+ ; resources (IDS_REPAIR_BOOTCODE_MSG), and must be nul-terminated.
+ ;
+msg label byte
+
+TheSeg ends
+
+ end Start
diff --git a/private/utils/rdisk/i386/readme b/private/utils/rdisk/i386/readme
new file mode 100644
index 000000000..3cd7df911
--- /dev/null
+++ b/private/utils/rdisk/i386/readme
@@ -0,0 +1,17 @@
+The file rdskboot.asm contains the program to be inserted into the
+boot sector of the emergency repair disk. There is also a message that needs
+to go in that sector -- the message is contained in setup.exe's resources,
+with resource id IDS_REPAIR_BOOTCODE_MSG.
+
+I build rdskboot.com by using the following commands:
+
+ masm386 rdskboot,,nul,nul,,
+ link_60 /tiny rdskboot,,nul,,,
+
+
+I then ran bin2c.exe (in sdktools, part of standard idw) over rdskboot.com
+using the following command:
+
+ bin2c rdskboot.com 45 0 45 ..\rdskboot.c REPAIR_DISK_BOOTSECTOR
+
+This generated rdskboot.c in setup\src, which I checked in.
diff --git a/private/utils/rdisk/i386/x.bat b/private/utils/rdisk/i386/x.bat
new file mode 100644
index 000000000..b2a801e37
--- /dev/null
+++ b/private/utils/rdisk/i386/x.bat
@@ -0,0 +1,2 @@
+masm386 rdskboot,,nul,nul,,
+link_60 /tiny rdskboot,,nul,,,
diff --git a/private/utils/rdisk/makefile b/private/utils/rdisk/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/utils/rdisk/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/utils/rdisk/precomp.h b/private/utils/rdisk/precomp.h
new file mode 100644
index 000000000..3e5ecee72
--- /dev/null
+++ b/private/utils/rdisk/precomp.h
@@ -0,0 +1,14 @@
+#include <windows.h>
+#include <commctrl.h>
+#include <diamondc.h>
+#include <winioctl.h>
+#include <fcntl.h>
+#include <sys\types.h>
+#include <sys\stat.h>
+#include <io.h>
+
+#include "rdisk.h"
+#include "resource.h"
+#include "dialogs.h"
+#include "help.h"
+#include "..\fmifs\inc\fmifs.h"
diff --git a/private/utils/rdisk/rdisk.c b/private/utils/rdisk/rdisk.c
new file mode 100644
index 000000000..bfb3a3ecd
--- /dev/null
+++ b/private/utils/rdisk/rdisk.c
@@ -0,0 +1,619 @@
+/*++
+
+Module Name:
+
+ repair.c
+
+Abstract:
+
+ This module contains the functions that create the main window
+ of the Repair Utility.
+
+ The syntax of this utility is:
+
+ repair [-s]
+
+ -s: Operate in the silent mode. The apllication will not have a client
+ area, and some dialogs that allow the user to confirm some
+ operations are not displayed.
+ When the utility is operating in the silent mode, it will display
+ the name of Setup program in the title bar of all error and
+ warning dialogs displayed. This name to be displayed in the
+ title bar is defined on resource.rc under IDS_SETUP.
+
+ If this switch is not specified this utility will be run on
+ its normal mode, and it will wait for the user to start
+ the process of saving repair information.
+
+Author:
+
+ Jaime Sasson - 24-Jan-1994
+
+Environment:
+
+ ULIB, Windows
+
+--*/
+
+
+#include "precomp.h"
+#pragma hdrstop
+
+//
+// Global Variables
+//
+
+HWND _hWndMain = NULL;
+HANDLE _hModule = NULL;
+PWSTR _pszApplicationClass = (PWSTR)( L"Repair" );
+BOOLEAN _SilentMode = FALSE;
+WCHAR _szApplicationName[128];
+INT _ReturnCode;
+BOOLEAN _AutoSkipRepairDisk = FALSE;
+BOOLEAN _AutoDoRepairDisk = FALSE;
+
+
+BOOLEAN
+SaveCurrentConfiguration(
+ );
+
+BOOLEAN
+CopyFilesToRepairDisk(
+ IN WCHAR Drive
+ );
+
+
+BOOLEAN
+FormatRepairDisk(
+ IN PWCHAR Drive
+ );
+
+BOOLEAN
+CreateRepairDisk(
+ IN BOOLEAN DisplayConfirmCreateDisk
+ );
+
+
+HCURSOR
+DisplayHourGlass(
+ )
+
+/*++
+
+Routine Description:
+
+ Changes the cursor currently displayed to the hour glass.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ HCURSOR - Handle to the cursor currently displayed.
+
+--*/
+
+{
+ HCURSOR hCursor;
+
+ hCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
+ ShowCursor( TRUE );
+ return( hCursor );
+
+}
+
+
+
+VOID
+RestoreCursor(
+ IN HCURSOR Cursor
+ )
+
+/*++
+
+Routine Description:
+
+ Replace the currently selected cursor with the one whose handle was
+ received as parameter.
+
+Arguments:
+
+ Cursor - Handle to the new cursor to be displayed.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ SetCursor( Cursor );
+ ShowCursor( FALSE );
+}
+
+
+PWSTR
+QueryFormattedString(
+ UINT MessageResId,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Retrieve, format a string.
+
+
+Arguments:
+
+ MessageResId - Id of the message to be displayed in the message box.
+
+ Optional list of strings to be inserted in the string to be retrieved.
+
+Return Value:
+
+ PWSTR - Retrurns a formatted string. The caller of this function must
+ free the buffer returned, using LocalFree().
+
+--*/
+
+
+{
+ WCHAR message[1024];
+ PWSTR FormattedString;
+ va_list arglist;
+
+
+ va_start(arglist, MessageResId);
+
+ LoadString(_hModule,MessageResId,message,sizeof(message)/sizeof(WCHAR));
+ FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ message,
+ 0,
+ 0,
+ (PVOID)&FormattedString,
+ 1024,
+ &arglist );
+
+
+ va_end(arglist);
+
+ return(FormattedString);
+}
+
+
+
+UINT
+DisplayMsgBox(
+ HWND hwnd,
+ UINT MessageResId,
+ UINT MsgBoxFlags,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Retrieve, format and display a message in a message box.
+
+
+Arguments:
+
+ hWnd - Handle of the windows that is displaying the message box.
+
+ MessageResId - Id of the message to be displayed in the message box.
+
+ MsgBoxFlags - Flags that define the style of the message box.
+
+ Optional list of strings to be inserted in the text to be displayed in
+ the message box.
+
+Return Value:
+
+ UINT - Returns one of the following, depending on what the user chose:
+
+ IDABORT, IDCANCEL, IDIGNORE, IDNO, IDOK, IDRETRY, IDYES
+
+--*/
+
+
+{
+ WCHAR message[1024];
+ WCHAR msgbody[1024];
+ va_list arglist;
+
+ va_start(arglist, MsgBoxFlags);
+
+ LoadString(_hModule,MessageResId,message,sizeof(message)/sizeof(WCHAR));
+
+ FormatMessage( FORMAT_MESSAGE_FROM_STRING,
+ message,
+ 0,
+ 0,
+ msgbody,
+ sizeof( msgbody ) / sizeof( WCHAR ),
+ &arglist );
+
+
+ va_end(arglist);
+
+ return(MessageBox(hwnd,msgbody,_szApplicationName,MsgBoxFlags));
+}
+
+
+
+long
+MainWndProc(
+ IN HWND hWnd,
+ IN UINT message,
+ IN WPARAM wParam,
+ IN LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ MainWndProc is the WndProc for application's main window. It is primarily
+ responsible for creating the MDICLIENT window and servicing menu
+ commands.
+
+Arguments:
+
+ Standard Windows' Proc parameters.
+
+Return Value:
+
+ long - Returns 0 if the message was handled.
+
+--*/
+
+{
+
+ static HWND LastFocus = NULL;
+
+ switch( message ) {
+
+ case WM_CREATE:
+ {
+ int ScreenHeight;
+ int ScreenWidth;
+
+ //
+ // Display the main window in the center of the screen.
+ //
+
+ ScreenWidth = GetSystemMetrics( SM_CXSCREEN );
+ ScreenHeight = GetSystemMetrics( SM_CYSCREEN );
+
+ SetWindowPos( hWnd,
+ NULL,
+ ( ScreenWidth - (( LPCREATESTRUCT ) lParam )->cx ) / 2,
+ ( ScreenHeight - (( LPCREATESTRUCT ) lParam )->cy ) / 2,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOREDRAW | SWP_NOZORDER
+ );
+ return 0;
+ }
+
+ case WM_INITDIALOG:
+ {
+ if( !_SilentMode ) {
+
+ LastFocus = GetDlgItem( hWnd, IDB_SAVE_CURRENT_INFO );
+ SetFocus( LastFocus );
+ SetHelpContext( IDH_SAVE_REPAIR_INFO );
+
+ }
+ return 0;
+ }
+
+ case WM_KILLFOCUS:
+
+ LastFocus = GetFocus();
+ break;
+
+ case WM_SETFOCUS:
+
+ SetFocus( LastFocus );
+ break;
+
+ case WM_CLOSE:
+ //
+ // Save application settings
+ //
+#if 0
+ if( !_SilentMode && _SaveSettingsOnExit ) {
+ SaveApplicationSettings();
+ }
+#endif
+ return DefWindowProc( hWnd, message, wParam, lParam );
+
+ case WM_DESTROY:
+
+ if( !_SilentMode ) {
+ QuitHelp();
+ }
+ PostQuitMessage( 0 );
+ break;
+
+ case WM_INITMENUPOPUP:
+
+// InitializeMenuPopup( wParam, lParam );
+ break;
+
+ case WM_MENUSELECT:
+
+ if( !_SilentMode ) {
+ SetMenuItemHelpContext( wParam, lParam );
+ }
+ break;
+
+ case WM_COMMAND:
+
+ switch( LOWORD( wParam )) {
+
+ case IDB_SAVE_CURRENT_INFO:
+ {
+ HCURSOR Cursor;
+ WCHAR Drive;
+ INT SaveHelpContext;
+
+ SaveHelpContext = GetHelpContext();
+ SetHelpContext( IDH_REPLACE_PREVIOUS );
+
+ Drive = ( WCHAR )'A';
+ Cursor = DisplayHourGlass();
+ if( SaveCurrentConfiguration() ) {
+
+ SetHelpContext( IDH_CREATE_REPAIR );
+ if( CreateRepairDisk( TRUE ) ) {
+ CopyFilesToRepairDisk(Drive);
+ }
+ }
+ SetHelpContext( SaveHelpContext );
+ SetFocus( GetDlgItem( hWnd, IDB_SAVE_CURRENT_INFO ) );
+ RestoreCursor( Cursor );
+ break;
+ }
+
+ case IDB_CREATE_DISK:
+ {
+ HCURSOR Cursor;
+ WCHAR Drive;
+ INT SaveHelpContext;
+
+ SaveHelpContext = GetHelpContext();
+ SetHelpContext( IDH_CREATE_REPAIR );
+
+ Drive = ( WCHAR )'A';
+ Cursor = DisplayHourGlass();
+
+ if( CreateRepairDisk( FALSE ) ) {
+ CopyFilesToRepairDisk(Drive);
+ }
+ SetHelpContext( SaveHelpContext );
+ SetFocus( GetDlgItem( hWnd, IDB_CREATE_DISK ) );
+ RestoreCursor( Cursor );
+ break;
+ }
+
+ case IDB_EXIT:
+ {
+ if( !_SilentMode ) {
+ SendMessage( hWnd, WM_CLOSE, 0, 0 );
+ }
+ break;
+ }
+
+ case IDB_HELP:
+ {
+ if( !_SilentMode ) {
+ DisplayHelpIndex();
+ SetFocus( GetDlgItem( hWnd, IDB_HELP ) );
+ }
+ break;
+ }
+
+ default:
+
+ return DefWindowProc( hWnd, message, wParam, lParam );
+ }
+ break;
+
+ case AP_AUTOMATIC_MODE:
+ {
+ WCHAR Drive;
+ HCURSOR Cursor;
+ Drive = ( WCHAR )'A';
+ Cursor = DisplayHourGlass();
+
+ if(SaveCurrentConfiguration()
+ && ( _AutoSkipRepairDisk
+ || (CreateRepairDisk((BOOLEAN)(!_AutoDoRepairDisk)) && CopyFilesToRepairDisk(Drive))))
+ {
+ _ReturnCode = 1;
+ } else {
+ _ReturnCode = 0;
+ }
+ RestoreCursor( Cursor );
+ PostMessage( hWnd, WM_CLOSE, 0, 0L );
+ break;
+ }
+ case AP_HELP_KEY:
+
+ if( !_SilentMode ) {
+ DisplayHelp();
+ }
+ break;
+
+ default:
+
+ return DefWindowProc( hWnd, message, wParam, lParam );
+ }
+
+ return 0L;
+}
+
+BOOLEAN
+InitializeApp(
+ )
+
+/*++
+
+Routine Description:
+
+ Initialize the application by registering the main window class, the child
+ window class, and by creating the application's main window.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+
+ BOOLEAN - Returns TRUE if the application was successfully initialized.
+ Returns FALSE otherwise.
+
+--*/
+
+{
+ WNDCLASS wc;
+ ULONG StringId;
+
+ //
+ // Register application's main window class.
+ //
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = ( WNDPROC )MainWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = DLGWINDOWEXTRA;
+ wc.hInstance = ( HINSTANCE )_hModule;
+ wc.hIcon = LoadIcon( ( HINSTANCE )_hModule, MAKEINTRESOURCE( IDI_REPAIR_UTILITY ));
+ wc.hCursor = LoadCursor( NULL, IDC_ARROW );
+ wc.hbrBackground = ( HBRUSH )( COLOR_BTNFACE + 1 );
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = _pszApplicationClass;
+
+ if( ! RegisterClass( &wc )) {
+ return FALSE;
+ }
+
+ InitCommonControls();
+
+ //
+ // Get the application name
+ //
+
+ StringId = ( _SilentMode )? IDS_SETUP : IDS_APPLICATION_NAME;
+ LoadString( _hModule,
+ StringId,
+ _szApplicationName,
+ sizeof(_szApplicationName)/sizeof(WCHAR));
+
+ //
+ // Create the main window.
+ //
+
+ _hWndMain = CreateDialog( _hModule,
+ MAKEINTRESOURCE( IDD_REPAIR ),
+ NULL,
+ MainWndProc );
+
+ if( _hWndMain == NULL ) {
+ GetLastError();
+ return FALSE;
+ }
+
+ UpdateWindow( _hWndMain );
+ if( !_SilentMode ) {
+ ShowWindow( _hWndMain, SW_SHOWNORMAL );
+ } else {
+ ShowWindow( _hWndMain, SW_HIDE );
+ PostMessage( _hWndMain, AP_AUTOMATIC_MODE, 0, 0 );
+ }
+ return TRUE;
+}
+
+
+INT _CRTAPI1
+main(
+ IN INT argc,
+ IN PCHAR argv[ ]
+ )
+
+/*++
+
+Routine Description:
+
+ Entry point to the application.
+
+Arguments:
+
+ Standard C program arguments.
+
+Return Value:
+
+
+--*/
+
+{
+ MSG msg;
+ HANDLE hAccel;
+
+ UNREFERENCED_PARAMETER( argc );
+ UNREFERENCED_PARAMETER( argv );
+
+ _SilentMode = FALSE;
+
+ if( argc > 1 ) {
+ PSTR p;
+
+ p = argv[ 1 ];
+
+ if( ( _strnicmp( p, ( LPSTR )"-s", 2 ) == 0 ) ||
+ ( _strnicmp( p, ( LPSTR )"/s", 2 ) == 0 ) ) {
+
+ _SilentMode = TRUE;
+
+ if( p[2] == '-' ) {
+ _AutoSkipRepairDisk = TRUE;
+ } else {
+ if( p[2] == '+' ) {
+ _AutoDoRepairDisk = TRUE;
+ }
+ }
+ }
+ }
+
+ _hModule = GetModuleHandle( NULL );
+
+ //
+ // Register window classes and create the main window
+ //
+ if( ! InitializeApp( )) {
+ return 0;
+ }
+
+ hAccel = LoadAccelerators( ( HINSTANCE )_hModule, MAKEINTRESOURCE( IDA_REPAIR_UTILITY ));
+ if( !_SilentMode ) {
+ InitializeHelp( (LPWSTR)L"rdisk.hlp" );
+ }
+
+ while( GetMessage( &msg, NULL, 0, 0 )) {
+
+ if( ! TranslateAccelerator( _hWndMain, ( HACCEL )hAccel, &msg ) &&
+ ! IsDialogMessage( _hWndMain, &msg )) {
+
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+ }
+ if( !_SilentMode ) {
+ CleanUpHelp();
+ }
+ return _ReturnCode;
+}
diff --git a/private/utils/rdisk/rdisk.h b/private/utils/rdisk/rdisk.h
new file mode 100644
index 000000000..8b4295365
--- /dev/null
+++ b/private/utils/rdisk/rdisk.h
@@ -0,0 +1,65 @@
+/*++
+
+Module Name:
+
+ rdisk.h
+
+Abstract:
+
+ This module contains the declaration of the public functions, and
+ public variables defined on repair.c
+
+Author:
+
+ Jaime Sasson - 24-Jan-1994
+
+Environment:
+
+ ULIB, Windows
+
+--*/
+
+#if !defined( _REPAIR_DISK_ )
+#define _REPAIR_DISK_
+
+#include "windows.h"
+
+extern HWND _hWndMain;
+extern HANDLE _hModule;
+extern BOOLEAN _SilentMode;
+extern WCHAR _szApplicationName[];
+
+//
+// Range we will use for the gas gauge display.
+// This large range provides plenty of granularity.
+//
+#define GAUGE_BAR_RANGE 10000
+
+HCURSOR
+DisplayHourGlass(
+ );
+
+VOID
+RestoreCursor(
+ IN HCURSOR Cursor
+ );
+
+UINT
+DisplayMsgBox(
+ HWND hwnd,
+ UINT MessageResId,
+ UINT MsgBoxFlags,
+ ...
+ );
+
+DWORD
+DiamondCompressFile(
+ IN PSTR SourceFile,
+ IN PSTR TargetFile,
+ IN DWORD GaugeBasePosition,
+ IN DWORD GaugeRangeForThisFile,
+ IN HWND GaugeNotifyWindow
+ );
+
+#endif // _REPAIR_DISK_
+
diff --git a/private/utils/rdisk/rdisk.ico b/private/utils/rdisk/rdisk.ico
new file mode 100644
index 000000000..b447b8007
--- /dev/null
+++ b/private/utils/rdisk/rdisk.ico
Binary files differ
diff --git a/private/utils/rdisk/rdskboot.c b/private/utils/rdisk/rdskboot.c
new file mode 100644
index 000000000..74e72d58f
--- /dev/null
+++ b/private/utils/rdisk/rdskboot.c
@@ -0,0 +1,8 @@
+#define REPAIR_DISK_BOOTSECTOR_SIZE 45
+
+
+unsigned char REPAIR_DISK_BOOTSECTOR[] = {
+51,219,142,211,142,219,188,0,124,184,3,0,205,16,232,0,
+0,94,129,198,28,0,252,180,14,172,10,192,116,4,205,16,
+235,247,180,2,138,211,182,25,205,16,251,235,254
+};
diff --git a/private/utils/rdisk/resource.h b/private/utils/rdisk/resource.h
new file mode 100644
index 000000000..2bcb9e781
--- /dev/null
+++ b/private/utils/rdisk/resource.h
@@ -0,0 +1,70 @@
+//
+// Resource IDs.
+//
+
+#define IDA_REPAIR_UTILITY 110 // Accelerators
+#define IDM_REPAIR_UTILITY 100 // Menu
+#define IDI_REPAIR_UTILITY 200 // Icon
+
+
+
+#define IDM_ABOUT 403
+
+//
+// Help IDs
+//
+
+#define IDH_SYSTEM_MENU 8000
+#define IDH_SAVE_REPAIR_INFO 8001
+#define IDH_REPLACE_PREVIOUS 8002
+#define IDH_CREATE_REPAIR 8003
+#define IDH_NONE 8004
+
+
+//
+// String IDs (strings used on message boxes)
+//
+
+
+#define IDS_APPLICATION_NAME 7000 // Application Name
+#define IDS_SETUP 7001 // Name of setup.exe
+#define IDS_REPAIR_BOOTCODE_MSG 7002
+
+#define IDS_INSERTDISKETTE 7010
+#define IDS_FIRSTREPAIRDISKPROMPT 7011
+#define IDS_SECONDREPAIRDISKPROMPT 7012
+#define IDS_FORMATTINGDISK 7013
+#define IDS_FORMATGENERALFAILURE 7014
+#define IDS_CANTDETERMINEFLOPTYPE 7015
+#define IDS_BADFLOPPYTYPE 7016
+#define IDS_FLOPPYWRITEPROT 7017
+#define IDS_FLOPPYIOERR 7018
+#define IDS_FLOPPYUNKERR 7019
+#define IDS_RETRYFORMATREPAIRDISK 7020
+#define IDS_ALLDATAWILLBELOST 7021
+#define IDS_CANTINITFLOPPYSUP 7022
+#define IDS_HUGEFLOPPYNOTSUPPORTED 7023
+
+#define IDS_COPYING_FILES 7030
+#define IDS_SAVING_CONFIGURATION 7031
+#define IDS_UNABLE_TO_COPY_ALL_FILES 7032
+#define IDS_FILE_NOT_FOUND 7033
+#define IDS_DISK_FULL 7044
+#define IDS_CANT_SAVE_CONFIGURATION 7045
+#define IDS_CONFIRM_SAVE_CONFIGURATION 7046
+#define IDS_CONFIRM_CREATE_DISK 7047
+#define IDS_CONFIRM_CREATE_DISK_TEST 7048
+
+#define IDS_CONFIRM_CREATE_YOU 7049
+
+
+//
+// Application defined messages
+//
+
+#define AP_SAVE_SETTINGS WM_USER
+#define AP_HELP_KEY WM_USER + 1
+#define AP_AUTOMATIC_MODE WM_USER + 20
+#define AP_UPDATE_GAUGE WM_USER + 30
+#define AP_TASK_COMPLETED WM_USER + 40
+#define AP_TERMINATE_DIALOG WM_USER + 50
diff --git a/private/utils/rdisk/resource.rc b/private/utils/rdisk/resource.rc
new file mode 100644
index 000000000..d57af5114
--- /dev/null
+++ b/private/utils/rdisk/resource.rc
@@ -0,0 +1,74 @@
+#include <windows.h>
+#include "resource.h"
+
+//
+// Icon Definition
+//
+
+IDI_REPAIR_UTILITY ICON rdisk.ico
+
+//
+// Accelerator Definition
+//
+
+IDA_REPAIR_DISK ACCELERATORS
+BEGIN
+ VK_F1, IDM_ABOUT, VIRTKEY, CONTROL
+END
+
+//
+// String Table Definition
+//
+
+STRINGTABLE LOADONCALL MOVEABLE DISCARDABLE
+ {
+ IDS_SETUP, "Setup"
+ IDS_APPLICATION_NAME, "Repair Disk Utility"
+ IDS_CANTINITFLOPPYSUP, "%1 was unable to load required floppy disk operation support."
+ IDS_INSERTDISKETTE "Insert Disk"
+ IDS_FIRSTREPAIRDISKPROMPT, "Label a floppy disk 'Emergency Repair Disk' and insert it into drive %1. Select OK when the disk is in the drive.\n\n%2"
+ IDS_ALLDATAWILLBELOST "Warning: All data in the floppy disk will be erased."
+ IDS_SECONDREPAIRDISKPROMPT,"The Setup disk may not be used as the Emergency Repair Disk. Insert a different disk into drive %1.\n\n%2"
+ IDS_RETRYFORMATREPAIRDISK, "%1 was unable to create the Emergency Repair Disk from the disk you provided because the disk could not be formatted.\n\nInsert a new disk into drive %2 and select Retry."
+ IDS_CANTDETERMINEFLOPTYPE, "%1 is unable to get configuration information for the floppy disk drive."
+ IDS_BADFLOPPYTYPE, "The floppy drive is unable to support the required media type."
+ IDS_FORMATGENERALFAILURE, "%1 was unable to format the disk."
+ IDS_FLOPPYWRITEPROT, "The floppy cannot be written to because it is write-protected."
+ IDS_FLOPPYIOERR, "An error occurred reading from or writing to the disk.\n\nThe disk is unusable."
+ IDS_FLOPPYUNKERR, "An unknown error has occurred reading from or writing to the disk.\n\nThe disk is possibly unusable."
+ IDS_HUGEFLOPPYNOTSUPPORTED,"The Emergency Repair Disk cannot be a 120MB floppy disk."
+ IDS_REPAIR_BOOTCODE_MSG "The Emergency Repair Disk is not startable.\r\n\r\nRepairing a damaged Windows NT installation is an option\r\navailable at the beginning of Windows NT Setup.\r\nTo start Setup, insert the Windows NT Setup Disk into drive A:.\r\n\r\nPress control+alt+delete to restart your computer."
+
+ IDS_FORMATTINGDISK, "Formatting Disk"
+
+ IDS_COPYING_FILES, "Copying Configuration Files"
+ IDS_SAVING_CONFIGURATION, "Saving Configuration"
+ IDS_UNABLE_TO_COPY_ALL_FILES, "%1 could not copy all files to the Emergency Repair Disk."
+ IDS_FILE_NOT_FOUND, "%1 could not copy all files to the Emergency Repair Disk.\n\nOne or more configuration files were not found."
+ IDS_DISK_FULL, "%1 could not copy all files to the Emergency Repair Disk.\n\nThe Emergency Repair Disk is full. The configuration files were saved in your hard disk."
+ IDS_CANT_SAVE_CONFIGURATION, "%1 could not save all configuration files."
+ IDS_CONFIRM_SAVE_CONFIGURATION, "The repair information that was saved when you installed the system or when you last ran this utility will be deleted.\n\nDo you want to continue this operation?"
+ IDS_CONFIRM_CREATE_DISK, "%1 can create an Emergency Repair disk, which will contain a copy of the repair information in your system. This disk can be used in the future to repair Windows NT.\n\nDo you want to create the Emergency Repair disk?"
+ IDS_CONFIRM_CREATE_YOU, "You"
+ }
+
+
+
+//
+// Dialogs Definition
+//
+
+#include "dialogs.h"
+// #include "gauge.h"
+#include "dialogs.dlg"
+
+
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_APP
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "Repair Disk Utility"
+#define VER_INTERNALNAME_STR "rdisk.exe"
+#define VER_ORIGINALFILENAME_STR "rdisk.exe"
+
+#include "common.ver"
diff --git a/private/utils/rdisk/sources b/private/utils/rdisk/sources
new file mode 100644
index 000000000..ee7dbc915
--- /dev/null
+++ b/private/utils/rdisk/sources
@@ -0,0 +1,29 @@
+MAJORCOMP=utils
+MINORCOMP=rdisk
+
+TARGETNAME=rdisk
+TARGETPATH=obj
+TARGETTYPE=LIBRARY
+
+C_DEFINES=-DUNICODE
+
+SOURCES=resource.rc \
+ config.c \
+ format.c \
+ floppyop.c \
+ help.c \
+ diamond.c
+
+UMTYPE=windows
+UMAPPL=rdisk
+UMLIBS= $(BASEDIR)\public\sdk\lib\*\mci.lib \
+ $(BASEDIR)\public\sdk\lib\*\fci.lib \
+ $(BASEDIR)\public\sdk\lib\*\qstub.lib \
+ $(BASEDIR)\public\sdk\lib\*\comctl32.lib \
+ obj\*\rdisk.lib
+
+UMRES=obj\*\resource.res
+
+PRECOMPILED_INCLUDE=precomp.h
+PRECOMPILED_PCH=precomp.pch
+PRECOMPILED_OBJ=precomp.obj