/*++ Copyright (c) 1991-2000 Microsoft Corporation Module Name: diskcopy.cxx Abstract: Utility to duplicate a disk 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" #include "mldcopy.hxx" INT __cdecl main( ) /*++ Routine Description: Main program for DISKCOPY. Arguments: None. Return Value: 0 - Copy was successful. 1 - A nonfatal read/write error occured. 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; FLAG_ARGUMENT genvalue; DSTRING dossource; DSTRING dosdest; DSTRING ntsource; DSTRING ntdest; DSTRING currentdrive; 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("*:") || !slashv.Initialize("/v") || !helparg.Initialize("/?") || !genvalue.Initialize("/machinetoken")) { return 4; } if (!arg_array.Put(&progname) || !arg_array.Put(&drive_arg1) || !arg_array.Put(&drive_arg2) || !arg_array.Put(&slashv) || !arg_array.Put(&helparg) || !arg_array.Put(&genvalue)) { return 4; } if (!arglex.DoParsing(&arg_array)) { message->Set(MSG_INVALID_PARAMETER); message->Display("%W", pwstring = arglex.QueryInvalidArgument()); DELETE(pwstring); return 4; } if (genvalue.QueryFlag()) { message->Set(MSG_ONE_STRING_NEWLINE); message->Display("%X", QueryMachineUniqueToken()); return 0; } if (helparg.QueryFlag()) { message->Set(MSG_DCOPY_INFO); message->Display(); message->Set(MSG_DCOPY_USAGE); message->Display(); message->Set(MSG_DCOPY_SLASH_V); message->Display(); message->Set(MSG_DCOPY_INFO_2); 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 (!SYSTEM::QueryCurrentDosDriveName(¤tdrive) || currentdrive == dosdest) { message->Set(MSG_CANT_LOCK_CURRENT_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 = DiskCopyMainLoop(&ntsource, &ntdest, &dossource, &dosdest, slashv.QueryFlag(), message); if (result > 1) { message->Set(MSG_DCOPY_ENDED); message->Display(); } message->Set(MSG_DCOPY_ANOTHER); message->Display(); if (!message->IsYesResponse(FALSE)) { break; } } return result; }