🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

5 total messages Started by Mike Morearty Mon, 06 Oct 1986 10:18
You can get argv[0] in DOS 3.x
#8167
Author: Mike Morearty
Date: Mon, 06 Oct 1986 10:18
111 lines
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
Re: You can get argv[0] in DOS 3.x
#8175
Author: Scott Hazen Mueller
Date: Mon, 06 Oct 1986 18:22
26 lines
1669 bytes
In article <> morearty@cory.Berkeley.EDU (Mike Morearty) writes:
<I just discovered an undocumented feature of the more recent
<versions of DOS: it is at last possible to obtain argv[0].
<...environment...complete path and filename of the program
<
<     NAME=value#0        ;one or more null-terminated strings
<     #0                  ;the terminating null byte
<     #1                  ;followed by a byte with value one

I'm not absolutely certain, but I believe that this can have values other than
one.  I think that it is actually argc.

<     #0                  ;followed by another null byte
<     C:\PAS\ENV.COM#0    ;argv[0], null-terminated

The entire command line _might_ be copied here.  Again, I don't remember
exactly.

<                                   -- Mike Morearty
                  \scott

-- 
Scott Hazen Mueller                         lll-crg.arpa!csustan!smdev
City of Turlock                             work:  (209) 668-5590 -or- 5628
901 South Walnut Avenue                     home:  (209) 527-1203
Turlock, CA 95380                           <Insert pithy saying here...>
Re: You can get argv[0] in DOS 3.x
#8186
Author: John R. Levine
Date: Tue, 07 Oct 1986 15:01
13 lines
1287 bytes
In article <468@zen.BERKELEY.EDU> morearty@cory.Berkeley.EDU (Mike Morearty) writes:
>I just discovered an undocumented feature of the more recent
>versions of DOS: it is at last possible to obtain argv[0].
>...

You can indeed get the name under which the program was invoked, but you could
have saved yourself a lot of effort by reading the DOS 3.x technical reference,
in the section on the EXEC call, in which the feature is documented.
-- 
John R. Levine, Javelin Software Corp., Cambridge MA +1 617 494 1400
{ ihnp4 | decvax | cbosgd | harvard | yale }!ima!johnl, Levine@YALE.EDU
The opinions expressed herein are solely those of a 12-year-old hacker
who has broken into my account and not those of any person or organization.
Re: You can get argv[0] in DOS 3.x
#8249
Author: hamilton
Date: Thu, 09 Oct 1986 04:44
13 lines
1106 bytes
morearty@cory.Berkeley.EDU sez:
>I just discovered an undocumented feature of the more recent
>versions of DOS: it is at last possible to obtain argv[0].

ummm, this WAS documented, in my dos 3.0 technical reference manual.

	wayne hamilton
	U of Il and US Army Corps of Engineers CERL
UUCP:	{ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!hamilton
ARPA:	hamilton%uiucuxc@a.cs.uiuc.edu	USMail:	Box 476, Urbana, IL 61801
CSNET:	hamilton%uiucuxc@uiuc.csnet	Phone:	(217)333-8703
CIS:    [73047,544]			PLink: w hamilton
Re: You can get argv[0] in DOS 3.x
#8272
Author: hamilton
Date: Tue, 14 Oct 1986 01:14
13 lines
1231 bytes
morearty@cory.Berkeley.EDU sez:
>I just discovered an undocumented feature of the more recent
>versions of DOS: it is at last possible to obtain argv[0].

ummm, this WAS documented, in my dos 3.0 technical reference manual.

	wayne hamilton
	U of Il and US Army Corps of Engineers CERL
UUCP:	{ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!hamilton
ARPA:	hamilton%uiucuxc@a.cs.uiuc.edu	USMail:	Box 476, Urbana, IL 61801
CSNET:	hamilton%uiucuxc@uiuc.csnet	Phone:	(217)333-8703
CIS:    [73047,544]			PLink: w hamilton
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads