內核編程基礎(1)

驅動對象,設備對象,IRP之間的關系?
  • 類似于程序,窗口,消息三者之間的關系;
  • 每個驅動程序只有一個驅動對象(程序實例句柄),一個驅動對象對應若干個(大于等于1個)設備對象(窗口),每個設備對象可以處理不同的IRP(I/O請求包,I/O Request Package)
IRP棧:

IRP其實本質上是由IRP頭部和IRP棧組成,一般所說的IRP只是"I/O請求包"IRP的頭部,在IRP數據結構的后面還有一個IO_STACK_LOCATION結構體數組

typedef struct _IO_STACK_LOCATION {<br />
    UCHAR MajorFunction;<br />
    UCHAR MinorFunction;<br />
    UCHAR Flags;<br />
    UCHAR Control;<br />
    //<br />
    // The following user parameters are based on the service that is being<br />
    // invoked.  Drivers and file systems can determine which set to use based<br />
    // on the above major and minor function codes.<br />
    //<br />
    union {<br />
        //<br />
        // System service parameters for:  NtCreateFile<br />
        //<br />
        struct {<br />
            PIO_SECURITY_CONTEXT SecurityContext;<br />
            ULONG Options;<br />
            USHORT POINTER_ALIGNMENT FileAttributes;<br />
            USHORT ShareAccess;<br />
            ULONG POINTER_ALIGNMENT EaLength;<br />
        } Create;</p>
<p>        //<br />
        // System service parameters for:  NtReadFile<br />
        //<br />
        struct {<br />
            ULONG Length;<br />
            ULONG POINTER_ALIGNMENT Key;<br />
            LARGE_INTEGER ByteOffset;<br />
        } Read;<br />
        //<br />
        // System service parameters for:  NtWriteFile<br />
        //<br />
        struct {<br />
            ULONG Length;<br />
            ULONG POINTER_ALIGNMENT Key;<br />
            LARGE_INTEGER ByteOffset;<br />
        } Write;</p>
<p>        //<br />
        // System service parameters for:  NtQueryInformationFile<br />
        //<br />
        struct {<br />
            ULONG Length;<br />
            FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass;<br />
        } QueryFile;<br />
        //<br />
        // System service parameters for:  NtSetInformationFile<br />
        //<br />
        struct {<br />
            ULONG Length;<br />
            FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass;<br />
            PFILE_OBJECT FileObject;<br />
            union {<br />
                struct {<br />
                    BOOLEAN ReplaceIfExists;<br />
                    BOOLEAN AdvanceOnly;<br />
                };<br />
                ULONG ClusterCount;<br />
                HANDLE DeleteHandle;<br />
            };<br />
        } SetFile;</p>
<p>        //<br />
        // System service parameters for:  NtQueryVolumeInformationFile<br />
        //<br />
        struct {<br />
            ULONG Length;<br />
            FS_INFORMATION_CLASS POINTER_ALIGNMENT FsInformationClass;<br />
        } QueryVolume;</p>
<p>        //<br />
        // System service parameters for:  NtFlushBuffersFile<br />
        //<br />
        // No extra user-supplied parameters.<br />
        //</p>
<p>        //<br />
        // System service parameters for:  NtDeviceIoControlFile<br />
        //<br />
        // Note that the user's output buffer is stored in the UserBuffer field<br />
        // and the user's input buffer is stored in the SystemBuffer field.<br />
        //<br />
        struct {<br />
            ULONG OutputBufferLength;<br />
            ULONG POINTER_ALIGNMENT InputBufferLength;<br />
            ULONG POINTER_ALIGNMENT IoControlCode;<br />
            PVOID Type3InputBuffer;<br />
        } DeviceIoControl;<br />
// end_wdm<br />
        //<br />
        // System service parameters for:  NtQuerySecurityObject<br />
        //<br />
        struct {<br />
            SECURITY_INFORMATION SecurityInformation;<br />
            ULONG POINTER_ALIGNMENT Length;<br />
        } QuerySecurity;<br />
        //<br />
        // System service parameters for:  NtSetSecurityObject<br />
        //<br />
        struct {<br />
            SECURITY_INFORMATION SecurityInformation;<br />
            PSECURITY_DESCRIPTOR SecurityDescriptor;<br />
        } SetSecurity;<br />
// begin_wdm<br />
        //<br />
        // Non-system service parameters.<br />
        //<br />
        // Parameters for MountVolume<br />
        //<br />
        struct {<br />
            PVPB Vpb;<br />
            PDEVICE_OBJECT DeviceObject;<br />
        } MountVolume;<br />
        //<br />
        // Parameters for VerifyVolume<br />
        //<br />
        struct {<br />
            PVPB Vpb;<br />
            PDEVICE_OBJECT DeviceObject;<br />
        } VerifyVolume;<br />
        //<br />
        // Parameters for Scsi with internal device contorl.<br />
        //<br />
        struct {<br />
            struct _SCSI_REQUEST_BLOCK *Srb;<br />
        } Scsi;</p>
<p>        //<br />
        // Parameters for IRP_MN_QUERY_DEVICE_RELATIONS<br />
        //<br />
        struct {<br />
            DEVICE_RELATION_TYPE Type;<br />
        } QueryDeviceRelations;<br />
        //<br />
        // Parameters for IRP_MN_QUERY_INTERFACE<br />
        //<br />
        struct {<br />
            CONST GUID *InterfaceType;<br />
            USHORT Size;<br />
            USHORT Version;<br />
            PINTERFACE Interface;<br />
            PVOID InterfaceSpecificData;<br />
        } QueryInterface;<br />
// end_ntifs<br />
        //<br />
        // Parameters for IRP_MN_QUERY_CAPABILITIES<br />
        //<br />
        struct {<br />
            PDEVICE_CAPABILITIES Capabilities;<br />
        } DeviceCapabilities;<br />
        //<br />
        // Parameters for IRP_MN_FILTER_RESOURCE_REQUIREMENTS<br />
        //<br />
        struct {<br />
            PIO_RESOURCE_REQUIREMENTS_LIST IoResourceRequirementList;<br />
        } FilterResourceRequirements;<br />
        //<br />
        // Parameters for IRP_MN_READ_CONFIG and IRP_MN_WRITE_CONFIG<br />
        //<br />
        struct {<br />
            ULONG WhichSpace;<br />
            PVOID Buffer;<br />
            ULONG Offset;<br />
            ULONG POINTER_ALIGNMENT Length;<br />
        } ReadWriteConfig;<br />
        //<br />
        // Parameters for IRP_MN_SET_LOCK<br />
        //<br />
        struct {<br />
            BOOLEAN Lock;<br />
        } SetLock;<br />
        //<br />
        // Parameters for IRP_MN_QUERY_ID<br />
        //<br />
        struct {<br />
            BUS_QUERY_ID_TYPE IdType;<br />
        } QueryId;<br />
        //<br />
        // Parameters for IRP_MN_QUERY_DEVICE_TEXT<br />
        //<br />
        struct {<br />
            DEVICE_TEXT_TYPE DeviceTextType;<br />
            LCID POINTER_ALIGNMENT LocaleId;<br />
        } QueryDeviceText;<br />
        //<br />
        // Parameters for IRP_MN_DEVICE_USAGE_NOTIFICATION<br />
        //<br />
        struct {<br />
            BOOLEAN InPath;<br />
            BOOLEAN Reserved[3];<br />
            DEVICE_USAGE_NOTIFICATION_TYPE POINTER_ALIGNMENT Type;<br />
        } UsageNotification;<br />
        //<br />
        // Parameters for IRP_MN_WAIT_WAKE<br />
        //<br />
        struct {<br />
            SYSTEM_POWER_STATE PowerState;<br />
        } WaitWake;<br />
        //<br />
        // Parameter for IRP_MN_POWER_SEQUENCE<br />
        //<br />
        struct {<br />
            PPOWER_SEQUENCE PowerSequence;<br />
        } PowerSequence;<br />
        //<br />
        // Parameters for IRP_MN_SET_POWER and IRP_MN_QUERY_POWER<br />
        //<br />
        struct {<br />
            ULONG SystemContext;<br />
            POWER_STATE_TYPE POINTER_ALIGNMENT Type;<br />
            POWER_STATE POINTER_ALIGNMENT State;<br />
            POWER_ACTION POINTER_ALIGNMENT ShutdownType;<br />
        } Power;<br />
        //<br />
        // Parameters for StartDevice<br />
        //<br />
        struct {<br />
            PCM_RESOURCE_LIST AllocatedResources;<br />
            PCM_RESOURCE_LIST AllocatedResourcesTranslated;<br />
        } StartDevice;<br />
// begin_ntifs<br />
        //<br />
        // Parameters for Cleanup<br />
        //<br />
        // No extra parameters supplied<br />
        //<br />
        //<br />
        // WMI Irps<br />
        //<br />
        struct {<br />
            ULONG_PTR ProviderId;<br />
            PVOID DataPath;<br />
            ULONG BufferSize;<br />
            PVOID Buffer;<br />
        } WMI;<br />
        //<br />
        // Others - driver-specific<br />
        //<br />
        struct {<br />
            PVOID Argument1;<br />
            PVOID Argument2;<br />
            PVOID Argument3;<br />
            PVOID Argument4;<br />
        } Others;<br />
    } Parameters;<br />
    //<br />
    // Save a pointer to this device driver's device object for this request<br />
    // so it can be passed to the completion routine if needed.<br />
    //<br />
    PDEVICE_OBJECT DeviceObject;<br />
    //<br />
    // The following location contains a pointer to the file object for this<br />
    //<br />
    PFILE_OBJECT FileObject;<br />
    //<br />
    // The following routine is invoked depending on the flags in the above<br />
    // flags field.<br />
    //<br />
    PIO_COMPLETION_ROUTINE CompletionRoutine;<br />
    //<br />
    // The following is used to store the address of the context parameter<br />
    // that should be passed to the CompletionRoutine.<br />
    //<br />
    PVOID Context;<br />
} IO_STACK_LOCATION, *PIO_STACK_LOCATION;

