home *** CD-ROM | disk | FTP | other *** search
- {$C-}
- {
- G E T F I L E . P A S
- written by Neil J. Rubenking
-
-
- This program demonstrates the use of FIND_FIRST and FIND_NEXT, contained
- in GETFILE.LIB. You can enter a "template" (e.g., "*.COM", "BASIC*.*",
- "FILE????.CHK") and a set of file attributes, and get back a list of
- all the files matching the template and the attributes.
-
- "Ordinary" files will be found along with those with special attributes.
- If you specify [E]xclusive, only those files with EXACTLY the attributes
- you selected will be shown. Thus, if your DOS disk is in drive A, you
- might ask for "a:*.*" with attributes "RHS" and [E]xclusive, and you
- would get the IBMBIOS.COM and IBMDOS.COM.
-
- }
- PROGRAM get_file;
- TYPE
- filename_type = STRING[64];
- regpack = RECORD
- ax, bx, cx, dx, bp, si, di, ds, es, flags : Integer;
- END;
-
- {!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!
- separate the following code out into G E T F I L E . L I B
- !?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!}
- {
- GETFILE consists of a set of three procedures based on a variable-type
- BUFFER-TYPE, which is the exact "shape" of the information returned by
- DOS function calls $4E (Find First matching file) and $4F (Find Next).
-
- SetDTA is called by Find_First to Set the Data Transfer Area to the Buffer.
-
- Find_First takes as input the file attribute and name-template of the file
- required and returns the actual attribute found, the first matching name,
- and an error code.
-
- Find_Next takes no input, but the buffer must be initialized by Find_First.
- The output of Find_Next is the same as that of Find_First.
-
- Any program that calls GETFILE must also include the standard type definitions
- for "filename_type" and "regPack".
-
- }
-
-
- TYPE
- buffer_type = RECORD
- reserved : ARRAY[1..21] OF Byte;
- attribute : Byte;
- time, date, FileSizeLo, FileSizeHi : Integer;
- name : STRING[13];
- END;
- VAR
- filename : filename_type;
- buffer : buffer_type;
- attribute : Byte;
-
-
- PROCEDURE SetDTA(VAR buff);
- VAR
- registers : regpack;
- BEGIN
- WITH registers DO
- BEGIN
- AX := $1A SHL 8;
- DS := Seg(buff);
- DX := Ofs(buff);
- MsDos(registers);
- END;
- END;
-
-
- PROCEDURE Find_Next(VAR att : Byte; VAR filename : filename_type;
- VAR Next_error : Byte);
- VAR
- registers : regpack;
- carry_flag : Integer;
- N : Byte;
- BEGIN
- FillChar(buffer.name, SizeOf(buffer.name), 0);
- WITH registers DO
- BEGIN
- AX := $4F SHL 8;
- MsDos(registers);
- att := buffer.attribute;
- carry_flag := 1 AND Flags;
- filename := ' ';
- IF carry_flag = 1 THEN
- Next_error := AX AND $00FF
- ELSE
- BEGIN
- Next_error := 0;
- FOR N := 0 TO 12 DO FileName[N+1] := buffer.name[N];
- END;
- END; {with}
- att := buffer.attribute;
- END;
-
-
- PROCEDURE Find_First(VAR att : Byte;
- VAR filename : filename_type;
- VAR error_code : Byte);
-
- VAR
- registers : regpack;
- carry_flag : Integer;
- mask, N : Byte;
-
- BEGIN
- SetDTA(buffer);
- filename[Length(filename)+1] := Chr(0);
- FillChar(buffer.name, SizeOf(buffer.name), 0);
- WITH registers DO
- BEGIN
- AX := $4E SHL 8;
- CX := att;
- DS := Seg(filename);
- DX := Ofs(filename)+1;
- MsDos(registers);
- att := buffer.attribute;
- { If there was an error set the error code and don't do
- anything else. }
-
- carry_flag := 1 AND Flags;
- IF carry_flag = 1 THEN
- BEGIN
- error_code := AX AND $00FF;
- END
- ELSE
- BEGIN
- error_code := 0;
- filename := ' ';
- FOR N := 0 TO 12 DO FileName[N+1] := buffer.name[N];
- END;
- END; {with}
- END;
- {!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!
- end of G E T F I L E . L I B
- !?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!!?!?!?!?!?!}
-
- TYPE
- AttString = STRING[6];
- CharSet = SET OF Char;
- CONST
- AttChars : charset = ['R', 'H', 'S', 'V', 'D', 'A', 'Q'];
- VAR
- att, choice, dummy : Char;
- row, N : Byte;
- atts : AttString;
- okay : Boolean;
- error,
- attribyte,
- OldAttribute : Byte;
- chars : set of char;
-
- FUNCTION convert(attribute : Byte) : AttString;
- VAR
- temp : attString;
- BEGIN
- temp := ' ';
- IF attribute AND 1 = 1 THEN temp[1] := 'R';
- IF attribute AND 2 = 2 THEN temp[2] := 'H';
- IF attribute AND 4 = 4 THEN temp[3] := 'S';
- IF attribute AND 8 = 8 THEN temp[4] := 'V';
- IF attribute AND 16 = 16 THEN temp[5] := 'D';
- IF attribute AND 32 = 32 THEN temp[6] := 'A';
- convert := temp;
- END;
-
-
- FUNCTION UnConvert(atts : attString) : Byte;
- VAR
- temp : Byte;
- BEGIN
- temp := 0;
- IF Pos('R', atts) <> 0 THEN temp := temp+1;
- IF Pos('H', atts) <> 0 THEN temp := temp+2;
- IF Pos('S', atts) <> 0 THEN temp := temp+4;
- IF Pos('V', atts) <> 0 THEN temp := temp+8;
- IF Pos('D', atts) <> 0 THEN temp := temp+16;
- IF Pos('A', atts) <> 0 THEN temp := temp+32;
- UnConvert := temp;
- END;
-
-
-
- BEGIN { main program }
- ClrScr;
- FOR row := 1 TO 24 DO
- BEGIN
- GoToXY(40, row);
- Write(#186);
- END;
- REPEAT
- Window(1, 1, 39, 25);
- ClrScr;
- WriteLn('Enter the template for files sought.');
- WriteLn('It can contain "wildcard" characters');
- WriteLn('"*" and "?".');
- ReadLn(filename);
- WriteLn('Enter the attribute(s) to seek:');
- WriteLn('[R]ead-only, [H]idden, [S]ystem, ');
- WriteLn('[V]olume-label, [D]irectory, [A]rchive');
- WriteLn('or [Q]uit.');
- okay := true;
- FillChar(chars,SizeOf(chars),0);
- chars := ['R','H','S','V','D','A','Q',#13];
- atts := '';
- repeat
- repeat until keypressed;
- read(Kbd,Choice);
- choice := UpCase(choice);
- IF choice in chars THEN
- BEGIN
- IF choice = 'Q' THEN okay := false
- ELSE
- BEGIN
- IF choice <> #13 THEN
- BEGIN
- write(choice);
- atts := atts + choice;
- chars := chars - [choice];
- END;
- END;
- END;
- until (choice = #13) or (not okay) or (chars = ['Q',#13]);
- attribyte := unConvert(atts);
- writeln; writeLn('attribute byte is ',attribyte);
- IF Okay THEN
- BEGIN
- WriteLn; WriteLn;
- WriteLn('[E]xclusive or [I]nclusive?');
- WriteLn('(i.e., show ONLY files with');
- WriteLn('exactly the specified attributes');
- WriteLn('or all "normal" files plus those');
- WriteLn('with the specified attributes).');
- WriteLn(' NOTE: specify [E] if you just');
- WriteLn(' want the [V]olume label.');
- REPEAT
- REPEAT UNTIL KeyPressed;
- Read(Kbd,choice);
- choice := UpCase(choice);
- UNTIL choice IN ['E', 'I'];
- WriteLn(choice);
- Window(41, 1, 80, 25);
- ClrScr;
- OldAttribute := attribyte;
-
- { Step one--Find the First file matching our criteria.}
-
- Find_First(attribyte, filename, error);
- IF error = 0 THEN
- BEGIN
-
- { If we asked for [E]xclusive choices, we want to
- screen out any files that do not have exactly the
- same attributes as our request. However, we don't
- care whether or not the ARCHIVE bit is set. Thus
- the condition "if attribyte MOD 32 = OldAttribute}
- IF choice = 'E' THEN
- BEGIN
-
- IF attribyte MOD 32 = OldAttribute THEN
- WriteLn(filename, ' ', convert(attribyte));
- END
- ELSE WriteLn(filename, ' ', convert(attribyte));
-
- {Now we repeat Find_Next until it DOESN't Find a Next--
- that is, until error <> 0 }
-
- REPEAT
- Find_Next(attribyte, filename, error);
- IF error = 0 THEN
- BEGIN
- IF choice = 'E' THEN
- BEGIN
- IF attribyte MOD 32 = OldAttribute THEN
- WriteLn(filename, ' ', convert(attribyte));
- END
- ELSE WriteLn(filename, ' ', convert(attribyte));
- IF WhereY >= 24 THEN {-----------------}
- BEGIN { Stop when screen}
- WriteLn('Press a key...'); { gets full. }
- REPEAT UNTIL KeyPressed; {-----------------}
- read(Kbd,dummy);
- ClrScr;
- END;
- END;
- UNTIL error <> 0;
- WriteLn('Press a key . . .');
- REPEAT UNTIL KeyPressed;
- read(Kbd,dummy);
- ClrScr;
- END;
- END;
- UNTIL attribyte = 0;
- Window(1, 1, 80, 25);
- ClrScr;
- END.
-