WEB开发网
开发学院操作系统windows 2008 深度剖析WinPcap之(六)——驱动程序的初始化与清除... 阅读

深度剖析WinPcap之(六)——驱动程序的初始化与清除 (2)

 2009-09-11 00:00:00 来源:WEB开发网   
核心提示: 1.3.1 getAdaptersList函数函数getAdaptersList返回系统中可用的MAC链表,函数的原型如下:PWCHAR getAdaptersList(VOID);函数返回一个包含网络适配器链表的字符串,深度剖析WinPcap之(六)——驱动程序的初始化与清除 (2)(2),该

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

深度剖析WinPcap之(六)——驱动程序的初始化与清除 (2)

图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("\\Registry\\Machine\\System\\CurrentControlSet
*      \\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"\\Registry\\Machine\\System\\CurrentControlSet\\
Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
            UINT ExportKeyPrefixSize =
sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\
Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
            //需要打开的子项"Linkage"
            PWCHAR LinkageKeyPrefix = L"\\Linkage";
            UINT LinkageKeyPrefixSize = sizeof(L"\\Linkage");
            //所查找的键名为"Export"
            NDIS_STRING FinalExportKey = NDIS_STRING_CONST("Export");
 
            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);
                    if (!NT_SUCCESS(status)) {
                        //查询失败
                    }
                    else{//查询成功
                        if( BufPos + valueInfoP->DataLength > BufLen ) {
                        //如果DeviceNames的内存空间不够,翻倍增长内存空间            
                          PWCHAR DeviceNames2 =
(PWCHAR)ExAllocatePoolWithTag
(PagedPool, BufLen<< 1, '0PWA');
                            if( DeviceNames2 ) {//分配成功,数据转存
                                RtlCopyMemory((PCHAR)DeviceNames2,
(PCHAR)DeviceNames, BufLen);
                                BufLen <<= 1;//内存长度翻倍
                                ExFreePool(DeviceNames);
                                DeviceNames = DeviceNames2;
                            }
                        }
                        if( BufPos + valueInfoP->DataLength < BufLen ) {                            //复制“Export”键名的键值到DeviceNames中
                            RtlCopyMemory((PCHAR)DeviceNames+BufPos,                                   valueInfoP->Data,valueInfoP->DataLength);
                            BufPos+=valueInfoP->DataLength-2;
                        }
                    }
                    ExFreePool(valueInfoP);
                }
                else {
//分配用于查询的内存失败
                }
            }//一次查找“Export”键名的键值信息结束
          
//设置结束符
            DeviceNames[BufPos/2]=0;
            DeviceNames[BufPos/2+1]=0;
            //关闭注册表子项
            ZwClose (ExportKeyHandle);
            i++;
        }//结束while语句
 
/*关闭注册表项*/
        ZwClose (keyHandle);          
    }
/*设置函数返回内容*/
    if(BufPos==0){
        ExFreePool(DeviceNames);
        return NULL;
    } 
    return DeviceNames;
}

1.3.2        getTcpBindings函数

函数getTcpBindings返回绑定到TCP/IP的MAC。函数原型如下:

PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(VOID);

如果getAdaptersList 函数失败,NPF通过该函数试图获取TCP/IP的绑定。函数通过对注册表项HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Services\Tcpip\Linkage下Bind键值获得TCP-IP绑定的适配器。函数返回指向注册表”Bind”键名的键值的指针,该注册表键值包含绑定了TCP/IP的适配器。

深度剖析WinPcap之(六)——驱动程序的初始化与清除 (2)

图5-3 注册表项Tcpip\Linkage

深度剖析WinPcap之(六)——驱动程序的初始化与清除 (2)

图5-4 Bind键名的键值

出处: http://eslxf.blog.51cto.com/918801/197738

上一页  1 2 

Tags:深度 剖析 WinPcap

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接