IRP會一層一層的傳遞,每一層都對應著一個IO_STACK_LOCATION

  • 上面那個結構體,最為重要的是一個大聯合體,其中對應著不同類型IRP所攜帶的參數
請簡述IRP與IRP棧之間的關系
  • 任何內核模式程序在創建一個IRP時,同時還創建了一個與之相關聯的IO_STACK_LOCATION結構數組;
  • 數組中的每個堆棧單元都對應一個將處理該IRP的驅動程序,堆棧單元中包含該IRP類型代碼(1)和參數信息(2)以及完成函數的地址(3)
上面一句話的總結:每個堆棧單元都對應一個驅動程序;堆棧單元中IRP包含類型、參數信息、完成函數地址.
  • IO_STACK_LOCATION內有兩個重要成員,他們分別是MajorFunction和MinorFunction,分別記錄了IRP的主類型與子類型,通過MajorFunction可以知道是什么IRP,通過MinorFunction可以知道一些子消息.
    還有一個重要的聯合體,根據不同的IRP,它會傳遞不同的消息.
IRP的處理:
  • 驅動中的請求處理都是通過I/O請求包(IRP)與派遣函數完成的
  • 當我們在用戶層調用CreateFile,ReadFile,CloseHandle等系統API的時候,操作系統則會產生與之對應的IRP_MJ_CREATE,IRP_MJ_READ,IRP_MJ_CLOSE,并發送到相應的設備
  • Windows中的設備有:


    image.png
