Article View: net.micro.pc
Article #8167You can get argv[0] in DOS 3.x
From: Mike Morearty
Date: Mon, 06 Oct 1986 10:18
Date: Mon, 06 Oct 1986 10:18
111 lines
5061 bytes
5061 bytes
I just discovered an undocumented feature of the more recent
versions of DOS: it is at last possible to obtain argv[0].
I discovered this because I was surprised to read in the DOS 3.2
manual that XCOPY.EXE behaves differently if you rename it as
MCOPY.EXE. So I disassembled it, and found the following method
to determine the name of the program that is being run.
As you probably know, in all versions of DOS from 2.0 on, there
is an environment area in memory with strings that can be created
with the SET command, such as "set PATH=\". The segment of this
environment area is stored as a word at offset 2Ch into the
Program Segment Prefix. If, for example, the word at address 2Ch
is 1000, then the environment area begins at offset 1000:0000.
This environment area consists of null-terminated strings of the
form "NAME=value" (with NAME all upper case), followed by a null
byte. If the next byte is also a null, then that marks the end
of the environment area. (Thus, if the very first byte in the
environment area is a null, there are no strings present.)
Now, the good stuff: in DOS 3.1 and 3.2, and possibly in 3.0 (I
haven't been able to test it), this environment area is followed
by the complete path and filename of the program that has been
invoked. Here is the exact format (#x indicates a byte with
value x):
NAME=value#0 ;one or more null-terminated strings
#0 ;the terminating null byte
#1 ;followed by a byte with value one
#0 ;followed by another null byte
C:\PAS\ENV.COM#0 ;argv[0], null-terminated
Note the following changes from older versions of DOS:
1. There are always TWO null bytes at the end of the
environment area. In older versions, there may have been
only one null byte if there were no environment strings
present.
2. The environment area is immediately followed by a 1 and then
a 0. If this is not present, assume that argv[0] is not
present either.
Note that the drive specifier and/or certain subdirectory names
in the path may be lower case, and there may be "." and/or ".."
entries in the path, depending on the line that the user typed to
invoke the program. Some examples follow, assuming that the user
is in the directory C:\DIR, and there is a program in that
directory called PROGRAM.COM:
User typed argv[0] contains
---------- ----------------
program C:\DIR\PROGRAM.COM
PROGRAM C:\DIR\PROGRAM.COM
.\program C:\DIR\.\PROGRAM.COM
\dir\program C:\dir\PROGRAM.COM
c:program c:\DIR\PROGRAM.COM
program.exe C:\DIR\PROGRAM.COM
Here is a sample program written in Turbo Pascal (version 3.x),
to display argv[0].
=================================================================
{
Argv0.pas - Display argv[0], in other words, the path and filename
that invoked this program. Works under DOS 3.1 and 3.2,
and possibly 3.0.
}
program Argv0;
var
env: integer absolute cseg:$2C; (* segment of environment *)
cp: integer; (* pointer into environment segment *)
r: record (* record of registers *)
ax,bx,cx,dx,bp,si,di,ds,es,flags: integer;
end;
begin
r.ax := $3000;
MsDos(r); (* get DOS version number *)
if (lo(r.ax) <> 3) or (hi(r.ax) > $20) then begin
writeln('Needs DOS 3.0, 3.1, or 3.2');
halt;
end;
cp := 0; (* point to beginning of segment *)
(* find the end of the environment space, e.g., where two nulls are
found in a row. *)
while (memw[env:cp] <> 0) do begin
cp := cp + 1;
end;
cp := cp + 2; (* move past the two nulls *)
(* If this version of DOS has argv[0], then the two nulls are
immediately followed by an ASCII 1 and then another null. *)
if (memw[env:cp] <> 1) then begin
writeln('Invalid memory format');
end else begin
cp := cp + 2; (* move past the 1 and the 0 *)
while mem[env:cp] <> 0 do begin (* argv[0] is null-terminated *)
write(chr(mem[env:cp]));
cp := cp+1;
end;
end;
end.
-- Mike Morearty
Technical Details
Message-ID:
<468@zen.BERKELEY.EDU>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!seismo!lll-crg!nike!ucbcad!zen!cory.Berkeley.EDU!moreartyShow Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!lll-crg!nike!ucbcad!zen!cory.Berkeley.EDU!morearty From: morearty@cory.Berkeley.EDU (Mike Morearty) Newsgroups: net.micro.pc Subject: You can get argv[0] in DOS 3.x Message-ID: <468@zen.BERKELEY.EDU> Date: Mon, 6-Oct-86 06:18:52 EDT Article-I.D.: zen.468 Posted: Mon Oct 6 06:18:52 1986 Date-Received: Tue, 7-Oct-86 21:00:29 EDT Sender: news@zen.BERKELEY.EDU Reply-To: morearty@cory.Berkeley.EDU (Mike Morearty) Organization: University of California, Berkeley Lines: 111