DOS and the PSP structure with its environment block === The PSP structure === The PSP (with offsets in hexadecimal) is formatted as follows: (* = undocumented) PROGRAM SEGMENT PREFIX offset size C O N T E N T S 0000h 2 bytes int 20h 0002h 2 bytes segment address, end of allocation block 0004h 1 byte reserved, normally 0 0005h 5 bytes FAR call to MSDOS function dispatcher (int 21h) 000Ah 4 bytes previous termination handler interrupt vector (int 22h) 000Eh 4 bytes previous contents of ctrl-C interrupt vector (int 23h) 0012h 4 bytes prev. critical error handler interrupt vector (int 24h) 0016h 22 bytes reserved for DOS * 2 bytes (16) parent process' PSP * 20 bytes (18) "handle table" used for redirection of files 002Ch 2 bytes segment address of the program's environment block 002Eh 34 bytes reserved, DOS work area * 4 bytes (2E) stores the calling process's stack pointer when switching to DOS's internal stack. * (32) DOS 3.x max open files * 2 bytes (3A) size of handle table |these functions are in here * 4 bytes (3C) handle table address |but reported addresses vary 0050h 3 bytes int 21h, RETF instruction 0053h 2 bytes reserved - unused? 0055h 7 bytes reserved, or FCB#1 extension 005Ch 16 bytes default unopened File Control Block #1 006Ch 16 bytes default unopened FCB #2 (overlaid if FCB #1 opened) 0080h 1 byte parameter length (number of chars entered after filename) 0081h ... parameters 00FFh 128 bytes command tail and default Disk Transfer Area (DTA) 1. The first segment of available memory is in segment (paragraph) form. For example, 1000h would respresent 64k. 2. Offset 2Ch contains the segment address of the environment. 3. Programs must not alter any part of the PSP below offset 5Ch. PSP (comments): offset 00h contains hex bytes CD 20, the int 20h opcode. A program can end by making a jump to this location when the CS points to the PSP. For normal cases, int 21, function 4Ch should be used. offset 02h contains the segment-paragraph address of the end of memory as reported by DOS. (which may not be the same as the real end of RAM). Multiply this number by 10h or 16 to get the amount of memory availible. ex. 1000h would be 64k. offset 04h "reserved or used by DOS" according to Microsoft offset 05h contains a long call to the DOS function dispatcher. Programs may jump to this address instead of calling int 21 if they wish. Used by Basic and other CPM object-code translated programs. It is slower than standard int 21h. offset 0Ah, 0Eh, 12h vectors (IP, CS) offset 16h PSP:16h is the segment address of the invoking program's PSP, which * will most often be COMMAND.COM but perhaps may be a secondary non-permanent COMMAND or a multitasking shell, etc. At any rate, the resident shell version of COMMAND.COM has PSP:16H = PSP, which indicates "don't look any lower in memory" for the command interpreter. To find the beginning of the allocation chain, look backwards through the PSP link addresses until the link address is equal to the PSP segment address that it resides in. This should be COMMAND.COM. To find COMMAND.COM's environment, look at the word stored at offset 0BD3h (PC-DOS 3.1 only). This is a segment address, so look there at offset 0. offset 18h handle alias table (networking). Also you can make PRN go to CON, * CON go to PRN, ERR go to PRN, etc. 0FFh = availible. offset 2Ch is the segment:offset address of the environment for the program using this particular PSP. This pointer does not point to COMMAND.COM's environment unless it is a second copy of COMMAND. offset 2Eh the DWORD at PSP+2Eh is used by DOS to store the calling process's * stack pointer when switching to DOS's own private stack - at the end of a DOS function call, SS:SP is restored from this address. 32h, 34h * table of number of file handles (to 64k of handles!) offset 40h 2 byte field points to the segment address of COMMAND.COM's PSP in * "weird" EXE files produced by Digital Research RASMPC/LINKPC. EXE files created with these tools can cause all sorts of problems with standard MSDOS debugging tools. offset 50h contains a long call to the DOS int 21 function dispatcher. offset 5Ch, 65h, 6Ch contain FCB information for use with FCB function calls. The first FCB may overlay the second if it is an extended call; your program should revector these areas to a safe place if you intend to use them. offset 5Ch 16 bytes first command-line argument (formatted as uppercase 11 character filename) offset 6Ch 16 bytes second command-line argument (formatted as uppercase 11 character filename) offset 7Ch-7Fh "reserved or used by DOS" offset 80h 1 byte number of bytes in command line argument offset 80h, 81h contain the length and value of parameters passed on the command line. offset 81h 97 bytes unformatted command line and/or default DTA offset 0FFh contains the DTA The PSP is created by DOS for all programs and contains most of the information you need to know about a program running. You can change the environment for the current process, however, but for the parent process, DOS in this case, you need to literally backtrack to DOS or COMMAND.COM's PSP. In order to get there you must look at the current PSP. At offset 16h of the current PSP segment, there a 2 byte segment address to the parent or previous process PSP. From there you can manipulate the enviroment by looking at offset 2Ch. As you know, at offset 2Ch, there is 2 byte segment address to the environment block. === The Environment Block === The environment is a series of ASCII strings totalling less than 32k bytes in the form: NAME=value The default environment is 160 bytes. Each string is a maximum of 127 bytes terminated by a byte of zeroes for a total of 128 bytes, and the entire set of strings is terminated by another byte of zeroes. Following the byte of zeroes that terminates the set of environment string is a set of initial arguments passed to a program that contains a word count followed by an ASCIIZ string. The ASCIIZ string contains the drive, path, and filename.ext of the executable program. Programs may use this area to determine where the program was loaded from. The environment built by the command processor (and passed to all programs it invokes) contains a COMSPEC=string at a minimum (the parameter on COMSPEC is the path used by DOS to locate COMMAND.COM on disk). The last PATH and PROMPT commands issued will also be in the environment, along with any environment strings entered through the SET command. The environment that you are passed is actually a copy of the invoking process's environment. If your application terminates and stays resident through int 27h, you should be aware that the copy of the environment passed to you is static. That is, it will not change even if subsequent PATH, PROMPT, or SET commands are issued. The size of the environment may be changed from its default of 160 bytes by using the SHELL= command in the config.sys from in DOS version 3.1 up, or COMMAND.COM may be patched in earlier versions. The environment can be used to transfer information between processes or to store strings for later use by application programs. The environment is always located on a paragraph boundary. This is its format: byte ASCIIZ string 1 byte ASCIIZ string 2 .... byte ASCIIZ string n byte of zeros (0) Typically the environment strings have the form: NAME = VALUE The length of NAME or VALUE can be anything desired as long as it still fits into the 123 byte space (4 bytes are used by "SET "). Following the byte of zeros in the environment, a WORD indicates the number of other strings following. If the environment is part of an EXECed command interpreter, it is followed by a copy of the DS:DX filename passed to the child process. A zero value causes the newly created process to inherit the parent's environment.