函式原型
下面是其中一個函式的原型:
NTSTATUS IoAttachDevice( IN PDEVICE_OBJECT SourceDevice, IN PUNICODE_STRING TargetDevice, OUT PDEVICE_OBJECT *AttachedDevice ); |
參數
SourceDevice是調用者生成的用來過濾的虛擬設備;
TargetDevice是要被綁定的目標設備。請注意這裡的TargetDevice並不是一個PDEVICE_OBJECT(DEVICE_OBJECT
是設備對象的數據結構,以P開頭的是其指針),而是一個字元串(在驅動開發中字元串用UNICODE_STRING來表示)。實際上,
這個字元串是要被綁定的設備的名字。Windows中許多設備對象是有名字的,但是並不是所有的設備對象都有名字。必須是有名字
的設備,才能用這個核心API進行綁定。 在Windows中,串口設備是有固定名字的。
這裡有一個疑問:假設這個函式綁定一個名字所對應的設備,那么如果這個設備已經被其他的設備綁定了,會怎么樣呢?
如果一個設備被其他設備綁定,它們在一起的一組設備,被稱為設備棧(之所以稱為棧,是由於和請求的傳遞方式有關)。實際上,
IoAttachDevice總是會綁定設備棧上最頂層的那個設備。
AttachedDevice是一個用來返回的指針的指針。綁定成功後,被綁定的設備指針被返回到這個地址。
前面已經提到了並不是所有的設備都有設備名字,所以依靠IoAttachDevice無法綁定沒有名字的設備。另外還有兩個API:一個是
IoAttachDeviceToDeviceStack,另一個是IoAttachDeviceToDeviceStackSafe。這兩個函式功能一樣,都是根據設備對象的
指針(而不是名字)進行綁定;區別是IoAttachDeviceToDeviceStackSafe更加安全,而且只有在Windows 2000SP4和Windows XP
以上的系統中才有。一般都使用IoAttachDeviceToDeviceStackSafe,但當試圖兼容較低版本的Windows 2000時,
應該使用IoAttachDeviceToDeviceStack。
NTSTATUS IoAttachDeviceToDeviceStackSafe( IN PDEVICE_OBJECT SourceDevice, // 過濾設備 IN PDEVICE_OBJECT TargetDevice, // 要被綁定的設備棧中的設備 IN OUT PDEVICE_OBJECT *AttachedToDeviceObject// 返回最終被綁定的設備 ); |
在Window 2000下應該使用另外一個函式IoAttachDeviceToDeviceStack,這個函式除了缺少最後一個參數之外(實際上放到返回值里了),
其他的和IoAttachDeviceToDeviceStackSafe函式相同。
PDEVICE_OBJECT IoAttachDeviceToDeviceStack( IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice ); |
這個函式返回了最終被綁定的設備指針,這也就導致了它不能返回一個明確的錯誤碼。但是如果為NULL,則表示綁定失敗了。