WinPcap驱动程序的初始化与清除(六).doc_第1页
WinPcap驱动程序的初始化与清除(六).doc_第2页
WinPcap驱动程序的初始化与清除(六).doc_第3页
WinPcap驱动程序的初始化与清除(六).doc_第4页
WinPcap驱动程序的初始化与清除(六).doc_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

深度剖析WinPcap之(六)驱动程序的初始化与清除驱动程序的初始化主要由函数DriverEntry完成,卸载主要由函数DriverUnload完成。下面主要分析驱动程序的初始化与清除过程,以及相关的基础知识。图5-1 函数调用关系图1.1 结构体_NDIS_PROTOCOL_CHARACTERISTICS结构体_NDIS_PROTOCOL_CHARACTERISTICS的定义如下:typedef struct _NDIS_PROTOCOL_CHARACTERISTICS UCHAR MajorNdisVersion;UCHAR MinorNdisVersion;UINT Reserved;OPEN_ADAPTER_COMPLETE_HANDLER OpenAdapterCompleteHandler;CLOSE_ADAPTER_COMPLETE_HANDLER CloseAdapterCompleteHandler;SEND_COMPLETE_HANDLER SendCompleteHandler;TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;RESET_COMPLETE_HANDLER ResetCompleteHandler;REQUEST_COMPLETE_HANDLER RequestCompleteHandler;RECEIVE_HANDLER ReceiveHandler;RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler;STATUS_HANDLER StatusHandler;STATUS_COMPLETE_HANDLER StatusCompleteHandler;NDIS_STRING Name;/使用下列任何成员,需要把MajorNdisVersion设置为0x04或0x05/RECEIVE_PACKET_HANDLER ReceivePacketHandler;BIND_HANDLER BindAdapterHandler;UNBIND_HANDLER UnbindAdapterHandler;PNP_EVENT_HANDLER PnPEventHandler;UNLOAD_PROTOCOL_HANDLER UnloadHandler;/使用下列任何成员,需要把MajorNdisVersion设置为0x05/面向连接的协议驱动程序使用,不分析。/CO_SEND_COMPLETE_HANDLER CoSendCompleteHandler;CO_STATUS_HANDLER CoStatusHandler;CO_RECEIVE_PACKET_HANDLER CoReceivePacketHandler;CO_AF_REGISTER_NOTIFY_HANDLER CoAfRegisterNotifyHandler; NDIS_PROTOCOL_CHARACTERISTICS, *PNDIS_PROTOCOL_CHARACTERISTICS;下面分别说明结构体_NDIS_PROTOCOL_CHARACTERISTICS各成员的作用,其中,只在面向连接的协议驱动程序中使用的成员不作分析说明。MajorNdisVersion描述驱动程序所使用NDIS库的主要版本。当前值为0x05(WinPcap当前使用的为版本5,NDIS目前已到版本6),虽然NDIS库支持早期采用NDIS V4.0开发的驱动程序,但不再对V3.0版本的协议驱动程序进行支持。MinorNdisVersion描述NDIS的次版本,当前为0x00。Reserved该成员保留给系统使用。OpenAdapterCompleteHandler这是一个必须提供的函数。如果协议驱动程序对NdisOpenAdapter的调用返回NDIS_STATUS_PENDING,则接着调用ProtocolOpenAdapterComplete来完成绑定操作。CloseAdapterCompleteHandler这是一个必须提供的函数。如果协议驱动程序对NdisCloseAdapter的调用返回NDIS_STATUS_PENDING,则接着调用ProtocolCloseAdapterComplete来完成解除绑定操作。SendCompleteHandler这是一个必须提供的函数。如果协议驱动程序对NdisSendPackets或NdisSend的调用返回NDIS_STATUS_PENDING,则接着调用SendCompleteHandler来完成发送处理。TransferDataCompleteHandler如果协议驱动程序可以把它自己绑定到一个低层非面向连接的NIC驱动程序(以NdisMIndicateReceivePacket指定并不是接收所有的数据包)上,这就是一个必须提供的函数。当协议驱动程序发起传输数据请求,对NdisTransferData的调用返回NDIS_STATUS_PENDING时,ProtocolTransferDataComplete函数被调用。专门面向连接的协议驱动程序不需要ProtocolTransferDataComplete函数。ResetCompleteHandler这是一个必须提供的函数。当协议驱动程序调用NdisReset函数执行复位操作,返回值为NDIS_STATUS_PENDING,则接着调用ProtocolResetComplete完成复位操作。RequestCompleteHandler这是一个必须提供的函数。当协议驱动程序调用NdisRequest函数查询和设置操作,返回值为NDIS_STATUS_PENDING,则调用ProtocolRequestComplete完成操作。ReceiveHandler对绑定到一个非面向连接的NIC驱动程序上的NDIS协议驱动程序,这是一个必须提供的函数。ProtocolReceive决定协议驱动程序的使用者对一个被接收的网络数据包是否感兴趣,如果感兴趣,就复制所需要的数据,可能地,调用NdisTransferData重新获取剩余的所需数据包。ReceiveCompleteHandler这是一个必须提供的函数。驱动程序完成前面所述的一个或多个从一个NIC驱动程序接收所需数据的操作后,ProtocolReceiveComplete完成诸如通知协议驱动程序使用者之类的后处理。StatusHandler这是一个必须提供的函数。ProtocolStatus函数用来处理低层NIC驱动程序所指示状态的改变。StatusCompleteHandler这是一个必须提供的函数。ProtocolStatusComplete完成一个状态改变的操作,该操作由底层驱动程序调用NdisMIndicateStatus发起。Name一个NDIS_STRING类型,包含调用者初始化的一个字符串,用来命名该驱动程序,采用系统默认的字符集。对Windows 2000与后面的驱动,该字符串为Unicode字符。也就是说,对Windows 2000与以后的版本,NDIS定义NDIS_STRING类型为一个UNICODE_STRING类型。当协议被安装时,该字符串必须与注册表所指定的(在Services条目之下)匹配。NdisRegisterProtocol把所提供的字符串转换为大写字符,因此一个协议驱动程序的编写者不能假设通过改变一个已经注册协议名称的大小写来为驱动创建一个唯一的名称。ReceivePacketHandler这是一个可选函数。如果协议驱动程序绑定到支持多数据包(multipacket )的NIC驱动程序(通过调用NdisMIndicateReceivePacket指定),那么ProtocolReceivePacket函数应该被提供。BindAdapterHandler这是一个必须提供的函数。NDIS调用该函数请求协议驱动程序绑定到低层网卡或虚拟网卡上,网卡名作为该处理程序的参数传递。UnbindAdapterHandler这是一个必须提供的函数。NDIS调用ProtocolUnbindAdapter释放对低层网卡或虚拟网卡的绑定,网卡名作为参数传递。当绑定成功解除时,ProtocolUnbindAdapter函数调用NdisCloseAdapter,并释放资源。PnPEventHandler这是一个必须提供的函数。NDIS调用ProtocolPnPEvent来指示即插即用事件或电源管理事件。UnloadHandler这是一个可选函数。NDIS调用ProtocolUnload函数来响应用户卸载中间层驱动程序的请求。对于每一个绑定的适配器,在调用NDIS的 ProtocolUnbindAdapter之后,调用ProtocolUnload函数卸载驱动程序。ProtocolUnload执行驱动程序决定的清除操作。1.2 NPF的DriverEntry函数的主要流程和编写普通应用程序一样,驱动程序也有个入口函数,也就是首先被执行的函数。该函数通常被命名为DriverEntry,可以指定另外的名称,但最好遵循这个名称。该函数的原型如下:NTSTATUSDriverEntry(IN PDRIVER_OBJECTDriverObject,IN PUNICODE_STRINGRegistryPath);DriverEntry主要是对驱动程序进行初始化工作,它由系统进程所调用。在Windows中有个特殊的进程叫做系统进程。打开进程管理器,可见里面有个名为System的进程就是系统进程。系统进程在系统启动的时候,就已经被创建了。图5-2 System进程驱动加载的时候,系统进程启动新的线程,调用执行体组件中的对象管理器,创建一个驱动对象。这个驱动对象是一个DRIVER_OBJECT的结构体。另外,系统进程调用执行体组件中的配置管理程序,查询此驱动程序在注册表中对应的项。系统线程调用驱动程序的DriverEntry例程时,同时传进两个参数,分别是pDrivelobject和pRegistryPath。其中,第一个是指向刚才被创建驱动对象的指针,第二个是指向设备服务键的键名称符串的指针。为了和NDIS库建立通信,驱动程序的DriverEntry必须调用NdisRegisterProtocol作为协议驱动程序注册,稍候将作详细描述。DriverEntry返回值是NTSTATUS的数据,NTSTATUS被定义为32位的无符号长整型。在驱动程序开发中,人们习惯用NTSTATUS返回状态。DriverEntry的返回值如果表示成功,则意味着加载驱动成功,否则意味着加载驱动失败,调用对象管理程序销毁驱动对象。如果该程序成功,它必须返回STATUS_SUCCESS,否则,它必须返回一个在ntstatus.h定义的错误状态码。下面列出STATUS_SUCCESS与STATUS_UNSUCCESSFUL的定义。st1:*behavior:url(#ieooui) #defineSTATUS_SUCCESS(NTSTATUS)0x00000000L)#defineSTATUS_UNSUCCESSFUL(NTSTATUS)0xC0000001L)1.2.1协议驱动程序注册驱动程序在DriverEntry环境中通过调用NdisRegisterProtocol向NDIS注册ProtocolXxx函数。NdisRegisterProtocol定义如下:VOID NdisRegisterProtocol(OUT PNDIS_STATUSStatus,OUT PNDIS_HANDLENdisProtocolHandler,IN NDIS_PROTOCOL_CHARACTERISTICSProtocolCharacteristics,IN UINTCharacteristicsLength);参数Status是指向调用者提供的一个变量的指针,该函数可以返回下列的值:NDIS_STATUS_SUCCESSNDIS库把调用者注册为一个协议驱动程序NDIS_STATUS_BAD_CHARACTERISTICS对参数ProtocolCharacteristics 中MajorNdisVersion所描述的版本而言CharacteristicsLength太短NDIS_STATUS_BAD_VERSION参数ProtocolCharacteristics 中MajorNdisVersion描述的版本不可用NDIS_STATUS_RESOURCES资源不够,可能是内存,阻止NDIS库注册调用者参数NdisProtocolHandle指向调用者提供的一个变量,函数将通过它返回一个描述已注册驱动的一个句柄。参数ProtocolCharacteristics指向一个NDIS_PROTOCOL_CHARACTERISTICS结构体,由调用者设置。参数CharacteristicsLength描述ProtocolCharacteristics所指结构体的大小。该调用的返回句柄NdisProtocolHandler对协议驱动程序是透明的,协议驱动程序必须保存该句柄,并在将来对NDIS的调用中作为输入参数传递,例如,打开低层适配器(调用NdisOpenAdapter函数时)。在调用NdisRegisterProtocol之前,DriverEntry必须完成以下操作:对NDIS_PROTOCOL_CHARACTERISTICS结构体进行零初始化,例如调用NdisZeroMemory函数。这将确保可选入口点的尚未使用的成员设置为NULL。如果该结构没被置零,那么在调用NdisRegisterProtocol之前,任何不使用的成员必须置为NULL;在NDIS_PROTOCOL_CHARACTERISTICS结构中指定协议兼容的NDIS版本;在NDIS_PROTOCOL_CHARACTERISTICS结构中设置驱动程序导出的必需的和可选的ProtocolXxx函数的地址。在WinPcap的NPF中的具体实现为:首先分配一个NDIS_PROTOCOL_CHARACTERISTICS的结构体,然后执行零初始化,接着用协议数据(版本、名称等)与驱动程序所需回调函数的地址设置该结构体。最后调用NdisRegisterProtocol函数把NPF注册为一个NDIS协议驱动程序。下面为NPF中对应的代码:/声明一个NDIS_PROTOCOL_CHARACTERISTICS结构实例ProtocolChar;NDIS_PROTOCOL_CHARACTERISTICSProtocolChar;/协议名称PacketDriverNDIS_STRING ProtoName = NDIS_STRING_CONST(PacketDriver);/对ProtocolChar的内存空间清零RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS);/用协议数据(版本、名称等)与回调函数地址设置ProtocolChar#ifdef #ifdef NDIS50ProtocolChar.MajorNdisVersion= 5;#elseProtocolChar.MajorNdisVersion= 3;#endifProtocolChar.MinorNdisVersion= 0;ProtocolChar.Reserved= 0;ProtocolChar.OpenAdapterCompleteHandler= NPF_OpenAdapterComplete;ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete;ProtocolChar.SendCompleteHandler= NPF_SendComplete;ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete;ProtocolChar.ResetCompleteHandler= NPF_ResetComplete;ProtocolChar.RequestCompleteHandler= NPF_RequestComplete;ProtocolChar.ReceiveHandler= NPF_tap;ProtocolChar.ReceiveCompleteHandler= NPF_ReceiveComplete;ProtocolChar.StatusHandler= NPF_Status;ProtocolChar.StatusCompleteHandler= NPF_StatusComplete;#ifdef NDIS50ProtocolChar.BindAdapterHandler= NPF_BindAdapter;ProtocolChar.UnbindAdapterHandler= NPF_UnbindAdapter;ProtocolChar.PnPEventHandler= NPF_PowerChange;ProtocolChar.ReceivePacketHandler= NULL;#endifProtocolChar.Name= ProtoName;/把NPF注册为一个NDIS协议驱动程序NdisRegisterProtocol(&Status,&g_NdisProtocolHandle,&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS);if (Status != NDIS_STATUS_SUCCESS) /注册协议驱动程序到NDIF失败,程序结束return Status;1.2.2设置卸载例程和IRP的派遣函数在DriverEntry函数中,一般设置卸载例程和IRP的派遣函数。设置卸载例程和设置派遣函数都是对驱动对象的设置。设备对象中的MajorFunction是一个函数指针数组,IRP_MJ_CREATE、IRP_MJ_ CLOSE、IRP_MJ_WRlTE等代表数组的第几个元素。下列为NPF的DriverEntry函数中的设置:DriverObject-MajorFunctionIRP_MJ_CREATE = NPF_Open;DriverObject-MajorFunctionIRP_MJ_CLOSE= NPF_Close;DriverObject-MajorFunctionIRP_MJ_CLEANUP= NPF_Cleanup;DriverObject-MajorFunctionIRP_MJ_READ= NPF_Read;DriverObject-MajorFunctionIRP_MJ_WRITE= NPF_Write;DriverObject-MajorFunctionIRP_MJ_DEVICE_CONTROL= NPF_IoControl;DriverObject-DriverUnload = NPF_Unload;/ 卸载例程1.2.3获取系统中可用网络适配器的信息函数getAdaptersList获取系统中可用的网络适配器信息,返回一个包含系统中可用网络适配器列表的字符串。如果getAdaptersList失败了,NPF试图通过调用getTcpBindings函数获得绑定了TCP/IP的网络适配器信息。函数getTcpBindings返回指向包含绑定了TCP/IP适配器的注册表键值的指针。下面为DriverEntry函数中相关的代码。bindP = getAdaptersList();if (bindP = NULL)/在注册表中没找到适配器,试图复制TCP-IP绑定的适配器tcpBindingsP = getTcpBindings();if (tcpBindingsP = NULL)/没有找到绑定了TCP/IP的适配器,程序执行错误处理goto RegistryError;bindP = (WCHAR*)tcpBindingsP;bindT = (WCHAR*)(tcpBindingsP-Data);else bindT = bindP;for (; *bindT != UNICODE_NULL;bindT += (macName.Length + sizeof(UNICODE_NULL) / sizeof(WCHAR)RtlInitUnicodeString(&macName, bindT);NPF_CreateDevice(DriverObject, &macName);/给网络适配器创建一个设备1.2.4对可用的网络适配器创建一个设备函数NPF_CreateDevice对一个给定的网络适配器创建一个设备。NPF驱动程序也调用NPF_CreateDevice函数,通过IoCreateDevice系统接口把Open/close,read/write与IOCTL请求的句柄地址传递给操作系统。1.3DriverEntry函数的具体实现NPF的DriverEntry注册所有驱动程序的I/O回调函数、创建设备、在NDIS内把NPF定注册为一个协议驱动程序。NPF的DriverEntry函数的主要代码如下:packetNtxdriverpacket.c91282NTSTATUSDriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)/*根据操作系统的版本,定义跳过回环数据包的正确标识*/获得操作系统的版本PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL);/根据不同的操作系统,定义跳过回环数据包的正确标识if(OsMajorVersion = 5) & (OsMinorVersion = 0)/ Windows 2000 需要NDIS_FLAGS_DONT_LOOPBACK与/ NDIS_FLAGS_SKIP_LOOPBACK两个标识g_SendPacketFlags = NDIS_FLAGS_DONT_LOOPBACK |NDIS_FLAGS_SKIP_LOOPBACK_W2K;else/ Windows XP、Windows 2003与后续的操作系统/只需要NDIS_FLAGS_DONT_LOOPBACK标识g_SendPacketFlags =NDIS_FLAGS_DONT_LOOPBACK;/*初始化设备名称的前缀*/NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer);/*获得CPU的个数,并保存该值*/g_NCpu = NdisSystemProcessorCount();/*零初化ProtocolChar结构体*/RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS);/*向NDIS注册协议驱动程序*/用协议数据(版本、名称等)与回调函数地址设置ProtocolChar#ifdefNDIS50ProtocolChar.MajorNdisVersion= 5;#elseProtocolChar.MajorNdisVersion= 3;#endifProtocolChar.MinorNdisVersion= 0;ProtocolChar.Reserved= 0;ProtocolChar.OpenAdapterCompleteHandler= NPF_OpenAdapterComplete;ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete;ProtocolChar.SendCompleteHandler= NPF_SendComplete;ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete;ProtocolChar.ResetCompleteHandler= NPF_ResetComplete;ProtocolChar.RequestCompleteHandler= NPF_RequestComplete;ProtocolChar.ReceiveHandler= NPF_tap;ProtocolChar.ReceiveCompleteHandler= NPF_ReceiveComplete;ProtocolChar.StatusHandler= NPF_Status;ProtocolChar.StatusCompleteHandler= NPF_StatusComplete;#ifdefNDIS50ProtocolChar.BindAdapterHandler= NPF_BindAdapter;ProtocolChar.UnbindAdapterHandler= NPF_UnbindAdapter;ProtocolChar.PnPEventHandler= NPF_PowerChange;ProtocolChar.ReceivePacketHandler= NULL;#endifProtocolChar.Name= ProtoName;/把NPF注册为一个NDIS协议驱动程序NdisRegisterProtocol(&Status,&g_NdisProtocolHandle,&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS);if(Status != NDIS_STATUS_SUCCESS) /注册失败,函数返回returnStatus;/*设置IRP派遣函数和卸载例程*/DriverObject-MajorFunctionIRP_MJ_CREATE = NPF_Open;DriverObject-MajorFunctionIRP_MJ_CLOSE= NPF_Close;DriverObject-MajorFunctionIRP_MJ_CLEANUP= NPF_Cleanup;DriverObject-MajorFunctionIRP_MJ_READ= NPF_Read;DriverObject-MajorFunctionIRP_MJ_WRITE= NPF_Write;DriverObject-MajorFunctionIRP_MJ_DEVICE_CONTROL= NPF_IoControl;DriverObject-DriverUnload = NPF_Unload;/ 卸载例程/*获取系统中可用的网络适配器信息*/bindP = getAdaptersList();if(bindP = NULL)/没有找到适配器,试图复制TCP-IP的绑定tcpBindingsP = getTcpBindings();if(tcpBindingsP = NULL)/TCP-IP没有找到,函数退出gotoRegistryError;bindP = (WCHAR*)tcpBindingsP;bindT = (WCHAR*)(tcpBindingsP-Data);elsebindT = bindP;for(; *bindT != UNICODE_NULL;bindT += (macName.Length +sizeof(UNICODE_NULL) /sizeof(WCHAR)RtlInitUnicodeString(&macName, bindT);NPF_CreateDevice(DriverObject, &macName);/给一个适配器创建一个设备对象returnSTATUS_SUCCESS;/*处理函数错误*/RegistryError:NdisDeregisterProtocol(&Status,g_NdisProtocolHandle);Status=STATUS_UNSUCCESSFUL;return(Status);1.3.1getAdaptersList函数函数getAdaptersList返回系统中可用的MAC链表,函数的原型如下:PWCHAR getAdaptersList(VOID);函数返回一个包含网络适配器链表的字符串。该适配器链表从注册表的SYSTEMCurrentControlSetControlClass4D36E972-E325-11CE-BFC1-08002BE10318注册项获取。函数首先遍历该注册表项,获取子项的信息,再打开子项的“Linkage”子项,在“Linkage”子项下查找“Export”键名的键值,如在图5-2中,键值为“DeviceNdisWanIp”。并把键值存储到内存中,形成一个列表。函数最后返回该列表。NPF试图从这个链表创建它的绑定。通过这种方式,它可以动态的加载或卸载,而不用通过控制面板操作。图5-2 注册表项0006Linkage函数的主要代码如下:PWCHAR getAdaptersList(void)PKEY_VALUE_PARTIAL_INFORMATION result = NULL;OBJECT_ATTRIBUTES objAttrs;NTSTATUS status;HANDLE keyHandle;UINT BufPos=0;UINT BufLen=4096;/*分配DeviceNames所需的内存空间*/PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, BufLen,0PWA);if(DeviceNames = NULL)/分配失败,函数返回returnNULL;/*设置一个OBJECT_ATTRIBUTES类型的参数objAttrs,为了后续调用*其中NDIS_STRING AdapterListKey =*NDIS_STRING_CONST(RegistryMachineSystemCurrentControlSet*ControlClass4D36E972-E325-11CE-BFC1-08002BE10318);*/InitializeObjectAttributes(&objAttrs, &AdapterListKey,OBJ_CASE_INSENSITIVE, NULL, NULL);/*打开注册表表项,返回objAttrs中所描述的注册表表项的句柄*/status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);if(!NT_SUCCESS(status) /打开失败else/打开成功ULONG resultLength;KEY_VALUE_PARTIAL_INFORMATION valueInfo;CHAR AdapInfo1024;UINT i=0;/*遍历设备链表,获取一个已打开注册表项子项的信息*/while(status=ZwEnumerateKey(keyHandle,i,KeyBasicInformation,AdapInfo,sizeof(AdapInfo),&resultLength)=STATUS_SUCCESS)WCHAR ExportKeyName 512;/所打开的注册表项PWCHAR ExportKeyPrefix =LRegistryMachineSystemCurrentControlSetControlClass4D36E972-E325-11CE-BFC1-08002BE10318;UINT ExportKeyPrefixSize =sizeof(LRegistryMachineSystemCurrentControlSetControlClass4D36E972-E325-11CE-BFC1-08002BE10318);/需要打开的子项LinkagePWCHAR LinkageKeyPrefix = LLinkage;UINT LinkageKeyPrefixSize =sizeof(LLinkage);/所查找的键名为ExportNDIS_STRING FinalExportKey = NDIS_STRING_CONST(Export);PKEY_BASIC_INFORMATION tInfo=(PKEY_BASIC_INFORMATION)AdapInfo;UNICODE_STRING AdapterKeyName;HANDLE ExportKeyHandle;/合成要打开的注册表子项,如图5-2中的为:/”RegistryMachineSystemCurrentControlSetControl/Class4D36E972-E325-11CE-BFC1-08002BE10318/0006Linkage”RtlCopyMemory(ExportKeyName,ExportKeyPrefix,ExportKeyPrefixSize);RtlCopyMemory(PCHAR)ExportKeyName+ExportKeyPrefixSize,tInfo-Name,tInfo-NameLength+2);RtlCopyMemory(PCHAR)ExportKeyName+Ex

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论