home *** CD-ROM | disk | FTP | other *** search
- /* CURRDIR.C -- uses undocumented DOS to return pointer to
- current directory structure for a given drive */
-
- #include <stdlib.h>
- #include <dos.h>
-
- #include "currdir.h"
-
- typedef enum { UNKNOWN=-1, FALSE=0, TRUE=1 } OK;
-
- CDS far *currdir(unsigned drive)
- {
- /* statics to preserve state: only do init once */
- static BYTE far *dir = (BYTE far *) 0;
- static OK ok = UNKNOWN;
- static unsigned currdir_size;
- static BYTE lastdrv;
-
- if (ok == UNKNOWN) /* only do init once */
- {
- unsigned drv_ofs, lastdrv_ofs;
-
- /* curr dir struct not available in DOS 1.x or 2.x */
- if ((ok = (_osmajor < 3) ? FALSE : TRUE) == FALSE)
- return (CDS far *) 0;
-
- /* compute offset of curr dir struct and LASTDRIVE in DOS
- list of lists, depending on DOS version */
- drv_ofs = (_osmajor == 3 && _osminor == 0) ? 0x17 : 0x16;
- lastdrv_ofs = (_osmajor == 3 && _osminor == 0)
- ? 0x1b
- : 0x21;
-
- #if defined(__TURBOC) || (defined(_MSC_VER) && (_MSC_VER >= 600))
- #ifdef __TURBOC__
- #define _asm asm
- #endif
-
- _asm push si /* needs to be preserved */
-
- /* get DOS list of lists into ES:BX */
- _asm mov ah, 52h
- _asm int 21h
-
- /* get LASTDRIVE byte */
- _asm mov si, lastdrv_ofs
- _asm mov ah, byte ptr es:[bx+si]
- _asm mov lastdrv, ah
-
- /* get current directory structure */
- _asm mov si, drv_ofs
- _asm les bx, es:[bx+si]
- _asm mov word ptr dir+2, es
- _asm mov word ptr dir, bx
-
- _asm pop si
- #else
- { // Microsoft C 5.1 -- no inline assembler available
- union REGS r;
- struct SREGS s;
- BYTE far *doslist;
- segread(&s);
- r.h.ah = 0x52;
- intdosx(&r, &r, &s);
- FP_SEG(doslist) = s.es;
- FP_OFF(doslist) = r.x.bx;
- lastdrv = doslist[lastdrv_ofs];
- dir = *((BYTE far * far *) (&doslist[drv_ofs]));
- }
- #endif
-
- /* OS/2 DOS box sets dir to FFFF:FFFF */
- if (dir == (BYTE far *) -1L) ok = FALSE;
-
- /* compute curr directory structure size */
- currdir_size = (_osmajor >= 4) ? 0x58 : 0x51;
-
- } /* end of static initializations */
-
- if (ok == FALSE)
- return (CDS far *) 0;
-
- if (drive >= lastdrv) /* is their drive < LASTDRIVE? */
- return (CDS far *) 0;
-
- /* return array entry corresponding to drive */
- return dir + (drive * currdir_size);
- }
-