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

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

 2009-09-11 00:00:00 来源:WEB开发网   
核心提示: 1.3.3 NPF_CreateDevice函数函数NPF_CreateDevice对一个给定的MAC创建一个设备,NPF驱动程序也调用NPF_CreateDevice函数,深度剖析WinPcap之(六)——驱动程序的初始化与清除 (3)(2),通过IoCreateDevice系统接口把Open

1.3.3        NPF_CreateDevice函数

函数NPF_CreateDevice对一个给定的MAC创建一个设备。NPF驱动程序也调用NPF_CreateDevice函数,通过IoCreateDevice系统接口把Open/close,read/write与IOCTL请求的句柄地址传递给操作系统。

函数原型如下:

BOOLEAN
NPF_CreateDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
                     IN PUNICODE_STRING amacNameP
)

参数adriverObjectP是用来与设备相关联的驱动对象,例如NPF的一个实例。参数 amacNameP是所创建设备将要指向的网络接口名称。

如果函数成功,返回非0值。

NPF对每一个可用的网络适配器只创建一个设备。该新设备指向该NPF驱动程序,但包含关于原始设备的信息。通过这种方式,当用户打开该新设备时,NPF将能够确定使用正确的适配器。

函数的主要代码如下:

BOOLEAN NPF_CreateDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
                     IN PUNICODE_STRING amacNameP)
{
    NTSTATUS status;
    PDEVICE_OBJECT devObjP;
    UNICODE_STRING deviceName;
    UNICODE_STRING deviceSymLink;
  
/*检查amacNameP->Buffer是否包含合法的 “\\Device\\”子字符串*/
    if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer,
        devicePrefix.Length) < devicePrefix.Length)
    {
        return FALSE;
    }
/*分配设置设备对象的名称的内存空间*/
    deviceName.Length = 0;
    deviceName.MaximumLength = (USHORT)(amacNameP->Length +
        g_NPF_Prefix.Length + sizeof(UNICODE_NULL));
    deviceName.Buffer = ExAllocatePoolWithTag(PagedPool,
 deviceName.MaximumLength, '3PWA');
    if (deviceName.Buffer == NULL)
        return FALSE;
 
/*分配用户可见的设备名称的内存空间*/
    deviceSymLink.Length = 0;
    deviceSymLink.MaximumLength=
(USHORT)(amacNameP->Length-devicePrefix.Length
        + symbolicLinkPrefix.Length
        + g_NPF_Prefix.Length
        + sizeof(UNICODE_NULL));
    deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool,
deviceSymLink.MaximumLength, '3PWA');
    if (deviceSymLink.Buffer  == NULL)
    {
        ExFreePool(deviceName.Buffer);
        return FALSE;
    }
 
/*生成设置设备对象的名称*/
    RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
    RtlAppendUnicodeStringToString(&deviceName, &g_NPF_Prefix);
    RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer +
        devicePrefix.Length / sizeof(WCHAR));
 
/*生成用户可见的设备名称*/
    RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
    RtlAppendUnicodeStringToString(&deviceSymLink, &g_NPF_Prefix);
    RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer +
        devicePrefix.Length / sizeof(WCHAR));
      
/*为驱动程序的使用者分配内存,并初始化一个设备对象*/
    status = IoCreateDevice(adriverObjectP,
        sizeof(DEVICE_EXTENSION),
        &deviceName,
        FILE_DEVICE_TRANSPORT,
        FILE_DEVICE_SECURE_OPEN,  
        FALSE,
        &devObjP);
 
    if (NT_SUCCESS(status))
    {
PDEVICE_EXTENSION devExtP =
(PDEVICE_EXTENSION)devObjP->DeviceExtension;
        devObjP->Flags |= DO_DIRECT_IO;
//设置适配器的名称
        RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);
      
       /*在一个设备对象名称与一个用户可见的名称之间建立一个符号连接*/
        if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) !=
STATUS_SUCCESS)
        {//创建连接失败,函数返回
            ExFreePool(deviceName.Buffer);
            ExFreePool(deviceSymLink.Buffer);
            devExtP->ExportString = NULL;
            return FALSE;
        }
        /*设置应用程序可见的设备名称*/
        devExtP->ExportString = deviceSymLink.Buffer;
        ExFreePool(deviceName.Buffer);
        return TRUE;
    }
    else
    { //IoCreateDevice调用失败,函数返回
        ExFreePool(deviceName.Buffer);
        ExFreePool(deviceSymLink.Buffer);     
        return FALSE;
    }
}

上一页  1 2 3 4  下一页

Tags:深度 剖析 WinPcap

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