home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!utoday!jaflrn!jaf
- From: Jon Freivald <jaf@jaflrn.UUCP>
- Newsgroups: alt.msdos.programmer
- Subject: Re: Local vs Net drive. How Tell ?
- Message-ID: <oTJsXB2w164w@jaflrn.UUCP>
- Date: Fri, 22 Jan 93 13:28:11 EST
- References: <JONES.93Jan19151743@hal.uvm.edu>
- Organization: The Wizzard's Cave, East Meadow, NY
- Lines: 448
-
- jones@hal.uvm.edu (Mike Jones) writes:
-
- > I am building a network login program to work under StarLan (lanman
- > 2.0). Currently I look for a mounted network drive (by attempting to
- > get drive params/diskspace) to figure out if "net logon" worked (it
- > doesn't return any values via status or doserror).
- >
- > Problem, Drive D: is a network drive for most people, and on almost
- > all of our computers, there is no local drive D:. However, there are
- > some prof's around who have a local drive D:. Some other drive gets
- > mounted for them. So the logical check is, does drive H: exist, if
- > not, does drive D: ? For the Prof's, drive D: will always exist.
- >
- > The quick fix is to do a findfirst() and look for a specific file
- > (network.dat). But I have seen programs that know how many disks are
- > installed in the system, and which ones are local, and which are
- > network drives. How do they do this ?
- >
- > Is there one "get params" call that returns the information that I
- > want. Versions of DOS are 3.1 upto 5.0, so it has to work everywhere,
- > and for everybody.
- >
- > Thanks,
- > Mike
- >
- > (sorry, can't move net drive D: to E:. It was thought of, but not
- > done because of the large number of machines that we have. Maybe next
- > year. I want a full time fix.)
-
- Mike,
-
- Attached are 3 files - drives.c, ceh.asm & numflopy.asm - if you
- put them together, you end up with drives.exe which will go out and find
- all your drives and tell you what type they are. It ought to be quite
- easy for you to modify this code to suit your needs...
-
- Jon
-
- P.S. - this was put together using Borland TurboC++ 1.0 & TASM 2.0 (I
- think). If you use MSC, you've got some work to do, but all the pieces
- of how to make it work are here...
-
- -------- drives.c -----------------------------------------------------
-
- //===========================================================================
- //
- // drives.c
- //
- // test prog for critical error handler & disk determination routine
- //
- // also requires ceh.asm and numflopy.asm
- //
- // TurboC - use:
- // tasm /mx ceh.asm
- // tasm /mx numflopy.asm
- // tcc -mt drives.c ceh.obj numflopy.obj
- //
- //===========================================================================
-
- #pragma inline // start compilation via assembly to eliminate
- // the error message generated
- #include <stdio.h>
- #include <dos.h>
-
- //===========================================================================
- //
- // function declarations
- //
- //===========================================================================
-
- int main ( void );
- int check_disk_type ( int disk_number );
- int test_cd_driver ( void );
- extern void setCEH ( void );
- extern void unsetCEH ( void );
- extern unsigned short number_floppy ( void );
-
- //===========================================================================
- //
- // character arrays
- //
- //===========================================================================
-
- char *drive_type [] = { "", "160K diskette", "180K diskette",\
- "320K diskette", "360K diskette", "1.2M diskette", "720K diskette",\
- "1.44M diskette", "unknown floppy disk type", "fixed disk",\
- "network file service", "CD-ROM", 0 };
-
- //===========================================================================
- //
- // miscellany
- //
- //===========================================================================
-
- #define SMALL 0
- char memory_model = SMALL; // needed for C-Express functions ( numflopy.asm )
- int cd_driver = 0; // status for presence/version of CD-ROM driver
-
- //===========================================================================
- //
- // main()
- //
- // arguments: currently none
- //
- // returns: 0
- //
- //===========================================================================
-
- int main ( void )
-
- {
- int i, disk_type_found;
-
- setCEH();
-
- cd_driver = test_cd_driver();
-
- if ( cd_driver == 1 )
- {
- printf("\n\n\a\tA CD-ROM device driver (MSCDEX compatible) has been detected,");
- printf("\n\thowever, it is not version 2.0 or higer. This program will be unable");
- printf("\n\tto differentiate between the CD-ROM drive(s) and any network drive(s)");
- printf("\n\n");
- }
-
- for ( i=1; i <= number_floppy(); i++ )
- {
- disk_type_found = check_disk_type ( i );
- if ( disk_type_found != 0 )
- {
- printf("\nDrive %c:, type - %s", (i + 'a' - 1), drive_type[disk_type_found]);
- }
- }
-
- if ( i == 2 )
- i++;
-
- for ( ; i < 27; i++ )
- {
- disk_type_found = check_disk_type ( i );
- if ( disk_type_found != 0 )
- {
- printf("\nDrive %c:, type - %s", (i + 'a' - 1), drive_type[disk_type_found]);
- }
- }
-
- printf("\n");
-
- unsetCEH();
-
- return ( 0 );
- }
-
- //===========================================================================
- //
- // check_disk_type()
- //
- // determines whether disk is local, remote, or CD-ROM
- //
- // arguments: int disk_number number of disk as
- // from getdisk()
- //
- // returns: int disk type;
- // 0 = no disk
- // 1 = 160K floppy
- // 2 = 180K floppy
- // 3 = 320K floppy
- // 4 = 360K floppy
- // 5 = 1.2M floppy
- // 6 = 720K floppy
- // 7 = 1.44M floppy
- // 8 = unknown floppy
- // 9 = local
- // 10 = network
- // 11 = CD-ROM
- //
- // uses global: cd_driver (0 if no driver or < 2.0, 1 if >= 2.0)
- //
- //===========================================================================
-
- int check_disk_type ( int disk_number )
-
- {
- union REGS regs;
- struct SREGS sregs;
- unsigned char far *des_byte; // media descriptor byte
- int rc = 1;
-
- regs.h.dl = disk_number; // drive number to test (a: == 1)
- regs.h.ah = 0x1C; // "get drive data" function
- int86x ( 0x21, ®s, ®s, &sregs );
-
- if ( regs.h.al == 0xFF ) // Did an error occur?
- {
- return ( 0 ); // Assume no disk present
- }
- des_byte = MK_FP ( sregs.ds, regs.x.bx ); // Make the far pointer to the descriptor byte
-
- if ( ( des_byte[0] != 0xF8 ) && ( des_byte[0] != 0x00 ) ) // Is it a fixed disk?
-
- /* This is where the code varies from the documentation I can find
- on the subject -- it *SEEMS* that CD's return a descriptor byte of 0x00,
- however, I cannot find that documented anywhere... (0xF8 is fixed disk).
- I've had to include the test for 0x00 here so that we progress to the tests
- further down the line... */
-
- {
- regs.h.ah = 0x36; // If not, get the number of sectors on it
- regs.h.dl = disk_number; // to determine the type of floppy it is
- int86 ( 0x21, ®s, ®s ); // (the descriptor byte is not specific enough...)
- switch ( regs.x.dx * regs.x.ax )
- {
- case 313: // 160K
- return ( 1 );
- case 351: // 180K
- return ( 2 );
- case 630: // 320K
- return ( 3 );
- case 708: // 360K
- return ( 4 );
- case 2371: // 1.2M
- return ( 5 );
- case 1426: // 720K
- return ( 6 );
- case 2847: // 1.44M
- return ( 7 );
- default: // Unknown type
- return ( 9 );
- }
- }
-
- // If we get this far, it's a hard, net or CD-ROM disk
-
- rc = 9; // Set rc to 9 if we get this far because
- // it's at least a local hard disk
- regs.h.ah = 0x44; // Int 21, func 44, sub 9 is IOCTL, we
- regs.h.al = 0x9; // use it to diff local & net/cd (remote)
- // This requires DOS 3.1 or higher
- regs.h.bl = (unsigned char) disk_number;
- int86 ( 0x21, ®s, ®s );
-
- if ( ( regs.x.dx & 0x1000 ) == 0x1000 ) // if bit 12 of DX is 1, disk is remote
- {
- rc = 10; // if we're here, we're either net or cd
- if ( cd_driver == 2 ) // test for cd requires MSCDEX >= 2.0, variable
- { // cd_driver is set by test_cd_driver()
- regs.h.ah = 0x15;
- regs.h.al = 0x0b;
- regs.x.bx = 0;
- regs.x.cx = disk_number - 1; // less 1 due to a: == 0
- int86 ( 0x2f, ®s, ®s );
-
- if ( regs.x.ax != 0 && regs.x.bx == 0xadad ) // check on BX not really necessary since we
- { // check for the presence of MSCDEX elsewhere, however, let's leave it
- // in for reusabilitiy's sake
- rc = 11; // disk is CD-ROM
- }
- }
- }
- return ( rc );
- }
-
- //===========================================================================
- //
- // test_cd_driver()
- //
- // tests for presence of and version of MSCDEX driver
- // (version >= 2.0 required for "is this a CD" test)
- //
- // arguments: none
- //
- // returns: 0 = no driver loaded or no CD-ROMs
- // 1 = driver loaded, >= 1 CD, < version 2.0
- // 2 = driver loaded, >= 1 CD, >= version 2.0
- //
- //===========================================================================
-
- int test_cd_driver ( void )
-
- {
- union REGS regs;
-
- asm mov ax,1500h // check if CD-ROM available
- asm xor bx,bx
- asm int 2fh // invoke MSCDEX
- asm or bx,bx // one or more CD-ROMs?
- asm jnz present // yes, CD-ROMs are present
-
- return ( 0 ); // no MSCDEX or 0 CD-ROM units
-
- present: // One or more CD-ROMs
-
- regs.h.ah = 0x15;
- regs.h.al = 0x0c; // get version number
- regs.x.bx = 0;
- int86 ( 0x2f, ®s, ®s );
- if ( regs.h.bh < 2 )
- return ( 1 ); // version < 2.0
- return ( 2 ); // version >= 2.0
- }
-
- //===========================================================================
- //
- // End of file, drives.c
- //
- //===========================================================================
-
- ------------- ceh.asm --------------------------------------------------
- ; setCEH() Install replacement Critical Error Handler to cause
- ; automatic "Fail" on drive-not-ready when testing
- ; empty floppy drives. All other conditions are passed
- ; to the original handler
- ;
- ; unsetCEH() Use to deinstall our replacement CEH
- ;
- ; use: tasm /mx ceh.asm
- ;
- ; written by Jesse Chisholm, 91.12.31
- ; released to the Public Domain: 91.12.31
- ; modified to use from C code by Jon Freivald, 92.01.12
-
- ;_STACK segment para stack 'STACK'
- ; dw 100h dup (0)
- ;_STACK ends
-
- _TEXT segment word public 'CODE'
-
- assume cs:_TEXT
-
- PUBLIC _setCEH, _unsetCEH
-
- Oldint24 dd 0 ; store the original address
-
- Newint24 dd int24 ; address of new CEH
-
- ;
- ; This code is executed during program's initialization
- ; to install the new critical error handler.
- ;
-
- _setCEH proc near
-
- push bx ; save some registers
- push dx
- push ds
- push es
-
- mov ax,3524h ; get the original vector
- int 21h
- mov word ptr Oldint24,bx
- mov bx,es
- mov word ptr Oldint24+2, bx
-
- lds dx,Newint24 ; DS:DX == handler address
- mov ax,2524h ; set new vector
- int 21h ; transfer to MS-DOS
-
- pop es ; restore registers
- pop ds
- pop dx
- pop bx
-
- ret
- _setCEH endp
-
- ;
- ; This code is executed in the program's termination and cleanup code
- ;
- _unsetCEH proc near
-
- push dx ; save some registers
- push ds
-
- mov dx,word ptr Oldint24 ; check if vector ever set
- or dx,word ptr Oldint24+2
- cmp dx,0
- je unsetCEHx ; no, don't reset
-
- mov ax,2524h ; restore old address
- lds dx,Oldint24
- int 21h
-
- xor dx,dx ; zap address for next time
- mov word ptr Oldint24,dx
- mov word ptr Oldint24+2,dx
-
- unsetCEHx: pop ds ; restore registers
- pop dx
-
- ret
- _unsetCEH endp
-
- ;
- ; This is the replacement critical error handler.
- ; If the drive was not ready, it causes the MS-DOS function
- ; to "FAIL". All other conditions are passed to the original
- ; int 24 handler.
- ;
-
- int24 proc far
-
- mov ax,di ; get error code
- cmp al,02h ; 02 == DRIVE NOT READY
- je FloppyNotReady
- jmp far ptr [Oldint24] ; go to original handler
-
- FloppyNotReady:
- mov al,03h ; 03 == Fail function call in progress
-
- iret ; exit critical error handler
- int24 endp
-
- _TEXT ends
-
- end
-
- -------- numflopy.asm ------------------------------------------------
-
- ;unsigned short number_floppy();
-
- EXTRN _memory_model:byte
-
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:_TEXT
- PUBLIC _number_floppy
- _number_floppy proc near
- sub ax,ax ;clear AX in case none
- int 11h ;make BIOS equipment chk
- test ax,1 ;any drives at all?
- jz L1 ;jump ahead if not
- and ax,11000000B ;clear bits 0-5
- mov cl,6 ;ready for shift
- shr ax,cl ;bits to bottom of AX
- inc ax ;count from 1, not 0
- L1: cmp _memory_model,0 ;quit
- jle Quit ;
- db 0CBh ;RET far
- Quit: ret ;RET near
- _number_floppy endp
- _TEXT ENDS
- END
-
-
- =============================================================================
- Jon Freivald ( jaf%jaflrn@uunet.UU.NET )
- Nothing is impossible for the man who doesn't have to do it.
- PGP V2 public key available on request
- =============================================================================
-