Enumerate/list the open files in DOS 7.x
The following code will allow you to list the files that are currently opened.
Use service 440Dh/6Dh of DOS 7.x. Remember that this service asks for the index in the
total list of open files. So this codes starts with zero in SI and goes until and error
is returned.
; ENUM
; Enumerates all open files in DOS 7.x
; Assembled with NBASM
.model tiny
.code
org 100h
xor si,si ; start with number 1 (si = index - 1)
More: mov ax,440Dh ; generic IOCTR / drive function 0Dh
mov cx,086Dh ; enumerate open files
xor bl,bl ; current drive
mov dx,offset Buffer ; Buffer
xor di,di ; all files
int 21h ; do it
jc short Done ; carry set if error (no more)
push si ; print the file returned
mov si,offset CRLF ; starting with a CRLF
call prtstring ;
mov bx,offset FTypeO ; get file type (CX on return from above)
shl cx,1 ; index it
add bx,cx ; add to bx
mov si,[bx] ; and get it into si
call prtstring ; print it
pop si ; restore index number
inc si ; inc to next index number
jmp short More ; do it again
Done: .exit ; exit to DOS
Prtstring proc near uses ax dx si
mov ah,02 ; DOS print char service
Ps1: lodsb ; Get character & point to next one
or al,al ; End of string?
jz short ps2 ; Yes, so exit
mov dl,al ;
int 21h ; Output a character
jmp short Ps1 ; Keep doing it
Ps2: ret
Prtstring endp
FTypeO dw offset Type1
dw offset Type2
dw offset Type3
dw offset Type4 ; filler
dw offset Type5
Type1 db ' [normal file]',0
Type2 db ' [memory-mapped file (unmovable)]',0
Type3 db ' [unmovable file]',0
Type4 db ' [*filler*]',0 ; shouldn't get this one
Type5 db ' [swap file]',0
CRLF db 13,10,0 ; CRLF
Buffer dup 128,? ; a 128 byte buffer
.end
Values for file type:
0000h normal file
0001h memory-mapped file (unmovable)
0002h unmovable file
0004h swap file
Mode returned in AL:
bit 7 inheritance
bits 4-6 sharing mode
bit 3 reserved
bits 0-2 access mode
100 read-only, do not modify file's last-access time (DOS 7.0)
A note: If you are in a Windows DOS session, Windoze might open and close a file while you are displaying them with the above code. With this in mind, you might get the same file returned twice, or you might "skip" a file. If you want, you could add the CLI/STI instructions to help keep this to a minimal. However, prolonged usage without interrupts can cause hangs, errors, and even serious damage.
Maybe you could get all the file names and store them in a buffer, then print the buffer. This would make the actual "getting" time smaller with less chance of errors.
How about a C version:
#include <dos.h>
union REGS inregs, outregs;
struct SREGS segregs;
unsigned int FileIndex = 0;
char FileName[128];
unsigned char FileType, FileMode;
int main(int argc, char *argv[]) {
void far *mptr = FileName;
do {
inregs.x.ax = 0x440D;
inregs.x.dx = FP_OFF(mptr);
segregs.ds = FP_SEG(mptr);
inregs.x.bx = 0x00;
inregs.x.cx = 0x086D;
inregs.x.si = FileIndex++;
inregs.x.di = 0x00;
intdosx(&inregs, &outregs, &segregs);
if (!outregs.x.cflag) {
FileType = outregs.x.cx;
FileMode = outregs.x.ax;
printf("\n File: %s",FileName);
}
} while (!outregs.x.cflag);
}