15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Как узнать тип диска?

Для NT все пpосто - там надо вызвать QueryDosDevice, а остальное настолько очевидно, что описывать дольше чем самому посмотpеть ;-))
Для Win95 несколько сложнее. Я не буду выкусывать соответствующий кусок из функции опpеделения типа диска. Без контекста там не совсем понятно что к чему. Hадо только учесть, что эта функция 16-ти битная и ее надо вызывать чеpез Thunk-и. Конечно, часть того, что она делает можно сделать и в 32-х битном коде, но не все.

/************************************************************************\
* Module   : DrvType.cpp                                                *
*-----------------------------------------------------------------------*
*          :               : Original by Micro$oft corp. from MSDN      *
\************************************************************************/
/*
How to Determine Drive Types in Windows

Article ID: Q105922

*/

#include  <windows.h>
#include  <string.h>
#include    "..\SRC\IO_Const.h"

#pragma warning(disable:4704)

extern void FAR PASCAL DOS3Call(void);


   // See the "MS-DOS Programmer's Reference" for further information
   // about this structure.
typedef struct tagDEVICEPARAMS {
   BYTE  bSpecFunc;        // Special functions
   BYTE  bDevType;         // Device type
   WORD  wDevAttr;         // Device attributes
   WORD  wCylinders;       // Number of cylinders
   BYTE  bMediaType;       // Media type
                        // Beginning of BIOS parameter block (BPB)
   WORD  wBytesPerSec;     // Bytes per sector
   BYTE  bSecPerClust;     // Sectors per cluster
   WORD  wResSectors;      // Number of reserved sectors
   BYTE  bFATs;            // Number of FATs
   WORD  wRootDirEnts;     // Number of root-directory entries
   WORD  wSectors;         // Total number of sectors
   BYTE  bMedia;           // Media descriptor
   WORD  wFATsecs;         // Number of sectors per FAT
   WORD  wSecPerTrack;     // Number of sectors per track
   WORD  wHeads;           // Number of heads
   DWORD dwHiddenSecs;     // Number of hidden sectors
   DWORD dwHugeSectors;    // Number of sectors if wSectors == 0
   char  Dummy[71];        // Fuck Microsoft and Microsoft's sample code!!!
   // ----------------------  // End of BIOS parameter block (BPB)
} DEVICEPARAMS, FAR * LPDEVICEPARAMS;

// Function prototypes
static BOOL GetDeviceParameters (int nDrive,LPDEVICEPARAMS dp) ;
static BOOL IsCDRomDrive (int nDrive) ;

//-----------------------------------------------------------------
// GetDeviceParameters()
//
// Fills a DEVICEPARAMS struct with info about the given drive.
// Calls DOS IOCTL Get Device Parameters (440Dh, 60h) function.
//
// Parameters
//   nDrive   Drive number  0 = A, 1 = B, 2 = C, and so on.
//   dp       Pointer to a structure that will contain the drive's
//            parameters.
//
// Returns TRUE if it succeeded, FALSE if it failed.
//-----------------------------------------------------------------
static BOOL GetDeviceParameters (int nDrive, LPDEVICEPARAMS dp)
{
    BOOL bResult = TRUE;      // Assume success
    __asm {
         push ds
         mov  bx, nDrive
         inc  bx           // Convert 0-based #'s to 1-based #s
         mov  ch, 08h      // Device category--must be 08h
         mov  cl, 60h      // MS-DOS IOCTL Get Device Parameters
         lds  dx, dp
         mov  ax, 440Dh
         int  21h
         jnc  gdp_done     // CF SET if error
         mov  bResult, FALSE
      gdp_done:
         pop  ds
    }
    return (bResult);
}
//-----------------------------------------------------------------
// IsCDRomDrive()
//
// Determines if a drive is a CD-ROM. Calls MSCDEX and checks
// that MSCDEX is loaded, and that MSCDEX reports the drive is a
// CD-ROM.
//
// Parameters
//    nDrive    Drive number  0 = A, 1 = B, 2 = C, and so forth.
//
// Returns TRUE if nDrive is a CD-ROM drive, FALSE if it isn't.
//-----------------------------------------------------------------
static BOOL IsCDRomDrive (int nDrive)
{
    BOOL bResult = FALSE;      // Assume not a CD-ROM drive
    __asm {
         mov  ax, 150Bh       // MSCDEX CD-ROM Drive Check
         xor  bx, bx
         mov  cx, nDrive
         int  2Fh
         cmp  bx, 0ADADh      // Check MSCDEX signature
         jne  not_cd_drive
         or   ax, ax          // Check the drive type
         jz   not_cd_drive    // 0 (zero) means not CD-ROM
         mov  bResult, TRUE
      not_cd_drive:
    }
    return (bResult);
}

//-----------------------------------------------------------------
UINT GetDriveTypeEx (int nDrive)
{
    DEVICEPARAMS dp;
    UINT uType;
    UINT Drv4409Flag ;
    UINT fAddFlags = 0 ;

    _fmemset (&dp, 0, sizeof(dp));    // Init device params struct
    uType = GetDriveType (nDrive);

    switch (uType) {
      case DRIVE_REMOTE:
            // GetDriveType() reports CD-ROMs as Remote drives. Need
-7395------------------------------------------------------------------------
            // to see if the drive is a CD-ROM or a network drive.
        if (IsCDRomDrive (nDrive)) {
            return (EX_DRIVE_CDROM | EX_DRIVE_NOACCESS);
        } else {
            return (EX_DRIVE_REMOTE | EX_DRIVE_NOACCESS);
        }
        break;

      case DRIVE_REMOVABLE:
            // Check for a floppy disk drive. If it isn't, then we
            // don't know what kind of removable media it is.
            // For example, could be a Bernoulli box or something new...
        if (GetDeviceParameters (nDrive, &dp))
            switch (dp.bDevType) {
               // Floppy disk drive types
               case 0x0: case 0x1:              // 5.25" floppy
               case 0x3: case 0x4:              // 8" floppy
                  return (EX_DRIVE_FLOPPY5);
               case 0x2: case 0x7: case 0x8:    // 3.5" floppy
                  return (EX_DRIVE_FLOPPY3);
            }
        return (EX_DRIVE_REMOVABLE);  // Unknown removable media type
        break;

      case DRIVE_FIXED:
        __asm {
            xor  dx,dx
            mov  bx,nDrive
            inc  bl                    // 1-'A', 2-'B',...
            mov  ax,0x4409
            call far ptr DOS3Call
            mov  Drv4409Flag,dx
        }
        if (Drv4409Flag & 0x0100) fAddFlags |= EX_DRIVE_NOACCESS ;
            // GetDeviceParameters returns a device type of 0x05 for
            // hard disks. Because hard disks and RAM disks are the two
            // types of fixed-media drives, we assume that any fixed-
            // media drive that isn't a hard disk is a RAM disk.
        if (GetDeviceParameters (nDrive, &dp) && dp.bDevType == 0x05) {
            if (Drv4409Flag & 0x8000)
                return (EX_DRIVE_SUBSTED | fAddFlags);
            else
                return (EX_DRIVE_FIXED | fAddFlags);
        } else {
            return (EX_DRIVE_RAMDISK | fAddFlags);
        }
        break;
    }
    return (EX_DRIVE_INVALID);   // Drive is invalid if we get here.
}