⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.c

📁 WinAoE is an open source GPLv3 driver for using AoE (ATA over Ethernet) on Microsoft Windows
💻 C
📖 第 1 页 / 共 2 页
字号:
  PHEADER Header;
  PUCHAR HeaderCopy, Data;
  UINT BytesTransferred;
#ifdef DEBUGALLPROTOCOLCALLS
  DbgPrint("ProtocolReceive\n");
#endif

  if (HeaderBufferSize != sizeof(HEADER)) {
    DbgPrint("ProtocolReceive HeaderBufferSize %d != sizeof(HEADER) %d\n");
    return NDIS_STATUS_NOT_ACCEPTED;
  }
  Header = (PHEADER)HeaderBuffer;
  if (ntohs(Header->Protocol) != AOEPROTOCOLID) return NDIS_STATUS_NOT_ACCEPTED;

  if (LookaheadBufferSize == PacketSize) {
    AoEReply(Header->SourceMac, Header->DestinationMac, LookAheadBuffer, PacketSize);
    return NDIS_STATUS_SUCCESS;
  }

  if ((HeaderCopy = (PUCHAR)ExAllocatePool(NonPagedPool, HeaderBufferSize)) == NULL) {
    DbgPrint("ProtocolReceive ExAllocatePool HeaderCopy\n");
    return NDIS_STATUS_NOT_ACCEPTED;
  }
  RtlCopyMemory(HeaderCopy, HeaderBuffer, HeaderBufferSize);
  if ((Data = (PUCHAR)ExAllocatePool(NonPagedPool, PacketSize)) == NULL) {
    DbgPrint("ProtocolReceive ExAllocatePool HeaderData\n");
    ExFreePool(HeaderCopy);
    return NDIS_STATUS_NOT_ACCEPTED;
  }
  NdisAllocatePacket(&Status, &Packet, Context->PacketPoolHandle);
  if (!NT_SUCCESS(Status)) {
    Error("ProtocolReceive NdisAllocatePacket", Status);
    ExFreePool(Data);
    ExFreePool(HeaderCopy);
    return NDIS_STATUS_NOT_ACCEPTED;
  }

  NdisAllocateBuffer(&Status, &Buffer, Context->BufferPoolHandle, Data, PacketSize);
  if (!NT_SUCCESS(Status)) {
    Error("ProtocolReceive NdisAllocateBuffer (Data)", Status);
    NdisFreePacket(Packet);
    ExFreePool(Data);
    ExFreePool(HeaderCopy);
    return NDIS_STATUS_NOT_ACCEPTED;
  }
  NdisChainBufferAtFront(Packet, Buffer);

  NdisAllocateBuffer(&Status, &Buffer, Context->BufferPoolHandle, HeaderCopy, PacketSize);
  if (!NT_SUCCESS(Status)) {
    Error("ProtocolReceive NdisAllocateBuffer (HeaderCopy)", Status);
    NdisUnchainBufferAtFront(Packet, &Buffer);
    NdisFreeBuffer(Buffer);
    NdisFreePacket(Packet);
    ExFreePool(Data);
    ExFreePool(HeaderCopy);
    return NDIS_STATUS_NOT_ACCEPTED;
  }
  NdisChainBufferAtBack(Packet, Buffer);

  NdisTransferData(&Status, Context->BindingHandle, MacReceiveContext, 0, PacketSize, Packet, &BytesTransferred);
  if (Status != NDIS_STATUS_PENDING) ProtocolTransferDataComplete(ProtocolBindingContext, Packet, Status, BytesTransferred);
  return Status;
}

VOID STDCALL ProtocolReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext) {
#ifdef DEBUGALLPROTOCOLCALLS
  DbgPrint("ProtocolReceiveComplete\n");
#endif
}

VOID STDCALL ProtocolStatus(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS GeneralStatus, IN PVOID StatusBuffer, IN UINT StatusBufferSize) {
#if !defined(DEBUGMOSTPROTOCOLCALLS) && !defined(DEBUGALLPROTOCOLCALLS)
  if (!NT_SUCCESS(GeneralStatus))
#endif
  Error("ProtocolStatus", GeneralStatus);
}

VOID STDCALL ProtocolStatusComplete(IN NDIS_HANDLE  ProtocolBindingContext) {
#if defined(DEBUGMOSTPROTOCOLCALLS) || defined(DEBUGALLPROTOCOLCALLS)
  DbgPrint("ProtocolStatusComplete\n");
#endif
}