MDL(內存描述表)
  • 內存描述符表(Memory Descriptor List)是Windows未公開的一個結構,可以通過Windows提供的函數使用此結構將內存重新映射,并指定我們自己的內存屬性.
小結:MDL功能->將內存重新映射,并指定我們自己的內存屬性.
  • 當需要對其他模塊的內存空間進行操作時,微軟可以確保MDL的讀寫操作不會引發其他問題
設備通訊有三種方式,哪三種,有什么區別?
  • 緩沖區設備讀寫方式:將用戶態緩沖區拷貝至內核態,在內核態使用完畢之后會再拷貝至用戶態
  • 直接讀取方式(MDL):對用戶態內存地址進程重新映射,映射到內核空間
  • 其他方式:取決于創建完設備對象之后,映射到內核空間
常見的IRP結構體中的字段有哪些,以及他們的作用?
  • PMDL MdlAddress:MDLAddress域指向一個內存描述符(MDL),描述了一個與該IO請求相關聯的用戶模式緩沖區;

  • AssociateIrp:我們WDM驅動會用到AssociatedIrp.SystemBuffer,這是一個指向系統空間的緩沖區.當使用直接IO的時候,,這個緩沖區的用途由與IRP相關的Majorfunction決定;IRP_MJ_DEVICE_CONTROL或者IRP_MJ_INTERNAL_DEVICE_CONTROL這兩類IRP,該緩沖區被作為DeviceConTrol函數的輸入緩沖區;該緩沖區的長度由IO_STACK_LOCATION結構中的Paramters.DeviceIoControl.InputBufferLehgth成員確定.

  • IOStatus(IO_STATUS_BLOCK):是一個僅包含兩個域的結構,驅動程序在最終完成請求的時候設置這個結構(這里沒有寫全。。。。。。)

目前學習了IO_STACK_LOCATION中的哪些字段,有什么作用?

MajorFunction:I/O操作的類型
MinorFunction:MajorFunction的附屬碼
Paramters:不同MajorFunction攜帶的附加信息.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,709評論 18 399
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,779評論 18 139
  • 操作系統概論 操作系統的概念 操作系統是指控制和管理計算機的軟硬件資源,并合理的組織調度計算機的工作和資源的分配,...
    野狗子嗷嗷嗷閱讀 11,991評論 3 34
  • 其實這篇文章早在16年10月份就已經開始列提綱了,后來由于沒時間就一直耽擱了。昨天下午五點半我正在...
    落十一只閱讀 893評論 0 0
  • 一份愛會出現裂痕 兩個人都要負責任 有些成長 來自承認 我終于掙脫怨與恨 年輕總習慣去爭論 要別人照我的劇本 滿身...
    班文閱讀 286評論 0 0