最近為了撰寫ACPI Driver所以先把之前WDM Driver的筆記整理一下:
//--------------------------
// IRP 用途
//--------------------------
IRP, I/O Request Packet : 內含command, data的一組封包。系統和Driver溝通時使用。
例如AP端送出IRP,內涵IOCTL_XXXX指令,以及一些參數
對應的Driver會去分析指令然後做對應的動作:
Switch(IRP->Command)
{
case IOCTL_XXXX :
Do Somethings here
case: ...
}
//---------------------------
//WDM Driver的Entry Point
//---------------------------
NTSTATUS
DriverEntry( IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
...
//在這邊去註冊你的Routine到DriverObject資料結構內
DriverObject->DriverUnload = MyIo_Unload;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyIo_CreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyIo_Dispatcher;
...
}
//---------------------------
// WDM Driver 命名方式有兩種:
//---------------------------
1.內部名稱 (在你使用IoCreateDevice會用到) : Kernel 使用
\\Devices Kernel Mode定義
2.外部名稱(symbolic link name,給User應用程式的CreateFile使用) : User端使用
\\DosDevices
#define MYIO_NT_DEVICE_NAME L"\\Device\\MyIO"
#define MYIO_DOS_DEVICE_NAME L"\\DosDevices\\MyIO"
簡單的說就是OS 會把我們寫的Driver載入到記憶體中,然後會幫我們產生一個Driver Object資料結構在記憶體中,然後把這個資料結構位址當作參數傳給我們的DriverEntry(),接著我們就會設定資料結構中的一些函數指標指向我們Driver記憶體中的函數位址。EX: DriverObject->DriverUnload = MyIo_Unload;
當Driver Object結構設定好之後(或稱註冊)我們會去呼叫IoCreateDevice()函數,這個函數會在OS管理的Namespace中插入一個名稱,然後Kernel Driver層如果要找我們Driver時候就會去找這個名稱,而這個名稱就是內部名稱。
另外當應用程式需要對我們撰寫driver送出一些IRP的時候,其實也是透過"名稱"的方式來找到我們註冊進去的函數,然後OS才會把我們的IRP送給Driver Object內指標所指向的函數來處理,因此為了不要混亂掉,所以用另一種命名方式給應用程式使用,這就是外部名稱。
//-----------------------
// WDM Driver被載入的時機
//-----------------------
1. OpenSCM 方式
我們自己寫的Driver可以不用到到Windows目錄下,當我們需要這個Driver來使用的時候,可以透過SCM所提供的一些服務,先在登入檔SYSTEM\CurrentControlSet\Services 下面替我們的Driver建立一個鍵值,然後利用SCM 的服務去把我們的Driver載入到記憶體中,接著呼叫DriverEntry(),之後我們就可以透過AP對這個Driver 送出IRP
2. PnP Driver方式
對照 Registry 和 INF 檔,找到對應的driver,因為每個PnP Device都有自己的ID,類似PCI ID或是Vendor ID...等,當系統偵測到Device時,就會去登入檔內找到對應的Driver,所以自己撰寫的Driver也要撰寫一個xxx.inf 用來安裝這些資訊。
(1) 當系統偵測到device,就會將對應的driver載入到記憶體中,接著呼叫driver的DeviceEntry()
(2) 接著系統的PnP Manager 會去呼叫driver中的AddDevice() (註冊在Driver Object中)
(3) 處理AP的IRP或是PnP Manager 的IRP,或是Device 的INT 請求...等
3.非 PnP Driver
也是對照Registry 和INF 檔找到對應的Driver,但是與PnP Driver差別在於沒有PnP ID,因此OS不會自動找到Driver且載入Driver,而是User自己要利用新增設備(Add New Hardware Wizard)來增加Device,接著OS也是對照Registry 和INF 檔找到對應的Driver來載入到記憶體中。
1 則留言:
請問有範本怎麼寫PNP Driver嗎?
張貼留言