WinPcap驱动程序的初始化与清除(六)(3)

2019-01-26 14:21

&ProtocolChar,

sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

if (Status != NDIS_STATUS_SUCCESS) { //注册失败,函数返回 return Status; }

/*设置IRP派遣函数和卸载例程*/

DriverObject->MajorFunction[IRP_MJ_CREATE] = NPF_Open; DriverObject->MajorFunction[IRP_MJ_CLOSE] = NPF_Close; DriverObject->MajorFunction[IRP_MJ_CLEANUP]= NPF_Cleanup; DriverObject->MajorFunction[IRP_MJ_READ] = NPF_Read; DriverObject->MajorFunction[IRP_MJ_WRITE] = NPF_Write;

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NPF_IoControl; DriverObject->DriverUnload = NPF_Unload;// 卸载例程

/*获取系统中可用的网络适配器信息*/ 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);//给一个适配器创建一个设备对象 }

return STATUS_SUCCESS;

/*处理函数错误*/ RegistryError:

NdisDeregisterProtocol( &Status,

g_NdisProtocolHandle );

Status=STATUS_UNSUCCESSFUL; return(Status); }

1.3.1 getAdaptersList函数

函数getAdaptersList返回系统中可用的MAC链表,函数的原型如下: PWCHAR getAdaptersList(VOID);

函数返回一个包含网络适配器链表的字符串。

该适配器链表从注册表的SYSTEM\\\\CurrentControlSet\\\\Control\\\\Class

\\\\{4D36E972-E325-11CE-BFC1-08002BE10318}注册项获取。函数首先遍历该注册表项,获取子项的信息,再打开子项的“Linkage”子项,在“Linkage”子项下查找“Export”键名的键值,如在图5-2中,键值为“\\Device\\NdisWanIp”。并把键值存储到内存中,形成一个列表。函数最后返回该列表。

NPF试图从这个链表创建它的绑定。通过这种方式,它可以动态的加载或卸载,而不用通过控制面板操作。

图5-2 注册表项0006\\Linkage

函数的主要代码如下: 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)

{//分配失败,函数返回 return NULL; } /*

*设置一个OBJECT_ATTRIBUTES类型的参数objAttrs,为了后续调用 *其中NDIS_STRING AdapterListKey =

* NDIS_STRING_CONST(\ * \\\\Control\\\\Class\\\\{4D36E972-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 AdapInfo[1024];

UINT i=0;

/*遍历设备链表,获取一个已打开注册表项子项的信息*/ while((status=ZwEnumerateKey(keyHandle,i,KeyBasicInformation,

AdapInfo,sizeof(AdapInfo),&resultLength))==STATUS_SUCCESS) {

WCHAR ExportKeyName [512];

//所打开的注册表项 PWCHAR ExportKeyPrefix =

L\

Control\\\\Class\\\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\\\\; UINT ExportKeyPrefixSize =

sizeof(L\ Control\\\\Class\\\\{4D36E972-E325-11CE-BFC1-08002BE10318}\);

//需要打开的子项\

PWCHAR LinkageKeyPrefix = L\; UINT LinkageKeyPrefixSize = sizeof(L\); //所查找的键名为\

NDIS_STRING FinalExportKey = NDIS_STRING_CONST(\);

PKEY_BASIC_INFORMATION tInfo=

(PKEY_BASIC_INFORMATION)AdapInfo; UNICODE_STRING AdapterKeyName; HANDLE ExportKeyHandle;

//合成要打开的注册表子项,如图5-2中的为:

//”\\\\Registry\\\\Machine\\\\System\\\\CurrentControlSet\\\\Control //\\\\Class\\\\{4D36E972-E325-11CE-BFC1-08002BE10318} //\\\\0006\\\\Linkage”

RtlCopyMemory(ExportKeyName,ExportKeyPrefix, ExportKeyPrefixSize);

RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize,

tInfo->Name,tInfo->NameLength+2); RtlCopyMemory(

(PCHAR)ExportKeyName+ExportKeyPrefixSize+tInfo->NameLength, LinkageKeyPrefix,LinkageKeyPrefixSize);

/*给一个Unicode字符串初始化赋值*/

RtlInitUnicodeString(&AdapterKeyName, ExportKeyName);

/*设置一个OBJECT_ATTRIBUTES类型的参数objAttrs,为了后续调用*/

InitializeObjectAttributes(&objAttrs, &AdapterKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);

/*打开注册表表项,返回objAttrs中所描述的注册表表项的句柄*/ status=ZwOpenKey(&ExportKeyHandle,KEY_READ,&objAttrs); if (!NT_SUCCESS(status)) {//打开失败,跳出本次循环 continue; }

/*查找“Export”键名的键值信息*/

status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey, KeyValuePartialInformation, &valueInfo, sizeof(valueInfo), &resultLength);

if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) { //查询失败 }

else { //查询成功

/*计算所需的内存大小*/

ULONG valueInfoLength = valueInfo.DataLength +

FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);

/*分配内存,用于查询*/

PKEY_VALUE_PARTIAL_INFORMATION valueInfoP =

(PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag

(PagedPool, valueInfoLength, '1PWA');

if (valueInfoP != NULL) {

status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,

KeyValuePartialInformation, valueInfoP,

valueInfoLength, &resultLength);


WinPcap驱动程序的初始化与清除(六)(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:教育顾问呼出、学科分析、家庭教育话术-已印

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: