本文转自http://eslxf.blog.51cto.com/918801/206420
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));
}
}
---------------待续---------------------------------