深度剖析WinPcap之(八)――打开与关闭适配器(8)

1.5.2.1.1      PacketOpenAdapterNPF函数
函数PacketOpenAdapterNPF()的作用是打开一个使用NPF设备驱动的适配器。该函数被PacketOpenAdapter()AddAdapter()作为内部函数调用。 函数原型如下:
LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterNameA)
参数 AdapterNameA 字符串包含待打开设备的名称。
函数如果成功,返回一个已经正确初始化的ADAPTER对象的指针。否则返回NULL
函数的主要代码如下:
LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterNameA)
{
    LPADAPTER lpAdapter;
   
    CHAR SymbolicLinkA[MAX_PATH];
//NPF_DRIVER_NAME 定义为"NPF"
    CHAR    NpfDriverName[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_NAME;
    CHAR    NpfServiceLocation[MAX_WINPCAP_KEY_CHARS];
 
    /* 连接到服务控制管理器*/
    scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ);
       
    if(scmHandle == NULL)
    {// 连接到服务控制管理器失败
        error = GetLastError();
    }
    else
    {
/*
* 检查NPF服务是否已经存在,
* 如果存在则接下来可以分配并初始化ADAPTER对象
*/
 
// 设置NPF服务的注册表位置
        StringCchPrintfA(NpfServiceLocation, sizeof(NpfServiceLocation),
"SYSTEM\\CurrentControlSet\\Services\\%s" , NpfDriverName);
 
        // 检查NPF注册表的键值是已否存在,如果已经存在,
// 这意味着驱动已经安装,
// 我们不再需要调用PacketInstallDriver()函数安装驱动程序
        KeyRes=RegOpenKeyExA(HKEY_LOCAL_MACHINE,
            NpfServiceLocation,
            0,
            KEY_READ,
            &PathKey);
       
        if(KeyRes != ERROR_SUCCESS)
        {//NPF 注册表的键值不存在,调用PacketInstallDriver()函数
            Result = PacketInstallDriver();
        }
        else
        {//NPF 注册表的键值已经存在,驱动已经安装
            Result = TRUE;
            RegCloseKey(PathKey);
        }
       
        if (Result)
        { // 驱动已经存在,检查NPF服务是否正在运行
           
// 打开NPF服务
            svcHandle = OpenServiceA(scmHandle, NpfDriverName,
SERVICE_START | SERVICE_QUERY_STATUS );
            if (svcHandle != NULL)
            {  // 获得服务状态
                QuerySStat = QueryServiceStatus(svcHandle, &SStat);
                if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
                {// 获得服务状态失败或驱动NPF没有运行,启动NPF服务
                    if (StartService(svcHandle, 0, NULL)==0)
                    { // 如果不是服务正在运行或服务已经存在的状态,
// 就处理错误,函数返回NULL
                        error = GetLastError();
                        if(
error!=ERROR_SERVICE_ALREADY_RUNNING &&
error!=ERROR_ALREADY_EXISTS)
                        {// 处理错误,函数返回NULL
                            return NULL;
                        }
                    }              
                }
// 驱动NPF已正常运行,关闭服务控制管理器的句柄
                CloseServiceHandle( svcHandle );
                svcHandle = NULL;
            }
            else
            {// 打开NPF服务失败
                error = GetLastError();
                SetLastError(error);
            }
        }
        else
        {
            if(KeyRes != ERROR_SUCCESS)
            { // 第一次安装驱动程序失败,并且NPF注册表的键值不存在
// 再次安装驱动
                Result = PacketInstallDriver();
}
            else
                Result = TRUE;
           
            if (Result) {//NPF 的驱动程序已存在
// 打开NPF服务           
                svcHandle = OpenServiceA(scmHandle,
                                     NpfDriverName,SERVICE_START);
                if (svcHandle != NULL)
                {// 打开NPF服务成功,获取NPF服务的状态
                    QuerySStat = QueryServiceStatus(svcHandle, &SStat);
                    if(!QuerySStat ||
SStat.dwCurrentState != SERVICE_RUNNING)
{// 获得服务状态失败或驱动NPF没有运行,启动NPF服务
                        if (StartService(svcHandle, 0, NULL)==0){
                            // 如果不是服务正在运行或服务已经存在的状态,
// 就处理错误,函数返回NULL
                            if(error!=ERROR_SERVICE_ALREADY_RUNNING &&
                                error!=ERROR_ALREADY_EXISTS)
                            {
                                return NULL;
                            }
                        }
                    }
    // 驱动NPF已正常运行,关闭服务控制管理器的句柄
                    CloseServiceHandle( svcHandle );
                    svcHandle = NULL;
                }
                else{
// 打开NPF服务失败,设置错误状态
                    error = GetLastError();
                    SetLastError(error);
                }
            }
        }
    }
 
if (scmHandle != NULL) // 关闭服务控制管理器的句柄
CloseServiceHandle(scmHandle);
 
    /* 分配ADAPTER结构体的的内存空间 */
    lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
 sizeof(ADAPTER));
    if (lpAdapter==NULL)
    {// 分配失败,函数返回NULL;
       
        return NULL;
    }
    // 设置单个数据包发送的次数为一次
    lpAdapter->NumWrites=1;
 
// 从原始的设备名创建NPF设备的名称
#define DEVICE_PREFIX "\\Device\\"
    if (LOWORD(GetVersion()) == 4)
    {
        // 操作系统为Windows NT 4.0Windows 95Windows 98、或 Windows Me的处理
             
    }
    else
    {
        if (strlen(AdapterNameA) > strlen(DEVICE_PREFIX))
        {
            StringCchPrintfA(SymbolicLinkA, MAX_PATH,
"\\\\.\\Global\\%s" , AdapterNameA + strlen(DEVICE_PREFIX));
        }
        else
        {
            ZeroMemory(SymbolicLinkA, sizeof(SymbolicLinkA));
        }
    }
   ---------------待续---------------------------------

你可能感兴趣的:(职场,休闲,winpcap)