Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!execu!sequoia!uudell!bigtex!texsun!exodus!newstop!jaytee!bodleian!geoff From: geoff@bodleian.East.Sun.COM (Geoff Arnold @ Sun BOS - R.H. coast near the top) Newsgroups: comp.os.msdos.programmer Subject: Re: Number of drives on system, how do you find out the ... Keywords: MS-DOS, drives Message-ID: <2993@jaytee.East.Sun.COM> Date: 19 Oct 90 20:47:26 GMT References: <1085@duteca4.UUCP> <25000@uflorida.cis.ufl.EDU> Sender: news@jaytee.East.Sun.COM Reply-To: geoff@east.sun.com (Geoff Arnold @ Sun BOS - R.H. coast near the top) Distribution: usa Organization: Sun Microsystems PC-NFS Engineering Lines: 264 The following little program is derived from the material in the Ralf Brown "interrupt list". It shows how to prowl the Logical Drive Table and GetRedirList outputs. Depending on your system and network, drives may show up on either or both of these. Sorry about the cryptic output: the "V" bit in the LDT means that the drive is valid. Also, you MUST compile with /AL, or all of the pointer will be screwed up. The code will adjust for DOS 3.x or 4.x correctly. Enjoy Geoff ---------------------------------------------------------------------- /* * SYS_SCAN.C * Compile with "cl /AL sys_scan.c". I use MSC5.0. */ #include #include #include /* The following requires that we compile with /Zp for * packed structures, or use the pragmas */ #pragma pack(1) struct dpb { unsigned char d_number; unsigned char d_unit; unsigned int d_secsize; unsigned char d_secpercl; unsigned char d_allocshf; unsigned int d_rsvsec; unsigned char d_fatnum; unsigned int d_roots; unsigned int d_data1; unsigned int d_lastcl; unsigned char d_fatsize; unsigned int d_root1; void far * d_blkdev_p; unsigned char d_mediad; unsigned char d_mediaf; struct dpb far * d_next; }; struct ldt3 { char p_path[67]; unsigned int p_flags; struct dpb far * p_dpb_p; unsigned int p_seek; unsigned int p_unknown1; unsigned int p_unknown2; unsigned int p_substptr; }; #define NETWORK_DRIVE 0x8000 #define VALID_DRIVE 0x4000 #define JOINED_DRIVE 0x2000 #define SUBST_DRIVE 0x1000 #define DRIVE_UNUSED 0 #define DRIVE_REDIRECTED 1 #define DRIVE_PERMANENT 2 #define DRIVE_INVALID 3 struct ldt4 { char p_path[67]; unsigned int p_flags; struct dpb far * p_dpb_p; unsigned int p_seek; unsigned int p_unknown1; unsigned int p_unknown2; unsigned int p_substptr; unsigned char p_unknown3[7]; }; struct dbuf { struct dpb far * s_dpb_p; void far * s_oft_p; void far * s_clkdev_p; void far * s_condev_p; unsigned int s_maxlogsec; void far * s_sbs_p; struct ldt3 far * s_ldt_p; void far * s_fcb_p; int s_fcbs; unsigned char s_logdrv; unsigned char s_lastdrv; }; static struct dbuf far * buf_p; static struct dpb far * dpb_p; static struct ldt3 far * ldt_p; static int onetime = 1; static int lastdrive; static unsigned int dos_major_version; /* * static prototypes */ static void setup_pointers(void ); static struct ldt3 far *find_drive(int n); static char get_redir_device[128]; static char get_redir_info[128]; static void display_redir_list() { int index; union REGS inregs; union REGS outregs; struct SREGS segregs; char far *dev_p; char far *info_p; printf("\n\nGetRedirectionList output:\n\n"); index = 0; dev_p = &get_redir_device[0]; info_p = &get_redir_info[0]; while(1) { inregs.h.ah = 0x5f; inregs.h.al = 2; segregs.ds = FP_SEG(dev_p); inregs.x.si = FP_OFF(dev_p); segregs.es = FP_SEG(info_p); inregs.x.di = FP_OFF(info_p); inregs.x.bx = index; intdosx(&inregs, &outregs, &segregs); if (outregs.x.cflag) break; if(outregs.h.bh & 1) printf("Entry %2d: (invalid)\n", index); else printf("Entry %2d: Type=%02X Status=%02X User=%04X Device=%s\n Info=%s\n", index, outregs.h.bl, outregs.h.bh, outregs.x.cx, get_redir_device, get_redir_info); index++; } printf("GetRedirectionList terminated after %2d entries with Error=%04X\n", index, outregs.x.ax); if(outregs.x.ax == 1) printf(" (Network not installed)\n"); if(outregs.x.ax == 18) printf(" (No more entries)\n"); } /* * -- setup_pointers -- setup_pointers -- setup_pointers -- * * setup_pointers() * */ static void setup_pointers() { union REGS inregs; union REGS outregs; struct SREGS segregs; inregs.h.ah = 0x30; /* get dos version */ intdos(&inregs, &outregs); dos_major_version = outregs.h.al; inregs.h.ah = 0x52; /* get address of list of lists */ intdosx(&inregs, &outregs, &segregs); FP_OFF(buf_p) = outregs.x.bx; FP_SEG(buf_p) = segregs.es; lastdrive = buf_p->s_lastdrv; dpb_p = buf_p->s_dpb_p; ldt_p = buf_p->s_ldt_p; onetime = 0; } /* * -- find_drive -- find_drive -- find_drive -- * * find_drive(n) * */ static struct ldt3 far * find_drive(n) int n; { struct ldt4 far *p4; if (dos_major_version == 3) return(&ldt_p[n]); p4 = (struct ldt4 far *)ldt_p; p4 = &p4[n]; return((struct ldt3 far *)p4); } main() { int i; struct ldt3 far * lp; printf("SYS_SCAN 1.0 - display key device info\n\n"); printf("Logical Drive Table\n\n"); setup_pointers(); printf("Home:%04X:%04X LDT:%04X:%04X DPB:%04X:%04X DosMaj=%d LastDrive=%d\n", FP_SEG(buf_p), FP_OFF(buf_p), FP_SEG(ldt_p), FP_OFF(ldt_p), FP_SEG(dpb_p), FP_OFF(dpb_p), dos_major_version, lastdrive); for(i = 0; i < lastdrive; i++) { lp = find_drive(i); printf("%04X:%04X %c: Flags=%04X=%c%c%c%c DPB:%04X:%04X Seek=%04X ?1=%04X ?2=%04X Subst=%04X\n", FP_SEG(lp), FP_OFF(lp), 'A'+i, lp->p_flags, (lp->p_flags & NETWORK_DRIVE ? 'N' : '-'), (lp->p_flags & VALID_DRIVE ? 'V' : '-'), (lp->p_flags & JOINED_DRIVE ? 'J' : '-'), (lp->p_flags & SUBST_DRIVE ? 'S' : '-'), FP_SEG(lp->p_dpb_p), FP_OFF(lp->p_dpb_p), lp->p_seek, lp->p_unknown1, lp->p_unknown2, lp->p_substptr); if(lp->p_flags & VALID_DRIVE) printf(".... Path=%s\n", lp->p_path); } display_redir_list(); } ---------------------------------------------------------------------- -- Geoff Arnold, PC-NFS architect, Sun Microsystems. (geoff@East.Sun.COM) -- *** "Now is no time to speculate or hypothecate, but rather a time *** *** for action, or at least not a time to rule it out, though not *** *** necessarily a time to rule it in, either." - George Bush ***