mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
347 lines
8.0 KiB
347 lines
8.0 KiB
#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 );
|
|
}
|