📄 packet.c
字号:
/*
* Copyright (c) 1999, 2000
* Politecnico di Torino. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the Politecnico
* di Torino, and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <basedef.h>
#include <vmm.h>
#include <ndis.h>
#include <vwin32.h>
#include "debug.h"
#include "packet.h"
#include <ntddpack.h>
#include <vmmreg.h>
#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG
/*head of the open instances*/
PDEVICE_EXTENSION GlobalDeviceExtension = 0;
UINT nOpen = 0;
POPEN_INSTANCE InstToClose[128];
/*number of processes attached to this driver*/
int Instances=0;
/************************************************************
This routine initializes the Packet driver.
Arguments:
DriverObject - Pointer to driver object created by system.
RegistryPath - Pointer to the Unicode name of the registry path
for this driver.
Return Value:
The function value is the final status from the initialization operation.
************************************************************/
NTSTATUS
DriverEntry( IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
NDIS_STRING ProtoName = NDIS_STRING_CONST("PACKET");
NDIS_HANDLE NdisProtocolHandle;
NDIS_STATUS Status;
TRACE_ENTER( "DriverEntry" );
NdisAllocateMemory( (PVOID *)&GlobalDeviceExtension, sizeof( DEVICE_EXTENSION ), 0, -1 );
if ( GlobalDeviceExtension != NULL )
{
NdisZeroMemory( (UCHAR*)GlobalDeviceExtension, sizeof(DEVICE_EXTENSION) );
NdisZeroMemory( (UCHAR*)&ProtocolChar, sizeof(NDIS_PROTOCOL_CHARACTERISTICS) );
ProtocolChar.MajorNdisVersion = 0x03;
ProtocolChar.MinorNdisVersion = 0x0A;
ProtocolChar.Reserved = 0;
ProtocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete;
ProtocolChar.CloseAdapterCompleteHandler = PacketUnbindAdapterComplete;
ProtocolChar.SendCompleteHandler = PacketSendComplete;
ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete;
ProtocolChar.ResetCompleteHandler = PacketResetComplete;
ProtocolChar.RequestCompleteHandler = PacketRequestComplete;
ProtocolChar.ReceiveHandler = Packet_tap;
ProtocolChar.ReceiveCompleteHandler = PacketReceiveComplete;
ProtocolChar.StatusHandler = PacketStatus;
ProtocolChar.StatusCompleteHandler = PacketStatusComplete;
ProtocolChar.BindAdapterHandler = PacketBindAdapter;
ProtocolChar.UnbindAdapterHandler = PacketUnbindAdapter;
ProtocolChar.UnloadProtocolHandler = PacketUnload;
ProtocolChar.Name = ProtoName;
NdisRegisterProtocol( &Status,
&GlobalDeviceExtension->NdisProtocolHandle,
&ProtocolChar,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS) );
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreeMemory( GlobalDeviceExtension, sizeof( DEVICE_EXTENSION ) , 0 );
IF_TRACE( "Failed to register protocol with NDIS" );
INIT_LEAVE( "DriverEntry" );
return Status;
}
/*initializes the list of the open instances*/
NdisAllocateSpinLock( &(GlobalDeviceExtension->OpenSpinLock) );
InitializeListHead( &GlobalDeviceExtension->OpenList );
GlobalDeviceExtension->DriverObject = DriverObject;
if(Bind_Names() != NDIS_STATUS_SUCCESS) return NDIS_STATUS_FAILURE;
IF_TRACE( "protocol registered with NDIS!!!" );
INIT_LEAVE( "DriverEntry" );
return Status;
}
IF_TRACE( "Memory Failure" );
TRACE_LEAVE( "DriverEntry" );
return NDIS_STATUS_RESOURCES;
}
/************************************************************
Function used to associate the names of the network devices
with the internal NDIS names
INPUT:
OUTPUT: NDIS_STATUS_SUCCESS if succesful, otherwise NDIS_STATUS_FAILURE
************************************************************/
DWORD Bind_Names(void){
DWORD res;
VMMHKEY Key,Key1;
DWORD Klen,Klen1;
char NdisName[64];
char DevName[64];
int i=0;
PADAPTER_NAME AName;
TRACE_ENTER( "Bind_Names" );
// initialize the list of adapter names
InitializeListHead( &GlobalDeviceExtension->AdapterNames);
// change to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Net
res=VMM_RegOpenKey(HKEY_LOCAL_MACHINE,"SYSTEM",&Key);
res=VMM_RegOpenKey(Key,"CURRENTCONTROLSET",&Key);
res=VMM_RegOpenKey(Key,"SERVICES",&Key);
res=VMM_RegOpenKey(Key,"CLASS",&Key);
res=VMM_RegOpenKey(Key,"NET",&Key);
if(res!=ERROR_SUCCESS) return NDIS_STATUS_FAILURE;
Klen=64;
// Scan the list of the adapters
while(VMM_RegEnumKey(Key,i,NdisName,Klen)==ERROR_SUCCESS)
{
res=VMM_RegOpenKey(Key,NdisName,&Key1);
res=VMM_RegOpenKey(Key1,"NDIS",&Key1);
Klen1=64;
res=VMM_RegQueryValueEx(Key1,"LOGDRIVERNAME",NULL,NULL, DevName,&Klen1);
if(res!=ERROR_SUCCESS){
Klen=64;
i++;
continue;
}
NdisAllocateMemory( (PVOID *)&AName, sizeof(ADAPTER_NAME), 0, -1 );
if ( AName == NULL )
{
return NDIS_STATUS_FAILURE;
}
NdisMoveMemory(AName->realname,NdisName,Klen);
NdisMoveMemory(AName->devicename,DevName,Klen1);
AName->realnamestr.Length=strlen(NdisName);
AName->realnamestr.MaximumLength=Klen;
AName->realnamestr.Buffer=AName->realname;
InsertHeadList( &GlobalDeviceExtension->AdapterNames, &AName->ListElement);
Klen=64;
i++;
}
TRACE_LEAVE( "Bind_Names" );
if(i==0) return NDIS_STATUS_FAILURE;
else return NDIS_STATUS_SUCCESS;
}
/************************************************************
Callback function called by NDIS when the last insatnce of
the packet driver is closed by the capture driver,
i.e. when the driver is unloaded
INPUT:
OUTPUT:
************************************************************/
VOID NDIS_API PacketUnload()
{
TRACE_ENTER( "Unload" );
TRACE_LEAVE( "Unload" );
return;
}
/************************************************************
this function returns the descriptor of the adapter from
the device ID and process tag
INPUT: Name of the adapter to open
OUTPUT: instance of the driver
************************************************************/
POPEN_INSTANCE GetRunningAdapter(DWORD hDevice,DWORD tagProcess)
{
DWORD dwBytes = 0;
DWORD dwSec_Counter=1000; // Or something like that
BYTE *lpzName;
POPEN_INSTANCE pOpen;
PWRAPPER_MAC_BLOCK pWMBlock;
PNDIS_MAC_CHARACTERISTICS pNMChar;
PLIST_ENTRY pEntry;
PLIST_ENTRY pHead;
NdisAcquireSpinLock(&GlobalDeviceExtension->OpenSpinLock);
pHead = &(GlobalDeviceExtension->OpenList);
pOpen = 0;
pEntry=pHead->Flink;
do
{
pOpen = CONTAINING_RECORD( pEntry, OPEN_INSTANCE, ListElement );
if((pOpen->hDevice==hDevice)&&(pOpen->tagProcess==tagProcess)){
NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock );
return pOpen;
}
pEntry=pEntry->Flink;
dwSec_Counter--;
}while ((pEntry != pHead)&&(dwSec_Counter));
NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock );
return NULL;
}
/************************************************************
this function returns the NDIS name of an adapter given its
device name
INPUT: Name of the adapter to open
OUTPUT: instance of the driver
************************************************************/
PNDIS_STRING GetNDISAdapterName(BYTE* DeviceName)
{
PADAPTER_NAME pAdap;
UINT count=0;
PLIST_ENTRY pHead = &(GlobalDeviceExtension->AdapterNames);
PLIST_ENTRY pEntry;
TRACE_ENTER( "GetNDISAdapterName" );
pEntry=pHead->Flink;
if(IsListEmpty(pHead)){
if(Bind_Names()==NDIS_STATUS_FAILURE)
return NULL;
}
do {
pAdap = CONTAINING_RECORD( pEntry, ADAPTER_NAME, ListElement );
if(compare(pAdap->devicename,DeviceName)==1)return &(pAdap->realnamestr);
pEntry=pEntry->Flink;
}while (pEntry != pHead || count++>32);
TRACE_LEAVE( "GetNDISAdapterName" );
return NULL;
}
/************************************************************
This function evaluates the length of a string.
Useful to avoid the string library functions that are not
defined at this level
************************************************************/
ULONG
strlen( BYTE *s )
{
ULONG len = 0;
while ( *s++ ) len++;
return len;
}
/************************************************************
This function compares two strings
************************************************************/
BYTE compare(BYTE *s1,BYTE *s2)
{
TRACE_ENTER( "compare" );
while (*s1 && *s2)
{
if (*s1!=*s2) return (BYTE) 0;
s1++;
s2++;
}
TRACE_LEAVE( "compare" );
if ((*s1==0) && (*s2==0)) return (BYTE) 1;
else return (BYTE) 0;
}
/************************************************************
Return the names of all the MAC drivers on which the driver
is attached
INPUT: dwDDB e hDevice - parameters coming from the
DeviceIOControl procedure, not used here.
OUTPUT: pDiocParms - structure containing the returned buffer
************************************************************/
DWORD PacketGetMacNameList( DWORD dwDDB,
DWORD hDevice,
PDIOCPARAMETERS pDiocParms )
{
DWORD dwBytes = 0;
BYTE *lpzName;
PADAPTER_NAME pAdap;
PWRAPPER_MAC_BLOCK pWMBlock;
PNDIS_MAC_CHARACTERISTICS pNMChar;
ULONG uLength;
PLIST_ENTRY pHead = &(GlobalDeviceExtension->AdapterNames);
PLIST_ENTRY pEntry;
TRACE_ENTER( "PacketGetMacNameList" );
pEntry=pHead->Flink;
do {
pAdap = CONTAINING_RECORD( pEntry, ADAPTER_NAME, ListElement );
uLength = strlen( pAdap->devicename );
if ( uLength < pDiocParms->cbOutBuffer - dwBytes - 1 )
{
strcat( (BYTE*)(pDiocParms->lpvOutBuffer), pAdap->devicename );
strcat( (BYTE*)(pDiocParms->lpvOutBuffer), " " );
dwBytes += (uLength + 1);
}
else break;
pEntry=pEntry->Flink;
}while (pEntry != pHead);
*(ULONG*)(pDiocParms->lpcbBytesReturned) = dwBytes;
IF_TRACE_MSG( " Bytes Returned: %lu", *(ULONG*)(pDiocParms->lpcbBytesReturned) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -