如何构造一个简单的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小驱动程序hidusb.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(NULL), FILE_DEVICE_UNKNOWN, static_cast(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=HIDClassGUID={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.CopyFilesAddReg=Keypad_Inst.AddReg[Keypad_Inst.CopyFiles]hidusb.syshidparse.syshidclass.sysusbfilt.sys[Keypad_Inst.AddReg]HKR,,DevLoader,,*ntkernHKR,,NTMPDriver,,"hidusb.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.CopyAddReg=USBHIDDevice.AddReg[USBHIDDevice.Copy]hidclass.syshidusb.syshidparse.sys[USBHIDDevice.AddReg]HKR,,DevLoader,,*ntkernHKR,,NTMPDriver,,"hidusb.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过滤驱动程序
一、基本原理 我们知道,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小驱动程序hidusb.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(NULL), FILE_DEVICE_UNKNOWN, static_cast(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=HIDClassGUID={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.CopyFilesAddReg=Keypad_Inst.AddReg[Keypad_Inst.CopyFiles]hidusb.syshidparse.syshidclass.sysusbfilt.sys[Keypad_Inst.AddReg]HKR,,DevLoader,,*ntkernHKR,,NTMPDriver,,"hidusb.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.CopyAddReg=USBHIDDevice.AddReg[USBHIDDevice.Copy]hidclass.syshidusb.syshidparse.sys[USBHIDDevice.AddReg]HKR,,DevLoader,,*ntkernHKR,,NTMPDriver,,"hidusb.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文件或范例来修改。在不侵权的前提下,充分利用现有资源是我们的一贯原则。
键盘的驱动怎么卸载?
1、浏览电脑中的所有软件信息,针对键盘的驱动怎么卸载的问题,只需要找到要用到的我的电脑这个选项,并点击进入。2、选择需要彻底删除数据所在文件夹的具体位置,并点击进入。3、随后在文件夹的主页面中,浏览文件夹中的所有内容信息,找到需要被彻底删除的键盘驱动的文件夹。4、然后浏览桌面上的所有软件信息,找到电脑上的回收站这个软件,然后点击打开。5、随后点击拖动将需要被彻底删除的数据的文件夹,将整个文件夹整体移入到回收站中。6、随后会出现一个数据传输窗口,窗口中就会显示需要被彻底删除的数据的文件夹正在被回收站回收。7、最后等待着传输任务达到百分之百,就说明被删除的传输任务已经成功的完成,返回到总文件检查到需要被删除的数据已经被彻底删除,这样键盘的驱动就彻底卸载了。
不小心把键盘驱动删了怎么办
1. 电脑上的键盘驱动不小心几删除掉,怎么安装回来
首先你要先确认你的鼠标 键盘是不是好的!
接着你要检查你的电源是否完好!
其次再拆开底部对主板里面进行除尘!顺便检查USB插口是否有损伤!(这个步骤很重要,需要留意)
如果上诉都没问题,就卸载USB驱动重装,,
还是不行就按下面步骤进行!下面步骤都不能解决就只有送修了~
解决方法如下:
“开始菜单”-“运行”-输入命令:regedit,打开系统注册表。依次展开下面的注册表项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{36FC9E60-C465-11CF-8056-444553540000}
在右面窗口找到“upperfilter”项或“lowerfilter”项,并删除,然后进入设备管理器中把通用串行总线控制器下面的所有带黄色惊叹号的设备都卸载掉。在设备管理器的菜单中,点“操作”-“扫描检测硬件改动”,让系统自动重装一下驱动即可。
2. 我不小心把鼠标驱动卸载了,怎么办
系统一般会自带鼠标的通用驱动,他会帮你自动重新安装的。
若你鼠标现在不能用,请下载驱动人生(驱动精灵没USB外设驱动检查与安装功能),打开驱动人生,点击外设驱动,你看看那里哪些显示不正常的外设驱动都可以安装重新,正常的它会自动隐藏。
我的电脑”或者“计算机”图标上点击右键,选择“管理”,在左边的选单上选择“设备管理器”,然后选择“人体学输入设备”左边的加号,找到你的鼠标名称,在上面右键,选择
拓展:
鼠标(Mouse)是一种很常见及常用的电脑输入设备,它可以对当前屏幕上的游标进行定位,并通过按键和滚轮装置对游标所经过位置的屏幕元素进行操作。
鼠标的鼻祖于1968年出现,美国科学家道格拉斯·恩格尔巴特(Douglas Englebart)在加利福尼亚制作了第一只鼠标,因形似老鼠而得名,“鼠标”的标准称呼应该是“鼠标器”,鼠标的使用是为了使计算机的操作更加简便,来代替键盘繁琐的指令。