📄 packet.c
字号:
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
packet.c
Abstract:
Author:
Environment:
Kernel mode only.
Notes:
Future:
Revision History:
--*/
#include "stdarg.h"
#include "ntddk.h"
#include "ntiologc.h"
#include "ndis.h"
#include "ntddpack.h"
#include "debug.h"
#include "packet.h"
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
PacketReadRegistry(
IN PWSTR *MacDriverName,
IN PWSTR *PacketDriverName,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
PacketCreateSymbolicLink(
IN PUNICODE_STRING DeviceName,
IN BOOLEAN Create
);
NTSTATUS
PacketQueryRegistryRoutine(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
);
#if DBG
//
// Declare the global debug flag for this driver.
//
ULONG PacketDebugFlag = PACKET_DEBUG_LOUD;
#endif
PDEVICE_EXTENSION GlobalDeviceExtension;
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
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.
--*/
{
NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
UNICODE_STRING MacDriverName;
UNICODE_STRING UnicodeDeviceName;
PDEVICE_OBJECT DeviceObject = NULL;
PDEVICE_EXTENSION DeviceExtension = NULL;
NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS ErrorCode = STATUS_SUCCESS;
NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver");
ULONG DevicesCreated=0;
PWSTR BindString;
PWSTR ExportString;
PWSTR BindStringSave;
PWSTR ExportStringSave;
NDIS_HANDLE NdisProtocolHandle;
IF_LOUD(DbgPrint("\n\nPacket: DriverEntry\n");)
RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
ProtocolChar.MajorNdisVersion = 3;
ProtocolChar.MinorNdisVersion = 0;
ProtocolChar.Reserved = 0;
ProtocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete;
ProtocolChar.CloseAdapterCompleteHandler = PacketCloseAdapterComplete;
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.Name = ProtoName;
NdisRegisterProtocol(
&Status,
&NdisProtocolHandle,
&ProtocolChar,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
if (Status != NDIS_STATUS_SUCCESS) {
IF_LOUD(DbgPrint("Packet: Failed to register protocol with NDIS\n");)
return Status;
}
//
// Set up the device driver entry points.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = PacketOpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = PacketClose;
DriverObject->MajorFunction[IRP_MJ_READ] = PacketRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = PacketWrite;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PacketCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PacketIoControl;
DriverObject->DriverUnload = PacketUnload;
//
// Get the name of the Packet driver and the name of the MAC driver
// to bind to from the registry
//
Status=PacketReadRegistry(
&BindString,
&ExportString,
RegistryPath
);
if (Status != STATUS_SUCCESS) {
IF_LOUD(DbgPrint("Perf: Failed to read registry\n");)
goto RegistryError;
}
BindStringSave = BindString;
ExportStringSave = ExportString;
//
// create a device object for each entry
//
while (*BindString!= UNICODE_NULL && *ExportString!= UNICODE_NULL) {
//
// Create a counted unicode string for both null terminated strings
//
RtlInitUnicodeString(
&MacDriverName,
BindString
);
RtlInitUnicodeString(
&UnicodeDeviceName,
ExportString
);
//
// Advance to the next string of the MULTI_SZ string
//
BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
IF_LOUD(DbgPrint("Packet: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);)
//
// Create the device object
//
Status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&UnicodeDeviceName,
FILE_DEVICE_PROTOCOL,
0,
FALSE,
&DeviceObject
);
if (Status != STATUS_SUCCESS) {
IF_LOUD(DbgPrint("Perf: IoCreateDevice() failed:\n");)
break;
}
DevicesCreated++;
DeviceObject->Flags |= DO_DIRECT_IO;
DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
DeviceExtension->DeviceObject = DeviceObject;
//
// Save the the name of the MAC driver to open in the Device Extension
//
DeviceExtension->AdapterName=MacDriverName;
if (DevicesCreated == 1) {
DeviceExtension->BindString = BindStringSave;
DeviceExtension->ExportString = ExportStringSave;
}
DeviceExtension->NdisProtocolHandle=NdisProtocolHandle;
}
if (DevicesCreated > 0) {
//
// Managed to create at least on device.
//
return STATUS_SUCCESS;
}
ExFreePool(BindStringSave);
ExFreePool(ExportStringSave);
RegistryError:
NdisDeregisterProtocol(
&Status,
NdisProtocolHandle
);
Status=STATUS_UNSUCCESSFUL;
return(Status);
}
VOID
PacketUnload(
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PDEVICE_EXTENSION DeviceExtension;
NDIS_HANDLE NdisProtocolHandle;
NDIS_STATUS Status;
IF_LOUD(DbgPrint("Packet: Unload\n");)
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject != NULL) {
DeviceExtension = DeviceObject->DeviceExtension;
NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;
if (DeviceExtension->BindString != NULL) {
ExFreePool(DeviceExtension->BindString);
}
if (DeviceExtension->ExportString != NULL) {
ExFreePool(DeviceExtension->ExportString);
}
OldDeviceObject=DeviceObject;
DeviceObject=DeviceObject->NextDevice;
IoDeleteDevice(OldDeviceObject);
}
NdisDeregisterProtocol(
&Status,
NdisProtocolHandle
);
}
NTSTATUS
PacketIoControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the dispatch routine for create/open and close requests.
These requests complete successfully.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
Status is returned.
--*/
{
POPEN_INSTANCE Open;
PIO_STACK_LOCATION IrpSp;
PLIST_ENTRY RequestListEntry;
PINTERNAL_REQUEST pRequest;
ULONG FunctionCode;
NDIS_STATUS Status;
IF_LOUD(DbgPrint("Packet: IoControl\n");)
IrpSp = IoGetCurrentIrpStackLocation(Irp);
FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
Open=IrpSp->FileObject->FsContext;
RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,
&Open->RequestSpinLock);
if (RequestListEntry == NULL) {
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}
pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
pRequest->Irp=Irp;
IoMarkIrpPending(Irp);
Irp->IoStatus.Status = STATUS_PENDING;
IF_LOUD(DbgPrint("Packet: Function code is %08lx buff size=%08lx %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);)
if (FunctionCode == IOCTL_PROTOCOL_RESET) {
IF_LOUD(DbgPrint("Packet: IoControl - Reset request\n");)
ExInterlockedInsertTailList(
&Open->ResetIrpList,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -