WINDOWS驱动编程
自动化安装Windows驱动程序脚本
![自动化安装Windows驱动程序脚本](https://img.taocdn.com/s3/m/c401fe755b8102d276a20029bd64783e09127dfc.png)
自动化安装Windows驱动程序脚本Windows操作系统是目前广泛使用的操作系统之一,它可以适应各种硬件设备的需求。
为了使这些硬件设备能够正常工作,我们需要安装相应的驱动程序。
然而,手动安装大量驱动程序可能会非常繁琐和耗时。
为了简化这一过程,让我们来介绍一种自动化安装Windows驱动程序的脚本。
首先,我们需要一个针对Windows操作系统的批处理脚本。
我们可以使用Windows自带的文本编辑器Notepad来创建脚本文件,并将其保存为批处理文件后缀(.bat)。
接下来,我们来介绍一些常见的脚本命令和语法。
1. 注释在脚本中添加注释是一种良好的编程习惯,可以使其他人更容易理解脚本的逻辑和功能。
在批处理脚本中,我们可以使用“REM”关键字来添加注释。
例如:```REM 这是一个自动化安装Windows驱动程序的脚本示例```2. 文件路径在脚本中,我们需要指定驱动程序的文件路径。
可以使用以下命令将指定路径保存到变量中:```SET driverPath=C:\path\to\driver```在后续的命令中,可以使用%driverPath%来引用该路径。
3. 安装驱动程序使用以下命令安装指定路径下的驱动程序:```start /wait pnputil.exe -i -a %driverPath%\*.inf```这个命令使用了Windows自带的工具“pnputil.exe”,通过传递驱动程序的.inf文件路径来安装驱动程序。
4. 批量安装多个驱动程序如果有多个驱动程序需要安装,我们可以使用循环来处理。
以下是一个示例:```FOR %%f IN (%driverPath%\*.inf) DO (start /wait pnputil.exe -i -a %%f)```这个命令将遍历指定路径下的所有.inf文件,并依次安装驱动程序。
5. 错误处理在自动化脚本中,错误处理是非常重要的。
我们可以使用以下语句来检查脚本中的错误:```IF %ERRORLEVEL% NEQ 0 (REM 处理错误的逻辑)```在错误处理部分,可以输出错误信息、重新尝试安装或退出脚本。
Windows 驱动程序开发指导说明书
![Windows 驱动程序开发指导说明书](https://img.taocdn.com/s3/m/b6170bb7846a561252d380eb6294dd88d0d23dde.png)
课程内容驱动基本概念介绍驱动核心代码分析WDM和WDF介绍Windows 10通用驱动平台驱动程序是一个软件模块,可以使操作系统和硬件设备进行交互驱动程序是操作系统的一个扩展驱动程序一般是由硬件的设计者或厂商进行编写Microsoft已经为符合公共设计规范的硬件设备提供了内置的驱动程序可执行文件,扩展名是.exe入口函数是Main()Main()函数完成大部分工作应用程序完成工作后返回,并释放内存空间在用户态运行可执行文件,扩展名是.sys入口函数是DriverEntry()DriverEntry()不会做很多工作,只是初始化驱动驱动其他部分会注册很多回调函数,会被系统的不同模块调用驱动不会返回,会一直存在直至被显示的释放在内核态或用户态运行Driver StacksPDO位于驱动栈的最底层,和总线驱动相关联当总线驱动被加载时,它会枚举所有挂载在总线上面的设备并请求设备所需要的资源每个设备都有自己对应的PDOPnP管理器会确定每个设备的驱动并在设备的PDO 之上构建适当的设备栈设备栈的核心部分,FDO和设备功能驱动相关联设备功能驱动完成Windows和设备交互的核心功能对上向应用程序和服务提供上层接口对下为设备或其他驱动提供数据交换的接口一个设备栈可以包含多个FiDO,可以在FDO之上或之下每个FiDO和一个过滤驱动相关联,FiDO是可选的通常的目的是修改一些在设备栈中传输的I/O请求,例如可以加密和解密读写请求当一个新设备被插入到系统后,系统总线驱动会向PnP管理器报告这个新设备PnP管理器通过总线驱动查询这个设备的更多信息,比如设备ID和设备所需要的资源PnP管理器利用这个信息去查找是否有有对应的驱动在本地或WU(Windows Update)上面一旦查找到设备对应的驱动,Windows便会安装并加载这个驱动加载驱动到地址空间解析驱动中引入的函数-调用其他模块调用驱动的入口函数(DriverEntry()),因此驱动可以注册回调函数调用AddDevice(),驱动此时可以创建一个“设备对象”,并将这个对象加入到设备栈中所有的事物在驱动框架中都是用对象呈现的(驱动,设备,请求等等)对象拥有属性,方法和事件WDF 对象方法属性事件操作对象的函数被WDF 框架调用用于通知某些事件设置或获取单个属性值的方法Driver (WDFDRIVER)Device (WDFDEVICE)Device (WDFDEVICE)Queue (WDFQUEUE)Queue (WDFQUEUE)……ObjectOperation方法:Status = Wdf Device Create ();属性:Cannot failWdfInterrupt Get Device();WdfInterrupt Set Policy();Can fail:Status = WdfRegistry Assign Value();Status = WdfRegistry Query Value();Status = WdfRequest Retrieve InputBuffer();回调事件:PFN_WDF_INTERRUPT_ENABLE EvtInterruptEnable初始化宏:WDF_XXX_CONFIG_INITWDF_XXX_EVENT_CALLBACKS_INIT当驱动被加载时,DriverEntry是第一个被操作系统调用的函数WdfDriverCreate( RawDriverObject, […] , attributes, &driver )NTSTATUS DriverEntry(_In_PDRIVER_OBJECT DriverObject ,_In_PUNICODE_STRING RegistryPath ) {[…]// Create WDF Driver ObjectWDF_OBJECT_ATTRIBUTES_INIT(&attributes);attributes.EvtDriverUnload = OnDriverUnload;WDF_DRIVER_CONFIG_INIT(&config, OnDeviceAdd);status = WdfDriverCreate(DriverObject ,RegistryPath ,&attributes,&config,&driver );}WDF EventWDF MethodWDF ObjectDeclare vars这是一个过滤驱动程序吗?驱动程序是电源管理策略的所有者吗?为设备对象创建I/O队列创建辅助对象,例如计时器,工作者对象,锁等NTSTATUS OnDeviceAdd( WDFDRIVER Driver,PWDFDEVICE_INIT DeviceInit) {WDFDEVICE device;IWDFIoQueue* pDefaultQueue= NULL;DeviceInit->SetPowerPolicyOwnership(TRUE );status= WdfDeviceCreate(&DeviceInit,&deviceAttributes, &device);context = GetContext(device);context->WdfDevice= device;status = pIWDFDevice->CreateIoQueue(NULL, TRUE, WdfIoQueueDispatchParallel,TRUE, FALSE, &pDefaultQueue);return status;}Static Configuration Device CreateSetting ContextQueue Create进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)NTSTATUS OnPrepareHardware(WDFDEVICE Device ,WDFCMRESLIST ResourcesRaw ,WDFCMRESLIST ResourcesTranslated ) {int ResourceCount = WdfCmResourceListGetCount(ResourcesTranslated );for (i=0; i < ResourceCount; i++) {descriptor =WdfCmResourceListGetDescriptor(ResourcesTranslated , i);switch (descriptor->Type) {case CmResourceTypePort : […]case CmResourceTypeMemory : […]case CmResourceTypeInterrupt : […]default : break ;}}return STATUS_SUCCESS ;}进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)NTSTATUS OnD0Entry(IN WDFDEVICE Device ,IN WDF_POWER_DEVICE_STATE RecentPowerState ){PADXL345AccDevice pAccDevice = nullptr pAccDevice = GetContext(Device);WdfWaitLockAcquire(pAccDevice->m_WaitLock);I2CSensorWriteRegister(pAccDevice->m_I2CIoTarget, MY_REGISTER,MY_VALUE, sizeof (MY_VALUE) );pAccDevice->m_PoweredOn = true ;WdfWaitLockRelease(pAccDevice->m_WaitLock);return STATUS_SUCCESS ;}进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)NTSTATUS OnInterruptEnable(IN WDFINTERRUPT Interrupt,IN WDFDEVICE Device){PDEVICE_EXTENSION devExt;ULONG regUlong;PULONG intCsr;devContext = GetDeviceContext(WdfInterruptGetDevice(Interrupt) );intRegId = &devContext->IntRegisterId regVal = READ_REGISTER_ULONG( intRegId );regVal = ENABLE_INTERRUPT_BYTE( regVal );WRITE_REGISTER_ULONG( intRegId, regVal );return STATUS_SUCCESS;}进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)EvtIoResume EvtDMAEnablerFillEvtDeviceSelfManagedIoInitEvtDeviceDisarmWakeFromSxEventChildListScanForChildren EvtDeviceRemoveAddedResourcesStart power-managed queuesEvtIoResume Disarm wake signal, if it was armed. (called onlyduring power up; not called during resource rebalance)EvtDeviceDisarmWakeFromSx EvtDeviceDisarmWakeFromS0Request information about child devicesEvtChildListScanForChildren Enable DMA, if driver supports it EvtDmaEnablerSelfManagedIoStartEvtDmaEnablerEnableEvtDmaEnablerFillConnect interruptsEvtDeviceD0EntryPostInterruptsEnabledEvtInterruptEnable Notify Driver of state change EvtDeviceD0EntryDevice OperationalRestart from here if device is in low power statePrepare hardware for power EvtDevicePrepareHardwareChange resources requirements EvtDeviceRemoveAddedResourcesEvtDeviceFilterAddResourceRequirementsEvtDeviceFilterRemoveResourcRequirementsRestart from here if rebalancing resourcesCreate Device object EvtDriverDeviceAddDevice arrivedEnable self-managed I/O, if driver supports it.EvtDeviceSelfManagedIoInit (implicit power up),EvtDeviceSelfManagedIoRestart (explicit power up)Stop power-managed queuesEvtIoStop Arm wake signal, if it was not armed. (calledonly during power up; not called duringresource rebalance)EvtDeviceArmWakeFromSx EvtDeviceArmWakeFromS0Disable DMA, if driver supports it EvtDmaEnablerSelfManagedIoStopEvtDmaEnablerDisableEvtDmaEnablerFlushDisconnect interrupts EvtDeviceD0EntryPostInterruptsDisabledEvtInterruptDisableNotify Driver of state changeEvtDeviceD0Exit Device OperationalStop here if transitioning to low power stateRelease hardware EvtDeviceReleaseHardwarePurge power-managed queuesEvtIoStop Stop here if rebalancing resourcesFlush I/O if driver supports self-managedI/OEvtDeviceSelfManagedIoFlush Device removedSuspend self-managed I/O, if driver supports it.EvtDeviceSelfManagedIoSuspend Cleanup I/O buffers if driver supports self-managed i/o EvtDeviceSelfManagedIoCleanupDelete device object s context area.EvtDeviceContextCleanupEvtDeviceContextDestroyWDM和操作系统深度耦合,WDM驱动程序直接调用系统服务例程,直接操作系统数据结构WDM驱动程序全部为内核态程序,操作系统对驱动输入只做有限的检查WDF框架处理与操作系统的交互,驱动本身专注于和设备交互WDF基于对象模型和事件驱动WDF支持内核态程序和用户态程序将操作系统底层的复杂逻辑抽象化使驱动代码有可能<20行对不同的硬件设备使用相同的编程模型例如GPIO,UART,I2C,NFC,传感器驱动框架内置的日志系统为数据分析定制的工具支持上千种不同的硬件设备最初UMDF V1基于C++ COMUMDF V2使用和内核态驱动开发相同的模型和语法支持USB周边设备,传感器,NFC,智能卡,HID(包括触控)等等驱动崩溃只会影响宿主进程,不会影响整个操作系统系统重启策略可以自动恢复崩溃的UMDF驱动Windows 10提供了一系列API和DDI,对于所有的Windows平台都是通用的,被称为Universal Windows Platform(UWP) Windows通用驱动是指一个内核态或用户态的驱动并能运行在所有基于UWP的系统上面Windows通用驱动只能调用属于UWP部分的DDI,这部分DDI会在MSDN文档中标记为Universal确定你的驱动是否支持UWP,把你的驱动标记为通用驱动然后重新编译在Visual Studio中打开驱动项目工程在配置选项中把操作系统选择为Windows 10在工程属性中把目标平台改为“通用”,其他选项还有“桌面”和“手机”重新编译驱动,这时可以会出现一些链接器错误尝试修复这些错误,对于出现错误的API,请参考文档是否有通用平台的API可以替代,如果没有,您可能需要重新设计你的驱动KMDF version Release method Included in this versionof Windows Drivers using it run on1.19Windows 10, version1607 WDK Windows 10, version1607Windows 10 version1607 and later,Windows Server 20161.17Windows 10, version1511 WDK Windows 10, version1511Windows 10 version1511 and later,Windows 10 Mobile,Windows 10 IoT Core,Windows Server 20161.15Windows 10 WDK Windows 10Windows 10 for desktop editions, Windows 10 Mobile, IoT Core, Windows Server 2016UMDF version Release method Included in this version ofWindows Drivers using it can run on2.19Windows 10, version 1607WDK Windows 10, version 1607Windows 10, version 1607 (all SKUs), Windows Server 20162.17Windows 10, version 1511WDK Windows 10, version 1511Windows 10 for desktop editions (Home, Pro, Enterprise, and Education), Windows 10 Mobile, Windows 10 IoT Core (IoT Core), Windows Server 20162.15Windows 10 WDK Windows 10Windows 10 for desktop editions, Windows 10 Mobile, IoT Core, Windows Server 2016驱动程序运行在哪个版本的操作系统上驱动程序支持的硬件类型驱动程序使用的驱动模型确定驱动程序是否使用了只有KMDF支持的功能,如果驱动程序没有使用KMDF的功能,并且驱动运行在Windows 8.1或以后的系统上,则可以迁移到UMDF 2https:///en-us/windows/hardware/drivers/wdf/wdf-porting-guide Which Drivers Can Be Ported and WhereDifferences Between WDM and WDFPreparing for PortingSteps in PortingSummary of KMDF and WDM Equivalents。
microsoft visual basic使用指南
![microsoft visual basic使用指南](https://img.taocdn.com/s3/m/caa5e6c5b8d528ea81c758f5f61fb7360a4c2b7e.png)
microsoft visual basic使用指南Microsoft Visual Basic是一种事件驱动的编程语言,广泛用于Windows操作系统中的软件开发。
它基于基本语言,但也具有许多面向对象编程的特性。
以下是使用Microsoft Visual Basic的一些重要指南:1. 安装和设置Visual Basic:首先,您需要安装Visual Studio软件包,其中包括Visual Basic。
安装后,您可以开始创建新项目并开始编写代码。
2. 学习Visual Basic语法:了解Visual Basic的语法是入门的关键。
通过学习变量、数据类型、运算符、条件语句和循环语句等基本概念,您可以开始编写简单的程序。
3. 使用IDE:Visual Basic提供了一个集成开发环境(IDE),用于编写和调试代码。
熟悉IDE的各种工具,如代码编辑器、调试器和窗体设计器,可以提高您的开发效率。
4. 编写事件处理程序:Visual Basic是一个事件驱动的编程语言,您可以编写事件处理程序来响应用户的操作。
了解如何编写按钮点击、菜单选择、文本框输入等事件处理程序是非常重要的。
5. 使用控件和窗体:Visual Basic提供了许多控件和窗体,用于构建用户界面。
了解如何在窗体上添加控件、设置属性、处理事件以及进行布局和对齐操作是重要的。
6. 数据库连接和操作:Visual Basic还支持数据库连接和操作。
学习如何连接到数据库、执行SQL查询、插入、更新和删除数据等操作是开发数据库应用程序的关键。
7. 调试和错误处理:在开发过程中,调试是一个重要的环节。
学习如何使用调试器进行单步调试、设置断点和查看变量的值等技巧可以帮助您找到并解决代码中的错误。
8. 学习其他相关技术:Visual Basic与其他技术和框架集成良好。
学习如何使用.NET框架、、Windows Forms、WPF等可以扩展您的开发能力。
windows设备驱动程序WDF开发(1)
![windows设备驱动程序WDF开发(1)](https://img.taocdn.com/s3/m/3c976fc8ab00b52acfc789eb172ded630b1c9839.png)
windows设备驱动程序WDF开发(1)武安河另外讲WDM的书是《windows 2000/xp wdm设备驱动开发》KDMF 构建在WDM之上,内核级,sys⽂件UDMF ⽤户级,dll⽂件第1章 Windows 2000和WDM驱动程序1.中断优先级(IRQL): 32个中断级别,可打断0 : PASSIVE_LEVEL, 常规线程1:APC_LEVEL, 异步调⽤过程2:DISPATCH_LEVEL, 延迟过程调⽤3~26: DIRQL, 硬件中断2. 在DISPATCH_LEVEL 运⾏代码时,访问⾮分页内存是⼀个根本原则第2章 KMDF驱动程序框架1. 环境变量结构_DEVICE_CONTEXT{}pDeviceContext = GetDeviceContext(Device);2. 创建对象的⽅法KMDF控制的对象⽣命周期:WDFDRIVER, WDFDEVICE, WDFFILEOBJECT, WDFREQUEST (IRP)3. KMDF结构1)DriverEntry:设置 EvtDeviceAdd (安装时调),WdfDriverCreate 创建驱动对象2) EvtDriverDeviceAdd: 新设备被枚举时会调⽤,职责:创建设备对象,I/O队列,GUID接⼝,事件回调例程,WdfDeviceCreate, WdfDeviceCreateDeviceInterface, WdfDeviceInitSetExclusive(DeviceInit,TRUE); // 独占,只允许⼀个应⽤打开WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchSequential); // IO为串⾏ WdfIoQueueCreate // io队列WdfDeviceCreateDeviceInterface // guid接⼝3)I/O处理例程WDF_FILEOBJECT_CONFIG_INIT(&FileConfig,EvtDeviceFileCreate, EvtFileClose, EvtFileCleanup);ioQueueConfig.EvtIoDeviceControl = PCI9056WDF_EvtIoDeviceControl; // DeviceIoControl 调⽤ioQueueConfig.EvtIoRead = PCI9056WDF_EvtIoRead; // ReadFileioQueueConfig.EvtIoWrite = PCI9056WDF_EvtIoWrite; // WriteFile第3章基本对象1. WDFREQUEST: I/O请求,即IRPWdfRequestComplete :完成请求WdfRequestCompleteWithInformation :完成请求,完成的传输字节数WdfRequestRetrieveInputBuffer: 获取输⼊缓冲器地址WdfRequestRetrieveInputMemory: 获取输⼊缓冲器地址,形式为WDFMEMORYWdfRequestRetrieveInputWdmMdl: 获取输⼊缓冲器地址,形式为MDLWdfRequestGetIoQueue:返回队列对象WdfRequestGetFileObject: 返回⽂件对象WdfRequestGetInformation: 完成的传输字节数WdfRequestCreate: 创建IO请求2. IO请求(IRP)基本操作取消IO请求:编写取消例程向下传递IO请求3. WDFQUEUE 队列, WdfIoQueueDispatchSequential 串⾏初始化默认队列 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUEWdfIoQueueCreateWdfIoQueueStart : 启动接收和分发IRPWdfIoQueueStop:暂停分发,但还接收WdfIoQueueDrain: 停⽌接收,但分发WdfIoQueuePurge: 停⽌接收,取消队列中的IRP4. WDFTIMER, WDFDPC, WDFWORKITEM, WDFMEMORY5. 数据同步1)⾃旋锁运⾏在DISPATCH_LEVEL(⾃动提升),因此不能访问分页内存WdfSpinLockCreate, WdfSpinLockAcquire, WdfSpinLockRelease2)WDFWAITLOCK 运⾏在PASSIVE_LEVEL, 同步锁WdfWaitLockCreate, WdfWaitLockAcquire, WdfWaitLockRelease6. 字符串CHAR, WCHAR, STRING, UNICODE_STRINGWDFSTRING: WdfStringCreate串处理函数:strlen之类7. 队列编程 QueueSample// 因为取消例程等要⽤环境变量,所以⽤⼀个设备对象范围同步(重要)deviceAttr.SynchronizationScope = WdfSynchronizationScopeDevice;调⽤例程,取消例程,定时器回调例程,都⽤了设备对象范围同步,所以运⾏在DISPATCH_LEVEL,不能⽤分页内存。
Windows调试工具入门7(WinDbg驱动程序源码调试)
![Windows调试工具入门7(WinDbg驱动程序源码调试)](https://img.taocdn.com/s3/m/cdc5f7ea998fcc22bcd10de2.png)
系列前面的几篇文章已经介绍过对符号路径和源码路径的设置。调试自己编写的驱动时,如 果是主控机上编译,在目标机上运行,那么一般都不需要专门设置 路径 WinDbg 就能找到正 确的符号和源文件。如果驱动不是在主控机上编译的,或者编译之后移动了源码或符号文件 就必须要进行设置。在这里我是这样设置 的:
1.准备
Windows 调试工具优于目前的其他内核调试器很重要的一点,就是能够非常方便的对自己编 写的驱动程序进行源码调试。为了能够更好的说明,我们首先需要做一些准备工作,分别编 写一个测试驱动程序和一个应用程序来使用驱动的功能。 驱动程序 首先实现一个最简单的驱动程序,除了 DriverEntry 等框架代码之外,我们添加一个 IRP_MJ_READ 的 Dispatch 例程,当应用程 序调用 ReadFile 时返回一个值递增的字节。另 外,实现两个 DeviceIoControl Code,一个调用 DbgPrint 向调试器显示信息并返回,另一 个访问非法指针造成崩溃。代码片断如下,完整的代码和编译出来的文件可以在附件中获取:
pstIrpStack = IoGetCurrentIrpStackLocation( Irp); pbyUserBuffer = (PUCHAR)Irp->UserBuffer; ulSize = pstIrpStack->Parameters.Read.Length;
if ( ulSize == 1) {
Device Object list: 82138030 kd> !devobj SrcDbgKnlDrv Device object (82138030) is for: SrcDbgKnlDrv \Driver\SrcDbgKnlDrv DriverObject 8219f5f0 Current Irp 00000000 RefCount 0 Type 00000022 Flags 000000c0 Dacl e10361f4 DevExt 00000000 DevObjExt 821380e8 ExtensionFlags (0000000000) Device queue is not busy. 如果我们的设备有附加到某个设备栈上的话,可以用!devstack 扩展命令显示设备栈的信 息。 kd> !devstack 82138030 !DevObj !DrvObj !DevExt ObjectName > 82138030 \Driver\SrcDbgKnlDrv00000000 SrcDbgKnlDrv 这里看到的输出说明 SrcDbgKnlDrv 没有附加到任何设备栈。 通过!devhandles 命令可以查看设备被打开的句柄。目前在这个地方使用的话,由于没有句 柄被打开,还看不到什么有用的信息,在后面进行演示。
Windows982000驱动程序编写方法
![Windows982000驱动程序编写方法](https://img.taocdn.com/s3/m/2529b3d0a1c7aa00b52acb73.png)
微计算机系统
微计算机系统 void doWrite(int n) // 向驱动程序中写数据 { char *buf; ULONG nWritten; int i, j; buf = (char *) malloc(n); if (buf == NULL) { printf("Failed to allocate buffer for write"); Exit(1); } // start with the mod26 letter of the number of bytes to write j = (n % 26); // load buffer with dummy data (abcdefg...) for (i=0; i<n; i++, j=(j + 1)%26) { buf[i] = 'a' + j; } 42
微计算机系统
驱动程序装载 器,可动态调 用驱动程序
28
微计算机系统
驱动程序监视器界面
29
微计算机系统
驱动程序装载器界面
30
微计算机系统
31
微计算机系统
32
微计算机系统
33
微计算机系统
34
微计算机系统
35
微计算机系统
36
2)完成应用程序和驱动程序之间的信息交换
微计算机系统
下面我们来修改有关代码,以便增加驱动程序和应 用程序之间相互通信的内容。需要增加的内容包括: a. 使用Read和Write方式分别从驱动程序读入字符和 向驱动程序写字符。 b. 使用IO控制代码方式分别从驱动程序读入字符和 向驱动程序写字符。 c. 使用IO控制代码方式向驱动程序写字符串再从驱动 程序中读出该字符串,并返回反馈串信息。 注意:程序中暗红色显示的部分是我们添加或修改 过的语句,其他是DriverWorks自动生成的。语句中 “t<< xxxxx”这样的语句是向调试软件输出信息,该 信息可以再DriverMonitor或其他调试监视器中看到。
Windows磁盘驱动基础教程
![Windows磁盘驱动基础教程](https://img.taocdn.com/s3/m/245e7d6eb84ae45c3b358c4e.png)
在存储设备驱动(storage driver)中,与实际的硬件设备打交道的驱动称为微端口(miniport)驱动,而更上层的驱动称为类驱动(class driver)。这里说的磁盘驱动(disk driver)是一个类驱动。类驱动具体功能通过下层的微端口驱动实现。而自己则抽象出一类设备(如磁盘),供文件系统驱动调用。这样,文件系统就不用自己去和硬件细节打交道了,在它看来所有的磁盘都是一个磁盘设备。这就是类驱动存在的意义。
list_lock是为了保证链表读写同步的锁。
request_event是一个事件。当链表中没有请求的时候,处理请求的系统线程并不做任何事情,而只等待这个事件。当有请求到来,我们把请求放入链表,然后设置这个事件。处理线程就会开始处理这些请求。
thread_pointer是线程的指针,用来最后等待这个线程的结束。
(3)你必然要在磁盘设备对象上保留一些私人信息,因此不能把设备扩展大小设置为0。你应该定义设备扩展的数据结构。当然这要看你的需要了。
(4)你还需要设置一些设备标志。
* * *
IN PIRP Irp
);
DeviceObject是接受请求的设备对象指针,应该是由你的驱动生成的,所以才会发到你的驱动的分发例程。Irp是请求包指针。里边含有请求相关的信息。最后返回执行的结果(成功或者错误代码)。
从FileDisk看来,分发例程比文件系统驱动要简单得多。DriverObject->DriverUnload是一个特殊的例程,在windows卸载你的驱动的时候被调用。你可以在其中删除设备,关闭打开的文件等等。
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
media_in_device是指这个设备是否已经指定了一个文件作为存储媒质。这是一个用文件来虚拟磁盘的驱动。那么一个磁盘应该对应一个实际存在的文件。读写这个磁盘的请求最终转变为对文件的读写。如果一个磁盘设备对象还没有指定文件,那么这个内容是FALSE.
Windows驱动程序开发环境配置
![Windows驱动程序开发环境配置](https://img.taocdn.com/s3/m/2d8d8610f18583d0496459be.png)
Windows驱动程序开发笔记一、WDK与DDK环境最新版的WDK 微软已经不提供下载了这里:https:/// 可以下并且这里有好多好东东!不要走进一个误区:下最新版的就好,虽然最新版是Windows Driver Kit (WDK) 7_0_0,支持windows7,vista 2003 xp等但是它的意思是指在windows7操作系统下安装能编写针对windows xp vista的驱动程序,但是不能在xp 2003环境下安装Windows Driver Kit (WDK) 7_0_0这个高版本,否则你在build的时候会有好多好多的问题.上文build指:首先安装好WDK/DDK,然后进入"开始"->"所有程序"->"Windows Driver Kits"->"WDK XXXX.XXXX.X" ->"Windows XP"->"x86 Checked Build Environment"在弹出来的命令行窗口中输入"Build",让它自动生成所需要的库如果你是要给xp下的开发环境还是老老实实的找针对xp的老版DDK吧,并且xp无WDK 版只有DDK版build自己的demo 有个常见问题: 'jvc' 不是内部或外部命令,也不是可运行的程序。
解决办法:去掉build路径中的空格。
二、下载 WDK 开发包的步骤1、访问Microsoft Connect Web site站点2、使用微软 Passport 账户登录站点3、登录进入之后,点击站点目录链接4、在左侧的类别列表中选择开发人员工具,在右侧打开的类别:开发人员工具目录中找到Windows Driver Kit (WDK) and Windows Driver Framework (WDF)并添加到您的控制面板中5、添加该项完毕后,选择您的控制面板,就可以看到新添加进来的项了。
Windows下设备驱动程序的开发方法
![Windows下设备驱动程序的开发方法](https://img.taocdn.com/s3/m/cfc1e2d1dbef5ef7ba0d4a7302768e9951e76e25.png)
目录一、驱动开发环境的搭建 (1)1.1 关于DDK (1)1.2 关于驱动程序的编译 (1)1.3关于驱动程序的运行 (2)二、驱动程序的结构 (3)2.1 驱动程序的头文件 (3)2.2 驱动程序的入口点 (3)2.3 创建设备例程 (4)2.4 卸载驱动例程 (5)2.5 派遣例程 (6)三、编写驱动程序的基础知识 (6)3.1 内核模式下的字符串操作 (6)3.2 内核模式下各种开头函数的区别 (8)3.3 一个示例程序 (10)3.4 补充说明 (10)四、在驱动中使用链表 (10)4.1 内存的分配与释放 (10)4.2 使用LIST_ENTRY (12)4.3 使用自旋锁 (12)五、在驱动中读写文件 (15)5.1 使用OBJECT_ATTRIBUTES (15)5.2 创建、打开文件 (16)5.3 读写文件操作 (16)5.4 文件的其它相关操作 (18)六、在驱动中操作注册表 (18)6.1 创建、打开注册表 (19)6.2 读写注册表 (20)6.3 枚举注册表 (21)七、在驱动中获取系统时间 (21)7.1 获取启动毫秒数 (21)7.2 获取系统时间 (22)八、在驱动中创建内核线程 (23)8.1 创建内核线程 (23)8.2 关于线程同步 (24)九、初探IRP (25)9.1 IRP的概念 (25)9.2 IRP的处理 (26)9.3 IRP派遣例程示例 (27)十、驱动程序与应用层的通信 (29)10.1 使用WriteFile通信 (29)10.2 使用DeviceIoControl进行通信 (32)十二、驱动程序开发实例 (33)12.1 NT驱动程序 (33)12.2 WDM驱动程序 (35)十三、参考资料 (41)一、驱动开发环境的搭建1.1 关于DDK开发驱动程序必备的一个东西就是DDK(Device Development Kit,设备驱动开发包),它跟我们在ring3常听到的SDK差不多,只不过它们分别支持开发不同的程序而已。
基于windows的c++驱动程序编写过程
![基于windows的c++驱动程序编写过程](https://img.taocdn.com/s3/m/8357fc338f9951e79b89680203d8ce2f0066653b.png)
基于windows的c++驱动程序编写过程在 Windows 操作系统上编写 C++驱动程序需要遵循特定的步骤和使用相关的工具。
以下是一般的编写过程概述:1. 选择驱动程序类型:首先,你需要确定要编写的驱动程序类型,例如设备驱动程序、文件系统驱动程序或网络驱动程序等。
不同类型的驱动程序有不同的功能和要求。
2. 了解 Windows 驱动模型:Windows 提供了两种主要的驱动模型:WDM(Windows Driver Model)和 KMDF(Kernel-Mode Driver Framework)。
WDM 是较旧的驱动模型,而 KMDF 是推荐使用的现代驱动模型。
了解所选择的驱动模型的架构和概念对于编写驱动程序非常重要。
3. 安装开发工具和头文件:你需要安装适当的开发工具,如 Visual Studio,以及相关的 Windows 驱动开发工具包(DDK)或 Windows Driver Kit(WDK)。
这些工具包提供了必要的头文件和库文件。
4. 创建驱动程序项目:使用开发工具创建一个驱动程序项目。
你可以选择创建一个空项目或使用驱动程序模板。
5. 编写驱动程序代码:根据所选择的驱动模型,编写驱动程序的功能代码。
这包括设备初始化、设备控制、数据传输等。
你需要使用相关的 Windows API 和驱动程序特定的函数来实现所需的功能。
6. 配置驱动程序属性:在项目属性中,设置驱动程序的相关属性,如驱动程序类型、版本号、制造商等。
7. 构建和调试驱动程序:使用开发工具构建驱动程序,并进行调试。
你可以使用调试器来检查代码的执行情况,并解决可能出现的问题。
8. 测试和部署驱动程序:在开发环境中测试驱动程序,确保其正常工作。
然后,你可以将驱动程序安装到实际的设备上进行测试。
需要注意的是,编写 Windows 驱动程序需要深入了解操作系统的内部机制和相关的编程概念。
此外,驱动程序的开发和调试过程可能比较复杂,需要耐心和经验。
Windows驱动开发入门
![Windows驱动开发入门](https://img.taocdn.com/s3/m/275040e9f8c75fbfc77db256.png)
接触windows驱动开发有一个月了,感觉Windows驱动编程并不像传说中的那么神秘。
为了更好地为以后的学习打下基础,记录下来这些学习心得,也为像跟我一样致力于驱动开发却苦于没有门路的菜鸟朋友们抛个砖,引个玉。
我的开发环境:Windows xp 主机+ VMW ARE虚拟机(windows 2003 server系统)。
编译环境:WinDDK6001.18002。
代码编辑工具:SourceInsight。
IDE:VS2005/VC6.0。
调试工具:WinDBG,DbgView.exe, SRVINSTW.EXE上面所有工具均来自互联网。
对于初学者,DbgView.exe和SRVINSTW.EXE是非常简单有用的两个工具,一定要装上。
前者用于查看日志信息,后者用于加载驱动。
下面从最简单的helloworld说起吧。
Follow me。
驱动程序的入口函数叫做DriverEntry(PDRIVER_OBJECT pDriverObj,PUNICODE_STRING pRegisgryString)。
两个参数,一个是驱动对象,代表该驱动程序;另一个跟注册表相关,是驱动程序在注册表中的服务名,暂时不用管它。
DriverEntry 类似于C语言中的main函数。
它跟main的差别就是,main完全按照顺序调用的方法执行,所有东西都按照程序员预先设定的顺序依次发生;而DriverEntry则有它自己的规则,程序员只需要填写各个子例程,至于何时调用,谁先调,由操作系统决定。
我想这主要是因为驱动偏底层,而底层与硬件打交道,硬件很多都是通过中断来与操作系统通信,中断的话就比较随机了。
但到了上层应用程序,我们是看不到中断的影子的。
说到中断,驱动程序中可以人为添加软中断,__asm int 3或者Int_3();前者是32位操作系统用的,后者是64位用的。
64位驱动不允许内嵌汇编。
下面是我的一个helloworld的源码:注意第16行的宏。
Windows下的接口调用方法,设备驱动方法和COM编程技术
![Windows下的接口调用方法,设备驱动方法和COM编程技术](https://img.taocdn.com/s3/m/d3cf7f601ed9ad51f11df205.png)
信息学院微机原理与接口技术自主学习报告报告名称:Windows下的接口调用方法,设备驱动方法和COM编程技术姓名:学号:专业:班级:时间:2010年6月15日星期二摘要Windows操作系统是一个采用图形界面的、多任务的操作系统。
这个系统不同于单用户的操作系统DOS,她的多任务特性,决定了系统的资源是有各个任务共享而不是独占的。
为此,Windows的体系结构也与DOS的体系结构完全相同。
AbstractWindows operating system is a graphical interface, multi-tasking operating system. This system is different from the single-user operating system, DOS, her multi-tasking features, determine the system's resources are shared in various tasks, rather than exclusive. To this end, Windows system structure and architecture of DOS is identical目录摘要...........................................................................................Abstract………………………………………………………………. 第一章Windos下的接口调用………………………………………2.1 接口调用的概念及特点……………………………………... 第二章设备驱动………………………………………………….3.1 为什么需要设备驱动………………………………………………3.2 什么是设备驱动程序…………………………………………….3.3 设备驱动程序编写简介…………………………………………….. 第三章COM编程技术…………………………………………..4.1 COM的概念……………………………………………………4.2 COM对象……………………………………………………..4.3 COM接口………………………………………………………4.31 从API到COM接口…………………………………………4.32 COM接口的定义和标识…………………………………..第四章结论………………………………………………………第一章Windos下的接口调用一、windows下的接口调用1、 Windows的体系结构在windows体系结构中,分为用户和系统内核两个不同的层次,这是windows操作系统为了对系统资源进行安全有效的管理,使用了cpu在不同运行空间的不同运行管理权,在windows系统的核心管理进程内包含虚拟内存管理、运行管理、系统任务分发管理等最重要系统的核心功能,也包括了一些与核心功能机密相关,为了提高系统效率的内核win32子系统功能。
Windows下编程实现驱动程序的安装和卸载
![Windows下编程实现驱动程序的安装和卸载](https://img.taocdn.com/s3/m/b154ef7a16fc700abb68fce2.png)
Windows下编程实现驱动程序的安装和卸载看到CreateService没有?那就就是安装驱动程序的过程。
########################################################### #####################加载一个驱动程序,主要就是,在SYSTEMCurrentControlSetServices 建一个键。
如:SYSTEMCurrentControlSetServicesTwdm1Type(1)ErrorControl(0)Start(3)多数驱动程序都是通过设置Start 的值为0, 1, 2 。
在系统启动的过程中加载驱动程序。
在win2k 下驱动程序的加载处理上述方式外,还可以在应用程序里用Service Api 实现,驱动程序的动态加载。
这时候的Start 为 3 。
所用到的Api 为:OpenSCManager, CreateService, OpenService, StartService ControlService, DeleteService, CloseServiceHandle其中需要说明的是:CreateService :他通过参数在注册表里自动创建驱动程序需要的键值。
DeleteService :他自动删除驱动程序在注册表里创的键值。
下面是一个,简单的例子:应用程序:#include "stdafx.h"#include <windows.h>#include <winsvc.h>#include <conio.h>void DelSvr( char * szSvrName ); //自动卸载驱动程序。
int main(int argc, char* argv[]){HANDLE hWdm;printf("Hello World!n");SC_HANDLE hServiceMgr, hServiceTwdm;BOOL bRtn;DWORD dwRtn, dwSize = 256;char szDir[256];if( argc > 1 ) //加任一个参数表示卸载驱动程序。
李银辉windows驱动开发教程
![李银辉windows驱动开发教程](https://img.taocdn.com/s3/m/c564f318580102020740be1e650e52ea5518ceb3.png)
李银辉windows驱动开发教程李银辉Windows驱动开发教程在计算机领域中,驱动程序是操作系统与硬件设备之间的桥梁,起到了关键的作用。
Windows操作系统中的驱动开发,是指为硬件设备编写相应的驱动程序,以实现操作系统与设备的通信和协同工作。
本篇文章将介绍李银辉编写的Windows驱动开发教程,帮助读者了解和掌握该领域的知识和技术。
一、什么是Windows驱动开发?Windows驱动开发是指为Windows操作系统编写设备驱动程序的过程。
驱动程序是操作系统的核心组成部分,负责管理和控制计算机硬件设备的工作。
通过编写驱动程序,可以实现对硬件设备的访问和控制,使其能够与操作系统无缝协同工作。
二、为什么需要学习Windows驱动开发?随着计算机技术的不断发展,硬件设备的种类和数量也在不断增加。
为了更好地支持和兼容各种硬件设备,Windows操作系统提供了丰富的驱动开发接口和工具。
学习Windows驱动开发可以帮助我们理解和掌握操作系统与硬件设备之间的交互原理,为开发高性能、高可靠性的驱动程序提供基础。
三、李银辉Windows驱动开发教程的特点作为国内著名的Windows驱动开发专家,李银辉编写的驱动开发教程具有以下特点:1.系统全面:李银辉的教程从驱动开发的基础知识开始讲解,逐步深入,涵盖了驱动程序开发的方方面面。
读者可以系统地学习和掌握驱动开发的各个环节和技术。
2.实践性强:李银辉的教程以实际案例为基础,通过编写具体的驱动程序来讲解相关的知识和技术。
读者可以通过实际的编程练习,加深对驱动开发原理和方法的理解。
3.案例丰富:李银辉的教程提供了大量的案例代码和实验,覆盖了多种设备类型和应用场景。
这些案例可以帮助读者更好地理解和应用所学知识,提升驱动开发的实际能力。
4.实用性强:李银辉的教程注重实用性,重点介绍了一些常见的驱动开发技术和工具,以及解决实际问题的方法。
读者可以通过学习这些内容,提高自己的驱动开发水平。
windows驱动开发教程
![windows驱动开发教程](https://img.taocdn.com/s3/m/9b7b6ce7ac51f01dc281e53a580216fc700a530a.png)
windows驱动开发教程Windows驱动开发是指在Windows操作系统下编写、调试和部署驱动程序的过程。
驱动程序是操作系统的核心组成部分,它负责与硬件设备通信,使得操作系统能够正确地识别、管理和控制硬件设备。
在本教程中,我们将介绍Windows驱动开发的基本概念、工具和流程。
首先,为了进行Windows驱动开发,我们需要准备好相应的开发工具。
其中最重要的工具是Windows Driver Kit(WDK),它包含了用于驱动开发的各种工具和库文件。
我们可以从微软官方网站上下载并安装最新版本的WDK。
接下来,我们需要熟悉驱动程序的基本概念。
在Windows中,驱动程序可以分为内核驱动和用户模式驱动。
内核驱动运行在操作系统的内核空间,具有更高的权限和更广泛的硬件访问能力;而用户模式驱动则运行在用户空间,通过系统调用与内核驱动进行通信。
我们需要了解如何编写和编译这两种类型的驱动程序,并了解它们的工作原理和特点。
在编写驱动程序之前,我们还需要了解一些基本的Windows内核编程概念,例如驱动对象模型(Driver Object Model)、设备对象模型(Device Object Model)和驱动程序接口(Driver Interface)。
这些概念是驱动程序的基础,对于理解和设计驱动程序非常重要。
接下来,我们将介绍如何使用WDK的工具和库文件来编写驱动程序。
我们可以使用Visual Studio编写驱动程序的源代码,并使用WDK的编译工具将源代码编译成驱动程序二进制文件。
在编译过程中,我们需要配置驱动程序的环境和依赖项,并确保编译成功。
在编写和编译驱动程序之后,我们需要进行驱动程序的调试和部署。
对于驱动程序的调试,我们可以使用WDK提供的调试工具和技术,例如Kernel-Mode Debugging和WinDbg。
对于驱动程序的部署,我们需要将驱动程序二进制文件和相关的配置文件复制到操作系统的指定目录,并注册驱动程序的信息到操作系统的驱动程序数据库。
C++第三十三篇--研究一下Windows驱动开发(一)内部构造介绍
![C++第三十三篇--研究一下Windows驱动开发(一)内部构造介绍](https://img.taocdn.com/s3/m/971cced7cf2f0066f5335a8102d276a20029607f.png)
C++第三⼗三篇--研究⼀下Windows驱动开发(⼀)内部构造介绍因为⼯作原因,需要做⼀些与⽹卡有关的测试,其中涉及到了驱动这⼀块的知识,虽然程序可以运⾏,但是不搞清楚,⼼⾥总是不安,觉得没理解清楚。
因此想看⼀下驱动开发。
查了很多资料,看到有⼈推荐Windows驱动开发技术详解这本书,因此本篇⽂章也是基于这本书进⾏学习的。
有些图⽚也是按照书上⾃⼰画的。
Windows操作系统⽰意图⾸先,需要下载相应的⼯具,将环境搭建起来,VS和WDK,由于我已经安装了VS2017,所以需要找对应版本的WDK()。
如果想要查OS的版本,可以WIN+R输⼊winver就可以看到OS的版本了,⽼版本对应链接:安装好了后就需要写⼀下程序了,参考链接:Windows架构简图Win32⼦系统将API函数转化为Native API函数。
在Native API接⼝中,已经没有了⼦系统的概念,它将这种调⽤转化为系统服务函数的调⽤。
其中,Native API穿过了⽤户模式和内核模式的界⾯,达到了内核模式。
系统服务函数通过I/O管理器将消息传递给驱动程序。
在内核模式下,执⾏体组件提供了⼤量的内核函数供驱动程序调⽤。
内核主要负责进程、线程的调度情况。
驱动程序通过硬件抽象层与具体硬件进⾏操作。
Windows API分为三类,分别是USER函数、GDI函数和KERNEL函数。
》USER函数:这类函数管理窗⼝、菜单、对话框和控件。
》GDI函数:这类函数在物理设备商执⾏绘图操作。
》KERNEL函数:这类函数管理⾮GUI资源,例如:进程、线程、⽂件和同步服务等。
可以发现Windows系统⽬录中有对应的三个系统⽂件,分别是USER32.dll、GDI32.dll和KERNEL32.dll。
这三个⽂件提供了以上三类API的接⼝。
当应⽤程序加载的时候,操作系统出了将应⽤程序加载到内存中,同时将以上三个DLL⽂件加载到内存中。
1、Native API⼤部分Win32⼦系统的API,都通过Native API实现的。
win uvc编程
![win uvc编程](https://img.taocdn.com/s3/m/15a2329cd05abe23482fb4daa58da0116c171f36.png)
win uvc编程摘要:1.引言2.UVC 编程简介3.UVC 编程环境搭建4.UVC 编程基础5.UVC 编程实例6.总结正文:Win UVC 编程是一种使用Microsoft Windows 平台的USB Video Class (UVC) 设备进行编程的方法。
UVC 是一种通用的驱动程序模型,它允许开发人员使用一种通用的API 来控制各种不同的USB 视频设备。
Win UVC 编程可以帮助开发人员轻松地实现USB 视频设备的控制和数据传输,使得开发人员可以更加专注于应用程序的开发。
要进行Win UVC 编程,首先需要安装一个适合的开发环境。
可以选择Visual Studio 作为开发环境,并安装相应的UVC 驱动程序开发工具包。
在安装完成后,可以开始编写UVC 程序。
在编写程序之前,需要了解一些UVC 编程的基础知识,包括UVC 设备枚举、设备控制、数据传输等。
了解这些知识可以帮助开发人员更好地理解UVC 编程的工作原理,并更加高效地进行编程。
在编程过程中,可以使用WinUSB API 或WDF USB 驱动程序框架来实现UVC 设备控制和数据传输。
WinUSB API 是一种方便的开发工具,它提供了简单易用的函数来控制UVC 设备。
WDF USB 驱动程序框架是一种更高级别的开发工具,它允许开发人员更加灵活地控制UVC 设备,并支持更多的功能。
在编写程序时,可以使用一些示例代码来帮助快速入门。
示例代码可以帮助开发人员更好地理解UVC 编程的工作原理,并可以作为应用程序的参考。
总结起来,Win UVC 编程是一种方便快捷的USB 视频设备编程方法。
windows驱动开发入门
![windows驱动开发入门](https://img.taocdn.com/s3/m/d1767c18c281e53a5802ff28.png)
主要应用场合
➢安全软件 ➢硬件驱动 ➢各种底层相关,特殊功能的软件
需要掌握的基础知识
➢汇编语言 ➢C语言 ➢Windows操作系统知识 ➢硬件相关知识
Windows驱动开发入门
Windows驱动简介 几个典型的Windows驱动 一个简单的Windows驱动例子 Windows驱动的开发、编译和调试 寒江独钓中的例子浅析 驱动编程中的注意点
键盘硬件
特定功能的实现
➢保护用户输入信息
在用户输入敏感信息时,从底层接管键盘输入,绕过任何之前的黑客程序, 将键盘输入直接交给用户处理。
➢更改按键功能
监视所有按键操作,在用户使用特定按键时调用特定功能。
➢可编程键盘
监视所有按键操作,遇到被编程按键后根据编程信息将此按键输入转为其它 按键或多个按键组合
➢WinDbg的设置
"C:\Program Files\Debugging Tools for Windows\windbg.exe" -k com:port=\\.\pipe\com_1,baud=115200,pipe
Windows驱动开发入门
Windows驱动简介 几个典型的Windows驱动 一个简单的Windows驱动例子 Windows驱动的开发、编译和调试 寒江独钓中的例子浅析 驱动编程中的注意点
WDK
➢获取WDK(免费)
/whdc/DevTools/WDK/WDKpkg.mspx
➢安装WDK ➢WDK相关文档
WDK编译环境
➢各种Windows版本 ➢Check build和Release build ➢Source和makefile文件 ➢命令行编译
Windows10驱动开发系列(一)环境搭建
![Windows10驱动开发系列(一)环境搭建](https://img.taocdn.com/s3/m/87e979e1162ded630b1c59eef8c75fbfc77d9468.png)
Windows10驱动开发系列(⼀)环境搭建Windows 10驱动开发系列(⼀)环境搭建1. 主机安装或者升级到windows 10系统,安装完后点击开始à设置à系统,可以查看windows版本信息,如笔者安装后查看如下:2. 主机安装vs2015,下载地址如下:安装过程较慢,请耐⼼等候,安装完成后会提⽰安装成功,之后激活vs2015。
在C:\Program Files(x86) \Microsoft Visual Studio 14.0\Common7\IDE下(笔者默认是安装在系统盘下的)双击devenv.exe启动vs2015,点击菜单栏Help->About Microsoft Visual Studio,可看到vs2015版本信息,如笔者安装后查看如下:同时点击License status会显⽰license状况,如未激活,请进⾏激活,否则试⽤期过后就⽆法使⽤vs2015了,如笔者的vs2015已经激活显⽰如下:右击此电脑->属性->⾼级系统设置,点击⾼级选项卡->环境变量,在系统变量中可以查看安装后的环境变量VS140COMNTOOLS , 如笔者查看如下:3. 安装 Windows驱动程序⼯具包 (WDK) 10安装地址:⾸先会下载wdksetup.exe,然后双击此exe进⾏安装,安装成功后打开vs2015,新建⼀个⼯程,可以看到可供创建的驱动程序模板有很多。
Applications模板:Package模板:Devices模板:WDF模板:Legacy模板:WDK 10 包含⽤于为 Windows 10⽣成、测试、调试和部署驱动程序的⼯具。
WDK 10统⼀了对移动和桌⾯设备、通⽤ Windows驱动程序的⽀持,并借助 Visual Studio提供了带有可靠部署和调试设置(包括 WinDbg)的统⼀测试体验。
在集成的环境中,你可以运⾏各种基本认证测试。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
WDM驱动程序开发之读写设备寄存器:KIoRange类2009-11-09 14:05WDM驱动程序开发之读写设备寄存器:KIoRange类收藏KIoRange类:一、OverviewKIoRange类将一系列特殊的外围总线的地址映射到CPU总线的地址空间。
CPU总线上的地址即可能在CPU的I/O空间,也可能在CPU的内存空间,这取决于平台和外围总线的控制方式。
考虑到可移植性,所有对I/O周期(I/O cycle)进行译码的设备驱动程序必须用这个类对I/O的位置(location)进行正确的访问(access)。
KIoRange是KPeripheralAddress类的派生类。
一旦映射关系建立起来,驱动程序就用KIoRange类的成员函数去控制设备的I/O寄存器。
这个类提供了8位、16位和32位I/O访问控制的函数。
这些函数是以内联(in-line)函数方式来使用的,它们调用系统内相应的宏来产生依赖于平台的代码。
对I/O位置(location)进行访问的另一种备选方案是创建一个KIoRegister 的实例。
这要通过取得一个KIoRange对象的数组元素来实现。
为了访问一系列外围总线内存空间的地址,需要用KMemoryRange类。
二、Member Functions1、KIoRange - Constructor (4 forms)构造函数【函数原型】FORM 1:KIoRange( void );FORM 2: (NTDDK Only)KIoRange(INTERFACE_TYPE IntfType,ULONG BusNumber ,ULONGLONG BaseBusAddress,ULONG Count,BOOLEAN MapToSystemVirtual =TRUE);FORM 3 (WDM):KIoRange(ULONGLONG CpuPhysicalAddress,BOOLEAN InCpuIoSpace,ULONG Count,BOOLEAN MapToSystemVirtual =TRUE);FORM 4 (WDM): (NOTE: This form is deprecated as of DriverStudio version 2.0.)KIoRange(PCM_RESOURCE_LIST pTranslatedResourceList,ULONG Ordinal=0,BOOLEAN MapToSystemVirtual =TRUE);FORM 5 (WDM):KIoRange(PCM_RESOURCE_LIST pTranslatedResourceList,PCM_RESOURCE_LIST pRawResourceList,ULONG Ordinal=0,BOOLEAN MapToSystemVirtual =TRUE);【Parameters】IntfType 指定总线类型。
列举如下:Internal, Isa, Eisa, MicroChannel, TurboChannel, PCIBus。
BusNumber 一个表示总线的整数。
这种与IntfType联合起来的表示方法当一个系统上有多条相同类型总线的时候是有意义的。
这些数以0为对照并由系统分配。
BaseBusAddress 被构造的对象所映射到的地址区域的首地址。
Count 以字节计数的地址区域大小。
MapToSystemVirtual 一个布尔值,用来指明构造函数是否要创建一个到系统非分页内存地址的映射。
CpuPhysicalAddress CPU总线上的物理地址或被翻译好的外围地址。
InCpuIoSpace 如果I/O范围在CPU总线的I/O空间则为TRUE,否则为FALSE。
细节参看KResourceAssignment::Flags。
pTranslatedResourceList 指向一个在KPnpDevice::OnStartDevice中可用的已翻译的资源列表的指针。
可以通过KIrp::TranslatedResources获得。
pRawResourceList 指向一个在KPnpDevice::OnStartDevice中可用的原始资源列表的指针。
可以通过KIrp::AllocatedResources获得。
Ordinal 序号。
从pTranslatedResourceList指向的资源列表中指定一个特殊的端口资源。
0表示第一个端口,1表示第二个端口,依次类推。
【Comments】如果用Form1,需要调用Initialize()才能建立映射。
当对象被嵌入KDevice 派生类对象时,这是一个常用的方法。
Form3和Form5只能用在WDM平台。
Form3需要一个已经译码到CPU空间的物理地址作为参数。
Form5需要一个已经译码的资源列表和一个指定列表中一个特定资源的序号。
这种形式需要从资源中提取信息来创建对象。
设置Ordinal为0可以指定列表中的第一个资源,1指定第二个,依次类推。
除了端口之外的类型列表中的资源没有被计数(not counted)。
注意:Form5要比Form4(以一个资源列表作为参数)优越,因为Form5考虑到了一个I/O端口也可能被映射到译码资源列表中的一个内存区域。
这种情况如果不考虑会在非IA-32系统上会导致一些问题。
Form5提取了必要的信息,从传进来的资源列表构建KIoRange对象。
使用成员函数ConstructorStatus()来获取构造函数的执行状态。
支撑它的底层系统服务是HalTranslateBusAddress (只对FORM 2有效) 和MmMapIoSpace。
这个函数只能在PASSIVE_LEVEL级别上被调用。
2、Initialize - Initialize or reinitialize an instance (3 forms)初始化或重新初始化KIoRange实例。
【函数原型】FORM 1: (NTDDK Only)NTSTATUS Initialize(INTERFACE_TYPE IntfType,ULONG BusNumber ,ULONGLONG BaseBusAddress,ULONG Count,BOOLEAN MapToSystemVirtual=TRUE);FORM 2 (WDM):NTSTATUS Initialize(ULONGLONG CpuPhysicalAddress,BOOLEAN InCpuIoSpace,ULONG Count,BOOLEAN MapToSystemVirtual=TRUE);FORM 3 (WDM): (NOTE: This form is deprecated as of DriverStudio version 2.0.)NTSTATUS Initialize(PCM_RESOURCE_LIST pTranslatedResourceList,ULONG Ordinal=0,BOOLEAN MapToSystemVirtual =TRUE);FORM 4 (WDM):Initialize(PCM_RESOURCE_LIST pTranslatedResourceList,PCM_RESOURCE_LIST pRawResourceList,ULONG Ordinal=0,BOOLEAN MapToSystemVirtual =TRUE);【Parameters】和【Comments】对照构造函数来看,只是当构造函数选择Form1时需要调用Initialize()进行初始化,如果构造函数采用后四种形式,那么Initialize()就没有必要了,因为Initialize的四种形式和构造函数的四种形式是一一对照的。
当然,在调用Invalidate 函数后可以调用这个函数进行重新初始化。
支撑它的底层系统服务是HalTranslateBusAddress (只对FORM 1有效) 和MmMapIoSpace。
这个函数只能在PASSIVE_LEVEL级别上被调用。
3、~KIoRange - Destructor析构函数。
【函数原型】~KIoRange( void );【Comments】支撑它的底层系统服务是MmUnmapIoSpace。
这个函数只能在PASSIVE_LEVEL级别上被调用。
4、Invalidate - Removes the object from an initialized state从已初始化的状态下删除对象。
【函数原型】VOID Invalidate( void );【Comments】这个函数是从KPeripheralAddress类继承过来的函数。
这个函数打破任何底层系统资源之间的联系,取消由构造函数和Initialize()初始化函数所建立的映射关系。
从这个状态上对象可以被重新初始化。
支撑它的底层系统服务是MmUnmapIoSpace。
析构函数在析构对象的时候调用了这个函数。
5、IsValid - Test if the object is initialized测试这个对象是否被正确的初始化了。
【函数原型】BOOLEAN IsValid( void );【Returns】如果当前KIoRange对象被正确的初始化了就返回TRUE。
【Comments】这个函数是从KPeripheralAddress类继承过来的函数。
如果对象和底层系统I/O范围(range)取得了联系就认为对象是被正确初始化了。
6、inb - Read a byte or multiple bytes (2 forms)从映射空间读一个或多个字节。
【函数原型】FORM 1:UCHAR inb( ULONG ByteOffset );FORM 2:VOID inb(ULONG ByteOffset,PUCHAR Buffer,ULONG Count);【Parameters】ByteOffset 以0为基地址的字节偏移量,从范围开始(the start of range)到目标单元的开始(the start of target location)之间的偏移。
Buffer 指向获取要读的数据的缓冲区指针。
Count 要读取的字节数。
【Returns】Form1返回的是读取的字节内容。
【Comments】Form1读单个字节,Form2从相同的I/O寄存器读多个字节。
这个函数是内联实现的(in-line),使用了恰当的系统宏来访问。
对于单个单元的访问,一个备选方案是创建一个KIoRegister类实例。
7、outb - Write a byte or multiple bytes (2 forms)向映射空间写一个或多个字节。