📄 packet.c
字号:
// packet.c - DriverEntry, PacketUnload, GetOpen, GetMacName
// PacketIoControl, PacketStatus, PacketStatusComplete
//
// Original code by William Ingle (address unknown)
// debugged and extended by Chris Chlap (chrisc@fir.canberra.edu.au)
// Usage Notes at EOF
#include <basedef.h>
#include <vmm.h>
#include <debug.h>
#include <ndis.h>
#include <vwin32.h>
#include "packet.h"
#include "ntddpack.h"
#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG
PDEVICE_EXTENSION GlobalDeviceExtension = 0;
int Initialized = 0; // initialization flag
ULONG strlen(BYTE *s) {
ULONG len = 0;
while (*s++) len++;
return len;
}
//--------------------------------------------------------------------
//
// DriverEntry - initialize the VPACKET driver
//
//--------------------------------------------------------------------
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
NDIS_STRING ProtoName = NDIS_STRING_CONST("VPACKET");
NDIS_STATUS Status;
//
// Because the driver can be loaded once for each Netcard on the system,
// and because DriverEntry is called each time, we must ensure that
// initialization is performed only once.
//
if (Initialized)
return NDIS_STATUS_SUCCESS;
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 = PacketBindAdapterComplete;
ProtocolChar.CloseAdapterCompleteHandler = PacketUnbindAdapterComplete;
ProtocolChar.SendCompleteHandler = PacketSendComplete;
ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete;
ProtocolChar.ResetCompleteHandler = PacketResetComplete;
ProtocolChar.RequestCompleteHandler = PacketRequestComplete;
ProtocolChar.ReceiveHandler = PacketReceiveIndicate;
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);
Debug_Out("DriverEntry: ERROR: register protocol failed\n");
return Status;
}
// initialize open list
InitializeListHead(&GlobalDeviceExtension->OpenList);
// initialize global device extension
GlobalDeviceExtension->DriverObject = DriverObject;
Initialized = TRUE;
return Status;
}
Debug_Out("DriverEntry: ERROR: no resources\n");
return NDIS_STATUS_RESOURCES;
}
//--------------------------------------------------------------------
//
// PacketUnload - deregister the protocol, free remaining memory
// - called by NdisCloseAdapter when last adapter closed
//
//--------------------------------------------------------------------
VOID NDIS_API PacketUnload() {
PNDIS_STATUS Status;
if (GlobalDeviceExtension) {
NdisDeregisterProtocol(Status, GlobalDeviceExtension->NdisProtocolHandle);
if (Status == NDIS_STATUS_SUCCESS) {
NdisFreeMemory(GlobalDeviceExtension, sizeof(DEVICE_EXTENSION), 0);
GlobalDeviceExtension = 0;
}
Initialized = 0;
}
return;
}
//--------------------------------------------------------------------
//
// GetOpen - return a specified Open Instance
//
//--------------------------------------------------------------------
POPEN_INSTANCE GetOpen(DWORD handle) {
PLIST_ENTRY pHead = &(GlobalDeviceExtension->OpenList);
PLIST_ENTRY pTemp;
POPEN_INSTANCE Open;
if (!GlobalDeviceExtension) {
Debug_Out("GetOpen: GDE is NULL\n");
return (POPEN_INSTANCE) NULL;
}
// search the list for the Open Instance containing the specified handle
for (pTemp=pHead->Flink; pTemp != pHead; pTemp=pTemp->Flink) {
Open = CONTAINING_RECORD(pTemp, OPEN_INSTANCE, ListElement);
if (Open)
if (Open->hDevice == handle)
return Open;
}
Debug_Out("GetOpen: returning NULL\n");
return (POPEN_INSTANCE) NULL; // just in case
}
//--------------------------------------------------------------------
//
// GetMacName - get the netcard name
//
//--------------------------------------------------------------------
DWORD GetMacName(POPEN_INSTANCE Open,
PDIOCPARAMETERS pDiocParms)
{
DWORD dwBytes = 0;
BYTE *lpzName;
ULONG uLength;
PWRAPPER_MAC_BLOCK pWMBlock;
PNDIS_MAC_CHARACTERISTICS pNMChar;
pWMBlock = ((PWRAPPER_OPEN_BLOCK)(Open->AdapterHandle))->MacHandle;
pNMChar = &pWMBlock->MacCharacteristics;
lpzName = pNMChar->Name.Buffer;
uLength = strlen(lpzName);
if (uLength < pDiocParms->cbOutBuffer - 1) {
strcat((BYTE*)(pDiocParms->lpvOutBuffer), lpzName);
dwBytes = uLength + 1;
}
*(ULONG*)(pDiocParms->lpcbBytesReturned) = dwBytes;
return NDIS_STATUS_SUCCESS;
}
//--------------------------------------------------------------------
//
// PacketIoControl - called from applications
//
//--------------------------------------------------------------------
DWORD _stdcall PacketIOControl(DWORD dwService,
DWORD dwDDB,
DWORD hDevice,
PDIOCPARAMETERS pDiocParms)
{
POPEN_INSTANCE Open;
NDIS_STATUS Status;
NDIS_STRING AdapterName = NDIS_STRING_CONST("0000");
switch (dwService) {
case DIOC_OPEN:
return NDIS_STATUS_SUCCESS;
case DIOC_CLOSEHANDLE:
Open = GetOpen(hDevice);
if (Open)
PacketUnbindAdapter(&Status, Open, NULL);
return NDIS_STATUS_SUCCESS;
case IOCTL_PROTOCOL_BIND:
strcpy(AdapterName.Buffer, (BYTE *)pDiocParms->lpvInBuffer);
PacketBindAdapter(&Status,
GlobalDeviceExtension->NdisProtocolHandle,
&AdapterName,
(PVOID) hDevice, /* special */
NULL);
// Note: If the above usage of the 4'th arg to PacketBindAdapter
// causes problems, use a global variable instead.
if (Status == NDIS_STATUS_SUCCESS) {
*(DWORD *)(pDiocParms->lpcbBytesReturned) = 1; /* OK */
break;
}
*(DWORD *)(pDiocParms->lpcbBytesReturned) = -1; /* SYSERR */
break;
case IOCTL_PROTOCOL_UNBIND:
// Not needed, Unbinding is done on close.
break;
case IOCTL_PROTOCOL_RESET:
Open = GetOpen(hDevice);
if (Open)
PacketReset(&Status, Open);
break;
case IOCTL_PROTOCOL_SET_OID:
case IOCTL_PROTOCOL_QUERY_OID:
case IOCTL_PROTOCOL_STATISTICS:
Open = GetOpen(hDevice);
if (Open)
return PacketRequest(Open, dwService, dwDDB, hDevice, pDiocParms);
break;
case IOCTL_PROTOCOL_READ:
Open = GetOpen(hDevice);
if (Open)
return PacketRead(Open, dwDDB, hDevice, pDiocParms);
break;
case IOCTL_PROTOCOL_WRITE:
Open = GetOpen(hDevice);
if (Open)
return PacketWrite(Open, dwDDB, hDevice, pDiocParms);
break;
case IOCTL_PROTOCOL_MACNAME:
Open = GetOpen(hDevice);
if (Open)
GetMacName(Open, pDiocParms);
break;
default:
Debug_Out("PacketIoControl: ERROR: unknown DIOC\n");
*(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
break;
}
return NDIS_STATUS_SUCCESS;
}
//--------------------------------------------------------------------
//
// PacketStatus - get packet status
//
//--------------------------------------------------------------------
VOID PacketStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize)
{
return;
}
//--------------------------------------------------------------------
//
// PacketStatusComplete - completion handler
//
//--------------------------------------------------------------------
VOID NDIS_API PacketStatusComplete(IN NDIS_HANDLE ProtocolBindingContext)
{
return;
}
//--------------------------------------------------------------------
//
// USAGE
//
//--------------------------------------------------------------------
/*
This version of the VPACKET VXD supports dynamic loading. The driver is
loaded with the WIN32 CreateFile function and the returned handle used
in subsequent calls to WIN32 DevIoControl.
Supported operations: IOCTL_PROTOCOL_QUERY_OID
IOCTL_PROTOCOL_SET_OID
IOCTL_PROTOCOL_STATISTICS
IOCTL_PROTOCOL_RESET
IOCTL_PROTOCOL_READ
IOCTL_PROTOCOL_WRITE
IOCTL_PROTOCOL_MACNAME
IOCTL_PROTOCOL_BIND
After loading, an App must first BIND the protocol to the Netcard of choice.
Netcards have names like "0000", "0001" and so on. These names can be found
in the Registry at:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Net
Thereafter, any of the supported operations can be performed on the bound
Netcard.
To use multiple Netcards, simply CreateFile and Bind for each Netcard. Use
the handle returned by each CreateFile to access the desired Netcard.
Be SURE to close all handles before exiting. On closing the last handle,
the driver will be removed from memory.
Note: Because the PPPMAC driver is NOT fully NDIS3 compatible,
the WRITE operation on PPPMAC does not work. Neither are
driver statistics returned. However, everything else works.
This driver was adapted for use in the P32 programming environment used at
the University of Canberra, Australia. The environment allows students to
program (amongst other things) network protocols, which require direct access
to the NDIS3 interface. The current P32 software is available from:
ftp.canberra.edu.au/pub/ise/p32/p32.exe
Report bugs to: Dipl.-Ing. Christopher Chlap
University of Canberra, Australia
chrisc@fir.canberra.edu.au
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -