📄 io.c
字号:
IoQueryMaintenanceBuffer(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_QUERY_MAINTENANCE_BUFFER_NODE *Query;
VRR_INFO_MAINTENANCE_BUFFER_NODE *Info;
MiniportAdapter *VA;
MaintBufNode *MBN;
Time Delta;
KIRQL OldIrql;
NTSTATUS Status;
Irp->IoStatus.Information = 0;
if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Query) ||
(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof *Info)) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
Query = (VRR_QUERY_MAINTENANCE_BUFFER_NODE *)
Irp->AssociatedIrp.SystemBuffer;
Info = (VRR_INFO_MAINTENANCE_BUFFER_NODE *)
Irp->AssociatedIrp.SystemBuffer;
//
// Return information about the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(&Query->VA);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
if (IsUnspecified(Query->Node.Address)) {
//
// Return query information for the first maintenance buffer node.
//
KeAcquireSpinLock(&VA->MaintBuf->Lock, &OldIrql);
ReturnQueryMaintenanceBufferNode(VA->MaintBuf->MBN, &Info->Query);
KeReleaseSpinLock(&VA->MaintBuf->Lock, OldIrql);
Irp->IoStatus.Information = sizeof Info->Query;
}
else {
//
// Return information about the specified maintenance buffer node.
//
KeAcquireSpinLock(&VA->MaintBuf->Lock, &OldIrql);
for (MBN = VA->MaintBuf->MBN; ; MBN = MBN->Next) {
if (MBN == NULL) {
KeReleaseSpinLock(&VA->MaintBuf->Lock, OldIrql);
Status = STATUS_INVALID_PARAMETER_2;
goto ReturnReleaseVA;
}
if (RtlEqualMemory(MBN->Address,
Query->Node.Address, SR_ADDR_LEN) &&
(MBN->InIf == Query->Node.InIF) &&
(MBN->OutIf == Query->Node.OutIF))
break;
}
//
// Return query information for the next maintenance buffer node.
//
ReturnQueryMaintenanceBufferNode(MBN->Next, &Info->Query);
//
// Return miscellaneous information about the maintenance buffer node.
//
Delta = IoTimeDelta();
Info->NextAckNum = MBN->NextAckNum;
Info->FirstAckReq = MBN->FirstAckReq + Delta;
Info->LastAckReq = MBN->LastAckReq + Delta;
Info->LastAckNum = MBN->LastAckNum;
Info->LastAckRcv = MBN->LastAckRcv + Delta;
Info->NumPackets = MBN->NumPackets;
Info->HighWater = MBN->HighWater;
Info->NumAckReqs = MBN->NumAckReqs;
Info->NumFastReqs = MBN->NumFastReqs;
Info->NumValidAcks = MBN->NumValidAcks;
Info->NumInvalidAcks = MBN->NumInvalidAcks;
Info->MBNCountPackets = MBN->MBNCountPackets;
Info->MBNTxSuccess = MBN->MBNTxSuccess;
Info->MBNRexmits = MBN->MBNRexmits;
Info->MBNTxFailed = MBN->MBNTxFailed;
KeReleaseSpinLock(&VA->MaintBuf->Lock, OldIrql);
Irp->IoStatus.Information = sizeof *Info;
}
ReturnQueryVirtualAdapter(VA, &Info->Query.VA);
Status = STATUS_SUCCESS;
ReturnReleaseVA:
#if 0
ReleaseVA(VA);
#endif
Return:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* IoResetStatistics
//
// Resets our counters and statistics gathering.
//
NTSTATUS
IoResetStatistics(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_QUERY_VIRTUAL_ADAPTER *Query;
MiniportAdapter *VA;
NTSTATUS Status;
Irp->IoStatus.Information = 0;
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Query) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
Query = (VRR_QUERY_VIRTUAL_ADAPTER *)
Irp->AssociatedIrp.SystemBuffer;
//
// Use the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(Query);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
MiniportResetStatistics(VA);
Status = STATUS_SUCCESS;
#if 0
ReleaseVA(VA);
#endif
Return:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* IoControlVirtualAdapter
//
// Handles requests to change attributes of a virtual adapter.
//
NTSTATUS
IoControlVirtualAdapter(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp,
IN boolint Persistent)
{
VRR_CONTROL_VIRTUAL_ADAPTER *Control;
MiniportAdapter *VA;
NTSTATUS Status;
Irp->IoStatus.Information = 0;
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Control) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
Control = (VRR_CONTROL_VIRTUAL_ADAPTER *) Irp->AssociatedIrp.SystemBuffer;
//
// Get the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(&Control->This);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
if (Persistent)
Status = MiniportPersistControl(VA, Control);
else
Status = MiniportControl(VA, Control);
Return:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* IoControlPhysicalAdapter
//
// Handles requests to change attributes of a physical adapter.
//
NTSTATUS
IoControlPhysicalAdapter(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_CONTROL_PHYSICAL_ADAPTER *Control;
MiniportAdapter *VA;
ProtocolAdapter *PA;
NTSTATUS Status;
Irp->IoStatus.Information = 0;
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Control) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
Control = (VRR_CONTROL_PHYSICAL_ADAPTER *) Irp->AssociatedIrp.SystemBuffer;
//
// Get the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(&Control->This.VA);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
//
// Get the specified physical adapter.
//
PA = FindPhysicalAdapterFromQuery(VA, &Control->This);
if (PA == NULL) {
Status = STATUS_INVALID_PARAMETER_2;
goto ReturnReleaseVA;
}
Status = ProtocolControl(PA, Control);
#if 0
ReleasePA(PA);
#endif
ReturnReleaseVA:
#if 0
ReleaseVA(VA);
#endif
Return:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* IoQueryVSet
//
// Handles queries for information about our VSet.
//
NTSTATUS
IoQueryVSet(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_QUERY_VSET *Query;
VRR_INFO_VSET *Info;
MiniportAdapter *VA = NULL;
NodeTable *NT;
NodeTableEntry *NTE;
KIRQL OldIrql;
NTSTATUS Status;
uint i;
PAGED_CODE();
Irp->IoStatus.Information = 0;
if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Query) ||
(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof *Info)) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
//
// Note that the Query and Info->Query structures overlap!
//
Query = (VRR_QUERY_VSET *) Irp->AssociatedIrp.SystemBuffer;
Info = (VRR_INFO_VSET *) Irp->AssociatedIrp.SystemBuffer;
//
// Return information about the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(&Query->VA);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
//
// Copy VSetLeft + self + VSetRight to info buffer.
//
RtlZeroMemory(Info->VSet,sizeof (Info->VSet));
NT = &VA->NT;
KeAcquireSpinLock(&NT->Lock, &OldIrql);
VSetToFlatBuffer(VA,Info->VSet);
Info->NTCount = VA->NT.Count;
KeReleaseSpinLock(&NT->Lock, OldIrql);
Irp->IoStatus.Information = sizeof *Info;
Status = STATUS_SUCCESS;
Return:
#if 0
if (VA != NULL)
ReleaseVA(VA);
#endif
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
//* IoQueryRouteTableEntry
//
// Handles queries for information about a route table entry.
//
NTSTATUS
IoQueryRouteTableEntry(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
VRR_QUERY_ROUTE_TABLE_ENTRY *Query;
VRR_INFO_ROUTE_TABLE_ENTRY *Info;
MiniportAdapter *VA = NULL;
RouteTableEntry *RTE;
KIRQL OldIrql;
NTSTATUS Status;
PAGED_CODE();
Irp->IoStatus.Information = 0;
if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof *Query) ||
(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof *Info)) {
Status = STATUS_INVALID_PARAMETER;
goto Return;
}
//
// Note that the Query and Info->Query structures overlap!
//
Query = (VRR_QUERY_ROUTE_TABLE_ENTRY *) Irp->AssociatedIrp.SystemBuffer;
Info = (VRR_INFO_ROUTE_TABLE_ENTRY *) Irp->AssociatedIrp.SystemBuffer;
//
// Return information about the specified virtual adapter.
//
VA = FindVirtualAdapterFromQuery(&Query->VA);
if (VA == NULL) {
Status = STATUS_INVALID_PARAMETER_1;
goto Return;
}
if (IsUnspecified(Query->EndpointA)) {
//
// Return the address of the first NTE.
//
KeAcquireSpinLock(&VA->RT.Lock, &OldIrql);
if (VA->RT.FirstRTE != SentinelRTE(&VA->RT)) {
RTE = VA->RT.FirstRTE;
// Ensure enough here to uniquely identify the entry.
RtlCopyMemory(Info->Query.EndpointA, RTE->A.Address, sizeof(VirtualAddress));
Info->Query.PathId = RTE->PathId;
Info->Query.addr = (uint)RTE; // gregos: debug then remove
}
KeReleaseSpinLock(&VA->RT.Lock, OldIrql);
Irp->IoStatus.Information = sizeof Info->Query;
}
else {
//
// Find the specified RTE.
//
KeAcquireSpinLock(&VA->RT.Lock, &OldIrql);
for (RTE = VA->RT.FirstRTE; ; RTE = RTE->Next) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -