今天看書的時候看到了這兩個函數,開始還沒在意,以為是同一個,功能應該一樣。後來想想一樣的幹嘛還弄兩個呢,於是就查了一下,發現這兩個函數差別還蠻大的。
首先來看這兩個函數的原型:
NTSTATUS<br /> IoCallDriver(<br /> IN PDEVICE_OBJECT DeviceObject,<br /> IN OUT PIRP Irp<br /> );<br />NTSTATUS<br /> PoCallDriver(<br /> IN PDEVICE_OBJECT DeviceObject,<br /> IN OUT PIRP Irp<br /> );
除了函數名不同之外,其他都一樣。參數都是兩個,一個是裝置對象的指標,另一個是IRP請求對象的指標。傳回值也是一樣。那麼區別到底是什麼呢?
我們來看WDK Documentation上的解釋:
The IoCallDriver
routine sends an IRP to the driver associated with a
specified device object.
The PoCallDriver
routine passes a power IRP
to the
next-lower driver in the device stack. (Windows Server 2003, Windows XP, and
Windows 2000 only.)
從上面的這兩句話中可以看出:IoCallDriver這個函數向DeviceObject裝置對象的驅動對象發送一個IRP請求;而PoCallDriver函數向裝置棧中的下層裝置傳遞一個主功能號為IRP_MJ_POWER的請求,且限於特定的OS。
而且,調用IoCallDriver之前,主調驅動程式必須要為目標驅動程式建立IRP裡的I/O stack location;同時,調用時,IoCallDriver函數還會協助驅動程式將輸入參數的DeviceObject值賦給IO_STACK_LOCATION結構裡的DeviceObject成員。