summaryrefslogtreecommitdiffstats
path: root/private/utils/rdisk/config.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/utils/rdisk/config.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/utils/rdisk/config.c')
-rw-r--r--private/utils/rdisk/config.c908
1 files changed, 908 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 );
+}
+