epacket.c

来自「pwlib源码库」· C语言 代码 · 共 996 行 · 第 1/3 页

C
996
字号
  PINTERNAL_REQUEST pRequest;  PPACKET_RESERVED  pReserved;  EPACKET_OID *  OidData;  NDIS_STATUS       Status;    // Acquire request element from list  NdisAcquireSpinLock(&Open->RequestSpinLock);    if (IsListEmpty(&Open->RequestList)) {     *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;    NdisReleaseSpinLock(&Open->RequestSpinLock);    return NDIS_STATUS_SUCCESS;  }  RequestListEntry = RemoveHeadList(&Open->RequestList);  NdisReleaseSpinLock(&Open->RequestSpinLock);    pReserved = CONTAINING_RECORD(RequestListEntry, PACKET_RESERVED, ListElement);  pRequest  = CONTAINING_RECORD(pReserved, INTERNAL_REQUEST, Reserved);  OidData   = (EPACKET_OID*)(pDiocParms->lpvInBuffer);  if ((pDiocParms->cbInBuffer != pDiocParms->cbOutBuffer) ||      (pDiocParms->cbInBuffer < sizeof(*OidData) - sizeof(OidData->Data) + OidData->Length)) {    *(DWORD *)pDiocParms->lpcbBytesReturned = 1;    return NDIS_STATUS_BUFFER_TOO_SHORT;  }  // The buffer is valid  pReserved->lpBuffer          = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);  pReserved->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));  pReserved->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));  pReserved->cbBuffer          = pDiocParms->cbInBuffer;  pReserved->hDevice           = pDiocParms->hDevice;  pReserved->tagProcess        = pDiocParms->tagProcess;    if (FunctionCode == IOCTL_EPACKET_SET_OID) {                          pRequest->Request.RequestType                                  = NdisRequestSetInformation;    pRequest->Request.DATA.SET_INFORMATION.Oid                     = OidData->Oid;    pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = OidData->Length;    pRequest->Request.DATA.SET_INFORMATION.InformationBuffer       = OidData->Data;  }   else {    if (OidData->Oid >= 0x01000000)      pRequest->Request.RequestType = NdisRequestQueryInformation;    else      pRequest->Request.RequestType = NdisRequestGeneric1;    pRequest->Request.DATA.QUERY_INFORMATION.Oid                     = OidData->Oid;    pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength = OidData->Length;    pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer       = OidData->Data;  }  // submit the request  NdisRequest(&Status, Open->AdapterHandle, &pRequest->Request);  if (Status == NDIS_STATUS_PENDING)    return(-1);      // This will make DeviceIOControl return ERROR_IO_PENDING  PacketRequestComplete(Open, &pRequest->Request, Status);  return Status;}///////////////////////////////////////////////////////////////////////////////NDIS_STATUS NDIS_API PacketReceiveIndicate(IN NDIS_HANDLE ProtocolBindingContext,                                           IN NDIS_HANDLE MacReceiveContext,                                           IN PVOID       HeaderBuffer,                                           IN UINT        HeaderBufferSize,                                           IN PVOID       LookaheadBuffer,                                           IN UINT        LookaheadBufferSize,                                           IN UINT        PacketSize){  // upcall on packet arrival  POPEN_INSTANCE      Open;  PLIST_ENTRY         PacketListEntry;  PNDIS_PACKET        pPacket;  NDIS_STATUS         Status;  UINT                BytesTransfered = 0;  PPACKET_RESERVED    pReserved;  if (HeaderBufferSize != ETHERNET_HEADER_LENGTH)    return NDIS_STATUS_NOT_ACCEPTED;    Open = (POPEN_INSTANCE) ProtocolBindingContext;    //  See if there are any pending reads that we can satisfy  NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 5.11.97    if (IsListEmpty(&Open->RcvList)) {     NdisReleaseSpinLock(&Open->RcvQSpinLock);    return NDIS_STATUS_NOT_ACCEPTED;  }  PacketListEntry = RemoveHeadList(&Open->RcvList);  NdisReleaseSpinLock(&Open->RcvQSpinLock);    pReserved = CONTAINING_RECORD(PacketListEntry, PACKET_RESERVED, ListElement);  pPacket = CONTAINING_RECORD(pReserved, NDIS_PACKET, ProtocolReserved);    // Copy the MAC header  NdisMoveMemory(RESERVED(pPacket)->lpBuffer, HeaderBuffer, HeaderBufferSize);  //  Call the Mac to transfer the data portion of the packet  NdisTransferData(&Status, Open->AdapterHandle, MacReceiveContext, 0, PacketSize, pPacket, &BytesTransfered);  if (Status == NDIS_STATUS_PENDING)    return NDIS_STATUS_PENDING;  if (Status == NDIS_STATUS_SUCCESS) {    PacketTransferDataComplete(Open, pPacket, Status, BytesTransfered);    return NDIS_STATUS_SUCCESS;  }  PacketTransferDataComplete(Open, pPacket, Status, 0);  return NDIS_STATUS_SUCCESS;}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext){  // upcall when receive complete}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketStatus(IN NDIS_HANDLE ProtocolBindingContext,                           IN NDIS_STATUS Status,                           IN PVOID       StatusBuffer,                           IN UINT        StatusBufferSize){  // get packet status}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketStatusComplete(IN NDIS_HANDLE ProtocolBindingContext){  // completion handler}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketBindAdapterComplete(IN NDIS_HANDLE  ProtocolBindingContext,                                        IN NDIS_STATUS  Status,                                        IN NDIS_STATUS  OpenErrorStatus){  // upcall on Bind completion  POPEN_INSTANCE Open = (POPEN_INSTANCE)ProtocolBindingContext;  // If the binding is unsuccessful then we deallocate data structures in   // preparation for unloading  if (Status != NDIS_STATUS_SUCCESS) {    NdisFreeSpinLock(&Open->RequestSpinLock);    NdisFreeSpinLock(&Open->RcvQSpinLock);    NdisFreeBufferPool(Open->BufferPool);    NdisFreePacketPool(Open->PacketPool);    NdisFreeMemory(Open, sizeof(OPEN_INSTANCE), 0);  }  else {    // Insert New Adapter into list    InsertTailList(&GlobalDeviceExtension->OpenList, &Open->ListElement);  }}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketBindAdapter(OUT PNDIS_STATUS pStatus,                                IN  NDIS_HANDLE  BindAdapterContext,                                IN  PNDIS_STRING pAdapterName,                                IN  PVOID        SystemSpecific1,                                IN  PVOID        SystemSpecific2){  //   bind this driver to a NIC    POPEN_INSTANCE    oiNew;  NDIS_STATUS	    ErrorStatus, AllocStatus;  UINT              Medium;  NDIS_MEDIUM       MediumArray = NdisMedium802_3;  UINT              i;  //  allocate some memory for the open structure  NdisAllocateMemory((PVOID *)&oiNew, sizeof(OPEN_INSTANCE), 0, -1);  if (oiNew == NULL) { // not enough memory    *pStatus = NDIS_STATUS_RESOURCES;    return;  }    NdisZeroMemory((PVOID)oiNew, sizeof(OPEN_INSTANCE));    // Save Binding Context  oiNew->BindAdapterContext = BindAdapterContext;    // Save the device handle  oiNew->hDevice = (DWORD)SystemSpecific1;    // Allocate a packet pool for our xmit and receive packets  NdisAllocatePacketPool(&AllocStatus,                         &(oiNew->PacketPool),                         TRANSMIT_PACKETS,                         sizeof(PACKET_RESERVED));  if (AllocStatus != NDIS_STATUS_SUCCESS) { // not enough memory    NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0);    *pStatus = NDIS_STATUS_RESOURCES;    return;  }    // Allocate a buffer pool for our xmit and receive buffers  NdisAllocateBufferPool(&AllocStatus, &(oiNew->BufferPool), TRANSMIT_PACKETS);  if (AllocStatus != NDIS_STATUS_SUCCESS) { // not enough memory    NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0);    *pStatus = NDIS_STATUS_RESOURCES;    return;  }  //  list to hold irp's that want to reset the adapter  NdisAllocateSpinLock(&oiNew->ResetSpinLock);  InitializeListHead(&oiNew->ResetIrpList);  //  Initialize list for holding pending read requests  NdisAllocateSpinLock(&oiNew->RcvQSpinLock);  InitializeListHead(&oiNew->RcvList);    //  Initialize the request list  NdisAllocateSpinLock(&oiNew->RequestSpinLock);  InitializeListHead(&oiNew->RequestList);    //  link up the request stored in our open block  for (i = 0; i < MAX_REQUESTS; i++) {    // Braces are required as InsertTailList macro has multiple statements in it    InsertTailList(&oiNew->RequestList, &oiNew->Requests[i].Reserved.ListElement);  }    //  Try to open the MAC  NdisOpenAdapter(pStatus, &ErrorStatus, &oiNew->AdapterHandle, &Medium, &MediumArray, 1,                  GlobalDeviceExtension->NdisProtocolHandle, oiNew, pAdapterName, 0, NULL);    //  Save the status returned by NdisOpenAdapter for completion routine  oiNew->Status = *pStatus;    switch (*pStatus) {    case NDIS_STATUS_PENDING:      break;        case NDIS_STATUS_SUCCESS:      ErrorStatus = NDIS_STATUS_SUCCESS;          // fall through to completion routine with oiNew->Status       // set to !NDIS_STATUS_PENDING        default:      PacketBindAdapterComplete(oiNew, *pStatus, ErrorStatus);      break;  }}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketUnbindAdapterComplete(IN POPEN_INSTANCE Open,                                          IN NDIS_STATUS Status){  // upcall on NdisCloseAdapter completion  // If Open->Status == NDIS_STATUS_PENDING then we must complete the pended unbinding  if (Open->Status == NDIS_STATUS_PENDING) {    NdisCompleteUnbindAdapter(Open->BindAdapterContext, Status);    Open->Status = NDIS_STATUS_SUCCESS;  }  if (Status != NDIS_STATUS_SUCCESS)    return;  // Remove Adapter from global list  RemoveEntryList(&Open->ListElement);  // Free Memory  NdisFreeSpinLock(&Open->RequestSpinLock);  NdisFreeSpinLock(&Open->RcvQSpinLock);  NdisFreeSpinLock(&Open->ResetSpinLock);  NdisFreeBufferPool(Open->BufferPool);  NdisFreePacketPool(Open->PacketPool);  NdisFreeMemory(Open, sizeof(OPEN_INSTANCE), 0);}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketUnbindAdapter(OUT PNDIS_STATUS   Status,                                  IN  POPEN_INSTANCE Open,                                  IN  POPEN_INSTANCE junk){  // detach protocol from the NIC clean up any pending I/O requests  PLIST_ENTRY  PacketListEntry;  PNDIS_PACKET pPacket;  //  The open instance of the device is about to close  //  We need to complete all pending I/O requests  //  First we complete any pending read requests  NdisAcquireSpinLock(&Open->RcvQSpinLock);  while (!IsListEmpty(&Open->RcvList)) {    PacketListEntry = RemoveHeadList(&Open->RcvList);    pPacket = CONTAINING_RECORD(PacketListEntry, NDIS_PACKET, ProtocolReserved);    //  complete normally    PacketTransferDataComplete(Open, pPacket, NDIS_STATUS_SUCCESS, 0);  }  NdisReleaseSpinLock(&Open->RcvQSpinLock);  // close the adapter  NdisCloseAdapter(Status, Open->AdapterHandle);  // Save status returned from NdisCloseAdapter for completion routine

⌨️ 快捷键说明

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