日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > 不同WINDOWS平臺下磁盤邏輯扇區的直接讀寫

不同WINDOWS平臺下磁盤邏輯扇區的直接讀寫

來源:程序員人生   發布時間:2015-06-11 08:29:43 閱讀次數:2950次
不同WINDOWS平臺下磁盤邏輯扇區的直接讀寫
  關鍵字:VWIN32、中斷、DeviceIoControl
  1、概述
   在DOS操作系統下,通過BIOS的INT13、DOS的INT25(絕對讀)、INT26(絕對寫)等功能調用實現對磁盤邏輯扇區或物理扇區的讀寫是很方便的,C語言中還有對應上述功能調用的函數:biosdisk、absread和abswrite等。但在WINDOWS操作系統下編寫WIN32利用程序時卻不再能直接使用上述的中斷調用或函數了。那末,在WINDOWS操作系統下能不能實現磁盤扇區的直接讀寫呢?如何實現磁盤扇區的讀寫呢?為了解決這些問題,筆者查閱了1些相干資料后發現,WINDOWS操作系統也提供了讀寫磁盤扇區的方法,只是在不同的版本中有著不同的方式和使用限制。最后,筆者編寫了1個磁盤扇區直接讀寫類,不敢獨專,特提供出來,希望能對大家有所幫助。
   注:這里INT13表示INT 13H,其它類同。
  2、1個讀取軟盤扇區的例子
   WINDOWS操作系統對所有的存儲裝備實行了統1管理,而且為了安全起見,操作系統還不允許在WIN32利用程序(工作在Ring3級)中直接調用中斷功能,如INT13、INT21、INT25、INT26等。但它同時也提供了1些服務來彌補這類缺憾,在WIN95/98中,VWIN32服務就是其中1種。VWIN32服務是通過1個VXD來實現的,它提供了裝備IO功能,通過它,使用API函數DeviceIoControl即可以實現WIN32利用程序和磁盤裝備驅動程序間的通訊,從而實現對磁盤的存取。VWIN32提供的服務是1系列的控制命令字,它們實現諸如DOS操作系統下的INT13、INT25、INT26和INT21等功能調用。下面是它定義的1些控制命令字:
   VWIN32_DIOC_DOS_IOCTL (1) 實現INT21 功能
   VWIN32_DIOC_DOS_INT25 (2) 實現INT25 功能
   VWIN32_DIOC_DOS_INT26 (3) 實現INT26 功能 
   VWIN32_DIOC_DOS_INT13 (4) 實現INT13 功能
   VWIN32_DIOC_DOS_DRIVEINFO (6) 實現INT21 730x 功能 
  如果要對磁盤進行讀寫,只要使用DeviceIoControl履行相應命令便可,下面的例子用來讀取軟盤的1個扇區(使用INT13):
   第1步:打開VWIN32服務,HANDLE hDev=CreateFile("\.VWIN32",0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,NULL);
   第2步:填充中斷所用到的相干寄存器。這里將寄存器放在1個結構中,結構定義以下(有關INT13使用的寄存器情況,請參閱相干資料):
   typedef struct INT13Regs{
   PVOID buffer; // ebx 寄存器
   BYTE Drive; // 盤號 dl
  BYTE Head; //頭號 dh
  WORD EDX_High; // edx 寄存器 
  BYTE Sector; //始扇區 cl
  BYTE Track; //道號 ch
  WORD ECX_High; //ecx 寄存器
  BYTE Number; //要讀寫的扇取數 al
  BYTE CMD; //命令:2--讀,3--寫,5--格式化 ah
  WORD EAX_High; //eax 寄存器
  DWORD EDI; // edi 寄存器
   DWORD ESI; // esi
   DWORD EFLAG; // flags
   }INT13_REGISTERS;
   unsigned char Buffer[512];//定義緩沖區,放置讀取扇區數據
   INT13_REGISTERS reg={0};//定義寄存器結構變量
   
   reg.buffer =(void *)Buffer;
   reg.Drive =0;//0-軟盤A 1-軟盤B 0x80-硬盤c
   reg.Head =0;
   reg.Track=0;
   reg.Sector=1;
   reg.Number=1;
   reg.CMD=2; //讀
   第3步:調用裝備IO API函數DeviceIoControl履行4號命令(即VWIN32_DIOC_DOS_INT13), BOOL b_ret=DeviceIoControl(hDev,4,&reg,sizeof(INT13_REGISTERS),&reg,sizeof(INT13_REGISTERS),&lpRet,0);
  如果其返回值不等于零,調用成功,進1步處理....否則調用失敗。
   第4步:關閉服務,CloseHandle(hDev);
  3、限制或局限
   上面是使用INT13讀取軟盤扇區的完全步驟,在WIN95/98下它是可以工作的。那末,是不是將上面的寄存器結構中的Drive置為0x80就能夠讀取邏輯硬盤C盤的扇區了呢?回答是不是定的。INT13用來存取硬盤的功能在WINDOWS中被疏忽了。另外,INT25、INT26雖然可以存取硬盤,但是它們不能工作在FAT32格式的硬盤上。下面的列表將詳細羅列與磁盤操作相干的中斷調用的限制情況(不特殊說明,指的是在WIN95/98操作系統下):
   中斷功能 限制及使用情況
   INT13 不可以讀寫硬盤,僅支持軟盤
   INT25/INT26 不可以讀/寫FAT32硬盤,支持FAT12、FAT16
   INT21(440DH⑷1H/61H) 不可用(文檔資料中說支持FAT12、FAT16、FAT32,實際上沒有實現)
   INT21(7305H) 可以讀寫軟盤、硬盤,支持FAT12、FAT16、FAT32,但要求WIN95OSR2及以后版本
   值得1提的是上表中的INT21-⑺305H功能是專門提供用來支持FAT32的,并且用來替換INT25/INT26,對應的控制命令字是6(即VWIN32_DIOC_DOS_DRIVEINFO),它和INT13、INT25、INT26等中斷功能的1個顯著區分是:它不使用寄存器來傳遞參數(INT21-⑷40DH⑷1H/61H類同),而是使用1個稱為DISKIO的結構,寄存器EBX用來保存指向該結構的地址。DISKIO的定義以下:
   typedef struct _DISKIO {
   DWORD dwStartSector; // 要讀寫的起始扇區號
   WORD wSectors; // 要讀寫的扇區數
   DWORD dwBuffer; // 用來保存讀/寫數據的緩沖區
   }DISKIO, * PDISKIO;
  另外,在使用該功能時還需要特別設置1些寄存器,如ECX必須為⑴,用ESI來表示讀寫。下面的例子是使用該功能來實現上面的例子功能,即讀軟盤A的1個扇區。首先定義1個新的寄存器結構供本例使用:
   typedef struct _DIOC_REGISTERS{ 
   DWORD EBX; 
   DWORD EDX; 
   DWORD ECX; 
   DWORD EAX; 
   DWORD EDI; 
   DWORD ESI; 
   DWORD Flags; 
   }DIOC_REGISTERS; 
  其實該結構和上面的INT13_REGISTERS是1樣的,只不過INT13_REGISTERS將寄存器細分開了,可讀性更強些。本例從步驟上說和上面的例子相同,只有寄存器設置1步在內容上有差異。
   第1步:打開VWIN32服務。
   第2步:設置寄存器。
   DIOC_REGISTERS reg = {0};
   DISKIO dio;
   unsigned char Buffer[512];
   //設置參數結構
   dio.dwStartSector = 0;//注意:和上例不同,不是1,從0開始編號
   dio.wSectors = 1;
   dio.dwBuffer = (DWORD)Buffer;
   //設置寄存器
   reg.EAX = 0x7305; //功能上類似于INT25,絕對讀 
   reg.EBX = (DWORD)&dio;//參數結構的地址
   reg.ECX = ⑴;//必須是⑴ 
   reg.EDX = 1; //注意:和上例不同,驅動器編號變了,0--缺省 1--A、2--B、3--C 
   reg.ESI = 0; //ESI的bit0表示讀寫,0--讀、1--寫
   在寫狀態時SI的bit1--bit12,bit15必須是0,bit13、bit14、bit15共同來表示所寫數據的類型,具體見下表:
   15 14 13 類型描寫
   0 0 0 其它或不知道. 
   0 0 1 FAT數據 
   0 1 0 目錄數據 
   0 1 1 1般數據 
   1 x x 保存。bit15必須是0 
   第3步:調用API。BOOL b_ret=DeviceIoControl(hDev,6,&reg, sizeof(DIOC_REGISTERS),&reg,sizeof(DIOC_REGISTERS),&cb,0);
   第4步:關閉服務。
  可以發現,兩種方法讀到的數據完全1致。
  4、WIN2000中的磁盤扇區讀寫
   在WINNT和WIN2000中磁盤被看作1種標準裝備,可使用CreateFile象打開文件1樣打開并存取。CreateFile支持兩種方式的磁盤裝備--邏輯磁盤(格式為".C:")和物理磁盤(格式為".PHYSICALDRIVEx",其中x為數字),例如打開A:盤進行讀取操作,只要這樣:
   HANDLE hDev=CreateFile("\.A:",GENERIC_READ,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
  如果得到的句柄有效,就能夠使用ReadFile來讀取了,
   ReadFile(hDev,Buffer,512,&dwRet,0);
  讀取結束要關閉該句柄,
   CloseHandle(hDev);
  這比WIN95/98下的磁盤扇區讀取方便多了。
   另外,上面的例子是操作邏輯磁盤的,它包括軟驅、硬盤分區等;物理磁盤指的是實際的硬盤,它不關心該硬盤被分成幾個區,硬盤的編號是從0開始的,".PHYSICALDRIVE0"表示第1塊硬盤,其它依此類推。大家可能馬上會想起,利用這類機制可以對硬盤的分區表進行存取了。確切如此,此時即可以對硬盤的主引導扇區(獨立存在的1個扇區,包括分區表信息,不同于磁盤分區的BOOT區)進行操作了。
   unsigned char Buffer[512]={0};
   HANDLE hDev=CreateFile("\.PHYSICALDRIVE0",GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
   WriteFile(hDev,Buffer,512,&dwRet,0);
   CloseHandle(hDev);
  危險!!!千萬別這么做!!!
  5、1個自適應的磁盤讀寫類
   由上面的例子可以看出,不同的操作系統下對磁盤扇區的讀寫有不同的方式,為了能夠在各類操作系統下能夠使用統1的方法讀寫磁盤扇區,特設計了1個通用類。該類的設計思想以下:首先編寫各類操作系統下的磁盤扇區存取函數,然后通過GetVersionEx來判斷操作系統,進而選取對應的函數來實現磁盤扇區的讀寫。由上面的分析可知,WINDOWS操作系統對INT13的支持是最差的,所以在這里只使用INT25、INT26、INT21-⑺305等中斷調用來實現。類的定義以下:
  class CDiskInfo{
  public:
  CDiskInfo();
  ~CDiskInfo();
  private:
  HANDLE hDev;
   DWORD dwCurrentPlatform;
   void GetPlatform(); //取得操作系統,并存入變量dwCurrentPlatform
   
  BOOL Win2000_AccessSectors(WORD CMD,BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);//用于WIN2000、WINNT等操作系統,
  BOOL Int25_ReadSectors(BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);
   BOOL Int26_WriteSectors(BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);//用于WIN95之前的操作系統
   BOOL Int21_AccessSectors(WORD CMD,BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);//7305功能實現,用于WIN95OSR2、WIN98等操作系統
  public:
   //對外統1提供Read和Write操作,類內部根據平臺選用合適的函數調用
  BOOL ReadSectors(BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);
  BOOL WriteSectors(BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);
  };
  該類對外提供了兩個接口,即ReadSectors和WriteSectors,其參數是1樣的,分別是要讀寫的磁盤編號bDrive,要存取磁盤的開始扇區號dwStartSector,要讀取的扇區數wSectors和讀寫扇區數據的緩沖區lpSectBuff。這里磁盤編號是從1開始的,即1代表A:,2代表B:,3代表C:,依此類推。扇區的編號從0開始。使用時也很簡單,只要作以下聲明便可:
   BYTE Buffer[1024]; 
   CDiskInfo A;
   BOOL bRet=A.ReadSectors(1,0,2,Buffer);
   詳細情況見附帶的類文件及測試程序。
  6、補充說明
   嚴格來講,在對磁盤進行讀寫時,應當遵守以下順序:打開裝備(WIN95/98下為VWIN32服務,WIN2000下為磁盤裝備)、鎖卷、驗證卷的有效性、讀/寫、開鎖卷、關閉裝備。這里為了描寫上的簡潔,疏忽了鎖卷/開鎖卷及驗證有效性等操作。有興趣的朋友可以自行添加。
   另外,該類僅實現了邏輯驅動器的讀寫,要想實現諸如對物理硬盤的主引導扇區的讀寫,還需要其它技術,如thunk技術,即編寫兩個動態庫,1個是WIN32動態庫,1個是WIN16動態庫(thunk技術只可以用動態庫實現),其中WIN16動態庫轉到DPMI模式,調用INT13(或擴大INT13)來實現物理磁盤扇區的讀寫。有關thunk技術請參閱相干文檔資料。
   所有的例子在WIN98、WIN2000操作系統、VC6集成環境下調試通過。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产成人精品综合 | 日韩精品高清一区二区三区 | 噜噜网站 | 国产麻豆乱码精品一区二区三区 | 99在线观看视频 | 国产人成看黄久久久久久久久 | 91麻豆精品国产91久久久使用方法 | 国产亚洲精品美女久久久久久久久久 | 日韩一区二区三区四区五区 | 男女在线视频 | 久久久久久久免费 | 日韩中文在线视频 | 性一交一乱一乱一视一频 | 欧美成在线观看 | 国产精品一区二区三区久久久 | 91精品一区二区三区久久久久久 | 国产精品自在线 | 一级性黄色片 | 国产在线激情 | 一级毛片在线看 | 亚洲一区视频 | 天天拍天天操 | 麻豆久久精品 | 久久av网站 | 99爱免费视频 | 91精品一区二区三区蜜桃 | 久久h| 国产精品一二三区 | 性一交一乱一乱一视频96 | 日韩精品一区二区三区av | 亚洲精品免费网站 | 精品在线一区 | 麻豆专区一区二区三区四区五区 | 91红桃视频 | 欧美日韩国内 | 一本久久a精品一合区久久久 | 日韩av网址大全 | 欧美性一区二区 | 精品国产乱码久久久久久牛牛 | 91精品久久久久久久久久入口 | 国产成人精品一区二区在线 |