VOID STDCALL ProtocolBindAdapter(OUT PNDIS_STATUS StatusOut, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2) {
  PBINDINGCONTEXT Context, Walker;
  NDIS_STATUS Status;
  NDIS_STATUS OpenErrorStatus;
  UINT SelectedMediumIndex, MTU;
  NDIS_MEDIUM MediumArray[] = {NdisMedium802_3};
  NDIS_STRING AdapterInstanceName;
  NDIS_REQUEST Request;
  ULONG InformationBuffer = NDIS_PACKET_TYPE_DIRECTED;
  UCHAR Mac[6];
  KIRQL Irql;
#if defined(DEBUGMOSTPROTOCOLCALLS) || defined(DEBUGALLPROTOCOLCALLS)
  DbgPrint("ProtocolBindAdapter\n");
#endif

  if ((Context = (NDIS_HANDLE)ExAllocatePool(NonPagedPool, sizeof(BINDINGCONTEXT))) == NULL) {
    DbgPrint("ProtocolBindAdapter ExAllocatePool\n");
    *StatusOut = NDIS_STATUS_RESOURCES;
    return;
  }
  Context->Next = NULL;
  KeInitializeEvent(&Context->Event, SynchronizationEvent, FALSE);

  NdisAllocatePacketPool(&Status, &Context->PacketPoolHandle, POOLSIZE, (4 * sizeof(VOID*)));
  if (!NT_SUCCESS(Status)) {
    Error("ProtocolBindAdapter NdisAllocatePacketPool", Status);
    ExFreePool(Context);
    *StatusOut = NDIS_STATUS_RESOURCES;
    return;
  }

  NdisAllocateBufferPool(&Status, &Context->BufferPoolHandle, POOLSIZE);
  if (!NT_SUCCESS(Status)) {
    Error("ProtocolBindAdapter NdisAllocateBufferPool", Status);
    NdisFreePacketPool(Context->PacketPoolHandle);
    ExFreePool(Context);
    *StatusOut = NDIS_STATUS_RESOURCES;
    return;
  }

  NdisOpenAdapter(&Status, &OpenErrorStatus, &Context->BindingHandle, &SelectedMediumIndex, MediumArray, (sizeof(MediumArray) / sizeof(NDIS_MEDIUM)), ProtocolHandle, Context, DeviceName, 0, NULL);
  if (!NT_SUCCESS(Status)) {
    DbgPrint("ProtocolBindAdapter NdisOpenAdapter 0x%lx 0x%lx\n", Status, OpenErrorStatus);
    NdisFreePacketPool(Context->PacketPoolHandle);
    NdisFreeBufferPool(Context->BufferPoolHandle);
    ExFreePool(Context->AdapterName);
    ExFreePool(Context->DeviceName);
    ExFreePool(Context);
    *StatusOut = Status;
    return;
  }
  if (SelectedMediumIndex != 0) DbgPrint("ProtocolBindAdapter NdisOpenAdapter SelectedMediumIndex: %d\n", SelectedMediumIndex);

  Context->AdapterName = NULL;
  if (NT_SUCCESS(Status = NdisQueryAdapterInstanceName(&AdapterInstanceName, Context->BindingHandle))) {
    if ((Context->AdapterName = (PWCHAR)ExAllocatePool(NonPagedPool, AdapterInstanceName.Length + sizeof(WCHAR))) == NULL) {
      DbgPrint("ProtocolBindAdapter ExAllocatePool AdapterName\n");
    } else {
      RtlZeroMemory(Context->AdapterName, AdapterInstanceName.Length + sizeof(WCHAR));
      RtlCopyMemory(Context->AdapterName, AdapterInstanceName.Buffer, AdapterInstanceName.Length);
    }
    NdisFreeMemory(AdapterInstanceName.Buffer, 0, 0);
  } else {
    Error("ProtocolBindAdapter NdisQueryAdapterInstanceName", Status);
  }

  Context->DeviceName = NULL;
  if (DeviceName->Length > 0) {
    if ((Context->DeviceName = (PWCHAR)ExAllocatePool(NonPagedPool, DeviceName->Length + sizeof(WCHAR))) == NULL) {
      DbgPrint("ProtocolBindAdapter ExAllocatePool DeviceName\n");
    } else {
      RtlZeroMemory(Context->DeviceName, DeviceName->Length + sizeof(WCHAR));
      RtlCopyMemory(Context->DeviceName, DeviceName->Buffer, DeviceName->Length);
    }
  }

  if (Context->AdapterName != NULL) DbgPrint("Adapter: %S\n", Context->AdapterName);
  if (Context->DeviceName != NULL) DbgPrint("Device Name: %S\n", Context->DeviceName);
  if ((Context->AdapterName == NULL) && (Context->DeviceName == NULL)) DbgPrint("Unnamed Adapter...\n");

  Request.RequestType = NdisRequestQueryInformation;
  Request.DATA.QUERY_INFORMATION.Oid = OID_802_3_CURRENT_ADDRESS;
  Request.DATA.QUERY_INFORMATION.InformationBuffer = Mac;
  Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(Mac);

  KeResetEvent(&Context->Event);
  NdisRequest(&Status, Context->BindingHandle, &Request);
  if (Status == NDIS_STATUS_PENDING) {
    KeWaitForSingleObject(&Context->Event, Executive, KernelMode, FALSE, NULL);
    Status = Context->Status;
  }
  if (!NT_SUCCESS(Status)) {
    Error("ProtocolBindAdapter NdisRequest (Mac)", Status);
  } else {
    RtlCopyMemory(Context->Mac, Mac, 6);
    DbgPrint("Mac: %02x:%02x:%02x:%02x:%02x:%02x\n", Mac[0], Mac[1], Mac[2], Mac[3], Mac[4], Mac[5]);
  }

  Request.RequestType = NdisRequestQueryInformation;
  Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_FRAME_SIZE;
  Request.DATA.QUERY_INFORMATION.InformationBuffer = &MTU;
  Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(MTU);

  KeResetEvent(&Context->Event);
  NdisRequest(&Status, Context->BindingHandle, &Request);
  if (Status == NDIS_STATUS_PENDING) {
    KeWaitForSingleObject(&Context->Event, Executive, KernelMode, FALSE, NULL);
    Status = Context->Status;
  }
  if (!NT_SUCCESS(Status)) {
    Error("ProtocolBindAdapter NdisRequest (MTU)", Status);
  } else {
    Context->MTU = MTU;
    DbgPrint("MTU: %d\n", MTU);
  }

  Request.RequestType = NdisRequestSetInformation;
  Request.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
  Request.DATA.SET_INFORMATION.InformationBuffer = &InformationBuffer;
  Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(InformationBuffer);

  KeResetEvent(&Context->Event);
  NdisRequest(&Status, Context->BindingHandle, &Request);
  if (Status == NDIS_STATUS_PENDING) {
    KeWaitForSingleObject(&Context->Event, Executive, KernelMode, FALSE, NULL);
    Status = Context->Status;
  }
  if (!NT_SUCCESS(Status)) Error("ProtocolBindAdapter NdisRequest (filter)", Status);

  KeAcquireSpinLock(&SpinLock, &Irql);
  if (BindingContextList == NULL) {
    BindingContextList = Context;
  } else {
    for (Walker = BindingContextList; Walker->Next != NULL; Walker = Walker->Next);
    Walker->Next = Context;
  }
  KeReleaseSpinLock(&SpinLock, Irql);

  AoEResetProbe();
  *StatusOut = NDIS_STATUS_SUCCESS;
}

