原创  用BIOS中断来检测设备的代码 收藏

#include <dpmi.h>   // for __dpmi_regs, __dpmi_int()
#include <string.h> // for memset()
#include <stdio.h>  // for printf()
#include <stdlib.h>

#define BYTE  unsigned char
#define WORD  unsigned short
#define DWORD unsigned long
#define QWORD unsigned long long

typedef struct TagInt13ExtDriveParam
{
 WORD    infoSize;    /*  结构大小        */
 WORD    flags;        /*  信息标志        */ 
 DWORD  cylinders;         /*  柱面个数        */
 DWORD  heads;     /*  磁头个数        */
 DWORD  sectorsPerTrack;  /*  每个磁道扇区数  */
 QWORD  totalSectors;      /*  总的扇区数      */
 WORD   bytesPerSector;         /*  扇区字节大小    */
 WORD offset;     /* DPTE 所指向的段的偏移地址 <1M 指向一个16字节的缓冲区*/
 WORD segm;     /* Device Parameter Table Extension (DPTE). 所指向的段地址 <1M*/  
 
}TInt13ExtDriveParam;

typedef struct DosMemoryBlock
{
 int  iSegment;     // Real-mode segment
 int  iSelector;    // The base selector for PM
 int  iMemSize;     // Block size (byte)
} DMB;

/*************************************************/
DMB         g_dmb;
__dpmi_regs regs;

void InitGlobalDmb()
{
 memset(&g_dmb, 0, sizeof(DMB));

 g_dmb.iMemSize = 64000 + 16;
    g_dmb.iSegment = __dpmi_allocate_dos_memory((g_dmb.iMemSize+15)>>4, &g_dmb.iSelector);
    if(g_dmb.iSegment == -1)
    {
  #ifdef DEBUG
        printf("Memory allocate error!\n");
  #endif
        exit(1);
    }
}

void FreeGlobalDmb()
{
    if(__dpmi_free_dos_memory(g_dmb.iSelector)  == -1)
    {
  #ifdef DEBUG
        printf("Memory free error!\n");
  #endif
    }
}

/*
 函数功能:检测是否支持扩展13h的使用
*/
int CheckInt13Ext(int driverNumber)
{
 __dpmi_regs regs;
 
 regs.h.ah = 0x41;
 regs.x.bx = 0x55aa;
 regs.h.dl = (BYTE) (driverNumber & 0x00ff);
 
 __dpmi_int(0x13,&regs);
 
 if( (regs.x.flags & 0x01) !=0 || regs.x.bx!=0xaa55 || (regs.x.cx & 0x01) == 0)
 {  
  return 0;
 }
 
 return 1;
}

void showByOldInt(int iHdNo)
{
 regs.h.ah = 0x08;
 regs.h.dl = iHdNo;
 __dpmi_int(0x13, &regs);
 if( (regs.x.flags & 0x01) != 0 )
 {
  printf("\nget info of DEV:%x(H) failed!!! int error code=%d", iHdNo, regs.h.ah);
  getchar();  
 } else {
  printf("\n   Dev info is (old) :");
  printf("\n      sectorsPerTrack = %lu ", regs.h.cl & 0x3f);
  printf("\n                heads = %lu ", regs.h.dh+1);
  printf("\n            cylinders = %lu ", ((WORD)regs.h.ch | (( ((WORD)regs.h.cl)<<2) & 0x300 ) ) + 1);
  //printf("\n         totalSectors = %lu ", (QWORD)params->cylinders *
  //           (QWORD)params->heads *
  //           (QWORD)params->sectorsPerTrack);
  getchar();
 }
}

void showByExtInt(int iHdNo)
{
 TInt13ExtDriveParam params;

 if (!CheckInt13Ext(iHdNo))
 {
  printf("\n DEV %x(H) not support ext INT 13", iHdNo);
  return;
 }
 else
 {
  printf("\n DEV %x(H) support ext INT 13", iHdNo);
 }

 //若支持扩展int 13h
 regs.h.ah = 0x48;
 regs.h.dl = (BYTE) (iHdNo & 0x00ff);
 regs.x.si = 0;
 regs.x.ds = g_dmb.iSegment;
   
 params.infoSize = sizeof(TInt13ExtDriveParam);
 dosmemput(&params, sizeof(TInt13ExtDriveParam), (g_dmb.iSegment<<4)&0xFFFFFFF0);
 __dpmi_int( 0x13, &regs );
 dosmemget((g_dmb.iSegment<<4)&0xFFFFFFF0 , sizeof(TInt13ExtDriveParam), &params );
 if( (regs.x.flags & 0x01) != 0)
 { 
  printf("\nget extended info DEV%x(H) failed!!! int error code=%d", iHdNo, regs.h.ah);
  getchar();
  
  return ;
 }
 
 printf("\n   Dev info is (ext) :");
 printf("\n      sectorsPerTrack = %lu ", params.sectorsPerTrack);
 printf("\n                heads = %lu ", params.heads);
 printf("\n            cylinders = %lu ", params.cylinders);
 printf("\n         totalSectors = %lu ", params.totalSectors);
 getchar();


void main(int argc, char *argv[])
{
 int i;

 InitGlobalDmb();
 printf("Hello, world\n");

 for (i=0; i<5; ++i)
 {
  printf("\n************************************");
  showByOldInt(0x80 + i);
  showByExtInt(0x80 + i);
  printf("\n************************************");
 }

 FreeGlobalDmb(); 
}
 

发表于 @ 2006年12月29日 16:34:00 | 评论( loading... ) | 编辑| 举报| 收藏

旧一篇:deassemble the code of MBR boot code | 新一篇:gawk 的使用例子

  • 发表评论
  • 评论内容:
  •  
Copyright © joeqi
Powered by CSDN Blog