epacket.c

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

C
996
字号
  Open->Status = *Status;  if (*Status != NDIS_STATUS_PENDING)    PacketUnbindAdapterComplete(Open, *Status);}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketUnload(){  // deregister the protocol, free remaining memory   //  - called by NdisCloseAdapter when last adapter closed  NDIS_STATUS Status;    if (GlobalDeviceExtension != NULL) {    NdisDeregisterProtocol(&Status, GlobalDeviceExtension->NdisProtocolHandle);        if (Status == NDIS_STATUS_SUCCESS)      NdisFreeMemory(GlobalDeviceExtension, sizeof(DEVICE_EXTENSION), 0);    GlobalDeviceExtension = NULL;  }}///////////////////////////////////////////////////////////////////////////////NTSTATUS NDIS_API DriverEntry(IN PDRIVER_OBJECT  DriverObject,                              IN PUNICODE_STRING RegistryPath){  // initialiae the driver  NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;  NDIS_STRING ProtoName = NDIS_STRING_CONST("EPACKET");  NDIS_STATUS Status;  // Because the driver can be loaded once for each Netcard on the system,  // and because DriverEntry is called each time, we must ensure that  // initialization is performed only once.  if (GlobalDeviceExtension != NULL)    return NDIS_STATUS_SUCCESS;          NdisAllocateMemory((PVOID *)&GlobalDeviceExtension, sizeof(DEVICE_EXTENSION), 0, -1 );  if (GlobalDeviceExtension == NULL)    return NDIS_STATUS_RESOURCES;  NdisZeroMemory((UCHAR*)GlobalDeviceExtension, sizeof(DEVICE_EXTENSION));  NdisZeroMemory((UCHAR*)&ProtocolChar, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));  ProtocolChar.MajorNdisVersion            = 0x03;  ProtocolChar.MinorNdisVersion            = 0x0a;  ProtocolChar.Reserved                    = 0;  ProtocolChar.OpenAdapterCompleteHandler  = PacketBindAdapterComplete;  ProtocolChar.CloseAdapterCompleteHandler = PacketUnbindAdapterComplete;  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.BindAdapterHandler          = PacketBindAdapter;  ProtocolChar.UnbindAdapterHandler        = PacketUnbindAdapter;  ProtocolChar.UnloadProtocolHandler       = PacketUnload;  ProtocolChar.Name                        = ProtoName;    NdisRegisterProtocol(&Status,                       &GlobalDeviceExtension->NdisProtocolHandle,                       &ProtocolChar,                       sizeof(NDIS_PROTOCOL_CHARACTERISTICS));    if (Status != NDIS_STATUS_SUCCESS) {    NdisFreeMemory(GlobalDeviceExtension, sizeof(DEVICE_EXTENSION), 0);    return Status;  }    // initialize open list  InitializeListHead(&GlobalDeviceExtension->OpenList);    // initialize global device extension  GlobalDeviceExtension->DriverObject = DriverObject;    return Status;}///////////////////////////////////////////////////////////////////////////////POPEN_INSTANCE GetOpen(DWORD handle){  // return a specified Open Instance        PLIST_ENTRY     pHead = &GlobalDeviceExtension->OpenList;  PLIST_ENTRY     pTemp;  POPEN_INSTANCE  Open;    if (GlobalDeviceExtension == NULL)    return NULL;    // search the list for the Open Instance containing the specified handle    for (pTemp = pHead->Flink; pTemp != pHead; pTemp = pTemp->Flink) {    Open = CONTAINING_RECORD(pTemp, OPEN_INSTANCE, ListElement);            if (Open && Open->hDevice == handle)      return Open;  }    return NULL; // just in case}///////////////////////////////////////////////////////////////////////////////VOID PacketAllocatePacketBuffer(PNDIS_STATUS    pStatus,                                POPEN_INSTANCE  pOpen,                                PNDIS_PACKET    *ppPacket,                                PDIOCPARAMETERS pDiocParms,                                DWORD           FunctionCode ){  // allocate a buffer for reading/writing  PNDIS_BUFFER pNdisBuffer;  PNDIS_PACKET pPacket;    //  Try to get a packet from our list of free ones  NdisAllocatePacket(pStatus, ppPacket, pOpen->PacketPool);    if (*pStatus != NDIS_STATUS_SUCCESS) {    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;    return;  }    pPacket = *ppPacket;    // Buffers used asynchronously must be page locked  switch (FunctionCode) {    case IOCTL_EPACKET_READ:      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvOutBuffer, pDiocParms->cbOutBuffer);      RESERVED(pPacket)->cbBuffer = pDiocParms->cbOutBuffer;      break;        case IOCTL_EPACKET_WRITE:      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);      RESERVED(pPacket)->cbBuffer = pDiocParms->cbInBuffer;      break;        default:      // recycle the packet      NdisReinitializePacket(pPacket);          // Put the packet on the free queue      NdisFreePacket(pPacket);          *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;      *pStatus = NDIS_STATUS_NOT_ACCEPTED;      return;  }    RESERVED(pPacket)->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));  RESERVED(pPacket)->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));  RESERVED(pPacket)->hDevice           = pDiocParms->hDevice;  RESERVED(pPacket)->tagProcess        = pDiocParms->tagProcess;    switch (FunctionCode) {    case IOCTL_EPACKET_READ:      NdisAllocateBuffer(pStatus,                         &pNdisBuffer,                         pOpen->BufferPool,                         (PVOID)(RESERVED(pPacket)->lpBuffer + ETHERNET_HEADER_LENGTH),                         pDiocParms->cbOutBuffer);      break;        case IOCTL_EPACKET_WRITE:      NdisAllocateBuffer(pStatus,                         &pNdisBuffer,                         pOpen->BufferPool,                         (PVOID)RESERVED(pPacket)->lpBuffer,                         pDiocParms->cbInBuffer);      break;  }    if (*pStatus == NDIS_STATUS_SUCCESS)    NdisChainBufferAtFront(pPacket, pNdisBuffer); // Attach buffer to Packet  else {    NdisReinitializePacket(pPacket);  // recycle the packet    NdisFreePacket(pPacket);          // Put the packet on the free queue    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;  }}///////////////////////////////////////////////////////////////////////////////DWORD PacketRead(POPEN_INSTANCE     Open,                 DWORD              dwDDB,                 DWORD              hDevice,                 PDIOCPARAMETERS    pDiocParms){  // read a packet  NDIS_STATUS     Status;  PNDIS_PACKET    pPacket;    //  Check that the buffer can hold a max length Ethernet packet  if (pDiocParms->cbOutBuffer < ETHERNET_PACKET_LENGTH) {    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; // Need bigger buffer           return NDIS_STATUS_SUCCESS;  }    PacketAllocatePacketBuffer(&Status, Open, &pPacket, pDiocParms, IOCTL_EPACKET_READ);    if (Status == NDIS_STATUS_SUCCESS) {    //  Put this packet in a list of pending reads.    //  The receive indication handler will attempt to remove packets    //  from this list for use in transfer data calls    NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 6.11.97    InsertTailList(&Open->RcvList, &RESERVED(pPacket)->ListElement);    NdisReleaseSpinLock(&Open->RcvQSpinLock);  }  return -1;  // This will make DeviceIOControl return ERROR_IO_PENDING}///////////////////////////////////////////////////////////////////////////////DWORD PacketWrite(POPEN_INSTANCE    Open,                  DWORD             dwDDB,                  DWORD             hDevice,                  PDIOCPARAMETERS   pDiocParms){  // write a packet  PNDIS_PACKET    pPacket;  NDIS_STATUS     Status;    PacketAllocatePacketBuffer(&Status, Open, &pPacket, pDiocParms, IOCTL_EPACKET_WRITE);  if (Status != NDIS_STATUS_SUCCESS)    return 0;   // This will return immediately with no data written    // Call the MAC  NdisSend(&Status, Open->AdapterHandle, pPacket);  if (Status != NDIS_STATUS_PENDING) {    //  The send didn't pend so call the completion handler now    PacketSendComplete(Open, pPacket, Status);  }  return(-1); // This will make DeviceIOControl return ERROR_IO_PENDING}///////////////////////////////////////////////////////////////////////////////DWORD _stdcall PacketIOControl(DWORD           dwService,                               DWORD           dwDDB,                               DWORD           hDevice,                               PDIOCPARAMETERS pDiocParms) {  // called from applications  POPEN_INSTANCE  Open;  NDIS_STATUS     Status;  UCHAR           AdapterBuffer[5];  NDIS_STRING     AdapterName = NDIS_STRING_CONST(AdapterBuffer);  switch (dwService) {    case DIOC_OPEN:      return NDIS_STATUS_SUCCESS;        case DIOC_CLOSEHANDLE:      if ((Open = GetOpen(hDevice)) != NULL)        PacketUnbindAdapter(&Status, Open, NULL);      return NDIS_STATUS_SUCCESS;    case IOCTL_EPACKET_VERSION:      if (pDiocParms->cbOutBuffer < 2)        *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;      else {        ((BYTE *)pDiocParms->lpvOutBuffer)[0] = MAJOR_VERSION;        ((BYTE *)pDiocParms->lpvOutBuffer)[1] = MINOR_VERSION;        *(DWORD *)pDiocParms->lpcbBytesReturned = 2;      }      return NDIS_STATUS_SUCCESS;    case IOCTL_EPACKET_BIND:      memcpy(AdapterName.Buffer, (BYTE *)pDiocParms->lpvInBuffer,             min(strlen((char *)pDiocParms->lpvInBuffer), sizeof(AdapterBuffer)-1));      AdapterName.Buffer[sizeof(AdapterBuffer)-1] = '\0';      PacketBindAdapter(&Status,                        GlobalDeviceExtension->NdisProtocolHandle,                        &AdapterName,                        (PVOID)hDevice, /* special */                        NULL);      // Note: If the above usage of the 4'th arg to PacketBindAdapter      //       causes problems, use a global variable instead.      if (Status == NDIS_STATUS_SUCCESS || Status == NDIS_STATUS_PENDING) {        *(DWORD *)pDiocParms->lpcbBytesReturned = 1;        return NDIS_STATUS_SUCCESS;      }      break;    case IOCTL_EPACKET_SET_OID:    case IOCTL_EPACKET_QUERY_OID:      if ((Open = GetOpen(hDevice)) != NULL)        return PacketRequest(Open, dwService, dwDDB, hDevice, pDiocParms);      break;        case IOCTL_EPACKET_READ:      if ((Open = GetOpen(hDevice)) != NULL)        return PacketRead(Open, dwDDB, hDevice, pDiocParms);      break;        case IOCTL_EPACKET_WRITE:      if ((Open = GetOpen(hDevice)) != NULL)        return PacketWrite(Open, dwDDB, hDevice, pDiocParms);      break;  }  *(DWORD *)pDiocParms->lpcbBytesReturned = 0;  return NDIS_STATUS_SUCCESS;}// End of File ////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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