?? packet.c
字號:
pRequest->Request.RequestType=NdisRequestSetInformation;
pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid;
pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=
OidData->Data;
pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=
OidData->Length;
} else {
pRequest->Request.RequestType=NdisRequestQueryInformation;
pRequest->Request.DATA.QUERY_INFORMATION.Oid= OidData->Oid;
pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=
OidData->Data;
pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=
OidData->Length;
}
//
// submit the request
//
NdisRequest(
&status,
open->AdapterHandle,
&pRequest->Request
);
} else {
//
// Buffer too small. The irp is completed by
// PacketRequestComplete routine.
//
status=NDIS_STATUS_FAILURE;
pRequest->Request.DATA.SET_INFORMATION.BytesRead=0;
pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0;
}
if (status != NDIS_STATUS_PENDING) {
DebugPrint(("Calling RequestCompleteHandler\n"));
PacketRequestComplete(
open,
&pRequest->Request,
status
);
}
}
return STATUS_PENDING;
}
VOID
PacketRequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status
)
/*++
Routine Description:
This routine is called when a protocol-initiated query or set
operation, begun with a call to NdisRequest that returned
NDIS_STATUS_PENDING, is completed.
Arguments:
Return Value:
--*/
{
POPEN_INSTANCE open;
PIO_STACK_LOCATION irpSp;
PIRP irp;
PINTERNAL_REQUEST pRequest;
UINT functionCode;
PPACKET_OID_DATA OidData;
DebugPrint(("RequestComplete\n"));
open = (POPEN_INSTANCE)ProtocolBindingContext;
pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
irp = pRequest->Irp;
if(Status == NDIS_STATUS_SUCCESS)
{
irpSp = IoGetCurrentIrpStackLocation(irp);
functionCode=irpSp->Parameters.DeviceIoControl.IoControlCode;
OidData = irp->AssociatedIrp.SystemBuffer;
if (functionCode == IOCTL_PROTOCOL_SET_OID) {
OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead;
} else {
if (functionCode == IOCTL_PROTOCOL_QUERY_OID) {
OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;
}
}
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information=irpSp->Parameters.DeviceIoControl.InputBufferLength;
} else {
irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
irp->IoStatus.Information = 0;
}
ExFreePool(pRequest);
IoCompleteRequest(irp, IO_NO_INCREMENT);
IoDecrement(open);
return;
}
VOID
PacketStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
)
/*++
Routine Description:
This routine is called to handle status changes indicated
by the underlying NDIS driver.
Arguments:
Return Value:
--*/
{
DebugPrint(("Indication Status: %0x, StatusBufferSize: %d\n",
Status, StatusBufferSize));
return;
}
VOID
PacketStatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
/*++
Routine Description:
This routine is called by NDIS, along with PacketStatus,
to report the start and end of an NDIS- or NIC-driver-
initiated status indicate operation.
Arguments:
Return Value:
--*/
{
DebugPrint(("StatusIndicationComplete\n"));
return;
}
NTSTATUS
PacketGetAdapterList(
IN PVOID Buffer,
IN ULONG Length,
IN OUT PULONG DataLength
)
/*++
Routine Description:
This routine walks the adapter list and gets the symbolic
link and NIC description and fills it in the Buffer.
The format of the information is given below.
Arguments:
Return Value:
--*/
{
ULONG requiredLength = 0, numOfAdapters = 0;
KIRQL oldIrql;
PLIST_ENTRY thisEntry, listHead;
POPEN_INSTANCE open;
DebugPrint(("Enter PacketGetAdapterList\n"));
KeAcquireSpinLock(&Globals.GlobalLock, &oldIrql);
//
// Walks the list to find out total space required for AdapterName
// and Symbolic Link.
//
listHead = &Globals.AdapterList;
for(thisEntry = listHead->Flink;
thisEntry != listHead;
thisEntry = thisEntry->Flink)
{
open = CONTAINING_RECORD(thisEntry, OPEN_INSTANCE, AdapterListEntry);
requiredLength += open->AdapterName.Length + sizeof(UNICODE_NULL);
requiredLength += open->SymbolicLink.Length + sizeof(UNICODE_NULL);
numOfAdapters++;
}
//
// We will return the data in the following format:
// numOfAdapters + One_Or_More("AdapterName\0" + "SymbolicLink\0") + UNICODE_NULL
// So let's include the numOfAdapters and UNICODE_NULL size
// to the total length.
//
requiredLength += sizeof(ULONG) + sizeof(UNICODE_NULL);
*DataLength = requiredLength;
if(requiredLength > Length) {
KeReleaseSpinLock(&Globals.GlobalLock, oldIrql);
return STATUS_BUFFER_TOO_SMALL;
}
*(PULONG)Buffer = numOfAdapters;
(PCHAR)Buffer += sizeof(ULONG);
//
// Copy the name and symbolic link of each adapter.
//
for(thisEntry = listHead->Flink;
thisEntry != listHead;
thisEntry = thisEntry->Flink)
{
open = CONTAINING_RECORD(thisEntry, OPEN_INSTANCE, AdapterListEntry);
RtlCopyMemory(Buffer, open->AdapterName.Buffer,
open->AdapterName.Length+sizeof(WCHAR));
(PCHAR)Buffer += open->AdapterName.Length+sizeof(WCHAR);
RtlCopyMemory(Buffer, open->SymbolicLink.Buffer,
open->SymbolicLink.Length+sizeof(WCHAR));
(PCHAR)Buffer += open->SymbolicLink.Length+sizeof(WCHAR);
}
*(PWCHAR)Buffer = UNICODE_NULL;
KeReleaseSpinLock(&Globals.GlobalLock, oldIrql);
return STATUS_SUCCESS;
}
VOID
PacketBindAdapter(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING DeviceName,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2
)
/*++
Routine Description:
Called by NDIS to bind to a miniport below.
Arguments:
Status - Return status of bind here.
BindContext - Can be passed to NdisCompleteBindAdapter
if this call is pended.
DeviceName - Device name to bind to. This is passed to
NdisOpenAdapter.
SystemSpecific1 - Can be passed to NdisOpenProtocolConfiguration to
read per-binding information
SystemSpecific2 - Unused for NDIS 4.0.
Return Value:
NDIS_STATUS_PENDING if this call is pended. In this case call
NdisCompleteBindAdapter to complete.
Anything else Completes this call synchronously
--*/
{
NDIS_STATUS status;
UINT mediumIndex;
USHORT length;
POPEN_INSTANCE open = NULL;
UNICODE_STRING unicodeDeviceName;
PDEVICE_OBJECT deviceObject = NULL;
PWSTR symbolicLink = NULL, deviceNameStr = NULL;
NDIS_MEDIUM mediumArray=NdisMedium802_3;// This sample only
//supports Ethernet medium.
DebugPrint(("Binding DeviceName %ws\n", DeviceName->Buffer));
do{
//
// Create a deviceobject for every adapter we bind to.
// To make a name for the deviceObject, we will append Packet_
// to the name portion of the input DeviceName.
//
unicodeDeviceName.Buffer = NULL;
length = DeviceName->Length + 7 * sizeof(WCHAR) + sizeof(UNICODE_NULL);
deviceNameStr = ExAllocatePool(NonPagedPool, length);
if (!deviceNameStr) {
DebugPrint(("Memory allocation for create symbolic failed\n"));
*Status = NDIS_STATUS_FAILURE;
break;
}
swprintf(deviceNameStr, L"\\Device\\Packet_%ws", &DeviceName->Buffer[8]);
RtlInitUnicodeString(&unicodeDeviceName, deviceNameStr);
DebugPrint(("Exported DeviceName %ws\n", unicodeDeviceName.Buffer));
//
// Create the deviceobject
//
status = IoCreateDevice(
Globals.DriverObject,
sizeof(OPEN_INSTANCE),
&unicodeDeviceName,
FILE_DEVICE_PROTOCOL,
0,
TRUE, // only one handle to the device at a time.
&deviceObject
);
if (status != STATUS_SUCCESS) {
DebugPrint(("CreateDevice Failed: %x\n", status));
*Status = NDIS_STATUS_FAILURE;
break;
}
deviceObject->Flags |= DO_DIRECT_IO;
open = (POPEN_INSTANCE) deviceObject->DeviceExtension;
open->DeviceObject = deviceObject;
//
// Create a symbolic link.
// We need to replace Device from \Device\Packet_{GUID} with DosDevices
// to create a symbolic link of the form \DosDevices\Packet_{GUID}
// There is a four character difference between these two
// strings.
//
length = unicodeDeviceName.Length + sizeof(UNICODE_NULL) +
(4 * sizeof(WCHAR));
symbolicLink = ExAllocatePool(NonPagedPool, length);
if (!symbolicLink) {
DebugPrint(("Memory allocation for create symbolic failed\n"));
*Status = NDIS_STATUS_FAILURE;
break;
}
swprintf(symbolicLink, L"\\DosDevices\\%ws",
&unicodeDeviceName.Buffer[8]);
RtlInitUnicodeString(&open->SymbolicLink,symbolicLink);
DebugPrint(("Symbolic Link: %ws\n", open->SymbolicLink.Buffer));
status = IoCreateSymbolicLink(
(PUNICODE_STRING) &open->SymbolicLink,
(PUNICODE_STRING) &unicodeDeviceName
);
if (status != STATUS_SUCCESS) {
DebugPrint(("Create symbolic failed\n"));
*Status = NDIS_STATUS_FAILURE;
break;
}
ExFreePool(unicodeDeviceName.Buffer);
unicodeDeviceName.Buffer = NULL;
//
// Allocate a packet pool for our xmit and receive packets
//
NdisAllocatePacketPool(
&status,
&open->PacketPool,
TRANSMIT_PACKETS,
sizeof(PACKET_RESERVED));
if (status != NDIS_STATUS_SUCCESS) {
DebugPrint(("Packet: Failed to allocate packet pool\n"));
break;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -