/svarcom/trunk/cmd/dir.c |
---|
85,6 → 85,10 |
outputnl("/A NOT IMPLEMENTED YET"); |
return(-1); |
break; |
case 'b': |
case 'B': |
flags |= DIR_FLAG_BARE; |
break; |
case 'p': |
case 'P': |
flags |= DIR_FLAG_PAUSE; |
105,8 → 109,29 |
if (filespecptr == NULL) filespecptr = "."; |
file_truename(filespecptr, p->BUFFER); |
{ |
unsigned short r = file_truename(filespecptr, p->BUFFER); |
if (r != 0) { |
outputnl(doserr(r)); |
return(-1); |
} |
} |
if ((flags & DIR_FLAG_BARE) == 0) { |
unsigned char drv = p->BUFFER[0]; |
if (drv >= 'a') { |
drv -= 'a'; |
} else { |
drv -= 'A'; |
} |
cmd_vol_internal(drv, p->BUFFER + 1024); |
sprintf(p->BUFFER + 1024, "Directory of %s", p->BUFFER); |
/* trim at first '?', if any */ |
for (i = 0; p->BUFFER[i + 1024] != 0; i++) if (p->BUFFER[i + 1024] == '?') p->BUFFER[i + 1024] = 0; |
outputnl(p->BUFFER + 1024); |
outputnl(""); |
} |
/* if dir then append \????????.??? */ |
i = file_getattr(p->BUFFER); |
if ((i > 0) && (i & DOS_ATTR_DIR)) strcat(p->BUFFER, "\\????????.???"); |
/svarcom/trunk/cmd/vol.c |
---|
0,0 → 1,126 |
/* |
* vol [drive:] |
*/ |
static void cmd_vol_internal(unsigned char drv, char *buff) { |
unsigned short *buff16 = (void *)(buff); |
unsigned short err = 0; |
struct DTA *dta = (void *)0x80; /* use the default DTA at location 80h in PSP */ |
outputnl(""); /* start with an empty line to mimic MS-DOS */ |
/* look for volume label in root dir via a FindFirst call */ |
sprintf(buff, "%c:\\????????.???", drv + 'A'); |
_asm { |
push ax |
push cx |
push dx |
mov [err], 0 /* preset errflag to zero */ |
mov ah, 0x4e /* FindFirst */ |
mov dx, buff |
mov cx, 0x08 /* match volume labels only */ |
int 0x21 /* dta filled or CF set on error */ |
jnc DONE |
mov [err], ax |
DONE: |
pop dx |
pop cx |
pop ax |
} |
if (err != 0) { |
sprintf(buff, "Volume in drive %c has no label", drv + 'A'); |
} else { |
/* if label > 8 chars then drop the dot (DRIVE_LA.BEL -> DRIVE_LABEL) */ |
if (strlen(dta->fname) > 8) memmove(dta->fname + 8, dta->fname + 9, 4); |
sprintf(buff, "Volume in drive %c is %s", drv + 'A', dta->fname); |
} |
outputnl(buff); |
/* try to fetch the disk's serial number (DOS 4+ internal call) */ |
err = 0; |
_asm { |
push ax |
push bx |
push dx |
mov ax, 0x6900 |
mov bl, drv /* A=1, B=2, etc */ |
inc bl /* adjust BL to +1 since drv is 0-based (A=0, B=1, etc) */ |
xor bh, bh /* "info level", must be 0 */ |
mov dx, buff /* pointer to a location where a DiskInfo struct will be written */ |
int 0x21 |
jnc DONE |
mov [err], ax /* err code */ |
DONE: |
pop dx |
pop bx |
pop ax |
} |
/* Format of DiskInfo struct (source: RBIL) |
Offset Size Description (Table 01766) |
00h WORD 0000h (info level) |
02h DWORD disk serial number (binary) |
06h 11 BYTEs volume label or "NO NAME " if none present |
11h 8 BYTEs filesystem type */ |
if ((err == 0) && (buff16[1] | buff16[2])) { |
sprintf(buff + 64, "Volume Serial Number is %04X-%04X", buff16[2], buff16[1]); |
outputnl(buff + 64); |
} |
} |
static int cmd_vol(struct cmd_funcparam *p) { |
char drv = 0; |
char curdrv = 0; |
unsigned short i; |
if (cmd_ishlp(p)) { |
outputnl("Displays the disk volume label and serial number, if they exist."); |
outputnl(""); |
outputnl("VOL [drive:]"); |
return(-1); |
} |
for (i = 0; i < p->argc; i++) { |
if (p->argv[i][0] == '/') { |
outputnl("Invalid switch"); |
return(-1); |
} |
if (drv != 0) { |
outputnl("Too many parameters"); |
return(-1); |
} |
if ((p->argv[i][0] == 0) || (p->argv[i][1] != ':') || (p->argv[i][2] != 0)) { |
outputnl("Invalid parameter format"); |
return(-1); |
} |
drv = p->argv[i][0]; |
/* convert drive letter to a value 1..x (1=A, 2=B, etc) */ |
if ((drv >= 'a') && (drv <= 'z')) { |
drv -= 'a'; |
} else { |
drv -= 'A'; |
} |
} |
/* fetch current drive */ |
_asm { |
push ax |
mov ah, 0x19 /* query default (current) disk */ |
int 0x21 /* drive in AL (0=A, 1=B, etc) */ |
mov [curdrv], al |
pop ax |
} |
/* if no drive specified, use the default one */ |
if (drv == 0) { |
drv = curdrv; |
} else if (!isdrivevalid(drv)) { /* is specified drive valid? */ |
outputnl("Invalid drive"); |
return(-1); |
} |
cmd_vol_internal(drv, p->BUFFER); |
return(-1); |
} |
/svarcom/trunk/cmd.c |
---|
33,6 → 33,7 |
#include "cmd/_notimpl.c" |
#include "cmd/cd.c" |
#include "cmd/del.c" |
#include "cmd/vol.c" /* must be included before dir.c due to dependency */ |
#include "cmd/dir.c" |
#include "cmd/exit.c" |
#include "cmd/mkdir.c" |
40,9 → 41,9 |
#include "cmd/prompt.c" |
#include "cmd/rmdir.c" |
#include "cmd/set.c" |
#include "cmd/type.c" |
#include "cmd/ver.c" |
#include "cmd/verify.c" |
#include "cmd/type.c" |
#include "cmd.h" |
82,7 → 83,7 |
{"TYPE", cmd_type}, |
{"VER", cmd_ver}, |
{"VERIFY", cmd_verify}, |
{"VOL", cmd_notimpl}, |
{"VOL", cmd_vol}, |
{NULL, NULL} |
}; |
/svarcom/trunk/helpers.c |
---|
145,9 → 145,12 |
} |
/* converts a path to its canonic representation */ |
void file_truename(const char *src, char *dst) { |
/* converts a path to its canonic representation, returns 0 on success |
* or DOS err on failure (invalid drive) */ |
unsigned short file_truename(const char *src, char *dst) { |
unsigned short res = 0; |
_asm { |
push es |
mov ah, 0x60 /* query truename, DS:SI=src, ES:DI=dst */ |
push ds |
pop es |
154,7 → 157,12 |
mov si, src |
mov di, dst |
int 0x21 |
jnc DONE |
mov [res], ax |
DONE: |
pop es |
} |
return(res); |
} |
208,3 → 216,32 |
int 0x21 |
} |
} |
/* validate a drive (A=0, B=1, etc). returns 1 if valid, 0 otherwise */ |
int isdrivevalid(unsigned char drv) { |
_asm { |
mov ah, 0x19 /* query default (current) disk */ |
int 0x21 /* drive in AL (0=A, 1=B, etc) */ |
mov ch, al /* save current drive to ch */ |
/* try setting up the drive as current */ |
mov ah, 0x0E /* select default drive */ |
mov dl, [drv] /* 0=A, 1=B, etc */ |
int 0x21 |
/* this call does not set CF on error, I must check cur drive to look for success */ |
mov ah, 0x19 /* query default (current) disk */ |
int 0x21 /* drive in AL (0=A, 1=B, etc) */ |
mov [drv], 1 /* preset result as success */ |
cmp al, dl /* is eq? */ |
je DONE |
mov [drv], 0 /* fail */ |
jmp FAILED |
DONE: |
/* set current drive back to what it was initially */ |
mov ah, 0x0E |
mov dl, ch |
int 0x21 |
FAILED: |
} |
return(drv); |
} |
/svarcom/trunk/helpers.h |
---|
51,8 → 51,9 |
* in string. keys in c MUST BE UPPERCASE! */ |
unsigned short askchoice(const char *s, const char *c); |
/* converts a path to its canonic representation */ |
void file_truename(const char *src, char *dst); |
/* converts a path to its canonic representation, returns 0 on success |
* or DOS err on failure (invalid drive) */ |
unsigned short file_truename(const char *src, char *dst); |
/* returns DOS attributes of file, or -1 on error */ |
int file_getattr(const char *fname); |
66,4 → 67,7 |
/* displays the "Press any key to continue" msg and waits for a keypress */ |
void press_any_key(void); |
/* validate a drive (A=0, B=1, etc). returns 1 if valid, 0 otherwise */ |
int isdrivevalid(unsigned char drv); |
#endif |