home *** CD-ROM | disk | FTP | other *** search
/ For Beginners & Professional Hackers / cd.iso / docum / dos-ref.doc / examples / chap4.arj / CURRDIR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-25  |  2.5 KB  |  89 lines

  1. /* CURRDIR.C -- uses undocumented DOS to return pointer to
  2.    current directory structure for a given drive */
  3.  
  4. #include <stdlib.h>
  5. #include <dos.h>
  6.  
  7. #include "currdir.h"
  8.  
  9. typedef enum { UNKNOWN=-1, FALSE=0, TRUE=1 } OK;
  10.  
  11. CDS far *currdir(unsigned drive)
  12. {
  13.     /* statics to preserve state: only do init once */
  14.     static BYTE far *dir = (BYTE far *) 0;
  15.     static OK ok = UNKNOWN;
  16.     static unsigned currdir_size;
  17.     static BYTE lastdrv;
  18.  
  19.     if (ok == UNKNOWN)  /* only do init once */
  20.     {
  21.         unsigned drv_ofs, lastdrv_ofs;
  22.  
  23.         /* curr dir struct not available in DOS 1.x or 2.x */
  24.         if ((ok = (_osmajor < 3) ? FALSE : TRUE) == FALSE)
  25.             return (CDS far *) 0;
  26.  
  27.         /* compute offset of curr dir struct and LASTDRIVE in DOS
  28.            list of lists, depending on DOS version */
  29.         drv_ofs = (_osmajor == 3 && _osminor == 0) ? 0x17 : 0x16;
  30.         lastdrv_ofs = (_osmajor == 3 && _osminor == 0)
  31.                          ? 0x1b
  32.                          : 0x21;
  33.  
  34. #if defined(__TURBOC) || (defined(_MSC_VER) && (_MSC_VER >= 600))       
  35. #ifdef __TURBOC__
  36. #define _asm    asm
  37. #endif
  38.  
  39.         _asm    push si    /* needs to be preserved */
  40.  
  41.         /* get DOS list of lists into ES:BX */
  42.         _asm    mov ah, 52h
  43.         _asm    int 21h
  44.  
  45.         /* get LASTDRIVE byte */
  46.         _asm    mov si, lastdrv_ofs
  47.         _asm    mov ah, byte ptr es:[bx+si]
  48.         _asm    mov lastdrv, ah
  49.  
  50.         /* get current directory structure */
  51.         _asm    mov si, drv_ofs
  52.         _asm    les bx, es:[bx+si]
  53.         _asm    mov word ptr dir+2, es
  54.         _asm    mov word ptr dir, bx
  55.  
  56.         _asm    pop si
  57. #else           
  58. {       // Microsoft C 5.1 -- no inline assembler available
  59.         union REGS r;
  60.         struct SREGS s;
  61.         BYTE far *doslist;
  62.         segread(&s);
  63.         r.h.ah = 0x52;
  64.         intdosx(&r, &r, &s);
  65.         FP_SEG(doslist) = s.es;
  66.         FP_OFF(doslist) = r.x.bx;
  67.         lastdrv = doslist[lastdrv_ofs];
  68.         dir = *((BYTE far * far *) (&doslist[drv_ofs]));
  69. }
  70. #endif
  71.  
  72.         /* OS/2 DOS box sets dir to FFFF:FFFF */
  73.         if (dir == (BYTE far *) -1L) ok = FALSE;
  74.  
  75.         /* compute curr directory structure size */
  76.         currdir_size = (_osmajor >= 4) ? 0x58 : 0x51;
  77.  
  78.     } /* end of static initializations */
  79.  
  80.     if (ok == FALSE)
  81.         return (CDS far *) 0;
  82.  
  83.     if (drive >= lastdrv) /* is their drive < LASTDRIVE? */
  84.         return (CDS far *) 0;
  85.  
  86.     /* return array entry corresponding to drive */
  87.     return dir + (drive * currdir_size);
  88. }
  89.