Contributor: STEPHEN M. OBERHOLTZER
(*> Hi, I am trying to write a program the writes to Standard output,> and reads from Standard input from windows console (win95 dosprmpt, winnt> dosprmpt)... so the io can be redirected. The program must be a windows> program for the project to work:> Using the program as a script for Microsoft Internet> Information Server on Winnt 3.51, the web server will not execute dos based stdio> programs. I have tried using program script(input,output) which reports file not> open for write, I have added rewrite(output) which causes an error because output
not assigned. I have assigned output to '' which outputs nothing to the
console or the redirected file.>> If anyone understands my problem, and has an idea or> solution,> please help me. Thank you.>>
Ok, here is the solution to your prob : you need to write a text file device
driver. I just happen to have code. You want the StdOut things, i can't
remember how it works =(
p.s. the file's attached.
(*)
unit SimultIO;
{$D-,F+,R-}
(* Unit for simultaneous I/O.
 This will be useful for redirection - when you write to a
 file assigned to by AssignSimult, data written to it will write to
 the file AND the screen. *)
interface
{$F+} procedure AssignSimult(var f : text;n : string); far; {$F-}
implementation
uses Dos,CRT;
var R : Registers;
 OP : Text;
{$F+} function WriteByteToFile(FileHandle : Word;var value) : integer;far; {$F-}
var r : registers;
begin
 r.ah := 40ドル;
 r.bx := FileHandle;
 r.cx := 1;
 r.ds := seg(value);
 r.dx := ofs(value);
 MsDos(R);
 if (r.flags and fcarry)0 then
 begin
 r.ah := 59ドル; (* Get extended error info *)
 msdos(R);
 WriteByteToFile := r.ax; (* IOResult returns the value in InOutRes *)
 end
 else WriteByteToFile := 0;
end;
(*
 INT 21,40 - Write To File or Device Using Handle
 AH = 40h
 BX = file handle
 CX = number of bytes to write, a zero value truncates/extends
 the file to the current file position
 DS:DX = pointer to write buffer
 on return:
 AX = number of bytes written if CF not set
 = error code if CF set (see DOS ERROR CODES)
 - if AX is not equal to CX on return, a partial write occurred
 - this function can be used to truncate a file to the current
 file position by writing zero bytes *)
{$F+} function StdOut(var f: textrec) : integer; far; {$F-}
var
 p,err : integer;
 r : registers;
begin
 if f.mode=fmclosed then
 begin
 StdOut := 103;
 exit;
 end;
 with F do
 begin
 for P := 0 to bufpos-1 do
 begin
 r.ah := 02ドル;
 r.dl := ord(bufptr^[p]);
 msdos(R);
 end;
 BufPos:=0;
 end;
 StdOut:=0;
end;
{$F+} function SimultWrite(var f: textrec): integer; far; {$F-}
var
 p,err : integer;
begin
 if f.mode=fmclosed then
 begin
 SimultWrite := 103;
 exit;
 end;
 with F do
 begin
 for P := 0 to bufpos-1 do
 begin
 err := WriteByteToFile(Handle,BufPtr^[p]);
 if err0 then
 begin
 SimultWrite := Err;
 BufPos := P+1;
 exit;
 end;
 Write(OP,BufPtr^[p]);
 end;
 BufPos:=0;
 end;
 SimultWrite:=0;
end;
{$F+} function SimultOpen(var f: textrec): integer; far; {$F-}
var
 P: integer;
begin;
 case F.Mode of
 FMOutput : begin (* Rewrite *)
 if f.name[0]= #0 then
 begin
 F.InOutFunc:= @StdOut;
 F.FlushFunc:= @StdOut;
 end else begin
 r.ah := 3ドルC;
 r.cx := 0000ドル;
 r.ds := Seg(F.Name);
 r.dx := Ofs(F.Name);
 MsDos(R);
 if (R.flags and FCarry)0 then
 begin
 R.AH := 59ドル;
 MsDos(R);
 SimultOpen := R.AX;
 exit;
 end;
 F.Handle := r.ax;
 (*
 INT 21,3C - Create File Using Handle
 AH = 3C
 CX = file attribute (see FILE ATTRIBUTES)
 DS:DX = pointer to ASCIIZ path name
 on return:
 CF = 0 if successful
 = 1 if error
 AX = files handle if successful
 = error code if failure (see DOS ERROR CODES)
 - if file already exists, it is truncated to zero bytes on opening
*)
 F.InOutFunc:= @SimultWrite;
 F.FlushFunc:= @SimultWrite;
 end;
 F.BufPos:= 0;
 SimultOpen:= 0;
 end;
 FMInOut : begin (* Append *)
 f.mode := fmOutput;
 r.ah := 3ドルd ;
 r.al := 01ドル;
 r.cx := 0000ドル;
 r.ds := Seg(F.Name);
 r.dx := Ofs(F.Name);
 MsDos(R);
 if (R.flags and FCarry)0 then
 begin
 R.AH := 59ドル;
 MsDos(R);
 SimultOpen := R.ax;
 exit;
 end;
 F.Handle := r.ax;
 r.bx := r.ax;
 r.al := 02ドル;
 R.ah := 42ドル;
 r.cx := 0000ドル;
 r.dx := 0001ドル; (* Seek past EOF *)
 MsDos(R);
 if (r.flags and fcarry)0 then
 begin
 r.ah := 59ドル;
 msdos(R);
 SimultOpen := R.AX;
 exit;
 end;
 (*
 INT 21,42 - Move File Pointer Using Handle
 AH = 42h
 AL = origin of move:
 00 = beginning of file plus offset (SEEK_SET)
 01 = current location plus offset (SEEK_CUR)
 02 = end of file plus offset (SEEK_END)
 BX = file handle
 CX = high order word of number of bytes to move
 DX = low order word of number of bytes to move
 on return:
 AX = error code if CF set (see DOS ERROR CODES)
 DX:AX = new pointer location if CF not set
 - seeks to specified location in file
 INT 21, - Open File Using Handle
 AH =
 AL = open access mode
 00 read only
 01 write only
 02 read/write
 DS:DX = pointer to an ASCIIZ file name
 =
 on return:
 AX = file handle if CF not set
 = error code if CF set (see DOS ERROR CODES)
 Access modes in AL:
 =B37=B36=B35=B34=B33=B32=B31=B30=B3 AL
 =B3 =B3 =B3 =B3 =B3 =C0=C4=C1=C4=C1=C4=C4=C4=C4 read/write/updat=
e access mode
 =B3 =B3 =B3 =B3 =C0=C4=C4=C4=C4=C4=C4=C4=C4=C4 reserved, always =
0
 =B3 =C0=C4=C1=C4=C1=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4 sharing mode (=
see below) (DOS 3.1+)
 =C0=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4=C4 1 = private, =
0 = inheritable (DOS 3.1+)
=0D
 Sharing mode bits (DOS 3.1+): Access mode bits:
 654 210
 000 compatibility mode (exclusive) 000 read access
 001 deny others read/write access 001 write access
 010 deny others write access 010 read/write access
 011 deny others read access
 100 full access permitted to all
*)
 F.InOutFunc := @SimultWrite;
 F.FlushFunc := @SimultWrite;
 F.BufPos:= 0;
 SimultOpen:= 0;
 end;
 else
 SimultOpen := 12; (* Invalid file access code - you can only Rewrite=
 or Append this *)
 end;
end;
{$F+}function SimultClose(var F: textrec): integer; far; {$F-}
var
 P: integer;
begin;
 if f.mode= fmclosed then
 begin
 SimultClose := 103;
 exit;
 end;
(*
 INT 21,3E - Close File Using Handle
 AH = 3E
 BX = file handle to close
 on return:
 AX = error code if CF set (see DOS ERROR CODES)
 - if file is opened for update, file time and date stamp
 as well as file size are updated in the directory
 - handle is freed
=0D
 *)
 r.ah := 3ドルE;
 r.bx := f.handle;
 MsDos(R);
 if (R.flags and fcarry)0 then
 begin
 r.ah := 59ドル;
 MsDos(R);
 SimultClose := R.AX;
 exit;
 end;
 F.Mode := FMClosed;
 SimultClose:= 0;
end;
{$F+} procedure AssignSimult(var f : text;n : string); {$F-}
begin
 with textrec(f) do begin
 Mode := fmClosed;
 Handle := $FFFF;
 Bufsize := SizeOf(Buffer);
 Bufpos := 0;
 Bufptr := @Buffer;
 OpenFunc := @SimultOpen;
 CloseFunc:= @SimultClose;
 if n[0]>#79 then n[0] := #79; (* Truncate the name down to 79 chars=
 *)
 Move(N[1],Name[0],79);
 Name[Length(N)] := #0; (* Name is null-terminated *)
 end;
end;
begin
 AssignCRT(OP);
 Rewrite(OP);
end.


AltStyle によって変換されたページ (->オリジナル) /