核心空間物件由物件管理器統一管理,邏輯上以命名空間組織。Device 目錄存放 IoCreateDevice 建立的裝置物件,FileSystem 目錄存放檔案系統驅動與識別器裝置物件。使用者模式透過「符號連結」映射存取核心裝置物件,如 COM1 對應 Serial0,C: 對應 HarddiskVolume4。核心建立符號連結用 IoCreateSymbolicLink,使用者模式用 DefineDosDevice。
hDevice = CreateFile("\\\\.\\IoctlTest", GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
其中 \\.\\ 對應命名空間 GLOBAL??。
IOCTL 為 4 位元組整數,由巨集 CTL_CODE 定義:
#define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)
位元分配:DeviceType (16-31)、Function (2-13)、Method (0-1)、Access (14-15)。驅動程式可定義多個 IOCTL 碼對應不同功能。
BOOL DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
LPVOID lpInBuffer, DWORD nInBufferSize,
LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
最後一個參數決定同步/非同步(需 FILE_FLAG_OVERLAPPED 開啟裝置)。同步模式下函數阻塞直到核心操作完成。
| 模式 | 特性 | 效率 |
|---|---|---|
| METHOD_BUFFERED | 輸入/輸出皆在使用者與核心緩衝區間複製 | 較低 |
| METHOD_IN_DIRECT | 輸入複製,輸出透過 MDL 直接映射 | 中等 |
| METHOD_OUT_DIRECT | 輸出透過 MDL 直接映射,輸入複製 | 中等 |
| METHOD_NEITHER | 直接傳遞使用者緩衝區位址,驅動需在該處理序內文存取 | 最高 |
MDL (Memory Descriptor List) 將使用者模式記憶體映射至核心,避免複製。Neither 模式要求驅動程式在正確的處理序內文執行。
驅動例程可能在三種內文執行:系統處理序內文、特定使用者執行緒/處理序內文、任意使用者執行緒/處理序內文。理解內文對正確存取使用者模式記憶體至關重要。
DeviceIoControl 使用。IOCTL 設計簡單功能強大,掌握控制碼定義、緩衝模式選擇與同步/非同步機制,即可實現使用者模式與核心高效互動。建議以標準範例為基礎,逐步理解相關資料結構。