📄 packet32.c
字号:
/** @ingroup packetapi
* @{
*/
/** @defgroup packet32 Packet.dll exported functions and variables
* @{
*/
/// Current packet.dll Version. It can be retrieved directly or through the PacketGetVersion() function.
char PacketLibraryVersion[] = "2.3";
/*!
\brief Returns a string with the dll version.
\return A char pointer to the version of the library.
*/
PCHAR PacketGetVersion(){
return PacketLibraryVersion;
}
/*!
\brief Returns information about the MAC type of an adapter.
\param AdapterObject The adapter on which information is needed.
\param type Pointer to a NetType structure that will be filled by the function.
\return If the function succeeds, the return value is nonzero, otherwise the return value is zero.
This function return the link layer technology and the speed (in bps) of an opened adapter.
The LinkType field of the type parameter can have one of the following values:
- NdisMedium802_3: Ethernet (802.3)
- NdisMediumWan: WAN
- NdisMedium802_5: Token Ring (802.5)
- NdisMediumFddi: FDDI
- NdisMediumAtm: ATM
- NdisMediumArcnet878_2: ARCNET (878.2)
*/
BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
{
BOOLEAN Status;
ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
PPACKET_OID_DATA OidData;
OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
if (OidData == NULL) {
ODS("PacketGetNetType failed\n");
return FALSE;
}
//get the link-layer type
OidData->Oid = OID_GEN_MEDIA_IN_USE;
OidData->Length = sizeof (ULONG);
Status = PacketRequest(AdapterObject,FALSE,OidData);
type->LinkType=*((UINT*)OidData->Data);
//get the link-layer speed
OidData->Oid = OID_GEN_LINK_SPEED;
OidData->Length = sizeof (ULONG);
Status = PacketRequest(AdapterObject,FALSE,OidData);
type->LinkSpeed=*((UINT*)OidData->Data)*100;
GlobalFreePtr (OidData);
ODSEx("Media:%d ",type->LinkType);
ODSEx("Speed=%d\n",type->LinkSpeed);
return Status;
}
/*!
\brief Stops and unloads the WinPcap device driver.
\return If the function succeeds, the return value is nonzero, otherwise it is zero.
This function can be used to unload the driver from memory when the application no more needs it.
Note that the driver is physically stopped and unloaded only when all the files on its devices
are closed, i.e. when all the applications that use WinPcap close all their adapters.
*/
BOOL PacketStopDriver()
{
SC_HANDLE scmHandle;
SC_HANDLE schService;
BOOL ret;
SERVICE_STATUS serviceStatus;
scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(scmHandle != NULL){
schService = OpenService (scmHandle,
NPFServiceName,
SERVICE_ALL_ACCESS
);
if (schService != NULL)
{
ret = ControlService (schService,
SERVICE_CONTROL_STOP,
&serviceStatus
);
if (!ret)
{
}
CloseServiceHandle (schService);
CloseServiceHandle(scmHandle);
return ret;
}
}
return FALSE;
}
/*!
\brief Opens an adapter.
\param AdapterName A string containing the name of the device to open.
Use the PacketGetAdapterNames() function to retrieve the list of available devices.
\return If the function succeeds, the return value is the pointer to a properly initialized ADAPTER object,
otherwise the return value is NULL.
This function tries to load and start the packet driver at the first invocation. In this way,
the management of the driver is transparent to the application, that simply needs to open an adapter to start
WinPcap.
\note the Windows 95 version of the NPF driver works with the ASCII string format, while the Windows NT
version works with UNICODE. Therefore, AdapterName \b should be an ASCII string in Windows 95, and a UNICODE
string in Windows NT. This difference is not a problem if the string pointed by AdapterName was obtained
through the PacketGetAdapterNames function, because it returns the names of the adapters in the proper format.
Problems can arise in Windows NT when the string is obtained from ANSI C functions like scanf, because they
use the ASCII format. Since this could be a relevant problem during the porting of command-line applications
from UNIX, we included in the Windows NT version of PacketOpenAdapter the ability to detect ASCII strings and
convert them to UNICODE before sending them to the device driver. Therefore PacketOpenAdapter in Windows NT
accepts both the ASCII and the UNICODE format. If a ASCII string is received, it is converted to UNICODE
by PACKET.DLL before being passed to the driver.
*/
LPADAPTER PacketOpenAdapter(LPTSTR AdapterName)
{
LPADAPTER lpAdapter;
BOOLEAN Result;
char *AdapterNameA;
WCHAR *AdapterNameU;
DWORD error;
SC_HANDLE svcHandle = NULL;
TCHAR driverPath[512];
TCHAR WinPath[256];
LONG KeyRes;
HKEY PathKey;
SERVICE_STATUS SStat;
BOOLEAN QuerySStat;
WCHAR SymbolicLink[128];
ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName);
scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(scmHandle == NULL){
error = GetLastError();
ODSEx("OpenSCManager failed! Error=%d\n", error);
} else {
*driverPath = 0;
GetCurrentDirectory(512, driverPath);
wsprintf(driverPath + wcslen(driverPath), NPFDriverName);
// check if the NPF registry key is already present
// this means that the driver is already installed and that we don't need to call PacketInstallDriver
KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
NPFRegistryLocation,
0,
KEY_READ,
&PathKey);
if(KeyRes != ERROR_SUCCESS){
Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath);
} else {
Result = TRUE;
RegCloseKey(PathKey);
}
if (Result) {
srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
if (srvHandle != NULL){
QuerySStat = QueryServiceStatus(srvHandle, &SStat);
ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
if (!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
ODS("Calling startservice\n");
if (StartService(srvHandle, 0, NULL)==0){
error = GetLastError();
if (error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
SetLastError(error);
if (scmHandle != NULL) CloseServiceHandle(scmHandle);
error = GetLastError();
ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
return NULL;
}
}
}
} else {
error = GetLastError();
ODSEx("OpenService failed! Error=%d", error);
}
} else {
if (GetSystemDirectory(WinPath, sizeof(WinPath)/sizeof(TCHAR)) == 0) {
return FALSE;
}
wsprintf(driverPath, TEXT("%s\\drivers%s"), WinPath, NPFDriverName);
if (KeyRes != ERROR_SUCCESS) {
Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath);
} else {
Result = TRUE;
}
if (Result) {
srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
if (srvHandle != NULL) {
QuerySStat = QueryServiceStatus(srvHandle, &SStat);
ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
if (!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING) {
ODS("Calling startservice\n");
if (StartService(srvHandle, 0, NULL) == 0) {
error = GetLastError();
if (error != ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) {
SetLastError(error);
if (scmHandle != NULL) CloseServiceHandle(scmHandle);
ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
return NULL;
}
}
}
} else {
error = GetLastError();
ODSEx("OpenService failed! Error=%d", error);
}
}
}
}
if (scmHandle != NULL) CloseServiceHandle(scmHandle);
AdapterNameA = (char*)AdapterName;
if (AdapterNameA[1] != 0) { // ASCII
AdapterNameU = SChar2WChar(AdapterNameA);
AdapterName = AdapterNameU;
} else { // Unicode
AdapterNameU = NULL;
}
lpAdapter = (LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER));
if (lpAdapter == NULL) {
ODS("PacketOpenAdapter: GlobalAlloc Failed\n");
error = GetLastError();
if (AdapterNameU != NULL) free(AdapterNameU);
//set the error to the one on which we failed
SetLastError(error);
ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n");
return NULL;
}
lpAdapter->NumWrites = 1;
wsprintf(SymbolicLink,TEXT("\\\\.\\%s%s"), DOSNAMEPREFIX, &AdapterName[8]);
// Copy only the bytes that fit in the adapter structure.
// Note that lpAdapter->SymbolicLink is present for backward compatibility but will
// never be used by the apps
memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
//try if it is possible to open the adapter immediately
lpAdapter->hFile = CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);
if (lpAdapter->hFile != INVALID_HANDLE_VALUE) {
ODSEx("PacketOpenAdapter: CreateFile(%S) successfull\n", SymbolicLink);
if (PacketSetReadEvt(lpAdapter) == FALSE) {
error = GetLastError();
ODS("PacketOpenAdapter: Unable to open the read event\n");
if (AdapterNameU != NULL)
free(AdapterNameU);
GlobalFreePtr(lpAdapter);
//set the error to the one on which we failed
SetLastError(error);
ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error);
return NULL;
}
PacketSetMaxLookaheadsize(lpAdapter);
if (AdapterNameU != NULL)
free(AdapterNameU);
return lpAdapter;
}
//this is probably the first request on the packet driver.
//We must create the dos device and set the access rights on it
else {
Result = DefineDosDevice(DDD_RAW_TARGET_PATH,
&SymbolicLink[4],
AdapterName);
if (Result) {
ODSEx("PacketOpenAdapter: calling CreateFile(%S)\n", SymbolicLink);
lpAdapter->hFile = CreateFile(
SymbolicLink,
GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);
if (lpAdapter->hFile != INVALID_HANDLE_VALUE) {
if (PacketSetReadEvt(lpAdapter) == FALSE) {
error = GetLastError();
ODS("PacketOpenAdapter: Unable to open the read event\n");
if (AdapterNameU != NULL)
free(AdapterNameU);
GlobalFreePtr(lpAdapter);
//set the error to the one on which we failed
SetLastError(error);
ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=1,%d\n",error);
return NULL;
}
PacketSetMaxLookaheadsize(lpAdapter);
if (AdapterNameU != NULL)
free(AdapterNameU);
return lpAdapter;
} else {
ODS("PacketOpenAdapter: CreateFile failed\n");
}
} else {
ODSEx("PacketOpenAdapter: DefineDosDevice(%S) failed\n", &SymbolicLink[4]);
}
}
error = GetLastError();
if (AdapterNameU != NULL)
free(AdapterNameU);
GlobalFreePtr(lpAdapter);
//set the error to the one on which we failed
SetLastError(error);
ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error);
return NULL;
}
/*!
\brief Closes an adapter.
\param lpAdapter the pointer to the adapter to close.
PacketCloseAdapter closes the given adapter and frees the associated ADAPTER structure
*/
VOID PacketCloseAdapter(LPADAPTER lpAdapter)
{
CloseHandle(lpAdapter->hFile);
SetEvent(lpAdapter->ReadEvent);
CloseHandle(lpAdapter->ReadEvent);
GlobalFreePtr(lpAdapter);
}
/*!
\brief Allocates a _PACKET structure.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -