|
|
/*++
Copyright (c) 1991-2000 Microsoft Corporation
Module Name:
diskcomp.cxx
Abstract:
Utility to compare two disks
Author:
Norbert P. Kusters (norbertk) 10-May-1991
Revision History:
--*/
#define _NTAPI_ULIB_
#include "ulib.hxx"
#include "arg.hxx"
#include "array.hxx"
#include "smsg.hxx"
#include "rtmsg.h"
#include "wstring.hxx"
#include "system.hxx"
#include "ifssys.hxx"
#include "supera.hxx"
#include "hmem.hxx"
#include "cmem.hxx"
#include "ulibcl.hxx"
INT DiskComp( IN PCWSTRING SrcNtDriveName, IN PCWSTRING DstNtDriveName, IN PCWSTRING SrcDosDriveName, IN PCWSTRING DstDosDriveName, IN OUT PMESSAGE Message ) /*++
Routine Description:
This routine copies on floppy diskette to another floppy diskette.
Arguments:
SrcNtDriveName - Supplies the NT style drive name for the source. DstNtDriveName - Supplies the NT style drive name for the destination. SrcDosDriveName - Supplies the DOS style drive name for the source. DstDosDriveName - Supplies the DOS style drive name for the destination. Message - Supplies an outlet for messages.
Return Value:
0 - The disks are the same. 1 - The disks are different. 3 - A hard error occurred. 4 - An initialization error occurred.
--*/ { LOG_IO_DP_DRIVE src_drive; LOG_IO_DP_DRIVE dst_drive; HMEM src_hmem; HMEM dst_hmem; CONT_MEM src_cmem; PVOID mem_ptr; SECRUN src_secrun; SECRUN dst_secrun; SECTORCOUNT sec_per_track; ULONG total_tracks; ULONG grab; // number of tracks to grab at once.
ULONG sector_size; BOOLEAN one_drive; ULONG src_top; // src track pointer -- next read
ULONG dst_top; // dst track pointer -- next write
PCHAR dst_pchar; PCHAR src_pchar; ULONG i; BOOLEAN the_same; ULONG heads; DSTRING fsname; #if defined(FE_SB) && defined(_X86_)
MEDIA_TYPE AltMediaType; #endif
one_drive = (*SrcDosDriveName == *DstDosDriveName);
Message->Set(MSG_DCOMP_INSERT_FIRST); Message->Display("%W", SrcDosDriveName);
if (!one_drive) { Message->Set(MSG_DCOMP_INSERT_SECOND); Message->Display("%W", DstDosDriveName); }
Message->Set(MSG_PRESS_ENTER_WHEN_READY); Message->Display(); Message->WaitForUserSignal();
if (!src_drive.Initialize(SrcNtDriveName)) {
// Verify that we can access the source drive:
if (src_drive.QueryLastNtStatus() == STATUS_ACCESS_DENIED) { Message->Set(MSG_DASD_ACCESS_DENIED); Message->Display(); return 4; }
Message->Set(MSG_DCOMP_FIRST_DISK_BAD); Message->Display(); return 3; }
if (!src_drive.IsFloppy()) { Message->Set(MSG_DCOPY_INVALID_DRIVE); Message->Display(); return 4; }
if (src_drive.QueryMediaType() == Unknown) { Message->Set(MSG_DCOMP_FIRST_DISK_BAD); Message->Display(); return 3; }
Message->Set(MSG_DCOMP_COMPARING); Message->Display("%d%d%d", src_drive.QueryCylinders().GetLowPart(), src_drive.QuerySectorsPerTrack(), src_drive.QueryHeads());
sec_per_track = src_drive.QuerySectorsPerTrack(); sector_size = src_drive.QuerySectorSize(); total_tracks = src_drive.QueryTracks().GetLowPart(); heads = src_drive.QueryHeads();
DebugAssert(src_drive.QuerySectors().GetHighPart() == 0);
src_top = 0;
if (!dst_hmem.Initialize()) { return 4; }
the_same = TRUE;
for (dst_top = 0; dst_top < total_tracks; dst_top++) {
if (src_top == dst_top) {
if (src_top && one_drive) { Message->Set(MSG_DCOMP_INSERT_FIRST); Message->Display("%W", SrcDosDriveName); Message->Set(MSG_PRESS_ENTER_WHEN_READY); Message->Display(); Message->WaitForUserSignal(); }
// Allocate memory for read.
for (grab = total_tracks - src_top; !src_hmem.Initialize() || !(mem_ptr = src_hmem.Acquire(grab*sector_size*sec_per_track, src_drive.QueryAlignmentMask())); grab /= 2) {
if (grab < 2) { Message->Set(MSG_CHK_NO_MEMORY); Message->Display(); return 4; } }
if (!src_cmem.Initialize(mem_ptr, grab*sector_size*sec_per_track)) { return 4; }
// Read the source, track by track.
for (i = 0; i < grab; i++) { if (!src_secrun.Initialize(&src_cmem, &src_drive, src_top*sec_per_track, sec_per_track)) { return 4; }
if (!src_secrun.Read()) {
if (src_drive.QueryLastNtStatus() == STATUS_NO_MEDIA_IN_DEVICE || src_drive.QueryLastNtStatus() == STATUS_UNRECOGNIZED_MEDIA) { return 3; }
Message->Set(MSG_DCOPY_READ_ERROR); Message->Display("%W%d%d", SrcDosDriveName, src_top%heads, src_top/heads); the_same = FALSE; } src_top++; }
if (!src_cmem.Initialize(mem_ptr, grab*sector_size*sec_per_track)) { return 4; }
if (one_drive) { Message->Set(MSG_DCOMP_INSERT_SECOND); Message->Display("%W", DstDosDriveName); Message->Set(MSG_PRESS_ENTER_WHEN_READY); Message->Display(); Message->WaitForUserSignal(); }
if (!dst_top) {
if (!dst_drive.Initialize(DstNtDriveName)) {
// verify that we can access the destination drive:
if (dst_drive.QueryLastNtStatus() == STATUS_ACCESS_DENIED) {
Message->Set(MSG_DASD_ACCESS_DENIED); Message->Display( "" ); return 4; }
Message->Set(MSG_DCOMP_SECOND_DISK_BAD); Message->Display(); return 3; }
if (dst_drive.QueryMediaType() != src_drive.QueryMediaType()) { #if defined(FE_SB) && defined(_X86_)
switch (src_drive.QueryMediaType()) { case F5_1Pt23_1024: AltMediaType = F3_1Pt23_1024; break; case F3_1Pt23_1024: AltMediaType = F5_1Pt23_1024; break; case F5_1Pt2_512: AltMediaType = F3_1Pt2_512; break; case F3_1Pt2_512: AltMediaType = F5_1Pt2_512; break; case F3_720_512: AltMediaType = F5_720_512; break; case F5_720_512: AltMediaType = F3_720_512; break; case F5_640_512: AltMediaType = F3_640_512; break; case F3_640_512: AltMediaType = F5_640_512; break; default: AltMediaType = src_drive.QueryMediaType(); break; }
// Second try with AltMediaType
if (dst_drive.QueryMediaType() != AltMediaType) { #endif
Message->Set(MSG_DCOMP_NOT_COMPATIBLE); Message->Display(); return 4; #if defined(FE_SB) && defined(_X86_)
} #endif
} } }
if (!dst_secrun.Initialize(&dst_hmem, &dst_drive, dst_top*sec_per_track, sec_per_track)) { return 4; }
if (dst_secrun.Read()) { src_pchar = (PCHAR) src_cmem.Acquire(sector_size*sec_per_track); dst_pchar = (PCHAR) dst_secrun.GetBuf();
if (!dst_top) { if ((src_pchar[0x26] == 0x28 || src_pchar[0x26] == 0x29) && (dst_pchar[0x26] == 0x28 || dst_pchar[0x26] == 0x29)) { memcpy(src_pchar + 0x27, dst_pchar + 0x27, sizeof(ULONG)); } }
if (memcmp(src_pchar, dst_pchar, (UINT) (sector_size*sec_per_track))) { Message->Set(MSG_DCOMP_COMPARE_ERROR); Message->Display("%d%d", dst_top%heads, dst_top/heads); the_same = FALSE; }
} else {
if (dst_drive.QueryLastNtStatus() == STATUS_NO_MEDIA_IN_DEVICE || dst_drive.QueryLastNtStatus() == STATUS_UNRECOGNIZED_MEDIA) { return 3; }
Message->Set(MSG_DCOPY_READ_ERROR); Message->Display("%W%d%d", DstDosDriveName, dst_top%heads, dst_top/heads); the_same = FALSE; } }
if (the_same) { Message->Set(MSG_DCOMP_OK); Message->Display(); }
return the_same ? 0 : 1; }
INT __cdecl main( ) /*++
Routine Description:
Main program for DISKCOMP.
Arguments:
None.
Return Value:
0 - The disks are the same. 1 - The disks are different. 3 - Fatal hard error. 4 - Initialization error.
--*/ { STREAM_MESSAGE msg; PMESSAGE message; ARGUMENT_LEXEMIZER arglex; ARRAY lex_array; ARRAY arg_array; STRING_ARGUMENT progname; STRING_ARGUMENT drive_arg1; STRING_ARGUMENT drive_arg2; FLAG_ARGUMENT slashv; FLAG_ARGUMENT helparg; DSTRING dossource; DSTRING dosdest; DSTRING ntsource; DSTRING ntdest; PWSTRING pwstring; DSTRING colon; INT result;
if (!msg.Initialize(Get_Standard_Output_Stream(), Get_Standard_Input_Stream())) { return 4; }
message = &msg;
if (!lex_array.Initialize() || !arg_array.Initialize()) { return 4; }
if (!arglex.Initialize(&lex_array)) { return 4; }
arglex.SetCaseSensitive(FALSE);
if (!arglex.PrepareToParse()) { return 4; }
if (!progname.Initialize("*") || !drive_arg1.Initialize("*:") || !drive_arg2.Initialize("*:") || !helparg.Initialize("/?")) { return 4; }
if (!arg_array.Put(&progname) || !arg_array.Put(&drive_arg1) || !arg_array.Put(&drive_arg2) || !arg_array.Put(&helparg)) { return 4; }
if (!arglex.DoParsing(&arg_array)) { message->Set(MSG_INVALID_PARAMETER); message->Display("%W", pwstring = arglex.QueryInvalidArgument()); DELETE(pwstring); return 4; }
if (helparg.QueryFlag()) { message->Set(MSG_DCOMP_INFO); message->Display(); message->Set(MSG_DCOMP_USAGE); message->Display(); return 0; }
if (!colon.Initialize(":")) { return 4; }
if (drive_arg1.IsValueSet()) { if (!dossource.Initialize(drive_arg1.GetString()) || !dossource.Strcat(&colon) || !dossource.Strupr()) { return 4; } } else { if (!SYSTEM::QueryCurrentDosDriveName(&dossource)) { return 4; } }
if (drive_arg2.IsValueSet()) { if (!dosdest.Initialize(drive_arg2.GetString()) || !dosdest.Strcat(&colon) || !dosdest.Strupr()) { return 4; } } else { if (!SYSTEM::QueryCurrentDosDriveName(&dosdest)) { return 4; } }
if (SYSTEM::QueryDriveType(&dossource) != RemovableDrive) { message->Set(MSG_DCOPY_INVALID_DRIVE); message->Display(); return 4; }
if (SYSTEM::QueryDriveType(&dosdest) != RemovableDrive) { message->Set(MSG_DCOPY_INVALID_DRIVE); message->Display(); return 4; }
if (!IFS_SYSTEM::DosDriveNameToNtDriveName(&dossource, &ntsource)) { message->Set(MSG_DCOPY_INVALID_DRIVE); message->Display(); return 4; }
if (!IFS_SYSTEM::DosDriveNameToNtDriveName(&dosdest, &ntdest)) { message->Set(MSG_DCOPY_INVALID_DRIVE); message->Display(); return 4; }
for (;;) {
result = DiskComp(&ntsource, &ntdest, &dossource, &dosdest, message);
if (result > 1) { message->Set(MSG_DCOMP_ENDED); message->Display(); }
message->Set(MSG_DCOMP_ANOTHER); message->Display();
if (!message->IsYesResponse(FALSE)) { break; } }
return result; }
|