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.0、Windows 95、Windows 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));
}
}
---------------待续---------------------------------