home *** CD-ROM | disk | FTP | other *** search
- /*
- * DRSP - DriveSpeed, version 3.10 (GPL FREEWARE)
- * Copyleft (l) Stanislav Sokolov, May 1998 and onwards.
- *
- * This program is subject to GNU General Public License ver. 2 of June 1991
- * and any later version.
- *
- * You may use this source with your programs, provided
- * due credits are given.
- *
- * Contact the author by e-mail: stanislavs@hotmail.com
- *
- * Internet: http://members.tripod.com/~stanislavs/prog/prog.htm
- */
-
- #include "D:\TC\MY\DRSP\DRSP.H"
-
-
- int HError = 0;
- Bool fError = False;
-
- //Local global variable used by DRSPCC
- Bool FromCC = False;
- extern char **environ;
-
- int main(int argc, char *argv[]){
- TestData TD;
- float WriteSpd = 0.0, ReadSpd = 0.0;
- unsigned int i;
- TestFile TF[MAX_FBUF];
- char *RetPath = NULL; //Will be allocated in SearchRO()
-
- //Init TF
- for(i = 0; i < MAX_FBUF; i++)
- TF[i].Size = 0;
-
- //Display help if the user enters /?
- if(!(strcmp(argv[1], "/?") && strcmp(argv[1], "-?")))
- Info(True);
- else
- Info(False);
-
-
- //Install a do-nothing Ctrl-Break routine.
- FindLong f;
- f.Whole = (long)Brk;
- asm{
- push DS
- mov AH, 0x25
- mov AL, 0x23
- mov DS, word ptr [f.Part.High]
- mov DX, word ptr [f.Part.Low]
- int 0x21
- pop DS
- }
-
-
- //Install a hardware-error handler routine.
- harderr(FatalHandler);
-
- //Parse the program arguements
- TD = ParseArg(argc, argv);
-
- //Get the test parameters, if they are not (correctly) given in the
- //COMMAND-line. Note that the batch-mode is reset to false in this case.
-
- //Work with the drive letter
- if((TD.Drive == '\0') && TD.Batch)
- Abort(0, NULL, "\nNo drive selected!", EX_BAD_DRV);
-
- if((TD.Drive == '\0') && Ask("\nScan for available drives? (Y/N) ") == 'Y')
- ScanDrv();
-
- if((TD.Drive == '\0') || !DriveIsOK(TD.Drive - 64)){
- if(TD.Batch)
- Abort(0, NULL, "\nWrong drive selected!", EX_BAD_DRV);
- TD.Drive = GetDrive();
- }else
- printf("Drive %c: selected.", TD.Drive);
-
- //Test if RO-mode should be used
- TD.RO = SetRO(TD);
-
- //Ajust or get the testsize
- TD.Size = GetTestSize(&TD);
-
- //Prepare Read-Only test.
- if(TD.RO != Off)
- RetPath = SearchRO(&TD, TF);
-
- //Get the number of turns
- if(((TD.Turns < 3) || (TD.Turns > 999)) && (TD.RO != Single)){
- if(TD.Batch)
- Abort(0, NULL, "\nWrong number of turns selected!", EX_BAD_TURN);
- TD.Turns = GetTurns();
- }else if(TD.RO != Single)
- printf("\n%i turns selected.", TD.Turns);
-
- //Perform the test & display results
- if(TD.RO == Off){
- DoTest(TD, &ReadSpd, &WriteSpd);
- Analyze(TD, WriteSpd, ReadSpd, TestFAS(TD.Drive));
- }else{
- if(TD.RO == Multi)
- ReadSpd = DoTest(RetPath, TD);
- else{
- ReadSpd = DoTest(TF, TD.Size);
- TD.Turns = 1; //Set to one to mark a single-pass test
- }
-
- Analyze(TD, ReadSpd);
- }
-
- nfree(RetPath);
- nfree(TD.LogFile);
-
- //Make a "meep" when the program is done.
- sound(45);
- delay(110);
- nosound();
-
- nexit(EX_OK);
- return EX_OK;
- }
-
-
- TestData ParseArg(int argc, char *argv[]){
- //Example of legal arguments DRSP c: /t3 /s3.4
- //Means test drive c: with 3.4MB test-file over 3 turns
- //DRSP c: /R /t4 /s9
- //Perform read-only test of drive c: 4 times, while finding a file, which
- //is not larger than 9MB
- //
- //Additional arguments from ver. 3.00 are:
- // /rs - read-only single-pass mode; /rm - read-only multi-pass mode;
- // /b - batch mode.
- //Additional argument from ver. 3.10 is:
- // /l - specifies the log-file name and path to use.
-
- TestData TD;
-
- //Initialize test data.
- memset(&TD, 0, sizeof(TestData));
-
- for(int i = 1; i < argc; i++){
- switch (argv[i][1]){
- case ':':
- TD.Drive = argv[i][0];
- if(TD.Drive >= 97) TD.Drive -= 32;
- break;
-
- case 't':
- case 'T':
- TD.Turns = atoi(&argv[i][2]);
- break;
-
- case 's':
- case 'S':
- TD.TestSize = atof(&argv[i][2]);
- break;
-
- case 'r':
- case 'R':
- if((argv[i][2] == 's') || (argv[i][2] == 'S'))
- TD.RO = Single;
- else if((argv[i][2] == 'm') || (argv[i][2] == 'M'))
- TD.RO = Multi;
- break;
-
- case 'b':
- case 'B':
- TD.Batch = True;
- break;
-
- case 'l':
- case 'L':
- TD.LogFile = strdup(&argv[i][2]);
- break;
-
- case 'f': //Undocumented - used by the front-end DRSPCC
- case 'F':
- FromCC = True;
- break;
-
- }
-
- }// end for()
-
- return TD;
- }
-
-
- //General prompt routine
- char Ask(const char *Prompt){
- printf("%s", Prompt);
-
- while (!kbhit());
- textcolor(10);
- char Resp = getche();
- textcolor(7);
-
- if((Resp >= 97) && (Resp <= 122)) Resp -= 32;
-
- if(Resp == 27) nexit(EX_ABORT); //User wants to quit
-
- return Resp;
- }
-
-
-
- void Abort(int Handle, const char *FName, const char *Msg, int status){
- _setcursortype(_NORMALCURSOR);
- textcolor(12);
- cprintf("\r%s\r", Msg);
- textcolor(7);
- printf("\n\n\n");
- if(Handle != 0) close(Handle);
- if(FName != NULL) unlink(FName);
-
- nexit(status);
- }
-
-
-
- //General info
- void Info(Bool Help){
- printf("\nDriveSpeed, version 3.10 (GPL FREEWARE)\n"
- "Copyleft (l) Stanislav Sokolov, May 1998 and onwards.\n\n"
- );
-
- if(Help){
- printf("DriveSpeed uses the most common sequential write and read operations performed\n"
- "via DOS functions 3fH and 40H. It also tests File Access Speed. The program can\n"
- "test any drive.\n\n"
-
- "The program will check which drives are available, ask for which drive to test,\n"
- "the size of the test file, and how many times it should repeat the test. At the\n"
- "end of the test you will be prompted to store the results in a log-file. Read-\n"
- "only drives can be tested with one of the two read-only modes.\n\n"
-
- "DriveSpeed accepts COMMAND-line parameters:\tDRSP C: /S3.5 /T5,\n"
- "which means: test drive C: with a 3.5MB test-file, repeating the test 5 turns.\n"
- "Invalid pameters will be re-prompted from within the program. For more\n"
- "information see README.TXT\n\n"
-
- "If you find this program useful, send me an (e-)postcard telling so:\n"
-
- "\tStanislav Sokolov,\tE-mail:\n"
- "\tSnorresvei 24,\t\t stanislavs@hotmail.com\n"
- "\t1473 SKÅRER,\t\tInternet:\n"
- "\tNorway\t\t\t http://members.tripod.com/~stanislavs/\n"
- );
-
- nexit(EX_OK);
-
- }
-
- if((_osmajor < 4)/* || ((_osmajor == 4) && (_osminor < 0))*/){
- textcolor(12);
- cprintf("The program will only run under DOS version 4.0 or higher.\n");
- textcolor(7);
- nexit(EX_OLD_DOS);
- }
-
-
- printf("This program will test a conventional speed of a selected drive\n"
- "by performing a series of DOS I/O operations.\n\n"
- );
- }
-
-
- void ClearCache(void){
- //Crear SMARTDRV's cache (and hopefully Windows xxxx')
- asm{
- mov AX, 0x4A10
- mov BX, 0x0001 //Commit
- int 0x2F
- mov AX, 0x4A10
- mov BX, 0x0002 //Clear
- int 0x2F
- }
- }
-
-
- //Works according to UNIX specification - NULL pointer is ignored!
- void nfree(void *ptr){
- if(ptr == NULL) return;
- free(ptr);
- }
-
- //A special version of exit() that prints the status to a file that is used
- //by the Windows front-end. Windows is seemingly unable to pass the return
- //status to the caller, so I had to employ this work-around.
- void nexit(int status){
- FILE *Res;
- char resPath[MAX_PATH];
- char *tmp;
-
- if(FromCC){
- //Try to put the res-file to a path in either TEMP, TMP or root.
- tmp = getenv("TEMP");
- if(tmp == NULL) tmp = getenv("TMP");
- if(tmp == NULL) tmp = "C:\\";
-
- strcpy(resPath, tmp);
- if(resPath[strlen(resPath) - 1] != '\\')
- strcat(resPath, "\\");
- strcat(resPath, "@DRSPRES.TMP");
-
- if((Res = fopen(resPath, "w+t")) != NULL){
- fprintf(Res, "%d", status);
- fclose(Res);
- }
- }
-
- _setcursortype(_NORMALCURSOR);
-
- exit(status);
- }