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 + -
显示快捷键?