home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / alt / msdos / programm / 3216 < prev    next >
Encoding:
Text File  |  1993-01-23  |  12.3 KB  |  459 lines

  1. Path: sparky!uunet!utoday!jaflrn!jaf
  2. From: Jon Freivald <jaf@jaflrn.UUCP>
  3. Newsgroups: alt.msdos.programmer
  4. Subject: Re: Local vs Net drive. How Tell ?
  5. Message-ID: <oTJsXB2w164w@jaflrn.UUCP>
  6. Date: Fri, 22 Jan 93 13:28:11 EST
  7. References: <JONES.93Jan19151743@hal.uvm.edu>
  8. Organization: The Wizzard's Cave, East Meadow, NY
  9. Lines: 448
  10.  
  11. jones@hal.uvm.edu (Mike Jones) writes:
  12.  
  13. > I am building a network login program to work under StarLan (lanman
  14. > 2.0).  Currently I look for a mounted network drive (by attempting to
  15. > get drive params/diskspace) to figure out if "net logon" worked (it
  16. > doesn't return any values via status or doserror).
  17. > Problem, Drive D: is a network drive for most people, and on almost
  18. > all of our computers, there is no local drive D:.  However, there are
  19. > some prof's around who have a local drive D:.  Some other drive gets
  20. > mounted for them.  So the logical check is, does drive H: exist, if
  21. > not, does drive D: ?  For the Prof's, drive D: will always exist.
  22. > The quick fix is to do a findfirst() and look for a specific file
  23. > (network.dat).  But I have seen programs that know how many disks are
  24. > installed in the system, and which ones are local, and which are
  25. > network drives.  How do they do this ?
  26. > Is there one "get params" call that returns the information that I
  27. > want.  Versions of DOS are 3.1 upto 5.0, so it has to work everywhere,
  28. > and for everybody.
  29. > Thanks,
  30. >   Mike
  31. > (sorry, can't move net drive D: to E:.  It was thought of, but not
  32. > done because of the large number of machines that we have.  Maybe next
  33. > year.  I want a full time fix.)
  34.  
  35. Mike,
  36.  
  37.      Attached are 3 files - drives.c, ceh.asm & numflopy.asm - if you
  38. put them together, you end up with drives.exe which will go out and find
  39. all your drives and tell you what type they are.  It ought to be quite
  40. easy for you to modify this code to suit your needs...
  41.  
  42. Jon
  43.  
  44. P.S. - this was put together using Borland TurboC++ 1.0 & TASM 2.0 (I
  45. think).  If you use MSC, you've got some work to do, but all the pieces
  46. of how to make it work are here...
  47.  
  48. -------- drives.c -----------------------------------------------------
  49.  
  50. //===========================================================================
  51. //
  52. //    drives.c
  53. //
  54. //    test prog for critical error handler & disk determination routine
  55. //
  56. //    also requires ceh.asm and numflopy.asm
  57. //
  58. //    TurboC  - use:
  59. //        tasm /mx ceh.asm
  60. //        tasm /mx numflopy.asm
  61. //        tcc -mt drives.c ceh.obj numflopy.obj
  62. //
  63. //===========================================================================
  64.  
  65. #pragma inline            // start compilation via assembly to eliminate
  66.                 // the error message generated
  67. #include <stdio.h>
  68. #include <dos.h>
  69.  
  70. //===========================================================================
  71. //
  72. //    function declarations
  73. //
  74. //===========================================================================
  75.  
  76. int    main ( void );
  77. int    check_disk_type ( int disk_number );
  78. int    test_cd_driver ( void );
  79. extern    void setCEH ( void );
  80. extern    void unsetCEH ( void );
  81. extern    unsigned short    number_floppy ( void );
  82.  
  83. //===========================================================================
  84. //
  85. //    character arrays
  86. //
  87. //===========================================================================
  88.  
  89. char    *drive_type    [] = { "", "160K diskette", "180K diskette",\
  90.     "320K diskette", "360K diskette", "1.2M diskette", "720K diskette",\
  91.     "1.44M diskette", "unknown floppy disk type", "fixed disk",\
  92.     "network file service", "CD-ROM", 0 };
  93.  
  94. //===========================================================================
  95. //
  96. //    miscellany
  97. //
  98. //===========================================================================
  99.  
  100. #define    SMALL    0
  101. char    memory_model = SMALL;    // needed for C-Express functions ( numflopy.asm )
  102. int    cd_driver = 0;        // status for presence/version of CD-ROM driver
  103.  
  104. //===========================================================================
  105. //
  106. //    main()
  107. //
  108. //        arguments:    currently none
  109. //
  110. //        returns:    0
  111. //
  112. //===========================================================================
  113.  
  114. int main ( void )
  115.  
  116. {
  117.     int i, disk_type_found;
  118.  
  119.     setCEH();
  120.  
  121.     cd_driver = test_cd_driver();
  122.  
  123.     if ( cd_driver == 1 )
  124.         {
  125.         printf("\n\n\a\tA CD-ROM device driver (MSCDEX compatible) has been detected,");
  126.         printf("\n\thowever, it is not version 2.0 or higer.  This program will be unable");
  127.         printf("\n\tto differentiate between the CD-ROM drive(s) and any network drive(s)");
  128.         printf("\n\n");
  129.         }
  130.  
  131.     for ( i=1; i <= number_floppy(); i++ )
  132.         {
  133.         disk_type_found = check_disk_type ( i );
  134.         if ( disk_type_found != 0 )
  135.             {
  136.             printf("\nDrive %c:, type - %s", (i + 'a' - 1), drive_type[disk_type_found]);
  137.             }
  138.         }
  139.  
  140.     if ( i == 2 )
  141.         i++;
  142.     
  143.     for ( ; i < 27; i++ )
  144.         {
  145.         disk_type_found = check_disk_type ( i );
  146.         if ( disk_type_found != 0 )
  147.             {
  148.             printf("\nDrive %c:, type - %s", (i + 'a' - 1), drive_type[disk_type_found]);
  149.             }
  150.         }
  151.  
  152.     printf("\n");
  153.  
  154.     unsetCEH();
  155.  
  156.     return ( 0 );
  157. }
  158.  
  159. //===========================================================================
  160. //
  161. //    check_disk_type()
  162. //
  163. //        determines whether disk is local, remote, or CD-ROM
  164. //
  165. //        arguments:    int    disk_number    number of disk as
  166. //                            from getdisk()
  167. //
  168. //        returns:    int    disk type;
  169. //                            0 = no disk
  170. //                            1 = 160K floppy
  171. //                            2 = 180K floppy
  172. //                            3 = 320K floppy
  173. //                            4 = 360K floppy
  174. //                            5 = 1.2M floppy
  175. //                            6 = 720K floppy
  176. //                            7 = 1.44M floppy
  177. //                            8 = unknown floppy
  178. //                            9 = local
  179. //                            10 = network
  180. //                            11 = CD-ROM
  181. //
  182. //        uses global:    cd_driver    (0 if no driver or < 2.0, 1 if >= 2.0)
  183. //
  184. //===========================================================================
  185.  
  186. int check_disk_type ( int disk_number )
  187.  
  188. {
  189.     union    REGS    regs;
  190.     struct    SREGS    sregs;
  191.     unsigned char far *des_byte;        // media descriptor byte
  192.     int    rc = 1;
  193.  
  194.     regs.h.dl = disk_number;        // drive number to test (a: == 1)
  195.     regs.h.ah = 0x1C;            // "get drive data" function
  196.     int86x ( 0x21, ®s, ®s, &sregs );
  197.  
  198.     if ( regs.h.al == 0xFF )        // Did an error occur?
  199.         {
  200.         return ( 0 );            // Assume no disk present
  201.         }
  202.     des_byte = MK_FP ( sregs.ds, regs.x.bx );    // Make the far pointer to the descriptor byte
  203.  
  204.     if ( ( des_byte[0] != 0xF8 ) && ( des_byte[0] != 0x00 ) )    // Is it a fixed disk?
  205.  
  206.     /*  This is where the code varies from the documentation I can find
  207. on the subject -- it *SEEMS* that CD's return a descriptor byte of 0x00,
  208. however, I cannot find that documented anywhere... (0xF8 is fixed disk).
  209. I've had to include the test for 0x00 here so that we progress to the tests
  210. further down the line... */
  211.  
  212.         {
  213.         regs.h.ah = 0x36;        // If not, get the number of sectors on it
  214.         regs.h.dl = disk_number;    //   to determine the type of floppy it is
  215.         int86 ( 0x21, ®s, ®s );    //   (the descriptor byte is not specific enough...)
  216.         switch ( regs.x.dx * regs.x.ax )
  217.             {
  218.             case 313:        // 160K
  219.                 return ( 1 );
  220.             case 351:        // 180K
  221.                 return ( 2 );
  222.             case 630:        // 320K
  223.                 return ( 3 );
  224.             case 708:        // 360K
  225.                 return ( 4 );
  226.             case 2371:        // 1.2M
  227.                 return ( 5 );
  228.             case 1426:        // 720K
  229.                 return ( 6 );
  230.             case 2847:        // 1.44M
  231.                 return ( 7 );
  232.             default:        // Unknown type
  233.                 return ( 9 );
  234.             }
  235.         }
  236.  
  237.     // If we get this far, it's a hard, net or CD-ROM disk
  238.  
  239.     rc = 9;                    // Set rc to 9 if we get this far because
  240.                         //   it's at least a local hard disk
  241.     regs.h.ah = 0x44;            // Int 21, func 44, sub 9 is IOCTL, we
  242.     regs.h.al = 0x9;            //   use it to diff local & net/cd (remote)
  243.                         //   This requires DOS 3.1 or higher
  244.     regs.h.bl = (unsigned char) disk_number;
  245.     int86 ( 0x21, ®s, ®s );
  246.  
  247.     if ( ( regs.x.dx & 0x1000 ) == 0x1000 )    // if bit 12 of DX is 1, disk is remote
  248.         {
  249.         rc = 10;            // if we're here, we're either net or cd
  250.         if ( cd_driver == 2 )        // test for cd requires MSCDEX >= 2.0, variable
  251.             {            //   cd_driver is set by test_cd_driver()
  252.             regs.h.ah = 0x15;
  253.             regs.h.al = 0x0b;
  254.             regs.x.bx = 0;
  255.             regs.x.cx = disk_number - 1;    // less 1 due to a: == 0
  256.             int86 ( 0x2f, ®s, ®s );
  257.  
  258.             if ( regs.x.ax != 0 && regs.x.bx == 0xadad )    // check on BX not really necessary since we
  259.                 {        //   check for the presence of MSCDEX elsewhere, however, let's leave it
  260.                         //   in for reusabilitiy's sake
  261.                 rc = 11;    // disk is CD-ROM
  262.                 }
  263.             }
  264.         }
  265.     return ( rc );
  266. }
  267.  
  268. //===========================================================================
  269. //
  270. //    test_cd_driver()
  271. //
  272. //        tests for presence of and version of MSCDEX driver
  273. //            (version >= 2.0 required for "is this a CD" test)
  274. //
  275. //        arguments:    none
  276. //
  277. //        returns:    0 = no driver loaded or no CD-ROMs
  278. //                1 = driver loaded, >= 1 CD, < version 2.0
  279. //                2 = driver loaded, >= 1 CD, >= version 2.0
  280. //
  281. //===========================================================================
  282.  
  283. int test_cd_driver ( void )
  284.  
  285. {
  286.     union REGS regs;
  287.  
  288.     asm    mov    ax,1500h                // check if CD-ROM available
  289.     asm    xor    bx,bx
  290.     asm    int    2fh                    // invoke MSCDEX
  291.     asm    or    bx,bx                    // one or more CD-ROMs?
  292.     asm    jnz    present                    // yes, CD-ROMs are present
  293.  
  294.     return ( 0 );                        // no MSCDEX or 0 CD-ROM units
  295.  
  296.     present:                        // One or more CD-ROMs
  297.  
  298.     regs.h.ah = 0x15;
  299.     regs.h.al = 0x0c;                    // get version number
  300.     regs.x.bx = 0;
  301.     int86 ( 0x2f, ®s, ®s );
  302.     if ( regs.h.bh < 2 )
  303.         return ( 1 );                    // version < 2.0
  304.     return ( 2 );                        // version >= 2.0
  305. }
  306.  
  307. //===========================================================================
  308. //
  309. //    End of file, drives.c
  310. //
  311. //===========================================================================
  312.  
  313. ------------- ceh.asm --------------------------------------------------
  314. ;       setCEH()        Install replacement Critical Error Handler to cause
  315. ;            automatic "Fail" on drive-not-ready when testing
  316. ;            empty floppy drives.  All other conditions are passed
  317. ;            to the original handler
  318. ;
  319. ;    unsetCEH()    Use to deinstall our replacement CEH
  320. ;
  321. ;    use:    tasm /mx ceh.asm
  322. ;
  323. ;    written by Jesse Chisholm, 91.12.31
  324. ;    released to the Public Domain: 91.12.31
  325. ;    modified to use from C code by Jon Freivald, 92.01.12
  326.  
  327. ;_STACK    segment    para stack 'STACK'
  328. ;    dw    100h dup (0)
  329. ;_STACK    ends
  330.  
  331. _TEXT    segment word public 'CODE'
  332.  
  333.     assume    cs:_TEXT
  334.  
  335.     PUBLIC _setCEH, _unsetCEH
  336.  
  337. Oldint24    dd    0        ; store the original address
  338.  
  339. Newint24    dd    int24        ; address of new CEH
  340.  
  341. ;
  342. ; This code is executed during program's initialization
  343. ; to install the new critical error handler.
  344. ;
  345.  
  346. _setCEH        proc    near
  347.  
  348.         push    bx        ; save some registers
  349.         push    dx
  350.         push    ds
  351.         push    es
  352.  
  353.         mov    ax,3524h    ; get the original vector
  354.         int    21h
  355.         mov    word ptr Oldint24,bx
  356.         mov    bx,es
  357.         mov    word ptr Oldint24+2, bx
  358.  
  359.         lds    dx,Newint24    ; DS:DX == handler address
  360.         mov    ax,2524h    ; set new vector
  361.         int    21h        ; transfer to MS-DOS
  362.  
  363.         pop    es        ; restore registers
  364.         pop    ds
  365.         pop    dx
  366.         pop    bx
  367.  
  368.         ret
  369. _setCEH        endp
  370.  
  371. ;
  372. ; This code is executed in the program's termination and cleanup code
  373. ;
  374. _unsetCEH    proc    near
  375.  
  376.         push    dx            ; save some registers
  377.         push    ds
  378.  
  379.         mov    dx,word ptr Oldint24    ; check if vector ever set
  380.         or    dx,word ptr Oldint24+2
  381.         cmp    dx,0
  382.         je    unsetCEHx        ; no, don't reset
  383.  
  384.         mov    ax,2524h        ; restore old address
  385.         lds    dx,Oldint24
  386.         int    21h
  387.  
  388.         xor    dx,dx            ; zap address for next time
  389.         mov    word ptr Oldint24,dx
  390.         mov    word ptr Oldint24+2,dx
  391.  
  392. unsetCEHx:    pop    ds            ; restore registers
  393.         pop    dx
  394.  
  395.         ret
  396. _unsetCEH    endp
  397.  
  398. ;
  399. ; This is the replacement critical error handler.
  400. ; If the drive was not ready, it causes the MS-DOS function
  401. ; to "FAIL".  All other conditions are passed to the original
  402. ; int 24 handler.
  403. ;
  404.  
  405. int24        proc    far
  406.  
  407.         mov    ax,di        ; get error code
  408.         cmp    al,02h        ; 02 == DRIVE NOT READY
  409.          je    FloppyNotReady
  410.         jmp    far ptr [Oldint24]    ; go to original handler
  411.  
  412. FloppyNotReady:
  413.         mov    al,03h        ; 03 == Fail function call in progress
  414.  
  415.         iret                ; exit critical error handler
  416. int24        endp
  417.  
  418. _TEXT    ends
  419.  
  420.     end
  421.  
  422. -------- numflopy.asm ------------------------------------------------
  423.  
  424. ;unsigned short  number_floppy();
  425.  
  426.     EXTRN  _memory_model:byte
  427.  
  428. _TEXT    SEGMENT BYTE PUBLIC 'CODE'
  429.     ASSUME CS:_TEXT
  430.     PUBLIC _number_floppy
  431. _number_floppy proc near
  432.     sub  ax,ax        ;clear AX in case none
  433.     int  11h        ;make BIOS equipment chk
  434.     test ax,1        ;any drives at all?
  435.     jz   L1            ;jump ahead if not
  436.     and  ax,11000000B    ;clear bits 0-5
  437.     mov  cl,6        ;ready for shift
  438.     shr  ax,cl        ;bits to bottom of AX
  439.     inc  ax            ;count from 1, not 0
  440. L1:    cmp  _memory_model,0    ;quit
  441.     jle  Quit        ;
  442.     db   0CBh        ;RET far
  443. Quit:    ret            ;RET near
  444. _number_floppy endp
  445. _TEXT    ENDS
  446.     END
  447.  
  448.  
  449. =============================================================================
  450.                    Jon Freivald ( jaf%jaflrn@uunet.UU.NET )
  451.      Nothing is impossible for the man who doesn't have to do it.
  452.             PGP V2 public key available on request
  453. =============================================================================
  454.