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