您现在的位置是: 首页 > 驱动程序 驱动程序

ddk开发u盘驱动_usb驱动开发

ysladmin 2024-05-31 人已围观

简介ddk开发u盘驱动_usb驱动开发       非常感谢大家聚集在这里共同探讨ddk开发u盘驱动的话题。这个问题集合涵盖了ddk开发u盘驱动的广泛内容,我将用我的知识和经验

ddk开发u盘驱动_usb驱动开发

       非常感谢大家聚集在这里共同探讨ddk开发u盘驱动的话题。这个问题集合涵盖了ddk开发u盘驱动的广泛内容,我将用我的知识和经验为大家提供全面而深入的回答。

1.TF储存卡或U盘是怎么储存数据的?

2.vs2012 可以用wdk7600 开发驱动吗

3.PCSC驱动问题?

4.什么叫 SDK ? 还有 DDK 是什么意思?

ddk开发u盘驱动_usb驱动开发

TF储存卡或U盘是怎么储存数据的?

       USB的结构与工作原理

       1.1物理结构

        USB的物理拓扑结构如图1所示。在USB2.0中,高速方式下Hub使全速和低速方式的信令环境独立出来,图2中显示了高速方式下Hub的作用。

        通过使用集线器(Hub)扩展可外接多达127个外设。USB的电缆有四根线,两根传送的是5V的电源,另外的两根是数据线。功率不大的外围设备可以直接通过USB总线供电,而不必外接电源。USB总线最大可以提供5V 500mA电流,并支持节约能源的挂机和唤醒模式。

       1.2 USB设备逻辑结构

        USB的设备可以分成多个不同类型,同类型的设备可以拥有一些共同的行为特征和工作协议,这样可以使设备驱动程序的编写变得简单一些。USB Forum在USB类规范?2?中定义了USB的设备类型,比如音频、通信、HID、HUB等设备类。

        每一个USB设备会有一个或者多个的逻辑连接点在里面?每个连接点叫端点。在USB的规范中用4位地址标识端点地址,每个设备最多有16个端点。端点0都被用来传送配置和控制信息。在NS公司的USB接口芯片USBN9602?4?中有7个端点。

        管道实现了在主机的一个内存缓冲区和设备的端点之间的数据传输,连接端点0的叫做缺省管道。管道是具有多个特征的信道,如带宽分配,包大小,管道类别以及数据流向。管道有两种类型分别是流管道(stream pipe)和消息管道(messagepipe)。流管道传输的数据包的内容不具有USB要求的结构,它是单向传输的;流管道支持批量、等时和中断传输方式。而消息管道与流管道具有不同的行为。首先,由主机发请求给USB设备,然后在适当的方向上传输数据,最后是到达一个状态阶段。为了保证三个阶段的数据传输,消息管道定义了一个数据结构使命令可靠地被识别和传输。消息管道是双向的,它只支持控制传输方式。

        对于同样性质的一组端点的组合叫做接口,如果一个设备包含不止一个接口就可以称之为复合设备(见图1)。

        对于同样类型接口的组合可以称之为配置。但是每次只能有一个配置是可用的,而一旦该配置被激活,里面的接口和端点就都同时可以使用。主机从设备发过来的描述字中来判断用的是哪个配置?哪个接口等等?而这些描述字通常是在端点0中传送的。

       1.3 USB通信分层模型

       一台主机到设备的连接需要许多层与实体之间的相互作用。USB总线接口层提供了主机和设备之间的物理/信令/包的连接。在系统软件看来,USB设备层执行的是一般的USB操作。功能接口层提供和应用软件层相对应的附加功能。分层模型如图3所示,虽然逻辑上USB设备层和功能层各自与主机上的相应层通信,但物理上都是通过USB总线接口层实现数据传输的。

       1.4 四种传输方式

        USB提供了四种传输方式,以适应各种设备的需要。这四种传输方式分别是:

        控制传输方式:控制传输是双向传输,数据量通常较小,主要用来进行查询、配置和给USB设备发送通用的命令。控制传输主要用在主计算机和USB外设中端点0之间。

        等时传输方式:等时传输提供了确定的带宽和间隔时间。它被用于时间严格并具有较强容错性的流数据传输,或者用于要求恒定的数据传送率的即时应用中。例如进行语音业务传输时,使用等时传输方式是很好的选择。

        中断传输方式:中断方式传送是单向的并且对于主机来说只有输入的方式。中断传输方式主要用于定时查询设备是否有中断数据要传送,该传输方式应用在少量的、分散的、不可预测的数据传输。键盘、游戏杆和鼠标就属于这一类型。

        大量传输方式:主要应用在没有带宽和间隔时间要求的大量数据的传送和接收,它要求保证传输。打印机和扫描仪属于这种类型。

        在开发USB设备时通过设置接口芯片中相应的寄存器使端点处于不同的工作方式。

       1.5 USB通信协议

        USB的物理协议规定了在总线上传输的数据格式,一个全速的数据帧有1500字节,而对于低速的帧有187字节。帧的作用是分配带宽给不同的数据传送方式。

        在USB2.0中又增加了几种类型的包以满足高速传输的需要。其中data类型增加了DATA2和MDATA,handshake类型增加了NYET,special类型则增加了ERR,SPLIT,PING,Reserved。

        事务是在主机和设备之间不连续地数据交换。一个事务通常由主机开始,一般分三个阶段,第一阶段发送token包,第二阶段发送是data包(可以向上也可以向下),在数据包传送完之后,就会由设备返回一个handshake包。

        当客户端程序通过一个USB管道发送或接收数据时,它首先会调用Win32API,API会发送一个IRP到USB设备驱动程序。USB设备驱动程序的任务就是把客户端的请求通过一个管道发送到外设合适的端点。为了实现这个任务,USB设备驱动程序会递交请求给总线驱动程序,总线驱动程序可以把这些请求转变成事务,然后将这些事务组合成帧在总线上传输。

       1.6 USB带宽分析举例

        在USB1.1标准中将其有效的带宽分成帧,每帧通常是1ms长。但由于USB2.0的传输速率可高达480Mbps,因此在USB2.0增加了一种微帧,它只有原来帧的1/8,这使得在传输数据时使用更小的缓冲。在完成了系统的配置信息和连接之后,USB的主机就会对不同的端点和传输方式做一个统筹安排,用来适应它的带宽。对全速和低速的端点,系统为等时和中断方式的传输保留整个带宽的90%,即占每个帧时间的90%,剩下的就安排给控制方式传送数据。在USB2.0中,对于高速的端点,则为等时和中断方式的传输保留每个微帧的80%。

        以等时传输为例,在某个配置中作为一个等时传输管道的端点,定义了它能传输的数据有效负载的长度。USB系统软件用这个长度限制去保证足够的总线时间使每帧的内容能容纳最多的数据有效负载。如果有足够的总线时间,配置才会建立。每个等时管道的数据有效负载可以是1,2,4,...,512,1023字节。

        例如,当数据包最大有效负载为512个字节时,一个全速帧(1500字节)最多可以传输2个这样的包。除去协议开销的18个字节,剩余458个字节可以用于其他事务的传输。因此每帧有效字节数为2个包的字节即1024字节,因此最大带宽为1.024Mbyte/s,每个包的有效字节占整个帧的35%。同样可推算,数据有效负载长度为64、128或256时其最大带宽值最大,为1.28Mbyte/s。

        在USB2.0高速工作方式下,每个等时管道的数据有效负载可以是1,2,4,...,2048,3072字节。当数据有效负载长度为1024时其最大带宽值最大,为5.7344Mbyte/s,每个包的有效字节占整个微帧的14%。

       2 Windows USB驱动程序接口

        USB的驱动程序和以往的直接跟硬件打交道的Win95的VxD(Virtual DeviceDriver)驱动程序不同,它属于WDM(Windows DriverModel)类型的,Win98、Win2000等操作系统均支持该类型的驱动程序。WDM首先定义了一个基本的核心驱动程序模型,处理所有类型的数据,使驱动程序模型的内核实现更加的固定。WDM驱动程序还是一种分层的程序结构,可以看做是WindowsNT驱动程序的改进,WDM驱动程序支持即插即用、电源管理和WMI(Windows ManagementInstrumentation)特性。Win98和Win2000提供了一系列的系统驱动程序,它们具有为许多标准类型设备服务所需的所有基本功能。

       Windows提供了USB的系统类驱动程序,它处理USB上的所有底层通信,这样其他驱动程序就有了一个定义好的接口可以使用。USBHub.sys是USB集线器的驱动程序。USBD.sys是USB类驱动程序,它使用图4中UHCD.sys或OpenHCI.sys分别驱动两种类型的控制器?UHCI(USB Host Controller Driver),OHCI(Open Host ControllerInterface)。当PCI枚举器发现USB主机控制器后,就会装入相关的驱动程序。

        通常一些设备都需要开发者写一个核模式的驱动程序来使硬件正常工作。在核模式下?驱动程序通过IRP(I/O Request Packet)来组织和操作一些由其他部分发过来的要求和命令。而IRP又是通过URB(USB Request Blocks)来实现的。但对于一些HID(Human Interface Device)的USB设备,象键盘、鼠标和游戏操纵杆之类的设备可以被操作系统自动识别并且支持,开发者不需要再另写驱动程序。

       3 USB接口10M以太网卡的实现

       3.1 选择器件

        目前市场上USB的接口产品有两种,一种是集成了USB接口的单片机,另一种是不带单片机的USB接口芯片。由于前者需要专用的开发机故开发成本较高,本文将介绍一种使用廉价USB接口芯片USBN9602(NS公司)加高速的51单片机实现10M以太网卡的方案。

        在做设计之前一定要计算好外设所要求的带宽和USB的速度是否匹配。一个USB以太网卡应该包括USB通信接口(USBN9602)、8051单片机以及IEEE802.3的MAC层和物理层。USBN9602在全速工作方式下可以达到12Mbit/s,采用USBN9602基本可以满足10M以太网的带宽需求。为达到较高的传输速率,USBN9602还应该用DMA方式与单片机通信。电路框图如图5所示。

       3.2 设计单片机控制程序

        对于单片机控制程序,目前没有任何厂商提供自动生成微码(firmware)的工具。USB单片机控制程序通常由三部分组成,第一、初始化单片机和所有的外围电路(包括USBN9602);第二、主循环部分,其任务是可以中断;第三、中断句柄,其任务是对时间敏感的,必须马上执行。

       3.3 开发USB网卡驱动程序

        开发USB设备驱动程序通常采用WindowsDDK来实现,但现在有许多第三方软件厂商提供了各种各样的生成工具,象Compuware的Driver Works,BlueWaters的DriverWizard等软件能够方便地生成高质量的USB的驱动程序。没有DDK或WDM基础的开发人员可使用KRFTech公司的开发软件WinDriver,它的最新版本4.32已经支持USB驱动程序的开发。最后的驱动程序调试工作可以使用Compuware的Softice或Microsoft的Windows Debugger来进行。

        Windows下的网卡驱动程序需符合NDIS规范(Network Driver Interface Specification)。网络驱动程序不直接调用操作系统的例程,而是通过NDIS进行系统调用,NDIS还根据需要调用了驱动程序提供的例程,共同完成网卡的功能。

        USB网卡驱动程序可分为NDIS中间介质小端口驱动程序和USB驱动程序两部分,然后将两部分驱动程序动态连接。如果USB设备未连接和被禁止,使USB驱动不可用,那么NDIS驱动会返回一个NOT_AVAILABLE的状态。这种实现方法可以保证用户不必重新安装NDIS或重启就可以连接或拔掉USB设备。

