home *** CD-ROM | disk | FTP | other *** search
-
- Program CheckOS;
-
- { This program was written to be compiled with Turbo Pascal version 4.0. It }
- { checks the Filesize, File Date/Time (last updated), and Checksum of }
- { COMMAND.COM, AUTOEXEC.BAT, and CONFIG.SYS. It was developed to verify }
- { that no virus had installed itself in DOS. It does not stay resident to }
- { guard against Viruses, it just checks the specified drive once when the }
- { program is invoked. It also doesn't have terribly extensive error }
- { checking so little things like the disk being too full to create the }
- { Control file, or a Write protect error will cause a runtime error. I }
- { didn't feel it was necessary to fix these since I only use the program on }
- { my hard disk. }
- { }
- { No warranty is given with this software - use at your own risk. }
- { }
- { R.J. Bartlett 05 March 1988 GEnie address R.BARTLETT }
- { }
- { Modified by Erik Ch. Ohrnberger GEnie address E.OHRNBERGER }
- { Added support for ReadOnly files and the CONFIG.SYS SHELL= line. For }
- { people who configured their system so that the COMMAND.COM file is not }
- { in the root of the hard drive. }
- { }
-
- {$R-,S-,I+,D+,T-,F-,V-,B-,N-,L+}
- {$M 8192,0,0}
-
- Uses
- DOS, CRT, StdDef, StdFunc, Debug;
-
- Const
- Checked_Files = 5;
-
- Type
- Frec = Record
- FPathname : string79; { max string for Assigns }
- FSize : LongInt;
- FTime : LongInt;
- FChkSum : Word;
- End;
-
- Frec_Array = Array [1..Checked_Files] Of Frec;
-
- Var
-
- {
- The NewRec array contains the current file information. The CtlRec array
- contains the refrence information. Both arrays hold the file information
- in the following order:
- Array element: 1 File: COMMAND.COM
- 2 CONFIG.SYS (if it exists)
- 3 AUTOEXEC.BAT (if it exists)
- 4 IBMDOS.COM (or 'DOS' hidden system file)
- 5 IBMBIO.COM (or 'BIO' hidden system file)
-
- }
-
- Buffer : Array [1..4096] Of Byte;
- CtlRec : Frec_Array;
- CtlFile : File of frec;
- Drive : Char;
- ErrFlag : Boolean;
- I : Integer;
- NewRec : Frec_Array;
- Parm : String [80];
-
-
-
- Function ChkSumBlock (Count : Word;
- OldChkSum : Word) : Word;
-
- Var
- I : Word;
- ChkSum : Word;
-
- Begin
- ChkSum := OldChksum;
- For I := 1 To Count Do
- ChkSum := ChkSum + (Buffer [I] XOR I);
- ChkSumBlock := ChkSum;
- End;
-
-
- Procedure ChkFile (Var FArray : Frec_Array;
- Ndx : Word);
-
- Var
- Attr_Word : Word;
- Cnt : Word;
- F : File;
-
- Begin
- If (Length (FArray [Ndx]. FPathname) <> 0) Then
- Begin
- Assign (F, Drive + FArray [Ndx]. FPathname);
- GetFAttr (F, Attr_Word);
- SetFAttr (F, Archive);
- {$I-} Reset (F, 1); {$I+}
- If (IOResult <> 0) Then
- Begin
- Close (CtlFile);
- Erase (CtlFile);
- Error_Halt ('Could not find the: ' + Drive +
- FArray [Ndx]. FPathname + ' file.');
- End;
- GetFTime (F, FArray [Ndx]. FTime);
- FArray [Ndx]. FSize := FileSize (F);
- FArray [Ndx]. FChkSum := 0;
- Repeat
- BlockRead (F, Buffer, 4096, Cnt);
- FArray [Ndx]. FChkSum := ChkSumBlock (Cnt, FArray [Ndx].FChkSum);
- Until (Cnt < 1024);
- Close (F);
- SetFAttr (F, Attr_Word);
- End;
- End; { Of Procedure ChkFile }
-
-
- Procedure WrtError (ErrMsg : String;
- FNum : Word;
- FilePath : AnyStr);
-
- Begin
- WriteLn (ErrMsg,' mismatch on file ', Drive, FilePath);
- ErrFlag := True;
-
- End;
-
-
- Procedure ValidateFiles;
-
- Var
- I : Integer;
- Ch : Char;
-
- Begin
- ErrFlag := false;
- For I := 1 To Checked_Files Do
- Begin
- If CtlRec [I]. FSize <> NewRec [I]. FSize Then
- WrtError ('File size', I, CtlRec [I]. FPathname);
- If CtlRec [I]. FTime <> NewRec [I]. FTime Then
- WrtError ('Date/Time', I, CtlRec [I]. FPathname);
- If CtlRec [I]. FChkSum <> NewRec [I]. FChkSum Then
- WrtError ('Checksum ', I, CtlRec [I]. FPathname);
- End;
- If ErrFlag Then
- Begin
- WriteLn ( CR, LF,
- 'Check-OS has determined that the file (or files) listed above', CR, LF,
- 'have been changed since the last time Check-OS was run.', CR, LF,
- #7,
- 'Do you wish to update the Check-OS control file (\Check-OS.CTL)', CR, LF);
- Write ('to reflect new values (Y or N)? ');
- Ch := ReadKey;
- WriteLn (Ch);
- If UpCase (Ch) = 'Y' Then
- Begin
- ReWrite (CtlFile);
- For I := 1 To Checked_Files Do
- Write (CtlFile, NewRec [I]);
- End;
- End
- Else
- WriteLn ('Check-OS found no errors');
- End;
-
- Procedure CreateControlFile;
-
- Var
- Attr_Word : Word;
- Config : Text;
- Config_Found : Boolean;
- Dir_Info : SearchRec;
- I : Word;
- J : Word;
- Line : AnyStr;
- Shell_Found : Boolean;
-
- Begin
- {
- If the drive has a CONFIG.SYS file, and a 'SHELL=' line, find and log that
- file path for the COMMAND.COM . If there is an AUTOEXEC.BAT file log
- it. If there is a CONFIG.SYS file, log that too.
- }
- FillChar (CtlRec, SizeOf (CtlRec), Null);
- Config_Found := False;
- Assign (Config, Drive + ':\CONFIG.SYS');
- {$I-} Reset (Config); {$I+}
-
- If (IOResult <> 0) Then { Didn't find file, try readonly. }
- Config_Found := False
- Else
- Config_Found := True;
-
- If Config_Found Then { scan CONFIG.SYS for 'SHELL=' line }
- Begin
- Shell_Found := False;
- CtlRec [2]. FPathname := ':\CONFIG.SYS';
- While NOT EOF (Config) AND NOT Shell_Found Do
- Begin
- ReadLn (Config, Line);
- I := Pos ('SHELL', UpCaseStr (Line));
- If I <> 0 Then
- Begin
- I := Pos ('=', Line);
- J := Pos ('.COM', Line);
- Line := RTrim (LTrim (SubStr (Line, I + 1, J + 4)));
- Shell_Found := True;
- End;
- End;
- Close (Config);
- CtlRec [1].fpathname := SubStr (Line, 2, Length (Line));
- End
- Else
- CtlRec [1].fpathname := ':\COMMAND.COM';
- CtlRec [3].fpathname := ':\AUTOEXEC.BAT';
-
- Attr_Word := Hidden OR SysFile;
- I := 4;
- FindFirst (Drive + ':\*.*', Attr_Word, Dir_Info);
- While (DOSError = 0) AND (I <= Checked_Files) Do
- Begin
- If (Pos ('DOS', Dir_Info.Name) <> 0) OR
- (Pos ('BIO', Dir_Info.Name) <> 0) Then
- Begin
- CtlRec [I]. FPathname := ':\' + Dir_Info.Name;
- Inc (I);
- End;
- FindNext (Dir_Info);
- End;
-
- Assign (CtlFile, Drive + ':\CHECK-OS.CTL');
- ReWrite (CtlFile);
- For I := 1 to Checked_Files Do
- Begin
- ChkFile (CtlRec, I);
- Write (CtlFile, CtlRec[I]);
- End;
- Writeln ('Control file created');
-
- End;
-
-
-
- Begin
- DirectVideo := False; { make this program well behaved. }
- Assign (Output,''); { allows redirection even though CRT unit is used }
- ReWrite (Output);
- WriteLn ('Check-OS Version 1.0b 13 March 88', CR, LF);
- If (ParamCount < 1) Then
- WriteLn ('Usage: Check-OS <drive letter>')
- Else
- Begin
- Parm := Paramstr (1);
- Drive := UpCase (Parm [1]);
- Assign (CtlFile, Drive + ':\CHECK-OS.CTL');
- {$I-} Reset (CtlFile); {$I+}
- If (IOResult = 0) Then
- Begin
- For I := 1 to Checked_Files Do
- Begin
- Read (CtlFile, CtlRec[I]);
- NewRec [I]. FPathname := CtlRec [I]. FPathname;
- ChkFile (NewRec, I);
- End;
- ValidateFiles;
- End
- Else
- CreateControlFile;
- Close (CtlFile);
- End;
- End.