?? tapdrvr.c
字號:
// to satisfy IRP requests in the IRP queue. // // QueueLock is used to lock the packet queue used // for the TAP-Win32 NIC -> User Space packet flow direction. // // All accesses to packet or IRP queues should be // bracketed by the QueueLock spinlock, // in order to be SMP-safe. //======================================================== NdisAllocateSpinLock (&p_Extension->m_QueueLock); p_Extension->m_AllocatedSpinlocks = TRUE; p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE); p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE); if (!p_Extension->m_PacketQueue || !p_Extension->m_IrpQueue) { DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name)); l_Return = NDIS_STATUS_RESOURCES; goto cleanup; } //======================== // Finalize initialization //======================== p_Extension->m_TapIsRunning = TRUE; DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name, p_Extension->m_TapName)); cleanup: if (l_FreeTapUnicode) RtlFreeUnicodeString (&l_TapUnicode); if (l_LinkString.Buffer) MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE); if (l_Dispatch) MemFree (l_Dispatch, SIZEOF_DISPATCH); if (l_Return != NDIS_STATUS_SUCCESS) TapDeviceFreeResources (p_Extension); return l_Return;}#undef SIZEOF_DISPATCH//========================================================// Adapter Control//========================================================NDIS_STATUSAdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext){ TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; DEBUGP (("[%s] is resetting\n", NAME (l_Adapter))); return NDIS_STATUS_SUCCESS;}NDIS_STATUS AdapterReceive (OUT PNDIS_PACKET p_Packet, OUT PUINT p_Transferred, IN NDIS_HANDLE p_AdapterContext, IN NDIS_HANDLE p_ReceiveContext, IN UINT p_Offset, IN UINT p_ToTransfer){ return NDIS_STATUS_SUCCESS;}//==============================================================// Adapter Option Query/Modification//==============================================================NDIS_STATUS AdapterQuery(IN NDIS_HANDLE p_AdapterContext, IN NDIS_OID p_OID, IN PVOID p_Buffer, IN ULONG p_BufferLength, OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded){ TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; TapAdapterQuery l_Query, *l_QueryPtr = &l_Query; NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS; UINT l_QueryLength = 4; BOOLEAN lock_succeeded; NdisZeroMemory (&l_Query, sizeof (l_Query)); switch (p_OID) { //=================================================================== // Vendor & Driver version Info //=================================================================== case OID_GEN_VENDOR_DESCRIPTION: l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_STRING; l_QueryLength = strlen (PRODUCT_STRING) + 1; break; case OID_GEN_VENDOR_ID: l_Query.m_Long = 0xffffff; break; case OID_GEN_DRIVER_VERSION: l_Query.m_Short = (((USHORT) TAP_NDIS_MAJOR_VERSION) << 8 | (USHORT) TAP_NDIS_MINOR_VERSION); l_QueryLength = sizeof (unsigned short); break; case OID_GEN_VENDOR_DRIVER_VERSION: l_Query.m_Long = (((USHORT) TAP_DRIVER_MAJOR_VERSION) << 8 | (USHORT) TAP_DRIVER_MINOR_VERSION); break; //================================================================= // Statistics //================================================================= case OID_GEN_RCV_NO_BUFFER: l_Query.m_Long = 0; break; case OID_802_3_RCV_ERROR_ALIGNMENT: l_Query.m_Long = 0; break; case OID_802_3_XMIT_ONE_COLLISION: l_Query.m_Long = 0; break; case OID_802_3_XMIT_MORE_COLLISIONS: l_Query.m_Long = 0; break; case OID_GEN_XMIT_OK: l_Query.m_Long = l_Adapter->m_Tx; break; case OID_GEN_RCV_OK: l_Query.m_Long = l_Adapter->m_Rx; break; case OID_GEN_XMIT_ERROR: l_Query.m_Long = l_Adapter->m_TxErr; break; case OID_GEN_RCV_ERROR: l_Query.m_Long = l_Adapter->m_RxErr; break; //=================================================================== // Device & Protocol Options //=================================================================== case OID_GEN_SUPPORTED_LIST: l_QueryPtr = (TapAdapterQueryPointer) g_SupportedOIDList; l_QueryLength = sizeof (g_SupportedOIDList); break; case OID_GEN_MAC_OPTIONS: // This MUST be here !!! l_Query.m_Long = (NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | NDIS_MAC_OPTION_NO_LOOPBACK | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND); break; case OID_GEN_CURRENT_PACKET_FILTER: l_Query.m_Long = (NDIS_PACKET_TYPE_ALL_LOCAL | NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL); break; case OID_GEN_PROTOCOL_OPTIONS: l_Query.m_Long = 0; break; //================================================================== // Device Info //================================================================== case OID_GEN_MEDIA_CONNECT_STATUS: l_Query.m_Long = l_Adapter->m_MediaState ? NdisMediaStateConnected : NdisMediaStateDisconnected; break; case OID_GEN_HARDWARE_STATUS: l_Query.m_HardwareStatus = NdisHardwareStatusReady; l_QueryLength = sizeof (NDIS_HARDWARE_STATUS); break; case OID_GEN_MEDIA_SUPPORTED: case OID_GEN_MEDIA_IN_USE: l_Query.m_Medium = l_Adapter->m_Medium; l_QueryLength = sizeof (NDIS_MEDIUM); break; case OID_GEN_PHYSICAL_MEDIUM: l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified; l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM); break; case OID_GEN_LINK_SPEED: l_Query.m_Long = 1000000; // rate / 100 bps break; case OID_802_3_PERMANENT_ADDRESS: case OID_802_3_CURRENT_ADDRESS: COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC); l_QueryLength = sizeof (MACADDR); break; //================================================================== // Limits //================================================================== case OID_GEN_MAXIMUM_SEND_PACKETS: l_Query.m_Long = 1; break; case OID_802_3_MAXIMUM_LIST_SIZE: l_Query.m_Long = NIC_MAX_MCAST_LIST; break; case OID_GEN_CURRENT_LOOKAHEAD: l_Query.m_Long = l_Adapter->m_Lookahead; break; case OID_GEN_MAXIMUM_LOOKAHEAD: case OID_GEN_MAXIMUM_TOTAL_SIZE: case OID_GEN_RECEIVE_BUFFER_SPACE: case OID_GEN_RECEIVE_BLOCK_SIZE: l_Query.m_Long = DEFAULT_PACKET_LOOKAHEAD; break; case OID_GEN_MAXIMUM_FRAME_SIZE: case OID_GEN_TRANSMIT_BLOCK_SIZE: case OID_GEN_TRANSMIT_BUFFER_SPACE: l_Query.m_Long = l_Adapter->m_MTU; break; case OID_PNP_CAPABILITIES: do { PNDIS_PNP_CAPABILITIES pPNPCapabilities; PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct; if (p_BufferLength >= sizeof (NDIS_PNP_CAPABILITIES)) { pPNPCapabilities = (PNDIS_PNP_CAPABILITIES) (p_Buffer); // // Setting up the buffer to be returned // to the Protocol above the Passthru miniport // pPMstruct = &pPNPCapabilities->WakeUpCapabilities; pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified; pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified; pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified; } l_QueryLength = sizeof (NDIS_PNP_CAPABILITIES); } while (FALSE); break; case OID_PNP_QUERY_POWER: break; // Required OIDs that we don't support case OID_GEN_SUPPORTED_GUIDS: case OID_GEN_MEDIA_CAPABILITIES: case OID_TCP_TASK_OFFLOAD: case OID_FFP_SUPPORT: l_Status = NDIS_STATUS_INVALID_OID; break; // Optional stats OIDs case OID_GEN_DIRECTED_BYTES_XMIT: case OID_GEN_DIRECTED_FRAMES_XMIT: case OID_GEN_MULTICAST_BYTES_XMIT: case OID_GEN_MULTICAST_FRAMES_XMIT: case OID_GEN_BROADCAST_BYTES_XMIT: case OID_GEN_BROADCAST_FRAMES_XMIT: case OID_GEN_DIRECTED_BYTES_RCV: case OID_GEN_DIRECTED_FRAMES_RCV: case OID_GEN_MULTICAST_BYTES_RCV: case OID_GEN_MULTICAST_FRAMES_RCV: case OID_GEN_BROADCAST_BYTES_RCV: case OID_GEN_BROADCAST_FRAMES_RCV: l_Status = NDIS_STATUS_INVALID_OID; break; //=================================================================== // Not Handled //=================================================================== default: DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID)); l_Status = NDIS_STATUS_INVALID_OID; break; } if (l_Status != NDIS_STATUS_SUCCESS) ; else if (l_QueryLength > p_BufferLength) { l_Status = NDIS_STATUS_INVALID_LENGTH; *p_BytesNeeded = l_QueryLength; } else NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr, (*p_BytesWritten = l_QueryLength)); return l_Status;}NDIS_STATUS AdapterModify(IN NDIS_HANDLE p_AdapterContext, IN NDIS_OID p_OID, IN PVOID p_Buffer, IN ULONG p_BufferLength, OUT PULONG p_BytesRead, OUT PULONG p_BytesNeeded){ TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer; TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID; ULONG l_Long; switch (p_OID) { //================================================================== // Device Info //================================================================== case OID_802_3_MULTICAST_LIST: DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n", NAME (l_Adapter))); *p_BytesNeeded = sizeof (ETH_ADDR); *p_BytesRead = p_BufferLength; if (p_BufferLength % sizeof (ETH_ADDR)) l_Status = NDIS_STATUS_INVALID_LENGTH; else if (p_BufferLength > sizeof (MC_LIST)) { l_Status = NDIS_STATUS_MULTICAST_FULL; *p_BytesNeeded = sizeof (MC_LIST); } else { NdisAcquireSpinLock (&l_Adapter->m_MCLock); NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST)); NdisMoveMemory(&l_Adapter->m_MCList, p_Buffer, p_BufferLength); l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR); NdisReleaseSpinLock (&l_Adapter->m_MCLock); l_Status = NDIS_STATUS_SUCCESS; } break; case OID_GEN_CURRENT_PACKET_FILTER: l_Status = NDIS_STATUS_INVALID_LENGTH; *p_BytesNeeded = 4; if (p_BufferLength >= sizeof (ULONG)) { DEBUGP (("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n", NAME (l_Adapter), l_Query->m_Long)); l_Status = NDIS_STATUS_SUCCESS; *p_BytesRead = sizeof (ULONG); } break; case OID_GEN_CURRENT_LOOKAHEAD: if (p_BufferLength < sizeof (ULONG)) { l_Status = NDIS_STATUS_INVALID_LENGTH; *p_BytesNeeded = 4; } else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD || l_Query->m_Long <= 0) { l_Status = NDIS_STATUS_INVALID_DATA; } else { DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n", NAME (l_Adapter), l_Query->m_Long)); l_Adapter->m_Lookahead = l_Query->m_Long; l_Status = NDIS_STATUS_SUCCESS; *p_BytesRead = sizeof (ULONG); } break; case OID_GEN_NETWORK_LAYER_ADDRESSES: l_Status = NDIS_STATUS_SUCCESS; *p_BytesRead = *p_BytesNeeded = 0; break; case OID_GEN_TRANSPORT_HEADER_OFFSET: l_Status = NDIS_STATUS_SUCCESS; *p_BytesRead = *p_BytesNeeded = 0; break; case OID_PNP_SET_POWER: do { NDIS_DEVICE_POWER_STATE NewDeviceState; NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE) p_Buffer); switch (NewDeviceState) { case NdisDeviceStateD0: l_Adapter->m_DeviceState = '0'; break; case NdisDeviceStateD1: l_Adapter->m_DeviceState = '1'; break; case NdisDeviceStateD2: l_Adapter->m_DeviceState = '2'; break; case NdisDeviceStateD3: l_Adapter->m_DeviceState = '3'; break; default: l_Adapter->m_DeviceState = '?'; break; } l_Status = NDIS_STATUS_FAILURE; // // Check for invalid length // if (p_BufferLength < sizeof (NDIS_DEVICE_POWER_STATE)) { l_Status = NDIS_STATUS_INVALID_LENGTH; break; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -