驅動程式 - Windows Driver Model (WDM) - 教學說明 - 7. IOCTL Buffer的使用策略



User Application和驅動程式必須定義一致的IOCTL,雙方才可以正確識別,IOCTL可以透過CTL_CODE()做定義,如下範例:

#define IOCTL_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

int __cdecl main(int argc, char **argv)
{
    ...
    DeviceIoControl(hFile, IOCTL_TEST, NULL, 0, NULL, 0, &dwRet, NULL);  
    ...
}

第三個參數用來描述Buffer的處理方式,分為Buffered、Direct和Neither三種處理方式,針對每種處理方式,司徒整理如下表格:

使用方式行為描述
METHOD_BUFFEREDI/O Manager會新增一塊跟User Buffer一樣大小的記憶體,讀寫都需要由I/O Manager負責同步更新(進行複製的動作)
METHOD_IN_DIRECT、METHOD_OUT_DIRECTI/O Manager會Mapping User Buffer到一個MDL(Memory Description List),驅動程式使用這個MDL進行操作,相較於METHOD_BUFFERED,因為資料不須由I/O Manager做複製的動作,因此,效率會比較好
METHOD_NEITHERI/O Manager會將Use Buffer Pointer,透過特殊操作後,再傳遞給驅動程式使用,因為,驅動程式可以直接存取User Buffer的資料,因此,效率是這三種方式裡面最好的一個

驅動程式必須依據Buffer的設定去存取不同欄位的Pointer,這樣才可以正確存取到User Buffer

使用方式Buffer TypeBuffer PointerBuffer Length
METHOD_BUFFEREDInput(IRP)
AssociatedIrp.SystemBuffer
(IrpStack)
Parameters.DeviceIoControl.InputBufferLength
Output(IRP)
AssociatedIrp.SystemBuffer
(IrpStack)
Parameters.DeviceIoControl.OutputBufferLength
METHOD_IN_DIRECTInput(MDL)
AssociatedIrp.SystemBuffer
(IrpStack)
Parameters.DeviceIoControl.InputBufferLength
METHOD_OUT_DIRECTOutput(MDL)
MmGetSystemAddressForMdlSafe
(IrpStack)
Parameters.DeviceIoControl.OutputBufferLength
METHOD_NEITHERInput(IrpStack)
Parameters.DeviceIoControl.Type3InputBuffer
(IrpStack)
Parameters.DeviceIoControl.InputBufferLength
Output(IRP)
UserBuffer
(IrpStack)
Parameters.DeviceIoControl.OutputBufferLength