VOID STDCALL ProtocolUnbindAdapter(OUT PNDIS_STATUS StatusOut, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext) {
  PBINDINGCONTEXT Context = (PBINDINGCONTEXT)ProtocolBindingContext;
  PBINDINGCONTEXT Walker, PreviousContext;
  NDIS_STATUS Status;
  KIRQL Irql;
#if defined(DEBUGMOSTPROTOCOLCALLS) || defined(DEBUGALLPROTOCOLCALLS)
  DbgPrint("ProtocolUnbindAdapter\n");
#endif

  PreviousContext = NULL;
  KeAcquireSpinLock(&SpinLock, &Irql);
  for (Walker = BindingContextList; Walker != Context && Walker != NULL; Walker = Walker->Next) PreviousContext = Walker;
  if (Walker == NULL) {
    DbgPrint("Context not found in BindingContextList!!\n");
    KeReleaseSpinLock(&SpinLock, Irql);
    return;
  }
  if (PreviousContext == NULL) {
    BindingContextList = Walker->Next;
  } else {
    PreviousContext->Next = Walker->Next;
  }
  KeReleaseSpinLock(&SpinLock, Irql);

  NdisCloseAdapter(&Status, Context->BindingHandle);
  if (!NT_SUCCESS(Status)) Error("ProtocolUnbindAdapter NdisCloseAdapter", Status);
  NdisFreePacketPool(Context->PacketPoolHandle);
  NdisFreeBufferPool(Context->BufferPoolHandle);
  ExFreePool(Context);
  if (BindingContextList == NULL) KeSetEvent(&ProtocolStopEvent, 0, FALSE);
  *StatusOut = NDIS_STATUS_SUCCESS;
}

NDIS_STATUS STDCALL ProtocolPnPEvent(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT NetPnPEvent) {
#if defined(DEBUGMOSTPROTOCOLCALLS) || defined(DEBUGALLPROTOCOLCALLS)
  DbgPrint("ProtocolPnPEvent %s\n", NetEventString(NetPnPEvent->NetEvent));
#endif
  if (ProtocolBindingContext == NULL && NetPnPEvent->NetEvent == NetEventReconfigure) {
#ifdef _MSC_VER
    NdisReEnumerateProtocolBindings(ProtocolHandle);
#else
    DbgPrint("No vector to NdisReEnumerateProtocolBindings\n");
#endif
  }
  if (NetPnPEvent->NetEvent == NetEventQueryRemoveDevice) {
    return NDIS_STATUS_FAILURE;
  } else {
    return NDIS_STATUS_SUCCESS;
  }
}

PCHAR STDCALL NetEventString(IN NET_PNP_EVENT_CODE NetEvent) {
  switch (NetEvent) {
    case NetEventSetPower:           return "NetEventSetPower";
    case NetEventQueryPower:         return "NetEventQueryPower";
    case NetEventQueryRemoveDevice:  return "NetEventQueryRemoveDevice";
    case NetEventCancelRemoveDevice: return "NetEventCancelRemoveDevice";
    case NetEventReconfigure:        return "NetEventReconfigure";
    case NetEventBindList:           return "NetEventBindList";
    case NetEventBindsComplete:      return "NetEventBindsComplete";
    case NetEventPnPCapabilities:    return "NetEventPnPCapabilities";
    default:                         return "NetEventUnknown";
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -