Article View: alt.msdos.programmer
Article #1010Re: Local vs Net drive. How Tell ?
From: Jon Freivald
Date: Fri, 22 Jan 1993 18:28
Date: Fri, 22 Jan 1993 18:28
448 lines
13062 bytes
13062 bytes
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
=============================================================================
Technical Details
Message-ID:
<oTJsXB2w164w@jaflrn.UUCP>Path:
arc1-ca.pugleaf.net!sparky!uunet!utoday!jaflrn!jafReferences:
<JONES.93Jan19151743@hal.uvm.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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