EMC中文网

MS-DOS Device Driver >> Assembly >> Basic

发布日期:2025-01-04 12:36    点击次数:137

MS-DOS Device Driver >> Assembly >> Basic I/O Request Packet(IRP) DOS系統決定要呼叫驅動程式做事情時,會採取兩個階段的呼叫動作,而這兩個階段的關連就是依靠ES:BX的資料(IRP),Strategy Callback副程式必須先把這個IRP保存起來,等到Interrupt Callback副程式被呼叫時,再去存取該IRP的資料。 司徒使用一個Command 0(Initialization)說明一下處理流程: Step 1. 系統將Command 0的IRP資料位址儲存在ES:BX Step 2. 系統呼叫驅動程式的Strategy Callback副程式 Step 3. 驅動程式儲存IRP的位址 Step 4. 系統呼叫驅動程式的Interrupt Callback副程式 Step 5. 驅動程式從IRP得知這是一個Command 0的命令 Step 6. 驅動程式跳到本身處理Command 0的副程式去處理 Step 7. 驅動程式處理完後並返回控制權給DOS系統 每個IRP都是經由Header和Data Structure這兩個部份組合而成,Header的Structure是固定的格式,而Data Structure的部份,則會因IRP的不同而有所改變,意思就是Data Structure的欄位不是固定的,有些IRP甚至沒有Data Structure的欄位。 為了更容易瞭解,司徒使用Command 0(Initialization)的IRP解說一下: CMD0_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD0_DATA dup(?) CMD0_IRP ends 從上面的Structure可以看出,IRP是由Header和Data兩個部份組合而成,Header的部份是固定的Structure,如下表示: IRP_HEADER struc Length db ? UnitCode db ? Command db ? Status dw ? Reserved1 dd ? Reserved2 dd ? IRP_HEADER ends Length說明IRP Header的資料長度 UnitCode代表設備的順序號碼,例如:磁碟機有兩部,第一部就是0 Command說明要處理的命令 Command DOS Driver Description 0 2.0+ Char and Block Initialization 1 2.0+ Block Media Check 2 2.0+ Block Get BIOS Parameter Block 3 2.0+ Char and Block IOCTL 4 2.0+ Char and Block Input 5 2.0+ Char Nondestructive Input 6 2.0+ Char Input Status 7 2.0+ Char Input Flush 8 2.0+ Char and Block Output 9 2.0+ Char and Block Output With Verify 10 2.0+ Char Output Status 11 2.0+ Char Output Flush 12 2.0+ Char and Block IOCTL Output 13 3.0+ Char and Block Open 14 3.0+ Char and Block Close 15 3.0+ Block Removable Media 16 3.0+ Char Output Til Busy 17 3.2+ Char and Block Undefined 18 3.2+ Char and Block Undefined 19 3.2+3.3+ BlockChar and Block Generic IOCTL 20 3.2+ Char and Block Undefined 21 3.2+ Char and Block Undefined 22 3.2+ Char and Block Undefined 23 3.2+ Block Get Logical Device 24 3.2+ Block Get Logical Device 25 5.0+ Char and Block IOCTL Query Status是驅動程式回傳給系統的狀態,如下表: Bit15 Bit14~Bit10 Bit9 Bit8 Bit7~Bit0 Error Reserved Busy Done Error Code 0 (Write protect violation) 1 (Unknown unit) 2 (Drive not ready) 3 (Unknown command) 4 (CRC error) 5 (Bad drive request structure length) 6 (Seek error) 7 (Unknown media) 8 (Sector not found) 9 (Printer out of paper) 10 (Write fault) 11 (Read fault) 12 (General failure) 13 (Reserved) 14 (Reserved) 15 (Invalid disk change) Reserved1和Reserved2則是保留欄位 Data Structure的部份則因IRP的不同而有所差異,Command 0的Data Structure如下表示: CMD0_DATA struc UnitNum db ? BreakOffset dw ? BreakSegment dw ? BPBOffset dw ? BPBSegment dw ? FirstDrive db ? CMD0_DATA ends 經由上面的解說,使用者應該對IRP有了基本的認知。 接著司徒針對那25個Command依序列出它們的IRP Structure,基本上,這部份使用者可先跳過,等之後需要使用該Command時,再回頭來參考即可。 Command 0: Initialization 初始化設定的Command,在驅動程式被載入到記憶體之後,系統會馬上傳送這個Command給驅動程式,這是驅動程式唯一可以做初始化的Command,而且使用者必須記得一點,只有該Command可以執行DOS的系統服務常式(0x01~0x0c, 0x30) CMD0_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD0_DATA dup(?) CMD0_IRP ends CMD0_DATA struc UnitNum db ? BreakOffset dw ? BreakSegment dw ? BPBOffset dw ? BPBSegment dw ? FirstDrive db ? CMD0_DATA ends Command 1: Media Check 這個命令是DOS在存取所有磁碟機前,都會先執行的命令,用以確認是否目錄或FAT資料有被更改過 CMD1_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD1_DATA dup(?) CMD1_IRP ends CMD1_DATA struc MediaDescriptor db ? RetStatus db ? CMD1_DATA ends Command 2: Get BPB Parameter 這個命令用於取得磁碟機的BPB資料 CMD2_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD2_DATA dup(?) CMD2_IRP ends CMD2_DATA struc MediaDescriptor db ? BPBArrayOffset dw ? BPBArraySegment dw ? BPBInfoOffset dw ? BPBInfoSegment dw ? CMD2_DATA ends Command 3: IOCTL Input Input Output Control(IOCTL)命令是應用程式用於跟驅動程式做為溝通傳輸的命令,所以會有Input跟Output兩種方向,DOS的系統呼叫常式44H就是用於此目的,驅動程式想要提供IOCTL命令給應用程式呼叫時,檔頭資訊中的Attribute第14位元(SUPPORT IOCTL),必須先設定為1 CMD3_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD3_DATA dup(?) CMD3_IRP ends CMD3_DATA struc MediaDescriptor db ? BufferOffset dw ? BufferSegment dw ? Count dw ? StartSectorNum dw ? CMD3_DATA ends Command 4: Input 從驅動程式讀取資料 CMD4_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD4_DATA dup(?) CMD4_IRP ends CMD4_DATA struc MediaDescriptor db ? BufferOffset dw ? BufferSegment dw ? Count dw ? StartSectorNum dw ? VolumeIDOffset dw ? VolumeIDSegment dw ? StartSector32 dd ? CMD4_DATA ends Command 5: Nondestructive Input 應用程式可以使用DOS的系統呼叫常式0B取得Input Buffer裡面的資料,但是不清除Input Buffer,如果沒有資料在Input Buffer,則設定IRP Header的Status狀態(Busy=1) CMD5_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD5_DATA dup(?) CMD5_IRP ends CMD5_DATA struc Buffer db ? CMD5_DATA ends Command 6: Input Status 取得Input Buffer的狀態,如果Input Buffer有資料,則設定IRP Header的Status狀態(Busy=0),反之則設定Busy=1,設定值是跟Nondestructive Input相反 CMD6_IRP struc Header db size IRP_HEADER dup(?) CMD6_IRP ends Command 7: Input Flush 清除驅動程式的Input Buffer CMD7_IRP struc Header db size IRP_HEADER dup(?) CMD7_IRP ends Command 8: Output 傳送資料給驅動程式 CMD8_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD8_DATA dup(?) CMD8_IRP ends CMD8_DATA struc MediaDescriptor db ? BufferOffset dw ? BufferSegment dw ? Count dw ? StartSectorNum dw ? VolumeIDOffset dw ? VolumeIDSegment dw ? StartSector32 dd ? CMD8_DATA ends Command 9: Output with Verify 基本上,這個命令跟Command 8是一樣的,差別僅在於Verify這個功能,DOS的VERIFY旗標若被ON時,該命令才會被呼叫到,該命令能夠讓驅動程式讀回剛剛被寫出的資料,用以確保資料的正確性 CMD9_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD9_DATA dup(?) CMD9_IRP ends CMD9_DATA struc MediaDescriptor db ? BufferOffset dw ? BufferSegment dw ? Count dw ? StartSectorNum dw ? VolumeIDOffset dw ? VolumeIDSegment dw ? StartSector32 dd ? CMD9_DATA ends Command 10: Output Status 此命令用以得知驅動程式的設備輸出狀態,如:印表機,假設印表機的輸出緩衝區有字元等待列印,則此命令可以得知緩衝區的狀態(透過IRP Header的Busy Status狀態得知) CMD10_IRP struc Header db size IRP_HEADER dup(?) CMD10_IRP ends Command 11: Output Flush 清除Output Bufferi CMD11_IRP struc Header db size IRP_HEADER dup(?) CMD11_IRP ends Command 12: IOCTL Output IOCTL的Ouput輸出(到驅動程式),驅動程式如要提供IOCTL命令給應用程式呼叫時,檔頭資訊中的Attribute第14位元(SUPPORT IOCTL),必須先設定為1 CMD12_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD12_DATA dup(?) CMD12_IRP ends CMD12_DATA struc MediaDescriptor db ? BufferOffset dw ? BufferSegment dw ? Count dw ? StartSectorNum dw ? CMD12_DATA ends Command 13: Open 該命令就是當應用程式開啟該驅動程式時,DOS會透過此命令呼叫該驅動程式,至於應用程式如何知道它要開啟該驅動程式的名稱為何呢?答案就是驅動程式的檔頭資訊,在檔頭資訊中,有一個DriverName的欄位,該欄位就是代表該驅動程式的名稱,應用程式只要使用該名稱開啟即可,不過大家還是要注意一點,想要支援此功能,檔頭資訊中的Attribute第11位元(支援OPEN/CLOSE/REMOVABLE MEDIA設備),必須先設定為1 CMD13_IRP struc Header db size IRP_HEADER dup(?) CMD13_IRP ends Command 14: Close 該命令就是用來關閉剛剛使用Open命令開啟的驅動程式,想要支援此功能,該驅動程式的檔頭資訊中的Attribute第11位元(支援OPEN/CLOSE/REMOVABLE MEDIA設備),必須先設定為1 CMD14_IRP struc Header db size IRP_HEADER dup(?) CMD14_IRP ends Command 15: Removable Media 這個命令提供磁片是否可以更換的訊息給應用程式,應用程式可以使用DOS系統服務常式44H來詢問磁片是否可更換(08H),想要支援此功能,檔頭資訊中的Attribute第11位元(支援OPEN/CLOSE/REMOVABLE MEDIA設備),必須先設定為1,驅動程式回應在IRP Header的Status欄位(Busy) CMD15_IRP struc Header db size IRP_HEADER dup(?) CMD15_IRP ends Command 16: Output til Busy 輸出字元並等待所有字元寫完或設備發出Busy信號為止 CMD16_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD16_DATA dup(?) CMD16_IRP ends CMD16_DATA struc MediaDescriptor db ? BufferOffset dw ? BufferSegment dw ? Count dw ? CMD16_DATA ends Command 19: Generic IOCTL 這個IOCTL命令跟IOCTL Output命令是類似的觀念,差別僅在於此命令是以控制碼的觀念傳輸給驅動程式,一般應用程式可以使用DOS系統服務常式44H並指定使用Generic IOCTL(0DH),驅動程式想要提供此命令給應用程式呼叫時,檔頭資訊中的Attribute第6位元(GENERIC IOCTL),必須先設定為1 CMD19_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD19_DATA dup(?) CMD19_IRP ends CMD19_DATA struc Major db ? Minor db ? SI dw ? DI dw ? PacketOffset dw ? PacketSegment dw ? CMD19_DATA ends Command 23: Get Logical Device 取得邏輯設備的資料 CMD23_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD23_DATA dup(?) CMD23_IRP ends CMD23_DATA struc IO db ? Command db ? RetStatus dw ? Reserved dd ? CMD23_DATA ends Command 24: Set Logical Device 設定邏輯設備的資料 CMD24_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD24_DATA dup(?) CMD24_IRP ends CMD24_DATA struc IO db ? Command db ? RetStatus dw ? Reserved dd ? CMD24_DATA ends Command 25: IOCTL Query 該命令用來詢問驅動程式是否支援某些IOCTL,一般應用程式可以呼叫DOS的系統服務常式4401H和4411H要求驅動程式執行此要求,要使用該命令功能時,檔案標頭的Attribute第7位元必須被設定為1 CMD25_IRP struc Header db size IRP_HEADER dup(?) Data db size CMD25_DATA dup(?) CMD25_IRP ends CMD25_DATA struc Major db ? Minor db ? SI dw ? DI dw ? PacketOffset dw ? PacketSegment dw ? CMD25_DATA ends 返回上一頁




Powered by EMC中文网 @2013-2022 RSS地图 HTML地图

Copyright Powered by365站群 © 2013-2024