vs2012 可以用wdk7600 开发驱动吗

       #include <vcl.h>

       #include <dir.h>

       #include <setupapi.h>

       #include "C:/WINDDK/3790/inc/ddk/w2k/usbdi.h"

       #include "C:/WINDDK/3790/inc/ddk/w2k/devioctl.h"

       #include <initguid.h>

       //---------------------------------------------------------------------------

       // DEFINE_GUID(USB_DRIVER_GUID, 0x12345678,0xabcd,0x1122,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00);

       //---------------------------------------------------------------------------

       HANDLE OpenOneDevice(HDEVINFO hDvcInfo, PSP_INTERFACE_DEVICE_DATA DvcInfoData, char *sDevNameBuf)

       {

        HANDLE hOut = INVALID_HANDLE_VALUE;

        ULONG iReqLen = 0;

        SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, NULL, 0, &iReqLen, NULL);

        ULONG iDevDataLen = iReqLen; //sizeof(SP_FNCLASS_DEVICE_DATA) + 512;

        PSP_INTERFACE_DEVICE_DETAIL_DATA pDevData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(iDevDataLen);

        pDevData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

        if(SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL))

        {

        strcpy(sDevNameBuf, pDevData->DevicePath);

        hOut = CreateFile(pDevData->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

        }

        free(pDevData);

        return hOut;

       }

       //---------------------------------------------------------------------------

       HANDLE OpenUsbDevice(const GUID *pGuid, char *sDevNameBuf)

       {

        HANDLE hOut = INVALID_HANDLE_VALUE;

        HDEVINFO hDevInfo = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

        SP_INTERFACE_DEVICE_DATA deviceInfoData;

        deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);

        ULONG nGuessCount = MAXLONG;

        for(ULONG iDevIndex=0; iDevIndex<nGuessCount; iDevIndex++)

        {

        if(SetupDiEnumDeviceInterfaces(hDevInfo, 0, pGuid, iDevIndex, &deviceInfoData))

        {

        if((hOut=OpenOneDevice(hDevInfo, &deviceInfoData, sDevNameBuf)) != INVALID_HANDLE_VALUE)

        break;

        }

        else if(GetLastError() == ERROR_NO_MORE_ITEMS) //No more items

        {

        break;

        }

        }

        SetupDiDestroyDeviceInfoList(hDevInfo);

        return hOut;

       }

       //---------------------------------------------------------------------------

       bool GetUsbDeviceFileName(const GUID *pGuid, char *sDevNameBuf)

       {

        HANDLE hDev = OpenUsbDevice(pGuid, sDevNameBuf);

        if(hDev != INVALID_HANDLE_VALUE)

        {

        CloseHandle(hDev);

        return true;

        }

        return false;

       }

       //---------------------------------------------------------------------------

       HANDLE OpenMyDevice()

       {

        char DeviceName[MAXPATH] = "";

        return OpenUsbDevice(&USB_DRIVER_GUID, DeviceName);

       }

       //---------------------------------------------------------------------------

       HANDLE OpenMyDevPipe(const char *PipeName)

       {

        char DeviceName[MAXPATH] = "";

        if(GetUsbDeviceFileName(&USB_DRIVER_GUID, DeviceName))

        {

        strcat(DeviceName,"\\");

        strcat(DeviceName,PipeName);

        return CreateFile(DeviceName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

        }

        return INVALID_HANDLE_VALUE;

       }

       //---------------------------------------------------------------------------

PCSC驱动问题?

       可以。

       (Windows Driver Kit)是一种完全集成的驱动程序开发系统,它包含Windows Driver Device Kit (DDK),用于测试 Windows 驱动器的可靠性和稳定性。

什么叫 SDK ? 还有 DDK 是什么意思?

       pcsc驱动开发

       以下内容是翻译国外网站上的:

       如果想完全了解pcsc协议,可以去PC/SC Workgroup网站上下载协议看.该网站包括了大量pcsc主题方面的信息 也可以去啃MSDN , 也可发现相关文档. DDK中也包含了一些smartcard例子,留给有信心有毅力的一定要写出pcsc驱动的人.这可不是一件轻松的事,pcsc驱动有它自己的内部构造(pcsc驱动会与smclib连续),很多地方比较晦涩难懂,非驱动老手,还要多从各种可能的地方获取信息。当然ddk是开发驱动一个不错的出发点。

       把pcsc协议搬到这里来讲,个人认为并不是什么好办法,这里主要讲讲对pcsc的理解来让读者入门。

       例子中的pcsc驱动不是一个服务读卡器和智能卡的全功能的pcsc驱动,如大家所知,驱动安装以后,系统就能识别pcsc读卡器,应用程序就可以通过微软的smartcard组件来访问智能卡。现在流行的usbkey(国外习惯叫usbtoken或usb dongle)是一种安全认证的设备,集成了读卡器和卡片,上层应用利用pcsc框架调用微软的csp进行数字签名,身份认证等功能。 如果不走pcsc架构,这些功能的开发可以说一点不比开发驱动容易。

       pcsc架构有几个层次:

       ICC - integrated circuit cards; 卡片

       IFD - interface device (读卡器);

       IFD handler - handler of interface device (简单的说就是驱动);

       Resource Manager - service, 管理和控制应用程序所有对任何读卡器中智能卡访问. 比如多个应用程序同时对一张卡操作,那么Resource Manager会对请求进行管理排队,从而保证系统和设备不会打架。

       Service Providers - 如cryptographic (CSP) and noncryptographic(SCSP) service providers 这部分通常是建立的基于智能卡的应用服务。用户的智能卡能当作什么用途,就是在这里实现的。这部分要由用户自行开发。

       pcsc驱动屏蔽了设备和其他一些通讯协议方面的事情,这样不管你的读卡器是串口,并口,usb口,不管你的通讯协议是怎么定义的。用户要对你的智能卡进行开发,都只需调用windows提供的pcsc函数,而不需管底层的实现细节。把设备和应用开发划分成了两个独立的模块。这两块都用windows的pcsc函数进行接口。这样只要符合pcsc协议的设备,都可以拿来为你所用,而你开发的软件,无需任何修改也可以应用到许多不同厂商的设备上。

       如果你的pcsc驱动满足某些条件,那么你可以开发出很奇特的设备,比如usbkey(把读卡器和卡固定地做在一起),然后让系统识别它为插入卡的读卡器。那么usbkey可以替代读卡器+卡模式完成windows的域登录等。开发usbkey的成本比开发读卡器加卡的成本要低得多。可能只有三分之一不到。当然,我也承认目前这方面的争论很大,但是我们面对争论的办法,只是让研究继续……

       生产usbkey比较大的厂家国内有华大,握奇,明华,海泰等,国外有aladdin,rainbow等。

       小结:无论对于usbkey或者读卡器来说PC/SC驱动是非常重要的部分。 希望这个例子能够对那些对pcsc驱动有兴趣的人有所帮助。

       基本上比较正确。但是在98系统下,PCSC架构的驱动有硬伤,98智能卡补丁中的SCRM不支持读卡器的即插即用,即使设备本身是PNP的。所以在98系统可以考虑只使用USB驱动。

       卡商一般在驱动以上会封装一层设备API层,本层通过SCRM访问驱动,或者直接和通过USB驱动访问设备。设备API层上面再封装一层应用API层,封装了7816指令,对上层的应用屏蔽了7816指令的细节。再往上就是CSP,当然也可能在CSP和应用API层之间加上P11层,以实现CSP和P11的无缝连接和互用。

       例子中最重要的函数是SendSmdReader().此函数应当在外部硬件(卡上或usbkey)上执行。为了模拟虚拟卡片的插拔动作,我建立了一个额外的线程WORKER thread (function VdVendorIOCTL),还用函数IoCreateSynchronizationEvent建立了一个事件 SC_INSERT_REMOVE。 用户应用程序(ins_rem.exe) 触发这个事件和驱动模拟卡片插拔。第二个应用程序 (sc_mon.exe) 报告虚拟卡片目前的状态。并且也可以用工具软件PCSCInf.exe等来检测卡片状态。

       此驱动支持系统事件日志SYSTEM EVENT LOG, 保存相应的状态信息和错误信息。所有的信息都可以用系统标准的事件查看器查看。

       复位应答数据、用二进制文件来模拟卡片上内存的文件,都保存在驱动源码中。能通过注册表对它很容易地修改和设置。虚拟读卡器的名称是"COMRAD 000001 0"

       PC/SC driver测试工具:

       1. TAPDUDemoCard from Vizvary Istvan

       此工具用来与虚拟的智能卡通讯,无需写一行代码,通讯是双向模式的。

       2. APDU command test from Vizvary Istvan;

       和第一个工具很相似。

       3.PCSC Info from ZeitControl cardsystems GmbH;

       工具,用来测试任何pcsc兼容读卡器,它能控制读卡器中卡的状态,并报告当前卡状态

       虚拟读卡器能用在win2k的域登录上。智能卡登录是win2k的一项非常棒的功能特性。在你的智能卡或usbkey中存放证书,这样登录时系统会检查你的证书,认可方能登录。此例中,当虚拟智能卡拔出和系统锁定pc机时,虚拟读卡器才向资源管理器报告。

       首先,把lock_pc。reg文件导入注册表,激活win2k登录设置。即"请 CTRL+ALT+DEL登录", 参数 "Winlogon\scremoveoption" 能被置 "1"或 "2", 意味着 "卡拔出时锁定计算机" 和"卡拔除时注销当前用户". 如果驱动正确安装,你就能看到域登录窗口弹出来. 请用ins_rem工具模拟虚拟卡片的插拔动作.

       SDK 就是 Software Development Kit 的缩写,中文意思就是“软件开发工具包”。这是一个覆盖面相当广泛的名词,可以这么说:辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做“SDK”。具体到我们这个系列教程,我们后面只讨论广义 SDK 的一个子集——即开发 Windows 平台下的应用程序所使用的 SDK。

       呵呵,其实上面只是说了一个 SDK 大概的概念而已,理解什么是 SDK 真有这么容易吗?恐怕没这么简单!为了解释什么是 SDK 我们不得不引入 API、动态链接库、导入库等等概念。^_^,不要怕,也就是几个新的名词而已,我也是到了大学快结束的时候才体会到其实学习新知识就是在学习新名词、新概念和新术语。

       首先要接触的是“API”,也就是 Application Programming Interface,其实就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用程序的命令(动作)。其实早在 DOS 时代就有 API 的概念,只不过那个时候的 API 是以中断调用的形式(INT 21h)提供的,在 DOS 下跑的应用程序都直接或间接的通过中断调用来使用操作系统功能,比如将 AH 置为 30h 后调用 INT 21h 就可以得到 DOS 操作系统的版本号。而在 Windows 中,系统 API 是以函数调用的方式提供的。同样是取得操作系统的版本号,在 Windows 中你所要做的就是调用 GetVersionEx() 函数。可以这么说,DOS API 是“Thinking in 汇编语言”的,而 Windows API 则是“Thinking in 高级语言”的。DOS API 是系统程序的一部分,他们与系统一同被载入内存并且可以通过中断矢量表找到他们的入口,那么 Windows API 呢?要说明白这个问题就不得不引入我们下面要介绍得这个概念——DLL。

       DLL(又是一个缩写,感觉 IT 这个行业里三字头缩写特别多),即 Dynamic Link Library(动态链接库)。我们经常会看到一些 .dll 格式的文件,这些文件就是动态链接库文件,其实也是一种可执行文件格式。跟 .exe 文件不同的是,.dll 文件不能直接执行,他们通常由 .exe 在执行时装入,内含有一些资源以及可执行代码等。其实 Windows 的三大模块就是以 DLL 的形式提供的(Kernel32.dll,User32.dll,GDI32.dll),里面就含有了 API 函数的执行代码。为了使用 DLL 中的 API 函数,我们必须要有 API 函数的声明(.H)和其导入库(.LIB),函数的原型声明不难理解,那么导入库又是做什么用的呢?我们暂时先这样理解:导入库是为了在 DLL 中找到 API 的入口点而使用的。

       所以,为了使用 API 函数,我们就要有跟 API 所对应的 .H 和 .LIB 文件,而 SDK 正是提供了一整套开发 Windows 应用程序所需的相关文件、范例和工具的“工具包”。到此为止,我们才真正的解释清楚了 SDK 的含义。

       由于 SDK 包含了使用 API 的必需资料,所以人们也常把仅使用 API 来编写 Windows 应用程序的开发方式叫做“SDK 编程”。而 API 和 SDK 是开发 Windows 应用程序所必需的东西,所以其它编程框架和类库都是建立在它们之上的,比如 VCL 和 MFC,虽然他们比起“SDK 编程”来有着更高的抽象度,但这丝毫不妨碍它们在需要的时候随时直接调用 API 函数

       今天关于“ddk开发u盘驱动”的探讨就到这里了。希望大家能够更深入地了解“ddk开发u盘驱动”,并从我的答案中找到一些灵感。