Определение cdrom в DOS

Тема в разделе "WASM.ASSEMBLER", создана пользователем Ignat, 15 янв 2009.

  1. Ignat

    Ignat New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    5
    В общем, программа должна найти все логические жёсткие диски.
    Проблема в том, что все функции, которые пытался использовать, не могут отличить CDROM от
    жёсткого диска.
    Вот мои неудачные варианты:

    Вариант 1:
    Код (Text):
    1.          unsigned int type = 0;  
    2.          asm {
    3.             MOV AH, 0x44
    4.             MOV AL, 0x8
    5.             MOV AX, 0x4408
    6.             MOV BL, disk
    7.             INT 0x21
    8.             MOV type, AX
    9.             }
    Вариант 2:
    Код (Text):
    1.                  unsigned char type = 0;
    2.                  asm {
    3.                     MOV AH, 0x10
    4.                     MOV DL, disk
    5.                     INT 0x13
    6.                     MOV type, AH
    7.                     }
    В обоих случаях для жёсткого диска и для CDROM значение type одно и то же.
    Может, кто подскажет, что я делаю неправильно...
    Может надо использовать другую функцию, которую я не нашёл?
    На сайте есть примеры для Win32, а для DOS нет.
     
  2. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    Ignat

    не могут отличить CDROM от жёсткого диска - получи DPB и посмотри у него размер сектора.
    Код (Text):
    1. --------D-2132-------------------------------
    2. INT 21 - DOS 2+ - GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE
    3.         AH = 32h
    4.         DL = drive number (00h = default, 01h = A:, etc)
    5. Return: AL = status
    6.             00h successful
    7.                 DS:BX -> Drive Parameter Block (DPB) (see #01395) for specified
    8.                           drive
    9.             FFh invalid or network drive
    10. Notes:  the OS/2 compatibility box supports the DOS 3.3 version of this call
    11.           except for the DWORD at offset 12h
    12.         this call updates the DPB by reading the disk; the DPB may be accessed
    13.           via the DOS list of lists (see #01627 at AH=52h) if disk access is not
    14.           desirable.
    15.         undocumented prior to the release of DOS 5.0; only the DOS 4.0+
    16.           version of the DPB has been documented, however
    17.         supported by DR DOS 3.41+; DR DOS 3.41-6.0 return the same data as
    18.           MS-DOS 3.31
    19.         IBM ROM-DOS v4.0 also reports invalid/network (AL=FFh) on the ROM drive
    20. SeeAlso: AH=1Fh,AH=52h,AX=7302h
    21.  
    22. Format of DOS Drive Parameter Block:
    23. Offset  Size    Description     (Table 01395)
    24.  00h    BYTE    drive number (00h = A:, 01h = B:, etc)
    25.  01h    BYTE    unit number within device driver
    26.  02h    WORD    bytes per sector
    27.  04h    BYTE    highest sector number within a cluster
    28.  05h    BYTE    shift count to convert clusters into sectors
    29.  06h    WORD    number of reserved sectors at beginning of drive
    30.  08h    BYTE    number of FATs
    31.  09h    WORD    number of root directory entries
    32.  0Bh    WORD    number of first sector containing user data
    33.  0Dh    WORD    highest cluster number (number of data clusters + 1)
    34.                 16-bit FAT if greater than 0FF6h, else 12-bit FAT
    35.  0Fh    BYTE    number of sectors per FAT
    36.  10h    WORD    sector number of first directory sector
    37.  12h    DWORD   address of device driver header (see #01646)
    38.  16h    BYTE    media ID byte (see #01356)
    39.  17h    BYTE    00h if disk accessed, FFh if not
    40.  18h    DWORD   pointer to next DPB
    41. ---DOS 2.x---
    42.  1Ch    WORD    cluster containing start of current directory, 0000h=root,
    43.                 FFFFh = unknown
    44.  1Eh 64 BYTEs   ASCIZ pathname of current directory for drive
    45. ---DOS 3.x---
    46.  1Ch    WORD    cluster at which to start search for free space when writing
    47.  1Eh    WORD    number of free clusters on drive, FFFFh = unknown
    48. ---DOS 4.0-6.0---
    49.  0Fh    WORD    number of sectors per FAT
    50.  11h    WORD    sector number of first directory sector
    51.  13h    DWORD   address of device driver header (see #01646)
    52.  17h    BYTE    media ID byte (see #01356)
    53.  18h    BYTE    00h if disk accessed, FFh if not
    54.  19h    DWORD   pointer to next DPB
    55.  1Dh    WORD    cluster at which to start search for free space when writing,
    56.                 usually the last cluster allocated
    57.  1Fh    WORD    number of free clusters on drive, FFFFh = unknown
    58. SeeAlso: #01357,#01663,#01787 at AX=7302h,#04039 at INT E0/CL=71h
     
  3. Ignat

    Ignat New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    5
    Спасибо за совет, но вот проблема - предоставленная функция работает под DOS, а Винды при запуске программы ругаются на 16-разрядную функцию, и выполнять её не собираются.
    А мне надо, чтоб работало и в Виндах и в DOSе ...
    Жду ответа как соловей лета!
     
  4. Ignat

    Ignat New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    5
    Долгие поиски завели в тупик.
    Наиболее подходящая функция, которую я нашёл:

    Код (Text):
    1.                  asm {
    2.                     MOV AH, 0x36
    3.                     MOV DL, disk
    4.                     INT 0x21
    5.                     MOV type, AX
    6.                     }
    type выдаёт размер сектора. Всё бы ничего, но если в CDROM нет диска, то цикл останавливается с
    сообщением на консоль "Нет готовности чтение диск X. Abort, Retry, Fail?", и требует нажатия клавиши. Если
    нажать 'F' то цикл продолжается. Такая интерактивность меня не устраивает, программа должна искать диски автоматически.
    Я начинаю постепенно приходить к выводу, что задача не решаема.
     
  5. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    Ignat
    Проверил код под Хрюхой (думаю, и под Ви98СЕ пойдет) - находит все логические харды. СиДиРамы игнорирует, если диска в нем нет.
    Код (Text):
    1. --------D-2171A0-----------------------------
    2. INT 21 - Windows95 - LONG FILENAME - GET VOLUME INFORMATION
    3.         AX = 71A0h
    4.         DS:DX -> ASCIZ root name (e.g. "C:\")
    5.         ES:DI -> buffer for file system name
    6.         CX = size of ES:DI buffer
    7. Return: CF clear if successful
    8.             AX destroyed (0000h and 0200h seen)
    9.             BX = file system flags (see #01783)
    10.             CX = maximum length of file name [usually 255]
    11.             DX = maximum length of path [usually 260]
    12.             ES:DI buffer filled (ASCIZ, e.g. "FAT","NTFS","CDFS")
    13.         CF set on error
    14.             AX = error code
    15.                 7100h if function not supported
    16. Notes:  for the file system name buffer, 32 bytes should be sufficient; that's
    17.          what is used in some sample code by Walter Oney from Microsoft.
    18.         this function accesses the disk the first time it is called
    19. BUG:    this function returns DX=0000h for CD-ROM drives under Win95 SP1
    20. SeeAlso: AX=714Eh,AX=7160h/CL=00h
    21.  
    22. Bitfields for long filename volume information flags:
    23. Bit(s)  Description     (Table 01783)
    24.  0      searches are case sensitive
    25.  1      preserves case in directory entries
    26.  2      uses Unicode characters in file and directory names
    27.  3-13   reserved (0)
    28.  14     supports DOS long filename functions
    29.  15     volume is compressed
    Фрагмент ниже не проверял - лень.
    Код (Text):
    1. --------D-217302-----------------------------
    2. INT 21 - Windows95 - FAT32 - "Get_ExtDPB" - GET EXTENDED DPB
    3.         AX = 7302h
    4.         DL = drive number (00h=default, 01h=A:, etc.)
    5.         ES:DI -> buffer for returned data (see #01786)
    6.         CX = length of buffer (003Fh for Windows95)
    7.         SI = signature (undocumented, must be F1A6h to get device driver
    8.               address and next-DBP pointer) (see #01787)
    9. Return: CF clear if successful
    10.             ES:DI buffer filled
    11.         CF set on error
    12.             AX = error code
    13.                0018h bad buffer length
    14. SeeAlso: AX=7303h,AX=7304h,AH=1Fh,AH=32h
    15.  
    16. Format of Get_ExtDPB data buffer:
    17. Offset  Size    Description     (Table 01786)
    18.  00h    WORD    (call) length of following data (003Dh)
    19.  02h 61 BYTEs   (ret) drive parameter block (DPB) (see #01787)
    20.  
    21. Format of Extended Drive Parameter Block:
    22. Offset  Size    Description     (Table 01787)
    23.  00h 24 BYTEs   standard DOS 4+ DPB
    24.  18h    BYTE    "dpb_flags" (undocumented)
    25.                 FFh force media check
    26.  19h    DWORD   pointer to next DPB (see note)
    27.  1Dh    WORD    cluster at which to start search for free space when writing,
    28.                 usually the last cluster allocated
    29.  1Fh    WORD    number of free clusters on drive, FFFFh = unknown
    30.  21h    WORD    high word of free cluster count
    31.  23h    WORD    active FAT/mirroring
    32.                 bit 7: do not mirror active FAT to inactive FATs
    33.                 bits 6-4: reserved (0)
    34.                 bits 3-0: the 0-based FAT number of the active FAT
    35.                     (only meaningful if mirroring disabled)            
    36.  25h    WORD    sector number of file system information sector, or
    37.                   FFFFh for none (see also #01788)
    38.  27h    WORD    sector number of backup boot sector, or FFFFh for none
    39.  29h    DWORD   first sector number of the first cluster
    40.  2Dh    DWORD   maximum cluster number
    41.  31h    DWORD   number of sectors occupied by FAT
    42.  35h    DWORD   cluster number of start of root directory
    43.  39h    DWORD   cluster number at which to start searching for free space
    44. Notes:  except for offset 18h, all of the first 33 bytes are identical to
    45.           the standard DOS 4-6 DPB
    46.         unless the proper value is given in SI on entry to "Get_ExtDBP", the
    47.           next-DPB pointer and device driver address are set to 0000h:0000h
    48. SeeAlso: #01786,#01395 at AH=32h,#01664
    49.  
    50. Format of File System Information structure:
    51. Offset  Size    Description     (Table 01788)
    52.  00h    DWORD   signature 61417272h
    53.  04h    DWORD   number of free clusters (FFFFFFFFh if unknown)
    54.  08h    DWORD   most recently allocated cluster
    55.  0Ch 12 BYTEs   reserved
    56. SeeAlso: #01787
     
  6. Ignat

    Ignat New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    5
    Первая функция работает только под виндами, а в DOS выдаёт мусор.
    Вторая функция судя по всему - только для FAT32, поэтому не проверял.

    Но всё таки уже можно построить некую работающую конструкцию, типа такой:
    Вначале определяется версия DOS:
    Код (Text):
    1.    asm {
    2.       MOV AH, 0x30
    3.       INT 0x21
    4.       MOV highver, AL
    5.       MOV lowver, AH
    6.       }
    Если highver равен 5, то запуск идёт из Виндов и выполняем (получая тип ФС):
    Код (Text):
    1.          unsigned char type[100];
    2.          unsigned char sdisk[5];
    3.          sprintf(sdisk,"%c:\\",disk + 'A' - 1);
    4.          asm {
    5.             MOV AX, 0x71A0
    6.             LEA DX, sdisk
    7.             LEA DI, type
    8.             MOV CX, 100
    9.             INT 0x21
    10.             }
    Иначе - выполняем 16-ти разрядную функцию в DOS (получая размер сектора):
    Код (Text):
    1.          unsigned char type = 0;
    2.          asm {
    3.             MOV AH, 0x32
    4.             MOV DL, disk
    5.             INT 0x21
    6.             MOV type, AL
    7.             }
    Тут слабое звено - определение версии DOS, потому что наверно не всегда Винды будут соответствовать 5 версии, а 16-разрядный DOS - остальным версиям.
     
  7. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    Ignat
    Первая функция работает только под виндами, а в DOS выдаёт мусор. - Если в ДОСе выставляет флаг CF - замечательно. Так можно узнать, активна ли Виндоза. Если активна, используй 71А0, если нет - 32 для INT21h.
     
  8. Ignat

    Ignat New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    5
    Memphis
    Как выяснилось, флаг в ДОСе выставляется. Но он также выставляется в Винде, если в cdrom нет диска.
    Поэтому лучше наверное через версию.