ddk有些設備過濾驅動
『壹』 過濾驅動怎麼安裝
換win7的啦 就沒問題
『貳』 請教USB過濾驅動如何寫端點
本文分三部分來介紹如何構造一個簡單的USB過濾驅動程序,包括「基本原理」、「程序的實現」、「使用INF安裝」。此文的目的在於希望讀者了解基本原理後,可以使用除DDK以外最流行也最方便的驅動開發工具DriverStudio來實現一個自己的過濾驅動,並正確地安裝。
一、基本原理
我們知道,WDM(和KDM)是分層的,在構造設備棧時,IO管理器可以使一個設備對象附加到另外一個初始驅動程序創建的設備對象上。與初始設備對象相關的驅動程序決定的IRP,也將被發送到附加的設備對象相關的驅動程序上。這個被附加的驅動程序便是過濾驅動程序。如右圖,過濾驅動可以在設備棧的任何層次中插入。IO管理器發出的IRP將會沿著右圖的順序從上往下傳遞並返回。因此,我們可以使用過濾驅動程序來檢查、修改、完成它接收到的IRP,或者構造自己的IRP。
上面這種文字是很枯燥的,好在「前人」已經寫過一些範例以供我們更好地理解這些概念。讀過Waltz Oney的《Programming Windows Driver Mode》一書的讀者大概都知道Waltz Oney提供的範例中有一個關於USB過濾器(第九章)的例子,而在此基礎上,《USB Design By Example》(http://www.usb-by-example.com)的作者John Hyde實現了一個USB鍵盤過濾驅動程序,即給此程序增加了一個「攔截(Intercept)」功能來處理USB鍵盤的Report以實現特定的功能:當驅動程序在IRP_MJ_INTERNAL_DEVICE_CONTROL設置的完成常式從USB設備攔截到一個Get_Report_Descriptor時,攔截程序將此Descriptor中的USAGE值從「Keyboard」改為「UserDefined」,再返回給系統。
我們可以從這個例子中獲得一些靈感,比如,在Win2k下,鍵盤是由OS獨占訪問的,我們可以通過這種方式使之可以讓用戶自由訪問;我們也可以攔截其他Report_Descriptor,將部分鍵重新定義,以滿足特殊的要求;如果你願意再做一個用戶態的程序,你還可以將你攔截到的鍵值傳遞給你的用戶態程序,以實現象聯想、實達等國內電腦大廠出品的那些鍵盤上的各種實用的功能。
二、程序的實現
Waltz Oney和John Hyde的例子已經寫得很詳細了,讀者可以不用修改一個位元組便順利地編譯生成一個過濾驅動程序。本文的目的在於使用DriverStudio組件Driverworks來實現同樣的功能。
相信讀者讀到這篇文章時,已經對DriverStudio有了很多的了解。DriverStudio作為一個以C++為基礎的「快速」驅動開發工具,它封裝了基本上所有的DDK的函數,其集成在VC++中的DriverWizard,可以很方便地引導你完成設備驅動程序開發的全過程,能根據你的硬體種類自動生成設備驅動程序源代碼,並提供了很多范常式序。當然,這些例子中便包含一個USB Filter驅動程序的框架。在不侵犯版權的前提下,充分利用現有共享的、免費的、授權的代碼是我們的一貫作法。我們下面便以此範例為基礎來作修改。
我們的目的是做一個HID小驅動程序hisb.sys的Lower Filter,它附加在「人機介面設備」 ,通過攔截USB的Get_Report_Descriptor來修改其返回值,當它發現該Descriptor的Usage 為「Keyboard」時,將其改為「UserDefined」,如此我們便可以完全控制這只鍵盤。具體做法是,攔截IRP_MJ_INTERNAL_DEVICE_CONTROL,並檢查其IOCTL代碼及URB,如果滿足IOCTRL功能代碼為IOCTL_INTERNAL_USB_SUBMIT_URB以及URB功能代碼為URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE的條件,即上層驅動發來Get_Report_Descriptor請求時,設置一個完成常式,在這個完成常式中,我們將判斷Usage的值,將Usage由「6(Keyboard)」時,將其改為「0(UserDefined)」。
打開C:\Program Files\NuMega\DriverStudio\DriverWorks\Examples\wdm\usbfilt目錄(具體目錄依你的DriverStudio所安裝的目錄不同而不同) ,再打開工程文件usbfilt.dsw,我們先看一下代碼。
程序由兩個類組成,一個是Driver類,一個是Device類。Driver類包括:
入口函數DriverEntry:
DECLARE_DRIVER_CLASS(UsbFilterDriver, NULL)
/////////////////////////////////////////////////////////////////////
// Driver Entry
//
NTSTATUS UsbFilterDriver::DriverEntry(PUNICODE_STRING RegistryPath)
{
T << "UsbFilterDriver::DriverEntry\n";
m_Unit = 0;
return STATUS_SUCCESS;
// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(RegistryPath);
}
AddDevice函數
NTSTATUS UsbFilterDriver::AddDevice(PDEVICE_OBJECT Pdo)
{
T << "UsbFilterDriver::AddDevice\n";
UsbFilterDevice * pFilterDevice = new (
static_cast<PCWSTR>(NULL),
FILE_DEVICE_UNKNOWN,
static_cast<PCWSTR>(NULL),
0,
DO_DIRECT_IO
)
UsbFilterDevice(Pdo, m_Unit);
if (pFilterDevice)
{
NTSTATUS status = pFilterDevice->ConstructorStatus();
if ( !NT_SUCCESS(status) )
{
T << "Failed to construct UsbFilterDevice"
<< (ULONG) m_Unit
<< " status = "
<< status
<< "\n";
delete pFilterDevice;
}
else
{
m_Unit++;
}
return status;
}
else
{
T << "Failed to allocate UsbFilterDevice"
<< (ULONG) m_Unit
<< "\n";
return STATUS_INSUFFICIENT_RESOURCES;
}
}
這兩段代碼基本上和自動生成的代碼差不多。AddDevice的作用是構造一個過濾器的實例。
關鍵的代碼在Device類。在這個類里,我們把過濾器插入設備棧,並攔截IRP,用自己的完成常式來實現特定的功能。
Device構造函數
UsbFilterDevice::UsbFilterDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KWdmFilterDevice(Pdo, NULL)
{
T << "UsbFilterDevice::UsbFilterDevice\n";
// Check constructor status
if ( ! NT_SUCCESS(m_ConstructorStatus) )
{
return;
}
// Remember our unit number
m_Unit = Unit;
// initialize the USB lower device
m_Usb.Initialize(this, Pdo);
NTSTATUS status = AttachFilter(&m_Usb); //Attach the filter
if(!NT_SUCCESS(status))
{
m_ConstructorStatus = status;
return;
}
SetFilterPowerPolicy();
SetFilterPnpPolicy();
}
在DDK中,我們用IoAttachDevice將設備對象插入設備棧中。DriverStudio封裝了這個函數。在DriverStudio中,其他驅動程序需要用Initialize來初始化設備對象和介面,對於過濾驅動,我們關鍵是需要Attachfilter將其附加在堆棧中。
對於大部分如IRP_MJ_SYSTEM_CONTROL等IRP,我們所做的只需用PassThrough(Irp)將其直接往設備棧下層傳遞,不需要做任何工作。這些代碼我們就不一一列舉了。下面的部分才是本文的關鍵。
我們知道,HIDUSB.SYS是使用內部IOCTRL發出URB給USB類驅動程序(USBD)讀取數據的,那麼,HIDUSB首先必須構造一個IRP_MJ_INTERNAL_DEVICE_CONTROL,它的IOCTL功能碼為IOCTL_INTERNAL_USB_SUBMIT_URB(發出URB的內部IOCTL)。另外,因為我們要檢查並修改的是USB鍵盤某個介面的報告描述,那麼這個URB應該是URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE,如下:
NTSTATUS UsbFilterDevice::InternalDeviceControl(KIrp I)
{
T << "UsbFilterDevice::InternalDeviceControl\n";
// Pass through IOCTLs that are not submitting an URB
//不是我們感興趣的IOCTL不要理它
if (I.IoctlCode() != IOCTL_INTERNAL_USB_SUBMIT_URB)
return DefaultPnp(I);
PURB p = I.Urb(CURRENT); // get URB pointer from IRP
//不是我們感興趣的URB,也不要理它,
if (p->UrbHeader.Function !=
URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE)
return DefaultPnp(I);
//符合要求的IRP才被設置完成常式
return PassThrough(I, LinkTo(DeviceControlComplete), this);
}
在設置好條件以後,再來實現完成常式。所有的檢查、修改等動作都是在完成常式裡面完成的。
NTSTATUS UsbFilterDevice::DeviceControlComplete(KIrp I)
{
PURB p = I.Urb(CURRENT);
if(p)
{
//攔截到設備返回的描述表,
char* DescriptorBuffer = (char*)p->UrbControlDescriptorRequest.TransferBuffer;
//指向第三個位元組,表示設備Usage屬性的值
DescriptorBuffer += 3;
//如果值為6則改成0,6表示hid鍵盤,0表示未知設備
//在設備管理器裡面,原來的hid兼容鍵盤就不復存在了,取而代之的則是hid兼容設備
if ((*DescriptorBuffer&0xff) == 6)
*DescriptorBuffer = 0;
}
return I.Status();
}
讀者可以對照DriverWorks中的例子,直接替換掉(或者修改)上面這兩個函數,再編譯一下,便可以得到一個完整的鍵盤過濾器驅動程序。
其實,只要弄清楚了我們需要做些什麼動作,在DriverStudio裡面只需要寫少量的關鍵代碼,便可實現我們的要求,其餘的大部分工作,或有範例可供參考,或有Driver Wizard自動生成。
從上面可以看出,我們只需要修改這兩個函數,攔截合適的IRP,便可以在完成常式裡面實現我們特定的要求。正如開頭所說,我們也可以攔截其他的IRP,攔截其他的URB,或者攔截特定鍵盤的按鍵鍵值,將之傳遞到用戶態,以方便實現聯想、實達等隨機配備的多功能鍵盤的功能。
三、使用INF安裝驅動
在完成了驅動以後,還必須把它安裝到系統裡面,驅動程序才會起作用。一般來說,我們都必須為我們的驅動程序提供一個inf文件,以便於用戶安裝或者維護。對於新手來說,過濾驅動程序的inf或許有些棘手。所以,針對本文所描述的驅動,我們提供一個Win98下的安裝範例usbkey.inf,範例中「;」後的文字是註解,以方便讀者理解。
; usbkey.INF
;
; Installs Lower Level Filter for a HID keyboard device
;
; (c) Copyright 2001 SINO Co., Ltd.
;
[Version]
;」CHICAGO」表示Win9x平台
Signature="$CHICAGO$"
;鍵盤所屬類名
Class=HID
ClassGUID={745a17a0-74d3-11d0-b6fe-00a0c90f57da}
;驅動程序提供者,此信息會顯示在設備屬性的「常規」頁
Provider=%USBDBE%
LayoutFile=layout.inf
;顯示在驅動程序文件詳細資料窗口
DriverVer=11/12/2001,4.10.2222.12
;[ControlFlags]
;ExcludeFromSelect = *
;驅動程序安裝目錄,inf會將我們的驅動程序安裝到如下目錄
;記得Destinationdir後面一定要帶一個「s」
[DestinationDirs]
DefaultDestDir = 10,system32\drivers
;要增加的注冊表項
[ClassInstall]
Addreg=HIDClassReg
[HIDClassReg]
HKR,,,,%HID.ClassName%
HKR,,Icon,,-20
;製造商
[Manufacturer]
%USBDBE%=USBDBE
[USBDBE]
;我們所要附加過濾驅動程序的設備ID。這個ID可以從IC的規范上得來,也可以
;用hidview.exe讀出,或者從注冊表HKLM\Enum\hid和usb項找出
%HID.DeviceDesc% = Keypad_Inst, USB\VID_05AF&PID_0805&MI_00
;要安裝的文件和需要修改的注冊表項
;Install usbkey driver
[Keypad_Inst]
CopyFiles=Keypad_Inst.CopyFiles
AddReg=Keypad_Inst.AddReg
[Keypad_Inst.CopyFiles]
hisb.sys
hidparse.sys
hidclass.sys
usbfilt.sys
[Keypad_Inst.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,"hisb.sys"
[Keypad_Inst.HW]
AddReg=Keypad_Inst.AddReg.HW
;Lowerfilters表示是低層過濾驅動,如果是上層過濾驅動,則必須改為upperfilters
[Keypad_Inst.AddReg.HW]
HKR,,"LowerFilters",0x00010000,"usbfilt.sys"
;HID設備所需要安裝的文件和注冊表中需要修改的地方
;Install USBHIDDevice
[USBHIDDevice]
CopyFiles=USBHIDDevice.Copy
AddReg=USBHIDDevice.AddReg
[USBHIDDevice.Copy]
hidclass.sys
hisb.sys
hidparse.sys
[USBHIDDevice.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,"hisb.sys"
;以下定義需要在上面某些地方使用時替換的字元串
[strings]
USBDBE = "SINO Co., Ltd."
HID.DeviceDesc = "SINO USB MultiKeyboard"
HID.HIDDeviceDesc = "Human Interface Devices"
HID.DefaultDevice = "HID Default Device"
HID.ClassName = "Human Input Devices (HID)"
HID.SvcDesc = "Microsoft HID Class Driver"
其實最簡單的寫inf的方式,是找一些類似設備的inf文件或範例來修改。在不侵權的前提下,充分利用現有資源是我們的一貫原則。
『叄』 打開usb過濾驅動失敗,請查看設備管理器中,通用串列匯流排控制器 是否存在
這是裝了usb密碼保護復軟體制,卻沒有有效的裝載或設置完善,開機時那個設置過密碼的usb介面中的u盤不見了,造成查找提示。。
卸載軟體,重啟。
如果還恢復不了就是流氓軟體,如果想乾乾凈凈,只有重裝系統。。或者臨時使用360啟動管理,關閉啟動項中這個軟體的啟動運行及服務運行。
『肆』 台式電腦開機後顯示"打開usb過濾驅動失敗,請查看設備管理器中,通用
這是裝了抄usb密碼保護軟體,卻沒襲有有效的裝載或設置完善,開機時那個設置過密碼的usb介面中的u盤不見了,造成查找提示。。
卸載軟體,重啟。
如果還恢復不了就是流氓軟體,如果想乾乾凈凈,只有重裝系統。。或者臨時使用360啟動管理,關閉啟動項中這個軟體的啟動運行及服務運行。
『伍』 amd主板的usb過濾器驅動有什麼作用卸載了會對電腦有什麼影響
AMD的USB過濾器驅動程序是抄AMD用來提供增強USB多媒體功能的驅動,但是在Windows7操作系統下安裝VMware7後發現USB設備不能正常載入,提示31錯誤,發現是服務裡面的「VMware USB Arbitration Service」無法啟動導致,手動啟動總是報31錯誤,這就是因為系統安裝了AMD的USB過濾器驅動的原因,只要是使用AMD平台的Windows7系統應該都存在這個問題,解決問題的辦法就是把USB過濾器驅動移除。
移除USB過濾器的步驟:
開始->控制面板->卸載程序,(或者這運行對話框裡面輸入:「control」,也能進入控制面板裡面)找到」ATI Catalyst Install Manager」,右鍵點擊更改,然後選擇自定義,「下一步」後就會在第一行發現「AMD USB 過濾器驅動」,然後選擇卸載,就OK了!
『陸』 過濾驅動中打開文件時如何避免重入
在處理IRP_MJ_CREATE請求時,過濾驅動可能會使用不同的屬性/許可權等打開這個文件。這種情況經常發生在第二次調用ZwCreatefile時。這會導致生成一個對FSD 過濾驅動的回調(就是重入了).因而,正常的過濾驅動就要有能力檢測這種重入的問題。
There are several ways of dealing with reentrancy ring an IRP_MJ_CREATE operation, and the appropriate solution for your particular driver will depend upon the circumstances. In addition, there are a number of techniques that might work for a single file system filter driver, but that fail when used in a multi-filter environment.
在處理IRP_MJ_CREATE操作過程中,有幾種方法可以處理重入,處理你的驅動(中的重入)的適當方法取決於你的環境。另外,有許多種技術可以在單個文件系統過濾驅動上工作,但在多層過濾的環境下可能會失效。
For Windows XP and newer versions of Windows, the best mechanism for opening a file within the filter is to use . A filter driver can call this function and specify a given device object. The IRP_MJ_CREATE that is built will be passed to the specified device object. This technique avo
ids reentrancy issues and is the best mechanism available for a filter to open a file.
對Windows xp或者更新版的Windows來說,在過濾驅動中打開一個文件的最好方法是使用.文件過濾驅動可以調用這個函數並且指定一個給定的設備對象。
For versions of Windows prior to Windows XP, this mechanism is not available. The best mechanism in this environment is to implement your own functional equivalent of . This can be done by creating a second device object for each device you are filtering.
對Windows xp以前的Windows操作系統,這種方法無效。在這種環境下最好的方法是實現你自己的與等價的功能。這可以通過給你要過濾的設備創建第二個設備對象來實現。
For example, suppose you decide to filter some given file system device object, FSDVolumeDeviceObject. You then create a device object MyFilterDeviceObject and attach it using IoAttachDeviceToDeviceStack (of course, in Windows XP you would use instead). In addition, you create a second device object MyFilterShadowDeviceObject. This device object must be assigned a name ("DeviceMyFilterDevice27", for example). The name can be anything, but it must obviously be unique. In your device extension for your two device objects, you need to track this name, and you need to maintain pointers to the respective device objects (that is, the device extension for MyFilterShadowDeviceObject should point to MyFilterDeviceObject and the device object extension for MyFilterDeviceObject should point to yFilterShadowDeviceObject). Don't forget to set the StackSize field of the device object correctly!)
例如,假設你要過濾某個特定的文件系統設備對象,FSDVolumeDeviceObject(文件系統卷設備對象).這時你要創建一個設備對象MyFilterDeviceObject 並且使用IoAttachDeviceToDeviceStack 函數(在windows xp下使用 )來掛接它。另外,你還要創建第二個設備對象yFilterShadowDeviceObject.這個設備對象必須被指定一個名字(例如"DeviceMyFilterDevice27",注: 這里指的第二個設備對象,即Shadow device object )。名字可以是任意的,但必須唯一的。在這兩個設備的設備擴展結構中,你需要跟蹤這個名字
(注,其實就是做標志,你要知道你當前是處在哪個設備中,是第一個設備對象還是Shadow object )你需要維護一些指向相應的設備對象的指針(也就是說,MyFilterShadowDeviceObject的設備擴展要指向MyFilterDeviceObject,MyFilterDeviceObject的設備擴展對象要指向MyFilterShadowDeviceObject.不要忘了正確設置設備對象的StackSize成員變數。
Now, an IRP_MJ_CREATE request arrives in your filter, specifying MyFilterDeviceObject. To open the file without experiencing reentrancy problems, you call IoCreateFile (or ZwCreateFile). Since you must pass the name of the file being opened, you construct that by using both the name you gave MyFilterShadowDeviceObject and the name that is in the FileObject of the I/O stack Location (IoGetCurrentIr
pStackLocation(Irp)->FileObject).
現在,當IRP_MJ_CREATE 請求到達你的過濾驅動時,指定了 MyFilterDeviceObject.你調用IoCreateFile(或ZwCreateFile) 打開文件就沒有重入的問題了.以後,你必須傳遞這個打開的文件的名字,這個名字是用你設置在MyFilterShadowDeviceObject中的名字和從I/O 堆棧區域中得到的文件對象中的名字一起構造的。
Since you are passing a name in that points to your second device object, the I/O Manager will build the IRP_MJ_CREATE and pass the resulting I/O request packet to your driver, but specifying MyFilterShadowDeviceObject.
當你傳遞一個指向你的第二個設備對象的名字,I/O管理器會構建IRP_MJ_CREATE 並且傳遞I/O請求的結果到你的驅動,但指定了MyFilterShadowDeviceObject.
In your IRP_MJ_CREATE dispatch handler you must detect that this is a "shadow" device object, rather than a typical filter device object. In this case, you should send the IRP_MJ_CREATE operation down to the device being filtered by MyFilterDeviceObject. Indeed, since you should not need to do any further processing, you can use IoSkipCurrentIrpStackLocation (rather than ).
在你的IRP_MJ_CREATE 分發常式處理函數中,你必須檢測它是一個"Sahdow"設備對象而不是是一個典型的過濾設備對象。在這種情況下,你必須將IRP_MJ_CREATE操作下傳到已經被 MyFilterDeviceObject過濾了的設備中。確實,此後你不需要作進一步的處理,你可以用IoSkipCurrentIrpStackLocation函數(不是).
『柒』 如何構造一個簡單的USB過濾驅動程序
一、基本原理 我們知道,WDM(和KDM)是分層的,在構造設備棧時,IO管理器可以使一個設備對象專附加到屬另外一個初始驅動程序創建的設備對象上。與初始設備對象相關的驅動程序決定的IRP,也將被發送到附加的設備對象相關的驅動程序上。
『捌』 文件過濾驅動和磁碟過濾驅動有什麼區別
神馬狗屁老師教的啊
『玖』 (500分)DDK 和 Driver Studio,編寫設備驅動程序相關問題
DDK全名是Device Development Kit,是設備開發包的意思。
如果你要開發windows下驅動程序的話,就必須安裝DDK。
但是用DDK開發驅動程序是比較困難的,於是就有了Driver Studio,Driver Studio其實一個開發包,裡面有很多驅動開發的、調試和測試的工具。可以大大簡化Windows 平台下使用DDK開發設備驅動程序的難度。
Driver Studio下開發驅動的工具是DriverWorks ,它其實是把DDK重新進行了封裝,使用起來更加的方便了。
使用Driver Studio來開發驅動還是比較簡單的,易於入門,所以建議你用Driver Studio來開發驅動。
使用方法是先安裝VC,然後安裝DDK,然後安裝Driver Studio。
全部安裝以後還要執行一下步驟:
1、安裝好DDK後在開始菜單中有Development Kits\Windows DDK XXXX.XXXX\Checked Build Environment 點擊他,然後build -cZ
2、啟動VC6.0。在菜單 FILE|Open Workspace中打開DriverStudio\DriverWorks\Source\vdwlibs.dsw將VDWLIBS工程載入。
選擇菜單 Build|Batch Build,在彈出的對話框中選擇你想編譯的庫(一般選擇Win32相關的庫)。
然後Build。
3、在系統變數中添加一個BASEDIR的變數,變數值是安裝DDK的目錄。例如我現在安裝的是XP DDK 2600.1106,裝在了E盤,那麼目錄就是E:\WINDDK\2600.1106
然後在VC6中會多出一個DriverStudio菜單,使用裡面的DriverWizard就是創建Driver Studio的驅動工程了。
暫時就想到這么多,安裝後的具體使用,可以網路HI上找我。
用Driver Studio開發驅動建議你看看武安河的《Windows 2000/XP WDM設備驅動程序開發》這本書,這里有電子版:
http://forum.eviloctal.com/thread-32827-1-1.html
『拾』 什麼是過濾驅動
過濾驅動就是掛載在其他驅動上,對某設備的irp進行攔截過濾作用,可以對設備進行功能版擴展,或是數據加權密等的驅動程序。
比如:
1. 可以對寫入硬碟的數據做加密,然後讀取的時候解密,這樣對於用戶來說,根本不知道有加密解密的過程,然後存在硬碟上的數據是加密的。
2. 可以對已有驅動做一些擴展,或者改變已有驅動的功能。比如已有驅動一次只能寫1024位元組的數據,那麼過濾驅動可以擴展到任何長度,然後分段調用已有驅動就是了。
過濾驅動可以在功能型驅動的上面,稱之為上層過濾驅動,或者高層,反正就這個意思。過濾驅動在功能型驅動下面,稱之為下層過濾驅動。看示意圖: