From d3cf84a5118cd2aec491aaa4e4d0b9a57eb384ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adonais=20Romero=20Gonz=C3=A1lez?= Date: Tue, 18 Oct 2022 16:47:17 -0700 Subject: [PATCH 01/15] Upgrade actions environment to Windows 2022 (#794) --- .github/workflows/ci-pr.yml | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 12062b340..931df9e4d 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -14,7 +14,7 @@ jobs: matrix: configuration: [Debug, Release] platform: [x64, arm64] - runs-on: windows-2019 + runs-on: windows-2022 env: Solution_Path: general\echo\kmdf\kmdfecho.sln steps: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68b46552d..4c07460a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: matrix: configuration: [Debug, Release] platform: [x64, arm64] - runs-on: windows-2019 + runs-on: windows-2022 env: Solution_Path: general\echo\kmdf\kmdfecho.sln steps: From 6c5e839e0c65af210026a94becdcf68ef297d926 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Thu, 27 Oct 2022 10:05:01 -0700 Subject: [PATCH 02/15] code for cxwmbclass sample driver --- network/wwan/cxwmbclass/IpAddress.c | 1192 + network/wwan/cxwmbclass/IpAddress.h | 74 + network/wwan/cxwmbclass/LocalWPP.ini | 21 + .../wwan/cxwmbclass/MbbFastIOControlPlane.c | 116 + .../wwan/cxwmbclass/MbbFastIOControlPlane.h | 5 + network/wwan/cxwmbclass/MbbFastIODataPlane.c | 263 + network/wwan/cxwmbclass/MbbFastIODataPlane.h | 12 + network/wwan/cxwmbclass/MbbLibrary.c | 505 + network/wwan/cxwmbclass/RequestManager.c | 2176 ++ network/wwan/cxwmbclass/RequestManager.h | 230 + network/wwan/cxwmbclass/adapter.c | 3398 +++ network/wwan/cxwmbclass/adapter.h | 337 + network/wwan/cxwmbclass/init.c | 2269 ++ network/wwan/cxwmbclass/port.c | 825 + network/wwan/cxwmbclass/port.h | 252 + network/wwan/cxwmbclass/precomp.h | 44 + network/wwan/cxwmbclass/product.pbxproj | 13 + network/wwan/cxwmbclass/receive.c | 1961 ++ network/wwan/cxwmbclass/receive.h | 22 + network/wwan/cxwmbclass/request.c | 19728 ++++++++++++++++ network/wwan/cxwmbclass/send.c | 2744 +++ network/wwan/cxwmbclass/send.h | 42 + network/wwan/cxwmbclass/tmpMbbMessages.h | 3306 +++ network/wwan/cxwmbclass/util.c | 9090 +++++++ network/wwan/cxwmbclass/util.h | 1263 + network/wwan/cxwmbclass/wmbclass.h | 1096 + network/wwan/cxwmbclass/wmbclass.rc | 21 + 27 files changed, 51005 insertions(+) create mode 100644 network/wwan/cxwmbclass/IpAddress.c create mode 100644 network/wwan/cxwmbclass/IpAddress.h create mode 100644 network/wwan/cxwmbclass/LocalWPP.ini create mode 100644 network/wwan/cxwmbclass/MbbFastIOControlPlane.c create mode 100644 network/wwan/cxwmbclass/MbbFastIOControlPlane.h create mode 100644 network/wwan/cxwmbclass/MbbFastIODataPlane.c create mode 100644 network/wwan/cxwmbclass/MbbFastIODataPlane.h create mode 100644 network/wwan/cxwmbclass/MbbLibrary.c create mode 100644 network/wwan/cxwmbclass/RequestManager.c create mode 100644 network/wwan/cxwmbclass/RequestManager.h create mode 100644 network/wwan/cxwmbclass/adapter.c create mode 100644 network/wwan/cxwmbclass/adapter.h create mode 100644 network/wwan/cxwmbclass/init.c create mode 100644 network/wwan/cxwmbclass/port.c create mode 100644 network/wwan/cxwmbclass/port.h create mode 100644 network/wwan/cxwmbclass/precomp.h create mode 100644 network/wwan/cxwmbclass/product.pbxproj create mode 100644 network/wwan/cxwmbclass/receive.c create mode 100644 network/wwan/cxwmbclass/receive.h create mode 100644 network/wwan/cxwmbclass/request.c create mode 100644 network/wwan/cxwmbclass/send.c create mode 100644 network/wwan/cxwmbclass/send.h create mode 100644 network/wwan/cxwmbclass/tmpMbbMessages.h create mode 100644 network/wwan/cxwmbclass/util.c create mode 100644 network/wwan/cxwmbclass/util.h create mode 100644 network/wwan/cxwmbclass/wmbclass.h create mode 100644 network/wwan/cxwmbclass/wmbclass.rc diff --git a/network/wwan/cxwmbclass/IpAddress.c b/network/wwan/cxwmbclass/IpAddress.c new file mode 100644 index 000000000..29f9d0697 --- /dev/null +++ b/network/wwan/cxwmbclass/IpAddress.c @@ -0,0 +1,1192 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" +#include "IpAddress.tmh" + + +#define MBB_PREALLOC_IP_WORKITEM_COUNT 1 + + +//////////////////////////////////////////////////////////////////////////////// +// +// PROTOTYPES +// +//////////////////////////////////////////////////////////////////////////////// + +_Requires_lock_held_( Port->Lock ) +VOID +MbbIpSnapPortAddressTable( + __in PMBB_PORT Port, + __in MBB_ADDRESS_TABLE_ID TableId, + __deref_out_ecount(*AddressCount) PMBB_IPADDRESS_ENTRY* AddressTable, + __out PULONG AddressCount + ); + +_Requires_lock_held_( Port->Lock ) +VOID +MbbIpSnapPortIpTable( + __in PMBB_PORT Port, + __deref_out_ecount(*AddressCount) PMBB_IPADDRESS_ENTRY* AddressTable, + __out PULONG AddressCount + ); + +__callback +VOID +MbbIpProcessChange( + __in PVOID Context1, + __in PVOID Context2, + __in PVOID Context3, + __in PVOID Context4 + ); + +NDIS_STATUS +MbbIpQueueIPChange( + __in PMINIPORT_DRIVER_CONTEXT Driver, + __in PNET_LUID NetLuid, + __in MBB_IP_CHANGE_TYPE IPChangeType, + __in NDIS_PORT_NUMBER PortNumber + ); + +__callback +VOID +MbbIpInterfaceChangeCallback( + __in PVOID CallerContext, + __in_opt PMIB_IPINTERFACE_ROW Row, + __in MIB_NOTIFICATION_TYPE NotificationType + ); + +__callback +VOID +MbbIpRouteChangeCallback( + _In_ PVOID CallerContext, + _In_opt_ PMIB_IPFORWARD_ROW2 Row, + _In_ MIB_NOTIFICATION_TYPE NotificationType + ); + +__callback +VOID +MbbIpUnicastAddressChangeCallback( + _In_ PVOID CallerContext, + _In_opt_ PMIB_UNICASTIPADDRESS_ROW Row, + _In_ MIB_NOTIFICATION_TYPE NotificationType + ); + + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// IMPLEMENTATION +// +//////////////////////////////////////////////////////////////////////////////// +_Requires_lock_held_( Port->Lock ) +VOID +MbbIpSnapPortAddressTable( + __in PMBB_PORT Port, + __in MBB_ADDRESS_TABLE_ID TableId, + __deref_out_ecount(*AddressCount) PMBB_IPADDRESS_ENTRY* AddressTable, + __out PULONG AddressCount + ) +{ + ULONG AddressIndex; + ULONG V4Index; + ULONG V6Index; + ULONG V4Count = 0; + ULONG V6Count = 0; + #pragma prefast (suppress:__WARNING_IPV6_ADDRESS_STRUCTURE_IPV4_SPECIFIC) + IN_ADDR* V4Table = NULL; + IN6_ADDR* V6Table = NULL; + ULONG LocalAddressCount = 0; + PMBB_IPADDRESS_ENTRY LocalAddressTable = NULL; + + do + { + if( Port->IpAddressInfo == NULL ) + { + // + // We are not connected yet. + // + break; + } + + switch( TableId ) + { + case MbbAddressTableGateway: + { + V4Count = MBB_IP_GET_GWV4COUNT( Port->IpAddressInfo ); + V4Table = MBB_IP_GET_GWV4TABLE( Port->IpAddressInfo ); + V6Count = MBB_IP_GET_GWV6COUNT( Port->IpAddressInfo ); + V6Table = MBB_IP_GET_GWV6TABLE( Port->IpAddressInfo ); + } + break; + + case MbbAddressTableDns: + { + V4Count = MBB_IP_GET_DSV4COUNT( Port->IpAddressInfo ); + V4Table = MBB_IP_GET_DSV4TABLE( Port->IpAddressInfo ); + V6Count = MBB_IP_GET_DSV6COUNT( Port->IpAddressInfo ); + V6Table = MBB_IP_GET_DSV6TABLE( Port->IpAddressInfo ); + } + break; + + default: + { + ASSERT( TableId == MbbAddressTableGateway || TableId == MbbAddressTableDns ); + } + break; + } + + if( (LocalAddressCount = V4Count + V6Count) == 0 ) + { + break; + } + + if( (LocalAddressTable = ALLOCATE_NONPAGED_POOL( sizeof(MBB_IPADDRESS_ENTRY) * LocalAddressCount )) == NULL ) + { + LocalAddressCount = 0; + break; + } + + for( V4Index = 0, AddressIndex = 0; + V4Index < V4Count; + V4Index ++, AddressIndex ++ ) + { + LocalAddressTable[AddressIndex].IsIpv6 = FALSE; + LocalAddressTable[AddressIndex].IsReported = FALSE; + + #pragma prefast (suppress:__WARNING_IPV6_ADDRESS_STRUCTURE_IPV4_SPECIFIC) + RtlCopyMemory( + &LocalAddressTable[AddressIndex].Ipv4.IPV4Address, + &V4Table[V4Index], + sizeof(IN_ADDR) + ); + } + + for( V6Index = 0; + V6Index < V6Count; + V6Index ++, AddressIndex ++ ) + { + LocalAddressTable[AddressIndex].IsIpv6 = TRUE; + LocalAddressTable[AddressIndex].IsReported = FALSE; + + RtlCopyMemory( + &LocalAddressTable[AddressIndex].Ipv6.IPV6Address, + &V6Table[V6Index], + sizeof(IN6_ADDR) + ); + } + } while( FALSE ); + + *AddressCount = LocalAddressCount; + *AddressTable = LocalAddressTable; +} + +_Requires_lock_held_( Port->Lock ) +VOID +MbbIpSnapPortIpTable( + __in PMBB_PORT Port, + __deref_out_ecount(*AddressCount) PMBB_IPADDRESS_ENTRY* AddressTable, + __out PULONG AddressCount + ) +{ + ULONG AddressIndex; + ULONG V4Index; + ULONG V6Index; + ULONG V4Count = 0; + ULONG V6Count = 0; + PMBB_IPV4_ADDRESS V4Table = NULL; + PMBB_IPV6_ADDRESS V6Table = NULL; + ULONG LocalAddressCount = 0; + PMBB_IPADDRESS_ENTRY LocalAddressTable = NULL; + + do + { + if( Port->IpAddressInfo == NULL ) + { + // + // We are not connected yet. + // + break; + } + + V4Count = MBB_IP_GET_IPV4COUNT( Port->IpAddressInfo ); + V4Table = MBB_IP_GET_IPV4TABLE( Port->IpAddressInfo ); + V6Count = MBB_IP_GET_IPV6COUNT( Port->IpAddressInfo ); + V6Table = MBB_IP_GET_IPV6TABLE( Port->IpAddressInfo ); + + if( (LocalAddressCount = V4Count + V6Count) == 0 ) + { + break; + } + + if( (LocalAddressTable = ALLOCATE_NONPAGED_POOL( sizeof(MBB_IPADDRESS_ENTRY) * LocalAddressCount )) == NULL ) + { + LocalAddressCount = 0; + break; + } + + for( V4Index = 0, AddressIndex = 0; + V4Index < V4Count; + V4Index ++, AddressIndex ++ ) + { + LocalAddressTable[AddressIndex].IsIpv6 = FALSE; + LocalAddressTable[AddressIndex].IsReported = FALSE; + + RtlCopyMemory( + &LocalAddressTable[AddressIndex].Ipv4, + &V4Table[V4Index], + sizeof(MBB_IPV4_ADDRESS) + ); + } + + for( V6Index = 0; + V6Index < V6Count; + V6Index ++, AddressIndex ++ ) + { + LocalAddressTable[AddressIndex].IsIpv6 = TRUE; + LocalAddressTable[AddressIndex].IsReported = FALSE; + + RtlCopyMemory( + &LocalAddressTable[AddressIndex].Ipv6, + &V6Table[V6Index], + sizeof(MBB_IPV6_ADDRESS) + ); + } + } while( FALSE ); + + *AddressCount = LocalAddressCount; + *AddressTable = LocalAddressTable; +} + +// +// Ip Address CID +// + +NDIS_STATUS +MbbIpAddressStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +/*++ +Description: + + The IP Status Handler processes responses to requested IP Info as well as + unsolicited change indications from the device. Only one instance of this routine + runs at any time due to the CID Serializer (RequestManager) so there is no race in + reporting two IP indications from the device on two threads. + + It does the following - + + 1. Verify that IP information received is valid. + + 2. Copy & cache the information in the adapter object. + a. Required for validating the IP configured on the adpater in IpChangeCallback. + + 3. Enable \ Disable DHCPv4 depending on whether IP Address is available via Layer2. + DHCPv6 or NDP behavior is not changed. + The network is required to be configured correctly i.e. not give IPv6 over Layer2 and Layer3. + + 4. Report the new DNS, IP, Gateway to IP stack. + The order in which the information is reported is important. + a. MTU (Supported starting in Blue) + b. DNS Servers + c. IP Address + d. Routes + + 5. Indicate LinkUP to NDIS under the following condition - + a. DNS Server setting changed. LinkDOWN followed by a LinkUP is required for the stack to pick up the changes. + b. IP Information was retrieved as a result of a connect (not unsolicited indication). +--*/ +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; + PMBB_IP_ADDRESS_INFO IpAddressInfo = (PMBB_IP_ADDRESS_INFO)InBuffer; + MBB_CONNECTION_STATE ConnectionState; + PMBB_PORT Port = NULL; + NDIS_PORT_NUMBER PortNumber = DEFAULT_NDIS_PORT_NUMBER; + USHORT EffectiveMaxMtu = MBIM_MAX_MTU_SIZE; + + do + { + // + // Only parse the result on sucess + // + if( NdisStatus != STATUS_SUCCESS || + (MbbStatus != MBB_STATUS_SUCCESS) || + IpAddressInfo == NULL ) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: FAILED to get IP Address info, NdisStatus=%!STATUS! MbbStatus=%!MbbStatus!", + Adapter->NetLuid.Value, + NdisStatus, + MbbStatus + ); + break; + } + + //Get the port corresponding to the session id + + Port = MbbWwanTranslateSessionIdToPort(Adapter, IpAddressInfo->SessionId); + + if(!Port) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid session id. No port corresponding to the session id %lu", + Adapter->NetLuid.Value, IpAddressInfo->SessionId + ); + break; + } + + MBB_ACQUIRE_PORT_LOCK(Port); + PortNumber = Port->PortNumber; + MBB_RELEASE_PORT_LOCK(Port); + + // + // Device should only send unsolicited indications after successful connection. + // + if( MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE && + MbbPortIsConnected(Port) == FALSE ) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: IGNORING unsolicited notification when port is disconnected", + Adapter->NetLuid.Value + ); + break; + } + + // + // Minimum buffer size check + // + if( InBufferSize < sizeof(MBB_IP_ADDRESS_INFO) ) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: INSUFFICIENT IP Address info length, expected=%d received=%d", + Adapter->NetLuid.Value, + sizeof(MBB_IP_ADDRESS_INFO), + InBufferSize + ); + break; + } + + // + // Max MTU is different from initialized value if the device has the Extended descriptor (per Errata). + // + if ( Adapter->BusParams.IsErrataDevice ) + { + EffectiveMaxMtu = Adapter->BusParams.MTU; + } + + // + // Minimum and Maximum IPv4 MTU size check, but only require correct + // value if MTU being set. If not correct, just ignore. + // + if( MBB_IP_IS_MTUV4_AVAILABLE( IpAddressInfo ) ) + { + + if( ( + IpAddressInfo->IPv4MTU < MBIM_MIN_MTU_SIZE + ) || + ( + (USHORT) IpAddressInfo->IPv4MTU > EffectiveMaxMtu + ) ) + + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: IGNORING Invalid IPv4 MTU value, received=%d min=%d max=%d", + Adapter->NetLuid.Value, + IpAddressInfo->IPv4MTU, + MBIM_MIN_MTU_SIZE, + EffectiveMaxMtu + ); + // Do *NOT* break so other settings continue to work even if MTU setting is off. + // Simply set to be ignored when effecting the actual change in MbbIpProcessChange() later on. + IpAddressInfo->IPv4Flags &= ~MbbIpFlagsMTUAvailable; + } + } + + // + // Minimum and Maximum IPv6 MTU size check, but only require correct + // value if MTU being set, otherwise ignore. + // + if( MBB_IP_IS_MTUV6_AVAILABLE( IpAddressInfo ) ) + { + + if( ( + IpAddressInfo->IPv6MTU < MBIM_MIN_MTU_SIZE + ) || + ( + (USHORT) IpAddressInfo->IPv6MTU > EffectiveMaxMtu + ) ) + + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: IGNORING Invalid IPv6 MTU value, received=%d min=%d max=%d", + Adapter->NetLuid.Value, + IpAddressInfo->IPv6MTU, + MBIM_MIN_MTU_SIZE, + EffectiveMaxMtu + ); + // Do *NOT* break so other settings continue to work even if MTU setting is off. + // Simply set to be ignored when effecting the actual change in MbbIpProcessChange() later on. + IpAddressInfo->IPv6Flags &= ~MbbIpFlagsMTUAvailable; + } + } + + // + // Variable fields check + // + #pragma prefast (suppress:__WARNING_IPV6_ADDRESS_STRUCTURE_IPV4_SPECIFIC) + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + IpAddressInfo->IPv4GatewayOffset, + sizeof(IN_ADDR), + 1, + sizeof(IN_ADDR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv4 gateway, offset=%d received=%d", + Adapter->NetLuid.Value, + IpAddressInfo->IPv4GatewayOffset, + InBufferSize + ); + + break; + + } + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + IpAddressInfo->IPv6GatewayOffset, + sizeof(IN6_ADDR), + 1, + sizeof(IN6_ADDR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv6 gateway, offset=%d received=%d", + Adapter->NetLuid.Value, + IpAddressInfo->IPv6GatewayOffset, + InBufferSize + ); + + break; + + } + + + NdisStatus=MbbIsArrayFieldValid( + InBufferSize, + IpAddressInfo->IPv4AddressOffset, + IpAddressInfo->IPv4AddressCount, + sizeof(MBB_IPV4_ADDRESS) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv4 address array, offset=%d, count=%d, received=%d", + Adapter->NetLuid.Value, + IpAddressInfo->IPv4AddressOffset, + IpAddressInfo->IPv4AddressCount, + InBufferSize + ); + + break; + + } + + NdisStatus=MbbIsArrayFieldValid( + InBufferSize, + IpAddressInfo->IPv6AddressOffset, + IpAddressInfo->IPv6AddressCount, + sizeof(MBB_IPV6_ADDRESS) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv6 address array, offset=%d, count=%d, received=%d", + Adapter->NetLuid.Value, + IpAddressInfo->IPv6AddressOffset, + IpAddressInfo->IPv6AddressCount, + InBufferSize + ); + + break; + + } + + #pragma prefast (suppress:__WARNING_IPV6_ADDRESS_STRUCTURE_IPV4_SPECIFIC) + NdisStatus=MbbIsArrayFieldValid( + InBufferSize, + IpAddressInfo->IPv4DnsServerOffset, + IpAddressInfo->IPv4DnsServerCount, + sizeof(IN_ADDR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv4 DNS address array, offset=%d, count=%d, received=%d", + Adapter->NetLuid.Value, + IpAddressInfo->IPv4DnsServerOffset, + IpAddressInfo->IPv4DnsServerCount, + InBufferSize + ); + + break; + + } + + NdisStatus=MbbIsArrayFieldValid( + InBufferSize, + IpAddressInfo->IPv6DnsServerOffset, + IpAddressInfo->IPv6DnsServerCount, + sizeof(IN6_ADDR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv6 DNS address array, offset=%d, count=%d, received=%d", + Adapter->NetLuid.Value, + IpAddressInfo->IPv6DnsServerOffset, + IpAddressInfo->IPv6DnsServerCount, + InBufferSize + ); + + break; + + } + + + // + // IP and Gateway should be reported using the same mechanism + // + if( MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ) != MBB_IP_IS_GWV4_AVAILABLE( IpAddressInfo ) && + MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo ) != MBB_IP_IS_GWV6_AVAILABLE( IpAddressInfo ) ) + { + ASSERT( FALSE ); + + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: IP and Gateway should be configured using same Layer mechanisms. v4[IP=%!bool! GW=%!bool!] v6[IP=%!bool! GW=%!bool!]", + Adapter->NetLuid.Value, + MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ), + MBB_IP_IS_GWV4_AVAILABLE( IpAddressInfo ), + MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo ), + MBB_IP_IS_GWV6_AVAILABLE( IpAddressInfo ) + ); + break; + } + // + // Log a warning when IP is derived from Layer2 mechanisms and DNS is derived from Layer3 + // + if( ( + MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ) && + !MBB_IP_IS_DSV4_AVAILABLE( IpAddressInfo ) + ) || + ( + MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo ) && + !MBB_IP_IS_DSV6_AVAILABLE( IpAddressInfo ) + ) ) + { + TraceWarn( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: DNS configured using Layer3 when IP is derived from Layer2. v4[IP=%!bool! DNS=%!bool!] v6[IP=%!bool! DNS=%!bool!]", + Adapter->NetLuid.Value, + MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ), + MBB_IP_IS_DSV4_AVAILABLE( IpAddressInfo ), + MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo ), + MBB_IP_IS_DSV6_AVAILABLE( IpAddressInfo ) + ); + } + + if(!IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + // Enable/Disable DHCP for default port connection. For non-default + // port connection the virtual miniport will do it when we send + // NDIS_WWAN_IP_ADDRESS_STATE indication + WwanAdjustDhcpSettings( + Adapter->NetLuid, + Adapter->NetCfgId, + (! MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ))); + } + + TraceInfo( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x][Port=%lu] CID_IP_CONFIGURATION: %02d IPv4 %02d IPv6 %02d DNv4 %02d DNv6 %02d GWv4 %02d GWv6 (IPv4MTU %d IPv6MTU %d)", + Adapter->NetLuid.Value, + PortNumber, + MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo )? IpAddressInfo->IPv4AddressCount: 0, + MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo )? IpAddressInfo->IPv6AddressCount: 0, + MBB_IP_IS_DSV4_AVAILABLE( IpAddressInfo )? IpAddressInfo->IPv4DnsServerCount: 0, + MBB_IP_IS_DSV6_AVAILABLE( IpAddressInfo )? IpAddressInfo->IPv6DnsServerCount: 0, + MBB_IP_IS_GWV4_AVAILABLE( IpAddressInfo )? 1: 0, + MBB_IP_IS_GWV6_AVAILABLE( IpAddressInfo )? 1: 0, + MBB_IP_IS_MTUV4_AVAILABLE( IpAddressInfo ) ? IpAddressInfo->IPv4MTU : 0, + MBB_IP_IS_MTUV6_AVAILABLE( IpAddressInfo ) ? IpAddressInfo->IPv6MTU : 0 + ); + + if (MBB_IP_IS_IPV4_AVAILABLE(IpAddressInfo)) + { + PMBB_IPV4_ADDRESS pIPV4Elem = (PMBB_IPV4_ADDRESS)(InBuffer + IpAddressInfo->IPv4AddressOffset); + for (unsigned int i = 0; i < IpAddressInfo->IPv4AddressCount; i++, pIPV4Elem++) + { + TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: IPv4 #%d (subnetAddrLen %d) : %!IPV4ADDR!", + i+1, pIPV4Elem->OnLinkPrefixLength, pIPV4Elem->IPV4Address); + } + } + + if (MBB_IP_IS_GWV4_AVAILABLE(IpAddressInfo)) + { + PIN_ADDR pInAddr = (PIN_ADDR)(InBuffer + IpAddressInfo->IPv4GatewayOffset); + TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: GWv4: %d.%d.%d.%d", + pInAddr->S_un.S_un_b.s_b1, pInAddr->S_un.S_un_b.s_b2, pInAddr->S_un.S_un_b.s_b3, pInAddr->S_un.S_un_b.s_b4); + } + + if (MBB_IP_IS_DSV4_AVAILABLE(IpAddressInfo)) + { + PIN_ADDR pInAddr = (PIN_ADDR)(InBuffer + IpAddressInfo->IPv4DnsServerOffset); + for (unsigned int i = 0; i < IpAddressInfo->IPv4DnsServerCount; i++, pInAddr++) + { + TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: DNSv4 #%d: %d.%d.%d.%d", + i+1, pInAddr->S_un.S_un_b.s_b1, pInAddr->S_un.S_un_b.s_b2, pInAddr->S_un.S_un_b.s_b3, pInAddr->S_un.S_un_b.s_b4); + } + } + + if (MBB_IP_IS_IPV6_AVAILABLE(IpAddressInfo)) + { + PMBB_IPV6_ADDRESS pIPV6Elem = (PMBB_IPV6_ADDRESS)(InBuffer + IpAddressInfo->IPv6AddressOffset); + for (unsigned int i = 0; i < IpAddressInfo->IPv6AddressCount; i++, pIPV6Elem++) + { + TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: IPv6 #%d (prefixLen %d): %!IPV6ADDR!", + i + 1, pIPV6Elem->OnLinkPrefixLength, pIPV6Elem->IPV6Address); + } + } + + if (MBB_IP_IS_GWV6_AVAILABLE(IpAddressInfo)) + { + PIN6_ADDR pIn6Addr = (PIN6_ADDR)(InBuffer + IpAddressInfo->IPv6GatewayOffset); + TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: GWv6: %!IPV6ADDR!", pIn6Addr->u.Byte); + } + + if (MBB_IP_IS_DSV6_AVAILABLE(IpAddressInfo)) + { + PIN6_ADDR pIn6Addr = (PIN6_ADDR)(InBuffer + IpAddressInfo->IPv6DnsServerOffset); + for (unsigned int i = 0; i < IpAddressInfo->IPv6DnsServerCount; i++, pIn6Addr++) + { + TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: DNSv6 #%d: %!IPV6ADDR!", i+1, pIn6Addr->u.Byte); + } + } + + // + // Copy the received info. + // +#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate IP address info, only one instance exists, released if new IP info comes.") + if( (IpAddressInfo = ALLOCATE_NONPAGED_POOL( InBufferSize )) == NULL ) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: FAILED to allocate IP Address Info", Adapter->NetLuid.Value ); + break; + } + RtlCopyMemory( IpAddressInfo, InBuffer, InBufferSize ); + + MBB_ACQUIRE_PORT_LOCK(Port); + + if( Port->IpAddressInfo != NULL ) + { + FREE_POOL( Port->IpAddressInfo ); + } + Port->IpAddressInfo = IpAddressInfo; + + MBB_RELEASE_PORT_LOCK(Port); + + MbbIpQueueIPChange( + &GlobalControl, + &Adapter->NetLuid, + MbbReqMgrIsUnsolicitedIndication( Request )? + MbbIPChangeTypeDeviceConfigurationChange: + MbbIPChangeTypeDeviceConfiguration, + PortNumber + ); + + + } + while( FALSE ); + + if(Port != NULL) + { + // Remove the reference added in find + Dereference(Port); + } + + return NDIS_STATUS_SUCCESS; +} + +__callback +VOID +MbbIpProcessChange( + __in PVOID Context1, + __in PVOID Context2, + __in PVOID Context3, + __in PVOID Context4 + ) +{ + PMBB_REQUEST_CONTEXT NextRequest; +// PMINIPORT_DRIVER_CONTEXT Driver = (PMINIPORT_DRIVER_CONTEXT)Context1; + PMINIPORT_ADAPTER_CONTEXT Adapter= (PMINIPORT_ADAPTER_CONTEXT)Context2; + MBB_IP_CHANGE_TYPE IPChangeType = (MBB_IP_CHANGE_TYPE)Context3; + PMBB_PORT Port = (PMBB_PORT)Context4; + NDIS_PORT_NUMBER PortNumber = DEFAULT_NDIS_PORT_NUMBER; + PMBB_IPADDRESS_ENTRY IpTable = NULL; + ULONG IpCount; + PMBB_IPADDRESS_ENTRY GatewayTable = NULL; + ULONG GatewayCount; + PMBB_IPADDRESS_ENTRY DnsTable = NULL; + ULONG DnsCount = 0; + PMBB_IPADDRESS_ENTRY LastIpTable; + ULONG LastIpCount; + PMBB_IPADDRESS_ENTRY LastGatewayTable; + ULONG LastGatewayCount; + PMBB_IPADDRESS_ENTRY LastDnsTable; + ULONG LastDnsCount; + BOOLEAN IsUserConfiguredIP = FALSE; + MBB_CONNECTION_STATE ConnectionState; + NDIS_STATUS NdisStatus; + WWAN_IP_ADDRESS_STATE IpAddressState = {0}; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + TraceInfo( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] Processing %!MbbIPChangeType!", Adapter->NetLuid.Value, IPChangeType ); + + do + { + if(Port == NULL) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] IP change queued on invalid ndis port", Adapter->NetLuid.Value); + break; + } + + // + // Get current IP information + // + + MBB_ACQUIRE_PORT_LOCK(Port); + + PortNumber = Port->PortNumber; + + MbbIpSnapPortIpTable( + Port, + &IpTable, + &IpCount + ); + + MbbIpSnapPortAddressTable( + Port, + MbbAddressTableGateway, + &GatewayTable, + &GatewayCount + ); + // + // Only evaluate DNS changes when the device reports a change. + // + if( IPChangeType == MbbIPChangeTypeDeviceConfiguration || + IPChangeType == MbbIPChangeTypeDeviceConfigurationChange ) + { + MbbIpSnapPortAddressTable( + Port, + MbbAddressTableDns, + &DnsTable, + &DnsCount + ); + } + + Status = MbbUtilPopulateWwanIPAddressState( + Port->IpAddressInfo, + IpTable, + GatewayTable, + DnsTable, + IpCount, + GatewayCount, + DnsCount, + &IpAddressState); + + MBB_RELEASE_PORT_LOCK(Port); + + if(Status != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] IP change queued for disconnected port", Adapter->NetLuid.Value); + break; + } + + // For DEFAULT_NDIS_PORT ( i.e Port 0 ) update the IP address information + // For non default ports we send the indication upto the virtual miniport. + // The virtual miniport then updates its IP address information in the registry + + if(IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + MbbPortSetIpAddressState( + Adapter, + &IpAddressState, + PortNumber); + } + else + { + // Report the information in order to the IP stack for default port + WwanUpdateIPStack( + Adapter->MiniportAdapterHandle, + &IpAddressState, + Adapter->NetLuid, + Adapter->NetCfgId, + Adapter->IfIndex, + (IPChangeType == MbbIPChangeTypeDeviceConfiguration + || IPChangeType == MbbIPChangeTypeDeviceConfigurationChange) + ); + } + + // + // Indicate LinkUP to NDIS. + // In case of successful connect request this is done even when IP info was not reported to IP successfully + // since the CONNECT OID is already completed with success. Worst case is that the adapter will not + // have an IP info. + // + if( IPChangeType == MbbIPChangeTypeDeviceConfiguration ) + { + ConnectionState.ConnectionUp = MediaConnectStateConnected; + + ConnectionState.UpStreamBitRate = Adapter->UplinkSpeed; + ConnectionState.DownStreamBitRate = Adapter->DownlinkSpeed; + + MbbAdapterSetConnectionState( + Adapter, + &ConnectionState, + PortNumber + ); + } + } + while( FALSE ); + + if(DnsTable!= NULL) + { + FREE_POOL( DnsTable ); + DnsTable = NULL; + } + + if(IpTable!= NULL) + { + FREE_POOL( IpTable ); + IpTable = NULL; + } + + if(GatewayTable!= NULL) + { + FREE_POOL( GatewayTable ); + GatewayTable = NULL; + } + + if(IpAddressState.IpTable) + { + FREE_POOL(IpAddressState.IpTable); + IpAddressState.IpTable = NULL; + } + + if(IpAddressState.GatewayTable) + { + FREE_POOL(IpAddressState.GatewayTable); + IpAddressState.GatewayTable = NULL; + } + + if(IpAddressState.DnsTable) + { + FREE_POOL(IpAddressState.DnsTable); + IpAddressState.DnsTable = NULL; + } + + if(Port != NULL) + { + Dereference(Port); + } + + MbbAdapterDeref( Adapter ); +} + + +__callback +VOID +MbbIpInterfaceChangeCallback( + __in PVOID CallerContext, + __in_opt PMIB_IPINTERFACE_ROW Row, + __in MIB_NOTIFICATION_TYPE NotificationType + ) +{ + NET_LUID NetLuid; + PMINIPORT_DRIVER_CONTEXT Driver = (PMINIPORT_DRIVER_CONTEXT)CallerContext; + + switch( NotificationType ) + { + case MibInitialNotification : + { + TraceInfo( WMBCLASS_IP, "[MbbIP] Successfully regsitered for interface change notification" ); + } + break; + + case MibAddInstance : __fallthrough; + case MibDeleteInstance : __fallthrough; + case MibParameterNotification : __fallthrough; + { + ASSERT(Row != NULL); + + __analysis_assume(Row != NULL); + MbbIpQueueIPChange( + Driver, + &Row->InterfaceLuid, + MbbIPChangeTypeHostInterfaceChange, + DEFAULT_NDIS_PORT_NUMBER // indicate on default NDIS port, the adapter may indicate it to the miniport if needed + ); + } + break; + } +} + +__callback +VOID +MbbIpUnicastAddressChangeCallback( + _In_ PVOID CallerContext, + _In_opt_ PMIB_UNICASTIPADDRESS_ROW Row, + _In_ MIB_NOTIFICATION_TYPE NotificationType + ) +{ + PMINIPORT_DRIVER_CONTEXT Driver = (PMINIPORT_DRIVER_CONTEXT)CallerContext; + + if (Row != NULL) + { + MbbIpQueueIPChange( + Driver, + &Row->InterfaceLuid, + MbbIPChangeTypeHostIPChange, + DEFAULT_NDIS_PORT_NUMBER // indicate on default NDIS port, the adapter may indicate it to the miniport if needed + ); + } + else + { + ASSERT(NotificationType == MibInitialNotification); + } +} + +__callback +VOID +MbbIpRouteChangeCallback( + _In_ PVOID CallerContext, + _In_opt_ PMIB_IPFORWARD_ROW2 Row, + _In_ MIB_NOTIFICATION_TYPE NotificationType + ) +{ + PMINIPORT_DRIVER_CONTEXT Driver = (PMINIPORT_DRIVER_CONTEXT)CallerContext; + + if (Row != NULL) + { + if (NotificationType != MibDeleteInstance) + { + MbbIpQueueIPChange( + Driver, + &Row->InterfaceLuid, + MbbIPChangeTypeHostRouteChange, + DEFAULT_NDIS_PORT_NUMBER // indicate on default NDIS port, the adapter may indicate it to the miniport if needed + ); + } + } + else + { + ASSERT(NotificationType == MibInitialNotification); + } +} + +NDIS_STATUS +MbbIpQueueIPChange( + __in PMINIPORT_DRIVER_CONTEXT Driver, + __in PNET_LUID NetLuid, + __in MBB_IP_CHANGE_TYPE IPChangeType, + __in NDIS_PORT_NUMBER PortNumber + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + PMBB_PORT Port = NULL; + + if( (Adapter = MbbDriverFindAdapterByNetLuid( + Driver, + NetLuid + )) != NULL ) + { + Port = MbbWwanTranslatePortNumberToPort( + Adapter, + PortNumber); + + if(Port) + { + MBB_ACQUIRE_PORT_LOCK(Port); + + if( IPChangeType == MbbIPChangeTypeDeviceConfiguration || + Port->ConnectionState.ConnectionUp == TRUE ) + { + // Add reference to the port before queuing it up in the workitem. + // The workitem routine will cleanup the reference + + // Adapter find reference is reused and cleared insider the worker thread + Reference(Port); + if( (NdisStatus = MbbWorkMgrQueueWorkItem( + Driver->IpWorkItemManagerHandle, + Driver, + Adapter, + (PVOID)IPChangeType, + (PVOID)Port, + MbbIpProcessChange + )) != NDIS_STATUS_SUCCESS ) + { + // Remove the reference added for queuing + Dereference(Port); + TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] FAILED to queue work item to process %!MbbIPChangeType! with status=%!status!.", NetLuid->Value, IPChangeType, NdisStatus ); + } + else + { + TraceInfo( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] Queuing %!MbbIPChangeType!", NetLuid->Value, IPChangeType ); + } + } + else + { + NdisStatus = NDIS_STATUS_MEDIA_DISCONNECT; + } + + MBB_RELEASE_PORT_LOCK(Port); + } + else + { + NdisStatus = NDIS_STATUS_INVALID_PORT; + } + } + else + { + NdisStatus = NDIS_STATUS_ADAPTER_NOT_FOUND; + } + + if(Port!= NULL) + { + //Remove the reference on the port due to find + Dereference(Port); + } + + // + // If successful, adapter and port would be derefed in MbbIpProcessChange + // + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + if( Adapter != NULL ) + { + MbbAdapterDeref( Adapter ); + } + } + return NdisStatus; +} + +NDIS_STATUS +MbbIpInitialize( + __in PMINIPORT_DRIVER_CONTEXT Driver + ) +{ + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + // + // Work item manager + // + if( (Driver->IpWorkItemManagerHandle = MbbWorkMgrInitialize( MBB_PREALLOC_IP_WORKITEM_COUNT )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbIP] FAILED to initialize work item manager" ); + NtStatus = NDIS_STATUS_FAILURE; + break; + } + // + // Register with IP Helper for IP change notifications. + // + if( (NtStatus = NotifyIpInterfaceChange( + AF_UNSPEC, + MbbIpInterfaceChangeCallback, + Driver, + TRUE, + &Driver->IpInterfaceNotificationHandle + ))!= STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbIP] FAILED to register for Interface change notifications, status=%!STATUS!", NtStatus ); + NtStatus = NDIS_STATUS_FAILURE; + break; + } + + if( (NtStatus = NotifyRouteChange2( + AF_UNSPEC, + MbbIpRouteChangeCallback, + Driver, + TRUE, + &Driver->IpRouteNotificationHandle + )) != NO_ERROR ) + { + TraceError( WMBCLASS_INIT, "[MbbIP] FAILED to register for Route change notifications, status=%!STATUS!", NtStatus ); + NtStatus = NDIS_STATUS_FAILURE; + break; + } + + if( (NtStatus = NotifyUnicastIpAddressChange( + AF_UNSPEC, + MbbIpUnicastAddressChangeCallback, + Driver, + TRUE, + &Driver->IpUnicastAddressNotificationHandle + )) != NO_ERROR ) + { + TraceError( WMBCLASS_INIT, "[MbbIP] FAILED to register for Unicast address change notifications, status=%!STATUS!", NtStatus ); + NtStatus = NDIS_STATUS_FAILURE; + break; + } + } + while( FALSE ); + // + // Cleanup on error + // + if( NtStatus != NDIS_STATUS_SUCCESS ) + { + MbbIpCleanup( Driver ); + } + else + { + TraceInfo( WMBCLASS_INIT, "[MbbIP] IP subsystem initialized" ); + } + + return (NDIS_STATUS)NtStatus; +} + +VOID +MbbIpCleanup( + __in PMINIPORT_DRIVER_CONTEXT Driver + ) +{ + TraceInfo( WMBCLASS_INIT, "[MbbIP] IP subsystem clean up" ); + + if( Driver->IpUnicastAddressNotificationHandle != NULL ) + { + CancelMibChangeNotify2( Driver->IpUnicastAddressNotificationHandle ); + Driver->IpUnicastAddressNotificationHandle = NULL; + } + + if( Driver->IpRouteNotificationHandle != NULL ) + { + CancelMibChangeNotify2( Driver->IpRouteNotificationHandle ); + Driver->IpRouteNotificationHandle = NULL; + } + + if( Driver->IpInterfaceNotificationHandle != NULL ) + { + CancelMibChangeNotify2( Driver->IpInterfaceNotificationHandle ); + Driver->IpInterfaceNotificationHandle = NULL; + } + + if( Driver->IpWorkItemManagerHandle != NULL ) + { + MbbWorkMgrCleanup( Driver->IpWorkItemManagerHandle ); + Driver->IpWorkItemManagerHandle = NULL; + } +} diff --git a/network/wwan/cxwmbclass/IpAddress.h b/network/wwan/cxwmbclass/IpAddress.h new file mode 100644 index 000000000..2d64e68b1 --- /dev/null +++ b/network/wwan/cxwmbclass/IpAddress.h @@ -0,0 +1,74 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#define MBB_IP_IS_IPV4_AVAILABLE(_X_) (((_X_)->IPv4Flags & MbbIpFlagsAddressAvailable) == MbbIpFlagsAddressAvailable) +#define MBB_IP_IS_IPV6_AVAILABLE(_X_) (((_X_)->IPv6Flags & MbbIpFlagsAddressAvailable) == MbbIpFlagsAddressAvailable) +#define MBB_IP_IS_GWV4_AVAILABLE(_X_) (((_X_)->IPv4Flags & MbbIpFlagsGatewayAvailable) == MbbIpFlagsGatewayAvailable) +#define MBB_IP_IS_GWV6_AVAILABLE(_X_) (((_X_)->IPv6Flags & MbbIpFlagsGatewayAvailable) == MbbIpFlagsGatewayAvailable) +#define MBB_IP_IS_MTUV4_AVAILABLE(_X_) (((_X_)->IPv4Flags & MbbIpFlagsMTUAvailable) == MbbIpFlagsMTUAvailable) +#define MBB_IP_IS_MTUV6_AVAILABLE(_X_) (((_X_)->IPv6Flags & MbbIpFlagsMTUAvailable) == MbbIpFlagsMTUAvailable) +#define MBB_IP_IS_DSV4_AVAILABLE(_X_) (((_X_)->IPv4Flags & MbbIpFlagsDnsServerAvailable) == MbbIpFlagsDnsServerAvailable) +#define MBB_IP_IS_DSV6_AVAILABLE(_X_) (((_X_)->IPv6Flags & MbbIpFlagsDnsServerAvailable) == MbbIpFlagsDnsServerAvailable) + +#define MBB_IP_GET_IPV4TABLE(_X_) (PMBB_IPV4_ADDRESS)(MBB_IP_IS_IPV4_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv4AddressOffset): NULL) +#define MBB_IP_GET_IPV6TABLE(_X_) (PMBB_IPV6_ADDRESS)(MBB_IP_IS_IPV6_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv6AddressOffset): NULL) +#define MBB_IP_GET_GWV4TABLE(_X_) (IN_ADDR*) (MBB_IP_IS_GWV4_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv4GatewayOffset): NULL) +#define MBB_IP_GET_GWV6TABLE(_X_) (IN6_ADDR*)(MBB_IP_IS_GWV6_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv6GatewayOffset): NULL) +#define MBB_IP_GET_DSV4TABLE(_X_) (IN_ADDR*) (MBB_IP_IS_DSV4_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv4DnsServerOffset): NULL) +#define MBB_IP_GET_DSV6TABLE(_X_) (IN6_ADDR*)(MBB_IP_IS_DSV6_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv6DnsServerOffset): NULL) + +#define MBB_IP_GET_IPV4COUNT(_X_) (MBB_IP_IS_IPV4_AVAILABLE(_X_)? (_X_)->IPv4AddressCount: 0) +#define MBB_IP_GET_IPV6COUNT(_X_) (MBB_IP_IS_IPV6_AVAILABLE(_X_)? (_X_)->IPv6AddressCount: 0) +#define MBB_IP_GET_DSV4COUNT(_X_) (MBB_IP_IS_DSV4_AVAILABLE(_X_)? (_X_)->IPv4DnsServerCount: 0) +#define MBB_IP_GET_DSV6COUNT(_X_) (MBB_IP_IS_DSV6_AVAILABLE(_X_)? (_X_)->IPv6DnsServerCount: 0) +#define MBB_IP_GET_GWV4COUNT(_X_) (MBB_IP_IS_GWV4_AVAILABLE(_X_)? 1: 0) +#define MBB_IP_GET_GWV6COUNT(_X_) (MBB_IP_IS_GWV6_AVAILABLE(_X_)? 1: 0) + + + +//////////////////////////////////////////////////////////////////////////////// +// +// TYPEDEFS +// +//////////////////////////////////////////////////////////////////////////////// + +typedef enum +{ + MbbIPChangeTypeNone = 0, + MbbIPChangeTypeDeviceConfiguration, + MbbIPChangeTypeDeviceConfigurationChange, + MbbIPChangeTypeHostInterfaceChange, + MbbIPChangeTypeHostIPChange, + MbbIPChangeTypeHostRouteChange, + +} MBB_IP_CHANGE_TYPE; + +//////////////////////////////////////////////////////////////////////////////// +// +// PROTOTYPES +// +//////////////////////////////////////////////////////////////////////////////// +NDIS_STATUS +MbbIpInitialize( + __in PMINIPORT_DRIVER_CONTEXT Driver + ); + +VOID +MbbIpCleanup( + __in PMINIPORT_DRIVER_CONTEXT Driver + ); + +NDIS_STATUS +MbbIpAddressStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); diff --git a/network/wwan/cxwmbclass/LocalWPP.ini b/network/wwan/cxwmbclass/LocalWPP.ini new file mode 100644 index 000000000..eb04ac298 --- /dev/null +++ b/network/wwan/cxwmbclass/LocalWPP.ini @@ -0,0 +1,21 @@ +CUSTOM_TYPE( MbbStatus, ItemEnum(MBB_STATUS) ); +CUSTOM_TYPE( MbbError, ItemEnum(MBB_ERROR) ); +CUSTOM_TYPE( MbbTimer, ItemEnum(MBB_TIMER_TYPE) ); +CUSTOM_TYPE( MbbMsgType, ItemEnum(MBB_MESSAGE_TYPE) ); +CUSTOM_TYPE( MbbCmdType, ItemEnum(MBB_COMMAND_TYPE) ); +CUSTOM_TYPE( MbbOidState, ItemEnum(MBB_NDIS_OID_STATE) ); +CUSTOM_TYPE( MbbRequestState, ItemEnum(MBB_REQUEST_STATE) ); +CUSTOM_TYPE( MbbRequestEvent, ItemEnum(MBB_REQUEST_EVENT) ); +CUSTOM_TYPE( MbbCellularClass, ItemEnum(MBB_CELLULAR_CLASS) ); +CUSTOM_TYPE( MibNotificationType, ItemEnum(MIB_NOTIFICATION_TYPE) ); +CUSTOM_TYPE( MbbAddressType, ItemEnum(MBB_ADDRESS_TABLE_ID) ); +CUSTOM_TYPE( MbbIPChangeType, ItemEnum(MBB_IP_CHANGE_TYPE) ); +CUSTOM_TYPE( WwanStatus, ItemEnum(wwan_status) ); +CUSTOM_TYPE( UsbCapDeviceType, ItemEnum(USB_CAP_DEVICE_TYPE) ); +CUSTOM_TYPE( MbbNblType, ItemEnum(MBB_NBL_TYPE) ); + +DEFINE_CPLX_TYPE(IPV4ADDR,WPP_LOGIPV4, CONST UCHAR*,ItemIPAddr,"s", _IPV4_, 0); +WPP_FLAGS(-DWPP_LOGIPV4(x) WPP_LOGPAIR( 4, (x))); + +DEFINE_CPLX_TYPE(IPV6ADDR,WPP_LOGIPV6, CONST UCHAR*,ItemIPV6Addr,"s", _IPV6_, 0); +WPP_FLAGS(-DWPP_LOGIPV6(x) WPP_LOGPAIR( 16, (x))); diff --git a/network/wwan/cxwmbclass/MbbFastIOControlPlane.c b/network/wwan/cxwmbclass/MbbFastIOControlPlane.c new file mode 100644 index 000000000..b96abe167 --- /dev/null +++ b/network/wwan/cxwmbclass/MbbFastIOControlPlane.c @@ -0,0 +1,116 @@ +#include "precomp.h" +#include "MbbFastIOControlPlane.tmh" + +BOOL FastIOPause(_In_ PSTATE_CHANGE_EVENT StateChange) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + if (MbbBusIsFastIO(Adapter->BusHandle)) + { + NdisAcquireSpinLock(&Adapter->Lock); + ASSERT(Adapter->AdapterState.Started); + Adapter->AdapterState.Started = FALSE; + NdisReleaseSpinLock(&Adapter->Lock); + + //MbbBusPause must return NDIS_STATUS_SUCCESS since we only support synchronous FastIOPause now + Status = MbbBusPause(Adapter->BusHandle); + ASSERT(Status == NDIS_STATUS_SUCCESS); + TraceInfo(WMBCLASS_INIT, "FastIO Completing Pause"); + + MbbWriteEvent( + &PAUSE_COMPLETE_EVENT, + NULL, + NULL, + 2, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &Status, + sizeof(Status) + ); + + NdisMPauseComplete(Adapter->MiniportAdapterHandle); + CompleteStateChange( + &Adapter->AdapterState, + StateChange + ); + return TRUE; + } + + return FALSE; +} + +BOOL FastIOReset(_In_ PSTATE_CHANGE_EVENT StateChange) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + if (MbbBusIsFastIO(Adapter->BusHandle)) + { + //FastIOReset must return NDIS_STATUS_SUCCESS since we only support synchronous FastIOReset now + Status = MbbBusReset(Adapter->BusHandle); + ASSERT(Status == NDIS_STATUS_SUCCESS); + TraceInfo(WMBCLASS_INIT, "FastIO Completing Reset"); + + MbbWriteEvent( + &RESET_COMPLETE_EVENT, + NULL, + NULL, + 2, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &Status, + sizeof(Status) + ); + NdisMResetComplete( + Adapter->MiniportAdapterHandle, + StateChange->Reset.PipeStartStatus, + FALSE + ); + CompleteStateChange( + &Adapter->AdapterState, + StateChange + ); + return TRUE; + } + + return FALSE; +} + +BOOL FastIORestart(_In_ PSTATE_CHANGE_EVENT StateChange) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + if (MbbBusIsFastIO(Adapter->BusHandle)) + { + NdisAcquireSpinLock(&Adapter->Lock); + Adapter->AdapterState.Started = TRUE; + NdisReleaseSpinLock(&Adapter->Lock); + + //FastIORestart must return NDIS_STATUS_SUCCESS since we only support synchronous FastIORestart now + Status = MbbBusRestart(Adapter->BusHandle); + ASSERT(Status == NDIS_STATUS_SUCCESS); + TraceInfo(WMBCLASS_INIT, "FastIO Completing Restart"); + + MbbWriteEvent( + &RESTART_COMPLETE_EVENT, + NULL, + NULL, + 2, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &Status, + sizeof(Status) + ); + + NdisMRestartComplete(Adapter->MiniportAdapterHandle, Status); + CompleteStateChange( + &Adapter->AdapterState, + StateChange + ); + return TRUE; + } + + return FALSE; +} \ No newline at end of file diff --git a/network/wwan/cxwmbclass/MbbFastIOControlPlane.h b/network/wwan/cxwmbclass/MbbFastIOControlPlane.h new file mode 100644 index 000000000..447063491 --- /dev/null +++ b/network/wwan/cxwmbclass/MbbFastIOControlPlane.h @@ -0,0 +1,5 @@ +#pragma once + +BOOL FastIOPause(_In_ PSTATE_CHANGE_EVENT StateChange); +BOOL FastIOReset(_In_ PSTATE_CHANGE_EVENT StateChange); +BOOL FastIORestart(_In_ PSTATE_CHANGE_EVENT StateChange); \ No newline at end of file diff --git a/network/wwan/cxwmbclass/MbbFastIODataPlane.c b/network/wwan/cxwmbclass/MbbFastIODataPlane.c new file mode 100644 index 000000000..d63e1fffb --- /dev/null +++ b/network/wwan/cxwmbclass/MbbFastIODataPlane.c @@ -0,0 +1,263 @@ +#include "precomp.h" +#include "MbbFastIODataPlane.tmh" + +VOID +FastIOSendNetBufferListsComplete( + _In_ PVOID MiniportAdapterContext, + _In_ PNET_BUFFER_LIST NetBufferLists, + _In_ ULONG SendCompleteFlags +) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + MBB_NBL_TYPE NblType = MBB_NBL_TYPE_MAXIMUM, LastNblType = MBB_NBL_TYPE_MAXIMUM; + PVOID NblContext; + USHORT NblContextSize; + MBB_REQUEST_HANDLE RequestHandle = NULL; + PNET_BUFFER_LIST NetBufferList = NetBufferLists, NextNetBufferList = NULL; + PNET_BUFFER NetBuffer = NULL; + + ASSERT(Adapter != NULL); + for (NetBufferList = NetBufferList; + NetBufferList != NULL; + NetBufferList = NextNetBufferList) + { + NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NblContext = NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); + NblContextSize = ALIGN(sizeof(MBB_NBL_TYPE), MEMORY_ALLOCATION_ALIGNMENT); + + ASSERT(NblContext != NULL); + + NblType = *((MBB_NBL_TYPE*)NblContext); + NdisFreeNetBufferListContext(NetBufferList, NblContextSize); + + if (LastNblType != MBB_NBL_TYPE_MAXIMUM && LastNblType != NblType) + { + TraceError(WMBCLASS_SEND, "[FastIOSend] Doesn't allow mixed NBL data type in the list, OS will crash. [NblType=%!MbbNblType!] [LastNblType=%!MbbNblType!] [NBL=0x%p]", + NblType, LastNblType, NetBufferList); + ASSERT(FALSE); + return; + } + + LastNblType = NblType; + + switch (NblType) + { + case MBB_NBL_TYPE_IP: + for (NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); + NetBuffer != NULL; + NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer)) + { + InterlockedAdd64(&Adapter->Stats.ifHCOutOctets, NET_BUFFER_DATA_LENGTH(NetBuffer)); + InterlockedIncrement64(&Adapter->GenXmitFramesOk); + InterlockedIncrement64(&Adapter->Stats.ifHCOutUcastPkts); + } + break; + case MBB_NBL_TYPE_DSS: + RequestHandle = (MBB_REQUEST_HANDLE)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList)[0]; + MbbNdisDeviceServiceSessionSendComplete( + RequestHandle, + NetBufferList->Status + ); + + // Free the Nbl & stuff associated with the request + MbbCleanupDssNbl(&Adapter->SendQueue, NetBufferList); + break; + default: + TraceError(WMBCLASS_SEND, "[FastIOSend] Unknown MBB_NBL_TYPE [%!MbbNblType!], OS will crash. [NBL=0x%p]", NblType, NetBufferList); + ASSERT(FALSE); + return; + } + } + + if (NblType == MBB_NBL_TYPE_IP) + { + NdisMSendNetBufferListsComplete(Adapter->MiniportAdapterHandle, NetBufferLists, SendCompleteFlags); + } +} + + +VOID +FastIONdisDeviceServiceSessionReceive( + _In_ PMINIPORT_ADAPTER_CONTEXT AdapterContext, + _In_ PNET_BUFFER_LIST NetBufferList, + _In_ ULONG SessionId, + _In_ ULONG ReceiveFlags +) +{ + PNET_BUFFER NetBuffer; + PMDL Mdl; + PCHAR MdlDataBuffer = NULL; + ULONG MdlDataOffset; + ULONG MdlDataLength; + ULONG datagramLength; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ NdisWwanDssRead = NULL; + PCHAR NdisWwanDssReadBuffer = NULL; + ULONG TotalNdisWwanSize = 0; + ULONG ReturnFlags = (ReceiveFlags & NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL) ? NDIS_RETURN_FLAGS_DISPATCH_LEVEL : 0; + + for (NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); + NetBuffer != NULL; + NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer)) + { + + datagramLength = NET_BUFFER_DATA_LENGTH(NetBuffer); + TotalNdisWwanSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_READ) + datagramLength; + // Allocate memory for the output buffer + if ((NdisWwanDssRead = (PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ)ALLOCATE_NONPAGED_POOL(TotalNdisWwanSize)) == NULL) + { + TraceError(WMBCLASS_RECEIVE, "[Receive][DSS Read] FAILED to allocate for PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ %d bytes", + TotalNdisWwanSize + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + NdisWwanDssRead->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisWwanDssRead->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_READ_1; + NdisWwanDssRead->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SESSION_READ_REVISION_1; + + NdisWwanDssRead->ReadData.uDataSize = datagramLength; + NdisWwanDssRead->ReadData.uSessionID = SessionId; + + // Copy the data. We cannot use the original buffer because it doesnt + // have space for the session Id, etc + Mdl = NET_BUFFER_CURRENT_MDL(NetBuffer); + MdlDataOffset = NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer); + NdisWwanDssReadBuffer = (PCHAR)(NdisWwanDssRead + 1); + + for (; + datagramLength > 0; + datagramLength -= MdlDataLength) + { + MdlDataLength = MmGetMdlByteCount(Mdl) - MdlDataOffset; + if ((MdlDataBuffer = (PCHAR)MmGetSystemAddressForMdlSafe( + Mdl, + NormalPagePriority | MdlMappingNoExecute + )) == NULL) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + MdlDataBuffer = MdlDataBuffer + MdlDataOffset; + MdlDataLength = MIN(datagramLength, MdlDataLength); + + RtlCopyMemory( + NdisWwanDssReadBuffer, + MdlDataBuffer, + MdlDataLength + ); + + NdisWwanDssReadBuffer = NdisWwanDssReadBuffer + MdlDataLength; + Mdl = Mdl->Next; + MdlDataOffset = 0; + } + + // Create the status indication + MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION( + &StatusIndication, + AdapterContext->MiniportAdapterHandle, + NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ + ); + + StatusIndication.StatusBuffer = NdisWwanDssRead; + StatusIndication.StatusBufferSize = TotalNdisWwanSize; + + TraceInfo(WMBCLASS_RECEIVE, "[Receive][DSS Read] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ"); + + MbbUtilNdisMiniportIndicateStatusEx( + AdapterContext, + &StatusIndication + ); + if (NdisWwanDssRead) + { + FREE_POOL(NdisWwanDssRead); + } + } + + NET_BUFFER_LIST_STATUS(NetBufferList) = NdisStatus; + if ((ReceiveFlags & NDIS_RECEIVE_FLAGS_RESOURCES) == 0) + MbbBusReturnNetBufferLists(AdapterContext->BusHandle, NetBufferList, ReturnFlags); +} + +VOID +FastIOIndicateReceiveNetBufferLists( + _In_ PVOID MiniportAdapterContext, + _In_ PNET_BUFFER_LIST NetBufferLists, + _In_ ULONG SessionId, + _In_ ULONG NumberOfNetBufferLists, + _In_ ULONG ReceiveFlags +) +{ + PVOID NblContext = NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter; + SESSIONID_PORTNUMBER_ENTRY SessionIdPortNumberEntry = { 0 }; + MBB_NBL_TYPE NblType; + ULONG ReturnFlags = (ReceiveFlags & NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL) ? NDIS_RETURN_FLAGS_DISPATCH_LEVEL : 0; + PNET_BUFFER_LIST NetBufferList = NetBufferLists, NextNetBufferList = NULL; + PNET_BUFFER NetBuffer = NULL; + + if (NetBufferList == NULL) + { + return; + } + + NblContext = NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + + ASSERT(NblContext != NULL); + ASSERT(Adapter != NULL); + + NblType = *((MBB_NBL_TYPE*)NblContext); + SessionIdPortNumberEntry = Adapter->SessionIdPortTable[SessionId]; + + switch (NblType) + { + case MBB_NBL_TYPE_IP: + if (!SessionIdPortNumberEntry.InUse) + { + //discard + TraceError(WMBCLASS_RECEIVE, "[FastIORecv][NBL=0x%p] FAILED to receive NBL as session id is not in use. [Session Id = %lu]", + NetBufferList, + SessionId + ); + NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_INVALID_PARAMETER; + InterlockedIncrement64(&Adapter->Stats.ifInDiscards); + MbbBusReturnNetBufferLists(Adapter->BusHandle, NetBufferList, ReturnFlags); + return; + } + for (; + NetBufferList != NULL; + NetBufferList = NextNetBufferList) + { + NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NetBufferList->SourceHandle = Adapter->MiniportAdapterHandle; + for (NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); + NetBuffer != NULL; + NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer)) + { + InterlockedAdd64(&Adapter->Stats.ifHCInOctets, NET_BUFFER_DATA_LENGTH(NetBuffer)); + InterlockedIncrement64(&Adapter->GenRcvFramesOk); + InterlockedIncrement64(&Adapter->Stats.ifHCInUcastPkts); + } + } + NdisMIndicateReceiveNetBufferLists(Adapter->MiniportAdapterHandle, NetBufferLists, SessionIdPortNumberEntry.PortNumber, NumberOfNetBufferLists, ReceiveFlags); + break; + case MBB_NBL_TYPE_DSS: + + for (; + NetBufferList != NULL; + NetBufferList = NextNetBufferList) + { + NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; + FastIONdisDeviceServiceSessionReceive(Adapter, NetBufferList, SessionId, ReceiveFlags); + } + break; + default: + TraceError(WMBCLASS_RECEIVE, "[FastIOReceive] Unknown MBB_NBL_TYPE [%!MbbNblType!], OS will crash. [NBL=0x%p]", NblType, NetBufferLists); + ASSERT(FALSE); + break; + } +} diff --git a/network/wwan/cxwmbclass/MbbFastIODataPlane.h b/network/wwan/cxwmbclass/MbbFastIODataPlane.h new file mode 100644 index 000000000..ae40944a4 --- /dev/null +++ b/network/wwan/cxwmbclass/MbbFastIODataPlane.h @@ -0,0 +1,12 @@ +#pragma once +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +FastIONdisDeviceServiceSessionReceive( + _In_ PMINIPORT_ADAPTER_CONTEXT AdapterContext, + _In_ PNET_BUFFER_LIST NetBufferList, + _In_ ULONG SessionId, + _In_ ULONG ReceiveFlags +); + +FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE FastIOSendNetBufferListsComplete; +FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS FastIOIndicateReceiveNetBufferLists; \ No newline at end of file diff --git a/network/wwan/cxwmbclass/MbbLibrary.c b/network/wwan/cxwmbclass/MbbLibrary.c new file mode 100644 index 000000000..1b575c8de --- /dev/null +++ b/network/wwan/cxwmbclass/MbbLibrary.c @@ -0,0 +1,505 @@ +/*************************************************************************** + +Copyright (c) 2010 Microsoft Corporation + +Module Name: + + MbbLibrary.c + +Abstract: + + This files contains the implementation of the pack / unpack and + fragment / reassembly functions provided by the Mbb library. + The class driver Protocol layer calls the libary to convert payloads + to messages as defined in the MBB Class Driver Hardware Interface + document before sending it to the Bus Layer. + +Environment: + + User and kernel mode only + +Notes: + + This library can be used both in user and kernel mode because it does not + to make any memory allocations. + +Revision History: + + 2/7/2010 : created + +Authors: + + TriRoy + +****************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#include +#include "tmpMbbMessages.h" +#include "MbbLibrary.h" +//#include "MbbLibrary.tmh" + +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#define MIN( _X_, _Y_ ) (((_X_) < (_Y_))? (_X_): (_Y_)) + +//////////////////////////////////////////////////////////////////////////////// +// +// FUNCTION PROTOTYPES +// +//////////////////////////////////////////////////////////////////////////////// +ULONG +MbbLibraryGetNextTransactionId( ); + + +//////////////////////////////////////////////////////////////////////////////// +// +// GLOBALS +// +//////////////////////////////////////////////////////////////////////////////// +static ULONG GlobalMbbLibraryTransactionId; + + +//////////////////////////////////////////////////////////////////////////////// +// +// EXPORTED ROUTINES +// +//////////////////////////////////////////////////////////////////////////////// +NTSTATUS +MbbLibForamtBufferAsOpenMessage( + __out_bcount_opt(*BufferLength) PVOID MessageBuffer, + __inout PULONG BufferLength, + __in ULONG MaximumControlTransfer + ) +/* + Description + Formats an input buffer as a MBB Open Message. + + Parameters + __out_opt_bcount(*BufferLength) PVOID MessageBuffer + The input message buffer. This parameter may be NULL + if BufferLength is 0. This parameter should not be NULL + when BufferLength is non-zero. + + __inout PULONG BufferLength + This provides the length of the memory location described by MessageBuffer. + If BufferLength is 0 then the function will return the required buffer length + in this parameter with STATUS_BUFFER_OVERFLOW. On success, the amount of + buffer space used by the routine is returned to the caller in BufferLength. + + __in ULONG MaximumControlTransfer + MaximumControlTransfer field of the Open Message. + + Return Value + STATUS_BUFFER_OVERFLOW + The buffer passed in is not sufficient for formatting the message. + + STATUS_INVALID_PARAMETER + One of the required parameters is missing. + + STATUS_SUCCESS + The input buffer was formatted successfully and the amount of buffer + used is returned in BufferLength. +*/ +{ + NTSTATUS Status = STATUS_SUCCESS; + PMBB_OPEN_MESSAGE Open = (PMBB_OPEN_MESSAGE)(MessageBuffer); + + do + { + if( BufferLength == NULL ) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + else if( *BufferLength != 0 && Open == NULL ) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + // + // If the caller is querying for the size or + // there isnt enough space in the buffer, + // return the size with the correct status. + // + if( *BufferLength < sizeof( MBB_OPEN_MESSAGE ) ) + { + *BufferLength = sizeof( MBB_OPEN_MESSAGE ); + Status = STATUS_BUFFER_OVERFLOW; + break; + } + // + // Sufficient space available. Format the input + // buffer as an open message. + // + Open->MessageHeader.MessageType = MBB_MESSAGE_TYPE_OPEN; + Open->MessageHeader.MessageLength = sizeof( MBB_OPEN_MESSAGE ); + Open->MessageHeader.MessageTransactionId = MbbLibraryGetNextTransactionId( ); + Open->MaximumControlTransfer = MaximumControlTransfer; + // + // Update how much buffer is written. + // + *BufferLength = sizeof( MBB_OPEN_MESSAGE ); + + } while( FALSE ); + + return Status; +} + +NTSTATUS +MbbLibForamtBufferAsCloseMessage( + __out_bcount_opt(*BufferLength) PVOID MessageBuffer, + __inout PULONG BufferLength + ) +/* + Description + Formats an input buffer as a MBB Close Message. + + Parameters + __out_opt_bcount(*BufferLength) PVOID MessageBuffer + The input message buffer. This parameter may be NULL + if BufferLength is 0. This parameter should not be NULL + when BufferLength is non-zero. + + __inout PULONG BufferLength + This provides the length of the memory location described by MessageBuffer. + If BufferLength is 0 then the function will return the required buffer length + in this parameter with STATUS_BUFFER_OVERFLOW. On success, the amount of + buffer space used by the routine is returned to the caller in BufferLength. + + Return Value + STATUS_BUFFER_OVERFLOW + The buffer passed in is not sufficient for formatting the message. + + STATUS_INVALID_PARAMETER + One of the required parameters is missing. + + STATUS_SUCCESS + The input buffer was formatted successfully and the amount of buffer + used is returned in BufferLength. +*/ +{ + NTSTATUS Status = STATUS_SUCCESS; + PMBB_CLOSE_MESSAGE Close = (PMBB_CLOSE_MESSAGE)(MessageBuffer); + + do + { + if( BufferLength == NULL ) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + else if( *BufferLength != 0 && Close == NULL ) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + // + // If the caller is querying for the size or + // there isnt enough space in the buffer, + // return the size with the correct status. + // + if( *BufferLength < sizeof( MBB_CLOSE_MESSAGE ) ) + { + *BufferLength = sizeof( MBB_CLOSE_MESSAGE ); + Status = STATUS_BUFFER_OVERFLOW; + break; + } + // + // Sufficient space available. Format the input + // buffer as an open message. + // + Close->MessageHeader.MessageType = MBB_MESSAGE_TYPE_CLOSE; + Close->MessageHeader.MessageLength = sizeof( MBB_CLOSE_MESSAGE ); + Close->MessageHeader.MessageTransactionId = MbbLibraryGetNextTransactionId( ); + // + // Update how much buffer is written. + // + *BufferLength = sizeof( MBB_CLOSE_MESSAGE ); + + } while( FALSE ); + + return Status; +} + +NTSTATUS +MbbLibFragmentBufferToCommandMessages( + __in PMBB_COMMAND Command, + __in MBB_COMMAND_TYPE CommandType, + __in_bcount_opt(PayloadLength) PCHAR Payload, + __in ULONG PayloadLength, + __inout_opt PULONG TransactionId, + __in ULONG CurrentFragment, + __inout PULONG FragmentBufferCount, + __inout PULONG FragmentLength, + __out_ecount_opt(*FragmentBufferCount) PCHAR* FragmentBuffers + ) +/* + Description + Given the Payload the routine fragments the payload + in to the FragmentBuffers. + + Parameters + __in MBB_COMMAND Command + Command contains the GUID and Cid. + The GUID identifying the service for this message. + The command identifier for the given service. + + __in MBB_COMMAND_TYPE CommandType + Identifies whether the command is a Set or Query. + + __in_bcount(PayloadLength) PCHAR Payload + The Payload is a byte array that needs to be fragmented. + If Payload length is not 0 Payload should be provided. + + __in ULONG PayloadLength + Length of the payload. If there is no Payload for this command + Payload is set to 0. + + __inout PULONG TransactionId + If non-zero then this is the transaction id used for the fragments. + If zero then a new transcation id is generated and returned to the caller. + + __in ULONG CurrentFragment + If non-zero then Fragments are constructed starting this Fragment. + If zero then Fragments are constructed from the beginning. + + __inout ULONG FragmentBufferCount + Number of input fragments i.e. numberof buffers described by + FragmentBuffers array. If the caller is querying for the + number of fragments required then this should be set to 0. + The function will return the number of fragment required + with STATUS_BUFFER_OVERFLOW. + + __in ULONG FragmentLength + Length of each output fragment buffers. All fragment + buffers needs to be of the same size. + The length of the last fragment is returned on STATUS_SUCCESS. + All but the last fragment are of FragmentLength size. + The last fragment can be lesser than the FragmentLength size. + + __out_ecount_opt(*FragmentBufferCount) PCHAR* FragmentBuffers + Array of input fragment buffers. If FragmentCount is 0 + FragmentBuffers can be NULL. If FragmentCount is non 0 + FragmentBuffers should be provided. + + Return Value + STATUS_INVALID_PARAMETER + One of the required parameters is missing. + + STATUS_SUCCESS + The Payload was fragmented successfully in to + FragmentBuffers and the number of fragments used is + returned in FragmentCount. + + STATUS_MORE_PROCESSING_REQUIRED + The complete Payload is not fragmented yet. + This is not a failure code but an indication to the caller that + more calls are needed with more fragment buffers. +*/ +{ + NTSTATUS Status = STATUS_SUCCESS; + PCHAR FragmentPayload; + ULONG BufferIndex; + ULONG FirstFragmentPayloadSize; + ULONG OtherFragmentPayloadSize; + ULONG FragmentPayloadLength; + ULONG TotalFragments; + ULONG PayloadOffset; + PMBB_COMMAND_HEADER CommandHeader; + PMBB_COMMAND_FRAGMENT_HEADER CommandFragmentHeader = NULL; + + do + { + // + // Parameter Validation. + // Check for required parameters. + // + if( (Command == NULL) || (FragmentBufferCount == NULL) || (FragmentLength == 0) || + (PayloadLength != 0 && Payload == NULL) || + (*FragmentBufferCount != 0 && FragmentBuffers == NULL) ) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + // + // The fragments must be atleast the header size. + // + if( *FragmentLength < sizeof(MBB_COMMAND_HEADER) ) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + // + // The size of the payload each fragment can carry. + // + FirstFragmentPayloadSize = *FragmentLength - sizeof(MBB_COMMAND_HEADER); + OtherFragmentPayloadSize = *FragmentLength - sizeof(MBB_COMMAND_FRAGMENT_HEADER); + // + // Calculate the number of fragments required. + // Equation to calculate the fragment count. + // Key : + // CH = CommandHeader = sizeof(MBB_COMMAND_HEADER) + // FH = FragmentHeader = sizeof(MBB_COMMAND_FRAGMENT_HEADER) + // PL = PayloadLength + // FL = FragmentLength + // n = FragmentBufferCount + // + // 1. There is 1 CH and (n-1) FH in n Fragments. + // 2. So the total length of all fragments would be (CH + (n-1)FH + PL). + // 3. To round off the result add (FL-FH-1). + // + // CH + (n-1)FH + PL + (FL-FH-1) / FL = n + // n = ( (CH+PL-1) + (FL-2FH) ) / (FL-FH) + // + TotalFragments = (sizeof(MBB_COMMAND_HEADER) + PayloadLength - 1); + TotalFragments += (*FragmentLength - (2* sizeof(MBB_COMMAND_FRAGMENT_HEADER))); + TotalFragments /= (*FragmentLength - sizeof(MBB_COMMAND_FRAGMENT_HEADER)); + // + // Starting fragment cannot be larger than the total fragments. + // + if( CurrentFragment >= TotalFragments ) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + // + // If the caller is querying for the size + // return the required fragment count to the caller. + // + if( *FragmentBufferCount == 0 ) + { + *FragmentBufferCount = (TotalFragments-CurrentFragment); + Status = STATUS_SUCCESS; + break; + } + // + // Get a transaction Id if not provided. + // Only get a new TransactionId if we are starting fragmentation. + // Do not get a new transaction id while in the middle of fragmentation. + // + if( TransactionId == NULL ) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + if( *TransactionId == 0 ) + { + *TransactionId = MbbLibraryGetNextTransactionId( ); + } + // + // PayloadOffset for Fragment #m is equal to amount of data + // in (m-1) fragments. + // + if( CurrentFragment > 0 ) + { + PayloadOffset = FirstFragmentPayloadSize; + PayloadOffset += (CurrentFragment-1) * OtherFragmentPayloadSize; + } + else + { + PayloadOffset = 0; + } + // + // Format the fragment buffers. + // + for( BufferIndex = 0; + BufferIndex < *FragmentBufferCount; + BufferIndex++ ) + { + // + // If all the data is filled dont create anymore fragments. + // This check is for the case where there are more fragments + // than are required. + // + if( PayloadLength != 0 && + PayloadOffset >= PayloadLength ) + { + break; + } + // + // Common header for all fragments + // + CommandFragmentHeader = (PMBB_COMMAND_FRAGMENT_HEADER)FragmentBuffers[BufferIndex]; + + CommandFragmentHeader->MessageHeader.MessageType = MBB_MESSAGE_TYPE_COMMAND; + CommandFragmentHeader->MessageHeader.MessageTransactionId = *TransactionId; + CommandFragmentHeader->FragmentHeader.CurrentFragment = (USHORT)CurrentFragment; + CommandFragmentHeader->FragmentHeader.TotalFragments = (USHORT)TotalFragments; + // + // Special handling for the first fragment. + // + if( CurrentFragment == 0 ) + { + CommandHeader = (PMBB_COMMAND_HEADER)FragmentBuffers[BufferIndex]; + + MBB_UUID_TO_NET( + &CommandHeader->Command.ServiceId, + &Command->ServiceId + ); + + CommandHeader->Command.CommandId = Command->CommandId; + CommandHeader->CommandType = CommandType; + CommandHeader->InformationBufferLength = PayloadLength; + + FragmentPayload = FragmentBuffers[BufferIndex] + sizeof(MBB_COMMAND_HEADER); + FragmentPayloadLength = MIN( ( PayloadLength - PayloadOffset ), FirstFragmentPayloadSize ); + CommandFragmentHeader->MessageHeader.MessageLength = FragmentPayloadLength + sizeof(MBB_COMMAND_HEADER); + } + else + { + FragmentPayload = FragmentBuffers[BufferIndex] + sizeof(MBB_COMMAND_FRAGMENT_HEADER); + FragmentPayloadLength = MIN( ( PayloadLength - PayloadOffset ), OtherFragmentPayloadSize ); + CommandFragmentHeader->MessageHeader.MessageLength = FragmentPayloadLength + sizeof(MBB_COMMAND_FRAGMENT_HEADER); + } + // + // Copy the actual payload. + // + memcpy( + FragmentPayload, + Payload + PayloadOffset, + FragmentPayloadLength + ); + CurrentFragment++; + PayloadOffset += FragmentPayloadLength; + } + // + // Update how much data is written. + // FragmentLength is the length of ONLY the last fragment. + // + *FragmentBufferCount = BufferIndex; + if (CommandFragmentHeader) + { + *FragmentLength = CommandFragmentHeader->MessageHeader.MessageLength; + } + // + // If the complete Payload is not fragmented indicate it to the caller. + // + if( CurrentFragment < TotalFragments ) + Status = STATUS_MORE_PROCESSING_REQUIRED; + else + Status = STATUS_SUCCESS; + + } while( FALSE ); + + return Status; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// INTERNAL ROUTINES +// +//////////////////////////////////////////////////////////////////////////////// + +ULONG +MbbLibraryGetNextTransactionId( ) +{ + return InterlockedIncrement( &GlobalMbbLibraryTransactionId ); +} diff --git a/network/wwan/cxwmbclass/RequestManager.c b/network/wwan/cxwmbclass/RequestManager.c new file mode 100644 index 000000000..9f639ecb2 --- /dev/null +++ b/network/wwan/cxwmbclass/RequestManager.c @@ -0,0 +1,2176 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" +#include "RequestManager.tmh" +#include "WMBClassTelemetry.h" + +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#define MBB_REQUEST_TIMEOUT_TOLERANCE_MS 5000 // 5 sec in milliseconds +#define MBB_REQUEST_TIMEOUT_MS 210000 // 210secs in milliseconds +#define MBB_REQUEST_TIMEOUT_100NS ((LONGLONG)MBB_REQUEST_TIMEOUT_MS * 10000) +#define MBB_FRAGMENT_TIMEOUT_TOLERANCE_MS 100 +#define MBB_FRAGMENT_TIMEOUT_MS 1250 // based on MBIM spec +#define MBB_FRAGMENT_TIMEOUT_100NS ((LONGLONG)MBB_FRAGMENT_TIMEOUT_MS * 10000) + + +//////////////////////////////////////////////////////////////////////////////// +// +// TYPEDEFS +// +//////////////////////////////////////////////////////////////////////////////// +typedef +VOID +(*MBB_REQUEST_STATE_TRANSITION)( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ); + + +//////////////////////////////////////////////////////////////////////////////// +// +// DECLARATIONS +// +//////////////////////////////////////////////////////////////////////////////// + +__callback +VOID +MbbReqMgrDrainCompleteCallback( + __in PVOID Context + ); + +// +// ASYNC CONTEXT MANAGEMENT +// + +VOID +MbbReqMgrTimerCallback( + __in PVOID SystemSpecific1, + __in PVOID FunctionContext, + __in PVOID SystemSpecific2, + __in PVOID SystemSpecific3 + ); + +VOID +MbbReqMgrTimerRequestTimeoutCallback( + __in PVOID SystemSpecific1, + __in PVOID FunctionContext, + __in PVOID SystemSpecific2, + __in PVOID SystemSpecific3 + ); + +VOID +MbbReqMgrTimerFragmentTimeoutCallback( + __in PVOID SystemSpecific1, + __in PVOID FunctionContext, + __in PVOID SystemSpecific2, + __in PVOID SystemSpecific3 + ); + +VOID +MbbReqMgrCleanupRequest( + __in __drv_freesMem(Mem) PMBB_REQUEST_CONTEXT Request + ); + +VOID +MbbReqMgrReleaseRequestEvent( + __in PMBB_EVENT_ENTRY EventEntry + ); + +NDIS_OID +MbbNdisGetOid( + __in PNDIS_OID_REQUEST OidRequest + ); + +PMBB_REQUEST_CONTEXT +MbbReqMgrGetRequestByKey( + __in PMBB_REQUEST_MANAGER RequestManager, + __in ULONG ValidKeys, + __in_opt ULONG RequestId, + __in_opt ULONG TransactionId, + __in_opt PNDIS_OID_REQUEST OidRequest + ); + +// +// REQUEST FSM +// + +VOID +MbbReqMgrInitializeFsmTransitionTable( ); + +VOID +MbbReqFsmReady( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ); + +VOID +MbbReqFsmDispatching( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ); + +VOID +MbbReqFsmSendPending( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ); + +VOID +MbbReqFsmSendComplete( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ); + +VOID +MbbReqFsmResponseReceived( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ); + +VOID +MbbReqFsmCancelled( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ); + +VOID +MbbReqFsmInvalid( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ); + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// GLOBALS +// +//////////////////////////////////////////////////////////////////////////////// +MBB_REQUEST_STATE MbbReqFsmTransitionTable[MbbRequestStateMaximum][MbbRequestEventMaximum]; + +MBB_REQUEST_STATE_TRANSITION MbbReqFsmStateHandlerTable[MbbRequestStateMaximum] = +{ + MbbReqFsmReady, + MbbReqFsmDispatching, + MbbReqFsmSendPending, + MbbReqFsmSendComplete, + MbbReqFsmResponseReceived, + MbbReqFsmResponseReceived, + MbbReqFsmCancelled, + MbbReqFsmInvalid +}; + +MBB_TIMER_CONTEXT GlobalTimerContexts[MbbTimerTypeMaximum] = +{ + { + MbbTimerTypeRequest, + 0, + NULL, + MBB_REQUEST_TIMEOUT_MS, + 0, + MBB_REQUEST_TIMEOUT_TOLERANCE_MS, + MbbReqMgrTimerRequestTimeoutCallback, + NULL + }, + { + MbbTimerTypeFragment, + 0, + NULL, + MBB_FRAGMENT_TIMEOUT_MS, + 0, + MBB_FRAGMENT_TIMEOUT_TOLERANCE_MS, + MbbReqMgrTimerFragmentTimeoutCallback, + NULL + } +}; + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// ASYNC REQUEST MANAGER +// +//////////////////////////////////////////////////////////////////////////////// +#define KEY_REQUESTID 1 +#define KEY_TRANSACTIONID 2 +#define KEY_OIDID 4 + +PMBB_REQUEST_CONTEXT +MbbReqMgrGetRequestByKey( + __in PMBB_REQUEST_MANAGER RequestManager, + __in ULONG ValidKeys, + __in_opt ULONG RequestId, + __in_opt ULONG TransactionId, + __in_opt PNDIS_OID_REQUEST OidRequest + ) +{ + PLIST_ENTRY ListEntry; + PMBB_REQUEST_CONTEXT Request = NULL; + + MbbReqMgrLockManager( RequestManager ); + for( ListEntry = RequestManager->AllocatedRequestList.Flink; + ListEntry != &RequestManager->AllocatedRequestList; + ListEntry = ListEntry->Flink ) + { + Request = CONTAINING_RECORD( + ListEntry, + MBB_REQUEST_CONTEXT, + ManagerLink + ); + if( ((ValidKeys & KEY_REQUESTID) && (Request->RequestId == RequestId)) || + ((ValidKeys & KEY_OIDID) && (OidRequest != NULL) && (Request->OidContext.OidRequest == OidRequest)) || + ((ValidKeys & KEY_TRANSACTIONID) && (Request->TransactionId == TransactionId)) ) + { + MbbReqMgrRefRequest( Request ); + break; + } + else + { + Request = NULL; + } + } + MbbReqMgrUnlockManager( RequestManager ); + + return Request; +} + +PMBB_REQUEST_CONTEXT +MbbReqMgrGetRequestById( + __in PMBB_REQUEST_MANAGER RequestManager, + __in ULONG RequestId + ) +{ + return MbbReqMgrGetRequestByKey( + RequestManager, + KEY_REQUESTID, + RequestId, + 0, + NULL + ); +} + +PMBB_REQUEST_CONTEXT +MbbReqMgrGetRequestByTransactionId( + __in PMBB_REQUEST_MANAGER RequestManager, + __in ULONG TransactionId + ) +{ + return MbbReqMgrGetRequestByKey( + RequestManager, + KEY_TRANSACTIONID, + 0, + TransactionId, + NULL + ); +} + +PMBB_REQUEST_CONTEXT +MbbReqMgrGetRequestByOidRequestId( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PNDIS_OID_REQUEST OidRequestId + ) +{ + return MbbReqMgrGetRequestByKey( + RequestManager, + KEY_OIDID, + 0, + 0, + OidRequestId + ); +} + +MBB_PROTOCOL_HANDLE +MbbReqMgrGetAdapterHandle( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + return (MBB_PROTOCOL_HANDLE)(Request->RequestManager->AdapterContext); +} + +BOOLEAN +MbbReqMgrIsInternalRequest( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + if( Request->OidContext.OidRequest == NULL && + MbbReqMgrIsUnsolicitedIndication( Request ) == FALSE ) + return TRUE; + else + return FALSE; +} + +VOID +MbbReqMgrSetUnsolicitedIndication( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + Request->HandlerContext.IsIndication = TRUE; +} + +BOOLEAN +MbbReqMgrIsUnsolicitedIndication( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + return Request->HandlerContext.IsIndication; +} + +_Requires_lock_not_held_(&(Request->RequestManager->Spinlock)) +VOID +MbbReqMgrGetState( + __in PMBB_REQUEST_CONTEXT Request, + __inout MBB_REQUEST_STATE *pCurrentState, + __inout MBB_REQUEST_STATE *pLastState + ) +{ + + PMBB_REQUEST_MANAGER RequestManager = NULL; + + RequestManager = Request->RequestManager; + + if(RequestManager) + { + MbbReqMgrLockManager( RequestManager ); + + if(pCurrentState) + { + *pCurrentState = Request->State; + } + + if(pLastState) + { + *pLastState = Request->LastState; + } + + MbbReqMgrUnlockManager( RequestManager ); + } +} + +BOOLEAN +MbbReqMgrIsSetOid( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + BOOLEAN IsOidRequest = ! MbbReqMgrIsInternalRequest( Request ); + + return ( IsOidRequest && Request->OidContext.IsSetOid ); +} + +MBB_NDIS_OID_STATE +MbbReqMgrGetSetOidState( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_NDIS_OID_STATE OidState + ) +/*++ +Description + Sets the new oid state and returns the old state. + Oid state is a enum so a interlocked exchange as a long is fine. + +Return + Old Oid state. +--*/ +{ + LONG Long; + + Long = InterlockedExchange( + (volatile LONG*)(&Request->OidContext.OidState), + OidState + ); + + return (MBB_NDIS_OID_STATE)Long; +} + +_Acquires_lock_( RequestManager->Spinlock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, RequestManager ) +VOID +MbbReqMgrLockManager( + __in PMBB_REQUEST_MANAGER RequestManager + ) +{ + NdisAcquireSpinLock( &RequestManager->Spinlock ); +} + +_Releases_lock_( RequestManager->Spinlock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, RequestManager ) +VOID +MbbReqMgrUnlockManager( + __in PMBB_REQUEST_MANAGER RequestManager + ) +{ + NdisReleaseSpinLock( &RequestManager->Spinlock ); +} + +VOID +MbbReqMgrIntProcessNextRequestWorker( + __in PVOID Context1, + __in PVOID Context2, + __in PVOID Context3, + __in PVOID Context4 + ) +{ + PMBB_REQUEST_CONTEXT NextRequest = NULL; + PMBB_REQUEST_MANAGER RequestManager = (PMBB_REQUEST_MANAGER)Context1; + + MbbReqMgrLockManager( RequestManager ); + if( ! IsListEmpty( &(RequestManager->PendingRequestQueue) ) ) + { + NextRequest = CONTAINING_RECORD( + RemoveHeadList( &(RequestManager->PendingRequestQueue) ), + MBB_REQUEST_CONTEXT, + ReqMgrContext.QueueLink + ); + InitializeListHead( &NextRequest->ReqMgrContext.QueueLink ); + NextRequest->ReqMgrContext.IsQueued = FALSE; + } + RequestManager->CurrentRequest = NextRequest; + MbbReqMgrUnlockManager( RequestManager ); + + if( NextRequest != NULL ) + { + MbbReqMgrQueueEvent( + RequestManager, + NextRequest, + MbbRequestEventStart, + NULL, + 0 + ); + // + // Ref taken when queuing the request in the PendingRequestQueue + // + MbbReqMgrDerefRequest( NextRequest ); + } +} + +VOID +MbbReqMgrIntProcessNextRequest( + __in PMBB_REQUEST_MANAGER RequestManager + ) +/*++ +Description + If a request is pending to be dispatched + this routine will queue a work item to start + the request on another thread. If there are + no more requests it returns enabling the + request manager serializer to process the + next request. +--*/ +{ + NDIS_STATUS NdisStatus; + + MbbReqMgrLockManager( RequestManager ); + if( IsListEmpty( &(RequestManager->PendingRequestQueue) ) ) + { + RequestManager->CurrentRequest = NULL; + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] No more requests, idling queue. QueueStatus[Current=0x%p %s]", + RequestManager->CurrentRequest, + IsListEmpty( &RequestManager->PendingRequestQueue )? "EMPTY": "NON-EMPTY" + ); + } + else + { + if( (NdisStatus = MbbWorkMgrQueueWorkItem( + RequestManager->WorkItemManagerHandle, + RequestManager, + NULL, + NULL, + NULL, + MbbReqMgrIntProcessNextRequestWorker + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to queue work item to process request with status=%!status!. Requests may hang", NdisStatus ); + } + } + MbbReqMgrUnlockManager( RequestManager ); +} + +VOID +MbbReqMgrTransition( + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + PMBB_REQUEST_CONTEXT Request; + PMBB_REQUEST_MANAGER RequestManager; + MBB_REQUEST_STATE OldState = {0}; + MBB_REQUEST_STATE NewState = MbbRequestStateMaximum; + + Request = EventEntry->Request; + RequestManager = Request->RequestManager; + + MbbReqMgrLockManager( RequestManager ); + if( (Request->State < MbbRequestStateMaximum && Request->State >= 0) && + (EventEntry->Event < MbbRequestEventMaximum && EventEntry->Event >= 0) ) + { + NewState = MbbReqFsmTransitionTable[Request->State][EventEntry->Event]; + TraceInfo( WMBCLASS_REQUEST_FSM, "[ReqFsm][ReqId=0x%04x] Transition: %!MbbRequestState! -> %!MbbRequestState! event=%!MbbRequestEvent!", + Request->RequestId, Request->State, NewState, EventEntry->Event + ); + OldState = Request->State; + Request->State = NewState; + Request->LastState = OldState; + Request->LastEvent = EventEntry->Event; + } + MbbReqMgrUnlockManager( RequestManager ); + + if( NewState < MbbRequestStateMaximum ) + { + MbbReqFsmStateHandlerTable[NewState]( + Request, + OldState, + EventEntry + ); + } +} + +FORCEINLINE +BOOLEAN +MbbReqMgrRef( + __in PMBB_REQUEST_MANAGER RequestManager + ) +{ + return DrainAddRef( &RequestManager->DrainObject ); +} + +FORCEINLINE +VOID +MbbReqMgrDeref( + __in PMBB_REQUEST_MANAGER RequestManager + ) +{ + DrainRelease( &RequestManager->DrainObject ); +} + +NDIS_STATUS +MbbReqMgrInitialize( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + ULONG BufferLength; + NTSTATUS NtStatus; + NDIS_STATUS NdisStatus = NDIS_STATUS_RESOURCES; + MBB_ALLOC_FLAGS Flags = { 0 }; + NDIS_TIMER_CHARACTERISTICS TimerCharacteristics; + + do + { + InitializeListHead( &(RequestManager->AllocatedRequestList) ); + + InitializeListHead( &(RequestManager->PendingRequestQueue) ); + + NdisAllocateSpinLock( &(RequestManager->Spinlock) ); + + KeInitializeEvent( + &RequestManager->DrainCompleteEvent, + NotificationEvent, + FALSE + ); + + InitDrainObject( + &RequestManager->DrainObject, + MbbReqMgrDrainCompleteCallback, + &RequestManager->DrainCompleteEvent + ); + + DrainComplete( &RequestManager->DrainObject ); + + MbbReqMgrInitializeFsmTransitionTable( ); + + KeInitializeEvent( + &(RequestManager->NoAllocatedRequestEvent), + NotificationEvent, + TRUE + ); + RequestManager->AdapterContext = Adapter; + // + // Work item manager + // + if( (RequestManager->WorkItemManagerHandle = MbbWorkMgrInitialize( MBB_PREALLOC_WORKITEM_COUNT )) == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to initialize work item manager" ); + break; + } + // + // Allocation manager for requests. + // + if( (RequestManager->RequestAllocatorHandle = MbbAllocMgrInitialize( + sizeof(MBB_REQUEST_CONTEXT), + MBB_PREALLOC_REQUEST_COUNT, + MbbPoolTagRequest, + Flags + )) == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to initialize request allocator" ); + break; + } + // + // Allocate fragment buffers + // + RequestManager->Fragmentation.ControlFragmentLength = Adapter->BusParams.FragmentSize; + RequestManager->Fragmentation.BulkFragmentLength = MBB_FRAGMENATION_BULK_BUFFER_LENGTH; + + BufferLength = MAX( + RequestManager->Fragmentation.ControlFragmentLength, + RequestManager->Fragmentation.BulkFragmentLength + ); + if( (RequestManager->Fragmentation.BufferManager = MbbBufMgrInitialize( + MBB_PREALLOC_FRAGMENATION_BUFFER_COUNT, + BufferLength + )) == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate %d fragment buffers of size=%dBytes", + MBB_PREALLOC_FRAGMENATION_BUFFER_COUNT, + BufferLength + ); + break; + } + // + // Allocate default response buffer. + // + RequestManager->Fragmentation.Reassemble.FragmentBufferLength = Adapter->BusParams.FragmentSize; + if( (RequestManager->Fragmentation.Reassemble.FragmentBuffer = ALLOCATE_NONPAGED_POOL( RequestManager->Fragmentation.Reassemble.FragmentBufferLength )) == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate default fragment buffer of size=%dBytes", RequestManager->Fragmentation.Reassemble.FragmentBufferLength ); + break; + } + // + // Allocate default reassemble buffer. + // + RequestManager->Fragmentation.Reassemble.BufferLength = MBB_REASSEMBLE_BUFFER_LENGTH; + if( (RequestManager->Fragmentation.Reassemble.Buffer = ALLOCATE_NONPAGED_POOL( RequestManager->Fragmentation.Reassemble.BufferLength )) == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate default fragment buffer of size=%dBytes", RequestManager->Fragmentation.Reassemble.BufferLength ); + break; + } + // + // Allocate default timer. + // + if( (NdisStatus = MbbReqMgrTimerInitialize( + RequestManager, + MbbTimerTypeRequest + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate %!MbbTimer! with status=%!status!", MbbTimerTypeRequest, NdisStatus ); + break; + } + + if( (NdisStatus = MbbReqMgrTimerInitialize( + RequestManager, + MbbTimerTypeFragment + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate %!MbbTimer! with status=%!status!", MbbTimerTypeFragment, NdisStatus ); + break; + } + + RequestManager->IsClosed = FALSE; + + NdisStatus = NDIS_STATUS_SUCCESS; + + } while( FALSE ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + MbbReqMgrTimerCleanup( RequestManager, MbbTimerTypeFragment ); + MbbReqMgrTimerCleanup( RequestManager, MbbTimerTypeRequest ); + + if( RequestManager->Fragmentation.Reassemble.Buffer != NULL ) + { + FREE_POOL( RequestManager->Fragmentation.Reassemble.Buffer ); + } + if( RequestManager->Fragmentation.Reassemble.FragmentBuffer != NULL ) + { + FREE_POOL( RequestManager->Fragmentation.Reassemble.FragmentBuffer ); + } + if( RequestManager->Fragmentation.BufferManager != NULL ) + { + MbbBufMgrCleanup( RequestManager->Fragmentation.BufferManager ); + RequestManager->Fragmentation.BufferManager = NULL; + } + if( RequestManager->RequestAllocatorHandle != NULL ) + { + MbbAllocMgrCleanup( RequestManager->RequestAllocatorHandle ); + RequestManager->RequestAllocatorHandle = NULL; + } + if( RequestManager->WorkItemManagerHandle != NULL ) + { + MbbWorkMgrCleanup( RequestManager->WorkItemManagerHandle ); + RequestManager->WorkItemManagerHandle = NULL; + } + } + else + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] Initialization complete" ); + } + return NdisStatus; +} + +__callback +VOID +MbbReqMgrDrainCompleteCallback( + __in PVOID Context + ) +{ + PKEVENT DrainCompleteEvent = (PKEVENT)Context; + + KeSetEvent( DrainCompleteEvent, IO_NO_INCREMENT, FALSE ); +} + +VOID +MbbReqMgrCleanup( + __in PMBB_REQUEST_MANAGER RequestManager + ) +{ + NTSTATUS NtStatus; + BOOLEAN SignalThread = FALSE; + BOOLEAN WaitForTimers = FALSE; + PVOID EventThreadObject; + + // + // Synchronize draining with new request creation. + // Once draining is started inside the lock + // it is guaranteed that no more requests would be created. + // + MbbReqMgrLockManager( RequestManager ); + KeResetEvent( &RequestManager->DrainCompleteEvent ); + StartDrain( &RequestManager->DrainObject ); + MbbReqMgrUnlockManager( RequestManager ); + // + // Cancel all pending requests by queuing cancel event. + // + MbbReqMgrCancelRequests( RequestManager, FALSE); + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Cleanup] Waiting for pending requests to complete" ); + // + // Wait for pending operations to complete. + // + KeWaitForSingleObject( + &(RequestManager->NoAllocatedRequestEvent), + Executive, + KernelMode, + FALSE, + NULL + ); + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Cleanup] Waiting for references to go down" ); + // + // Drop the reference that was taken to pass in the request manager. + // + MbbReqMgrDeref( RequestManager ); + // + // Wait for all references on request manager to go down. + // This guarantees that no thread is accessign the request + // manager while its wiped out here. + // + KeWaitForSingleObject( + &(RequestManager->DrainCompleteEvent), + Executive, + KernelMode, + FALSE, + NULL + ); + // + // Wait for the lock before cleaning up so that the + // thread that set the event has a change to release the lock. + // + MbbReqMgrLockManager( RequestManager ); + // + // Ensure all lists are empty + // + ASSERT( IsListEmpty( &(RequestManager->AllocatedRequestList) ) ); + ASSERT( IsListEmpty( &(RequestManager->PendingRequestQueue) ) ); + + MbbReqMgrUnlockManager( RequestManager ); + // + // Cancel timers + // + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Cleanup] Cancelling timers" ); + MbbReqMgrTimerCleanup( RequestManager, MbbTimerTypeFragment ); + MbbReqMgrTimerCleanup( RequestManager, MbbTimerTypeRequest ); + // + // Free resources, if allocated. + // + if( RequestManager->Fragmentation.Reassemble.Buffer != NULL ) + { + FREE_POOL( RequestManager->Fragmentation.Reassemble.Buffer ); + } + if( RequestManager->Fragmentation.Reassemble.FragmentBuffer != NULL ) + { + FREE_POOL( RequestManager->Fragmentation.Reassemble.FragmentBuffer ); + } + if( RequestManager->Fragmentation.BufferManager != NULL ) + { + MbbBufMgrCleanup( RequestManager->Fragmentation.BufferManager ); + RequestManager->Fragmentation.BufferManager = NULL; + } + if( RequestManager->RequestAllocatorHandle != NULL ) + { + MbbAllocMgrCleanup( RequestManager->RequestAllocatorHandle ); + RequestManager->RequestAllocatorHandle = NULL; + } + if( RequestManager->WorkItemManagerHandle != NULL ) + { + MbbWorkMgrCleanup( RequestManager->WorkItemManagerHandle ); + RequestManager->WorkItemManagerHandle = NULL; + } + // + // Always allocated + // + NdisFreeSpinLock( &(RequestManager->Spinlock) ); + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Cleanup] Cleanup complete" ); +} + +/// +/// Function to Cancel all the Requests in the Request Manager +/// +/// Pointer to the Request Manager +/// Flag to indicate that the Request Manager is Closed. Set only in the Surprise Removal Path +VOID +MbbReqMgrCancelRequests( + __in PMBB_REQUEST_MANAGER RequestManager, + __in BOOLEAN IsClosed + ) +{ + LIST_ENTRY TempList; + PLIST_ENTRY ListEntry; + PMBB_REQUEST_CONTEXT Request; + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] Cancelling pending requests" ); + + InitializeListHead( &TempList ); + + MbbReqMgrLockManager( RequestManager ); + RequestManager->IsClosed = IsClosed; + for( ListEntry = RequestManager->AllocatedRequestList.Flink; + ListEntry != &RequestManager->AllocatedRequestList; + ListEntry = ListEntry->Flink ) + { + Request = CONTAINING_RECORD( ListEntry, MBB_REQUEST_CONTEXT, ManagerLink ); + MbbReqMgrRefRequest( Request ); + InsertTailList( &TempList, &Request->ReqMgrContext.CancelLink ); + } + MbbReqMgrUnlockManager( RequestManager ); + + while (!IsListEmpty(&TempList)) + { + // Get the Entry of the list + ListEntry = RemoveHeadList(&TempList); + Request = CONTAINING_RECORD(ListEntry, MBB_REQUEST_CONTEXT, ReqMgrContext.CancelLink); + + MbbReqMgrQueueEvent( + RequestManager, + Request, + MbbRequestEventCancel, + (PVOID)(NDIS_STATUS_REQUEST_ABORTED), + 0 + ); + MbbReqMgrDerefRequest(Request); + } +} + +/// +/// Function to Create the Request for the Request Manager off the OID Request that came through +/// +/// Request Manager +/// The oid request. +/// Length of the response buffer. +/// out parameter that has the NDIS status filled in +/// newly created request otherwise null +__checkReturn +__drv_aliasesMem +__drv_allocatesMem(Mem) +PMBB_REQUEST_CONTEXT +MbbReqMgrCreateRequest( + __in PMBB_REQUEST_MANAGER RequestManager, + __in_opt PNDIS_OID_REQUEST OidRequest, + __in ULONG ResponseBufferLength, + __out PNDIS_STATUS NdisStatus + ) +{ + PMBB_REQUEST_CONTEXT Request = NULL; + NDIS_TIMER_CHARACTERISTICS TimerCharacteristics; + + do + { + *NdisStatus = NDIS_STATUS_RESOURCES; + + if( (Request = (PMBB_REQUEST_CONTEXT) MbbAllocMgrAllocate( RequestManager->RequestAllocatorHandle )) == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate request context" ); + break; + } + RtlZeroMemory( Request, sizeof(MBB_REQUEST_CONTEXT) ); + Request->OidContext.OidRequest = OidRequest; + if (OidRequest != NULL) + { + Request->OidContext.OidRequestId = OidRequest->RequestId; + Request->OidContext.OidRequestHandle = OidRequest->RequestHandle; + } + InitializeListHead( &(Request->ManagerLink) ); + InitializeListHead( &(Request->ReqMgrContext.QueueLink) ); + InitializeListHead( &(Request->ReqMgrContext.CancelLink) ); + InitializeListHead( &(Request->ReqMgrContext.TimeoutLink) ); + // + // Insert the request in allocated list for tracking. + // Take the reference on the request manager since a pointer + // is stored in the request. A successful reference also + // guarantees that the request manager is not draining. + // + MbbReqMgrLockManager( RequestManager ); + + // If the Request Manager is Closed, then no point in inserting the requests in to the Queue + // Currently this code path will get hit for Surprise Removal + if (RequestManager->IsClosed) + { + TraceError(WMBCLASS_REQUEST_MANAGER, "[ReqMgr] Not Queuing up the Requests as the Request Manager is Closed"); + *NdisStatus = NDIS_STATUS_NOT_ACCEPTED; + MbbReqMgrUnlockManager(RequestManager); + break; + } + + if( MbbReqMgrRef( RequestManager ) ) + { + Request->RequestId = (RequestManager->RequestIdCounter)++; + Request->RequestManager = RequestManager; + KeResetEvent( &(RequestManager->NoAllocatedRequestEvent) ); + InsertTailList( + &RequestManager->AllocatedRequestList, + &Request->ManagerLink + ); + } + + else + { + TraceError(WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to reference the RequestManager for creating a RequestContext"); + *NdisStatus = NDIS_STATUS_RESOURCES; + MbbReqMgrUnlockManager(RequestManager); + break; + } + + KeInitializeEvent( + &Request->WaitEvent, + NotificationEvent, + FALSE + ); + + if (OidRequest != NULL) + { + if (OidRequest->RequestType == NdisRequestSetInformation) + { + Request->OidContext.IsSetOid = TRUE; + } + TraceInfo(WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Request created for %s [RequestContext=0x%p OidRequest=0x%p] SET=%!BOOLEAN!", + Request->RequestId, GetOidName(MbbNdisGetOid(OidRequest)), Request, OidRequest, MbbReqMgrIsSetOid(Request) + ); + } + else + { + TraceInfo(WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Internal Request created [RequestContext=0x%p]", + Request->RequestId, Request + ); + } + Request->ReferenceCount = 1; + + MbbReqMgrUnlockManager( RequestManager ); + + *NdisStatus = NDIS_STATUS_SUCCESS; + + } while( FALSE ); + + if( Request != NULL ) + { + if( *NdisStatus != NDIS_STATUS_SUCCESS) + { + if(Request->RequestManager) + { + MbbReqMgrDeref(Request->RequestManager); + } + MbbAllocMgrFree( Request ); + + Request = NULL; + } + } + + return Request; +} + +#pragma warning(push) +#pragma warning(disable:__WARNING_MEMORY_LEAK) +VOID +MbbReqMgrCleanupRequest( + __in __drv_freesMem(Mem) PMBB_REQUEST_CONTEXT Request + ) +{ + PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; + + if(!RequestManager) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] MbbReqMgrCleanupRequest: RequestManager is NULL.", Request->RequestId ); + ASSERT(FALSE); + return; + } + + ASSERT( Request->ReferenceCount == 0 ); + + // + // If the request allocation failed directly free the request memory. + // + + MbbReqMgrLockManager( RequestManager ); + + if( IsListEmpty( &(Request->ManagerLink) ) ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Request double free attempt.", Request->RequestId ); + ASSERT(FALSE); + MbbReqMgrUnlockManager( RequestManager ); + return; + } + else + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Destroying request.", Request->RequestId ); + + RemoveEntryList( &(Request->ManagerLink) ); + + // Clear the manager link flink and blink so that if IsListEmpty + // check is called again on the same link, it returns empty. + InitializeListHead( &(Request->ManagerLink) ); + + if( IsListEmpty( &(RequestManager->AllocatedRequestList) ) ) + { + // + // The event can trigger the cleanup code which + // could cleanup the lock making it invalid. But + // the cleanup code waits for the lock before cleaning + // the request manager. So the lock is guaranteed to + // be valid until we release it. + // + KeSetEvent( + &(RequestManager->NoAllocatedRequestEvent), + IO_NO_INCREMENT, + FALSE + ); + // + // Disarm the request timeout timer if its still active. + // + MbbReqMgrTimerDisarm( + RequestManager, + MbbTimerTypeRequest, + MBB_LOCK_TAKEN + ); + } + + MbbReqMgrUnlockManager( RequestManager ); + MbbAllocMgrFree( Request ); + + // + // Do not touch the request manager beyond this point. + // + + if( RequestManager ) + MbbReqMgrDeref( RequestManager ); + } +} +#pragma warning(pop) + +VOID +MbbNdisIndicateStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +VOID +MbbReqMgrDestroyRequest( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + // + // Drop the initial reference taken during initialization. + // + MbbReqMgrDerefRequest( Request ); +} + +VOID +MbbReqMgrRefRequest( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + LONG ref = InterlockedIncrement( &Request->ReferenceCount ); + + // When the request is created its initial ref count is 1. Hence whenever + // the request is going to be ref'd the ref count should be > 1. + // This assert will catch the ref count to be going from 0 to 1, meaning + // that some thread is trying to use a freed request. + + ASSERT(ref > 1); +} + +VOID +MbbReqMgrDerefRequest( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + LONG ref = InterlockedDecrement( &Request->ReferenceCount ); + + // Catches negative dereferences + ASSERT(ref >= 0); + + if( ref == 0 ) + { + MbbReqMgrCleanupRequest( Request ); + } +} + +NDIS_STATUS +MbbReqMgrDispatchRequest( + __in PMBB_REQUEST_CONTEXT Request, + __in BOOLEAN IsSerialized, + __in MBB_REQUEST_DISPATCH_ROUTINE DispatchRoutine, + __in MBB_REQUEST_COMPLETION_CALLBACK CompletionCallback, + __in_opt MBB_REQUEST_RESPONSE_HANDLER ResponseHandler + ) +/*++ + Return Value + NDIS_STATUS_PENDING + Request was queued for later dispatch. + NDIS_STATUS_SUCCESS + Request was dispatched synchronously and successfully complete. + Ndis failure codes + Request was either not dispatched or completed with failure. +--*/ +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + LARGE_INTEGER DueTime; + + do + { + if( Request == NULL || DispatchRoutine == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] Invalid parameters, Request=0x%p DispatchRoutine=0x%p", Request, DispatchRoutine ); + NdisStatus = NDIS_STATUS_INVALID_PARAMETER; + break; + } + + Request->ReqMgrContext.IsSerialized = IsSerialized; + Request->ReqMgrContext.DispatchRoutine = DispatchRoutine; + Request->ReqMgrContext.CompletionCallback = CompletionCallback; + Request->ReqMgrContext.ResponseHandler = ResponseHandler; + Request->ReqMgrContext.IsQueued = FALSE; + + NdisGetSystemUpTimeEx( (PLARGE_INTEGER)(&Request->DispatchTime) ); + + MbbReqMgrQueueEvent( + Request->RequestManager, + Request, + MbbRequestEventDispatch, + NULL, + 0 + ); + NdisStatus = NDIS_STATUS_PENDING; + + } while( FALSE ); + + return NdisStatus; +} + +VOID +MbbReqMgrInitializeFsmTransitionTable( ) +{ + ULONG StateIndex; + ULONG EventIndex; + + for( StateIndex = 0; StateIndex < MbbRequestStateMaximum; StateIndex++ ) + { + for( EventIndex = 0; EventIndex < MbbRequestEventMaximum; EventIndex++ ) + { + MbbReqFsmTransitionTable[StateIndex][EventIndex] = MbbRequestStateInvalid; + } + } + // + // Valid State transitions. + // + MbbReqFsmTransitionTable[MbbRequestStateReady][MbbRequestEventDispatch] = MbbRequestStateDispatching; + MbbReqFsmTransitionTable[MbbRequestStateReady][MbbRequestEventCancel] = MbbRequestStateCancelled; + + MbbReqFsmTransitionTable[MbbRequestStateDispatching][MbbRequestEventStart] = MbbRequestStateSendPending; + MbbReqFsmTransitionTable[MbbRequestStateDispatching][MbbRequestEventCancel] = MbbRequestStateCancelled; + + MbbReqFsmTransitionTable[MbbRequestStateSendPending][MbbRequestEventCancel] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateSendPending][MbbRequestEventSendComplete] = MbbRequestStateSendComplete; + MbbReqFsmTransitionTable[MbbRequestStateSendPending][MbbRequestEventResponseReceived] = MbbRequestStateResponseReceived; + MbbReqFsmTransitionTable[MbbRequestStateSendPending][MbbRequestEventResponseReceivedMoreData] = MbbRequestStateResponseReceivedMoreData; + + MbbReqFsmTransitionTable[MbbRequestStateSendComplete][MbbRequestEventCancel] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateSendComplete][MbbRequestEventResponseReceived] = MbbRequestStateResponseReceived; + MbbReqFsmTransitionTable[MbbRequestStateSendComplete][MbbRequestEventResponseReceivedMoreData] = MbbRequestStateResponseReceivedMoreData; + + MbbReqFsmTransitionTable[MbbRequestStateResponseReceived][MbbRequestEventCancel] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateResponseReceived][MbbRequestEventSendComplete] = MbbRequestStateResponseReceived; + + MbbReqFsmTransitionTable[MbbRequestStateResponseReceivedMoreData][MbbRequestEventCancel] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateResponseReceivedMoreData][MbbRequestEventSendComplete] = MbbRequestStateResponseReceivedMoreData; + MbbReqFsmTransitionTable[MbbRequestStateResponseReceivedMoreData][MbbRequestEventResponseReceived] = MbbRequestStateResponseReceived; + MbbReqFsmTransitionTable[MbbRequestStateResponseReceivedMoreData][MbbRequestEventResponseReceivedMoreData] = MbbRequestStateResponseReceivedMoreData; + + MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventDispatch] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventStart] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventCancel] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventSendComplete] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventResponseReceived] = MbbRequestStateCancelled; + MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventResponseReceivedMoreData] = MbbRequestStateCancelled; +} + +VOID +MbbReqMgrReleaseRequestEvent( + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + PMBB_REQUEST_CONTEXT Request = EventEntry->Request; + PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; + + // + // If this is a pre-allocated event hold the manager + // lock to synchronize access. If allocated from pool + // no one else can access it. + // + if( EventEntry->EventFlags.Allocated == TRUE ) + { + FREE_POOL( EventEntry ); + } + else + { + MbbReqMgrLockManager( RequestManager ); + EventEntry->EventFlags.InUse = FALSE; + MbbReqMgrUnlockManager( RequestManager ); + } + MbbReqMgrDerefRequest( Request ); +} + +_Requires_lock_not_held_( RequestManager->Spinlock ) +VOID +MbbReqMgrQueueEvent( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_EVENT Event, + __in_opt PVOID EventData, + __in ULONG EventDataLength + ) +{ + BOOLEAN AllocateEvent = FALSE; + PMBB_EVENT_ENTRY EventEntry; + + // + // Try to use the pre-allocated events for forward progress. + // Some events can occur multiple times at the same instance like ResponseReceived. + // For these events try to allocate a new entry. + // + MbbReqMgrLockManager( RequestManager ); + EventEntry = &(Request->EventEntries[Event]); + if( EventEntry->EventFlags.InUse == TRUE ) + AllocateEvent = TRUE; + else + EventEntry->EventFlags.InUse = TRUE; + MbbReqMgrUnlockManager( RequestManager ); + + if( AllocateEvent ) + { +#pragma prefast(suppress: __WARNING_MEMORY_LEAK, "Released by MbbReqMgrReleaseRequestEvent") + if( (EventEntry = ALLOCATE_NONPAGED_POOL( sizeof(MBB_EVENT_ENTRY) )) == NULL ) + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqID=0x%04x] FAILED to queue event=%!MbbRequestEvent!, unable to allocate entry", Request->RequestId, Event ); + else + EventEntry->EventFlags.Allocated = TRUE; + } + + if( EventEntry != NULL ) + { + EventEntry->Event = Event; + EventEntry->EventData = EventData; + EventEntry->EventDataLength = EventDataLength; + EventEntry->Request = Request; + // + // Reference the request since the event stores a pointer to it. + // + MbbReqMgrRefRequest( Request ); + } + + MbbReqMgrTransition( EventEntry ); + + MbbReqMgrReleaseRequestEvent( EventEntry ); +} + +// Reassemble context + +_Requires_lock_not_held_( RequestManager->Spinlock ) +PMBB_REASSEMBLE_CONTEXT +MbbReqMgrAcquireSharedReassembleContext( + __in PMBB_REQUEST_MANAGER RequestManager, + __in_bcount(MessageLength) PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader, + __in ULONG MessageLength, + __in GUID ActivityId + ) +{ + MBB_COMMAND Command = { 0 }; + PMBB_COMMAND_DONE_HEADER CommandDone; + PMBB_INDICATE_STATUS_HEADER IndicationStatus; + PMBB_REASSEMBLE_CONTEXT ReassembleContext = &RequestManager->Fragmentation.Reassemble; + + // + // Get the command for debugging purposes + // + if( MessageFragmentHeader->FragmentHeader.CurrentFragment == 0 ) + { + if( MessageFragmentHeader->MessageHeader.MessageType == MBB_MESSAGE_TYPE_COMMAND_DONE && + MessageFragmentHeader->MessageHeader.MessageLength >= sizeof(MBB_COMMAND_DONE_HEADER) && + MessageLength >= sizeof(MBB_COMMAND_DONE_HEADER) ) + { + CommandDone = (PMBB_COMMAND_DONE_HEADER)MessageFragmentHeader; + Command.CommandId = CommandDone->Command.CommandId; + MBB_UUID_TO_HOST( + &Command.ServiceId, + &CommandDone->Command.ServiceId + ); + } + else + if( MessageFragmentHeader->MessageHeader.MessageType == MBB_MESSAGE_TYPE_INDICATE_STATUS && + MessageFragmentHeader->MessageHeader.MessageLength >= sizeof(MBB_INDICATE_STATUS_HEADER) && + MessageLength >= sizeof(MBB_INDICATE_STATUS_HEADER) ) + { + IndicationStatus = (PMBB_INDICATE_STATUS_HEADER)MessageFragmentHeader; + Command.CommandId = IndicationStatus->Command.CommandId; + MBB_UUID_TO_HOST( + &Command.ServiceId, + &IndicationStatus->Command.ServiceId + ); + } + } + + MbbReqMgrLockManager( RequestManager ); + + if( RequestManager->Fragmentation.ReassembleInUse == TRUE ) + { + if( ReassembleContext->TransactionId == MessageFragmentHeader->MessageHeader.MessageTransactionId && + ReassembleContext->FragmentCount == MessageFragmentHeader->FragmentHeader.TotalFragments && + ReassembleContext->NextFragment == MessageFragmentHeader->FragmentHeader.CurrentFragment ) + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] Using owned reassemble context", MessageFragmentHeader->MessageHeader.MessageTransactionId ); + } + else + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] FAILED to acquire reassemble context, owned by TID=0x%08x, Command=%s", + MessageFragmentHeader->MessageHeader.MessageTransactionId, + ReassembleContext->TransactionId, + MbbUtilGetCommandString( &Command ) + ); + ReassembleContext = NULL; + } + } + else + { + if( MessageFragmentHeader->FragmentHeader.CurrentFragment == 0 ) + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] Acquired reassemble context", MessageFragmentHeader->MessageHeader.MessageTransactionId ); + + ReassembleContext->Command = Command; + ReassembleContext->TransactionId = MessageFragmentHeader->MessageHeader.MessageTransactionId; + ReassembleContext->FragmentCount = MessageFragmentHeader->FragmentHeader.TotalFragments; + + RequestManager->Fragmentation.ReassembleInUse = TRUE; + } + else + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] FAILED to acquire reassemble context for out of order fragment, Fragement=%d/%d", + MessageFragmentHeader->MessageHeader.MessageTransactionId, + MessageFragmentHeader->FragmentHeader.CurrentFragment, + MessageFragmentHeader->FragmentHeader.TotalFragments + ); + ReassembleContext = NULL; + } + } + // + // If the context was acquired disable the fragment timer. + // If the timer cannot be disabled then do not proceed. + // + // Else send an error message to the device. + // + if( ReassembleContext != NULL ) + { + ReassembleContext->NextFragment = MessageFragmentHeader->FragmentHeader.CurrentFragment + 1; + + if( MessageFragmentHeader->FragmentHeader.CurrentFragment != 0 ) + { + if( MbbReqMgrTimerDisarm( + RequestManager, + MbbTimerTypeFragment, + MBB_LOCK_TAKEN + ) == FALSE ) + { + ReassembleContext = NULL; + } + } + } + else + { + MbbUtilSendMbimError( + MessageFragmentHeader->MessageHeader.MessageTransactionId, + MBB_ERROR_FRAGMENT_OUT_OF_SEQUENCE, + RequestManager->AdapterContext, + ActivityId, + &Command + ); + } + + MbbReqMgrUnlockManager( RequestManager ); + + return ReassembleContext; +} + +_Requires_lock_not_held_( RequestManager->Spinlock ) +VOID +MbbReqMgrReleaseSharedReassembleContext( + __in PMBB_REQUEST_MANAGER RequestManager + ) +{ + PMBB_REASSEMBLE_CONTEXT ReassembleContext = &RequestManager->Fragmentation.Reassemble; + + MbbReqMgrLockManager( RequestManager ); + + if( RequestManager->Fragmentation.ReassembleInUse == TRUE ) + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] Released reassemble context. Command=%s", + ReassembleContext->TransactionId, + MbbUtilGetCommandString( &ReassembleContext->Command ) + ); + + ReassembleContext->FragmentLength = 0; + ReassembleContext->BufferOffset = 0; + ReassembleContext->DataLength = 0; + ReassembleContext->TransactionId = 0; + ReassembleContext->FragmentCount = 0; + ReassembleContext->NextFragment = 0; + ReassembleContext->NdisStatus = 0; + ReassembleContext->MbbStatus = 0; + + RtlZeroMemory( &ReassembleContext->Command, sizeof(MBB_COMMAND) ); + + RequestManager->Fragmentation.ReassembleInUse = FALSE; + } + else + { + ReassembleContext = NULL; + } + + MbbReqMgrUnlockManager( RequestManager ); + + if( ReassembleContext == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] INVALID release of reassemble context." ); + ASSERT( FALSE ); + } +} + +// Timer + +NDIS_STATUS +MbbReqMgrTimerInitialize( + __in PMBB_REQUEST_MANAGER RequestManager, + __in MBB_TIMER_TYPE TimerType + ) +{ + NDIS_STATUS NdisStatus; + NDIS_TIMER_CHARACTERISTICS TimerCharacteristics; + + RtlCopyMemory( + &RequestManager->TimerContexts[TimerType], + &GlobalTimerContexts[TimerType], + sizeof(MBB_TIMER_CONTEXT) + ); + RequestManager->TimerContexts[TimerType].RequestManager = RequestManager; + + TimerCharacteristics.Header.Type = NDIS_OBJECT_TYPE_TIMER_CHARACTERISTICS; + TimerCharacteristics.Header.Revision = NDIS_TIMER_CHARACTERISTICS_REVISION_1; + TimerCharacteristics.Header.Size = NDIS_SIZEOF_TIMER_CHARACTERISTICS_REVISION_1; + TimerCharacteristics.AllocationTag = MbbPoolTagTimer; + TimerCharacteristics.TimerFunction = MbbReqMgrTimerCallback; + TimerCharacteristics.FunctionContext = &RequestManager->TimerContexts[TimerType]; + + NdisStatus = NdisAllocateTimerObject( + RequestManager->AdapterContext->MiniportAdapterHandle, + &TimerCharacteristics, + &RequestManager->TimerContexts[TimerType].TimerHandle + ); + return NdisStatus; +} + +BOOLEAN +MbbReqMgrTimerCleanup( + __in PMBB_REQUEST_MANAGER RequestManager, + __in MBB_TIMER_TYPE TimerType + ) +/*++ + Return Value + TRUE + Timer is successfully cancelled. + FALSE + Timer is running, caller needs to wait. +--*/ +{ + BOOLEAN WaitForTimer = FALSE; + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] Cleaning %!MbbTimer!", TimerType ); + + if( RequestManager->TimerContexts[TimerType].TimerHandle != NULL ) + { + MbbReqMgrLockManager( RequestManager ); + if( RequestManager->TimerContexts[TimerType].TimerArmTime != 0 ) + { + if( NdisCancelTimerObject( RequestManager->TimerContexts[TimerType].TimerHandle ) == FALSE ) + { + WaitForTimer = TRUE; + } + RequestManager->TimerContexts[TimerType].TimerArmTime = 0; + } + MbbReqMgrUnlockManager( RequestManager ); + + if( WaitForTimer ) + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] Waiting for %!MbbTimer! thread to exit", TimerType ); + KeFlushQueuedDpcs( ); + } + NdisFreeTimerObject( RequestManager->TimerContexts[TimerType].TimerHandle ); + RequestManager->TimerContexts[TimerType].TimerHandle = NULL; + } + + return (!WaitForTimer); +} + +_When_( Locked==FALSE, _Requires_lock_not_held_( RequestManager->Spinlock ) ) +VOID +MbbReqMgrTimerArm( + __in PMBB_REQUEST_MANAGER RequestManager, + __in MBB_TIMER_TYPE TimerType, + __in_opt ULONG DelayInMS, + __in_opt ULONG PeriodInMS, + __in_opt ULONG ToleranceInMS, + __in BOOLEAN Locked + ) +{ + LARGE_INTEGER DueTime; + + if( ! Locked ) + MbbReqMgrLockManager( RequestManager ); + + if( RequestManager->TimerContexts[TimerType].TimerArmTime == 0 ) + { + NdisGetSystemUpTimeEx( (PLARGE_INTEGER)(&RequestManager->TimerContexts[TimerType].TimerArmTime) ); + + if( DelayInMS == 0 ) + DelayInMS = RequestManager->TimerContexts[TimerType].TimerDelayInMS; + + if( PeriodInMS == 0 ) + PeriodInMS = RequestManager->TimerContexts[TimerType].TimerPeriodInMS; + + if( ToleranceInMS == 0 ) + ToleranceInMS = RequestManager->TimerContexts[TimerType].TimerToleranceInMS; + + DueTime.QuadPart = DelayInMS; + DueTime.QuadPart *= 10000 * -1; + + NdisSetCoalescableTimerObject( + RequestManager->TimerContexts[TimerType].TimerHandle, + DueTime, + PeriodInMS, + NULL, + ToleranceInMS + ); + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! armed at %I64x for %I64x ms", + TimerType, + RequestManager->TimerContexts[TimerType].TimerArmTime, + DelayInMS + ); + } + else + { + TraceWarn( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! already armed at %I64x, not re-arming", + TimerType, + RequestManager->TimerContexts[TimerType].TimerArmTime + ); + } + + if( ! Locked ) + MbbReqMgrUnlockManager( RequestManager ); +} + +_When_( Locked==FALSE, _Requires_lock_not_held_( RequestManager->Spinlock ) ) +BOOLEAN +MbbReqMgrTimerDisarm( + __in PMBB_REQUEST_MANAGER RequestManager, + __in MBB_TIMER_TYPE TimerType, + __in BOOLEAN Locked + ) +/*++ + Return Value + TRUE + Timer is successfully cancelled. + FALSE + Timer could not be cancelled. +--*/ +{ + BOOLEAN IsTimerCancelled = TRUE; + + if( ! Locked ) + MbbReqMgrLockManager( RequestManager ); + + if( RequestManager->TimerContexts[TimerType].TimerArmTime != 0 ) + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! disarmed", TimerType ); + IsTimerCancelled = NdisCancelTimerObject( RequestManager->TimerContexts[TimerType].TimerHandle ); + RequestManager->TimerContexts[TimerType].TimerArmTime = 0; + } + else + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! not armed, cant disarmed", TimerType ); + } + + if( ! Locked ) + MbbReqMgrUnlockManager( RequestManager ); + + return IsTimerCancelled; +} + +VOID +MbbReqMgrTimerCallback( + __in PVOID SystemSpecific1, + __in PVOID FunctionContext, + __in PVOID SystemSpecific2, + __in PVOID SystemSpecific3 + ) +{ + PMBB_TIMER_CONTEXT TimerContext = (PMBB_TIMER_CONTEXT)FunctionContext; + PMBB_REQUEST_MANAGER RequestManager = TimerContext->RequestManager; + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! fired", TimerContext->TimerType ); + + MbbReqMgrLockManager( RequestManager ); + TimerContext->TimerArmTime = 0; + MbbReqMgrUnlockManager( RequestManager ); + + TimerContext->TimerFunction( + SystemSpecific1, + RequestManager, + SystemSpecific2, + SystemSpecific3 + ); +} + +// Inter-Fragment timer + +VOID +MbbReqMgrTimerFragmentTimeoutCallback( + __in PVOID SystemSpecific1, + __in PVOID FunctionContext, + __in PVOID SystemSpecific2, + __in PVOID SystemSpecific3 + ) +{ + PMBB_REQUEST_MANAGER RequestManager = (PMBB_REQUEST_MANAGER)FunctionContext; + PMBB_REASSEMBLE_CONTEXT ReassembleContext = &RequestManager->Fragmentation.Reassemble; + PMBB_REQUEST_CONTEXT Request; + GUID ActivityId = {0}; + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer][TID=0x%08x] Fragment timeout", ReassembleContext->TransactionId ); + + Request = MbbReqMgrGetRequestByTransactionId( RequestManager, ReassembleContext->TransactionId ); + + if(Request) + { + ActivityId = Request->ActivityId; + } + + MbbUtilSendMbimError( + ReassembleContext->TransactionId, + MBB_ERROR_TIMEOUT_FRAGMENT, + RequestManager->AdapterContext, + ActivityId, + &ReassembleContext->Command + ); + + MbbReqMgrReleaseSharedReassembleContext( RequestManager ); + + if( Request ) + { + MbbReqMgrQueueEvent( + RequestManager, + Request, + MbbRequestEventCancel, + (PVOID)(STATUS_TIMEOUT), + 0 + ); + MbbReqMgrDerefRequest( Request ); + } +} + +// Request timeout timer + +VOID +MbbReqMgrTimerRequestTimeoutCallback( + __in PVOID SystemSpecific1, + __in PVOID FunctionContext, + __in PVOID SystemSpecific2, + __in PVOID SystemSpecific3 + ) +{ + PMBB_REQUEST_MANAGER RequestManager = (PMBB_REQUEST_MANAGER)FunctionContext; + PMBB_REQUEST_CONTEXT Request; + PLIST_ENTRY ListEntry; + LIST_ENTRY TempList; + ULONGLONG TimeoutDelta; + ULONGLONG NextTimeout = ULLONG_MAX; + ULONGLONG CurrentTime; + + InitializeListHead( &TempList ); + + MbbReqMgrLockManager( RequestManager ); + NdisGetSystemUpTimeEx( (PLARGE_INTEGER)(&CurrentTime) ); + for( ListEntry = RequestManager->AllocatedRequestList.Flink; + ListEntry != &RequestManager->AllocatedRequestList; + ListEntry = ListEntry->Flink ) + { + Request = CONTAINING_RECORD( ListEntry, MBB_REQUEST_CONTEXT, ManagerLink ); + + TimeoutDelta = CurrentTime - Request->DispatchTime; + if( TimeoutDelta > (MBB_REQUEST_TIMEOUT_MS-MBB_REQUEST_TIMEOUT_TOLERANCE_MS) ) + { + MbbReqMgrRefRequest( Request ); + InsertTailList( &TempList, &Request->ReqMgrContext.TimeoutLink ); + } + else + if( TimeoutDelta < NextTimeout ) + { + NextTimeout = TimeoutDelta; + } + } + // + // Re-arm the timer if required. + // Note that the tolerance is smaller than MBB_REQUEST_TIMEOUT_TOLERANCE_MS. + // This is because its not known how large NextTimeout is. + // + if( NextTimeout != ULLONG_MAX ) + { + MbbReqMgrTimerArm( + RequestManager, + MbbTimerTypeRequest, + (ULONG)NextTimeout, + 0, + 100, + MBB_LOCK_TAKEN + ); + } + + MbbReqMgrUnlockManager( RequestManager ); + + while (!IsListEmpty(&TempList)) + { + // Get the Entry of the list + ListEntry = RemoveHeadList(&TempList); + Request = CONTAINING_RECORD(ListEntry, MBB_REQUEST_CONTEXT, ReqMgrContext.TimeoutLink); + + MbbReqMgrQueueEvent( + RequestManager, + Request, + MbbRequestEventCancel, + (PVOID)(NDIS_STATUS_REQUEST_ABORTED), + 0 + ); + + PMBB_SEND_QUEUE SendQueue = &((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request))->SendQueue; + if (Request->OidHandler != NULL) + { + switch (Request->OidHandler->Oid) + { + case OID_WWAN_CONNECT: + TraceLoggingWrite( + g_hLoggingProvider, + "ConnectResponseTimeout", + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + //case OID_WWAN_PIN_EX: + TryQueueStallState(SendQueue); + break; + } + } + MbbReqMgrDerefRequest(Request); + } +} + +// +// FSM State Handlers +// + +VOID +MbbReqFsmReady( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + // + // No-op + // +} + +VOID +MbbReqFsmDispatching( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + BOOLEAN DispatchRequest; + PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; + + MbbReqMgrLockManager( RequestManager ); + + if( Request->ReqMgrContext.IsSerialized == TRUE ) + { + if( RequestManager->CurrentRequest == NULL ) + { + RequestManager->CurrentRequest = Request; + DispatchRequest = TRUE; + } + else + { + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Queuing request, QueueStatus[Current=0x%p %s]", + Request->RequestId, + RequestManager->CurrentRequest, + IsListEmpty( &RequestManager->PendingRequestQueue )? "EMPTY": "NON-EMPTY" + ); + // + // Reference request while it is queued + // + MbbReqMgrRefRequest( Request ); + + InsertTailList( + &(RequestManager->PendingRequestQueue), + &(Request->ReqMgrContext.QueueLink) + ); + DispatchRequest = FALSE; + Request->ReqMgrContext.IsQueued = TRUE; + } + } + else + { + DispatchRequest = TRUE; + } + // + // Schedule the timeout timer, if not already scheduled. + // + MbbReqMgrTimerArm( + RequestManager, + MbbTimerTypeRequest, + 0, + 0, + 0, + MBB_LOCK_TAKEN + ); + + MbbReqMgrUnlockManager( RequestManager ); + + if( DispatchRequest ) + { + MbbReqMgrQueueEvent( + RequestManager, + Request, + MbbRequestEventStart, + NULL, + 0 + ); + } +} + +VOID +MbbReqFsmSendPending( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + NDIS_STATUS NdisStatus; + PMBB_EVENT_ENTRY NewEventEntry; + + // + // Reference request while it is pending + // + MbbReqMgrRefRequest( Request ); + + NdisStatus = Request->ReqMgrContext.DispatchRoutine( + MbbReqMgrGetAdapterHandle( Request ), + Request + ); + if( NdisStatus != NDIS_STATUS_PENDING ) + { + MbbReqMgrQueueEvent( + Request->RequestManager, + Request, + MbbRequestEventSendComplete, + (PVOID)NdisStatus, + 0 + ); + } +} + +VOID +MbbReqFsmSendComplete( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + BOOLEAN IsSerialized = Request->ReqMgrContext.IsSerialized; + + if ((NDIS_STATUS)(EventEntry->EventData) != STATUS_SUCCESS) + { + // + // the send failed. copy the command id from the send to the response area since + // no response will be received and this can cause some handlers to not complete in indication + // + Request->HandlerContext.Response.Command= Request->HandlerContext.Command.Command; + } + + if( Request->ReqMgrContext.CompletionCallback != NULL ) + { + Request->ReqMgrContext.CompletionCallback( + MbbReqMgrGetAdapterHandle( Request ), + Request, + (NDIS_STATUS)(EventEntry->EventData) + ); + } + + if( IsSerialized == TRUE ) + { + MbbReqMgrIntProcessNextRequest( Request->RequestManager ); + } + // + // Request no longer pending + // + MbbReqMgrDerefRequest( Request ); +} + +VOID +MbbReqFsmResponseReceived( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + switch( EventEntry->Event ) + { + case MbbRequestEventResponseReceived: + { + if( Request->ReqMgrContext.ResponseHandler != NULL ) + { + Request->ReqMgrContext.ResponseHandler( + Request, + Request->HandlerContext.Response.NdisStatus, + Request->HandlerContext.Response.MbbStatus, + (PUCHAR) EventEntry->EventData, + EventEntry->EventDataLength + ); + } + } + break; + + case MbbRequestEventResponseReceivedMoreData: + { + if( Request->ReqMgrContext.ResponseHandler != NULL ) + { + Request->ReqMgrContext.ResponseHandler( + Request, + Request->HandlerContext.Response.NdisStatus, + MBB_STATUS_SMS_MORE_DATA, + (PUCHAR) EventEntry->EventData, + EventEntry->EventDataLength + ); + } + } + break; + + case MbbRequestEventSendComplete: + { + MbbReqFsmSendComplete( + Request, + OldState, + EventEntry + ); + } + break; + } +} + +VOID +MbbReqFsmCancelled( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + switch( EventEntry->Event ) + { + case MbbRequestEventDispatch: + { + // + // Request was cancelled after being created + // but before being dispatched. The request + // is not yet queued for dispatching. Fail the + // request instead of dispatching it. + // + ASSERT( Request->ReqMgrContext.CompletionCallback != NULL ); + + if( Request->ReqMgrContext.CompletionCallback != NULL ) + { + Request->ReqMgrContext.CompletionCallback( + MbbReqMgrGetAdapterHandle( Request ), + Request, + (NDIS_STATUS)(NDIS_STATUS_REQUEST_ABORTED) + ); + } + } + break; + + case MbbRequestEventSendComplete: + { + + EventEntry->EventData=(PVOID)NDIS_STATUS_REQUEST_ABORTED; + + MbbReqFsmSendComplete( + Request, + OldState, + EventEntry + ); + } + break; + + case MbbRequestEventCancel: + { + switch( OldState ) + { + case MbbRequestStateDispatching: + { + // + // Request was dispatched and serialized. + // Dequeue the request and fail it. + // + MbbReqMgrLockManager( Request->RequestManager ); + + RemoveEntryList( &Request->ReqMgrContext.QueueLink ); + + if(Request->ReqMgrContext.IsQueued) + { + // this means that the request was actually queued during + // dispatching and not processed directly. When the request + // was queued a reference was taken on the request which + // needs to be removed now. + + Request->ReqMgrContext.IsQueued = FALSE; + + MbbReqMgrUnlockManager( Request->RequestManager ); + + TraceInfo( WMBCLASS_REQUEST_FSM, "[ReqFsm][ReqId=0x%04x] Dequeuing queued request due to cancellation", Request->RequestId ); + + MbbReqMgrDerefRequest( Request ); + } + else + { + MbbReqMgrUnlockManager( Request->RequestManager ); + } + + if( Request->ReqMgrContext.CompletionCallback != NULL ) + { + Request->ReqMgrContext.CompletionCallback( + MbbReqMgrGetAdapterHandle( Request ), + Request, + (NDIS_STATUS)(EventEntry->EventData) + ); + } + } + break; + + case MbbRequestStateSendComplete: + case MbbRequestStateResponseReceivedMoreData: + { + if( Request->ReqMgrContext.ResponseHandler != NULL ) + { + Request->ReqMgrContext.ResponseHandler( + Request, + (NDIS_STATUS)(EventEntry->EventData), + MBB_STATUS_FAILURE, + NULL, + 0 + ); + } + } + break; + + case MbbRequestStateReady: + case MbbRequestStateCancelled: + case MbbRequestStateSendPending: + case MbbRequestStateResponseReceived: + default: + { + // + // No-op + // + } + break; + } + } + break; + + case MbbRequestEventStart: + case MbbRequestEventResponseReceived: + case MbbRequestEventResponseReceivedMoreData: + default: + { + // + // No-op + // + } + break; + } +} + +VOID +MbbReqFsmInvalid( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_STATE OldState, + __in PMBB_EVENT_ENTRY EventEntry + ) +{ + TraceInfo( WMBCLASS_REQUEST_FSM, "[ReqFsm][ReqId=0x%04x] INVALID Transition!!", Request->RequestId ); + ASSERT( FALSE ); +} diff --git a/network/wwan/cxwmbclass/RequestManager.h b/network/wwan/cxwmbclass/RequestManager.h new file mode 100644 index 000000000..790119dac --- /dev/null +++ b/network/wwan/cxwmbclass/RequestManager.h @@ -0,0 +1,230 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#define MBB_PREALLOC_REQUEST_COUNT 10 +#define MBB_PREALLOC_WORKITEM_COUNT 4 +#define MBB_PREALLOC_FRAGMENATION_BUFFER_COUNT 3 +#define MBB_FRAGMENATION_BULK_BUFFER_LENGTH (64*1024) +#define MBB_REASSEMBLE_BUFFER_LENGTH (64*1024) + + +//////////////////////////////////////////////////////////////////////////////// +// +// DECLARATIONS +// +//////////////////////////////////////////////////////////////////////////////// +FORCEINLINE +BOOLEAN +MbbReqMgrRef( + __in PMBB_REQUEST_MANAGER RequestManager + ); + +FORCEINLINE +VOID +MbbReqMgrDeref( + __in PMBB_REQUEST_MANAGER RequestManager + ); + +NDIS_STATUS +MbbReqMgrInitialize( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PMINIPORT_ADAPTER_CONTEXT AdapterContext + ); + +VOID +MbbReqMgrCleanup( + __in PMBB_REQUEST_MANAGER RequestManager + ); + +VOID +MbbReqMgrCancelRequests( + __in PMBB_REQUEST_MANAGER RequestManager, + __in BOOLEAN IsClosed + ); + +MBB_PROTOCOL_HANDLE +MbbReqMgrGetAdapterHandle( + __in PMBB_REQUEST_CONTEXT Request + ); + +BOOLEAN +MbbReqMgrIsInternalRequest( + __in PMBB_REQUEST_CONTEXT Request + ); + +VOID +MbbReqMgrSetUnsolicitedIndication( + __in PMBB_REQUEST_CONTEXT Request + ); + +BOOLEAN +MbbReqMgrIsUnsolicitedIndication( + __in PMBB_REQUEST_CONTEXT Request + ); + +_Requires_lock_not_held_(&(Request->RequestManager->Spinlock)) +VOID +MbbReqMgrGetState( + __in PMBB_REQUEST_CONTEXT Request, + __inout MBB_REQUEST_STATE *pCurrentState, + __inout MBB_REQUEST_STATE *pLastState + ); + +BOOLEAN +MbbReqMgrIsSetOid( + __in PMBB_REQUEST_CONTEXT Request + ); + +MBB_NDIS_OID_STATE +MbbReqMgrGetSetOidState( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_NDIS_OID_STATE OidState + ); + +__checkReturn +__drv_aliasesMem +__drv_allocatesMem(Mem) +PMBB_REQUEST_CONTEXT +MbbReqMgrCreateRequest( + __in PMBB_REQUEST_MANAGER RequestManager, + __in_opt PNDIS_OID_REQUEST OidRequest, + __in ULONG ResponseBufferLength, + __out PNDIS_STATUS NdisStatus + ); + +VOID +MbbReqMgrDestroyRequest( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PMBB_REQUEST_CONTEXT Request + ); + +NDIS_STATUS +MbbReqMgrDispatchRequest( + __in PMBB_REQUEST_CONTEXT Request, + __in BOOLEAN IsSerialized, + __in MBB_REQUEST_DISPATCH_ROUTINE DispatchRoutine, + __in MBB_REQUEST_COMPLETION_CALLBACK CompletionCallback, + __in_opt MBB_REQUEST_RESPONSE_HANDLER ResponseHandler + ); + +_Acquires_lock_( RequestManager->Spinlock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, RequestManager ) +VOID +MbbReqMgrLockManager( + __in PMBB_REQUEST_MANAGER RequestManager + ); + +_Releases_lock_( RequestManager->Spinlock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, RequestManager ) +VOID +MbbReqMgrUnlockManager( + __in PMBB_REQUEST_MANAGER RequestManager + ); + +PMBB_REQUEST_CONTEXT +MbbReqMgrGetRequestByOidRequestId( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PNDIS_OID_REQUEST RequestId + ); + +PMBB_REQUEST_CONTEXT +MbbReqMgrGetRequestById( + __in PMBB_REQUEST_MANAGER RequestManager, + __in ULONG RequestId + ); + +PMBB_REQUEST_CONTEXT +MbbReqMgrGetRequestByTransactionId( + __in PMBB_REQUEST_MANAGER RequestManager, + __in ULONG TransactionId + ); + +_Requires_lock_held_( RequestManager->Spinlock ) +VOID +MbbReqMgrQueueEventLocked( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_EVENT Event, + __in_opt PVOID EventData, + __in ULONG EventDataLength, + __in BOOLEAN SignalThread + ); + +_Requires_lock_not_held_( RequestManager->Spinlock ) +VOID +MbbReqMgrQueueEvent( + __in PMBB_REQUEST_MANAGER RequestManager, + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_EVENT Event, + __in_opt PVOID EventData, + __in ULONG EventDataLength + ); + +VOID +MbbReqMgrRefRequest( + __in PMBB_REQUEST_CONTEXT Request + ); + +VOID +MbbReqMgrDerefRequest( + __in PMBB_REQUEST_CONTEXT Request + ); + +// Reassemble context + +_Requires_lock_not_held_( RequestManager->Spinlock ) +PMBB_REASSEMBLE_CONTEXT +MbbReqMgrAcquireSharedReassembleContext( + __in PMBB_REQUEST_MANAGER RequestManager, + __in_bcount(MessageLength) PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader, + __in ULONG MessageLength, + __in GUID ActivityId + ); + +_Requires_lock_not_held_( RequestManager->Spinlock ) +VOID +MbbReqMgrReleaseSharedReassembleContext( + __in PMBB_REQUEST_MANAGER RequestManager + ); + +// Timer + +NDIS_STATUS +MbbReqMgrTimerInitialize( + __in PMBB_REQUEST_MANAGER RequestManager, + __in MBB_TIMER_TYPE TimerType + ); + +BOOLEAN +MbbReqMgrTimerCleanup( + __in PMBB_REQUEST_MANAGER RequestManager, + __in MBB_TIMER_TYPE TimerType + ); + +_When_( Locked==FALSE, _Requires_lock_not_held_( RequestManager->Spinlock ) ) +VOID +MbbReqMgrTimerArm( + __in PMBB_REQUEST_MANAGER RequestManager, + __in MBB_TIMER_TYPE TimerType, + __in_opt ULONG DelayInMS, + __in_opt ULONG PeriodInMS, + __in_opt ULONG ToleranceInMS, + __in BOOLEAN Locked + ); + +_When_( Locked==FALSE, _Requires_lock_not_held_( RequestManager->Spinlock ) ) +BOOLEAN +MbbReqMgrTimerDisarm( + __in PMBB_REQUEST_MANAGER RequestManager, + __in MBB_TIMER_TYPE TimerType, + __in BOOLEAN Locked + ); diff --git a/network/wwan/cxwmbclass/adapter.c b/network/wwan/cxwmbclass/adapter.c new file mode 100644 index 000000000..5e637838d --- /dev/null +++ b/network/wwan/cxwmbclass/adapter.c @@ -0,0 +1,3398 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +#include "precomp.h" +#include "adapter.tmh" +#include "WMBClassTelemetry.h" + +#define MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS (10 * 1000 * 1000) // 10 seconds +#define MBB_ADAPTER_PRESHUTDOWN_REQUEST_TIMEOUT_MS (6 * 1000 * 1000) // 6 seconds + +// +// Adapter routines +// +_Acquires_lock_( Adapter->Lock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterLock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NdisAcquireSpinLock( &Adapter->Lock ); +} + +_Releases_lock_( Adapter->Lock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterUnlock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NdisReleaseSpinLock( &Adapter->Lock ); +} + +_Acquires_lock_( Adapter->PortsLock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterPortsLock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NdisAcquireSpinLock( &Adapter->PortsLock ); +} + +_Releases_lock_( Adapter->PortsLock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterPortsUnlock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NdisReleaseSpinLock( &Adapter->PortsLock ); +} + +_Acquires_lock_( Adapter->SessionIdPortTableLock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterSessionIdPortTableLock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NdisAcquireSpinLock( &Adapter->SessionIdPortTableLock ); +} + +_Releases_lock_( Adapter->SessionIdPortTableLock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterSessionIdPortTableUnlock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NdisReleaseSpinLock( &Adapter->SessionIdPortTableLock ); +} + + +VOID +MbbAdapterRef( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + InterlockedIncrement( &Adapter->Reference ); +} + +VOID +MbbAdapterDeref( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + if( InterlockedDecrement( &Adapter->Reference ) == 0 ) + { + FreeAdapterBlock( Adapter ); + } +} + +VOID +MbbAdapterConnectionChange( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in PMBB_CONNECTION_STATE ConnectionState, + __in NDIS_PORT_NUMBER PortNumber + ) +{ + NDIS_STATUS NdisStatus; + MBB_COMMAND IpCommand; + PMBB_REQUEST_CONTEXT IpRequest; + PMBB_REQUEST_MANAGER RequestManager = NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; + PMBB_PORT Port = NULL; + + do + { + // Get the port + Port = MbbWwanTranslatePortNumberToPort(Adapter,PortNumber); + + if(!Port) + { + break; + } + + if( ConnectionState->ConnectionUp == TRUE ) + { + // + // Get the IP Address if connection was successful. + // When IP is retrieved link state would be indicated to NDIS. + // + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][Luid=0x%I64x] FAILED to reference RequestManager to get IP Address", Adapter->NetLuid.Value ); + break; + } + if( (IpRequest = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][Luid=0x%I64x] FAILED to allocate RequestContext to get IP Address", Adapter->NetLuid.Value ); + break; + } + IpCommand.ServiceId = MBB_UUID_BASIC_CONNECT; + IpCommand.CommandId = MBB_BASIC_CID_IP_ADDRESS_INFO; + IpRequest->OidHandler = MbbNdisGetOidHandlerByCommand( &IpCommand ); + // + // Save the connection state for indication to NDIS when IP is retrieved. + // + IpRequest->HandlerContext.Parameters.IpAddress.ConnectionState = *ConnectionState; + IpRequest->HandlerContext.Parameters.IpAddress.SessionId = MbbWwanGetPortSessionId(Port); + + NdisStatus = MbbReqMgrDispatchRequest( + IpRequest, + TRUE, + MbbUtilInternalCIDQuery, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + if( NdisStatus != NDIS_STATUS_PENDING ) + { + MbbReqMgrDestroyRequest( + IpRequest->RequestManager, + IpRequest + ); + } + } + else + { + MbbAdapterSetConnectionState( + Adapter, + ConnectionState, + PortNumber + ); + } + } + while( FALSE ); + + if(Port!=NULL) + Dereference(Port); + + if( RequestManager != NULL ) + MbbReqMgrDeref( RequestManager ); +} + +VOID +MbbAdapterSetConnectionState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_CONNECTION_STATE ConnectionState, + __in NDIS_PORT_NUMBER PortNumber + ) +{ + + PMBB_PORT Port = NULL; + BOOLEAN fIndicateLinkState = FALSE; + + Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); + + if(Port != NULL) + { + MBB_ACQUIRE_PORT_LOCK(Port); + + Port->ConnectionState = *ConnectionState; + + MBB_RELEASE_PORT_LOCK(Port); + } + + if(ConnectionState->ConnectionUp) + { + // Always indicate Link state when on a successful connection + fIndicateLinkState = TRUE; + } + else + { + // Connection is disconnected. + // Look at all the ports in the adapter and indicate the link state + // down only if all the ports are disconnected + + ULONG NumPortsConnected = 0; + fIndicateLinkState = ((NumPortsConnected = MbbWwanGetNumPortsConnected(Adapter))== 0); + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] %S status LINK_STATE disconnected for Port =%lu since %d ports are connected", + fIndicateLinkState ? L"Indicating" : L"Not indicating", + PortNumber, + NumPortsConnected); + } + + if(fIndicateLinkState) + { + // Indicate link down + MbbAdapterSetLinkState( + Adapter, + ConnectionState, + PortNumber); + } + + // Always indicate the port state + MbbAdapterSetPortState( + Adapter, + ConnectionState, + PortNumber); + + if(Port != NULL) + { + Dereference(Port); + } +} + +VOID +MbbAdapterSetLinkState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_CONNECTION_STATE ConnectionState, + __in NDIS_PORT_NUMBER PortNumber + ) +{ + NDIS_LINK_STATE LinkState; + NDIS_STATUS_INDICATION StatusIndication; + + LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1; + LinkState.Header.Size = NDIS_SIZEOF_LINK_STATE_REVISION_1; + LinkState.MediaConnectState = ConnectionState->ConnectionUp ? MediaConnectStateConnected : MediaConnectStateDisconnected; + LinkState.MediaDuplexState = MediaDuplexStateUnknown; + LinkState.XmitLinkSpeed = ConnectionState->UpStreamBitRate; + LinkState.RcvLinkSpeed = ConnectionState->DownStreamBitRate; + LinkState.PauseFunctions = NdisPauseFunctionsUnsupported; + LinkState.AutoNegotiationFlags = 0; + + StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; + StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; + StatusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; + StatusIndication.SourceHandle = Adapter->MiniportAdapterHandle; + StatusIndication.PortNumber = PortNumber; + StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE; + StatusIndication.Flags = 0; + StatusIndication.DestinationHandle = NULL; + StatusIndication.RequestId = 0; + StatusIndication.StatusBuffer = &LinkState; + StatusIndication.StatusBufferSize = sizeof(NDIS_LINK_STATE); + + RtlZeroMemory( &StatusIndication.Guid, sizeof(StatusIndication.Guid) ); + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] Indicating status LINK_STATE Connected=%!BOOLEAN! to NDIS, Uplink=%I64d, downlink=%I64d for Port =%lu", + ConnectionState->ConnectionUp, + ConnectionState->DownStreamBitRate, + ConnectionState->UpStreamBitRate, + PortNumber + ); + + MbbUtilNdisMiniportIndicateStatusEx( + Adapter, + &StatusIndication + ); +} + + +VOID +MbbAdapterSetPortState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_CONNECTION_STATE ConnectionState, + __in NDIS_PORT_NUMBER PortNumber + ) +{ + NDIS_PORT_STATE PortState; + NDIS_STATUS_INDICATION StatusIndication; + PMBB_PORT Port = NULL; + + Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); + + if(Port != NULL) + { + MBB_ACQUIRE_PORT_LOCK(Port); + + Port->ConnectionState = *ConnectionState; + + MBB_RELEASE_PORT_LOCK(Port); + + Dereference(Port); + } + + PortState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + PortState.Header.Revision = NDIS_PORT_STATE_REVISION_1; + PortState.Header.Size = NDIS_SIZEOF_PORT_STATE_REVISION_1; + PortState.MediaConnectState = ConnectionState->ConnectionUp ? MediaConnectStateConnected : MediaConnectStateDisconnected; + PortState.XmitLinkSpeed = ConnectionState->UpStreamBitRate; + PortState.RcvLinkSpeed = ConnectionState->DownStreamBitRate; + PortState.Direction = NET_IF_DIRECTION_SENDRECEIVE; + PortState.SendControlState = NdisPortControlStateUncontrolled; + PortState.RcvControlState = NdisPortControlStateUncontrolled; + PortState.SendAuthorizationState = NdisPortAuthorizationUnknown; + PortState.RcvAuthorizationState = NdisPortAuthorizationUnknown; + PortState.Flags = 0; + + StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; + StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; + StatusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; + StatusIndication.SourceHandle = Adapter->MiniportAdapterHandle; + StatusIndication.PortNumber = PortNumber; + StatusIndication.StatusCode = NDIS_STATUS_PORT_STATE; + StatusIndication.Flags = 0; + StatusIndication.DestinationHandle = NULL; + StatusIndication.RequestId = 0; + StatusIndication.StatusBuffer = &PortState; + StatusIndication.StatusBufferSize = sizeof(NDIS_PORT_STATE); + + RtlZeroMemory( &StatusIndication.Guid, sizeof(StatusIndication.Guid) ); + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] Indicating status PORT_STATE Connected=%!BOOLEAN! to NDIS, Uplink=%I64d, downlink=%I64d for Port =%lu", + ConnectionState->ConnectionUp, + ConnectionState->DownStreamBitRate, + ConnectionState->UpStreamBitRate, + PortNumber + ); + + MbbUtilNdisMiniportIndicateStatusEx( + Adapter, + &StatusIndication + ); +} + +VOID +MbbPortSetIpAddressState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PWWAN_IP_ADDRESS_STATE WwanIpAddressState, + __in NDIS_PORT_NUMBER PortNumber + ) +{ + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_IP_ADDRESS_STATE IpAddressState = {0}; + + if(!WwanIpAddressState) + { + return; + } + + IpAddressState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + IpAddressState.Header.Size = SIZEOF_NDIS_WWAN_IP_ADDRESS_STATE_1; + IpAddressState.Header.Revision = NDIS_WWAN_IP_ADDRESS_STATE_REVISION_1; + IpAddressState.WwanIpAddressState = *WwanIpAddressState; + + StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; + StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; + StatusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; + StatusIndication.SourceHandle = Adapter->MiniportAdapterHandle; + StatusIndication.PortNumber = PortNumber; + StatusIndication.Flags = 0; + StatusIndication.DestinationHandle = NULL; + StatusIndication.RequestId = 0; + StatusIndication.StatusCode = NDIS_STATUS_WWAN_IP_ADDRESS_STATE; + StatusIndication.StatusBuffer = &IpAddressState; + StatusIndication.StatusBufferSize = SIZEOF_NDIS_WWAN_IP_ADDRESS_STATE_1; + + RtlZeroMemory( &StatusIndication.Guid, sizeof(StatusIndication.Guid) ); + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] Indicating status NDIS_STATUS_WWAN_IPADDRESS_STATE on NDIS port number %lu",PortNumber); + + NdisMIndicateStatusEx( + Adapter->MiniportAdapterHandle, + &StatusIndication + ); +} + +BOOLEAN +MbbPortIsConnected( + __in PMBB_PORT Port + ) +{ + BOOLEAN IsConnected; + + MBB_ACQUIRE_PORT_LOCK(Port); + IsConnected = Port->ConnectionState.ConnectionUp; + MBB_RELEASE_PORT_LOCK(Port); + + return IsConnected; +} + +VOID +MbbAdapterIndicateD3Exit( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in NDIS_PORT_NUMBER PortNumber + ) +{ + NDIS_STATUS_INDICATION StatusIndication; + + StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; + StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; + StatusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; + StatusIndication.SourceHandle = Adapter->MiniportAdapterHandle; + StatusIndication.PortNumber = PortNumber; + StatusIndication.StatusCode = NDIS_STATUS_WWAN_RESERVED_3; //NDIS_STATUS_WWAN_DEVICE_POWER_STATE_D3_EXIT + StatusIndication.Flags = 0; + StatusIndication.DestinationHandle = NULL; + StatusIndication.RequestId = 0; + StatusIndication.StatusBuffer = NULL; + StatusIndication.StatusBufferSize = 0; + + RtlZeroMemory( &StatusIndication.Guid, sizeof(StatusIndication.Guid) ); + + TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] Indicating status NDIS_STATUS_WWAN_DEVICE_POWER_STATE_D3_EXIT to NDIS for adapter with guid %!GUID! on Port number %lu", + &(Adapter->NetCfgId), + PortNumber + ); + + MbbUtilNdisMiniportIndicateStatusEx( + Adapter, + &StatusIndication + ); +} + + +NDIS_STATUS +MbbAdapterDispatchQueryDeviceServicesRequest( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + MBB_COMMAND Command; + + do + { + RtlCopyMemory( + &(Command.ServiceId), + &MBB_UUID_BASIC_CONNECT, + sizeof(GUID) + ); + Command.CommandId = MBB_BASIC_CID_DEVICE_SERVICES; + + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Command, + MBB_COMMAND_TYPE_QUERY, + NULL, + 0 + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for QueryDeviceServices with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for QueryDeviceServices with status=%!status!", + Request->RequestId, NdisStatus ); + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterQueryDeviceServices( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_DEVICE_SERVICES }; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for QueryDeviceService" ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for QueryDeviceService" ); + break; + } + Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + // + // Ref the request so that the response handler does not free it + // + MbbReqMgrRefRequest( Request ); + + TraceInfo( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] Internal query dispatch for BASIC_CID_DEVICE_SERVICES", + Request->RequestId + ); + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbAdapterDispatchQueryDeviceServicesRequest, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If the request is pending wait for it to complete. + // If the request didnt complete within the timeout period drop our ref count and fail to the caller. + // Something is wrong with a device that does not complete a non-network request within the timeout + // If dispatching the request failed then our completion callback will not be invoked, + // in this case destroy the request. + // + if( NdisStatus == NDIS_STATUS_PENDING ) + { + Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; + NdisStatus = KeWaitForSingleObject( + &Request->WaitEvent, + Executive, + KernelMode, + TRUE, // Alertable + &Timeout // Timeout + ); + if( NdisStatus != STATUS_WAIT_0 ) + { + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + // + // Only if Send was successful then get the response status. + // + if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) + NdisStatus = Request->HandlerContext.Response.NdisStatus; + } + } + else + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + // + // It is ok to destroy the request here and deref it later. + // Destroy will not free the request while there is a pending ref. + // + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + if( Request != NULL ) + { + MbbReqMgrDerefRequest( Request ); + } + return NdisStatus; +} + + +NDIS_STATUS +MbbAdapterDispatchConfigureRadioStateRequest( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + MBB_COMMAND Command; + MBB_RADIO_STATE* MbbRadioState; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + + do + { + RtlCopyMemory( + &(Command.ServiceId), + &MBB_UUID_BASIC_CONNECT, + sizeof(GUID) + ); + Command.CommandId = MBB_BASIC_CID_RADIO_STATE; + + if( (MbbRadioState = (MBB_RADIO_STATE*) ALLOCATE_NONPAGED_POOL( sizeof(MBB_RADIO_STATE) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbRadioState; + + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + *MbbRadioState = Adapter->RadioOff ? MbbRadioStateOff : MbbRadioStateOn; + + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Command, + MBB_COMMAND_TYPE_SET, + (PUCHAR) MbbRadioState, + sizeof(MBB_RADIO_STATE) + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for ConfigureRadioState with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for ConfigureRadioState with status=%!status!", + Request->RequestId, NdisStatus ); + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterConfigureRadioState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_RADIO_STATE }; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for ConfigureRadioState" ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for ConfigureRadioState" ); + break; + } + Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + // + // Ref the request so that the response handler does not free it + // + MbbReqMgrRefRequest( Request ); + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbAdapterDispatchConfigureRadioStateRequest, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If the request is pending wait for it to complete. + // If the request didnt complete within the timeout period drop our ref count and fail to the caller. + // Something is wrong with a device that does not send response for a non-network request + // If dispatching the request failed then our completion callback will not be invoked, + // in this case destroy the request. + // + if( NdisStatus == NDIS_STATUS_PENDING ) + { + Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; + NdisStatus = KeWaitForSingleObject( + &Request->WaitEvent, + Executive, + KernelMode, + TRUE, // Alertable + &Timeout // Timeout + ); + if( NdisStatus != STATUS_WAIT_0 ) + { + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + // + // Only if Send was successful then get the response status. + // + if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) + NdisStatus = Request->HandlerContext.Response.NdisStatus; + } + } + else if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + // + // It is ok to destroy the request here and deref it later. + // Destroy will not free the request while there is a pending ref. + // + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + if( Request != NULL ) + { + MbbReqMgrDerefRequest( Request ); + } + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterPerformInitialRequests( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + // + // We are going to wait for these requests to finish. This will block the + // MiniportInitialize call. For NDIS 6.30 drivers, NDIS would not be blocking + // the PnP IRP until MiniportInitialize finishes. So we are OK with the taking + // a while for MiniportInitialize + // + + // Query device services + if( (Status = MbbAdapterQueryDeviceServices( Adapter )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to QueryDeviceService, status=%!STATUS!", Status ); + goto Cleanup; + } + + // Set default subscribe list + if( (Status = MbbAdapterConfigureDeviceServiceSubscription( Adapter, TRUE, 0, 0 )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to Set initial subscribe events list, status=%!STATUS!", Status ); + goto Cleanup; + } + + // Set the radio state that has been persisted in registry + if( (Status = MbbAdapterConfigureRadioState( Adapter )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to ConfigureRadioState, status=%!STATUS!", Status ); + goto Cleanup; + } + +Cleanup: + + return Status; +} + + + + +NDIS_STATUS +MbbAdapterDispatchConfigurePacketFiltersRequest( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + MBB_COMMAND Command; + MBB_PACKET_FILTERS* MbbPacketFilters=NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + ULONG BufferSize=0; + + do + { + RtlCopyMemory( + &(Command.ServiceId), + &MBB_UUID_BASIC_CONNECT, + sizeof(GUID) + ); + Command.CommandId = MBB_BASIC_CID_PACKET_FILTERS; + + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + NdisStatus=MbbUtilWwanToMbbSetPacketFilter( + Adapter, + Request->HandlerContext.Parameters.SetPacketFilter.Set, + Request->HandlerContext.Parameters.SetPacketFilter.PortNumber, + &MbbPacketFilters, + &BufferSize + ); + + if (!NT_SUCCESS(NdisStatus)) + { + break; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbPacketFilters; + + + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Command, + MBB_COMMAND_TYPE_SET, + (PUCHAR) MbbPacketFilters, + BufferSize + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for ConfigurePacketFilters with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for ConfigurePacketFilters with status=%!status!", + Request->RequestId, NdisStatus ); + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterConfigurePacketFilters( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN Set + ) + // Algorithm: + // 1) Iterate through the adapter powerfilter table and check if + // there are any empty slots. + // + // 2) Iterate over all the connected sessions and check if they are having + // any WOL patterns associated with them. + // + // 3) If no WOL patterns are found + // { + // create a no-match WOL pattern and add it to the power filter table for that session ID + // goto step4 + // } + // + //4) Plumb the WOL patterns for connected sessions + // + + // Assumptions: + // Since this routine is called under the context of an OID, there will not be + // any other routines trying to alter the Adapter->PowerFilterTable + // + // In case there are no WOL patterns corresponding to the session, the code will + // try to set no-match pattern for them, if any wake slots are available according to + // Adapter->PowerFilterTable. We will return on first failure. +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + ULONG NumEmptySlots = 0; + ULONG ConnectedPorts[MBB_MAX_NUMBER_OF_PORTS] = {0}; + ULONG NumConnectedPorts = 0; + ULONG i = 0, j = 0; + + + // Only if this is a set request for wake filters, get the number of + // empty slots + + if(Set) + { + for (i = 0; i < Adapter->BusParams.PowerFiltersSupported; i++) + { + if(!Adapter->PowerFilterTable[i].InUse) + { + NumEmptySlots++; + } + } + } + + + // We will create a transient array of connected ports and send the request to + // configure packet filters for them iteratively. No new ports are expected to be added + // since this routine is called in context of an OID request and until this OID request completes + // OID to create a new context can not come. There can however be unsolicited context + // deactivations. In that case we will still send the request to the device which should fail it. + + MbbAdapterPortsLock(Adapter); + + for(i = 0; i < Adapter->NumberOfPorts && NumConnectedPorts < MBB_MAX_NUMBER_OF_PORTS; i++) + { + NDIS_PORT_NUMBER PortNumber = MBB_INVALID_PORT_NUMBER; + PMBB_PORT Port = Adapter->PortList[i]; + + MBB_ACQUIRE_PORT_LOCK(Port); + + if(Port->ConnectionState.ConnectionUp) + { + ASSERT(Port->SessionId != MBB_INVALID_SESSION_ID && (ULONG)Port->SessionId < Adapter->MaxActivatedContexts); + + PortNumber = Port->PortNumber; + + MBB_RELEASE_PORT_LOCK(Port); + + ConnectedPorts[NumConnectedPorts++] = PortNumber; + + if(Set) + { + // add a no-match WOL pattern if there are empty slots + if(NumEmptySlots > 0) + { + // Evaluate and add no-match patterns for this + // port if it has no wake filter configured. + + BOOL fHasWOLPattern = FALSE; + + for(j = 0; j < Adapter->BusParams.PowerFiltersSupported; j++) + { + if(Adapter->PowerFilterTable[j].InUse + && Adapter->PowerFilterTable[j].PortNumber == PortNumber) + { + fHasWOLPattern = TRUE; + break; + } + } + + if(!fHasWOLPattern) + { + if((Status = MbbUtilAddNoMatchFilter(Adapter, Port)) == NDIS_STATUS_SUCCESS) + { + NumEmptySlots--; + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Remaining slots in adapter power filter table after addition of no-match filter = %d", NumEmptySlots); + } + else + { + // absorb the error + Status = NDIS_STATUS_SUCCESS; + } + } + } + else + { + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Not evaluating no-match filters for port number %lu since there are no empty slots", PortNumber); + } + } + else + { + // Remove the no-match filter for this port, if any + MbbUtilRemoveNoMatchFilter(Adapter, Port); + } + } + else + { + MBB_RELEASE_PORT_LOCK(Port); + } + } + + MbbAdapterPortsUnlock(Adapter); + + if(NumConnectedPorts > 0) + { + for(i = 0; i < NumConnectedPorts; i++) + { + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Attempting to %s packet filters or no-match filters for connected port %lu", Set ? "set":"reset", ConnectedPorts[i]); + + if( (Status = MbbAdapterConfigurePacketFiltersOnSession(Adapter, Set, ConnectedPorts[i])) != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] Failed to %s packet filters or no-match filters for port %lu. Status=%!status!", Set ? "set":"reset", ConnectedPorts[i], Status); + // continue plumbing as many packet filters as possible + } + else + { + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Successfully %s packet filters or no-match filters for connected port %lu", Set ? "set":"reset", ConnectedPorts[i]); + } + } + } + else + { + TraceWarn( WMBCLASS_INIT, "[MbbAdapter] Not attempting to %s packet filters or no-match filters as there are no connected ports", Set ? "set":"reset"); + } + + return Status ; +} + + +NDIS_STATUS +MbbAdapterConfigurePacketFiltersOnSession( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN Set, + __in NDIS_PORT_NUMBER PortNumber + ) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_FILTERS }; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for ConfigurePacketFilters" ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for ConfigurePacketFilters" ); + break; + } + Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + + Request->HandlerContext.Parameters.SetPacketFilter.Set=Set; + Request->HandlerContext.Parameters.SetPacketFilter.PortNumber = PortNumber; + + // + // Ref the request so that the response handler does not free it + // + MbbReqMgrRefRequest( Request ); + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbAdapterDispatchConfigurePacketFiltersRequest, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If the request is pending wait for it to complete. + // If the request didnt complete within the timeout period drop our ref count and fail to the caller. + // Something is wrong with a device that does not send response for a non-network request + // If dispatching the request failed then our completion callback will not be invoked, + // in this case destroy the request. + // + if( NdisStatus == NDIS_STATUS_PENDING ) + { + Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; + NdisStatus = KeWaitForSingleObject( + &Request->WaitEvent, + Executive, + KernelMode, + TRUE, // Alertable + &Timeout // Timeout + ); + if( NdisStatus != STATUS_WAIT_0 ) + { + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + // + // Only if Send was successful then get the response status. + // + if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) + NdisStatus = Request->HandlerContext.Response.NdisStatus; + } + } + else if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + // + // It is ok to destroy the request here and deref it later. + // Destroy will not free the request while there is a pending ref. + // + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + if( Request != NULL ) + { + MbbReqMgrDerefRequest( Request ); + } + return NdisStatus; +} + + +NDIS_STATUS +MbbAdapterDispatchConfigureDeviceServiceSubscriptionRequest( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + MBB_COMMAND Command; + MBB_SUBSCRIBE_EVENT_LIST* MbbDeviceServiceSubscription=NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + ULONG BufferSize=0; + + do + { + RtlCopyMemory( + &(Command.ServiceId), + &MBB_UUID_BASIC_CONNECT, + sizeof(GUID) + ); + Command.CommandId = MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES; + + + + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + NdisStatus=MbbUtilGenerateSubscribeEventList( + Adapter, + Request->HandlerContext.Parameters.SyncDeviceServiceSubription.FullPower, + Request->HandlerContext.Parameters.SyncDeviceServiceSubription.MediaSpecificWakeUpEvents, + Request->HandlerContext.Parameters.SyncDeviceServiceSubription.WakeUpFlags, + Adapter->DeviceServiceState.ExtSubscribeList, + Adapter->DeviceServiceState.ExtSubscribeListBufferSize, + &MbbDeviceServiceSubscription, + &BufferSize + ); + + + + if (!NT_SUCCESS(NdisStatus)) + { + break; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbDeviceServiceSubscription; + + + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Command, + MBB_COMMAND_TYPE_SET, + (PUCHAR) MbbDeviceServiceSubscription, + BufferSize + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for ConfigureDeviceServiceSubscription with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for ConfigureDeviceServiceSubscription with status=%!status!", + Request->RequestId, NdisStatus ); + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterConfigureDeviceServiceSubscription( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN FullPower, + __in ULONG MediaSpecificWakeUpEvents, + __in ULONG WakeUpFlags + ) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES }; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for ConfigureDeviceServiceSubscription" ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for ConfigureDeviceServiceSubscription" ); + break; + } + Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + + Request->HandlerContext.Parameters.SyncDeviceServiceSubription.FullPower=FullPower; + Request->HandlerContext.Parameters.SyncDeviceServiceSubription.MediaSpecificWakeUpEvents=MediaSpecificWakeUpEvents; + Request->HandlerContext.Parameters.SyncDeviceServiceSubription.WakeUpFlags=WakeUpFlags; + // + // Ref the request so that the response handler does not free it + // + MbbReqMgrRefRequest( Request ); + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbAdapterDispatchConfigureDeviceServiceSubscriptionRequest, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If the request is pending wait for it to complete. + // If the request didnt complete within the timeout period drop our ref count and fail to the caller. + // Something is wrong with a device that does not send response for a non-network request + // If dispatching the request failed then our completion callback will not be invoked, + // in this case destroy the request. + // + if( NdisStatus == NDIS_STATUS_PENDING ) + { + Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; + NdisStatus = KeWaitForSingleObject( + &Request->WaitEvent, + Executive, + KernelMode, + TRUE, // Alertable + &Timeout // Timeout + ); + if( NdisStatus != STATUS_WAIT_0 ) + { + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + // + // Only if Send was successful then get the response status. + // + if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) + NdisStatus = Request->HandlerContext.Response.NdisStatus; + } + } + else if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + // + // It is ok to destroy the request here and deref it later. + // Destroy will not free the request while there is a pending ref. + // + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + if( Request != NULL ) + { + MbbReqMgrDerefRequest( Request ); + } + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterDispatchSendNetworkIdleHintRequest( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + MBB_COMMAND Command; + MBB_SUBSCRIBE_EVENT_LIST* MbbDeviceServiceSubscription=NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + ULONG BufferSize=0; + PMBB_NETWORK_IDLE_HINT IdleHint=NULL; + + do + { + RtlCopyMemory( + &(Command.ServiceId), + &MBB_UUID_BASIC_CONNECT, + sizeof(GUID) + ); + Command.CommandId = MBB_BASIC_CID_NETWORK_IDLE_HINT; + + IdleHint=ALLOCATE_NONPAGED_POOL(sizeof(*IdleHint)); + + if (IdleHint == NULL) + { + NdisStatus=NDIS_STATUS_RESOURCES; + break; + } + + IdleHint->NetworkIdleHintState=MbbNetworkIdleHintEnabled; + + Request->HandlerContext.DataToFreeOnCompletion = IdleHint; + + + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Command, + MBB_COMMAND_TYPE_SET, + (PUCHAR) IdleHint, + sizeof(*IdleHint) + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for SendNetworkIdleHint with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for SendNetworkIdleHint with status=%!status!", + Request->RequestId, NdisStatus ); + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterSendNetworkIdleHint( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_NETWORK_IDLE_HINT }; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for SendNetworkIdleHint" ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for SendNetworkIdleHint" ); + break; + } + Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + + // + // Ref the request so that the response handler does not free it + // + MbbReqMgrRefRequest( Request ); + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbAdapterDispatchSendNetworkIdleHintRequest, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If the request is pending wait for it to complete. + // If the request didnt complete within the timeout period drop our ref count and fail to the caller. + // Something is wrong with a device that does not send response for a non-network request + // If dispatching the request failed then our completion callback will not be invoked, + // in this case destroy the request. + // + if( NdisStatus == NDIS_STATUS_PENDING ) + { + Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; + NdisStatus = KeWaitForSingleObject( + &Request->WaitEvent, + Executive, + KernelMode, + TRUE, // Alertable + &Timeout // Timeout + ); + if( NdisStatus != STATUS_WAIT_0 ) + { + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + // + // Only if Send was successful then get the response status. + // + if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) + NdisStatus = Request->HandlerContext.Response.NdisStatus; + } + } + else if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + // + // It is ok to destroy the request here and deref it later. + // Destroy will not free the request while there is a pending ref. + // + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + if( Request != NULL ) + { + MbbReqMgrDerefRequest( Request ); + } + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterDispatchSendNetworkShutdownHintRequest( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + MBB_COMMAND Command; + MBB_SUBSCRIBE_EVENT_LIST* MbbDeviceServiceSubscription=NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + ULONG BufferSize=0; + + do + { + RtlCopyMemory( + &(Command.ServiceId), + &MBB_UUID_HOSTSHUTDOWN, + sizeof(GUID) + ); + Command.CommandId = MBB_HOSTSHUTDOWN_CID_ONE; + + + + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Command, + MBB_COMMAND_TYPE_SET, + NULL, + 0 + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for SendNetworkShutdownHint with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for SendNetworkShutdownHint with status=%!status!", + Request->RequestId, NdisStatus ); + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterSendNetworkShutdownHint( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + MBB_COMMAND Command = { MBB_UUID_HOSTSHUTDOWN_CONSTANT, MBB_HOSTSHUTDOWN_CID_ONE }; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + BOOLEAN HintSupport=FALSE; + + do + { + MbbAdapterLock( Adapter ); + HintSupport = Adapter->AdapterFlags.ShutdownNotificationCapable == 1; + MbbAdapterUnlock( Adapter ); + + if (!HintSupport) + { + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] device does not support NetworkShutdownHint" ); + NdisStatus=STATUS_SUCCESS; + break; + } + + + + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for SendNetworkShutdownHint" ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for SendNetworkShutdownHint" ); + break; + } + Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + + // + // Ref the request so that the response handler does not free it + // + MbbReqMgrRefRequest( Request ); + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbAdapterDispatchSendNetworkShutdownHintRequest, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If the request is pending wait for it to complete. + // If the request didnt complete within the timeout period drop our ref count and fail to the caller. + // Something is wrong with a device that does not send response for a non-network request + // If dispatching the request failed then our completion callback will not be invoked, + // in this case destroy the request. + // + if( NdisStatus == NDIS_STATUS_PENDING ) + { + Timeout.QuadPart = -1 * 10 * 500000; + NdisStatus = KeWaitForSingleObject( + &Request->WaitEvent, + Executive, + KernelMode, + TRUE, // Alertable + &Timeout // Timeout + ); + if( NdisStatus != STATUS_WAIT_0 ) + { + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + // + // Only if Send was successful then get the response status. + // + if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) + NdisStatus = Request->HandlerContext.Response.NdisStatus; + } + } + else if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + // + // It is ok to destroy the request here and deref it later. + // Destroy will not free the request while there is a pending ref. + // + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + if( Request != NULL ) + { + MbbReqMgrDerefRequest( Request ); + } + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterDispatchSendPreShutdownRequest( + _In_ MBB_PROTOCOL_HANDLE AdapterHandle, + _In_ PMBB_REQUEST_CONTEXT Request +) +{ + NDIS_STATUS NdisStatus = MbbUtilSetAttributeWithParameter( + Request, + NULL, + 0); + + if ((NdisStatus != NDIS_STATUS_SUCCESS) && + (NdisStatus != NDIS_STATUS_PENDING)) + { + TraceError(WMBCLASS_INIT, "[MbbNdis][ReqID=0x%04x] SendPreShutdownRequest Set failed with status=%!status!", + Request->RequestId, NdisStatus); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterSendPreShutdown( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter +) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + MBB_COMMAND Command = { MBB_UUID_HOSTSHUTDOWN_CONSTANT, MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN }; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + BOOLEAN IsPreshutdownSupport = FALSE; + + MbbAdapterLock(Adapter); + IsPreshutdownSupport = (TRUE == Adapter->AdapterFlags.IsPreshutdownCapable); + MbbAdapterUnlock(Adapter); + + do { + if (!IsPreshutdownSupport) + { + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support PreShutdown"); + NdisStatus = STATUS_SUCCESS; + break; + } + + if ((RequestManager = MbbAdapterGetRequestManager(Adapter)) == NULL) + { + TraceError(WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for SendPreShutdown"); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + + if ((Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL) + { + TraceError(WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for SendPreShutdown"); + break; + } + Request->OidHandler = MbbNdisGetOidHandlerByCommand(&Command); + + // + // Ref the request so that the response handler does not free it + // + MbbReqMgrRefRequest(Request); + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbAdapterDispatchSendPreShutdownRequest, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // The request is dispatched and queued. We expect to get NDIS_STATUS_PENDING and wait for it to complete. + // + if (NdisStatus == NDIS_STATUS_PENDING) + { + // A positive value specifies an absolute time, relative to January 1, 1601. + // Here we use a NEGATIVE value to specify an interval relative to the current time. + Timeout.QuadPart = -10 * MBB_ADAPTER_PRESHUTDOWN_REQUEST_TIMEOUT_MS; // 100-nanosecond unit; + NdisStatus = KeWaitForSingleObject( + &Request->WaitEvent, + Executive, + KernelMode, + TRUE, // Alertable + &Timeout + ); + if (NdisStatus != STATUS_WAIT_0) + { + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + // get the response status only when Send was successful + if ((NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS) + { + NdisStatus = Request->HandlerContext.Response.NdisStatus; + } + } + } + else if (NdisStatus != NDIS_STATUS_SUCCESS) + { + // Something wrong when dispatching request, destroy it and deref later + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + } while (FALSE); + + if (RequestManager != NULL) + { + MbbReqMgrDeref(RequestManager); + } + if (Request != NULL) + { + MbbReqMgrDerefRequest(Request); + } + return NdisStatus; +} + +VOID +AdapterPauseHandler( + PSTATE_CHANGE_EVENT StateChange + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; + BOOLEAN StopSendQueue=FALSE; + BOOLEAN NoOustandingNBLs=FALSE; + + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + if (FastIOPause(StateChange)) + { + return; + } + + NdisAcquireSpinLock(&Adapter->Lock); + + ASSERT(Adapter->AdapterState.Started); + + Adapter->AdapterState.Started=FALSE; + + + // + // add one for this routine running now + // + Adapter->AdapterState.PendingActions++; + + // + // power changes don't effect the receive control, so we stop it now + // + NoOustandingNBLs=TRUE; + Adapter->AdapterState.PendingActions++; + + + if (Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) + { + // + // if the device is powered, + // stop everything + // + StopSendQueue=TRUE; + Adapter->AdapterState.PendingActions++; + } + else + { + // + // not powered, The send queue is already stopped + // + + } + + Adapter->AdapterState.RunningEvent=StateChange; + + NdisReleaseSpinLock(&Adapter->Lock); + + if (StopSendQueue) + { + MbbSendQCancel( + &Adapter->SendQueue, + NDIS_STATUS_PAUSED, + TRUE + ); + + // + // stop the pipes and cancel the io + // + MbbBusStopDataPipes(Adapter->BusHandle); + + } + + if (NoOustandingNBLs) + { + MbbRecvQCancel( + &Adapter->ReceiveQueue, + NDIS_STATUS_PAUSED, + TRUE + ); + } + + + + // + // call this to remove the pending action count added above + // + DrainCompleteCallback(Adapter); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; +} + + +VOID +AdapterRestartHandler( + PSTATE_CHANGE_EVENT StateChange + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; + NTSTATUS Status=STATUS_SUCCESS; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + if (FastIORestart(StateChange)) + { + return; + } + + if (Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) + { + Status=MbbBusStartDataPipes(Adapter->BusHandle); + + if (NT_SUCCESS(Status)) + { + + // + // powered up, start send queue + // + DrainComplete( &(Adapter->SendQueue.QueueDrainObject) ); + } + } + + // + // always enable receive control because power does not touch it + // + DrainComplete( &(Adapter->ReceiveQueue.QueueDrainObject) ); + + Adapter->AdapterState.Started=TRUE; + + CompleteStateChange( + &Adapter->AdapterState, + StateChange + ); + + StateChange=NULL; + + TraceInfo(WMBCLASS_INIT, "Calling NdisMRestartComplete()"); + + MbbWriteEvent( + &RESTART_COMPLETE_EVENT, + NULL, + NULL, + 2, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &Status, + sizeof(Status) + ); + + + NdisMRestartComplete(Adapter->MiniportAdapterHandle, Status); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); +} + + +VOID +AdapterPowerHandler( + PSTATE_CHANGE_EVENT StateChange + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; + BOOLEAN StartSendQueue=FALSE; + BOOLEAN StopSendQueue=FALSE; + NET_DEVICE_POWER_STATE PreviousPowerState; + BOOLEAN FullPower=FALSE; + NTSTATUS Status=STATUS_SUCCESS; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + NdisAcquireSpinLock(&Adapter->Lock); + + + PreviousPowerState=Adapter->AdapterState.CurrentPowerState; + Adapter->AdapterState.CurrentPowerState = StateChange->Power.NewPower; + + if (StateChange->Power.NewPower == NetDeviceStateD0) + { + // + // full power + // + if (Adapter->AdapterState.Started) + { + StartSendQueue=TRUE; + } + FullPower=TRUE; + + } + else + { + // + // reduced power + // + ASSERT(Adapter->AdapterState.PendingActions == 0); + + FullPower=FALSE; + + if (Adapter->AdapterState.Started && MbbBusIsFastIO(Adapter->BusHandle) == FALSE) + { + // + // started, stop the send queue + // + StopSendQueue=TRUE; + Adapter->AdapterState.PendingActions++; + + } + + Adapter->AdapterState.PendingActions++; + + } + + NdisReleaseSpinLock(&Adapter->Lock); + + + if (FullPower) + { + // + // D0 + // + + if (PreviousPowerState == NetDeviceStateD3) + { + do + { + // + // device was in d3, open it again + // + Status = MbbBusOpen(Adapter->BusHandle, MbbLibraryGetNextTransactionId(), FastIOSendNetBufferListsComplete, FastIOIndicateReceiveNetBufferLists); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] MbbBusOpen() with %!STATUS!", Status); + break; + } + + // + // opened, make sure the radio is in the right state + // + Status = MbbAdapterConfigureRadioState( Adapter ); + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "D0 power up FAILED to ConfigureRadioState, status=%!STATUS!. Reset data pipe as workaround for surface in order to reset modem", Status); + MbbBusResetBulkPipe(Adapter->BusHandle, TRUE); + + TraceLoggingWrite( + g_hLoggingProvider, + "MbbPipeReset", + TraceLoggingString("PowerHandler", "ResetType"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + + break; + } + + // send an indication to service indicating we are out of D3 + MbbAdapterIndicateD3Exit(Adapter, NDIS_DEFAULT_PORT_NUMBER); //always indicate on port 0 + }while(FALSE); + + if(NT_ERROR(Status)) + { + NdisMRemoveMiniport( + Adapter->MiniportAdapterHandle + ); + } + } + + if (StartSendQueue && MbbBusIsFastIO(Adapter->BusHandle) == FALSE) + { + // + // re-enable the send queue + // + + DrainComplete( &(Adapter->SendQueue.QueueDrainObject) ); + + if NT_SUCCESS(Status) + { + + MbbBusStartDataPipes(Adapter->BusHandle); + } + } + + + Adapter->LastLowSystemPowerState.TargetSystemState = PowerSystemWorking; + Adapter->LastLowSystemPowerState.EffectiveSystemState = PowerSystemWorking; + + MbbBusSetNotificationState(Adapter->BusHandle, TRUE); + + MbbAdapterConfigurePacketFilters(Adapter, FALSE); + + MbbAdapterConfigureDeviceServiceSubscription(Adapter, TRUE, 0, 0); + + TraceInfo(WMBCLASS_INIT, "Completing set power request"); + + // + // done + // + MbbReqMgrQueueEvent( + StateChange->Power.Request->RequestManager, + StateChange->Power.Request, + MbbRequestEventSendComplete, + (PVOID)(NDIS_STATUS_SUCCESS), + 0 + ); + + + CompleteStateChange( + &Adapter->AdapterState, + StateChange + ); + + StateChange=NULL; + } + else + { + // + // low power + // + Adapter->AdapterState.RunningEvent=StateChange; + + if (StopSendQueue) + { + + MbbSendQCancel( + &Adapter->SendQueue, + NDIS_STATUS_PAUSED, + TRUE + ); + + MbbBusStopDataPipes(Adapter->BusHandle); + } + + if ((PreviousPowerState == NetDeviceStateD0) && (Adapter->AdapterState.CurrentPowerState == NetDeviceStateD3)) + { + if (Adapter->LastLowSystemPowerState.TargetSystemState > PowerSystemSleeping3) + { + // when the system supports hibernate and user requests shutdown, the system will try + // hibernate first rather than full shutdown. + // That is, (TargetSysState: PowerSystemShutdown, EffectiveSysState: PowerSystemHibernate) + if (Adapter->LastLowSystemPowerState.EffectiveSystemState == PowerSystemHibernate) + { + // If the suspend event is S4, the network device would power off + // send preshutdown to make it cleanup in case the device is flashless. + // We don't send it for S5 here because S5 is handled by OID request from wwansvc + MbbAdapterSendPreShutdown(Adapter); + } + // + // only send in the case the sleep is greater than S3 + // + MbbAdapterSendNetworkShutdownHint(Adapter); + } + + MbbBusSetNotificationState(Adapter->BusHandle, FALSE); + + MbbBusClose(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FALSE); + } + else + { + MbbBusSetNotificationState(Adapter->BusHandle, FALSE); + } + + // + // the request will be completed when the drain has completed + // + DrainCompleteCallback(Adapter); + + + } + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; + + +} + +VOID +AdapterResetHandler( + PSTATE_CHANGE_EVENT StateChange + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; + BOOLEAN StopSendQueue=FALSE; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + if (FastIOReset(StateChange)) + { + return; + } + // + // add one for this routing running now + // + Adapter->AdapterState.PendingActions++; + + + if ((Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) && Adapter->AdapterState.Started) + { + // + // if the device is powered and started + // stop everything + // + StopSendQueue=TRUE; + Adapter->AdapterState.PendingActions++; + } + else + { + // + // not powered, The send queue is already stopped + // + + } + + StateChange->Reset.PipeStartStatus=STATUS_SUCCESS; + + if (StopSendQueue) + { + MbbSendQCancel( + &Adapter->SendQueue, + NDIS_STATUS_PAUSED, + TRUE + ); + + // + // stop and start the pipes to cancel any io + // + MbbBusStopDataPipes(Adapter->BusHandle); + + StateChange->Reset.PipeStartStatus = MbbBusResetBulkPipe(Adapter->BusHandle, TRUE); + + TraceLoggingWrite( + g_hLoggingProvider, + "MbbPipeReset", + TraceLoggingString("ResetHandler", "ResetType"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + + MbbBusStartDataPipes(Adapter->BusHandle); + + } + + Adapter->AdapterState.RunningEvent=StateChange; + + // + // call this to remove the pending action count add above + // + DrainCompleteCallback(Adapter); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; + + +} + +VOID +AdapterStallClearHandler( + PSTATE_CHANGE_EVENT StateChange + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; + BOOLEAN StartSendQueue=FALSE; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + NdisAcquireSpinLock(&Adapter->Lock); + // + // add one for this routine running now + // + Adapter->AdapterState.PendingActions++; + + + if ((Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) && Adapter->AdapterState.Started) + { + // + // if the device is powered and started + // stop everything + // + StartSendQueue=TRUE; + Adapter->AdapterState.PendingActions++; + } + else + { + // + // not powered, The send queue is already stopped + // + + } + NdisReleaseSpinLock(&Adapter->Lock); + + if(StartSendQueue) + { + MbbSendQCancel( + &Adapter->SendQueue, + NDIS_STATUS_PAUSED, + TRUE + ); + } + + // + // stop and start the pipes to cancel any io + // + MbbBusStopDataPipes(Adapter->BusHandle); + + MbbBusResetBulkPipe(Adapter->BusHandle, TRUE); + + TraceLoggingWrite( + g_hLoggingProvider, + "MbbPipeReset", + TraceLoggingString("StallClearHandler", "ResetType"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + + if (StartSendQueue) + { + MbbBusStartDataPipes(Adapter->BusHandle); + DrainComplete(&(Adapter->SendQueue.QueueDrainObject)); + } + + Adapter->AdapterState.RunningEvent=StateChange; + // + // call this to remove the pending action count add above + // + DrainCompleteCallback(Adapter); + + return; + + +} + + + + +NTSTATUS +InitAdapterStateObject( + __out PADAPTER_STATE AdapterState, + __in NDIS_HANDLE MiniportAdapterContext, + MBB_STATE_CHANGE_HANDLER PauseHandler, + MBB_STATE_CHANGE_HANDLER RestartHandler, + MBB_STATE_CHANGE_HANDLER PowerHandler, + MBB_STATE_CHANGE_HANDLER ResetHandler, + MBB_STATE_CHANGE_HANDLER StallClearHandler + ) + +{ + ULONG i; + + RtlZeroMemory(AdapterState, sizeof(*AdapterState)); + + // + // device is power to start with + // + AdapterState->CurrentPowerState=NetDeviceStateD0; + + AdapterState->Handlers[STATE_CHANGE_TYPE_PAUSE] = PauseHandler; + AdapterState->Handlers[STATE_CHANGE_TYPE_RESTART] = RestartHandler; + AdapterState->Handlers[STATE_CHANGE_TYPE_POWER] = PowerHandler; + AdapterState->Handlers[STATE_CHANGE_TYPE_RESET] = ResetHandler; + AdapterState->Handlers[STATE_CHANGE_TYPE_STALL_CLEAR] = StallClearHandler; + + InitializeListHead(&AdapterState->FreeList); + + + + InitializeListHead(&AdapterState->ListEntry); + AdapterState->CurrentEvent=NULL; + + KeInitializeEvent( + &AdapterState->StallClearCompleteEvent, + NotificationEvent, + TRUE + ); + + NdisAllocateSpinLock(&AdapterState->Lock); + + for (i=0; i< STATE_CHANGE_EVENT_RESERVE_COUNT; i++) + { + + PSTATE_CHANGE_EVENT StateChange=NULL; + + StateChange=ALLOCATE_NONPAGED_POOL(sizeof(*StateChange)); + + if (StateChange != NULL) + { + + NdisAcquireSpinLock(&AdapterState->Lock); + + InsertHeadList(&AdapterState->FreeList, &StateChange->ListEntry); + StateChange=NULL; + + NdisReleaseSpinLock(&AdapterState->Lock); + + } + else + { + return STATUS_INSUFFICIENT_RESOURCES; + } + } + + + AdapterState->WorkItem=NdisAllocateIoWorkItem(MiniportAdapterContext); + + if (AdapterState->WorkItem == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + return STATUS_SUCCESS; + +} + +VOID +ShutdownAdapterStateObject( + PADAPTER_STATE AdapterState + ) + +{ + PSTATE_CHANGE_EVENT StateChange=NULL; + + ASSERT(AdapterState->CurrentEvent == NULL); + ASSERT(IsListEmpty(&AdapterState->ListEntry)); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + AdapterState->ShuttingDown=TRUE; + + StateChange=AllocateStateChangeEvent(AdapterState); + + while (StateChange != NULL) + { + FREE_POOL(StateChange); + StateChange=NULL; + + StateChange=AllocateStateChangeEvent(AdapterState); + } + + if (AdapterState->WorkItem != NULL) + { + NdisFreeIoWorkItem(AdapterState->WorkItem); + AdapterState->WorkItem=NULL; + } + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; + +} + + + +VOID +AdapterStateWorkitemRoutine( + PVOID WorkItemContext, + NDIS_HANDLE WorkItemHandle + ) + +{ + PADAPTER_STATE AdapterState=(PADAPTER_STATE)WorkItemContext; + PSTATE_CHANGE_EVENT StateChange=AdapterState->CurrentEvent; + + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + if (StateChange->EventType < STATE_CHANGE_MAX && StateChange->EventType >= 0) + { + (*AdapterState->Handlers[StateChange->EventType])(StateChange); + } + else + { + ASSERT(0); + } + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; + +} + + +VOID +ProcessStateChangeQueue( + PADAPTER_STATE AdapterState + ) + +{ + PLIST_ENTRY ListEntry=NULL; + PSTATE_CHANGE_EVENT StateChangeEvent=NULL; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!:Entered"); + + NdisAcquireSpinLock(&AdapterState->Lock); + + if (AdapterState->CurrentEvent == NULL) + { + // + // queue is idle + // + if (!IsListEmpty(&AdapterState->ListEntry)) + { + // + // more item to run + // + ListEntry=RemoveTailList(&AdapterState->ListEntry); + + StateChangeEvent=CONTAINING_RECORD(ListEntry, STATE_CHANGE_EVENT, ListEntry); + + AdapterState->CurrentEvent=StateChangeEvent; + + TraceInfo(WMBCLASS_INIT, "Queuing work item"); + + NdisQueueIoWorkItem(AdapterState->WorkItem, AdapterStateWorkitemRoutine, AdapterState); + + } + } + + + NdisReleaseSpinLock(&AdapterState->Lock); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; + + + +} + +VOID +QueueStateChangeEvent( + PADAPTER_STATE AdapterState, + PSTATE_CHANGE_EVENT StateChange + ) + +{ + + TraceInfo(WMBCLASS_INIT, "%!FUNC!:Entered"); + + NdisAcquireSpinLock(&AdapterState->Lock); + + InsertHeadList(&AdapterState->ListEntry, &StateChange->ListEntry); + + + NdisReleaseSpinLock(&AdapterState->Lock); + + ProcessStateChangeQueue(AdapterState); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; +} + + + +VOID +CompleteStateChange( + PADAPTER_STATE AdapterState, + PSTATE_CHANGE_EVENT StateChange + ) + + +{ + TraceInfo(WMBCLASS_INIT, "%!FUNC!:Entered"); + + NdisAcquireSpinLock(&AdapterState->Lock); + + ASSERT(AdapterState->CurrentEvent == StateChange); + + AdapterState->CurrentEvent=NULL; + + NdisReleaseSpinLock(&AdapterState->Lock); + + FreeStateChangeEvent(AdapterState, StateChange); + + ProcessStateChangeQueue(AdapterState); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + +} + +PSTATE_CHANGE_EVENT +AllocateStateChangeEvent( + PADAPTER_STATE AdapterState + ) + +{ + PLIST_ENTRY ListEntry=NULL; + PSTATE_CHANGE_EVENT StateChangeEvent=NULL; + + NdisAcquireSpinLock(&AdapterState->Lock); + + if (!IsListEmpty(&AdapterState->FreeList)) + { + // + // more item to run + // + ListEntry=RemoveTailList(&AdapterState->FreeList); + + StateChangeEvent=CONTAINING_RECORD(ListEntry, STATE_CHANGE_EVENT, ListEntry); + + RtlZeroMemory(StateChangeEvent, sizeof(*StateChangeEvent)); + } + else + { + if (!AdapterState->ShuttingDown) + { + ASSERT(0); + } + } + + NdisReleaseSpinLock(&AdapterState->Lock); + + + return StateChangeEvent; + +} + + +VOID +FreeStateChangeEvent( + PADAPTER_STATE AdapterState, + PSTATE_CHANGE_EVENT StateChange + ) + +{ + NdisAcquireSpinLock(&AdapterState->Lock); + + InsertHeadList(&AdapterState->FreeList, &StateChange->ListEntry); + StateChange=NULL; + + NdisReleaseSpinLock(&AdapterState->Lock); + + return; + +} + +VOID +FreeDeviceServiceState( + __in PMBB_DS_STATE DeviceServiceState + ) +{ + PMBB_DS DeviceService; + ULONG* CIDList; + ULONG i; + + if (DeviceServiceState->ExtSubscribeList != NULL) + FREE_POOL(DeviceServiceState->ExtSubscribeList); + + if (DeviceServiceState->ServicesList != NULL) + { + // Free each device service entry + for (i = 0; i < DeviceServiceState->ServicesCount; i++) + { + DeviceService = &(DeviceServiceState->ServicesList[i]); + + // Free the CID list + if (DeviceService->CIDList != NULL) + FREE_POOL(DeviceService->CIDList); + } + + // Free the device services list structure + FREE_POOL(DeviceServiceState->ServicesList); + } + + return; +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetMultiCarrierCapable( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN IsMultiCarrierSupported + ) +{ + MbbAdapterLock( Adapter ); + Adapter->AdapterFlags.IsMultiCarrier = IsMultiCarrierSupported; + MbbAdapterUnlock( Adapter ); +} + + _Requires_lock_not_held_(&Adapter->Lock) +BOOLEAN +MbbAdapterIsMultiCarrierCapable( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + BOOLEAN IsMultiCarrierSupported; + + MbbAdapterLock( Adapter ); + IsMultiCarrierSupported = (Adapter->AdapterFlags.IsMultiCarrier == 1); + MbbAdapterUnlock( Adapter ); + + return IsMultiCarrierSupported; +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetDataClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in ULONG DataClass + ) +{ + MbbAdapterLock( Adapter ); + Adapter->AdapterDataClass = DataClass; + MbbAdapterUnlock( Adapter ); +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterGetDataClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __out ULONG* DataClass + ) +{ + MbbAdapterLock( Adapter ); + *DataClass = Adapter->AdapterDataClass; + MbbAdapterUnlock( Adapter ); +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetSupportedCellularClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_CELLULAR_CLASS CellularClass + ) +{ + MbbAdapterLock( Adapter ); + Adapter->AdapterSupportedCellularClass = CellularClass; + MbbAdapterUnlock( Adapter ); +} + +_Requires_lock_not_held_(&Adapter->Lock) +MBB_CELLULAR_CLASS +MbbAdapterGetSupportedCellularClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + MBB_CELLULAR_CLASS CellularClass; + + MbbAdapterLock( Adapter ); + CellularClass = Adapter->AdapterSupportedCellularClass; + MbbAdapterUnlock( Adapter ); + return CellularClass; +} + +_Requires_lock_not_held_(&Adapter->Lock) +BOOLEAN +MbbAdapterIsMultimodeCapable( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + ULONG BitValue; + + MbbAdapterLock( Adapter ); + BitValue = (ULONG)(Adapter->AdapterSupportedCellularClass); + MbbAdapterUnlock( Adapter ); + // + // If only a single bit is set then the following expression + // should be zero. Otherwise this will be set to the "other" bits. + // + if( (BitValue & (BitValue - 1)) != 0 ) + return TRUE; + else + return FALSE; +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetCurrentCellularClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_CELLULAR_CLASS CellularClass + ) +{ + MbbAdapterLock( Adapter ); + Adapter->AdapterCurrentCellularClass = CellularClass; + MbbAdapterUnlock( Adapter ); +} + +_Requires_lock_not_held_(&Adapter->PortsLock) +VOID +MbbAdapterSetMaxActivatedContexts( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in ULONG dwMaxActivatedContexts + ) +{ + ASSERT(dwMaxActivatedContexts >= 1); + MbbAdapterPortsLock(Adapter); + Adapter->MaxActivatedContexts = (dwMaxActivatedContexts < MBB_MAX_NUMBER_OF_PORTS) ? dwMaxActivatedContexts: MBB_MAX_NUMBER_OF_PORTS; + MbbAdapterPortsUnlock(Adapter); +} + + +_Requires_lock_not_held_(&Adapter->Lock) +MBB_CELLULAR_CLASS +MbbAdapterGetCurrentCellularClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + MBB_CELLULAR_CLASS CellularClass; + + MbbAdapterLock( Adapter ); + CellularClass = Adapter->AdapterCurrentCellularClass; + MbbAdapterUnlock( Adapter ); + return CellularClass; +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetRequestManager( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_REQUEST_MANAGER RequestManager + ) +{ + MbbAdapterLock( Adapter ); + Adapter->RequestManager = RequestManager; + MbbAdapterUnlock( Adapter ); +} + +_Requires_lock_not_held_(&Adapter->Lock) +PMBB_REQUEST_MANAGER +MbbAdapterGetRequestManager( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +/*++ +Description + Synchronizes access to request manager with its lifetime. + Try to return a valid request manager reference. + Caller is required to derefernce the request manager. + +Return Value + non-NULL + Request Manager is successfully returned. + NULL + Request Manager is not initialized or could not be referenced. +--*/ +{ + PMBB_REQUEST_MANAGER RequestManager = NULL; + + MbbAdapterLock( Adapter ); + if( Adapter->RequestManager && + MbbReqMgrRef( Adapter->RequestManager ) ) + { + RequestManager = Adapter->RequestManager; + } + MbbAdapterUnlock( Adapter ); + + return RequestManager; +} + +_Requires_lock_not_held_(&Adapter->Lock) +NDIS_STATUS +MbbAdapterQueryDeviceId( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_DEVICE_CAPS }; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for QueryDeviceCaps" ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for QueryDeviceCaps" ); + break; + } + Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + + // + // Ref the request so that the response handler does not free it + // + MbbReqMgrRefRequest( Request ); + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbUtilInternalCIDQuery, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If the request is pending wait for it to complete. + // If the request didnt complete within the timeout period drop our ref count and fail to the caller. + // Something is wrong with a device that does not send response for a non-network request + // If dispatching the request failed then our completion callback will not be invoked, + // in this case destroy the request. + // + if( NdisStatus == NDIS_STATUS_PENDING ) + { + Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; + NdisStatus = KeWaitForSingleObject( + &Request->WaitEvent, + Executive, + KernelMode, + TRUE, // Alertable + &Timeout // Timeout + ); + if( NdisStatus != STATUS_WAIT_0 ) + { + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + // + // Only if Send was successful then get the response status. + // + if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) + NdisStatus = Request->HandlerContext.Response.NdisStatus; + } + } + else if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + // + // It is ok to destroy the request here and deref it later. + // Destroy will not free the request while there is a pending ref. + // + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + + if( NdisStatus == NDIS_STATUS_SUCCESS ) + { + PCHAR pDeviceId = (PCHAR)(Request->HandlerContext.Parameters.DeviceCaps.DeviceId); + CHAR cOctet[MBB_MAC_ADDRESS_LENGTH]; + ULONG ulOctetIndex; + + RtlZeroMemory( + cOctet, + MBB_MAC_ADDRESS_LENGTH + ); + + // + // XOR the bytes to get a 6-byte MAC + // Left shift is done for more randomization. + // + for(ulOctetIndex = 0; + pDeviceId[ulOctetIndex*2]; + ulOctetIndex++ ) + { + cOctet[ulOctetIndex % MBB_MAC_ADDRESS_LENGTH] ^= ( pDeviceId[ulOctetIndex*2] << (ulOctetIndex / MBB_MAC_ADDRESS_LENGTH) ); + } + + // + // Mask of the multicast and locally administered bit + // + cOctet[0] &= ~0x03; + + RtlCopyMemory( + Adapter->MACAddress, + cOctet, + MBB_MAC_ADDRESS_LENGTH + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + if( Request != NULL ) + { + MbbReqMgrDerefRequest( Request ); + } + return NdisStatus; +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterResetCapabilities( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + MbbAdapterLock( Adapter ); + Adapter->AdapterFlags.IsUssdCapable = FALSE; + Adapter->AdapterFlags.IsSimAuthCapable = FALSE; + Adapter->AdapterFlags.IsAkaAuthCapable = FALSE; + Adapter->AdapterFlags.IsAkapAuthCapable = FALSE; + MbbAdapterUnlock( Adapter ); +} + +NDIS_STATUS +MbbAdapterQueryMultiCarrierDsCidList( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in const GUID* Guid, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus; + LARGE_INTEGER Timeout; + PMBB_REQUEST_CONTEXT NewRequest = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + PMBB_DS MbbDs; + MBB_COMMAND Command = { + MBB_UUID_MULTICARRIER_CONSTANT, + MBB_MULTICARRIER_CID_CURRENT_CID_LIST + }; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED to reference RequestManager", Request->RequestId ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + if( (NewRequest = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED to allocate RequestContext", Request->RequestId ); + break; + } + NewRequest->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + // + // Cache the context from the previous request since it will be destroyed + // + NewRequest->OidContext.OidRequestId = Request->OidContext.OidRequestId; + NewRequest->OidContext.OidRequestHandle = Request->OidContext.OidRequestHandle; + NewRequest->HandlerContext.Parameters.DeviceCaps= Request->HandlerContext.Parameters.DeviceCaps; + + TraceInfo( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x][ReqId=0x%04x] Request created to query CID list for DS=%!GUID!", Request->RequestId, NewRequest->RequestId, Guid ); + + MBB_UUID_TO_NET( + &NewRequest->HandlerContext.Parameters.DeviceCaps.CurrentQueriedDeviceService, + Guid + ); + + NdisStatus = MbbReqMgrDispatchRequest( + NewRequest, + (TRUE == Request->OidHandler->IsSerialized), + MbbUtilInternalCIDQuery, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + if( NdisStatus != NDIS_STATUS_PENDING && + NdisStatus != NDIS_STATUS_INDICATION_REQUIRED ) + { + // + // It is ok to destroy the request here and deref it later. + // Destroy will not free the request while there is a pending ref. + // + MbbReqMgrDestroyRequest( + NewRequest->RequestManager, + NewRequest + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + RequestManager = NULL; + } + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterMultiCarrierDeviceServicesToCapabilities( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + do + { + if( Request->HandlerContext.Parameters.DeviceCaps.IsUssdCapsValid == 0 ) + { + NdisStatus = MbbAdapterQueryMultiCarrierDsCidList( + Adapter, + &MBB_UUID_USSD, + Request + ); + if( NDIS_STATUS_SUCCESS != NdisStatus && + NDIS_STATUS_PENDING != NdisStatus ) + { + TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED MbbAdapterQueryMultiCarrierDsCidList(USSD)=%!STATUS!", Request->RequestId, NdisStatus ); + break; + } + } + else if( Request->HandlerContext.Parameters.DeviceCaps.IsAuthCapsValid == 0 ) + { + NdisStatus = MbbAdapterQueryMultiCarrierDsCidList( + Adapter, + &MBB_UUID_AUTH, + Request + ); + if( NDIS_STATUS_SUCCESS != NdisStatus && + NDIS_STATUS_PENDING != NdisStatus ) + { + TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED MbbAdapterQueryMultiCarrierDsCidList(AUTH)=%!STATUS!", Request->RequestId, NdisStatus ); + break; + } + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbAdapterSingleCarrierDeviceServicesToCapabilities( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + ULONG CidIndex; + PMBB_DS MbbDs; + + MbbDs = MbbUtilFindDeviceService( + Adapter, + (GUID*)&MBB_UUID_USSD + ); + if( MbbDs != NULL ) + { + MbbAdapterLock( Adapter ); + Adapter->AdapterFlags.IsUssdCapable = TRUE; + MbbAdapterUnlock( Adapter ); + } + + MbbDs = MbbUtilFindDeviceService( + Adapter, + (GUID*)&MBB_UUID_AUTH + ); + if( MbbDs != NULL ) + { + MbbAdapterLock( Adapter ); + for(CidIndex = 0; + CidIndex < MbbDs->CIDCount; + CidIndex++ ) + { + switch( MbbDs->CIDList[CidIndex] ) + { + case MBB_AUTH_CID_AKA: + { + Adapter->AdapterFlags.IsAkaAuthCapable = TRUE; + } + break; + + case MBB_AUTH_CID_AKAP: + { + Adapter->AdapterFlags.IsAkapAuthCapable = TRUE; + } + break; + + case MBB_AUTH_CID_SIM: + { + Adapter->AdapterFlags.IsSimAuthCapable = TRUE; + } + break; + } + } + MbbAdapterUnlock( Adapter ); + } + Request->HandlerContext.Parameters.DeviceCaps.IsUssdCapsValid = 1; + Request->HandlerContext.Parameters.DeviceCaps.IsAuthCapsValid = 1; + return NDIS_STATUS_SUCCESS; +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetShutdownNotificationCapabilities( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + ULONG CidIndex; + PMBB_DS MbbDs; + + MbbDs = MbbUtilFindDeviceService( + Adapter, + (GUID*)&MBB_UUID_HOSTSHUTDOWN + ); + if (MbbDs != NULL) + { + MbbAdapterLock(Adapter); + for (CidIndex = 0; + CidIndex < MbbDs->CIDCount; + CidIndex++) + { + switch (MbbDs->CIDList[CidIndex]) + { + case MBB_HOSTSHUTDOWN_CID_ONE: + { + Adapter->AdapterFlags.ShutdownNotificationCapable = TRUE; + } + break; + + case MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN: + { + Adapter->AdapterFlags.IsPreshutdownCapable = TRUE; + } + break; + } + } + MbbAdapterUnlock(Adapter); + } + + return; +} + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetOptionalServiceSupport( + __in PMINIPORT_ADAPTER_CONTEXT Adapter +) +{ + ULONG CidIndex; + PMBB_DS MbbDs; + + MbbDs = MbbUtilFindDeviceService( + Adapter, + (GUID*)&MBB_UUID_BASIC_CONNECT_EXTENSIONS + ); + if (MbbDs != NULL) + { + MbbAdapterLock(Adapter); + for (CidIndex = 0; + CidIndex < MbbDs->CIDCount; + CidIndex++) + { + switch (MbbDs->CIDList[CidIndex]) + { + case MBB_BASICCONNECTEXT_CID_PROVISIONED_CONTEXT_V2: + { + Adapter->AdapterFlags.IsProvisionedContextV2Capable = TRUE; + } + break; + + case MBB_BASICCONNECTEXT_CID_NETWORK_BLACKLIST: + { + Adapter->AdapterFlags.IsNetworkBlacklistCapable = TRUE; + } + break; + + case MBB_BASICCONNECTEXT_CID_LTE_ATTACH_CONFIG: + { + Adapter->AdapterFlags.IsLTEAttachConfigCapable = TRUE; + } + break; + + case MBB_BASICCONNECTEXT_CID_DEVICE_SLOT_MAPPINGS: + { + Adapter->AdapterFlags.IsMultiSIMCapable = TRUE; + } + break; + + case MBB_BASICCONNECTEXT_CID_DEVICE_CAPS_V2: + { + Adapter->AdapterFlags.IsDeviceCapsV2Capable = TRUE; + } + break; + + case MBB_BASICCONNECTEXT_CID_PCO: + { + Adapter->AdapterFlags.IsPcoCapable = TRUE; + } + break; + + case MBB_BASICCONNECTEXT_CID_DEVICE_RESET: + { + Adapter->AdapterFlags.IsDeviceResetCapable = TRUE; + } + break; + + case MBB_BASICCONNECTEXT_CID_BASE_STATIONS_INFO: + { + Adapter->AdapterFlags.IsBaseStationsInfoCapable = TRUE; + } + break; + + } + } + MbbAdapterUnlock(Adapter); + } + + MbbDs = MbbUtilFindDeviceService( + Adapter, + (GUID*)&MBB_UUID_SARCONTROL + ); + if (MbbDs != NULL) + { + MbbAdapterLock(Adapter); + for (CidIndex = 0; + CidIndex < MbbDs->CIDCount; + CidIndex++) + { + switch (MbbDs->CIDList[CidIndex]) + { + case MBB_SAR_CID_CONFIG: + { + Adapter->AdapterFlags.IsSARCapable = TRUE; + } + break; + } + } + MbbAdapterUnlock(Adapter); + } + + MbbDs = MbbUtilFindDeviceService( + Adapter, + (GUID*)&MBB_UUID_UICC_LOW_LEVEL + ); + if (MbbDs != NULL) + { + MbbAdapterLock(Adapter); + for (CidIndex = 0; + CidIndex < MbbDs->CIDCount; + CidIndex++) + { + switch (MbbDs->CIDList[CidIndex]) + { + case MBB_UICC_CID_ATR: + { + // if this CID is supported, the entire group of MBB_UUID_UICC_LOW_LEVEL CIDs must be supported. + Adapter->AdapterFlags.IsUiccLowLevelCapable = TRUE; + } + break; + } + } + MbbAdapterUnlock(Adapter); + } + + return; +} + +_Requires_lock_not_held_(&Adapter->Lock) +NDIS_STATUS +MbbAdapterFWDeviceServicesToCapabilities( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_REQUEST_CONTEXT Request + ) +/*++ +Description: + Check whether the optional multi-carrier + device service is implemented by the device. The presence + of the multi-carrier device service indicates that this + is a multi-carrier device. This method is called from + device caps query path. +--*/ +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PNDIS_WWAN_DEVICE_CAPS NdisDeviceCaps = Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCaps; + + do + { + // + //If this is not a multi-carrier device then get + //get the supported native device services from the + //device services. If this is a multi-carrier device + //find the support for USSD and AUTH. + // + if( NdisDeviceCaps->DeviceCaps.WwanControlCaps & WWAN_CTRL_CAPS_MODEL_MULTI_CARRIER ) + { + NdisStatus = MbbAdapterMultiCarrierDeviceServicesToCapabilities( Adapter, Request ); + if( NDIS_STATUS_SUCCESS != NdisStatus && + NDIS_STATUS_PENDING != NdisStatus ) + { + TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED MbbAdapterMultiCarrierDeviceServicesToCapabilities()=%!STATUS!", Request->RequestId, NdisStatus ); + break; + } + } + else + { + NdisStatus = MbbAdapterSingleCarrierDeviceServicesToCapabilities( Adapter, Request ); + if( NDIS_STATUS_SUCCESS != NdisStatus && + NDIS_STATUS_PENDING != NdisStatus ) + { + TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED MbbAdapterSingleCarrierDeviceServicesToCapabilities()=%!STATUS!", Request->RequestId, NdisStatus ); + break; + } + } + } + while( FALSE ); + + return NdisStatus; +} + +_Requires_lock_not_held_(&SendQueue->AdapterContext->Lock) +VOID TryQueueStallState(_In_ PMBB_SEND_QUEUE SendQueue) +{ + PSTATE_CHANGE_EVENT StateChange = NULL; + + MbbAdapterLock(SendQueue->AdapterContext); + + if (!SendQueue->AdapterContext->AdapterState.Hung) + { + StateChange = AllocateStateChangeEvent(&SendQueue->AdapterContext->AdapterState); + + if (StateChange != NULL) + { + SendQueue->AdapterContext->AdapterState.Hung = TRUE; + + StateChange->EventType = STATE_CHANGE_TYPE_STALL_CLEAR; + StateChange->Context1 = SendQueue->AdapterContext; + + TraceInfo(WMBCLASS_OID, "%!FUNC!: Reset data pipe has been scheduled"); + KeResetEvent(&SendQueue->AdapterContext->AdapterState.StallClearCompleteEvent); + QueueStateChangeEvent(&SendQueue->AdapterContext->AdapterState, StateChange); + + } + else + { + TraceError(WMBCLASS_OID, "%!FUNC!: Reset data pipe isn't scheduled since AllocateStateChangeEvent failed"); + } + } + else + { + TraceError(WMBCLASS_OID, "%!FUNC!: Skip reset data pipe since it has already been scheduled, "); + } + + MbbAdapterUnlock(SendQueue->AdapterContext); +} + +VOID WaitStallClearComplete( + _In_ PADAPTER_STATE AdapterState +) +{ + if (AdapterState->WorkItem != NULL) + { + KeWaitForSingleObject( + &AdapterState->StallClearCompleteEvent, + Executive, + KernelMode, + FALSE, // Alertable + NULL // Timeout + ); + } +} \ No newline at end of file diff --git a/network/wwan/cxwmbclass/adapter.h b/network/wwan/cxwmbclass/adapter.h new file mode 100644 index 000000000..0e9b7cf38 --- /dev/null +++ b/network/wwan/cxwmbclass/adapter.h @@ -0,0 +1,337 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +typedef struct _WWAN_IP_ADDRESS_STATE WWAN_IP_ADDRESS_STATE; +// +// Adapter routines +// +_Acquires_lock_( Adapter->Lock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterLock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Releases_lock_( Adapter->Lock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterUnlock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Acquires_lock_( Adapter->PortsLock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterPortsLock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Releases_lock_( Adapter->PortsLock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterPortsUnlock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Acquires_lock_( Adapter->SessionIdPortTableLock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterSessionIdPortTableLock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Releases_lock_( Adapter->SessionIdPortTableLock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) +VOID +MbbAdapterSessionIdPortTableUnlock( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + + +BOOLEAN +MbbAdapterIsReady( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +VOID +MbbAdapterConnectionChange( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in PMBB_CONNECTION_STATE ConnectionState, + __in NDIS_PORT_NUMBER PortNumber + ); + +VOID +MbbAdapterSetConnectionState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_CONNECTION_STATE ConnectionState, + __in NDIS_PORT_NUMBER PortNumber + ); + +VOID +MbbAdapterSetLinkState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_CONNECTION_STATE ConnectionState, + __in NDIS_PORT_NUMBER PortNumber + ); + +VOID +MbbAdapterSetPortState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_CONNECTION_STATE ConnectionState, + __in NDIS_PORT_NUMBER PortNumber + ); + +VOID +MbbPortSetIpAddressState( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PWWAN_IP_ADDRESS_STATE WwanIpAddressState, + __in NDIS_PORT_NUMBER PortNumber + ); + +BOOLEAN +MbbPortIsConnected( + __in PMBB_PORT Port + ); + +VOID +MbbAdapterRef( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +VOID +MbbAdapterDeref( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +NDIS_STATUS +MbbAdapterPerformInitialRequests( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +NTSTATUS +InitAdapterStateObject( + __out PADAPTER_STATE AdapterState, + __in NDIS_HANDLE MiniportAdapterContext, + MBB_STATE_CHANGE_HANDLER PauseHandler, + MBB_STATE_CHANGE_HANDLER RestartHandler, + MBB_STATE_CHANGE_HANDLER PowerHandler, + MBB_STATE_CHANGE_HANDLER ResetHandler, + MBB_STATE_CHANGE_HANDLER StallClearHandler + ); + +VOID +ShutdownAdapterStateObject( + PADAPTER_STATE AdapterState + ); + +VOID +QueueStateChangeEvent( + PADAPTER_STATE AdapterState, + PSTATE_CHANGE_EVENT StateChange + ); + +VOID +CompleteStateChange( + PADAPTER_STATE AdapterState, + PSTATE_CHANGE_EVENT StateChange + ); + + +PSTATE_CHANGE_EVENT +AllocateStateChangeEvent( + PADAPTER_STATE AdapterState + ); + +VOID +FreeStateChangeEvent( + PADAPTER_STATE AdapterState, + PSTATE_CHANGE_EVENT StateChange + ); + +VOID +FreeDeviceServiceState( + __in PMBB_DS_STATE DeviceServiceState + ); + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetMultiCarrierCapable( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN IsMultiCarrierSupported + ); + +_Requires_lock_not_held_(&Adapter->Lock) +BOOLEAN +MbbAdapterIsMultiCarrierCapable( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetDataClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in ULONG DataClass + ); + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterGetDataClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __out ULONG* DataClass + ); + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetSupportedCellularClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_CELLULAR_CLASS CellularClass + ); + +_Requires_lock_not_held_(&Adapter->Lock) +MBB_CELLULAR_CLASS +MbbAdapterGetSupportedCellularClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Requires_lock_not_held_(&Adapter->Lock) +BOOLEAN +MbbAdapterIsMultimodeCapable( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetCurrentCellularClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_CELLULAR_CLASS CellularClass + ); + +_Requires_lock_not_held_(&Adapter->Lock) +MBB_CELLULAR_CLASS +MbbAdapterGetCurrentCellularClass( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Requires_lock_not_held_(&Adapter->PortsLock) +VOID +MbbAdapterSetMaxActivatedContexts( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in DWORD dwMaxActivatedContexts + ); + + +NDIS_STATUS +MbbAdapterConfigurePacketFilters( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN Set + ); + +NDIS_STATUS +MbbAdapterConfigurePacketFiltersOnSession( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN Set, + __in NDIS_PORT_NUMBER PortNumber + ); + +NDIS_STATUS +MbbAdapterConfigureDeviceServiceSubscription( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN FullPower, + __in ULONG MediaSpecificWakeUpEvents, + __in ULONG WakeUpEvents + ); + +NDIS_STATUS +MbbAdapterSendNetworkIdleHint( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetRequestManager( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_REQUEST_MANAGER RequestManager + ); + +_Requires_lock_not_held_(&Adapter->Lock) +PMBB_REQUEST_MANAGER +MbbAdapterGetRequestManager( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Requires_lock_not_held_(&Adapter->Lock) +NDIS_STATUS +MbbAdapterQueryDeviceId( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Requires_lock_not_held_(&Adapter->Lock) +NDIS_STATUS +MbbAdapterFWDeviceServicesToCapabilities( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_REQUEST_CONTEXT Request + ); + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterResetCapabilities( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + + +VOID +AdapterStallClearHandler( + PSTATE_CHANGE_EVENT StateChange + ); + + +NDIS_STATUS +MbbAdapterSendNetworkShutdownHint( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +NDIS_STATUS +MbbAdapterSendPreShutdown( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter +); + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetShutdownNotificationCapabilities( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +VOID +MbbAdapterIndicateD3Exit( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in NDIS_PORT_NUMBER PortNumber + ); + + +_Requires_lock_not_held_(&Adapter->Lock) +VOID +MbbAdapterSetOptionalServiceSupport( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +_Requires_lock_not_held_(&SendQueue->AdapterContext->Lock) +VOID TryQueueStallState( + _In_ PMBB_SEND_QUEUE SendQueue +); + +VOID WaitStallClearComplete( + _In_ PADAPTER_STATE AdapterState +); diff --git a/network/wwan/cxwmbclass/init.c b/network/wwan/cxwmbclass/init.c new file mode 100644 index 000000000..17a8bb12e --- /dev/null +++ b/network/wwan/cxwmbclass/init.c @@ -0,0 +1,2269 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +#include "precomp.h" +#include "init.tmh" +#include "WMBClassTelemetry.h" + +MINIPORT_DRIVER_CONTEXT GlobalControl = {0}; + +const NDIS_OID WmbClassSupportedOids[] = +{ + + OID_GEN_SUPPORTED_LIST, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_LOOKAHEAD, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_TRANSMIT_BUFFER_SPACE, + OID_GEN_RECEIVE_BUFFER_SPACE, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_DRIVER_VERSION, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_CURRENT_LOOKAHEAD, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, + OID_GEN_PHYSICAL_MEDIUM, + OID_GEN_STATISTICS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_CURRENT_PACKET_FILTER, + OID_PM_PARAMETERS, + OID_PM_ADD_WOL_PATTERN, + OID_PM_REMOVE_WOL_PATTERN, + OID_WWAN_DRIVER_CAPS, + OID_WWAN_DEVICE_CAPS, + OID_WWAN_READY_INFO, + OID_WWAN_RADIO_STATE, + OID_WWAN_PIN_EX, + OID_WWAN_PIN_LIST, + OID_WWAN_HOME_PROVIDER, + OID_WWAN_PREFERRED_PROVIDERS, + OID_WWAN_VISIBLE_PROVIDERS, + OID_WWAN_REGISTER_STATE, + OID_WWAN_PACKET_SERVICE, + OID_WWAN_SIGNAL_STATE, + OID_WWAN_CONNECT, + OID_WWAN_PROVISIONED_CONTEXTS, + OID_WWAN_SERVICE_ACTIVATION, + OID_WWAN_SMS_CONFIGURATION, + OID_WWAN_SMS_READ, + OID_WWAN_SMS_SEND, + OID_WWAN_SMS_DELETE, + OID_WWAN_SMS_STATUS, + OID_WWAN_VENDOR_SPECIFIC, + OID_WWAN_USSD, + OID_WWAN_AUTH_CHALLENGE, + OID_WWAN_ENUMERATE_DEVICE_SERVICES, + OID_WWAN_DEVICE_SERVICE_COMMAND, + OID_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS, + OID_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS, + OID_WWAN_DEVICE_SERVICE_SESSION, + OID_WWAN_DEVICE_SERVICE_SESSION_WRITE, + OID_WWAN_PREFERRED_MULTICARRIER_PROVIDERS, + OID_WWAN_CREATE_MAC, + OID_WWAN_DELETE_MAC, + OID_WWAN_UICC_FILE_STATUS, + OID_WWAN_UICC_ACCESS_BINARY, + OID_WWAN_UICC_ACCESS_RECORD, + OID_WWAN_PIN_EX2, + OID_WWAN_MBIM_VERSION, + OID_WWAN_SYS_CAPS, + OID_WWAN_DEVICE_CAPS_EX, + OID_WWAN_SYS_SLOTMAPPINGS, + OID_WWAN_SLOT_INFO_STATUS, + OID_WWAN_DEVICE_BINDINGS, + OID_WWAN_REGISTER_STATE_EX, + OID_WWAN_IMS_VOICE_STATE, + OID_WWAN_SIGNAL_STATE_EX, + OID_WWAN_LOCATION_STATE, + OID_WWAN_NITZ, + OID_WWAN_NETWORK_IDLE_HINT, + OID_WWAN_PRESHUTDOWN, + OID_WWAN_UICC_ATR, + OID_WWAN_UICC_OPEN_CHANNEL, + OID_WWAN_UICC_CLOSE_CHANNEL, + OID_WWAN_UICC_APDU, + OID_WWAN_UICC_TERMINAL_CAPABILITY, + OID_WWAN_SAR_CONFIG, + OID_WWAN_SAR_TRANSMISSION_STATUS, + OID_WWAN_LTE_ATTACH_CONFIG, + OID_WWAN_LTE_ATTACH_STATUS, + OID_WWAN_NETWORK_BLACKLIST, + OID_WWAN_PCO, + OID_WWAN_UICC_RESET, + OID_WWAN_DEVICE_RESET, + OID_WWAN_BASE_STATIONS_INFO, + OID_WWAN_UICC_APP_LIST, +}; + +const UINT WmbClassSupportedOidsNum = sizeof(WmbClassSupportedOids) / sizeof(NDIS_OID); + +//volatile ULONG MbbGlobalTestFlags = MbbTestFlagNone; + +DRIVER_INITIALIZE DriverEntry; + +NDIS_STATUS +InitializeGeneralAttributes( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PNDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES GeneralAttributes, + __out PNDIS_PM_CAPABILITIES PnpCaps + ); + +MINIPORT_UNLOAD MbbNdisDriverUnload; + +MINIPORT_INITIALIZE MbbNdisMiniportInitialize; + +MINIPORT_SHUTDOWN MbbNdisMiniportShutdownEx; + +MINIPORT_HALT MbbNdisMiniportHaltEx; + +MINIPORT_SET_OPTIONS MbbNdisMiniportSetOption; + +MINIPORT_PAUSE MbbNdisMiniportPause; + +MINIPORT_RESTART MbbNdisMiniportRestart; + +MINIPORT_DEVICE_PNP_EVENT_NOTIFY MbbNdisMiniportDevicePnPEventNotify; + +MINIPORT_RESET MbbNdisMiniportResetEx; + +MINIPORT_CHECK_FOR_HANG MbbNdisMiniportCheckForHangEx; + +MINIPORT_IDLE_NOTIFICATION MbbNdisMiniportIdleNotification; + +MINIPORT_CANCEL_IDLE_NOTIFICATION MbbNdisMiniportCancelIdleNotification; + +NTSTATUS +SendOpenCommand( + PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +NTSTATUS +SendCloseCommand( + PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +VOID +MbbNdisResponseFragmentAvailable( + __in MBB_PROTOCOL_HANDLE ProtocolHandle + ); + + +NDIS_STATUS +MbbNdisAdapterReadParameters( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +VOID +AdapterPauseHandler( + PSTATE_CHANGE_EVENT StateChange + ); + +VOID +AdapterRestartHandler( + PSTATE_CHANGE_EVENT StateChange + ); + + +VOID +AdapterPowerHandler( + PSTATE_CHANGE_EVENT StateChange + ); + +VOID +AdapterResetHandler( + PSTATE_CHANGE_EVENT StateChange + ); + + +VOID +MbbNdisMiniportBusIdleConfirm( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in DEVICE_POWER_STATE PowerState + ); + +VOID +MbbNdisMiniportIdleNotificationComplete( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in NTSTATUS Status + ); + +VOID +MbbSystemPowerNotification( + _In_ NDIS_HANDLE MiniportAdapterContext, + _In_ NDIS_MINIPORT_SYSPOWER_NOTIFY const *SystemPowerNotification + ); + +void +NTAPI MbbDumpAdapterState( + _In_ LPCGUID SourceId, + _In_ ULONG IsEnabled, + _In_ UCHAR Level, + _In_ ULONGLONG MatchAnyKeyword, + _In_ ULONGLONG MatchAllKeywords, + _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, + _In_opt_ PVOID CallbackContext +); + +#pragma alloc_text(PAGE, MbbNdisDriverUnload) +#pragma alloc_text(PAGE, MbbNdisMiniportHaltEx) +#pragma alloc_text(PAGE, MbbNdisMiniportPause) +#pragma alloc_text(PAGE, MbbNdisMiniportRestart) +#pragma alloc_text(PAGE, MbbNdisMiniportDevicePnPEventNotify) +#pragma alloc_text(PAGE, MbbNdisMiniportInitialize) +#pragma alloc_text(PAGE, InitializeGeneralAttributes) +#pragma alloc_text(PAGE, DriverEntry) + +NTSTATUS +DriverEntry( + PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath + ) +/*++ +Routine Description: + + In the context of its DriverEntry function, a miniport driver associates + itself with NDIS, specifies the NDIS version that it is using, and + registers its entry points. + + +Arguments: + PVOID DriverObject - pointer to the driver object. + PVOID RegistryPath - pointer to the driver registry path. + + Return Value: + + NDIS_STATUS_xxx code + +--*/ +{ + NDIS_STATUS Status = STATUS_UNSUCCESSFUL; + NDIS_MINIPORT_DRIVER_CHARACTERISTICS Characteristics; + WDF_DRIVER_CONFIG config; + NTSTATUS ntStatus; + + PAGED_CODE(); + + do + { + WPP_INIT_TRACING(DriverObject,RegistryPath); + TraceLoggingRegister(g_hLoggingProvider); + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK); + + InitializeListHead( &GlobalControl.AdapterList ); + NdisAllocateSpinLock( &GlobalControl.AdapterListLock ); + + ntStatus=EtwRegister(&WmbclassServiceTrace, MbbDumpAdapterState, NULL, &GlobalControl.TraceHandle); + + if (!NT_SUCCESS(ntStatus)){ + + TraceError(WMBCLASS_INIT, "EtwRegister failed %08lx", ntStatus); + Status = ntStatus; + break; + } + + MbbWriteEvent( + &WMBCLASS_DRIVER_LOAD, + NULL, + NULL, + 1, + &RegistryPath->Buffer, + RegistryPath->Length + ); + + ntStatus=EtwRegister(&WmbclassServiceTraceOpn, NULL, NULL, &GlobalControl.TraceHandleOpn); + + if (!NT_SUCCESS(ntStatus)){ + + TraceError(WMBCLASS_INIT, "EtwRegister(Opn) failed %08lx", ntStatus); + // + // Don't fail the driver load if OPN trace handle cannot be registered + // + } + + // + // Set WdfDriverInitNoDispatchOverride flag to tell the framework + // not to provide dispatch routines for the driver. In other words, + // the framework must not intercept IRPs that the I/O manager has + // directed to the driver. In this case, it will be handled by NDIS + // port driver. + // + config.DriverInitFlags |= WdfDriverInitNoDispatchOverride; + + ntStatus = WdfDriverCreate(DriverObject, + RegistryPath, + WDF_NO_OBJECT_ATTRIBUTES, + &config, + &GlobalControl.hDriver); //vm control + + if (!NT_SUCCESS(ntStatus)){ + + TraceError(WMBCLASS_INIT, "WdfDriverCreate failed %08lx", ntStatus); + Status = NDIS_STATUS_FAILURE; + break; + } + + // + // Fill in the Miniport characteristics structure with the version numbers + // and the entry points for driver-supplied MiniportXxx + // + NdisZeroMemory(&Characteristics, sizeof(Characteristics)); + + + Characteristics.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS, + Characteristics.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS); + Characteristics.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_3; + Characteristics.MajorNdisVersion = 6; + Characteristics.MinorNdisVersion = 80; + Characteristics.MajorDriverVersion = 1; + Characteristics.MinorDriverVersion = 0; + + // + // Init/PnP handlers + // + Characteristics.UnloadHandler = MbbNdisDriverUnload; + + Characteristics.InitializeHandlerEx = MbbNdisMiniportInitialize; + Characteristics.HaltHandlerEx = MbbNdisMiniportHaltEx; + + Characteristics.RestartHandler = MbbNdisMiniportRestart; + Characteristics.PauseHandler = MbbNdisMiniportPause; + + Characteristics.DevicePnPEventNotifyHandler = MbbNdisMiniportDevicePnPEventNotify; + + Characteristics.ShutdownHandlerEx = MbbNdisMiniportShutdownEx; + + Characteristics.SetOptionsHandler = MbbNdisMiniportSetOption; + +#if 0 + // + // reset + // + Characteristics.ResetHandlerEx = MbbNdisMiniportResetEx; + Characteristics.CheckForHangHandlerEx = MbbNdisMiniportCheckForHangEx; + +#endif + // + // Query/Set/Method requests handlers + // + Characteristics.OidRequestHandler = MbbNdisMiniportOidRequest; + Characteristics.CancelOidRequestHandler = MbbNdisMiniportCancelOidRequest; + + // + // Send/Receive handlers + // + Characteristics.SendNetBufferListsHandler = MbbNdisMiniportSendNetBufferLists; + Characteristics.ReturnNetBufferListsHandler = MbbNdisMiniportReturnNetBufferLists; + Characteristics.CancelSendHandler = MbbNdisMiniportCancelSend; + + Characteristics.Flags = NDIS_WDM_DRIVER; + + TraceVerbose(WMBCLASS_INIT, "Calling NdisMRegisterMiniportDriver..."); + // + // Register with IP Helper for IP change notifications. + // + ntStatus = MbbIpInitialize( &GlobalControl ); + if( ntStatus != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to initialize IP subsystem, status=%!STATUS!", ntStatus ); + Status = NDIS_STATUS_FAILURE; + break; + } + // + // Registers miniport's entry points with the NDIS library as the first + // step in NIC driver initialization. The NDIS will call the + // MiniportInitialize when the device is actually started by the PNP + // manager. + // + if( (Status = NdisMRegisterMiniportDriver( + DriverObject, + RegistryPath, + (PNDIS_HANDLE)&GlobalControl, + &Characteristics, + &GlobalControl.NdisDriverHandle + )) != NDIS_STATUS_SUCCESS ) + { + TraceError(WMBCLASS_INIT, "NdisMRegisterMiniportDriver() failed %08lx", Status); + break; + } + } + while( FALSE ); + + if( NT_ERROR(Status) ) + { + MbbIpCleanup( &GlobalControl ); + + if (GlobalControl.TraceHandle != 0) + { + EtwUnregister(GlobalControl.TraceHandle); + TraceLoggingUnregister(g_hLoggingProvider); + GlobalControl.TraceHandle=0; + } + + if (GlobalControl.TraceHandleOpn != 0) + { + EtwUnregister(GlobalControl.TraceHandleOpn); + GlobalControl.TraceHandleOpn=0; + } + + WPP_CLEANUP(DriverObject); + } + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return Status; +} + +VOID +MbbNdisDriverUnload( + __in PDRIVER_OBJECT DriverObject + ) +/*++ + +Routine Description: + + The unload handler is called during driver unload to free up resources + acquired in DriverEntry. Note that an unload handler differs from + a MiniportHalt function in that the unload handler has a more global + scope, whereas the scope of the MiniportHalt function is restricted + to a particular miniport driver instance. + + During an unload operation, an NDIS 6.0 miniport driver must deregister + the miniport driver by calling NdisMDeregisterMiniportDriver + and passing the MiniportDriverHandle as a parameter. + The driver obtained the MiniportDriverHandle when it called + NdisMRegisterMiniportDriver. + + Runs at IRQL = PASSIVE_LEVEL. + +Arguments: + + DriverObject Not used + +Return Value: + + None + +--*/ +{ + PAGED_CODE(); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + UNREFERENCED_PARAMETER(DriverObject); + + MbbIpCleanup( &GlobalControl ); + + WdfDriverMiniportUnload(WdfGetDriver()); + + NdisMDeregisterMiniportDriver(GlobalControl.NdisDriverHandle); + + if (GlobalControl.TraceHandle != 0) + { + EtwUnregister(GlobalControl.TraceHandle); + TraceLoggingUnregister(g_hLoggingProvider); + GlobalControl.TraceHandle=0; + } + + if (GlobalControl.TraceHandleOpn != 0) + { + EtwUnregister(GlobalControl.TraceHandleOpn); + GlobalControl.TraceHandleOpn=0; + } + + ASSERT( IsListEmpty( &GlobalControl.AdapterList ) ); + NdisFreeSpinLock( &GlobalControl.AdapterListLock ); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + WPP_CLEANUP(DriverObject); +} + +NDIS_STATUS +MbbNdisMiniportInitialize( + __in NDIS_HANDLE MiniportAdapterHandle, + __in NDIS_HANDLE MiniportDriverContext, + __in PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters + ) +/*++ +Routine Description: + + The MiniportInitialize function is a required function. Here is the + list of things this function typically performs: + + Set the miniport attributes. + Read configuration parameters from the registry. + Allocate memory. + Allocate the NET_BUFFER_LIST pool and the NET_BUFFER pool. + Do hardware specific initialization like registering interrupt handlers/ set DMA resources etc. + Read and write to the bus-specific configuration space. + + MiniportInitialize runs at IRQL = PASSIVE_LEVEL. + +Arguments: + + MiniportAdapterHandle The handle NDIS uses to refer to us + MiniportDriverContext Handle passed to NDIS when we registered the driver + MiniportInitParameters Initialization parameters contains a pointer + to a list of the allocated hardware resources + for the miniport adapter + +Return Value: + + NDIS_STATUS_xxx code + +--*/ +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + BOOLEAN SendQueueInitialized = FALSE; + BOOLEAN RecvQueueInitialized = FALSE; + NDIS_MINIPORT_ADAPTER_ATTRIBUTES MiniportAttributes; + NDIS_MINIPORT_SS_CHARACTERISTICS SelectiveSuspend; + PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; + ULONG_PTR ModelNameLength=0; + ULONG TempInstance=0; + NDIS_PM_CAPABILITIES PnpCaps; + int i = 0; + PMBB_PORT DefaultPort = NULL; + + PAGED_CODE(); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + +#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocates a miniport adapter attributes structure, released in MbbNdisMiniportHaltEx.") + Adapter=ALLOCATE_NONPAGED_POOL(sizeof(*Adapter)); + + if (Adapter == NULL) + { + + TraceError(WMBCLASS_INIT, "[Init] FAILED to allocate adapter context"); + Status=NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + NdisZeroMemory(Adapter,sizeof(*Adapter)); + + // + // init elements of the adapter structure + // + NdisAllocateSpinLock(&Adapter->Lock); + + Adapter->TraceInstance=InterlockedIncrement(&GlobalControl.CurrentTraceInstance); + TempInstance=Adapter->TraceInstance; + + Adapter->MiniportAdapterHandle = MiniportAdapterHandle; + + Adapter->IfIndex=MiniportInitParameters->IfIndex; + Adapter->NetLuid=MiniportInitParameters->NetLuid; + Adapter->MaxActivatedContexts = 1; // initialize to 1.OID_WWAN_DRIVER_CAPS should return the correct value. + Adapter->SurpriseRemoved = FALSE; + + RtlInitAnsiString(&Adapter->FriendlyName, NULL); + + NdisAllocateSpinLock(&Adapter->PortsLock); + + NdisAllocateSpinLock(&Adapter->SessionIdPortTableLock); + + //Initialize all session Ids as available + for(i=0; i < ARRAYSIZE(Adapter->SessionIdPortTable); i++) + { + Adapter->SessionIdPortTable[i].InUse = FALSE; + Adapter->SessionIdPortTable[i].PortNumber = (ULONG)MBB_INVALID_PORT_NUMBER; + } + + MbbWriteEvent( + &INITIALIZE_EVENT, + NULL, + NULL, + 1, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance) + ); + + // + // object managed state of adapter while processing power and pnp events + // + Status=InitAdapterStateObject( + &Adapter->AdapterState, + Adapter->MiniportAdapterHandle, + AdapterPauseHandler, + AdapterRestartHandler, + AdapterPowerHandler, + AdapterResetHandler, + AdapterStallClearHandler + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "InitAdapterStateObject with %!STATUS!", Status); + goto Cleanup; + + } + + + Status=GetDeviceFriendlyName( MiniportAdapterHandle, &Adapter->FriendlyName); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] GetDeviceFriendlyName with %!STATUS!", Status); + goto Cleanup; + + } + + NdisMGetDeviceProperty( + MiniportAdapterHandle, + &Adapter->Pdo, + &Adapter->Fdo, + &Adapter->NextDeviceObject, + NULL, + NULL + ); + + + Status=MbbBusInitialize( + Adapter->Pdo, + Adapter->Fdo, + Adapter->NextDeviceObject, + MbbNdisResponseFragmentAvailable, + MbbNdisReceiveCallback, + MbbNdisMiniportBusIdleConfirm, + MbbNdisMiniportIdleNotificationComplete, + Adapter, + GlobalControl.TraceHandle, + Adapter->TraceInstance, + &Adapter->BusHandle + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] MbbBusInitialize with %!STATUS!", Status); + goto Cleanup; + + } + // + // Initialize the OID/CID handlers before the device is OPENED. + // Once the device is opened and the interrupt pipe is connected + // ReqMgr will start receiving unsolicited indications from the device. + // + Status = MbbBusQueryBusParameters( + Adapter->BusHandle, + &Adapter->BusParams + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] MbbBusQueryBusParameters() with %!STATUS!", Status); + goto Cleanup; + } + + if( (Status = MbbReqMgrInitialize( + &(Adapter->RequestManagerAllocation), + Adapter + )) != NDIS_STATUS_SUCCESS ) + { + goto Cleanup; + } + MbbAdapterSetRequestManager( + Adapter, + &(Adapter->RequestManagerAllocation) + ); + + if (Adapter->BusParams.PowerFiltersSupported > 0) + { + ULONG i = 0; + + Adapter->PowerFilterTable=(PPOWER_FILTER_LOOKUP)ALLOCATE_NONPAGED_POOL(sizeof(POWER_FILTER_LOOKUP) * Adapter->BusParams.PowerFiltersSupported); + + if (Adapter->PowerFilterTable == NULL) + { + TraceError(USBBUS_ALL, "power filter table"); + Status=STATUS_NO_MEMORY; + goto Cleanup; + + } + + RtlZeroMemory(Adapter->PowerFilterTable, sizeof(POWER_FILTER_LOOKUP) * Adapter->BusParams.PowerFiltersSupported); + + for (i = 0; i < Adapter->BusParams.PowerFiltersSupported; i++) + { + Adapter->PowerFilterTable[i].PortNumber = MBB_INVALID_PORT_NUMBER; + } + } + + + Status=MbbBusOpen(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FastIOSendNetBufferListsComplete, FastIOIndicateReceiveNetBufferLists); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] MbbBusOpen(1) with %!STATUS!", Status); + + MbbBusClose(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), TRUE); + + Status=MbbBusOpen(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FastIOSendNetBufferListsComplete, FastIOIndicateReceiveNetBufferLists); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] MbbBusOpen(2) with %!STATUS!", Status); + + goto Cleanup; + } + } + // + // Set the miniport registration attributes with NDIS + // + NdisZeroMemory(&MiniportAttributes, sizeof(MiniportAttributes)); + MiniportAttributes.RegistrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES; + MiniportAttributes.RegistrationAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1; + MiniportAttributes.RegistrationAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES); + + MiniportAttributes.RegistrationAttributes.MiniportAdapterContext = Adapter; + MiniportAttributes.RegistrationAttributes.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_NDIS_WDM | + NDIS_MINIPORT_ATTRIBUTES_SURPRISE_REMOVE_OK | + NDIS_MINIPORT_ATTRIBUTES_NO_PAUSE_ON_SUSPEND ; + + MiniportAttributes.RegistrationAttributes.CheckForHangTimeInSeconds = WMBCLASS_CHECK_FOR_HANG_INTERVAL; + MiniportAttributes.RegistrationAttributes.InterfaceType = WMBCLASS_INTERFACE_TYPE; + + Status=NdisMSetMiniportAttributes( + MiniportAdapterHandle, + &MiniportAttributes + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] NdisMSetMiniportAttributes(registration) with Status=%!STATUS!", Status); + goto Cleanup; + + } + + Status = MbbAdapterQueryDeviceId( Adapter ); + if( NT_ERROR( Status ) ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to query DeviceId with NdisStatus=%!STATUS!", Status ); + goto Cleanup; + } + + Status=InitializeGeneralAttributes(Adapter,&MiniportAttributes.GeneralAttributes,&PnpCaps); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] InitializeGeneralAttributes with Status=%!STATUS!", Status); + goto Cleanup; + + } + + Status=NdisMSetMiniportAttributes( + MiniportAdapterHandle, + &MiniportAttributes + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "[Init] NdisMSetMiniportAttributes(general) with Status=%!STATUS!", Status); + goto Cleanup; + + } + + + // + // init the stat structure + // + Adapter->Stats.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + Adapter->Stats.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1; + Adapter->Stats.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; + + Adapter->Stats.SupportedStatistics= \ + NDIS_STATISTICS_XMIT_OK_SUPPORTED \ + | NDIS_STATISTICS_RCV_OK_SUPPORTED \ + | NDIS_STATISTICS_XMIT_ERROR_SUPPORTED \ + | NDIS_STATISTICS_RCV_ERROR_SUPPORTED \ + | NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED \ + | NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED \ + | NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED \ + | NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED \ + | NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED \ + | NDIS_STATISTICS_BYTES_RCV_SUPPORTED \ + | NDIS_STATISTICS_BYTES_XMIT_SUPPORTED \ + | NDIS_STATISTICS_RCV_DISCARDS_SUPPORTED \ + | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED; + + if( (Status = MbbNdisAdapterReadParameters( Adapter )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to read adapter parameters, status=%!STATUS!", Status ); + goto Cleanup; + } + + Status=RtlStringCbLengthW( + Adapter->BusParams.Model, + sizeof(Adapter->BusParams.Model), + &ModelNameLength + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "RtlStringCbLength with %!STATUS!", Status); + goto Cleanup; + + } + + if (Adapter->OverrideDeviceName) + { + if (ModelNameLength > 0) + { + // + // Update the device name with the model from the USB descriptor + // + Status = IoSetDevicePropertyData( + Adapter->Pdo, + &DEVPKEY_Device_FriendlyName, + 0, + PLUGPLAY_PROPERTY_PERSISTENT, + DEVPROP_TYPE_STRING, + (ULONG)ModelNameLength + sizeof(WCHAR), + Adapter->BusParams.Model + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "IoSetDevicePropertyData with %!STATUS!", Status); + + Status=STATUS_SUCCESS; + + } + } + } + // + // Initialize the data queues. + // They would not be active until the miniport is put in the started state. + // + if( (Status = MbbSendQInitialize( + &Adapter->SendQueue, + MAX_PENDING_SENDS, + DrainCompleteCallback, + Adapter, + Adapter, + Adapter->BusHandle, + Adapter->MiniportAdapterHandle + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to initialize send queue, status=%!STATUS!", Status ); + goto Cleanup; + } + SendQueueInitialized = TRUE; + + if( (Status = MbbRecvQInitialize( + &Adapter->ReceiveQueue, + DrainCompleteCallback, + Adapter, + Adapter->MiniportAdapterHandle + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to initialize receive queue, status=%!STATUS!", Status ); + goto Cleanup; + } + RecvQueueInitialized = TRUE; + + // Perform some requests that we need to do to get setup + if( (Status = MbbAdapterPerformInitialRequests( Adapter )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[Init] FAILED to perform initial requests, status=%!STATUS!", Status ); + goto Cleanup; + } + +//#define TEST_CODE +#ifdef TEST_CODE + MbbAdapterConfigureDeviceServiceSubscription( + Adapter, + FALSE, + NDIS_WWAN_WAKE_ON_REGISTER_STATE_ENABLED | + NDIS_WWAN_WAKE_ON_SMS_RECEIVE_ENABLED | + NDIS_WWAN_WAKE_ON_USSD_RECEIVE_ENABLED | + NDIS_WWAN_WAKE_ON_PACKET_STATE_ENABLED | + NDIS_WWAN_WAKE_ON_UICC_CHANGE_ENABLED + ); + + MbbAdapterConfigureDeviceServiceSubscription( + Adapter, + TRUE, + NDIS_WWAN_WAKE_ON_REGISTER_STATE_ENABLED | + NDIS_WWAN_WAKE_ON_SMS_RECEIVE_ENABLED | + NDIS_WWAN_WAKE_ON_USSD_RECEIVE_ENABLED | + NDIS_WWAN_WAKE_ON_PACKET_STATE_ENABLED | + NDIS_WWAN_WAKE_ON_UICC_CHANGE_ENABLED + ); + + { + UCHAR Mask=0xff; + UCHAR Pattern[8]={1,2,3,4,5,6,7,8}; + + MbbUtilSetPowerFilterPattern( + Adapter, + MBB_DEFAULT_SESSION_ID, + 1, + &Mask, + sizeof(Mask), + (PCUCHAR)&Pattern, + sizeof(Pattern) + ); + + MbbAdapterConfigurePacketFilters(Adapter,TRUE); + } +#endif + + MbbAdapterSetShutdownNotificationCapabilities( Adapter ); + + TraceLoggingWrite( + g_hLoggingProvider, + "ShutdownCapability", + TraceLoggingUInt64(Adapter->AdapterFlags.IsPreshutdownCapable, "IsPreshutdownCapable"), + TraceLoggingUInt64(Adapter->AdapterFlags.ShutdownNotificationCapable, "ShutdownNotificationCapable"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); + + MbbAdapterSetOptionalServiceSupport(Adapter); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: OptionalServiceCapability SAR %d NetworkBlacklist %d ProvisionedContextV2 %d LTEAttachConfig %d MultiSIM %d UiccLowLevel %d PCO %d DeviceReset %d BaseStationsInfo %d", + Adapter->AdapterFlags.IsSARCapable, Adapter->AdapterFlags.IsNetworkBlacklistCapable, Adapter->AdapterFlags.IsProvisionedContextV2Capable, + Adapter->AdapterFlags.IsLTEAttachConfigCapable, Adapter->AdapterFlags.IsMultiSIMCapable, Adapter->AdapterFlags.IsUiccLowLevelCapable, + Adapter->AdapterFlags.IsPcoCapable, Adapter->AdapterFlags.IsDeviceResetCapable, Adapter->AdapterFlags.IsBaseStationsInfoCapable); + + TraceLoggingWrite( + g_hLoggingProvider, + "OptionalServiceCapability", + TraceLoggingUInt64(Adapter->AdapterFlags.IsSARCapable, "IsSARCapable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsNetworkBlacklistCapable, "IsNetworkBlacklistCapable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsProvisionedContextV2Capable, "IsProvisionedContextV2Capable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsLTEAttachConfigCapable, "IsLTEAttachConfigCapable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsMultiSIMCapable, "IsMultiSIMCapable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsUiccLowLevelCapable, "IsUiccLowLevelCapable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsDeviceCapsV2Capable, "IsDeviceCapsV2Capable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsPcoCapable, "IsPcoCapable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsDeviceResetCapable, "IsDeviceResetCapable"), + TraceLoggingUInt64(Adapter->AdapterFlags.IsBaseStationsInfoCapable, "IsBaseStationsInfoCapable"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); + + MbbDriverAddAdapter( &GlobalControl, Adapter ); + + // Clear the adapter port list + NdisZeroMemory(Adapter->PortList, sizeof(MBB_PORT*) * MBB_MAX_NUMBER_OF_PORTS); + + // Allocate the adapter port corresponding to default NDIS port ( port number 0). We are + // not managing port 0, however the adapter maintains a list of ports on which data/control traffic flows. + // Instead of managing Port 0 separately, we will attach it to the list of ports maintained by the adapter itself. + + Status = MbbWwanAllocatePort(Adapter, FALSE, &DefaultPort); // FALSE because we dont want to handle NDIS default port ourselves. + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "MbbWwanAllocatePort failed with %!STATUS!", Status); + goto Cleanup; + } + + ASSERT(DefaultPort->PortNumber == DEFAULT_NDIS_PORT_NUMBER); + + // Add the port to adapter ports list + MbbWwanAddPortToAdapterList(Adapter,&DefaultPort); + +Cleanup: + + if (Status != NDIS_STATUS_SUCCESS) + { + if (Adapter != NULL) + { + PMBB_REQUEST_MANAGER RequestManager; + PMBB_PORT Port = NULL; + + if (Adapter->BusHandle != NULL) + { + MbbBusClose(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FALSE); + } + + if( SendQueueInitialized == TRUE ) + MbbSendQCleanup( &Adapter->SendQueue ); + + if( RecvQueueInitialized == TRUE ) + MbbRecvQCleanup( &Adapter->ReceiveQueue ); + + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) != NULL ) + { + MbbReqMgrCleanup( RequestManager ); + } + + WaitStallClearComplete(&Adapter->AdapterState); + + if (Adapter->BusHandle != NULL) + { + MbbBusCleanup(Adapter->BusHandle); + Adapter->BusHandle = NULL; + } + + if((Port = Adapter->PortList[0]) != NULL) // if default port is allocated + { + // remove it from the adapter port list + MbbWwanRemovePortFromAdapterList(Adapter,Port); + + // Deallocate the port. It will get cleaned up when + // its reference goes to 0 + MbbWwanDeallocatePort(Port); + } + + FreeAdapterBlock(Adapter); + Adapter=NULL; + } + + TraceError(WMBCLASS_INIT, "[Init] miniport init failed with %08lx", Status); + } + + MbbWriteEvent( + &INITIALIZE_EXIT_EVENT, + NULL, + NULL, + 2, + &TempInstance, + sizeof(TempInstance), + &Status, + sizeof(Status) + ); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return Status; + +} + +/****************************************************************************/ +/* InitializeGeneralizeAttributes */ +/****************************************************************************/ +/* */ +/* Routine Description: */ +/* */ +/* Queries the device for information and initializes the general */ +/* attributes structure */ +/* */ +/* Arguments: */ +/* */ +/* Adapter - Pointer to the adapter structure */ +/* GeneralAttributes - Pointer to the general attributes structure */ +/* (Zeroed out by the caller) */ +/* */ +/* Return: */ +/* */ +/* NDIS_STATUS_SUCCESS on succes, error code otherwise */ +/* */ +/****************************************************************************/ + +NDIS_STATUS +InitializeGeneralAttributes( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PNDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES GeneralAttributes, + __out PNDIS_PM_CAPABILITIES PnpCaps + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + NDIS_STRING IfTypeStr = NDIS_STRING_CONST("*IfType"); + ULONG MediaState; + DWORD MaxPowerFilterSize = 0; + + PAGED_CODE(); + + GeneralAttributes->Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES; + GeneralAttributes->Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;//6.2 + GeneralAttributes->Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;//6.2 + + GeneralAttributes->MediaType = NdisMediumWirelessWan; + GeneralAttributes->PhysicalMediumType = NdisPhysicalMediumWirelessWan; + + if (Adapter->BusParams.IsErrataDevice) + { + GeneralAttributes->MtuSize = Adapter->BusParams.MTU; + GeneralAttributes->LookaheadSize = Adapter->BusParams.MTU; + } else { + GeneralAttributes->MtuSize = Adapter->BusParams.MaxSegmentSize; + GeneralAttributes->LookaheadSize = Adapter->BusParams.MaxSegmentSize; + } + + GeneralAttributes->MacAddressLength=0; + // + // Update the link speed in the adapter structure as well as + // general attributes + // + + Adapter->CurrentLinkSpeed = 0; + Adapter->MaxLinkSpeed = 100L*1000*1000; + + GeneralAttributes->MaxXmitLinkSpeed = Adapter->MaxLinkSpeed; + GeneralAttributes->XmitLinkSpeed = Adapter->CurrentLinkSpeed; + + GeneralAttributes->MaxRcvLinkSpeed = Adapter->MaxLinkSpeed; + GeneralAttributes->RcvLinkSpeed = Adapter->CurrentLinkSpeed; + + // Setting this to connected so that the filter driver state is also connected. + // The media connect state corresponding to the NDIS ports handled by this miniport + // will be indicated using NDIS_STATUS_PORT_STATE indication, which will be + // converted to NDIS_STATUS_LINK_STATE indications by the filter driver. + GeneralAttributes->MediaConnectState = MediaConnectStateDisconnected; + + GeneralAttributes->MediaDuplexState = MediaDuplexStateUnknown; + + RtlZeroMemory(PnpCaps,sizeof(*PnpCaps)); + + PnpCaps->Header.Type=NDIS_OBJECT_TYPE_DEFAULT; + PnpCaps->Header.Revision=NDIS_PM_CAPABILITIES_REVISION_2; + PnpCaps->Header.Size=NDIS_SIZEOF_NDIS_PM_CAPABILITIES_REVISION_2; + + PnpCaps->MediaSpecificWakeUpEvents = NDIS_WWAN_WAKE_ON_REGISTER_STATE_SUPPORTED | + NDIS_WWAN_WAKE_ON_SMS_RECEIVE_SUPPORTED | + NDIS_WWAN_WAKE_ON_USSD_RECEIVE_SUPPORTED | + NDIS_WWAN_WAKE_ON_PACKET_STATE_SUPPORTED | + NDIS_WWAN_WAKE_ON_UICC_CHANGE_SUPPORTED; + + PnpCaps->MinLinkChangeWakeUp = NdisDeviceStateD2; + + PnpCaps->SupportedWakeUpEvents=NDIS_PM_WAKE_ON_MEDIA_DISCONNECT_SUPPORTED; + + if (Adapter->BusParams.PowerFiltersSupported > 0) + { + PnpCaps->SupportedWoLPacketPatterns = NDIS_PM_WOL_BITMAP_PATTERN_SUPPORTED; + PnpCaps->NumTotalWoLPatterns = Adapter->BusParams.PowerFiltersSupported; + + if (Adapter->BusParams.IsErrataDevice) + { + // For errata devices we will report the device specific max pattern size. + // 192 bytes is the maximum power filter size as per the MBIM spec. + // If a device reports more than 192 bytes as the power filter size, we + // normalize it here to 192 bytes. This will prevent erroneous devices + // from indicating arbitrary pattern size. This needs to change with any + // MBIM spec revision. + + if(Adapter->BusParams.MaxPowerFilterSize > WMBCLASS_MAX_MBIM_WOL_PATTERN) + { + MaxPowerFilterSize = WMBCLASS_MAX_MBIM_WOL_PATTERN; + } + else + { + MaxPowerFilterSize = Adapter->BusParams.MaxPowerFilterSize; + } + } + else + { + // To maintain backward compatibility with Win8 devices, we continue + // reporting 256 bytes as the wake pattern size. + MaxPowerFilterSize = WMBCLASS_MAX_WOL_PATTERN; + } + + PnpCaps->MaxWoLPatternSize = MaxPowerFilterSize; + PnpCaps->MaxWoLPatternOffset = MaxPowerFilterSize; + PnpCaps->MinPatternWakeUp = NdisDeviceStateD2; + } + + if (Adapter->BusParams.SelectiveSuspendSupported) + { + PnpCaps->Flags |= NDIS_PM_SELECTIVE_SUSPEND_SUPPORTED; + } + + GeneralAttributes->PowerManagementCapabilitiesEx = PnpCaps; + + GeneralAttributes->MacOptions = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | NDIS_MAC_OPTION_NO_LOOPBACK; + + GeneralAttributes->MaxMulticastListSize=0; + + // + // Although MB device has no mac address DHCP requires a hardware id. + // + RtlCopyMemory( + GeneralAttributes->CurrentMacAddress, + Adapter->MACAddress, + MBB_MAC_ADDRESS_LENGTH + ); + RtlCopyMemory( + GeneralAttributes->PermanentMacAddress, + Adapter->MACAddress, + MBB_MAC_ADDRESS_LENGTH + ); + GeneralAttributes->MacAddressLength = MBB_MAC_ADDRESS_LENGTH; + + GeneralAttributes->IfType = IF_TYPE_WWANPP; + + GeneralAttributes->RecvScaleCapabilities = NULL; + + GeneralAttributes->AccessType = NET_IF_ACCESS_POINT_TO_POINT; + GeneralAttributes->ConnectionType = NET_IF_CONNECTION_DEDICATED; + GeneralAttributes->DirectionType = NET_IF_DIRECTION_SENDRECEIVE; + GeneralAttributes->SupportedPacketFilters = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_PROMISCUOUS; + + GeneralAttributes->IfConnectorPresent = TRUE; + + GeneralAttributes->SupportedStatistics = + NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV | + NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV | + NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS | + NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR | + NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT | + NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | + NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR | + NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV | + NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT ; + + GeneralAttributes->SupportedPauseFunctions = NdisPauseFunctionsUnknown; + GeneralAttributes->DataBackFillSize = 0; + GeneralAttributes->ContextBackFillSize = 0; + + GeneralAttributes->SupportedOidList = (PNDIS_OID)&WmbClassSupportedOids[0]; + GeneralAttributes->SupportedOidListLength = WmbClassSupportedOidsNum*sizeof(NDIS_OID); + + GeneralAttributes->AutoNegotiationFlags = 0; + + return Status; +} + + +VOID +MbbNdisMiniportShutdownEx( + __in NDIS_HANDLE MiniportAdapterContext, + __in NDIS_SHUTDOWN_ACTION ShutdownAction + ) + +{ + UNREFERENCED_PARAMETER(ShutdownAction); + + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] SHUTTING DOWN Adapter=0x%p", Adapter); + + MbbAdapterSendNetworkShutdownHint(Adapter); + + if (MbbBusIsFastIO(Adapter->BusHandle)) + { + MbbBusShutdown(Adapter->BusHandle, ShutdownAction); + } + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; +} + +VOID +MbbNdisMiniportHaltEx( + __in NDIS_HANDLE MiniportAdapterContext, + __in NDIS_HALT_ACTION HaltAction + ) +/*++ +Description: + Close the MBIM protocol before cleaning up the request manager. + Once MBIM CLOSE is sent the device should not queue any more notifications. +--*/ +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + ULONG TempInstance=Adapter->TraceInstance; + NDIS_STATUS TempStatus=NDIS_STATUS_SUCCESS; + PMBB_REQUEST_MANAGER RequestManager; + PMBB_PORT Port = NULL; + + UNREFERENCED_PARAMETER(HaltAction); + + PAGED_CODE(); + + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] HALTING Adapter=0x%p", Adapter ); + + MbbWriteEvent( + &HALT_EVENT, + NULL, + NULL, + 1, + &TempInstance, + sizeof(TempInstance) + ); + + MbbSendQCleanup( &Adapter->SendQueue ); + MbbRecvQCleanup( &Adapter->ReceiveQueue ); + + if (Adapter->BusHandle != NULL) + { + if (MbbBusIsFastIO(Adapter->BusHandle)) + { + MbbBusHalt(Adapter->BusHandle, HaltAction); + } + MbbBusClose(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FALSE); + } + + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) != NULL ) + { + MbbReqMgrCleanup( RequestManager ); + } + else + { + TraceError(WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager on Adapter=0x%p for HALT", Adapter ); + } + + WaitStallClearComplete(&Adapter->AdapterState); + + if (Adapter->BusHandle != NULL) + { + MbbBusCleanup(Adapter->BusHandle); + Adapter->BusHandle=NULL; + } + + while ((Port = Adapter->PortList[0]) != NULL) // if default port is allocated + { + // remove it from the adapter port list + if (MbbWwanRemovePortFromAdapterList(Adapter, Port)) + { + TempStatus = MbbWwanDeactivatePort(Adapter, Port); + if (TempStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_INIT, "MbbWwanDeactivatePort failed with status = 0x%x", TempStatus); + } + + // Deallocate the port. It will get cleaned up when + // its reference goes to 0 + MbbWwanDeallocatePort(Port); + } + else + { + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Port(0x%p) was already removed", Port); + } + } + + ASSERT(Adapter->PortList[0] == NULL); + + MbbDriverRemoveAdapter( &GlobalControl, Adapter ); + + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] HALTED Adapter=0x%p", Adapter ); + + MbbWriteEvent( + &HALT_EXIT_EVENT, + NULL, + NULL, + 2, + &TempInstance, + sizeof(TempInstance), + &TempStatus, + sizeof(TempStatus) + ); + + return; +} + +NDIS_STATUS +MbbNdisMiniportSetOption( + __in NDIS_HANDLE NdisDriverHandle, + __in NDIS_HANDLE DriverContext + ) + +{ + NDIS_MINIPORT_SS_CHARACTERISTICS SelectiveSuspendChars = {0}; + NDIS_MINIPORT_SYSPOWER_NOTIFY_CHARACTERISTICS SysPowerChars = {0}; + NDIS_STATUS Status=NDIS_STATUS_SUCCESS; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + SelectiveSuspendChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_SS_CHARACTERISTICS; + SelectiveSuspendChars.Header.Revision = NDIS_MINIPORT_SS_CHARACTERISTICS_REVISION_1; + SelectiveSuspendChars.Header.Size = sizeof(SelectiveSuspendChars); + + // + // Set the two function callbacks used by NDIS + // + SelectiveSuspendChars.IdleNotificationHandler = &MbbNdisMiniportIdleNotification; + SelectiveSuspendChars.CancelIdleNotificationHandler = &MbbNdisMiniportCancelIdleNotification; + + Status = NdisSetOptionalHandlers( + NdisDriverHandle, + (PVOID)&SelectiveSuspendChars + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "NdisMSetMiniportAttributes(general) with %08lx", Status); + goto Cleanup; + + } + + SysPowerChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_SYSPOWER_NOTIFICATION; + SysPowerChars.Header.Revision = NDIS_MINIPORT_SYSPOWER_NOTIFY_CHARACTERISTICS_REVISION_1; + SysPowerChars.Header.Size = NDIS_SIZEOF_MINIPORT_SYSPOWER_NOTIFY_CHARACTERISTICS_REVISION_1; + + SysPowerChars.SysPowerNotifyHandler = MbbSystemPowerNotification; + + Status = NdisSetOptionalHandlers( + NdisDriverHandle, + (PVOID)&SysPowerChars + ); + + if (NT_ERROR(Status)) + { + TraceError(WMBCLASS_INIT, "NdisMSetMiniportAttributes(general) with %08lx SysPowerCcaps", Status); + goto Cleanup; + } +Cleanup: + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return Status; +} + +NDIS_STATUS +MbbNdisMiniportIdleNotification( + __in NDIS_HANDLE MiniportAdapterContext, + __in BOOLEAN ForceIdle + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + NTSTATUS Status=NDIS_STATUS_SUCCESS; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + Status=MbbBusIdleNotification(Adapter->BusHandle, ForceIdle); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return Status; +} + + +VOID +MbbNdisMiniportCancelIdleNotification( + __in NDIS_HANDLE MiniportAdapterContext + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + MbbBusCancelIdleNotification(Adapter->BusHandle); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; +} + + +VOID +MbbNdisMiniportBusIdleConfirm( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in DEVICE_POWER_STATE PowerState + ) + +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + NdisMIdleNotificationConfirm( + Adapter->MiniportAdapterHandle, + PowerState + ); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; + +} + +VOID +MbbNdisMiniportIdleNotificationComplete( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in NTSTATUS Status + ) + +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + NdisMIdleNotificationCompleteEx(Adapter->MiniportAdapterHandle, Status); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; + +} + +VOID +MbbSystemPowerNotification( + _In_ NDIS_HANDLE MiniportAdapterContext, + _In_ NDIS_MINIPORT_SYSPOWER_NOTIFY const *SystemPowerNotification + ) + +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); + + NdisAcquireSpinLock(&Adapter->Lock); + + Adapter->LastLowSystemPowerState=*SystemPowerNotification; + + NdisReleaseSpinLock(&Adapter->Lock); + + TraceInfo(WMBCLASS_POWER, "%!FUNC!: TargetSystemPowerState S%d EffectiveSystemPowerState S%d", + SystemPowerNotification->TargetSystemState - PowerSystemWorking, + SystemPowerNotification->EffectiveSystemState - PowerSystemWorking); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; + +} + +VOID +DrainCompleteCallback( + PVOID Context + ) + +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)Context; + BOOLEAN CompletePause=FALSE; + BOOLEAN ResetComplete=FALSE; + BOOLEAN StallClear=FALSE; + PMBB_REQUEST_CONTEXT Request=NULL; + PSTATE_CHANGE_EVENT StateChange=NULL; + NDIS_STATUS TempStatus=NDIS_STATUS_SUCCESS; + + TraceInfo(WMBCLASS_INIT, "Entered Pending=%d", Adapter->AdapterState.PendingActions-1); + + NdisAcquireSpinLock(&Adapter->Lock); + + ASSERT(Adapter->AdapterState.PendingActions > 0); + + Adapter->AdapterState.PendingActions--; + + if (Adapter->AdapterState.PendingActions == 0) + { + StateChange=Adapter->AdapterState.RunningEvent; + + NdisReleaseSpinLock(&Adapter->Lock); + + switch (StateChange->EventType) + { + + case STATE_CHANGE_TYPE_PAUSE: + + CompletePause=TRUE; + + break; + + case STATE_CHANGE_TYPE_POWER: + + Request=StateChange->Power.Request; + + break; + + case STATE_CHANGE_TYPE_RESET: + + ResetComplete=TRUE; + + break; + + case STATE_CHANGE_TYPE_STALL_CLEAR: + + StallClear=TRUE; + + break; + + default: + + ASSERT(0); + break; + } + + if (ResetComplete) + { + if ((Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) && Adapter->AdapterState.Started) + { + // + // powered up, start send queue + // + DrainComplete( &(Adapter->SendQueue.QueueDrainObject) ); + + } + + TempStatus=StateChange->Reset.PipeStartStatus; + + MbbWriteEvent( + &RESET_COMPLETE_EVENT, + NULL, + NULL, + 2, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &TempStatus, + sizeof(TempStatus) + ); + + + if (!NT_SUCCESS(StateChange->Reset.PipeStartStatus)) + { + TraceError(WMBCLASS_INIT, "Reset failed %!STATUS!",StateChange->Reset.PipeStartStatus); + } + + NdisMResetComplete( + Adapter->MiniportAdapterHandle, + StateChange->Reset.PipeStartStatus, + FALSE + ); + + + } + + + if (Request) + { + TraceInfo(WMBCLASS_INIT, "Completing set power request"); + + MbbReqMgrQueueEvent( + Request->RequestManager, + Request, + MbbRequestEventSendComplete, + (PVOID)(NDIS_STATUS_SUCCESS), + 0 + ); + } + + + if (CompletePause) + { + TraceInfo(WMBCLASS_INIT, "Completing Pause"); + + MbbWriteEvent( + &PAUSE_COMPLETE_EVENT, + NULL, + NULL, + 2, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &TempStatus, + sizeof(TempStatus) + ); + + + NdisMPauseComplete(Adapter->MiniportAdapterHandle); + } + + if (StallClear) + { + TraceInfo(WMBCLASS_INIT, "Stall cleared"); + + MbbAdapterLock(Adapter); + + Adapter->AdapterState.Hung=FALSE; + KeSetEvent(&Adapter->AdapterState.StallClearCompleteEvent, IO_NO_INCREMENT, FALSE); + + MbbAdapterUnlock(Adapter); + + } + + Adapter->AdapterState.RunningEvent=NULL; + + CompleteStateChange( + &Adapter->AdapterState, + StateChange + ); + + NdisAcquireSpinLock(&Adapter->Lock); + } + + NdisReleaseSpinLock(&Adapter->Lock); + + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); + + return; +} + + +NDIS_STATUS +MbbNdisMiniportPause( + __in NDIS_HANDLE MiniportAdapterContext, + __in PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters + ) + +{ + + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + PSTATE_CHANGE_EVENT StateChange=NULL; + NDIS_STATUS Status=STATUS_INSUFFICIENT_RESOURCES; + + UNREFERENCED_PARAMETER(MiniportPauseParameters); + + PAGED_CODE(); + + MbbWriteEvent( + &PAUSE_EVENT, + NULL, + NULL, + 1, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance) + ); + + + StateChange = AllocateStateChangeEvent(&Adapter->AdapterState); + + if (StateChange != NULL) + { + StateChange->EventType=STATE_CHANGE_TYPE_PAUSE; + StateChange->Context1=Adapter; + + QueueStateChangeEvent(&Adapter->AdapterState,StateChange); + + Status= STATUS_PENDING; + + } + + + MbbWriteEvent( + &PAUSE_EXIT_EVENT, + NULL, + NULL, + 2, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &Status, + sizeof(Status) + ); + + + return Status; +} + + + +NDIS_STATUS +MbbNdisMiniportRestart( + __in NDIS_HANDLE MiniportAdapterContext, + __in PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters + ) + +{ + + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + NDIS_STATUS Status=STATUS_INSUFFICIENT_RESOURCES; + PSTATE_CHANGE_EVENT StateChange=NULL; + + UNREFERENCED_PARAMETER(MiniportRestartParameters); + + PAGED_CODE(); + + MbbWriteEvent( + &RESTART_EVENT, + NULL, + NULL, + 1, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance) + ); + + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] RESUMING Adapter=0x%p", Adapter ); + + StateChange = AllocateStateChangeEvent(&Adapter->AdapterState); + + if (StateChange != NULL) + { + StateChange->EventType=STATE_CHANGE_TYPE_RESTART; + StateChange->Context1=Adapter; + + QueueStateChangeEvent(&Adapter->AdapterState,StateChange); + + Status=STATUS_PENDING; + } + else + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to resume Adapter=0x%p", Adapter ); + } + + + MbbWriteEvent( + &RESTART_EXIT_EVENT, + NULL, + NULL, + 2, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &Status, + sizeof(Status) + ); + + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] RESUMING Adapter=0x%p Complete", Adapter); + + return Status; + +} + + + +VOID +MbbNdisMiniportDevicePnPEventNotify( + __in NDIS_HANDLE MiniportAdapterContext, + __in PNET_DEVICE_PNP_EVENT NetDevicePnPEvent + ) + +{ + + PMBB_REQUEST_MANAGER RequestManager; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MiniportAdapterContext; + + PAGED_CODE(); + + if( NetDevicePnPEvent->DevicePnPEvent == NdisDevicePnPEventSurpriseRemoved ) + { + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] SURPRISE_REMOVAL Adapter=0x%p. Cancelling OID requests", Adapter ); + // The Surprise Removed Flag is not used anywhere. It is just there for debugging purposes, so no need to set it under a lock + Adapter->SurpriseRemoved = TRUE; + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to reference RequestManager for SURPRISE_REMOVAL" ); + return; + } + // Adapter Now Surprise removed, so now close the Request Manager so that no more requests are allowed + // Pass that information to the MbbRrqMgrCancelRequests Call + MbbReqMgrCancelRequests( RequestManager, TRUE); + MbbReqMgrDeref( RequestManager ); + } + + return ; +} + +// +// Driver routines +// +_Acquires_lock_( Driver->AdapterListLock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, Driver ) +VOID +MbbDriverLockAdapterList( + __in PMINIPORT_DRIVER_CONTEXT Driver + ) +{ + NdisAcquireSpinLock( &Driver->AdapterListLock ); +} + +_Releases_lock_( Driver->AdapterListLock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, Driver ) +VOID +MbbDriverUnlockAdapterList( + __in PMINIPORT_DRIVER_CONTEXT Driver + ) +{ + NdisReleaseSpinLock( &Driver->AdapterListLock ); +} + +VOID +MbbDriverAddAdapter( + __in PMINIPORT_DRIVER_CONTEXT Driver, + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + MbbDriverLockAdapterList( Driver ); + InsertTailList( &Driver->AdapterList, &Adapter->DriverLink ); + MbbAdapterRef( Adapter ); + MbbDriverUnlockAdapterList( Driver ); +} + +VOID +MbbDriverRemoveAdapter( + __in PMINIPORT_DRIVER_CONTEXT Driver, + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + MbbDriverLockAdapterList( Driver ); + RemoveEntryList( &Adapter->DriverLink ); + MbbAdapterDeref( Adapter ); + MbbDriverUnlockAdapterList( Driver ); +} + +PMINIPORT_ADAPTER_CONTEXT +MbbDriverFindAdapterByNetLuid( + __in PMINIPORT_DRIVER_CONTEXT Driver, + __in PNET_LUID NetLuid + ) +{ + PLIST_ENTRY ListEntry; + PMINIPORT_ADAPTER_CONTEXT Adapter; + + MbbDriverLockAdapterList( Driver ); + for( ListEntry = Driver->AdapterList.Flink, Adapter = NULL; + ListEntry != &Driver->AdapterList; + ListEntry = ListEntry->Flink, Adapter = NULL ) + { + Adapter = CONTAINING_RECORD( + ListEntry, + MINIPORT_ADAPTER_CONTEXT, + DriverLink + ); + if( RtlCompareMemory( + &Adapter->NetLuid, + NetLuid, + sizeof(NET_LUID) + ) == sizeof(NET_LUID) ) + { + MbbAdapterRef( Adapter ); + break; + } + } + MbbDriverUnlockAdapterList( Driver ); + + return Adapter; +} + +NDIS_STATUS +MbbNdisAdapterReadParameters( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + NDIS_HANDLE ConfigurationHandle = NULL; + PNDIS_CONFIGURATION_PARAMETER pParameter = NULL; + NDIS_STRING NetCfgGuid = RTL_CONSTANT_STRING(MBB_REGVAL_NETCFGID); + NDIS_STRING NameOverride = RTL_CONSTANT_STRING(MBB_REGVAL_OVERRIDE_NAME); + NDIS_STRING RadioOffRegString = RTL_CONSTANT_STRING(MBB_REGVAL_RADIO_OFF); + NDIS_CONFIGURATION_OBJECT ConfigObject; + + do + { + // + // Open the registry for this adapter to read advanced + // configuration parameters stored by the INF file. + // + ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; + ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; + ConfigObject.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT); + ConfigObject.NdisHandle = Adapter->MiniportAdapterHandle; + ConfigObject.Flags = 0; + + if( (NdisStatus = NdisOpenConfigurationEx( + &ConfigObject, + &ConfigurationHandle + ))!= NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to open configuration, status=%!STATUS!", NdisStatus ); + break; + } + + // NetCfgInstanceId + NdisReadConfiguration( + &NdisStatus, + &pParameter, + ConfigurationHandle, + &NetCfgGuid, + NdisParameterString + ); + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to read NetCfgId, status=%!STATUS!", NdisStatus ); + break; + } + if( (NdisStatus = RtlGUIDFromString( + &pParameter->ParameterData.StringData, + &Adapter->NetCfgId + )) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to convert NetCfgId string to guid, status=%!STATUS!", NdisStatus ); + break; + } + + // DeviceNameOverride + NdisReadConfiguration( + &NdisStatus, + &pParameter, + ConfigurationHandle, + &NameOverride, + NdisParameterInteger + ); + + if ( NdisStatus == NDIS_STATUS_SUCCESS ) + { + if (pParameter->ParameterType == NdisParameterInteger) + { + Adapter->OverrideDeviceName = pParameter->ParameterData.IntegerData != 0; + + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Name override set to %d", Adapter->OverrideDeviceName); + } + } + else + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to read name override setting, status=%!STATUS!", NdisStatus ); + NdisStatus = NDIS_STATUS_SUCCESS; + } + + // RadioState: Default = ON + Adapter->RadioOff = FALSE; + NdisReadConfiguration( + &NdisStatus, + &pParameter, + ConfigurationHandle, + &RadioOffRegString, + NdisParameterInteger + ); + + if ( NdisStatus == NDIS_STATUS_SUCCESS ) + { + if (pParameter->ParameterType == NdisParameterInteger) + { + // Non zero value in registry means the radio should be OFF + Adapter->RadioOff = (pParameter->ParameterData.IntegerData != 0); + + TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Persisted radio state %s", Adapter->RadioOff ? "OFF" : "ON"); + } + } + else + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to read radio state, status=%!STATUS!", NdisStatus ); + NdisStatus = NDIS_STATUS_SUCCESS; + } + + } + while(FALSE); + + if( ConfigurationHandle != NULL ) + { + NdisCloseConfiguration( ConfigurationHandle ); + } + + return NdisStatus; +} + +void +NTAPI MbbDumpAdapterState( + _In_ LPCGUID SourceId, + _In_ ULONG IsEnabled, + _In_ UCHAR Level, + _In_ ULONGLONG MatchAnyKeyword, + _In_ ULONGLONG MatchAllKeywords, + _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, + _In_opt_ PVOID CallbackContext +) +{ + if(IsEnabled == EVENT_CONTROL_CODE_CAPTURE_STATE) + { + PLIST_ENTRY ListEntry; + PMINIPORT_ADAPTER_CONTEXT* Adapters = NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + PMINIPORT_DRIVER_CONTEXT Driver = &GlobalControl; + ULONG numberOfAdapters = 0, x = 0, y = 0; + + do + { + // Get the adapter context + MbbDriverLockAdapterList( Driver ); + + for( ListEntry = Driver->AdapterList.Flink, Adapter = NULL; + ListEntry != &Driver->AdapterList; + ListEntry = ListEntry->Flink, Adapter = NULL ) + { + if((Adapter = CONTAINING_RECORD( + ListEntry, + MINIPORT_ADAPTER_CONTEXT, + DriverLink + ))!=NULL) + { + numberOfAdapters++; + } + } + + if(numberOfAdapters == 0) + { + MbbDriverUnlockAdapterList( Driver ); + break; + } + + // Allocate an array of pointers + Adapters = ALLOCATE_NONPAGED_POOL(sizeof(Adapter) * numberOfAdapters); + + if(Adapters == NULL) + { + MbbDriverUnlockAdapterList( Driver ); + break; + } + + NdisZeroMemory(Adapters, sizeof(Adapter) * numberOfAdapters); + + numberOfAdapters = 0; + + for( ListEntry = Driver->AdapterList.Flink, Adapter = NULL; + ListEntry != &Driver->AdapterList; + ListEntry = ListEntry->Flink, Adapter = NULL ) + { + if((Adapter = CONTAINING_RECORD( + ListEntry, + MINIPORT_ADAPTER_CONTEXT, + DriverLink + ))!=NULL) + { + Adapters[numberOfAdapters++] = Adapter; + + // Take a ref on the adapter so that it doesnt + // get cleaned up while processing + MbbAdapterRef(Adapter); + } + } + + MbbDriverUnlockAdapterList( Driver ); + + // Now log the state of each adapter + for(x = 0; x < numberOfAdapters; x++) + { + MBB_CELLULAR_CLASS AdapterSupportedCellularClass; + MBB_CELLULAR_CLASS AdapterCurrentCellularClass; + ULONG MaxActivatedContexts = 0; + ULONG NumberOfPorts = 0; + PMBB_PORT* PortList = NULL; + ULONG RefCount = 0; + ULONG PendingRequests = 0; + BOOL RadioOff = TRUE; + + Adapter = Adapters[x]; + + MbbAdapterLock(Adapter); + AdapterSupportedCellularClass = Adapter->AdapterSupportedCellularClass; + AdapterCurrentCellularClass = Adapter->AdapterCurrentCellularClass; + MbbAdapterUnlock(Adapter); + + MbbAdapterPortsLock(Adapter); + MaxActivatedContexts = Adapter->MaxActivatedContexts; + NumberOfPorts = Adapter->NumberOfPorts; + PortList = ALLOCATE_NONPAGED_POOL(sizeof(PMBB_PORT) * NumberOfPorts); + + if(PortList == NULL) + { + MbbAdapterPortsUnlock(Adapter); + MbbAdapterDeref(Adapter); + continue; + } + + // Copy the port information of the adapter under adapter ports lock + NdisMoveMemory(PortList, &(Adapter->PortList), sizeof(PMBB_PORT)* NumberOfPorts); + MbbAdapterPortsUnlock(Adapter); + + // Pending request count + MbbReqMgrLockManager(Adapter->RequestManager); + + for( ListEntry = Adapter->RequestManager->PendingRequestQueue.Flink; + ListEntry != &(Adapter->RequestManager->PendingRequestQueue); + ListEntry = ListEntry->Flink) + { + PendingRequests++; + } + + MbbReqMgrUnlockManager(Adapter->RequestManager); + + RadioOff = Adapter->RadioOff; + + InterlockedExchange(&RefCount, Adapter->Reference); + + MbbWriteEvent( + &ADAPTER_CONTEXT, + NULL, + NULL, + 21, + Adapter->FriendlyName.Buffer, + ((Adapter->FriendlyName.Buffer) ? Adapter->FriendlyName.Length + 1 : 0), // 1 + &(Adapter->IfIndex), + sizeof(Adapter->IfIndex), // 2 + Adapter->MACAddress, + MBB_MAC_ADDRESS_LENGTH, // 3 + &(Adapter->NetCfgId), + sizeof(Adapter->NetCfgId), // 4 + &RadioOff, + sizeof(RadioOff), // 5 + &(Adapter->MaxLinkSpeed), + sizeof(Adapter->MaxLinkSpeed), // 6 + &(Adapter->CurrentLinkSpeed), + sizeof(Adapter->CurrentLinkSpeed), // 7 + &(Adapter->UplinkSpeed), + sizeof(Adapter->UplinkSpeed), // 8 + &(Adapter->DownlinkSpeed), + sizeof(Adapter->DownlinkSpeed), // 9 + &(Adapter->AvailableDataClass), + sizeof(Adapter->AvailableDataClass), // 10 + &(Adapter->AvailableDataClassValid), + sizeof(BOOL), // 11 + &AdapterSupportedCellularClass, + sizeof(Adapter->AdapterSupportedCellularClass), // 12 + &AdapterCurrentCellularClass, + sizeof(Adapter->AdapterCurrentCellularClass), // 13 + &(Adapter->GenXmitFramesOk), + sizeof(Adapter->GenXmitFramesOk), // 14 + &(Adapter->Stats.ifOutDiscards), + sizeof(Adapter->Stats.ifOutDiscards), // 15 + &(Adapter->GenRcvFramesOk), + sizeof(Adapter->GenRcvFramesOk), // 16 + &(Adapter->Stats.ifInDiscards), + sizeof(Adapter->Stats.ifInDiscards), // 17 + &MaxActivatedContexts, + sizeof(Adapter->MaxActivatedContexts), // 18 + &NumberOfPorts, + sizeof(Adapter->NumberOfPorts), // 19 + &RefCount, + sizeof(Adapter->Reference), // 20 + &PendingRequests, + sizeof(PendingRequests) // 21 + ); + + MbbAdapterDeref(Adapter); + + // Log port information + for(y = 0; y < NumberOfPorts; y++) + { + NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; + BOOL ConnectionUp = FALSE; + ULONG ConnectionId = 0; + LONG SessionId = MBB_INVALID_SESSION_ID; + ULONG RefCount = 0; + + PMBB_PORT Port = PortList[y]; + + MBB_ACQUIRE_PORT_LOCK(Port); + + PortNumber = Port->PortNumber; + ConnectionUp = Port->ConnectionState.ConnectionUp; + ConnectionId = Port->ConnectionId; + SessionId = Port->SessionId; + + MBB_RELEASE_PORT_LOCK(Port); + + InterlockedExchange(&RefCount, Port->RefCount.RefCount); + + MbbWriteEvent( + &PORT_CONTEXT, + NULL, + NULL, + 5, + &PortNumber, + sizeof(Port->PortNumber), // 1 + &ConnectionUp, + sizeof(ConnectionUp), // 2 + &ConnectionId, + sizeof(Port->ConnectionId), // 3 + &SessionId, + sizeof(Port->SessionId), // 4 + &RefCount, + sizeof(Port->RefCount.RefCount) // 5 + ); + } + + if(PortList != NULL) + { + FREE_POOL(PortList); + PortList = NULL; + } + } + }while(FALSE); + + if(Adapters != NULL) + { + FREE_POOL(Adapters); + Adapters = NULL; + } + } +} + diff --git a/network/wwan/cxwmbclass/port.c b/network/wwan/cxwmbclass/port.c new file mode 100644 index 000000000..d5ca11861 --- /dev/null +++ b/network/wwan/cxwmbclass/port.c @@ -0,0 +1,825 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + port.c + +Abstract: + Implements the functionality needed by ports + +Revision History: + When What + ---------- ---------------------------------------------- + 12-13-2012 Created + +Notes: + +--*/ + +#include "precomp.h" +#include "port.tmh" + +NDIS_STATUS +MbbWwanAllocateBasePort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _Outptr_result_nullonfailure_ PMBB_PORT* Port + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PMBB_PORT newPort = NULL; + + *Port = NULL; + + do + { + // Allocate a PORT data structure + newPort = ALLOCATE_NONPAGED_POOL_WITH_TAG(sizeof(MBB_PORT), MbbPoolTagPort); + + if (newPort == NULL) + { + TraceError(WMBCLASS_OID, "Failed to allocate %d bytes for port\n",sizeof(MBB_PORT)); + Status = NDIS_STATUS_RESOURCES; + break; + } + + // Clear everything + NdisZeroMemory(newPort, sizeof(MBB_PORT)); + + // Allocate memory for fields inside the PORT structure + NdisAllocateSpinLock(&(newPort->Lock)); + + // Reference the adapter since the port is going to be using it + // this reference will be removed in the port cleanup routine + MbbAdapterRef(Adapter); + + // Save the passed data into the PORT + newPort->MiniportAdapterHandle = Adapter->MiniportAdapterHandle; + newPort->Adapter = Adapter; + newPort->State = PortDeactivated; + newPort->PortNumber = DEFAULT_NDIS_PORT_NUMBER; + newPort->SessionId = MBB_INVALID_SESSION_ID; //no active session + + // Return the newly created structure to the caller + *Port = newPort; + }while(FALSE); + + return Status; +} + +VOID +MbbWwanFreeBasePort( + _In_ __drv_freesMem(Mem) PMBB_PORT Port + ) +{ + if(Port != NULL) + { + NdisFreeSpinLock(&(Port->Lock)); + + if( Port->IpAddressInfo != NULL ) + { + FREE_POOL(Port->IpAddressInfo); + } + + // Dereference the adapter + MbbAdapterDeref(Port->Adapter); + + FREE_POOL(Port); + Port = NULL; + } +} + +NDIS_STATUS +MbbWwanAllocatePort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ BOOLEAN fAllocateNdisPort, + _Outptr_result_nullonfailure_ PMBB_PORT* Port + ) +{ + + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PMBB_PORT newPort = NULL; + NDIS_PORT_CHARACTERISTICS portChar; + + *Port = NULL; + + do + { + Status = MbbWwanAllocateBasePort(Adapter, &newPort); + + if (Status != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "Failed to allocate base port structure\n"); + break; + } + + // Initialize the intial reference count to 1 + InitializeRefCount(&newPort->RefCount, MbbWwanFreePort); + + if(fAllocateNdisPort) + { + // Call NDIS to allocate the port + NdisZeroMemory(&portChar, sizeof(NDIS_PORT_CHARACTERISTICS)); + + + portChar.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + portChar.Header.Revision = NDIS_PORT_CHARACTERISTICS_REVISION_1; + portChar.Header.Size = sizeof(NDIS_PORT_CHARACTERISTICS); + + portChar.Flags = NDIS_PORT_CHAR_USE_DEFAULT_AUTH_SETTINGS; + portChar.Type = NdisPortTypeUndefined; + portChar.MediaConnectState = MediaConnectStateUnknown; + portChar.XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; + portChar.RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; + portChar.Direction = NET_IF_DIRECTION_SENDRECEIVE; + portChar.SendControlState = NdisPortControlStateUnknown; + portChar.RcvControlState = NdisPortControlStateUnknown; + portChar.SendAuthorizationState = NdisPortControlStateUncontrolled; // Ignored + portChar.RcvAuthorizationState = NdisPortControlStateUncontrolled; // Ignored + + Status = NdisMAllocatePort(Adapter->MiniportAdapterHandle, &portChar); + + if (Status != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "Failed to allocate NDIS port. Status = 0x%08x\n", Status); + break; + } + + TraceInfo(WMBCLASS_OID, "Associated Port Number %lu with allocated port\n", portChar.PortNumber); + + // Assign the NDIS port number that has been allocated to this port + newPort->PortNumber = portChar.PortNumber; + } + else + { + // means it the default ndis port + newPort->SessionId = 0; + } + + *Port = newPort; + }while(FALSE); + + if(Status != NDIS_STATUS_SUCCESS) + { + if(newPort != NULL) + { + MbbWwanDeallocatePort(newPort); + } + } + + return Status; +} + +VOID +MbbWwanDeallocatePort( + _In_ PMBB_PORT Port + ) +{ + // remove the intial reference count + Dereference(Port); +} + + +VOID +MbbWwanFreePort( + PREF_COUNT RefObj + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PMBB_PORT Port = NULL; + + Port = CONTAINING_RECORD(RefObj, MBB_PORT, RefCount); + + ASSERT(Port!=NULL); + + if(IS_ALLOCATED_PORT_NUMBER(Port->PortNumber)) + { + // Free the NDIS port. We do not manage default NDIS port ( port number 0 ) + Status = NdisMFreePort(Port->Adapter->MiniportAdapterHandle, Port->PortNumber); + ASSERT(Status == NDIS_STATUS_SUCCESS); + } + + // Free the base port structure + MbbWwanFreeBasePort(Port); +} + +// Port will not be deleted while in this function because the caller should take a ref before calling this function. +NDIS_STATUS +MbbWwanActivatePort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + NET_PNP_EVENT_NOTIFICATION NetPnpEventNotification; + NDIS_PORT NdisPort; + PNDIS_PORT_CHARACTERISTICS PortChar; + NDIS_PORT_NUMBER PortNumberToActivate = DEFAULT_NDIS_PORT_NUMBER; + BOOLEAN PortActive = FALSE; + + do + { + if(!Port) + { + Status = NDIS_STATUS_FAILURE; + break; + } + + MBB_ACQUIRE_PORT_LOCK(Port); + + if(!IS_ALLOCATED_PORT_NUMBER(Port->PortNumber)) + { + // we do not handle DEFAULT_NDIS_PORT_NUMBER + Status = NDIS_STATUS_SUCCESS; + MBB_RELEASE_PORT_LOCK(Port); + break; + } + + if(Port->State == PortActivated) + { + TraceInfo(WMBCLASS_OID, "Requested port with ndis port number %lu is already activated",Port->PortNumber); + Status = NDIS_STATUS_SUCCESS; + MBB_RELEASE_PORT_LOCK(Port); + break; + } + + if(Port->State != PortDeactivated) + { + Status = NDIS_STATUS_INVALID_PORT_STATE; + MBB_RELEASE_PORT_LOCK(Port); + break; + } + + // set port state to activating + Port->State = PortActivating; + + PortNumberToActivate = Port->PortNumber; + + MBB_RELEASE_PORT_LOCK(Port); + + NdisZeroMemory(&NetPnpEventNotification, sizeof(NET_PNP_EVENT_NOTIFICATION)); + NdisZeroMemory(&NdisPort, sizeof(NDIS_PORT)); + + NetPnpEventNotification.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NetPnpEventNotification.Header.Revision = NET_PNP_EVENT_NOTIFICATION_REVISION_1; + NetPnpEventNotification.Header.Size = sizeof(NET_PNP_EVENT_NOTIFICATION); + + NetPnpEventNotification.NetPnPEvent.NetEvent = NetEventPortActivation; + + + // Refill the characteristics structure for the port + PortChar = &(NdisPort.PortCharacteristics); + + PortChar->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + PortChar->Header.Revision = NDIS_PORT_CHARACTERISTICS_REVISION_1; + PortChar->Header.Size = sizeof(NDIS_PORT_CHARACTERISTICS); + + PortChar->Flags = NDIS_PORT_CHAR_USE_DEFAULT_AUTH_SETTINGS; + PortChar->Type = NdisPortTypeUndefined; + PortChar->MediaConnectState = MediaConnectStateUnknown; + PortChar->XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; + PortChar->RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; + PortChar->Direction = NET_IF_DIRECTION_SENDRECEIVE; + PortChar->SendControlState = NdisPortControlStateUnknown; + PortChar->RcvControlState = NdisPortControlStateUnknown; + PortChar->SendAuthorizationState = NdisPortControlStateUncontrolled; // Ignored + PortChar->RcvAuthorizationState = NdisPortControlStateUncontrolled; // Ignored + PortChar->PortNumber = PortNumberToActivate; + + + // Single port is being activated + NdisPort.Next = NULL; + + // We need to save a pointer to the NDIS_PORT in the NetPnPEvent::Buffer field + NetPnpEventNotification.NetPnPEvent.Buffer = (PVOID)&NdisPort; + NetPnpEventNotification.NetPnPEvent.BufferLength = sizeof(NDIS_PORT); + + Status = NdisMNetPnPEvent(Port->MiniportAdapterHandle, &NetPnpEventNotification); + + if (Status != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "Failed to activate NDIS port %d. Status = 0x%08x\n", PortNumberToActivate, Status); + } + else + { + TraceInfo( WMBCLASS_OID, "Activated Port Number %d\n", PortNumberToActivate); + PortActive = TRUE; + } + + + MBB_ACQUIRE_PORT_LOCK(Port); + + if(PortActive) + { + // set the port state to activated or reset it to initialized in case of failure + Port->State = PortActivated; + Reference(Port); // for activation + } + else + { + Port->State = PortDeactivated; + } + + MBB_RELEASE_PORT_LOCK(Port); + + }while(FALSE); + + return Status; +} + +NDIS_STATUS +MbbWwanDeactivatePort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + NET_PNP_EVENT_NOTIFICATION NetPnpEventNotification; + NDIS_PORT_NUMBER PortNumberArray[1]; + NDIS_PORT_NUMBER PortNumberToDeactivate = DEFAULT_NDIS_PORT_NUMBER; + + do + { + if(!Port) + { + Status = NDIS_STATUS_FAILURE; + break; + } + + MBB_ACQUIRE_PORT_LOCK(Port); + + if(!IS_ALLOCATED_PORT_NUMBER(Port->PortNumber)) + { + // we do not handle DEFAULT_NDIS_PORT_NUMBER + Status = NDIS_STATUS_SUCCESS; + MBB_RELEASE_PORT_LOCK(Port); + break; + } + + if(Port->State == PortDeactivated) + { + TraceInfo(WMBCLASS_OID, "Requested port with ndis port number %lu is already deactivated",Port->PortNumber); + Status = NDIS_STATUS_SUCCESS; + MBB_RELEASE_PORT_LOCK(Port); + break; + } + + if(Port->State != PortActivated) + { + Status = NDIS_STATUS_INVALID_PORT_STATE; + MBB_RELEASE_PORT_LOCK(Port); + break; + } + + // set port state to deactivating + Port->State = PortDeactivating; + + PortNumberToDeactivate = Port->PortNumber; + + MBB_RELEASE_PORT_LOCK(Port); + + + NdisZeroMemory(&NetPnpEventNotification, sizeof(NET_PNP_EVENT_NOTIFICATION)); + + NetPnpEventNotification.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NetPnpEventNotification.Header.Revision = NET_PNP_EVENT_NOTIFICATION_REVISION_1; + NetPnpEventNotification.Header.Size = sizeof(NET_PNP_EVENT_NOTIFICATION); + + + NetPnpEventNotification.NetPnPEvent.NetEvent = NetEventPortDeactivation; + + // We need to save a pointer to the NDIS_PORT_NUMBER in the NetPnPEvent::Buffer field + PortNumberArray[0] = PortNumberToDeactivate; + NetPnpEventNotification.NetPnPEvent.Buffer = (PVOID)PortNumberArray; + NetPnpEventNotification.NetPnPEvent.BufferLength = sizeof(NDIS_PORT_NUMBER); + + Status = NdisMNetPnPEvent(Port->MiniportAdapterHandle, &NetPnpEventNotification); + + if (Status != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "Failed to deactivate NDIS port %d. Status = 0x%08x\n", PortNumberToDeactivate, Status); + } + else + { + TraceInfo( WMBCLASS_OID, "Deactivated Port Number %d\n", PortNumberToDeactivate); + } + + // set the port state to PortDeactivated, because there is little we can do if the call to NdisMSetPnPEvent fails apart + // from logging the error. Setting the state to PortDeactivated will enable port re-use. + + MBB_ACQUIRE_PORT_LOCK(Port); + + Port->State = PortDeactivated; + + MBB_RELEASE_PORT_LOCK(Port); + + Dereference(Port); // this reference was added for activation + + }while(FALSE); + + return Status; +} + +_Requires_lock_not_held_(&Adapter->PortsLock) +VOID +MbbWwanAddPortToAdapterList( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT* PortToAdd + ) +{ + if(Adapter && PortToAdd && *PortToAdd) + { + MbbAdapterPortsLock(Adapter); + + // Add a reference to the port since now this port is being + // added to the adapter's port list + Reference(*PortToAdd); + + Adapter->PortList[Adapter->NumberOfPorts] = *PortToAdd; + Adapter->NumberOfPorts++; + + MbbAdapterPortsUnlock(Adapter); + } +} + +_Requires_lock_not_held_(&Adapter->PortsLock) +BOOL +MbbWwanRemovePortFromAdapterList( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT PortToRemove +) +{ + ULONG NumberOfPorts = 0; + ULONG i = 0; + BOOLEAN IsPortInAdapterList = FALSE; + + if (Adapter && PortToRemove) + { + MbbAdapterPortsLock(Adapter); + + NumberOfPorts = Adapter->NumberOfPorts; + + if (NumberOfPorts != 0 && NumberOfPorts <= Adapter->MaxActivatedContexts) + { + // first find the index of the port to be deleted in the adapter list + for (i = 0; i < NumberOfPorts; i++) + { + if (Adapter->PortList[i] == PortToRemove) + { + Adapter->PortList[i] = NULL; + IsPortInAdapterList = TRUE; + break; + } + } + + if (IsPortInAdapterList == FALSE) + { + MbbAdapterPortsUnlock(Adapter); + return FALSE; + } + + _Analysis_assume_(NumberOfPorts > 0); + + NumberOfPorts = NumberOfPorts - 1; + + // now shift all the ports after this port to the left + for (; i < NumberOfPorts; i++) + { + Adapter->PortList[i] = Adapter->PortList[i + 1]; + Adapter->PortList[i + 1] = NULL; + } + + // decrement the count of ports + Adapter->NumberOfPorts--; + } + + MbbAdapterPortsUnlock(Adapter); + + // Remove the reference to the port since now this port has been + // removed from the adapter's port list + + Dereference(PortToRemove); + return TRUE; + } + return FALSE; +} +_Requires_lock_not_held_(&Adapter->PortsLock) +PMBB_PORT +MbbWwanTranslatePortNumberToPort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ NDIS_PORT_NUMBER PortNumber + ) +{ + ULONG i = 0; + PMBB_PORT tempPort; + + MbbAdapterPortsLock(Adapter); + + for (i = 0; i < Adapter->NumberOfPorts; i++) + { + tempPort = Adapter->PortList[i]; + + MBB_ACQUIRE_PORT_LOCK(tempPort); + + if (tempPort->PortNumber == PortNumber) + { + // Add a reference and return + Reference(tempPort); + MBB_RELEASE_PORT_LOCK(tempPort); + MbbAdapterPortsUnlock(Adapter); + return tempPort; + } + + MBB_RELEASE_PORT_LOCK(tempPort); + } + + MbbAdapterPortsUnlock(Adapter); + + return NULL; +} + +_Requires_lock_not_held_(&Adapter->PortsLock) +PMBB_PORT +MbbWwanTranslateSessionIdToPort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ ULONG SessionId + ) +{ + ULONG i = 0; + PMBB_PORT tempPort = NULL; + + do + { + if(SessionId == MBB_INVALID_SESSION_ID) + { + break; + } + + MbbAdapterPortsLock(Adapter); + + for (i = 0; i < Adapter->NumberOfPorts; i++) + { + tempPort = Adapter->PortList[i]; + + MBB_ACQUIRE_PORT_LOCK(tempPort); + + if (tempPort->SessionId == SessionId) + { + // Add a reference and return + Reference(tempPort); + MBB_RELEASE_PORT_LOCK(tempPort); + MbbAdapterPortsUnlock(Adapter); + return tempPort; + } + + MBB_RELEASE_PORT_LOCK(tempPort); + } + + MbbAdapterPortsUnlock(Adapter); + }while(FALSE); + + return NULL; +} + +_Requires_lock_not_held_(&Port->Lock) +VOID +MbbWwanSetPortConnectionId( + __in PMBB_PORT Port, + __in ULONG ConnectionId + ) +{ + if(Port != NULL) + { + MBB_ACQUIRE_PORT_LOCK(Port); + Port->ConnectionId = ConnectionId; + MBB_RELEASE_PORT_LOCK(Port); + } +} + +_Requires_lock_not_held_(&Port->Lock) +ULONG +MbbWwanGetPortConnectionId( + __in PMBB_PORT Port + ) +{ + ULONG ConnectionId = 0; + + if(Port != NULL) + { + MBB_ACQUIRE_PORT_LOCK(Port); + ConnectionId = Port->ConnectionId; + MBB_RELEASE_PORT_LOCK(Port); + } + + return ConnectionId; +} + +_Requires_lock_not_held_(&Port->Lock) +NDIS_STATUS +MbbWwanSetPortSessionId( + __in PMBB_PORT Port + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + + ULONG MaxActivatedContexts = 0; + BOOLEAN fSessionIdFound = FALSE; + UINT i = 0; + + if(!Port) + { + return NDIS_STATUS_INVALID_PARAMETER; + } + + Adapter = Port->Adapter; + + MbbAdapterPortsLock(Adapter); + MaxActivatedContexts = Adapter->MaxActivatedContexts; + MbbAdapterPortsUnlock(Adapter); + + // Get a session Id and assign it to the port + MbbAdapterSessionIdPortTableLock(Adapter); + + MBB_ACQUIRE_PORT_LOCK(Port); + + if(Port->PortNumber == DEFAULT_NDIS_PORT_NUMBER) + { + if(MaxActivatedContexts >= 1) + { + // We dont check for Adapter->SessionIdPortTable[0].InUse flag here + // because if we send a connect request to the device with a session Id that + // is already connected, the device is supposed to succeed the call as per the MBIM spec. + // Also this is existing Win8 behavior. + + Port->SessionId = MBB_DEFAULT_SESSION_ID; + fSessionIdFound = TRUE; + } + else + { + TraceError( WMBCLASS_UTIL, "[MbbWwanSetPortSessionId] Device should support atleast 1 context"); + } + } + else + { + for(i = 1; i < MaxActivatedContexts; i++) + { + // We check for Adapter->SessionIdPortTable[0].InUse flag here because + // at this instant there can be multiple PDP contexts connected and we need to + // find an available session Id that can be used for this new PDP context. + + if(!Adapter->SessionIdPortTable[i].InUse) + { + // free session id slot + Port->SessionId = i; + fSessionIdFound = TRUE; + break; + } + } + } + + if(fSessionIdFound) + { + Adapter->SessionIdPortTable[Port->SessionId].InUse = TRUE; + Adapter->SessionIdPortTable[Port->SessionId].PortNumber = Port->PortNumber; + } + else + { + Status = NDIS_STATUS_FAILURE; + } + + MBB_RELEASE_PORT_LOCK(Port); + + MbbAdapterSessionIdPortTableUnlock(Adapter); + + return Status; +} + +_Requires_lock_not_held_(&Port->Lock) +LONG +MbbWwanGetPortSessionId( + __in PMBB_PORT Port + ) +{ + LONG SessionId = MBB_INVALID_SESSION_ID; + + if(Port != NULL) + { + MBB_ACQUIRE_PORT_LOCK(Port); + SessionId = Port->SessionId; + MBB_RELEASE_PORT_LOCK(Port); + } + + return SessionId; +} + +_Requires_lock_not_held_(&Port->Lock) +VOID +MbbWwanResetPortSessionId( + __in PMBB_PORT Port, + __in BOOLEAN ReturnSessionId + ) +{ + if(Port != NULL) + { + PMINIPORT_ADAPTER_CONTEXT Adapter = Port->Adapter; + ULONG SessionId = (ULONG)MBB_INVALID_SESSION_ID; + + MBB_ACQUIRE_PORT_LOCK(Port); + SessionId = Port->SessionId; + + // set the session id of the default port to 0 always. + // this is because when service starts, get connection + // state requests arrive on Port no 0. If the session id + // is set to -1, these requests will fail. + + Port->SessionId = (IS_ALLOCATED_PORT_NUMBER(Port->PortNumber)) ? + MBB_INVALID_SESSION_ID : MBB_DEFAULT_SESSION_ID ; + MBB_RELEASE_PORT_LOCK(Port); + + TraceInfo( WMBCLASS_UTIL, "[MbbWwanResetPortSessionId] Resetting Port session ID for port number %lu. Session ID: [%lu] -> [%lu]", Port->PortNumber, SessionId, Port->SessionId); + + if(ReturnSessionId) + { + // this implies that a session id was actually alloted + // to this port. Hence it needs to be returned. + MbbWwanReturnSessionId(Adapter,SessionId); + } + else + { + TraceInfo( WMBCLASS_UTIL, "[MbbWwanResetPortSessionId] Not returning session id = %d to adapter for port number %lu. This may be expected.", SessionId, Port->PortNumber); + } + } +} + +_Requires_lock_not_held_(&Adapter->PortsLock) +_Requires_lock_not_held_(&Adapter->SessionIdPortTableLock) +NDIS_STATUS +MbbWwanReturnSessionId( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in ULONG SessionId) +{ + + ULONG MaxActivatedContexts = 0; + + /* SessionId is acquired whenever a context activation request comes. + * But it is returned in the following cases: + * 1) Successful context deactivation. + * 2) Failed context activation attempt. + * 3) When port is torn down before context deactivation. + */ + + MbbAdapterPortsLock(Adapter); + MaxActivatedContexts = Adapter->MaxActivatedContexts; + MbbAdapterPortsUnlock(Adapter); + + if(SessionId != MBB_INVALID_SESSION_ID + && SessionId < MaxActivatedContexts) + { + TraceInfo( WMBCLASS_UTIL, "[MbbWwanReturnSessionId] Returning session id %lu to adapter",SessionId); + + MbbAdapterSessionIdPortTableLock(Adapter); + + Adapter->SessionIdPortTable[SessionId].InUse = FALSE; + Adapter->SessionIdPortTable[SessionId].PortNumber = (ULONG)MBB_INVALID_PORT_NUMBER; + + MbbAdapterSessionIdPortTableUnlock(Adapter); + } + + return NDIS_STATUS_SUCCESS; +} + +_Requires_lock_not_held_(&Adapter->PortsLock) +DWORD +MbbWwanGetNumPortsConnected( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ) +{ + ULONG NumConnectedPorts = 0; + ULONG i = 0; + + if(Adapter) + { + MbbAdapterPortsLock(Adapter); + + for(i = 0; i < Adapter->NumberOfPorts && NumConnectedPorts < MBB_MAX_NUMBER_OF_PORTS; i++) + { + PMBB_PORT Port = Adapter->PortList[i]; + + MBB_ACQUIRE_PORT_LOCK(Port); + + if(Port->ConnectionState.ConnectionUp) + { + ASSERT(Port->SessionId != MBB_INVALID_SESSION_ID && (ULONG)Port->SessionId < Adapter->MaxActivatedContexts); + NumConnectedPorts++; + } + + MBB_RELEASE_PORT_LOCK(Port); + } + + MbbAdapterPortsUnlock(Adapter); + } + + return NumConnectedPorts; +} + diff --git a/network/wwan/cxwmbclass/port.h b/network/wwan/cxwmbclass/port.h new file mode 100644 index 000000000..fd54b0e4b --- /dev/null +++ b/network/wwan/cxwmbclass/port.h @@ -0,0 +1,252 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + port.h + +Abstract: + Contains port declarations. + +Revision History: + When What + ---------- ---------------------------------------------- + 11-21-2012 Created + +Notes: + +--*/ +#pragma once + +#define DEFAULT_NDIS_PORT_NUMBER 0 + +// port lock manipulation macros +#define MBB_ACQUIRE_PORT_LOCK(_Port) \ + NdisAcquireSpinLock(&(_Port->Lock)) + +#define MBB_RELEASE_PORT_LOCK(_Port) \ + NdisReleaseSpinLock(&(_Port->Lock)) + +#define MBB_PORT_SET_SESSION_ID(_Port,_SessionId) \ + (_Port)->SessionId = (_SessionId) + +#define MBB_PORT_RESET_SESSION_ID(_Port) \ + (_Port)->SessionId = MBB_INVALID_SESSION_ID + + +typedef struct _REF_COUNT *PREF_COUNT; + +typedef VOID (*REFERENCE_OBJECT_CLEANUP_FN)(PREF_COUNT RefObj); + + +typedef struct _REF_COUNT +{ + ULONG RefCount; + REFERENCE_OBJECT_CLEANUP_FN Cleanup; +} REF_COUNT, *PREF_COUNT; + + +LONG +__inline ReferenceRefCount(PREF_COUNT RefCountObj) +{ + LONG newRef = InterlockedIncrement((volatile LONG *)&RefCountObj->RefCount); + ASSERT(newRef > 0); + + return newRef; +} + +LONG +__inline DereferenceRefCount(PREF_COUNT RefCountObj) +{ + LONG newRef = InterlockedDecrement((volatile LONG *)&RefCountObj->RefCount); + + ASSERT(newRef >= 0); + + if( newRef == 0 ) + { + RefCountObj->Cleanup(RefCountObj); + } + + return newRef; +} + +#define Reference(x) ReferenceRefCount(&(x)->RefCount) + +#define Dereference(x) DereferenceRefCount(&(x)->RefCount) + +VOID +__inline InitializeRefCount( + IN PREF_COUNT RefCountObj, + IN REFERENCE_OBJECT_CLEANUP_FN CleanupFn +) +{ + RefCountObj->Cleanup = CleanupFn; + RefCountObj->RefCount= 1; +} + + +// Just a busy wait for PortList refcount to go to 0 +//#define MBB_WAIT_FOR_PORTLIST_REFCOUNT(_Adapter) \ + // MP_VERIFY_PASSIVE_IRQL(); \ + // while (_Adapter->PortRefCount != 0) NdisMSleep(10); +// Macro to verify if this port number is allocated/"registered" with NDIS + +#define IS_ALLOCATED_PORT_NUMBER(_PortNumber) (_PortNumber != DEFAULT_NDIS_PORT_NUMBER) + +typedef enum _MBB_PORT_STATE +{ + PortDeactivated = 0, + PortActivating, + PortActivated, + PortDeactivating +} MBB_PORT_STATE; + + +typedef struct _MBB_PORT +{ + /** + * The handle by which NDIS recognizes this adapter. This handle needs to be passed + * in for many of the calls made to NDIS + */ + NDIS_HANDLE MiniportAdapterHandle; + + PMINIPORT_ADAPTER_CONTEXT Adapter; // Miniport adapter context + + NDIS_PORT_NUMBER PortNumber; // NDIS allocate port number + + /** State of the PORT.*/ + MBB_PORT_STATE State; + + UCHAR MACAddress[MBB_MAC_ADDRESS_LENGTH]; + + /** Refcount tracking operations that would block Pause/Restart, etc operations */ + REF_COUNT RefCount;// Used by Port/MP + + ULONG ConnectionId; + + LONG SessionId; + + MBB_CONNECTION_STATE ConnectionState; + + PMBB_IP_ADDRESS_INFO IpAddressInfo; + + BOOLEAN HasNoMatchWolPattern; + + /** Lock used to protect the PORT data including PortNumber, State and ConnectionCtx*/ + NDIS_SPIN_LOCK Lock; +} MBB_PORT, *PMBB_PORT; + +NDIS_STATUS +MbbWwanAllocateBasePort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _Outptr_result_nullonfailure_ PMBB_PORT* Port + ); + +VOID +MbbWwanFreeBasePort( + _In_ __drv_freesMem(Mem) PMBB_PORT Port + ); + +NDIS_STATUS +MbbWwanAllocatePort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ BOOLEAN fAllocateNdisPort, + _Outptr_result_nullonfailure_ PMBB_PORT* Port + ); + + +VOID +MbbWwanDeallocatePort( + _In_ PMBB_PORT Port + ); + +VOID +MbbWwanFreePort( + _In_ PREF_COUNT RefObj + ); + +NDIS_STATUS +MbbWwanActivatePort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port + ); + +NDIS_STATUS +MbbWwanDeactivatePort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port + ); + +_Requires_lock_not_held_(&Adapter->PortsLock) +VOID +MbbWwanAddPortToAdapterList( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT* PortToAdd + ); + +_Requires_lock_not_held_(&Adapter->PortsLock) +BOOL +MbbWwanRemovePortFromAdapterList( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT PortToRemove + ); + +_Requires_lock_not_held_(&Adapter->PortsLock) +PMBB_PORT +MbbWwanTranslatePortNumberToPort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ NDIS_PORT_NUMBER PortNumber + ); + +_Requires_lock_not_held_(&Adapter->PortsLock) +PMBB_PORT +MbbWwanTranslateSessionIdToPort( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ ULONG SessionId + ); + +_Requires_lock_not_held_(&Port->Lock) +VOID +MbbWwanSetPortConnectionId( + __in PMBB_PORT Port, + __in ULONG ConnectionId + ); + +_Requires_lock_not_held_(&Port->Lock) +ULONG +MbbWwanGetPortConnectionId( + __in PMBB_PORT Port + ); + +_Requires_lock_not_held_(&Port->Lock) +NDIS_STATUS +MbbWwanSetPortSessionId( + __in PMBB_PORT Port + ); + +_Requires_lock_not_held_(&Port->Lock) +LONG +MbbWwanGetPortSessionId( + __in PMBB_PORT Port + ); + +_Requires_lock_not_held_(&Port->Lock) +VOID +MbbWwanResetPortSessionId( + __in PMBB_PORT Port, + __in BOOLEAN ReturnSessionId + ); + +_Requires_lock_not_held_(&Adapter->PortsLock) +_Requires_lock_not_held_(&Adapter->SessionIdPortTableLock) +NDIS_STATUS +MbbWwanReturnSessionId( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in ULONG SessionId + ); + +_Requires_lock_not_held_(&Adapter->PortsLock) +DWORD +MbbWwanGetNumPortsConnected( + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); diff --git a/network/wwan/cxwmbclass/precomp.h b/network/wwan/cxwmbclass/precomp.h new file mode 100644 index 000000000..c825e4d40 --- /dev/null +++ b/network/wwan/cxwmbclass/precomp.h @@ -0,0 +1,44 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define INITGUID +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "wmbclass.h" +#include "port.h" +#include "WwanDrvCmn.h" +#include "adapter.h" +#include "send.h" +#include "receive.h" +#include "RequestManager.h" +#include "IpAddress.h" +#include "IpAddressCmn.h" +#include "util.h" +#include "MbbFastIODataPlane.h" +#include "MbbFastIOControlPlane.h" +#include diff --git a/network/wwan/cxwmbclass/product.pbxproj b/network/wwan/cxwmbclass/product.pbxproj new file mode 100644 index 000000000..8de56fe44 --- /dev/null +++ b/network/wwan/cxwmbclass/product.pbxproj @@ -0,0 +1,13 @@ + + + + v110 + Utility + + + + + false + + + \ No newline at end of file diff --git a/network/wwan/cxwmbclass/receive.c b/network/wwan/cxwmbclass/receive.c new file mode 100644 index 000000000..078fe8109 --- /dev/null +++ b/network/wwan/cxwmbclass/receive.c @@ -0,0 +1,1961 @@ +/*************************************************************************** + +Copyright (c) 2010 Microsoft Corporation + +Module Name: + Receive.c + +Abstract: + This module contains routines that parse data coming from the network. + Verifications on the receive path are very light. Alignment checks and + max size checks are not made. These constraints are meant for the device + rather than for the host. NTBs are only checked for buffer overflow and + malformed data. + +Environment: + kernel mode only + +Notes: + +Revision History: + 3/22/2011 : created + +Authors: + TriRoy + +****************************************************************************/ + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" +#include "receive.tmh" + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#define MBB_ETHER_TYPE_IPV4 0x0800 +#define MBB_ETHER_TYPE_IPV6 0x86dd + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// TYPEDEFS +// +//////////////////////////////////////////////////////////////////////////////// + +typedef struct _MBB_NDIS_RECEIVE_NDP_CONTEXT +{ + LIST_ENTRY NblQueue; + // + // Resources + // + PNET_BUFFER_LIST FirstNbl; + PNET_BUFFER_LIST CurrentNbl; + ULONG NblCount; + + SESSIONID_PORTNUMBER_ENTRY SessionIdPortNumberEntry; +}MBB_NDIS_RECEIVE_NDP_CONTEXT,*PMBB_NDIS_RECEIVE_NDP_CONTEXT; + +typedef struct _MBB_NDIS_RECEIVE_CONTEXT +{ + LIST_ENTRY ReceivedQLink; + NDIS_SPIN_LOCK Lock; + + // + // Protected by lock + // + + MBB_NDIS_RECEIVE_NDP_CONTEXT ReceiveNdpContext[MBB_MAX_NUMBER_OF_PORTS]; + + // + // Resources + // + PMDL Mdl; + PNPAGED_LOOKASIDE_LIST ReceiveLookasideList; + PMBB_RECEIVE_QUEUE RecvQueue; + PMINIPORT_ADAPTER_CONTEXT AdapterContext; + MBB_BUS_HANDLE BusHandle; + MBB_RECEIVE_CONTEXT BusContext; + // + // Parse state + // + ULONG NtbSequence; + +} MBB_NDIS_RECEIVE_CONTEXT, +*PMBB_NDIS_RECEIVE_CONTEXT; + +typedef struct _MBB_NBL_RECEIVE_CONTEXT +{ + LIST_ENTRY NblQLink; + PNET_BUFFER_LIST NetBufferList; + PMBB_NDIS_RECEIVE_CONTEXT Receive; +} MBB_NBL_RECEIVE_CONTEXT, +*PMBB_NBL_RECEIVE_CONTEXT; + +typedef +__callback NDIS_STATUS +(*MBB_NDP_CALLBACK)( + __in PVOID Nth, + __in PVOID Ndp, + __in PVOID Context + ); + +typedef +__callback NDIS_STATUS +(*MBB_DATAGRAM_CALLBACK)( + __in PVOID Nth, + __in ULONG NdpSignature, + __in PVOID Datagram, + __in ULONG DatagramLength, + __in ULONG SessionId, + __in PVOID Context + ); + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// PROTOTYPES +// +//////////////////////////////////////////////////////////////////////////////// + +// +// NTB +// + +NDIS_STATUS +MbbNtbValidate( + __in PVOID Nth, + __in ULONG BufferLength, + __in BOOLEAN Is32Bit + ); + +NDIS_STATUS +MbbNtbParse( + __in PVOID Nth, + __in ULONG BufferLength, + __in MBB_NDP_CALLBACK Callback, + __in PVOID Context + ); + +// +// NTB32 +// + +// Validation + +NDIS_STATUS +MbbNtbValidateNth32( + __in PNCM_NTH32 Nth, + __in ULONG BufferLength + ); + +NDIS_STATUS +MbbNtbValidateNdp32( + __in PNCM_NTH32 Nth, + __in PNCM_NDP32 Ndp + ); + +NDIS_STATUS +MbbNtbDetectNdp32Loop( + __in PNCM_NTH32 Nth + ); + +// Parsing + +NDIS_STATUS +MbbNtbParseNth32( + __in PNCM_NTH32 Nth, + __in ULONG BufferLength, + __in MBB_NDP_CALLBACK Callback, + __in PVOID Context + ); + +NDIS_STATUS +MbbNtbParseNdp32( + __in PNCM_NTH32 Nth, + __in PNCM_NDP32 Ndp, + __in MBB_DATAGRAM_CALLBACK Callback, + __in PVOID Context + ); + +// +// NTB16 +// + +// Validation + +NDIS_STATUS +MbbNtbValidateNth16( + __in PNCM_NTH16 Nth, + __in ULONG BufferLength + ); + +NDIS_STATUS +MbbNtbValidateNdp16( + __in PNCM_NTH16 Nth, + __in PNCM_NDP16 Ndp + ); + +NDIS_STATUS +MbbNtbDetectNdp16Loop( + __in PNCM_NTH16 Nth + ); + +// Parsing + +NDIS_STATUS +MbbNtbParseNth16( + __in PNCM_NTH16 Nth, + __in ULONG BufferLength, + __in MBB_NDP_CALLBACK Callback, + __in PVOID Context + ); + +NDIS_STATUS +MbbNtbParseNdp16( + __in PNCM_NTH16 Nth, + __in PNCM_NDP16 Ndp, + __in MBB_DATAGRAM_CALLBACK Callback, + __in PVOID Context + ); + +// +// RecvQ +// + +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( SpinLock, RecvQueue->Lock ) +__drv_when( DispatchLevel == FALSE, __drv_raisesIRQL(DISPATCH_LEVEL)) +FORCEINLINE +VOID +MbbRecvQLock( + __in __drv_at( RecvQueue->Lock, __drv_acquiresResource( Spinlock ) ) + PMBB_RECEIVE_QUEUE RecvQueue, + __in BOOLEAN DispatchLevel + ); + +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( SpinLock, RecvQueue->Lock ) +FORCEINLINE +VOID +MbbRecvQUnlock( + __in __drv_at( RecvQueue->Lock, __drv_releasesResource( Spinlock ) ) + PMBB_RECEIVE_QUEUE RecvQueue, + __in BOOLEAN DispatchLevel + ); + +PMBB_NDIS_RECEIVE_CONTEXT +MbbRecvQQueueReceive( + __in PMBB_RECEIVE_QUEUE RecvQueue, + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_RECEIVE_CONTEXT BusContext, + __in PMDL Mdl + ); + +VOID +MbbRecvQDequeueReceive( + __in PMBB_RECEIVE_QUEUE RecvQueue, + __in PMBB_NDIS_RECEIVE_CONTEXT Receive + ); + +// +// Receive Context +// + +NDIS_STATUS +MbbReceiveParseNdp( + __in PVOID Nth, + __in PVOID Ndp, + __in PVOID Context + ); + +NDIS_STATUS +MbbReceiveAddNbl( + __in PVOID Nth, + __in ULONG NdpSignature, + __in PVOID Datagram, + __in ULONG DatagramLength, + __in ULONG SessionId, + __in PVOID Context + ); + +NDIS_STATUS +MbbReceiveDssData( + __in PVOID Nth, + __in ULONG NdpSignature, + __in PVOID Datagram, + __in ULONG DatagramLength, + __in ULONG SessionId, + __in PVOID Context + ); + +VOID +MbbReceiveRemoveNbl( + __in PMBB_NDIS_RECEIVE_CONTEXT Receive, + __in PNET_BUFFER_LIST NetBufferList + ); + +VOID +MbbReceiveCleanupNbls( + __in PMBB_NDIS_RECEIVE_CONTEXT Receive + ); + +// +// NBL +// + +__drv_allocatesMem(mem) +PNET_BUFFER_LIST +MbbNblAlloc( + __in PVOID Nth, + __in PVOID Datagram, + __in ULONG DatagramLength, + __in PMBB_NDIS_RECEIVE_CONTEXT Receive + ); + +VOID +MbbNblCleanup( + __in PNET_BUFFER_LIST NetBufferList + ); + +// +// CID RESPONSE / INDICATION PARSING +// + +NTSTATUS +MbbNdisProcessCidData( + __in_bcount(Length) PUCHAR Buffer, + __in ULONG Length, + __in PMBB_REQUEST_MANAGER RequestManager + ); + +VOID +MbbNdisProcessDeviceServiceCommandResponse( + __in_bcount(FragmentLength) PUCHAR FragmentBuffer, + __in ULONG FragmentLength, + __in PMBB_REQUEST_MANAGER RequestManager + ); + +VOID +MbbNdisProcessDeviceServiceStatusIndication( + __in_bcount(FragmentLength) PUCHAR FragmentBuffer, + __in ULONG FragmentLength, + __in PMBB_REQUEST_MANAGER RequestManager + ); + +// +// Test +// + +#if DBG + +VOID +MbbTestValidateNblChain( + __in PNET_BUFFER_LIST NblChain + ); + +#endif + + +//////////////////////////////////////////////////////////////////////////////// +// +// IMPLEMENTATION +// +//////////////////////////////////////////////////////////////////////////////// + +// +// NTB +// + +NDIS_STATUS +MbbNtbValidate( + __in PVOID Nth, + __in ULONG BufferLength, + __in BOOLEAN Is32Bit + ) +{ + if( Is32Bit == TRUE ) + return MbbNtbValidateNth32( (PNCM_NTH32)Nth, BufferLength ); + else + return MbbNtbValidateNth16( (PNCM_NTH16)Nth, BufferLength ); +} + +NDIS_STATUS +MbbNtbParse( + __in PVOID Nth, + __in ULONG BufferLength, + __in MBB_NDP_CALLBACK Callback, + __in PVOID Context + ) +/*++ + NOTE: + Assumed that NTH has already been validated. + No validations are performed during parsing. +--*/ +{ + if( MBB_NTB_IS_32BIT( Nth ) ) + { + return MbbNtbParseNth32( + ((PNCM_NTH32)Nth), + BufferLength, + Callback, + Context + ); + } + else if( MBB_NTB_IS_16BIT( Nth ) ) + { + return MbbNtbParseNth16( + ((PNCM_NTH16)Nth), + BufferLength, + Callback, + Context + ); + } + else + { + TraceError( WMBCLASS_RECEIVE, "[NTB][Seq=0x%04x] BAD NTB signature=0x%04x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_SIGNATURE( Nth ) + ); + return NDIS_STATUS_FAILURE; + } +} + +NDIS_STATUS +MbbNtbParseNdp( + __in PVOID Nth, + __in PVOID Ndp, + __in MBB_DATAGRAM_CALLBACK Callback, + __in PVOID CallbackContext + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PMBB_NDIS_RECEIVE_CONTEXT Receive = (PMBB_NDIS_RECEIVE_CONTEXT)CallbackContext; + PMINIPORT_ADAPTER_CONTEXT Adapter = Receive->AdapterContext; + SESSIONID_PORTNUMBER_ENTRY SessionIdPortNumberEntry = {0}; + ULONG SessionId = MBB_INVALID_SESSION_ID; + BOOLEAN IsDeviceServiceStream = FALSE; + + do + { + if( MBB_NTB_IS_32BIT( Nth ) ) + { + if(MBB_NDP32_GET_SIGNATURE_TYPE((PNCM_NDP32)Ndp) == NCM_NDP32_VENDOR) + { + IsDeviceServiceStream = TRUE; + } + else if(MBB_NDP32_GET_SIGNATURE_TYPE((PNCM_NDP32)Ndp) == NCM_NDP32_IPS) + { + SessionId = MBB_NDP32_GET_SESSIONID((PNCM_NDP32)Ndp ); + } + else + { + ASSERT(FALSE); + } + } + else + { + if(MBB_NDP16_GET_SIGNATURE_TYPE((PNCM_NDP16)Ndp) == NCM_NDP16_VENDOR) + { + IsDeviceServiceStream = TRUE; + } + else if(MBB_NDP16_GET_SIGNATURE_TYPE((PNCM_NDP16)(Ndp)) == NCM_NDP16_IPS) + { + SessionId = MBB_NDP16_GET_SESSIONID((PNCM_NDP16)Ndp); + } + else + { + ASSERT(FALSE); + } + } + + if(!IsDeviceServiceStream) + { + if( SessionId >= MBB_MAX_NUMBER_OF_PORTS + || SessionId == MBB_INVALID_SESSION_ID) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature sessionid=%lu for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + SessionId, + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + NdisStatus = NDIS_STATUS_INVALID_PARAMETER; + break; + } + + MbbAdapterSessionIdPortTableLock(Adapter); + + SessionIdPortNumberEntry = Adapter->SessionIdPortTable[SessionId]; + + MbbAdapterSessionIdPortTableUnlock(Adapter); + + if(!SessionIdPortNumberEntry.InUse) + { + //discard + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] FAILED to parse Ndp as session id is not in use.Session Id is %lu", + MBB_NTB_GET_SEQUENCE( Nth ), + SessionId + ); + NdisStatus = NDIS_STATUS_INVALID_PARAMETER; + break; + } + + Receive->ReceiveNdpContext[SessionId].SessionIdPortNumberEntry = SessionIdPortNumberEntry; + } + + if( MBB_NTB_IS_32BIT( Nth ) ) + { + NdisStatus = MbbNtbParseNdp32( + (PNCM_NTH32)Nth, + (PNCM_NDP32)Ndp, + Callback, + CallbackContext + ); + } + else + { + NdisStatus = MbbNtbParseNdp16( + (PNCM_NTH16)Nth, + (PNCM_NDP16)Ndp, + Callback, + CallbackContext + ); + } + }while(FALSE); + + return NdisStatus; +} + +// +// NTB32 +// + +NDIS_STATUS +MbbNtbDetectNdp32Loop( + __in PNCM_NTH32 Nth + ) +{ + PNCM_NDP32 FirstNdp; + PNCM_NDP32 Ndp; + PNCM_NDP32 LoopNdp; + + if( (FirstNdp = MBB_NTH32_GET_FIRST_NDP( Nth )) == NULL ) + return NDIS_STATUS_SUCCESS; + + if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, FirstNdp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, FirstNdp ) + ); + return NDIS_STATUS_FAILURE; + } + LoopNdp = MBB_NDP32_GET_NEXT_NDP( Nth, FirstNdp ); + + for( Ndp = FirstNdp; + Ndp != NULL && LoopNdp != NULL; + Ndp = MBB_NDP32_GET_NEXT_NDP( Nth, Ndp ) ) + { + if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, LoopNdp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, LoopNdp ) + ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, Ndp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + + if( LoopNdp == Ndp ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] Loop detected on NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + + if( (LoopNdp = MBB_NDP32_GET_NEXT_NDP( Nth, LoopNdp )) != NULL ) + { + if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, LoopNdp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, LoopNdp ) + ); + return NDIS_STATUS_FAILURE; + } + LoopNdp = MBB_NDP32_GET_NEXT_NDP( Nth, LoopNdp ); + } + } + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNtbValidateNdp32( + __in PNCM_NTH32 Nth, + __in PNCM_NDP32 Ndp + ) +{ + ULONG Index; + ULONG DatagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp); + PNCM_NDP32_DATAGRAM Datagram; + + if( ! MBB_NTB32_IS_VALID_NDP_SIGNATURE( Ndp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature=0x%08x for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NDP32_GET_SIGNATURE( Ndp ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + + if (MBB_NDP32_GET_SIGNATURE_TYPE( Ndp) == NCM_NDP32_IPS) + { + // + // Check if the session id is valid, else discard + // + + // Check if session Id is greater than maximum supported. Here + // we can also check against MaxActivatedContexts, but this would + // mean we need to take a lock for getting the value of maxactivatedcontexts + // The lock can be avoided by checking against the maximum number of ports + // supported by the class driver. SESSION_PORT_TABLE.InUse can be used + // to check whether the session id is in use. + + if( MBB_NDP32_GET_SESSIONID( Ndp ) >= MBB_MAX_NUMBER_OF_PORTS + || MBB_NDP32_GET_SESSIONID( Ndp ) == MBB_INVALID_SESSION_ID) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature sessionid=0x%02x for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + (UCHAR)MBB_NDP32_GET_SESSIONID( Ndp ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + } + + if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, Ndp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID length=0x%08x for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NDP32_GET_LENGTH( Ndp ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + + for( Index = 0; + Index < DatagramCount; + Index ++ ) + { + if( MBB_NTB32_IS_END_DATAGRAM( Nth, Ndp, Index ) ) + return NDIS_STATUS_SUCCESS; + + if( ! MBB_NTB32_IS_VALID_DATAGRAM( Nth, Ndp, Index ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID datagram at index=%02d for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + Index, + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + } + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNtbValidateNth32( + __in PNCM_NTH32 Nth, + __in ULONG BufferLength + ) +{ + PNCM_NDP32 Ndp; + + if( BufferLength < sizeof(NCM_NTH32) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH Buffer length=0x%08x", BufferLength ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTH32_IS_VALID_SIGNATURE( Nth ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH signature=0x%08x", MBB_NTB_GET_SIGNATURE( Nth ) ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTH32_IS_VALID_HEADER_LENGTH( Nth ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH header length=0x%08x", MBB_NTB_GET_HEADER_LENGTH( Nth ) ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTH32_IS_VALID_BLOCK_LENGTH( Nth, BufferLength ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH block length=0x%08x", MBB_NTH32_GET_BLOCK_LENGTH( Nth ) ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTH32_IS_VALID_FIRST_NDP( Nth ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH first NDP offset=0x%08x", MBB_NTH32_GET_FIRST_NDP_OFFSET( Nth ) ); + return NDIS_STATUS_FAILURE; + } + + if( MbbNtbDetectNdp32Loop( Nth ) != NDIS_STATUS_SUCCESS ) + return NDIS_STATUS_FAILURE; + + for( Ndp = MBB_NTH32_GET_FIRST_NDP( Nth ); + Ndp != NULL; + Ndp = MBB_NDP32_GET_NEXT_NDP( Nth, Ndp ) ) + { + if( MbbNtbValidateNdp32( Nth, Ndp ) != NDIS_STATUS_SUCCESS ) + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNtbParseNdp32( + __in PNCM_NTH32 Nth, + __in PNCM_NDP32 Ndp, + __in MBB_DATAGRAM_CALLBACK Callback, + __in PVOID Context + ) +{ + ULONG Index; + ULONG DatagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp); + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG SessionId = MBB_NDP32_GET_SESSIONID( Ndp ); + + for( Index = 0; + Index < DatagramCount; + Index ++ ) + { + if( MBB_NTB32_IS_END_DATAGRAM( Nth, Ndp, Index ) ) + break; + + if( ! MBB_NTB32_IS_VALID_DATAGRAM( Nth, Ndp, Index ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID datagram at index=%02d for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + Index, + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + + if( (NdisStatus = Callback( + Nth, + MBB_NDP32_GET_SIGNATURE( Ndp ), + MBB_NDP32_GET_DATAGRAM( Nth, Ndp, Index ), + MBB_NDP32_GET_DATAGRAM_LENGTH(Ndp,Index), + SessionId, + Context + )) != NDIS_STATUS_SUCCESS ) + { + break; + } + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNtbParseNth32( + __in PNCM_NTH32 Nth, + __in ULONG BufferLength, + __in MBB_NDP_CALLBACK Callback, + __in PVOID Context + ) +/*++ + NOTE: + Assumed that NTH has already been validated. + No validations are performed during parsing. +--*/ +{ + PNCM_NDP32 Ndp; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + for( Ndp = MBB_NTH32_GET_FIRST_NDP( Nth ); + Ndp != NULL; + Ndp = MBB_NDP32_GET_NEXT_NDP( Nth, Ndp ) ) + { + if( (NdisStatus = Callback( + Nth, + Ndp, + Context + )) != NDIS_STATUS_SUCCESS ) + { + break; + } + } + return NdisStatus; +} + +// +// NTB16 +// + +NDIS_STATUS +MbbNtbDetectNdp16Loop( + __in PNCM_NTH16 Nth + ) +{ + PNCM_NDP16 FirstNdp; + PNCM_NDP16 Ndp; + PNCM_NDP16 LoopNdp; + + if( (FirstNdp = MBB_NTH16_GET_FIRST_NDP( Nth )) == NULL ) + return NDIS_STATUS_SUCCESS; + + if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, FirstNdp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, FirstNdp ) + ); + return NDIS_STATUS_FAILURE; + } + LoopNdp = MBB_NDP16_GET_NEXT_NDP( Nth, FirstNdp ); + + for( Ndp = FirstNdp; + Ndp != NULL && LoopNdp != NULL; + Ndp = MBB_NDP16_GET_NEXT_NDP( Nth, Ndp ) ) + { + if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, LoopNdp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, LoopNdp ) + ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, Ndp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + + if( LoopNdp == Ndp ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] Loop detected on NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + + if( (LoopNdp = MBB_NDP16_GET_NEXT_NDP( Nth, LoopNdp )) != NULL ) + { + if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, LoopNdp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, LoopNdp ) + ); + return NDIS_STATUS_FAILURE; + } + LoopNdp = MBB_NDP16_GET_NEXT_NDP( Nth, LoopNdp ); + } + } + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNtbValidateNdp16( + __in PNCM_NTH16 Nth, + __in PNCM_NDP16 Ndp + ) +{ + ULONG Index; + ULONG DatagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp); + PNCM_NDP16_DATAGRAM Datagram; + + if( ! MBB_NTB16_IS_VALID_NDP_SIGNATURE( Ndp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature=0x%08x for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NDP16_GET_SIGNATURE( Ndp ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + + + if (MBB_NDP16_GET_SIGNATURE_TYPE( Ndp) == NCM_NDP16_IPS) + { + // + // Check if the session id is valid, else discard + // + + // Check if session Id is greater than maximum supported. Here + // we can also check against MaxActivatedContexts, but this would + // mean we need to take a lock for getting the value of maxactivatedcontexts + // The lock can be avoided by checking against the maximum number of ports + // supported by the class driver. SESSION_PORT_TABLE.InUse can be used + // to check whether the session id is in use. + + if( MBB_NDP16_GET_SESSIONID( Ndp ) >= MBB_MAX_NUMBER_OF_PORTS + || MBB_NDP16_GET_SESSIONID( Ndp ) == MBB_INVALID_SESSION_ID ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature sessionid=0x%02x for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + (UCHAR)MBB_NDP16_GET_SESSIONID( Ndp ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + } + + if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, Ndp ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID length=0x%08x for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NDP16_GET_LENGTH( Ndp ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + + for( Index = 0; + Index < DatagramCount; + Index ++ ) + { + if( MBB_NTB16_IS_END_DATAGRAM( Nth, Ndp, Index ) ) + return NDIS_STATUS_SUCCESS; + + if( ! MBB_NTB16_IS_VALID_DATAGRAM( Nth, Ndp, Index ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID datagram at index=%02d for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + Index, + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + return NDIS_STATUS_FAILURE; + } + } + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNtbValidateNth16( + __in PNCM_NTH16 Nth, + __in ULONG BufferLength + ) +{ + PNCM_NDP16 Ndp; + + if( BufferLength < sizeof(NCM_NTH16) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH Buffer length=0x%08x", BufferLength ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTH16_IS_VALID_SIGNATURE( Nth ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH signature=0x%08x", MBB_NTB_GET_SIGNATURE( Nth ) ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTH16_IS_VALID_HEADER_LENGTH( Nth ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH header length=0x%08x", MBB_NTB_GET_HEADER_LENGTH( Nth ) ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTH16_IS_VALID_BLOCK_LENGTH( Nth, BufferLength ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH block length=0x%08x", MBB_NTH16_GET_BLOCK_LENGTH( Nth ) ); + return NDIS_STATUS_FAILURE; + } + + if( ! MBB_NTH16_IS_VALID_FIRST_NDP( Nth ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH first NDP offset=0x%08x", MBB_NTH16_GET_FIRST_NDP_OFFSET( Nth ) ); + return NDIS_STATUS_FAILURE; + } + + if( MbbNtbDetectNdp16Loop( Nth ) != NDIS_STATUS_SUCCESS ) + return NDIS_STATUS_FAILURE; + + for( Ndp = MBB_NTH16_GET_FIRST_NDP( Nth ); + Ndp != NULL; + Ndp = MBB_NDP16_GET_NEXT_NDP( Nth, Ndp ) ) + { + if( MbbNtbValidateNdp16( Nth, Ndp ) != NDIS_STATUS_SUCCESS ) + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNtbParseNdp16( + __in PNCM_NTH16 Nth, + __in PNCM_NDP16 Ndp, + __in MBB_DATAGRAM_CALLBACK Callback, + __in PVOID Context + ) +{ + ULONG Index; + ULONG DatagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp); + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG SessionId = MBB_NDP16_GET_SESSIONID( Ndp ); + + for( Index = 0; + Index < DatagramCount; + Index ++ ) + { + if( MBB_NTB16_IS_END_DATAGRAM( Nth, Ndp, Index ) ) + break; + + if( ! MBB_NTB16_IS_VALID_DATAGRAM( Nth, Ndp, Index ) ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID datagram at index=%02d for NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + Index, + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + + if( (NdisStatus = Callback( + Nth, + MBB_NDP16_GET_SIGNATURE( Ndp ), + MBB_NDP16_GET_DATAGRAM( Nth, Ndp, Index ), + MBB_NDP16_GET_DATAGRAM_LENGTH(Ndp,Index), + SessionId, + Context + )) != NDIS_STATUS_SUCCESS ) + { + break; + } + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNtbParseNth16( + __in PNCM_NTH16 Nth, + __in ULONG BufferLength, + __in MBB_NDP_CALLBACK Callback, + __in PVOID Context + ) +/*++ + NOTE: + Assumed that NTH has already been validated. + No validations are performed during parsing. +--*/ +{ + PNCM_NDP16 Ndp; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + for( Ndp = MBB_NTH16_GET_FIRST_NDP( Nth ); + Ndp != NULL; + Ndp = MBB_NDP16_GET_NEXT_NDP( Nth, Ndp ) ) + { + if( (NdisStatus = Callback( + Nth, + Ndp, + Context + )) != NDIS_STATUS_SUCCESS ) + { + break; + } + } + return NdisStatus; +} + +// +// NBL +// + +__drv_allocatesMem(mem) +PNET_BUFFER_LIST +MbbNblAlloc( + __in PVOID Nth, + __in PVOID Datagram, + __in ULONG DatagramLength, + __in PMBB_NDIS_RECEIVE_CONTEXT Receive + ) +{ + BOOLEAN Success = FALSE; + NDIS_STATUS NdisStatus; + USHORT NblContextSize = ALIGN( sizeof(MBB_NBL_RECEIVE_CONTEXT), MEMORY_ALLOCATION_ALIGNMENT ); + PNET_BUFFER_LIST NetBufferList = NULL; + PMBB_NBL_RECEIVE_CONTEXT NblContext; + + do + { + if( (NetBufferList = NdisAllocateNetBufferAndNetBufferList( + Receive->RecvQueue->NblPool, + NblContextSize, + 0, + Receive->Mdl, + MBB_NTB_GET_OFFSET( Nth, Datagram ), + DatagramLength + )) == NULL ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0X%04X] FAILED to allocate NetBufferList", MBB_NTB_GET_SEQUENCE( Nth ) ); + break; + } + +#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate a net buffer list from a pool, released when miniport returns buffer list.") + if( NdisAllocateNetBufferListContext( + NetBufferList, + NblContextSize, + 0, + MbbPoolTagNblReceive + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0X%04X] FAILED to allocate NetBufferListContext", MBB_NTB_GET_SEQUENCE( Nth ) ); + break; + } + + TraceVerbose( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x][NBL=0x%p] Added NBL", + MBB_NTB_GET_SEQUENCE( Nth ), + NetBufferList + ); + + ASSERT( NET_BUFFER_CURRENT_MDL( NET_BUFFER_LIST_FIRST_NB( NetBufferList ) ) != NULL ); + + if( DatagramLength >= sizeof(IPV4_HEADER) && + ((IPV4_HEADER*)Datagram)->Version == IPV4_VERSION ) + { + NdisSetNblFlag( NetBufferList, NDIS_NBL_FLAGS_IS_IPV4 ); + NET_BUFFER_LIST_INFO( NetBufferList, NetBufferListFrameType ) = UlongToPtr(RtlUshortByteSwap( MBB_ETHER_TYPE_IPV4 )); + } + else + if( DatagramLength >= sizeof(IPV6_HEADER) && + (((IPV6_HEADER*)Datagram)->VersionClassFlow & IP_VER_MASK) == IPV6_VERSION ) + { + NdisSetNblFlag( NetBufferList, NDIS_NBL_FLAGS_IS_IPV6 ); + NET_BUFFER_LIST_INFO( NetBufferList, NetBufferListFrameType ) = UlongToPtr(RtlUshortByteSwap( MBB_ETHER_TYPE_IPV6 )); + } + else + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0X%04X] INVALID IP Header, DatagramLength=%d Version=%d", + MBB_NTB_GET_SEQUENCE( Nth ), + DatagramLength, + (DatagramLength > 0)? *((PUCHAR)Datagram): 0 + ); + break; + } + NET_BUFFER_LIST_NEXT_NBL( NetBufferList ) = NULL; + + NblContext = (PMBB_NBL_RECEIVE_CONTEXT) NET_BUFFER_LIST_CONTEXT_DATA_START( NetBufferList ); + NblContext->NetBufferList = NetBufferList; + NblContext->Receive = Receive; + + Success = TRUE; + } + while( FALSE ); + + if( Success != TRUE ) + { + if( NetBufferList != NULL ) + { + TraceVerbose( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x][NBL=0x%p] Removed failed NBL", + MBB_NTB_GET_SEQUENCE( Nth ), + NetBufferList + ); + NdisFreeNetBufferList( NetBufferList ); + NetBufferList = NULL; + } + } + return NetBufferList; +} + +VOID +MbbNblCleanup( + __in PNET_BUFFER_LIST NetBufferList + ) +{ + USHORT NblContextSize = ALIGN( sizeof(MBB_NBL_RECEIVE_CONTEXT), MEMORY_ALLOCATION_ALIGNMENT ); + PNET_BUFFER NetBuffer; + PNET_BUFFER NextNetBuffer; + PMBB_NBL_RECEIVE_CONTEXT NblContext; + + NblContext = (PMBB_NBL_RECEIVE_CONTEXT) NET_BUFFER_LIST_CONTEXT_DATA_START( NetBufferList ); + TraceVerbose( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x][NBL=0x%p] Removed NBL", + NblContext->Receive->NtbSequence, + NetBufferList + ); + NblContext->Receive = MBB_BAD_POINTER; + NdisFreeNetBufferListContext( NetBufferList, NblContextSize ); + NdisFreeNetBufferList( NetBufferList ); +} + +// +// Receive Context +// + +NDIS_STATUS +MbbReceiveParseNdp( + __in PVOID Nth, + __in PVOID Ndp, + __in PVOID Context + ) +/*++ + Just a wrapper routine. It stores the + current NDP type which will be used for all + DPs within the NDP. +--*/ +{ + NDIS_STATUS NdisStatus; + PMBB_NDIS_RECEIVE_CONTEXT Receive = (PMBB_NDIS_RECEIVE_CONTEXT)Context; + MBB_DATAGRAM_CALLBACK Callback = MbbReceiveAddNbl; + + // If this is a device service stream NDP, switch the callback + if( MBB_NTB_IS_16BIT( Nth ) ) + { + if( MBB_NDP16_GET_SIGNATURE_TYPE( (PNCM_NDP16)Ndp ) == NCM_NDP16_VENDOR ) + { + // Vendor + Callback = MbbReceiveDssData; + } + } + else + { + if( MBB_NDP32_GET_SIGNATURE_TYPE( (PNCM_NDP32)Ndp ) == NCM_NDP32_VENDOR ) + { + // Vendor + Callback = MbbReceiveDssData; + } + } + + if( (NdisStatus = MbbNtbParseNdp( + Nth, + Ndp, + Callback, + Context + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0X%04X] FAILED to parse NDP at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, Ndp ) + ); + } + return NdisStatus; +} + +NDIS_STATUS +MbbReceiveAddNbl( + __in PVOID Nth, + __in ULONG NdpSignature, + __in PVOID Datagram, + __in ULONG DatagramLength, + __in ULONG SessionId, + __in PVOID Context + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PNET_BUFFER_LIST NetBufferList; + PMBB_NBL_RECEIVE_CONTEXT NblContext; + PMBB_NDIS_RECEIVE_CONTEXT Receive = (PMBB_NDIS_RECEIVE_CONTEXT)Context; + PMBB_NDIS_RECEIVE_NDP_CONTEXT ReceiveNdpContext = &(Receive->ReceiveNdpContext[SessionId]); + + do + { + if( (NetBufferList = MbbNblAlloc( + Nth, + Datagram, + DatagramLength, + Receive + )) == NULL ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] FAILED to allocate NetBufferList for Datagram at offset=0x%08x", + MBB_NTB_GET_SEQUENCE( Nth ), + MBB_NTB_GET_OFFSET( Nth, Datagram ) + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + NblContext = (PMBB_NBL_RECEIVE_CONTEXT) NET_BUFFER_LIST_CONTEXT_DATA_START( NetBufferList ); + // + // While building the NBL list we dont need the + // Receive lock since the parsing is serialized + // + InsertTailList( &ReceiveNdpContext->NblQueue, &NblContext->NblQLink ); + + if( ReceiveNdpContext->CurrentNbl != NULL ) + NET_BUFFER_LIST_NEXT_NBL(ReceiveNdpContext->CurrentNbl) = NetBufferList; + else + ReceiveNdpContext->FirstNbl = NetBufferList; + + ReceiveNdpContext->CurrentNbl = NetBufferList; + ReceiveNdpContext->NblCount++; + } + while( FALSE ); + // + // No cleanup required, caller will cleanup the + // Receive context thus freeing all NBLs and NBs. + // + return NdisStatus; +} + +VOID +MbbReceiveRemoveNbl( + __in PMBB_NDIS_RECEIVE_CONTEXT Receive, + __in PNET_BUFFER_LIST NetBufferList + ) +{ + UINT NonEmptyNblQueue = 0; + UINT ReceiveNdpIndex = 0; + PMBB_NBL_RECEIVE_CONTEXT NblContext = (PMBB_NBL_RECEIVE_CONTEXT) NET_BUFFER_LIST_CONTEXT_DATA_START( NetBufferList ); + + NdisAcquireSpinLock( &Receive->Lock ); + RemoveEntryList( &NblContext->NblQLink ); + + for(ReceiveNdpIndex = 0; ReceiveNdpIndex < ARRAYSIZE(Receive->ReceiveNdpContext); ReceiveNdpIndex++) + { + if(!IsListEmpty(&Receive->ReceiveNdpContext[ReceiveNdpIndex].NblQueue)) + { + NonEmptyNblQueue++; + } + } + + NdisReleaseSpinLock( &Receive->Lock ); + + MbbNblCleanup( NetBufferList ); + + if( NonEmptyNblQueue == 0 ) + MbbRecvQDequeueReceive( Receive->RecvQueue, Receive ); +} + +VOID +MbbReceiveCleanupNbls( + __in PMBB_NDIS_RECEIVE_CONTEXT Receive + ) +{ + UINT ReceiveNdpIndex = 0; + + for(ReceiveNdpIndex = 0; ReceiveNdpIndex < ARRAYSIZE(Receive->ReceiveNdpContext); ReceiveNdpIndex++) + { + LIST_ENTRY TempList; + PLIST_ENTRY ListEntry; + PLIST_ENTRY NextEntry; + PNET_BUFFER_LIST NetBufferList; + PMBB_NBL_RECEIVE_CONTEXT NblContext; + PMBB_NDIS_RECEIVE_NDP_CONTEXT ReceiveNdpContext = &(Receive->ReceiveNdpContext[ReceiveNdpIndex]); + + InitializeListHead( &TempList ); + + NdisAcquireSpinLock( &Receive->Lock ); + InsertHeadList( &ReceiveNdpContext->NblQueue, &TempList ); + RemoveEntryList( &ReceiveNdpContext->NblQueue ); + InitializeListHead( &ReceiveNdpContext->NblQueue ); + NdisReleaseSpinLock( &Receive->Lock ); + + for( ListEntry = TempList.Flink; + ListEntry != &TempList; + ListEntry = NextEntry ) + { + NextEntry = ListEntry->Flink; + NblContext = CONTAINING_RECORD( + ListEntry, + MBB_NBL_RECEIVE_CONTEXT, + NblQLink + ); + NetBufferList = NblContext->NetBufferList; + RemoveEntryList( ListEntry ); + MbbNblCleanup( NetBufferList ); + } + } +} + +// +// Receive Queue +// + +PMBB_NDIS_RECEIVE_CONTEXT +MbbRecvQQueueReceive( + __in PMBB_RECEIVE_QUEUE RecvQueue, + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_RECEIVE_CONTEXT BusContext, + __in PMDL Mdl + ) +/*++ + NOTE: + DrainAddRef( ) needs to be called before calling routine. +--*/ +{ + PMBB_NDIS_RECEIVE_CONTEXT Receive = NULL; + UINT i = 0; + + MbbRecvQLock( RecvQueue, FALSE ); + do + { + if( (Receive = ALLOCATE_LOOKASIDE(&RecvQueue->ReceiveLookasideList)) == NULL ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to allocate receive context" ); + break; + } + NdisAllocateSpinLock( &Receive->Lock ); + + NdisZeroMemory(Receive->ReceiveNdpContext,sizeof(Receive->ReceiveNdpContext)); + + for(i=0;i < ARRAYSIZE(Receive->ReceiveNdpContext);i++) + { + InitializeListHead(&Receive->ReceiveNdpContext[i].NblQueue ); + } + + Receive->Mdl = Mdl; + Receive->RecvQueue = RecvQueue; + Receive->AdapterContext = Adapter; + Receive->BusHandle = Adapter->BusHandle; + Receive->BusContext = BusContext; + Receive->ReceiveLookasideList = &RecvQueue->ReceiveLookasideList; + + InsertTailList( + &RecvQueue->ReceivedQueue, + &Receive->ReceivedQLink + ); + } + while( FALSE ); + MbbRecvQUnlock( RecvQueue, FALSE ); + + return Receive; +} + +VOID +MbbRecvQDequeueReceive( + __in PMBB_RECEIVE_QUEUE RecvQueue, + __in PMBB_NDIS_RECEIVE_CONTEXT Receive + ) +{ + MbbBusReturnReceiveBuffer( + Receive->BusHandle, + Receive->BusContext, + Receive->Mdl + ); + + MbbRecvQLock( RecvQueue, FALSE ); + RemoveEntryList( &Receive->ReceivedQLink ); + if( IsListEmpty( &RecvQueue->ReceivedQueue ) ) + KeSetEvent( &RecvQueue->QueueEmptyEvent, 0, FALSE ); + MbbRecvQUnlock( RecvQueue, FALSE ); + + Receive->RecvQueue = MBB_BAD_POINTER; + NdisFreeSpinLock( &Receive->Lock ); + FREE_LOOKASIDE( Receive, Receive->ReceiveLookasideList ); + + DrainRelease( &(RecvQueue->QueueDrainObject) ); +} + +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( SpinLock, RecvQueue->Lock ) +__drv_when( DispatchLevel == FALSE, __drv_raisesIRQL(DISPATCH_LEVEL)) +FORCEINLINE +VOID +MbbRecvQLock( + __in __drv_at( RecvQueue->Lock, __drv_acquiresResource( Spinlock ) ) + PMBB_RECEIVE_QUEUE RecvQueue, + __in BOOLEAN DispatchLevel + ) +{ + if( DispatchLevel == TRUE ) + { + NdisDprAcquireSpinLock( &RecvQueue->Lock ); + } + else + { + NdisAcquireSpinLock( &RecvQueue->Lock ); + } +} + +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( SpinLock, RecvQueue->Lock ) +FORCEINLINE +VOID +MbbRecvQUnlock( + __in __drv_at( RecvQueue->Lock, __drv_releasesResource( Spinlock ) ) + PMBB_RECEIVE_QUEUE RecvQueue, + __in BOOLEAN DispatchLevel + ) +{ + if( DispatchLevel == TRUE ) + { + NdisDprReleaseSpinLock( &RecvQueue->Lock ); + } + else + { + NdisReleaseSpinLock( &RecvQueue->Lock ); + } +} + +NDIS_STATUS +MbbRecvQInitialize( + __in PMBB_RECEIVE_QUEUE RecvQueue, + __in MBB_DRAIN_COMPLETE DrainCompleteCallback, + __in PVOID DrainCompleteCallbackContext, + __in NDIS_HANDLE MiniportHandle + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + USHORT NblContextSize = ALIGN( sizeof(MBB_NBL_RECEIVE_CONTEXT), MEMORY_ALLOCATION_ALIGNMENT ); + NET_BUFFER_POOL_PARAMETERS NbPoolParameters; + NET_BUFFER_LIST_POOL_PARAMETERS NblPoolParameters; + + do + { + InitializeListHead( &RecvQueue->ReceivedQueue ); + KeInitializeEvent( + &RecvQueue->QueueEmptyEvent, + NotificationEvent, + TRUE + ); + NdisAllocateSpinLock( &RecvQueue->Lock ); + + RecvQueue->NblPool = NULL; + RecvQueue->LookasideList = FALSE; + + NdisInitializeNPagedLookasideList( + &RecvQueue->ReceiveLookasideList, + NULL, + NULL, + 0, + sizeof(MBB_NDIS_RECEIVE_CONTEXT), + MbbPoolTagMdlReceive, + 0 + ); + RecvQueue->LookasideList = TRUE; + + NblPoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NblPoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; + NblPoolParameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; + NblPoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; + NblPoolParameters.fAllocateNetBuffer = TRUE; + NblPoolParameters.ContextSize = NblContextSize; + NblPoolParameters.PoolTag = MbbPoolTagNblPool; + NblPoolParameters.DataSize = 0; + + if( (RecvQueue->NblPool = NdisAllocateNetBufferListPool( + MiniportHandle, + &NblPoolParameters + )) == NULL ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to allocate NetBufferListPool" ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + InitDrainObject( + &RecvQueue->QueueDrainObject, + DrainCompleteCallback, + DrainCompleteCallbackContext + ); + TraceInfo( WMBCLASS_RECEIVE, "[Recv] Initialization complete" ); + } + while( FALSE ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + MbbRecvQCleanup( RecvQueue ); + } + return NdisStatus; +} + +VOID +MbbRecvQCleanup( + __in PMBB_RECEIVE_QUEUE RecvQueue + ) +/*++ + Description + Frees all resources allocated for the queue. + This is called from MiniportHalt so the queue should + already be empty. This routine does not call cancel + or wait for pending requests to complete since there + should not be any. +--*/ +{ + ASSERT( IsListEmpty( &RecvQueue->ReceivedQueue ) == TRUE ); + + if( RecvQueue->NblPool != NULL ) + { + NdisFreeNetBufferListPool( RecvQueue->NblPool ); + RecvQueue->NblPool = NULL; + } + if( RecvQueue->LookasideList == TRUE ) + { + NdisDeleteNPagedLookasideList( &RecvQueue->ReceiveLookasideList ); + RecvQueue->LookasideList = FALSE; + } + NdisFreeSpinLock( &RecvQueue->Lock ); + + TraceInfo( WMBCLASS_RECEIVE, "[Recv] Cleanup complete" ); +} + +VOID +MbbRecvQCancel( + __in PMBB_RECEIVE_QUEUE RecvQueue, + __in NDIS_STATUS Status, + __in BOOLEAN WaitForCompletion + ) +{ + StartDrain( &RecvQueue->QueueDrainObject ); + // + // Nothing to cancel + // + if( WaitForCompletion ) + { + TraceInfo( WMBCLASS_RECEIVE, "[Recv] Cancel, waiting for request to complete..." ); + + KeWaitForSingleObject( + &RecvQueue->QueueEmptyEvent, + Executive, + KernelMode, + FALSE, + NULL + ); + } + TraceInfo( WMBCLASS_RECEIVE, "[Recv] Cancel complete" ); +} + + + +NDIS_STATUS +MbbReceiveDssData( + __in PVOID Nth, + __in ULONG NdpSignature, + __in PVOID Datagram, + __in ULONG DatagramLength, + __in ULONG SessionIdentifier, + __in PVOID Context + ) +{ + PMBB_NDIS_RECEIVE_CONTEXT Receive = (PMBB_NDIS_RECEIVE_CONTEXT)Context; + ULONG SessionId; + + UNREFERENCED_PARAMETER(SessionIdentifier); + + // Pass this to the Dss indication processing code + SessionId = NdpSignature >> NCM_NDP_SESSION_SHIFT; + + // Forward to the dss receive handler + MbbNdisDeviceServiceSessionReceive( + Receive->AdapterContext, + SessionId, + Datagram, + DatagramLength + ); + + return NDIS_STATUS_SUCCESS; +} + +// +// NDIS / Bus Callbacks +// + +VOID +MbbNdisReceiveCallback( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in MBB_RECEIVE_CONTEXT ReceiveContext, + __in PMDL Mdl + ) +{ + PUCHAR DataBuffer; + ULONG DataLength; + PVOID Nth; + BOOLEAN Referenced = FALSE; + BOOLEAN ReturnBuffer = TRUE; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; + PMBB_NDIS_RECEIVE_CONTEXT Receive = NULL; + PMBB_NDIS_RECEIVE_NDP_CONTEXT ReceiveNdpContext = NULL; + int ReceiveNdpIndex = 0; + int MaxReceiveNdpIndex = -1; + + do + { + if( ! (Referenced = DrainAddRef( &(Adapter->ReceiveQueue.QueueDrainObject) )) ) + { + break; + } + + if( (DataBuffer = MmGetSystemAddressForMdlSafe( Mdl, NormalPagePriority | MdlMappingNoExecute )) == NULL ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to get system address for Mdl=0x%p", Mdl ); + break; + } + DataLength = MmGetMdlByteCount( Mdl ); + + Nth = DataBuffer; + + if( MbbNtbValidate( + Nth, + DataLength, + Adapter->BusParams.CurrentMode32Bit + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to validate NTB" ); + + + MbbWriteEvent( + &RECEIVED_BAD_NTB, + NULL, + NULL, + 2 + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &DataLength, + sizeof(DataLength) + ); + + + + { + ULONG i; + ULONG j; + + PUCHAR Buffer=(PUCHAR)Nth; + + for (i=0; i= DataLength) + { + // + // past the end, just put spaces + // + NumString[j*3] =' '; + NumString[j*3+1]=' '; + NumString[j*3+2]=' '; + + } else + { + Value=Buffer[i+j]; + + NumString[j*3]= TranslateTable[ Value >> 4]; + NumString[j*3+1]= TranslateTable[ Value & 0xf]; + NumString[j*3+2]=' '; + + if ((Buffer[i+j] >= 32) && (Buffer[i+j] < 128)) + { + AsciiBuffer[j]=Value; + } + else + { + AsciiBuffer[j]='.'; + } + } + } + + TraceError( WMBCLASS_RECEIVE, "%08lx - %s %s", i, NumString, AsciiBuffer); + } + + } + + + + + break; + } + + if( (Receive = MbbRecvQQueueReceive( + &Adapter->ReceiveQueue, + Adapter, + ReceiveContext, + Mdl + )) == NULL ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to allocate receive context" ); + break; + } + Receive->NtbSequence = MBB_NTB_GET_SEQUENCE( Nth ); + + if( MbbNtbParse( + Nth, + DataLength, + MbbReceiveParseNdp, + Receive + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to parse NTB" ); + break; + } + + // Preprocessing here to ensure that Receive Context is not cleaned up when + // MbbNdisMiniportReturnNetBufferLists is called for the last NDP NBL chain processed + + for(ReceiveNdpIndex = 0; ReceiveNdpIndex < ARRAYSIZE(Receive->ReceiveNdpContext); ReceiveNdpIndex++) + { + ReceiveNdpContext = &(Receive->ReceiveNdpContext[ReceiveNdpIndex]); + + if(!IsListEmpty( &ReceiveNdpContext->NblQueue ) ) + { + MaxReceiveNdpIndex = ReceiveNdpIndex; + } + } + + for(ReceiveNdpIndex = 0; ReceiveNdpIndex <= MaxReceiveNdpIndex && ReceiveNdpIndex < ARRAYSIZE(Receive->ReceiveNdpContext); ReceiveNdpIndex++) + { + ReceiveNdpContext = &(Receive->ReceiveNdpContext[ReceiveNdpIndex]); + + // If all the Ndps in this receive are Dss stuff, we + // wont have any NBLs to indicate + if( !IsListEmpty( &ReceiveNdpContext->NblQueue ) ) + { + ASSERT(ReceiveNdpContext->SessionIdPortNumberEntry.InUse); + + ReturnBuffer = FALSE; + + { + PNET_BUFFER_LIST CurrentNetBufferList; + PNET_BUFFER_LIST NextNetBufferList; + PNET_BUFFER NetBuffer; + + for( CurrentNetBufferList = ReceiveNdpContext->FirstNbl; + CurrentNetBufferList != NULL; + CurrentNetBufferList = NextNetBufferList ) + { + NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL( CurrentNetBufferList ); + + for( NetBuffer = NET_BUFFER_LIST_FIRST_NB( CurrentNetBufferList ); + NetBuffer != NULL; + NetBuffer = NET_BUFFER_NEXT_NB( NetBuffer ) ) + { + InterlockedAdd64(&Adapter->Stats.ifHCInOctets, NET_BUFFER_DATA_LENGTH(NetBuffer)); + InterlockedIncrement64(&Adapter->GenRcvFramesOk); + InterlockedIncrement64(&Adapter->Stats.ifHCInUcastPkts); + } + } + } + +#if DBG + MbbTestValidateNblChain(ReceiveNdpContext->FirstNbl ); +#endif + NdisMIndicateReceiveNetBufferLists( + Adapter->MiniportAdapterHandle, + ReceiveNdpContext->FirstNbl, + ReceiveNdpContext->SessionIdPortNumberEntry.PortNumber, + ReceiveNdpContext->NblCount, + 0 + ); + } + } + } + while( FALSE ); + + if( ReturnBuffer == TRUE ) + { + TraceError( WMBCLASS_RECEIVE, "[Recv] DROPPING received Mdl=0x%p", Mdl ); + InterlockedIncrement64( &Adapter->Stats.ifInDiscards ); + + if( Receive != NULL ) + { + MbbReceiveCleanupNbls( Receive ); + + MbbRecvQDequeueReceive( + &Adapter->ReceiveQueue, + Receive + ); + // + // Reference dropped by Dequeue + // + Referenced = FALSE; + } + else + { + MbbBusReturnReceiveBuffer( + Adapter->BusHandle, + ReceiveContext, + Mdl + ); + } + if( Referenced ) + DrainRelease( &(Adapter->ReceiveQueue.QueueDrainObject) ); + } +} + +VOID +MbbNdisMiniportReturnNetBufferLists( + __in NDIS_HANDLE MiniportAdapterContext, + __in PNET_BUFFER_LIST NetBufferLists, + __in ULONG ReturnFlags + ) +{ + PNET_BUFFER_LIST NetBufferList; + PNET_BUFFER_LIST NextNetBufferList; + PMBB_NBL_RECEIVE_CONTEXT NblContext; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + + if (MbbBusIsFastIO(Adapter->BusHandle)) + { + MbbBusReturnNetBufferLists(Adapter->BusHandle, NetBufferLists, ReturnFlags); + } + else + { + for (NetBufferList = NetBufferLists; + NetBufferList != NULL; + NetBufferList = NextNetBufferList) + { + NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); + NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; + NblContext = (PMBB_NBL_RECEIVE_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); + MbbReceiveRemoveNbl(NblContext->Receive, NetBufferList); + } + } +} + +#if DBG +VOID +MbbTestValidateNblChain( + __in PNET_BUFFER_LIST NblChain + ) +{ + PNET_BUFFER NetBuffer; + PNET_BUFFER_LIST NetBufferList; + + for( NetBufferList = NblChain; + NetBufferList != NULL; + NetBufferList = NET_BUFFER_LIST_NEXT_NBL( NetBufferList ) ) + { + NetBuffer = NET_BUFFER_LIST_FIRST_NB( NetBufferList ); + ASSERT( NET_BUFFER_CURRENT_MDL( NetBuffer ) != NULL ); + } +} +#endif diff --git a/network/wwan/cxwmbclass/receive.h b/network/wwan/cxwmbclass/receive.h new file mode 100644 index 000000000..e686f9f88 --- /dev/null +++ b/network/wwan/cxwmbclass/receive.h @@ -0,0 +1,22 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +NDIS_STATUS +MbbRecvQInitialize( + __in PMBB_RECEIVE_QUEUE RecvQueue, + __in MBB_DRAIN_COMPLETE DrainCompleteCallback, + __in PVOID DrainCompleteContext, + __in NDIS_HANDLE MiniportHandle + ); + +VOID +MbbRecvQCleanup( + __in PMBB_RECEIVE_QUEUE RecvQueue + ); + +VOID +MbbRecvQCancel( + __in PMBB_RECEIVE_QUEUE RecvQueue, + __in NDIS_STATUS Status, + __in BOOLEAN WaitForCompletion + ); diff --git a/network/wwan/cxwmbclass/request.c b/network/wwan/cxwmbclass/request.c new file mode 100644 index 000000000..5fd6a64ea --- /dev/null +++ b/network/wwan/cxwmbclass/request.c @@ -0,0 +1,19728 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" +#include "Request.tmh" +#include "WMBClassTelemetry.h" + +#pragma prefast(push) +// Disables oacr check for 26014(INCORRECT_VALIDATION) because we use many MBB struct carrying 1-element array for data buffer +// e.g. +// struct MBB_X { +// MBB_STRING str; // empty string +// UCHAR DataBuffer[ 1 ]; +// } +// The real size of payload could be "sizeof(MBB_X) - 1." +// To avoid noise, disable this specific validation in OACR as the implementation already validates the payload +#pragma prefast(disable: __WARNING_INCORRECT_VALIDATION) // allowed off-by-1 struct + +C_ASSERT(MbbCellularClassMaximum == 3 ); + +//////////////////////////////////////////////////////////////////////////////// +// +// DECLARATIONS +// +//////////////////////////////////////////////////////////////////////////////// +NDIS_STATUS +MbbNdisProcessSerializedOidRequest( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ); + +VOID +MbbNdisIndicateStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +// +// Get handlers +// + +NDIS_STATUS +MbbNdisGetVendorDriverVersion( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetVendorId( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetVendorDescription( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetReceiveBlockSize( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetReceiveBufferSpace( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetTransmitBlockSize( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetTransmitBufferSpace( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetMaximumTotalSize( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetInterruptModeration( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetCurrentLookahead( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetFramesReceived( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetFramesTransmitted( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetMediaSupported( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetDriverCaps( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetStatistics( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +// MAC +NDIS_STATUS +MbbNdisCreateMac( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetMbimVersion( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + + +#define MbbNdisGetDeviceCaps MbbUtilQueryAttribute + +#define MbbNdisGetReadyInfo MbbUtilQueryAttribute + +#define MbbNdisGetEmergencyMode MbbUtilQueryAttribute + +#define MbbNdisGetRadioState MbbUtilQueryAttribute + +#define MbbNdisGetPinInfo MbbUtilQueryAttribute + +#define MbbNdisGetPinList MbbUtilQueryAttribute + +#define MbbNdisGetHomeProvider MbbUtilQueryAttribute + +#define MbbNdisGetPreferredProviders MbbUtilQueryAttribute + +#define MbbNdisGetRegisterState MbbUtilQueryAttribute + +#define MbbNdisGetPacketService MbbUtilQueryAttribute + +#define MbbNdisGetSignalState MbbUtilQueryAttribute + +#define MbbNdisGetProvisionedContexts MbbUtilQueryAttribute + +NDIS_STATUS +MbbNdisGetProvisionedContextsV2( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + +#define MbbNdisGetMulticarrierProviders MbbUtilQueryAttribute + +#define MbbNdisGetSarConfig MbbUtilQueryAttribute + +#define MbbNdisGetSarTransmissionStatus MbbUtilQueryAttribute + +#define MbbNdisGetLteAttachConfig MbbUtilQueryAttribute + +#define MbbNdisGetLteAttachStatus MbbUtilQueryAttribute + +NDIS_STATUS +MbbNdisGetPcoStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + + +NDIS_STATUS +MbbNdisQueryPower( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +// SMS + +NDIS_STATUS +MbbNdisSmsRead( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + + +NDIS_STATUS +MbbNdisGetVisibleProviders( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetConnectState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbIpGetConfiguration( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + + +#define MbbNdisSmsGetConfiguration MbbUtilQueryAttribute + +#define MbbNdisSmsGetStatus MbbUtilQueryAttribute + +// Device Service + +NDIS_STATUS +MbbNdisEnumerateDeviceServices( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetDeviceServiceCommand( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisEnumerateDeviceServiceCommands( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +// EAP Authentication + +NDIS_STATUS +MbbNdisGetAuthChallenge( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +// Multi-carrier + +NDIS_STATUS +MbbNdisGetMultiCarrierDsCidList( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +// UICC +#define MbbNdisGetUiccAppList MbbUtilQueryAttribute + +NDIS_STATUS +MbbNdisGetUiccFileStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisUiccReadBinary( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisUiccReadRecord( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbNdisGetPinInfoEx( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + +// Device State and Configuration for MBIM 2.0 + +NDIS_STATUS +MbbNdisGetSysCapsInfo( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + +NDIS_STATUS +MbbNdisGetDeviceCapsEx( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + +#define MbbNdisGetSysSlotMappings MbbUtilQueryAttribute + +NDIS_STATUS +MbbNdisGetSlotInfoStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + +#define MbbNdisGetDeviceBindings MbbUtilQueryAttribute + +// Registration, Signal Strength, and NITZ for MBIM 2.0 + +#define MbbNdisGetRegisterStateEx MbbUtilQueryAttribute + +#define MbbNdisGetImsVoiceState MbbUtilQueryAttribute + +#define MbbNdisGetSignalStateEx MbbUtilQueryAttribute + +#define MbbNdisGetLocationState MbbUtilQueryAttribute + +#define MbbNdisGetNitzInfo MbbUtilQueryAttribute + +// Low-Level UICC Access + +NDIS_STATUS +MbbNdisGetAtr( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + +#define MbbNdisGetUiccTerminalCapability MbbUtilQueryAttribute + +NDIS_STATUS +MbbNdisGetUiccReset( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize, + _Out_writes_bytes_to_opt_(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + _Inout_ PULONG OutBufferSize +); + +// Base station information +NDIS_STATUS +MbbNdisGetBaseStationsInfo( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +); + + +// +// Set handlers +// + +NDIS_STATUS +MbbNdisSetInterruptModeration( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetCurrentLookahead( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetRadioState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetPinInfo( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetPinInfoEx2( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetPreferredProviders( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetRegisterState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetPacketService( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetPower( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetPmParameters( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetAddWolPattern( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetRemoveAddWolPattern( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + + +NDIS_STATUS +MbbNdisSetSignalState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + + +NDIS_STATUS +MbbNdisSetCurrentLookahead( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetConnectState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetProvisionedContexts( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetProvisionedContextsV2( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetServiceActivation( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetHomeProvider( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + + +NDIS_STATUS +MbbNdisSetMulticarrierProviders( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +// SMS + +NDIS_STATUS +MbbNdisSmsSetConfiguration( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSmsSend( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSmsDelete( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +// USSD + +NDIS_STATUS +MbbNdisSetUSSD( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + +); + +// DEVICE SERVICE + +NDIS_STATUS +MbbNdisSetDeviceServiceCommand( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSubscribeDeviceServiceEvents( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetDeviceServiceSession( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisDssWrite( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +// MAC ADDRESS + +NDIS_STATUS +MbbNdisDeleteMac( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +// UICC + +NDIS_STATUS +MbbNdisUiccUpdateBinary( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisUiccUpdateRecord( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + + +// Device State and Configuration for MBIM 2.0 + +NDIS_STATUS +MbbNdisSetSysSlotMappings( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +); + +NDIS_STATUS +MbbNdisSetDeviceBindings( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +); + +// Registration, Signal Strength, and NITZ for MBIM 2.0 + +NDIS_STATUS +MbbNdisSetRegisterStateEx( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +); + +NDIS_STATUS +MbbNdisSetImsVoiceState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +); + +NDIS_STATUS +MbbNdisSetSignalStateEx( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +); + +NDIS_STATUS +MbbNdisSetLocationState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +); + +// Vendor Specific + +NDIS_STATUS +MbbNdisSetVendorSpecific( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +// Network Idle Hint +NDIS_STATUS +MbbNdisSetNetworkIdleHint( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +// System Preshutdown +NDIS_STATUS +MbbNdisSetPreshutdown( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +// Low-Level UICC Access + +NDIS_STATUS +MbbNdisSetUiccOpenChannel( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetUiccCloseChannel( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetUiccApdu( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetUiccTerminalCapability( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetUiccReset( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetSarConfig( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetSarTransmissionStatus( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetLteAttachContexts( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetNetworkBlacklist( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSetDeviceReset( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize + ); + +// +// Status handlers +// + +NDIS_STATUS +MbbNdisDeviceCapsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisReadyInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisEmergencyModeStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisRadioStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisPinInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisPinListStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisHomeProviderStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisPreferredProviderStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisVisibleProviderStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisRegisterStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +VOID +MbbNdisIndicatePacketService( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); + + +NDIS_STATUS +MbbNdisPacketServiceStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSignalStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisConnectStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisProvisionedContextStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisProvisionedContextV2StatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisServiceActivationStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisMulticarrierProviderStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +// SMS + +NDIS_STATUS +MbbNdisSmsConfigurationStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSmsReadStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSmsSendStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSmsDeleteStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSmsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisGetStatsHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +// DEVICE SERVICE + +NDIS_STATUS +MbbNdisDeviceServiceListStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisDeviceServiceStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSubscribeDeviceServiceEventsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + + +// USSD + +NDIS_STATUS +MbbNdisUSSDStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + + +// EAP Authentication + +NDIS_STATUS +MbbNdisAuthAKAStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisAuthAKAPStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + + +NDIS_STATUS +MbbNdisAuthSIMStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + + +NDIS_STATUS +MbbNdisDssOpenStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + + +NDIS_STATUS +MbbNdisDssCloseStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisDssWriteCompleteStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +// Multi-carrier + +NDIS_STATUS +MbbNdisMultiCarrierDsCidListStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +// UICC + +NDIS_STATUS +MbbNdisUiccAppListStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisUiccFileStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisUiccAccessStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +// Device State and Configuration for MBIM 2.0 + +NDIS_STATUS +MbbNdisSysCapsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisDeviceCapsExStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisSysSlotMappingsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisSlotInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisDeviceBindingsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +// Registration, Signal Strength, and NITZ for MBIM 2.0 + +NDIS_STATUS +MbbNdisRegisterStateExStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisImsVoiceStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisSignalStateExStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisLocationStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisNitzStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +); + +// Vendor Specific + +NDIS_STATUS +MbbNdisVendorSpecificStatusHandler( +__in PMBB_REQUEST_CONTEXT Request, +__in NDIS_STATUS NdisStatus, +__in MBB_STATUS MbbStatus, +__in_bcount_opt(InBufferSize) PUCHAR InBuffer, +__in ULONG InBufferSize +); + +// System Preshutdown + +NDIS_STATUS +MbbNdisPreshutdownHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +// Low-Level UICC Access + +NDIS_STATUS +MbbNdisAtrInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisUiccOpenChannelInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisUiccCloseChannelInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisUiccApduInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisUiccTerminalCapabilityInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisUiccResetInfoStatusHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSarConfigHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisSarTransmissionStatusHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisLteAttachConfigHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisLteAttachStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisNetworkBlacklistHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +NDIS_STATUS +MbbNdisPcoStatusHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize +); + +NDIS_STATUS +MbbNdisDeviceResetStatusHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize + ); + +// Base station information + +NDIS_STATUS +MbbNdisBaseStationsInfoHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize +); + + +// +// Completion Handlers +// + +VOID +MbbNdisReadyInfoCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); + +VOID +MbbNdisPacketServiceStateCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); + +VOID +MbbNdisMultiCarrierDsCidListCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); +VOID +MbbNdisCreateMacCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); + +VOID +MbbNdisDeleteMacCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); + + +//////////////////////////////////////////////////////////////////////////////// +// +// GLOBALS +// +//////////////////////////////////////////////////////////////////////////////// +#define OID_INVALID (-1) + +#define MBIM_CID_VENDORSPECIFIC 1 + + +MBB_OID_HANDLER_ENTRY MbbSpecialOidHandlerTable[] = +{ + // + // Authentication Challenges - AKA, AKAP, and SIM + // + { + OID_WWAN_AUTH_CHALLENGE, // Oid + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_AUTH_CHALLENGE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_AUTH_CHALLENGE), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetAuthChallenge, // Query routine + sizeof(NDIS_WWAN_AUTH_CHALLENGE), // MinQueryInBufferSize + sizeof(NDIS_WWAN_AUTH_RESPONSE), // MinQueryOutBufferSize + + { MBB_UUID_AUTH_CONSTANT, MBB_AUTH_CID_AKA}, // ResponseCommand + sizeof(MBB_USSD), // ResponseBufferLength + MbbNdisAuthAKAStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_AUTH_CHALLENGE, // Oid + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_AUTH_CHALLENGE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_AUTH_CHALLENGE), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetAuthChallenge, // Query routine + sizeof(NDIS_WWAN_AUTH_CHALLENGE), // MinQueryInBufferSize + sizeof(NDIS_WWAN_AUTH_RESPONSE), // MinQueryOutBufferSize + + { MBB_UUID_AUTH_CONSTANT, MBB_AUTH_CID_AKAP}, // ResponseCommand + sizeof(MBB_USSD), // ResponseBufferLength + MbbNdisAuthAKAPStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_AUTH_CHALLENGE, // Oid + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_AUTH_CHALLENGE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_AUTH_CHALLENGE), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetAuthChallenge, // Query routine + sizeof(NDIS_WWAN_AUTH_CHALLENGE), // MinQueryInBufferSize + sizeof(NDIS_WWAN_AUTH_RESPONSE), // MinQueryOutBufferSize + + { MBB_UUID_AUTH_CONSTANT, MBB_AUTH_CID_SIM}, // ResponseCommand + sizeof(MBB_USSD), // ResponseBufferLength + MbbNdisAuthSIMStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // Device Service Sessions - Open & Close + // + { + OID_WWAN_DEVICE_SERVICE_SESSION, // Oid + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_REVISION_1, // NdisObjectHeaderRevision + SIZEOF_NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_1, // NdisObjectHeaderSize + + MbbNdisSetDeviceServiceSession, // Set routine + SIZEOF_NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_1, // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_DSS_CONSTANT, MBB_DSS_CID_CONNECT}, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisDssOpenStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, +#if 0 + { + OID_WWAN_DEVICE_SERVICE_SESSION, // Oid + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_REVISION_1, // NdisObjectHeaderRevision + SIZEOF_NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_1, // NdisObjectHeaderSize + + MbbNdisSetDeviceServiceSession, // Set routine + SIZEOF_NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_1, // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_DSS_CONSTANT, MBB_DSS_CID_CONNECT}, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisDssCloseStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, +#endif + {0} // terminator +}; + +MBB_OID_HANDLER_ENTRY MbbOidHandlerTable[] = +{ + { + OID_GEN_MEDIA_SUPPORTED, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetMediaSupported, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_RCV_OK, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetFramesReceived, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONGLONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_XMIT_OK, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetFramesTransmitted, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONGLONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_STATISTICS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetStatistics, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_STATISTICS_INFO), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_STATISTICS }, // ResponseCommand + sizeof(MBB_PACKET_STATISTICS), // ResponseBufferLength + NULL, //MbbNdisGetStatsHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_INTERRUPT_MODERATION, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + MbbNdisSetInterruptModeration, // Set routine + sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS), // MinSetInBufferSize + + MbbNdisGetInterruptModeration, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_PNP_QUERY_POWER, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisQueryPower, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_PNP_SET_POWER, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + MbbNdisSetPower, // Set routine + sizeof(ULONG), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_INVALID, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_NETWORK_IDLE_HINT }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_INVALID, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_HOSTSHUTDOWN_CONSTANT, MBB_HOSTSHUTDOWN_CID_ONE }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_INVALID, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_FILTERS }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_PM_PARAMETERS, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + FALSE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + MbbNdisSetPmParameters, // Set routine + sizeof(NDIS_PM_PARAMETERS), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_FILTERS }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_PM_ADD_WOL_PATTERN, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + MbbNdisSetAddWolPattern, // Set routine + sizeof(NDIS_PM_WOL_PATTERN), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_PM_REMOVE_WOL_PATTERN, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + MbbNdisSetRemoveAddWolPattern, // Set routine + sizeof(ULONG), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_VENDOR_DRIVER_VERSION, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetVendorDriverVersion, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_VENDOR_ID, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetVendorId, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_VENDOR_DESCRIPTION, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetVendorDescription, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_CURRENT_LOOKAHEAD, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + MbbNdisSetCurrentLookahead, // Set routine + sizeof(ULONG), // MinSetInBufferSize + + MbbNdisGetCurrentLookahead, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_RECEIVE_BLOCK_SIZE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + sizeof(ULONG), // MinSetInBufferSize + + MbbNdisGetReceiveBlockSize, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_RECEIVE_BUFFER_SPACE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + sizeof(ULONG), // MinSetInBufferSize + + MbbNdisGetReceiveBufferSpace, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_TRANSMIT_BLOCK_SIZE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + sizeof(ULONG), // MinSetInBufferSize + + MbbNdisGetTransmitBlockSize, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_TRANSMIT_BUFFER_SPACE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + sizeof(ULONG), // MinSetInBufferSize + + MbbNdisGetTransmitBufferSpace, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_GEN_MAXIMUM_TOTAL_SIZE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + sizeof(ULONG), // MinSetInBufferSize + + MbbNdisGetMaximumTotalSize, // Query routine + 0, // MinQueryInBufferSize + sizeof(ULONG), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + // + // BASIC CONNECT + // + { + OID_WWAN_DRIVER_CAPS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetDriverCaps, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_DRIVER_CAPS), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_DEVICE_CAPS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetDeviceCaps, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_DEVICE_CAPS), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_DEVICE_CAPS }, // ResponseCommand + sizeof(MBB_DEVICE_CAPS), // ResponseBufferLength + MbbNdisDeviceCapsStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_READY_INFO, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetReadyInfo, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_READY_INFO), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_SUBSCRIBER_READY_INFO }, // ResponseCommand + sizeof(MBB_SUBSCRIBER_READY_INFO), // ResponseBufferLength + MbbNdisReadyInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_INVALID, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetEmergencyMode, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_EMERGENCY_MODE }, // ResponseCommand + sizeof(MBB_EMERGENCY_MODE), // ResponseBufferLength + MbbNdisEmergencyModeStatusHandler, // ResponseHandler + MbbNdisReadyInfoCompletionHandler // CompletionHandler + }, + { + OID_WWAN_RADIO_STATE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_RADIO_STATE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_RADIO_STATE), // NdisObjectHeaderSize + + MbbNdisSetRadioState, // Set routine + sizeof(NDIS_WWAN_SET_RADIO_STATE), // MinSetInBufferSize + + MbbNdisGetRadioState, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_RADIO_STATE), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_RADIO_STATE }, // ResponseCommand + sizeof(MBB_QUERY_RADIO_STATE), // ResponseBufferLength + MbbNdisRadioStateStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + + { + OID_WWAN_PIN_EX, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_PIN_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_PIN), // NdisObjectHeaderSize + + MbbNdisSetPinInfo, // Set routine + sizeof(NDIS_WWAN_SET_PIN), // MinSetInBufferSize + + MbbNdisGetPinInfo, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_PIN_INFO), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PIN_INFO }, // ResponseCommand + sizeof(MBB_PIN_INFO), // ResponseBufferLength + MbbNdisPinInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_PIN_LIST, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetPinList, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_PIN_LIST), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PIN_LIST }, // ResponseCommand + sizeof(MBB_PIN_LIST), // ResponseBufferLength + MbbNdisPinListStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_HOME_PROVIDER, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_HOME_PROVIDER_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_HOME_PROVIDER), // NdisObjectHeaderSize + + MbbNdisSetHomeProvider, // Set routine + sizeof(NDIS_WWAN_SET_HOME_PROVIDER), // MinSetInBufferSize + + MbbNdisGetHomeProvider, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_HOME_PROVIDER2), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_HOME_PROVIDER },// ResponseCommand + sizeof(MBB_PROVIDER), // ResponseBufferLength + MbbNdisHomeProviderStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_PREFERRED_PROVIDERS, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_PREFERRED_PROVIDERS_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_PREFERRED_PROVIDERS), // NdisObjectHeaderSize + + MbbNdisSetPreferredProviders, // Set routine + sizeof(NDIS_WWAN_SET_PREFERRED_PROVIDERS), // MinSetInBufferSize + + MbbNdisGetPreferredProviders, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_PREFERRED_PROVIDERS), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PREFERRED_PROVIDERS }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisPreferredProviderStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_VISIBLE_PROVIDERS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetVisibleProviders, // Query routine + sizeof(NDIS_WWAN_GET_VISIBLE_PROVIDERS), // MinQueryInBufferSize + sizeof(NDIS_WWAN_VISIBLE_PROVIDERS), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_VISIBLE_PROVIDERS }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisVisibleProviderStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_REGISTER_STATE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_REGISTER_STATE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_REGISTER_STATE), // NdisObjectHeaderSize + + MbbNdisSetRegisterState, // Set routine + sizeof(NDIS_WWAN_SET_REGISTER_STATE), // MinSetInBufferSize + + MbbNdisGetRegisterState, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_REGISTRATION_STATE), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_REGISTER_STATE }, // ResponseCommand + sizeof(MBB_REGISTRATION_STATE), // ResponseBufferLength + MbbNdisRegisterStateStatusHandler, // ResponseHandler + MbbNdisPacketServiceStateCompletionHandler // CompletionHandler, intentional PacketServiceHandler + }, + { + OID_WWAN_PACKET_SERVICE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_PACKET_SERVICE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_PACKET_SERVICE), // NdisObjectHeaderSize + + MbbNdisSetPacketService, // Set routine + sizeof(NDIS_WWAN_SET_PACKET_SERVICE), // MinSetInBufferSize + + MbbNdisGetPacketService, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_PACKET_SERVICE_STATE), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_SERVICE }, // ResponseCommand + sizeof(MBB_PACKET_SERVICE), // ResponseBufferLength + MbbNdisPacketServiceStatusHandler, // ResponseHandler + MbbNdisPacketServiceStateCompletionHandler // CompletionHandler + }, + { + OID_WWAN_SIGNAL_STATE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_SIGNAL_INDICATION_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION), // NdisObjectHeaderSize + + MbbNdisSetSignalState, // Set routine + sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION), // MinSetInBufferSize + + MbbNdisGetSignalState, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_SIGNAL_STATE), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_SIGNAL_STATE }, // ResponseCommand + sizeof(MBB_SIGNAL_STATE), // ResponseBufferLength + MbbNdisSignalStateStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_CONNECT, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_CONTEXT_STATE_REVISION_2, // NdisObjectHeaderRevision + SIZEOF_NDIS_WWAN_SET_CONTEXT_STATE_REVISION_2, // NdisObjectHeaderSize + + MbbNdisSetConnectState, // Set routine + SIZEOF_NDIS_WWAN_SET_CONTEXT_STATE_REVISION_2, // MinSetInBufferSize + + MbbNdisGetConnectState, // Query routine + 0, // MinQueryInBufferSize + SIZEOF_NDIS_WWAN_CONTEXT_STATE_REVISION_2, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_CONNECT }, // ResponseCommand + sizeof(MBB_CONTEXT_STATE), // ResponseBufferLength + MbbNdisConnectStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_INVALID, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + FALSE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbIpGetConfiguration, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_IP_ADDRESS_INFO }, // ResponseCommand + sizeof(MBB_CONTEXT_STATE), // ResponseBufferLength + MbbIpAddressStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_PROVISIONED_CONTEXTS, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_PROVISIONED_CONTEXT_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT), // NdisObjectHeaderSize + + MbbNdisSetProvisionedContexts, // Set routine + sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT), // MinSetInBufferSize + + MbbNdisGetProvisionedContexts, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PROVISIONED_CONTEXTS }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisProvisionedContextStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_PROVISIONED_CONTEXTS, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_PROVISIONED_CONTEXT_REVISION_2, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT_V2), // NdisObjectHeaderSize + + MbbNdisSetProvisionedContextsV2, // Set routine + sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT_V2), // MinSetInBufferSize + + MbbNdisGetProvisionedContextsV2, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_PROVISIONED_CONTEXT_V2 }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisProvisionedContextV2StatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SERVICE_ACTIVATION, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SERVICE_ACTIVATION_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SERVICE_ACTIVATION), // NdisObjectHeaderSize + + MbbNdisSetServiceActivation, // Set routine + sizeof(NDIS_WWAN_SERVICE_ACTIVATION), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_SERVICE_ACTIVATION }, // ResponseCommand + sizeof(MBB_SERVICE_ACTIVATION_STATUS), // ResponseBufferLength + MbbNdisServiceActivationStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // SMS + // + { + OID_WWAN_SMS_CONFIGURATION, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_SMS_CONFIGURATION_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_SMS_CONFIGURATION), // NdisObjectHeaderSize + + MbbNdisSmsSetConfiguration, // Set routine + sizeof(NDIS_WWAN_SET_SMS_CONFIGURATION), // MinSetInBufferSize + + MbbNdisSmsGetConfiguration, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_SMS_CONFIGURATION), // MinQueryOutBufferSize + + { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_CONFIGURATION }, // ResponseCommand + sizeof(MBB_SMS_CONFIGURATION), // ResponseBufferLength + MbbNdisSmsConfigurationStatusHandler, // ResponseHandler + MbbNdisReadyInfoCompletionHandler // CompletionHandler + }, + { + OID_WWAN_SMS_READ, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisSmsRead, // Query routine + sizeof(NDIS_WWAN_SMS_READ), // MinQueryInBufferSize + sizeof(NDIS_WWAN_SMS_RECEIVE), // MinQueryOutBufferSize + + { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_READ }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisSmsReadStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SMS_SEND, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SMS_SEND_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SMS_SEND), // NdisObjectHeaderSize + + MbbNdisSmsSend, // Set routine + sizeof(NDIS_WWAN_SMS_SEND), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_SEND }, // ResponseCommand + sizeof(MBB_SMS_SEND_STATUS), // ResponseBufferLength + MbbNdisSmsSendStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SMS_DELETE, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SMS_DELETE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SMS_DELETE), // NdisObjectHeaderSize + + MbbNdisSmsDelete, // Set routine + sizeof(NDIS_WWAN_SMS_DELETE), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_DELETE }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisSmsDeleteStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SMS_STATUS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisSmsGetStatus, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_SMS_STATUS), // MinQueryOutBufferSize + + { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_STATUS }, // ResponseCommand + sizeof(MBB_SMS_STATUS), // ResponseBufferLength + MbbNdisSmsStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // USSD + // + { + OID_WWAN_USSD, // Oid + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_USSD_REQUEST_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_USSD_REQUEST), // NdisObjectHeaderSize + + MbbNdisSetUSSD, // Set routine + sizeof(NDIS_WWAN_USSD_REQUEST), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_USSD_CONSTANT, MBB_USSD_CID_USSD }, // ResponseCommand + sizeof(MBB_USSD), // ResponseBufferLength + MbbNdisUSSDStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // DEVICE SERVICES + // + { + OID_WWAN_ENUMERATE_DEVICE_SERVICES, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisEnumerateDeviceServices, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_DEVICE_SERVICES }, // ResponseCommand + sizeof(MBB_DEVICE_SERVICES_HEADER), // ResponseBufferLength + MbbNdisDeviceServiceListStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_DEVICE_SERVICE_COMMAND, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_DEVICE_SERVICE_COMMAND_REVISION_1, // NdisObjectHeaderRevision + SIZEOF_NDIS_WWAN_DEVICE_SERVICE_COMMAND_1, // NdisObjectHeaderSize + + MbbNdisSetDeviceServiceCommand, // Set routine + sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND), // MinSetInBufferSize + + MbbNdisGetDeviceServiceCommand, // Query routine + sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND), // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisDeviceServiceStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS_REVISION_1, // NdisObjectHeaderRevision + SIZEOF_NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS_1, // NdisObjectHeaderSize + + MbbNdisSubscribeDeviceServiceEvents, // Set routine + sizeof(NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisSubscribeDeviceServiceEventsStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS_REVISION_1, // NdisObjectHeaderRevision + SIZEOF_NDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS_1, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisEnumerateDeviceServiceCommands, // Query routine + sizeof(NDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS), // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_MAXIMUM }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_DEVICE_SERVICE_SESSION_WRITE, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + FALSE, // IsSerialized + TRUE, // IsIndicationRequired = Indicate will complete + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_REVISION_1, // NdisObjectHeaderRevision + SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_1, // NdisObjectHeaderSize + + MbbNdisDssWrite, // Set routine + sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisDssWriteCompleteStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_PREFERRED_MULTICARRIER_PROVIDERS, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS), // NdisObjectHeaderSize + + MbbNdisSetMulticarrierProviders, // Set routine + sizeof(NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS), // MinSetInBufferSize + + MbbNdisGetMulticarrierProviders, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_MULTICARRIER_PROVIDERS }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisMulticarrierProviderStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // CREATE/DELETE MAC + // + { + OID_WWAN_CREATE_MAC, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_MAC_PARAMETERS_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_MAC_PARAMETERS), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisCreateMac, // Query routine + SIZEOF_NDIS_WWAN_MAC_PARAMETERS_1, // MinQueryInBufferSize + sizeof(NDIS_WWAN_MAC_INFO), // MinQueryOutBufferSize + + {MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + MbbNdisCreateMacCompletionHandler // CompletionHandler + }, + { + OID_WWAN_DELETE_MAC, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_MAC_PARAMETERS_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_MAC_PARAMETERS), // NdisObjectHeaderSize + + MbbNdisDeleteMac, // Set routine + sizeof(NDIS_WWAN_MAC_INFO), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + MbbNdisDeleteMacCompletionHandler // CompletionHandler + }, + // + // MULTI-CARRIER + // + { + OID_INVALID, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetMultiCarrierDsCidList, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_MULTICARRIER_CONSTANT, MBB_MULTICARRIER_CID_CURRENT_CID_LIST }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisMultiCarrierDsCidListStatusHandler, // ResponseHandler + MbbNdisMultiCarrierDsCidListCompletionHandler // CompletionHandler + }, + // + // UICC + // + { + OID_WWAN_UICC_APP_LIST, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_UICC_APP_LIST_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_UICC_APP_LIST), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetUiccAppList, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_UICC_APP_LIST), // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_APP_LIST }, // ResponseCommand + sizeof(MBB_UICC_APP_LIST), // ResponseBufferLength + MbbNdisUiccAppListStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_UICC_FILE_STATUS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_UICC_FILE_PATH_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_UICC_FILE_PATH), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetUiccFileStatus, // Query routine + sizeof(NDIS_WWAN_UICC_FILE_PATH), // MinQueryInBufferSize + sizeof(NDIS_WWAN_UICC_FILE_STATUS), // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_FILE_STATUS }, // ResponseCommand + sizeof(MBB_UICC_FILE_STATUS), // ResponseBufferLength + MbbNdisUiccFileStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_UICC_ACCESS_BINARY, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_UICC_ACCESS_BINARY_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_UICC_ACCESS_BINARY), // NdisObjectHeaderSize + + MbbNdisUiccUpdateBinary, // Set routine + sizeof(NDIS_WWAN_UICC_ACCESS_BINARY), // MinSetInBufferSize + + MbbNdisUiccReadBinary, // Query routine + sizeof(NDIS_WWAN_UICC_ACCESS_BINARY), // MinQueryInBufferSize + sizeof(NDIS_WWAN_UICC_RESPONSE), // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_ACCESS_BINARY }, // ResponseCommand + sizeof(MBB_UICC_RESPONSE), // ResponseBufferLength + MbbNdisUiccAccessStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_UICC_ACCESS_RECORD, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_UICC_ACCESS_RECORD_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_UICC_ACCESS_RECORD), // NdisObjectHeaderSize + + MbbNdisUiccUpdateRecord, // Set routine + sizeof(NDIS_WWAN_UICC_ACCESS_RECORD), // MinSetInBufferSize + + MbbNdisUiccReadRecord, // Query routine + sizeof(NDIS_WWAN_UICC_ACCESS_RECORD), // MinQueryInBufferSize + sizeof(NDIS_WWAN_UICC_RESPONSE), // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_ACCESS_RECORD }, // ResponseCommand + sizeof(MBB_UICC_RESPONSE), // ResponseBufferLength + MbbNdisUiccAccessStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // UICC Security in MBIM 2.0 + // + { + OID_WWAN_PIN_EX2, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_PIN_REVISION_3, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_PIN_EX2), // NdisObjectHeaderSize + + MbbNdisSetPinInfoEx2, // Set routine + sizeof(NDIS_WWAN_SET_PIN_EX2), // MinSetInBufferSize + + MbbNdisGetPinInfoEx, // Query routine + sizeof(NDIS_WWAN_PIN_APP), // MinQueryInBufferSize + sizeof(NDIS_WWAN_PIN_INFO), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_PIN_INFO_EX2 }, // ResponseCommand + sizeof(MBB_PIN_INFO), // ResponseBufferLength + MbbNdisPinInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // MBIM-VERSION + // + { + OID_WWAN_MBIM_VERSION, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_MBIM_VERSION_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_MBIM_VERSION), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetMbimVersion, // Query routine + 0, // MinQueryInBufferSize + sizeof(USHORT), // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + // + // Device State and Configuration for MBIM 2.0 + // + { + OID_WWAN_SYS_CAPS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetSysCapsInfo, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_SYS_CAPS_INFO), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_SYS_CAPS }, // ResponseCommand + sizeof(MBB_MS_SYS_CAPS_INFO), // ResponseBufferLength + MbbNdisSysCapsStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_DEVICE_CAPS_EX, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetDeviceCapsEx, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_DEVICE_CAPS_EX), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_DEVICE_CAPS_V2 }, // ResponseCommand + sizeof(MBB_MS_DEVICE_CAPS_INFO_V2), // ResponseBufferLength + MbbNdisDeviceCapsExStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SYS_SLOTMAPPINGS, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO), // NdisObjectHeaderSize + + MbbNdisSetSysSlotMappings, // Set routine + sizeof(NDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO), // MinSetInBufferSize + + MbbNdisGetSysSlotMappings, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_DEVICE_SLOT_MAPPINGS }, // ResponseCommand + sizeof(MBB_MS_DEVICE_SLOT_MAPPING_INFO), // ResponseBufferLength + MbbNdisSysSlotMappingsStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SLOT_INFO_STATUS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetSlotInfoStatus, // Query routine + sizeof(NDIS_WWAN_GET_SLOT_INFO), // MinQueryInBufferSize + sizeof(NDIS_WWAN_SLOT_INFO), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_SLOT_INFO_STATUS }, // ResponseCommand + sizeof(MBB_MS_SLOT_INFO), // ResponseBufferLength + MbbNdisSlotInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_DEVICE_BINDINGS, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_DEVICE_BINDINGS_INFO_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_DEVICE_BINDINGS_INFO), // NdisObjectHeaderSize + + MbbNdisSetDeviceBindings, // Set routine + sizeof(NDIS_WWAN_SET_DEVICE_BINDINGS_INFO), // MinSetInBufferSize + + MbbNdisGetDeviceBindings, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO), // MinQueryOutBufferSize + + { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_DEVICE_BINDINGS }, // ResponseCommand + sizeof(MBB_DEVICE_BINDINGS_INFO), // ResponseBufferLength + MbbNdisDeviceBindingsStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // Registration, Signal Strength, and NITZ for MBIM 2.0 + // + { + OID_WWAN_REGISTER_STATE_EX, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_REGISTER_STATE_REVISION_2, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_REGISTER_STATE_EX), // NdisObjectHeaderSize + + MbbNdisSetRegisterState, // Set routine + sizeof(NDIS_WWAN_SET_REGISTER_STATE_EX), // MinSetInBufferSize + + MbbNdisGetRegisterStateEx, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX), // MinQueryOutBufferSize + + { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_REGISTER_STATE_V2 }, // ResponseCommand + sizeof(MBB_REGISTRATION_STATE_INFOS_V2), // ResponseBufferLength + MbbNdisRegisterStateExStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_IMS_VOICE_STATE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_IMS_VOICE_STATE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_IMS_VOICE_STATE), // NdisObjectHeaderSize + + MbbNdisSetImsVoiceState, // Set routine + sizeof(NDIS_WWAN_SET_IMS_VOICE_STATE), // MinSetInBufferSize + + MbbNdisGetImsVoiceState, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_IMS_VOICE_STATE), // MinQueryOutBufferSize + + { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_IMS_VOICE_STATE }, // ResponseCommand + sizeof(MBB_IMS_VOICE_STATE), // ResponseBufferLength + MbbNdisImsVoiceStateStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SIGNAL_STATE_EX, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_SIGNAL_INDICATION_REVISION_2, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION_EX), // NdisObjectHeaderSize + + MbbNdisSetSignalStateEx, // Set routine + sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION_EX), // MinSetInBufferSize + + MbbNdisGetSignalStateEx, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX), // MinQueryOutBufferSize + + { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_SIGNAL_STATE_V2 }, // ResponseCommand + sizeof(MBB_SIGNAL_STATE_INFOS_V2), // ResponseBufferLength + MbbNdisSignalStateExStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_LOCATION_STATE, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_LOCATION_TRIGGER_MODE_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_LOCATION_TRIGGER_MODE), // NdisObjectHeaderSize + + MbbNdisSetLocationState, // Set routine + sizeof(NDIS_WWAN_LOCATION_TRIGGER_MODE), // MinSetInBufferSize + + MbbNdisGetLocationState, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_LOCATION_STATE_INFO), // MinQueryOutBufferSize + + { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_LOCATION_STATE }, // ResponseCommand + sizeof(MBB_LOCATION_STATE_INFO), // ResponseBufferLength + MbbNdisLocationStateStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_NITZ, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetNitzInfo, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_NITZ_INFO), // MinQueryOutBufferSize + + { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_NITZ }, // ResponseCommand + sizeof(MBB_NITZ_INFO), // ResponseBufferLength + MbbNdisNitzStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // For MBIM vendor specific + // + { + OID_WWAN_VENDOR_SPECIFIC, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_VENDOR_SPECIFIC_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_VENDOR_SPECIFIC), // NdisObjectHeaderSize + + MbbNdisSetVendorSpecific, // Set routine + sizeof(NDIS_WWAN_VENDOR_SPECIFIC), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_MS_VENDOR_EXTENSION_CONSTANT, MBIM_CID_VENDORSPECIFIC }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisVendorSpecificStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // Network Idle Hint + // + { + OID_WWAN_NETWORK_IDLE_HINT, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + FALSE, // IsSerialized + FALSE, // IsIndicationRequired + FALSE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_NETWORK_IDLE_HINT_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_NETWORK_IDLE_HINT), // NdisObjectHeaderSize + + MbbNdisSetNetworkIdleHint, // Set routine + sizeof(NDIS_WWAN_NETWORK_IDLE_HINT), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand + 0, // ResponseBufferLength + NULL, // ResponseHandler + NULL // CompletionHandler + }, + // + // System Preshutdown + // + { + OID_WWAN_PRESHUTDOWN, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_PRESHUTDOWN_STATE_REVISION_1, // NdisObjectHeaderRevision + SIZEOF_NDIS_WWAN_SET_PRESHUTDOWN_STATE_1, // NdisObjectHeaderSize + + MbbNdisSetPreshutdown, // Set routine + SIZEOF_NDIS_WWAN_SET_PRESHUTDOWN_STATE_1, // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_HOSTSHUTDOWN_CONSTANT, MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN }, // ResponseCommand + SIZEOF_NDIS_WWAN_PRESHUTDOWN_STATE_1, // ResponseBufferLength + MbbNdisPreshutdownHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // Low-Level UICC Access + // + { + OID_WWAN_UICC_ATR, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetAtr, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_ATR_INFO), // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_ATR }, // ResponseCommand + sizeof(MBB_ATR_INFO), // ResponseBufferLength + MbbNdisAtrInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_UICC_OPEN_CHANNEL, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_UICC_OPEN_CHANNEL_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_UICC_OPEN_CHANNEL), // NdisObjectHeaderSize + + MbbNdisSetUiccOpenChannel, // Set routine + sizeof(NDIS_WWAN_SET_UICC_OPEN_CHANNEL), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_OPEN_CHANNEL }, // ResponseCommand + sizeof(MBB_UICC_OPEN_CHANNEL_INFO), // ResponseBufferLength + MbbNdisUiccOpenChannelInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_UICC_CLOSE_CHANNEL, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_UICC_CLOSE_CHANNEL_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_UICC_CLOSE_CHANNEL), // NdisObjectHeaderSize + + MbbNdisSetUiccCloseChannel, // Set routine + sizeof(NDIS_WWAN_SET_UICC_CLOSE_CHANNEL), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_CLOSE_CHANNEL }, // ResponseCommand + sizeof(MBB_UICC_CLOSE_CHANNEL_INFO), // ResponseBufferLength + MbbNdisUiccCloseChannelInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_UICC_APDU, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_UICC_APDU_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_UICC_APDU), // NdisObjectHeaderSize + + MbbNdisSetUiccApdu, // Set routine + sizeof(NDIS_WWAN_SET_UICC_APDU), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_APDU },// ResponseCommand + sizeof(MBB_UICC_APDU_INFO), // ResponseBufferLength + MbbNdisUiccApduInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_UICC_TERMINAL_CAPABILITY, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY), // NdisObjectHeaderSize + + MbbNdisSetUiccTerminalCapability, // Set routine + sizeof(NDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY), // MinSetInBufferSize + + MbbNdisGetUiccTerminalCapability, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO), // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_TERMINAL_CAPABILITY }, // ResponseCommand + sizeof(MBB_UICC_TERMINAL_CAPABILITY_INFO), // ResponseBufferLength + MbbNdisUiccTerminalCapabilityInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + // + // SAR backoff + // + { + OID_WWAN_SAR_CONFIG, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_SAR_CONFIG_REVISON_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_SAR_CONFIG), // NdisObjectHeaderSize + + MbbNdisSetSarConfig, // Set routine + sizeof(NDIS_WWAN_SET_SAR_CONFIG), // MinSetInBufferSize + + MbbNdisGetSarConfig, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_SAR_CONFIG_INFO), // MinQueryOutBufferSize + + { MBB_UUID_SARCONTROL_CONSTANT, MBB_SAR_CID_CONFIG }, // ResponseCommand + sizeof(MBB_SAR_CONFIG_INFO), // ResponseBufferLength + MbbNdisSarConfigHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_SAR_TRANSMISSION_STATUS, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_SAR_TRANSMISSION_STATUS_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_SAR_TRANSMISSION_STATUS), // NdisObjectHeaderSize + + MbbNdisSetSarTransmissionStatus, // Set routine + sizeof(NDIS_WWAN_SET_SAR_TRANSMISSION_STATUS), // MinSetInBufferSize + + MbbNdisGetSarTransmissionStatus, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO), // MinQueryOutBufferSize + + { MBB_UUID_SARCONTROL_CONSTANT, MBB_SAR_CID_TRANSMISSION_STATUS }, // ResponseCommand + sizeof(MBB_SAR_TRANSMISSION_STATUS_INFO), // ResponseBufferLength + MbbNdisSarTransmissionStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_LTE_ATTACH_CONFIG, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_LTE_ATTACH_CONTEXT_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_LTE_ATTACH_CONTEXT), // NdisObjectHeaderSize + + MbbNdisSetLteAttachContexts, // Set routine + sizeof(NDIS_WWAN_SET_LTE_ATTACH_CONTEXT), // MinSetInBufferSize + + MbbNdisGetLteAttachConfig, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_LTE_ATTACH_CONTEXTS), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_LTE_ATTACH_CONFIG }, // ResponseCommand + sizeof(MBB_MS_LTE_ATTACH_CONFIG_INFO), // ResponseBufferLength + MbbNdisLteAttachConfigHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_LTE_ATTACH_STATUS, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + 0, // NdisObjectHeaderType + 0, // NdisObjectHeaderRevision + 0, // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetLteAttachStatus, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_SYS_CAPS_INFO), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_LTE_ATTACH_STATUS }, // ResponseCommand + sizeof(MBB_MS_LTE_ATTACH_STATUS), // ResponseBufferLength + MbbNdisLteAttachStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_NETWORK_BLACKLIST, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_NETWORK_BLACKLIST_REVISON_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_NETWORK_BLACKLIST), // NdisObjectHeaderSize + + MbbNdisSetNetworkBlacklist, // Set routine + sizeof(NDIS_WWAN_SET_NETWORK_BLACKLIST), // MinSetInBufferSize + + MbbUtilQueryAttribute, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_NETWORK_BLACKLIST), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_NETWORK_BLACKLIST }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisNetworkBlacklistHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_PCO, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_PCO_STATUS_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_PCO_STATUS), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetPcoStatus, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_PCO_STATUS), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_PCO }, // ResponseCommand + sizeof(MBB_MS_PCO_VALUE), // ResponseBufferLength + MbbNdisPcoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_UICC_RESET, // Oid + + TRUE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_UICC_RESET_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_UICC_RESET), // NdisObjectHeaderSize + + MbbNdisSetUiccReset, // Set routine + sizeof(NDIS_WWAN_SET_UICC_RESET), // MinSetInBufferSize + + MbbNdisGetUiccReset, // Query routine + 0, // MinQueryInBufferSize + sizeof(NDIS_WWAN_UICC_RESET_INFO), // MinQueryOutBufferSize + + { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_RESET }, // ResponseCommand + sizeof(MBB_UICC_RESET_INFO), // ResponseBufferLength + MbbNdisUiccResetInfoStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_DEVICE_RESET, // Oid + + TRUE, // IsSettable + FALSE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_SET_DEVICE_RESET_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_SET_DEVICE_RESET), // NdisObjectHeaderSize + + MbbNdisSetDeviceReset, // Set routine + sizeof(NDIS_WWAN_SET_DEVICE_RESET), // MinSetInBufferSize + + NULL, // Query routine + 0, // MinQueryInBufferSize + 0, // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_DEVICE_RESET }, // ResponseCommand + 0, // ResponseBufferLength + MbbNdisDeviceResetStatusHandler, // ResponseHandler + NULL // CompletionHandler + }, + { + OID_WWAN_BASE_STATIONS_INFO, // Oid + + FALSE, // IsSettable + TRUE, // IsQueryable + TRUE, // IsSerialized + TRUE, // IsIndicationRequired + TRUE, // CompleteRequestOnSendComplete + + NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType + NDIS_WWAN_BASE_STATIONS_INFO_REQ_REVISION_1, // NdisObjectHeaderRevision + sizeof(NDIS_WWAN_BASE_STATIONS_INFO_REQ), // NdisObjectHeaderSize + + NULL, // Set routine + 0, // MinSetInBufferSize + + MbbNdisGetBaseStationsInfo, // Query routine + sizeof(NDIS_WWAN_BASE_STATIONS_INFO_REQ), // MinQueryInBufferSize + FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData), // MinQueryOutBufferSize + + { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_BASE_STATIONS_INFO }, // ResponseCommand + FIELD_OFFSET(MBB_MS_BASE_STATIONS_INFO, DataBuffer), // ResponseBufferLength + MbbNdisBaseStationsInfoHandler, // ResponseHandler + NULL // CompletionHandler + }, + + { 0 } // terminator +}; + + +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINITIONS +// +//////////////////////////////////////////////////////////////////////////////// + + +NDIS_STATUS +MbbNdisAdapterWriteBoolParameter( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN Value, + __in PNDIS_STRING RegNameString + ) +{ + NDIS_CONFIGURATION_OBJECT ConfigObject; + NDIS_HANDLE RegistryConfigurationHandle = NULL; + NDIS_CONFIGURATION_PARAMETER Parameter; + NDIS_STATUS NdisStatus; + + ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; + ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; + ConfigObject.Header.Size = sizeof( NDIS_CONFIGURATION_OBJECT ); + ConfigObject.NdisHandle = Adapter->MiniportAdapterHandle; + ConfigObject.Flags = 0; + + NdisStatus = NdisOpenConfigurationEx( + &ConfigObject, + &RegistryConfigurationHandle + ); + + if ((NdisStatus == NDIS_STATUS_SUCCESS) && (RegistryConfigurationHandle != NULL)) + { + NdisZeroMemory(&Parameter, sizeof(NDIS_CONFIGURATION_PARAMETER)); + + Parameter.ParameterData.IntegerData = (Value ? 1 : 0); + Parameter.ParameterType = NdisParameterInteger; + + NdisWriteConfiguration( + &NdisStatus, + RegistryConfigurationHandle, + RegNameString, + &Parameter + ); + } + else + { + TraceError( WMBCLASS_OID, "[MbbAdapter] FAILED to open configuration, status=%!STATUS!", NdisStatus ); + } + + // + // Close the handle to the registry + // + if (RegistryConfigurationHandle) + { + NdisCloseConfiguration(RegistryConfigurationHandle); + } + + return NdisStatus; +} + +MBB_BUS_HANDLE +MbbNdisGetBusHandle( + __in MBB_PROTOCOL_HANDLE AdapterHandle + ) +{ + return ((PMINIPORT_ADAPTER_CONTEXT)AdapterHandle)->BusHandle; +} + +NDIS_OID +MbbNdisGetOid( + __in PNDIS_OID_REQUEST OidRequest + ) +{ + switch( OidRequest->RequestType ) + { + case NdisRequestQueryInformation: + case NdisRequestQueryStatistics: + { + return OidRequest->DATA.QUERY_INFORMATION.Oid; + } + break; + + case NdisRequestSetInformation: + { + return OidRequest->DATA.SET_INFORMATION.Oid; + } + break; + + case NdisRequestMethod: + { + return OidRequest->DATA.METHOD_INFORMATION.Oid; + } + break; + } + + return (NDIS_OID)0; +} + +PMBB_OID_HANDLER_ENTRY +MbbNdisFetchOidHandler( + __in NDIS_OID Oid, + __in PNDIS_OID_REQUEST OidRequest + ) +{ + ULONG OidTableIndex; + PMBB_OID_HANDLER_ENTRY OidHandlerEntry = NULL; + PNDIS_WWAN_AUTH_CHALLENGE ndisWwanAuthChallenge; + ULONG CmdId = 0; + + + // + // Crack open the OID request + // + switch (Oid){ + case OID_WWAN_AUTH_CHALLENGE: + { + if (OidRequest->RequestType == NdisRequestQueryInformation){ + + if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < sizeof(*ndisWwanAuthChallenge)) + { + return NULL; + } + + ndisWwanAuthChallenge = (PNDIS_WWAN_AUTH_CHALLENGE)OidRequest->DATA.QUERY_INFORMATION.InformationBuffer; + if (ndisWwanAuthChallenge->AuthChallenge.AuthMethod == WwanAuthAka){ + CmdId = MBB_AUTH_CID_AKA; + } + else if (ndisWwanAuthChallenge->AuthChallenge.AuthMethod == WwanAuthAkaPrime){ + CmdId = MBB_AUTH_CID_AKAP; + } + else if (ndisWwanAuthChallenge->AuthChallenge.AuthMethod == WwanAuthSim){ + CmdId = MBB_AUTH_CID_SIM; + } + } + } + break; + case OID_WWAN_DEVICE_SERVICE_SESSION: + { + if (OidRequest->RequestType == NdisRequestSetInformation){ + + CmdId = MBB_DSS_CID_CONNECT; + } + + } + break; + + } + + + for( OidTableIndex = 0; + MbbSpecialOidHandlerTable[OidTableIndex].Oid != 0; + OidTableIndex++ ) + { + if( MbbSpecialOidHandlerTable[OidTableIndex].Oid == Oid ) + { + OidHandlerEntry = &MbbSpecialOidHandlerTable[OidTableIndex]; + if (CmdId == OidHandlerEntry->ResponseCommand.CommandId){ + return OidHandlerEntry; + } + } + } + + return NULL; +} + +PMBB_OID_HANDLER_ENTRY +MbbNdisFetchOidHandlerWithRev( + __in NDIS_OID Oid, + __in PNDIS_OID_REQUEST OidRequest +) +{ + ULONG OidTableIndex; + PMBB_OID_HANDLER_ENTRY OidHandlerEntry = NULL; + PNDIS_OBJECT_HEADER ndisHeader = NULL; + + // + // Crack open the OID request + // + switch (Oid) { + case OID_WWAN_PROVISIONED_CONTEXTS: + { + if (OidRequest->RequestType == NdisRequestQueryInformation) + { + ndisHeader = (PNDIS_OBJECT_HEADER)OidRequest->DATA.QUERY_INFORMATION.InformationBuffer; + } + else if (OidRequest->RequestType == NdisRequestSetInformation) + { + ndisHeader = (PNDIS_OBJECT_HEADER)OidRequest->DATA.SET_INFORMATION.InformationBuffer; + } + } + break; + + } + + if (ndisHeader) + { + for (OidTableIndex = 0; + MbbOidHandlerTable[OidTableIndex].Oid != 0; + OidTableIndex++) + { + if (MbbOidHandlerTable[OidTableIndex].Oid == Oid && + ndisHeader->Revision == MbbOidHandlerTable[OidTableIndex].NdisObjectHeaderRevision) + { + OidHandlerEntry = &MbbOidHandlerTable[OidTableIndex]; + break; + } + } + } + + return OidHandlerEntry; +} + +PMBB_OID_HANDLER_ENTRY +MbbNdisGetOidHandler( + __in NDIS_OID Oid + ) +{ + ULONG OidTableIndex; + PMBB_OID_HANDLER_ENTRY OidHandlerEntry = NULL; + + for( OidTableIndex = 0; + MbbOidHandlerTable[OidTableIndex].Oid != 0; + OidTableIndex++ ) + { + if( MbbOidHandlerTable[OidTableIndex].Oid == Oid ) + { + OidHandlerEntry = &MbbOidHandlerTable[OidTableIndex]; + break; + } + } + return OidHandlerEntry; +} + +PMBB_OID_HANDLER_ENTRY +MbbNdisGetOidHandlerByCommand( + __in PMBB_COMMAND Command + ) +{ + ULONG OidTableIndex; + ULONG TableNumber; + PMBB_OID_HANDLER_ENTRY Table; + PMBB_OID_HANDLER_ENTRY OidHandlerEntry = NULL; + + if( Command->CommandId == 0 && + memcmp( + &MBB_UUID_INVALID, + &(Command->ServiceId), + sizeof(GUID) + ) == 0 ) + { + return NULL; + } + + for( TableNumber = 0; + TableNumber < 2; + TableNumber ++ ) + { + if( TableNumber == 0 ) + Table = MbbOidHandlerTable; + else + Table = MbbSpecialOidHandlerTable; + + for( OidTableIndex = 0; + Table[OidTableIndex].Oid != 0; + OidTableIndex++ ) + { + if( Command->CommandId == Table[OidTableIndex].ResponseCommand.CommandId + && + memcmp( + &(Table[OidTableIndex].ResponseCommand.ServiceId), + &(Command->ServiceId), + sizeof(GUID) + ) == 0 ) + { + OidHandlerEntry = &Table[OidTableIndex]; + break; + } + } + } + + return OidHandlerEntry; +} + +__inline +VOID +MbbNdisMiniportIndicateRequestStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in PNDIS_STATUS_INDICATION StatusIndication + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=Request->RequestManager->AdapterContext; + + MbbUtilNdisMiniportIndicateStatusEx(Adapter, StatusIndication); +} + +VOID +MbbNdisMiniportOidRequestCompletion( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + NDIS_STATUS LocalNdisStatus; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(AdapterHandle); + PCSTR OidName=NULL; + ULONG OidNameLength=0; + BOOLEAN CompleteNdisRequest=TRUE; + BOOLEAN IndicationSentInHandler=FALSE; + + if (NdisStatus == MBB_STATUS_INDICATION_ALREADY_SENT) + { + // + // the request handler has indicated the response already, fix up the status + // and remember that we don't need to hold the request for a response that is not coming. + // + IndicationSentInHandler=TRUE; + NdisStatus = NDIS_STATUS_SUCCESS; + } + + if( NdisStatus == NDIS_STATUS_SUCCESS && + Request->OidHandler->IsIndicationRequired == TRUE ) + { + NdisStatus = NDIS_STATUS_INDICATION_REQUIRED; + + if (!Request->OidHandler->CompleteRequestOnSendComplete) + { + // + // We don't want to complete the request back to ndis at this point. + // We will complete the request when the response comes back from the device. + // + CompleteNdisRequest=FALSE; + } + + } + + if ((NdisStatus == NDIS_STATUS_PENDING)) + { + // + // We don't want to complete with status pending + // + CompleteNdisRequest=FALSE; + } + + // + // Complete the request to NDIS + // + if( CompleteNdisRequest ) + { + PNDIS_OID_REQUEST NdisRequest=NULL; + + NdisRequest=InterlockedExchangePointer(&Request->OidContext.OidRequest,(PNDIS_OID_REQUEST)-1); + + if (NdisRequest != (PNDIS_OID_REQUEST)-1) + { + MBB_NDIS_OID_STATE OldOidState; + + Request->OidContext.OidStatus = NdisStatus; + // + // Do not complete the OID request if the Oid handler is still running. + // Defer the OID completion to the Oid handler + // + OldOidState = MbbReqMgrGetSetOidState( + Request, + MbbNdisOidStateComplete + ); + if( OldOidState == MbbNdisOidStatePending || + OldOidState == MbbNdisOidStateDispatched ) + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Completing OID request in %!MbbOidState! to NDIS with status=%!status!", + Request->RequestId, OldOidState, NdisStatus + ); + + OidName=GetOidName(NdisRequest->DATA.QUERY_INFORMATION.Oid); + OidNameLength=strlen(OidName)+1; + + MbbWriteEvent( + &REQUEST_COMPLETE_EVENT, + NULL, + NULL, + 10, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &NdisRequest, + sizeof(NdisRequest), + &NdisRequest->DATA.QUERY_INFORMATION.Oid, + sizeof(NdisRequest->DATA.QUERY_INFORMATION.Oid), + (PVOID)OidName, + OidNameLength, + &NdisRequest->RequestId, + sizeof(NdisRequest->RequestId), + &NdisRequest->RequestHandle, + sizeof(NdisRequest->RequestHandle), + &NdisRequest->RequestType, + sizeof(NdisRequest->RequestType), + &NdisRequest->DATA.QUERY_INFORMATION.BytesWritten, + sizeof(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten), + &NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded, + sizeof(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded), + &NdisStatus, + sizeof(NdisStatus) + ); + + + NdisMOidRequestComplete( + Adapter->MiniportAdapterHandle, + NdisRequest, + NdisStatus + ); + + NdisRequest=NULL; + } + else + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Deferring oid completion in %!MbbOidState!", + Request->RequestId, OldOidState + ); + } + } + else + { + TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Oid already completed", + Request->RequestId + ); + } + } + + if( Request->OidHandler->CompletionHandler != NULL ) + { + Request->OidHandler->CompletionHandler( + Request, + NdisStatus + ); + } + + if( Request->HandlerContext.DataToFreeOnCompletion != NULL ) + FREE_POOL( Request->HandlerContext.DataToFreeOnCompletion ); + // + // If the request does not wait for a NDIS INDICATTION + // then free the request else move the request FSM + // to the next state. + // + if( IndicationSentInHandler || + ( NdisStatus != NDIS_STATUS_PENDING && + NdisStatus != NDIS_STATUS_INDICATION_REQUIRED )) + { + if ( Request->HandlerContext.DataToFreeOnResponse != NULL ) + FREE_POOL( Request->HandlerContext.DataToFreeOnResponse ); + + KeSetEvent( + &Request->WaitEvent, + IO_NO_INCREMENT, + FALSE + ); + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + + if (NdisStatus == NDIS_STATUS_FAILURE) + { + PMBB_SEND_QUEUE SendQueue = &Adapter->SendQueue; + switch (Request->OidHandler->Oid) + { + case OID_WWAN_RADIO_STATE: + TraceLoggingWrite( + g_hLoggingProvider, + "RadioStateSendFailure", + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + TryQueueStallState(SendQueue); + break; + } + } +} + +NDIS_STATUS +MbbNdisMiniportOidRequest( + __in NDIS_HANDLE MiniportAdapter, + __in PNDIS_OID_REQUEST OidRequest + ) +{ + NDIS_OID Oid; + ULONG ResponseBufferLength; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + PMBB_OID_HANDLER_ENTRY OidHandler; + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapter; + NDIS_STATUS Status=NDIS_STATUS_NOT_SUPPORTED; + PCSTR OidName=NULL; + ULONG OidNameLength=0; + + do + { + OidName=GetOidName(OidRequest->DATA.QUERY_INFORMATION.Oid); + OidNameLength=strlen(OidName)+1; + + MbbWriteEvent( + &REQUEST_EVENT, + NULL, + NULL, + 8, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &OidRequest, + sizeof(OidRequest), + &OidRequest->DATA.QUERY_INFORMATION.Oid, + sizeof(OidRequest->DATA.QUERY_INFORMATION.Oid), + (PVOID)OidName, + OidNameLength, + &OidRequest->RequestId, + sizeof(OidRequest->RequestId), + &OidRequest->RequestHandle, + sizeof(OidRequest->RequestHandle), + &OidRequest->RequestType, + sizeof(OidRequest->RequestType), + &OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength, + sizeof(OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength) + ); + + if( (Oid = MbbNdisGetOid( OidRequest )) == 0 ) + { + TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to get Oid value" ); + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + // + // Find it in the Oid table. But first check if it is a special OID that needs to handled differently. + // If its not in the OID table then its not supported. + // + if ((OID_WWAN_AUTH_CHALLENGE == Oid ) || + (OID_WWAN_DEVICE_SERVICE_SESSION == Oid)) { + OidHandler = MbbNdisFetchOidHandler(Oid, OidRequest); + if (NULL == OidHandler) { + TraceError( WMBCLASS_OID, "[MbbNdis] UNSUPPORTED Oid=0x%x", Oid ); + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + } + else if (OID_WWAN_PROVISIONED_CONTEXTS == Oid) + { + OidHandler = MbbNdisFetchOidHandlerWithRev(Oid, OidRequest); + if (NULL == OidHandler) { + TraceError(WMBCLASS_OID, "[MbbNdis] UNSUPPORTED Oid=0x%x", Oid); + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + } + else if( (OidHandler = MbbNdisGetOidHandler( Oid )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis] UNSUPPORTED Oid=0x%x", Oid ); + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + // + // Allocate the internal MBB request context. + // + if( OidHandler->IsIndicationRequired == TRUE ) + { + ResponseBufferLength = OidHandler->ResponseBufferLength; + } + else + { + ResponseBufferLength = 0; + } + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to reference RequestManager for Oid=0x%x", Oid); + break; + } + + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + OidRequest, + ResponseBufferLength, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to allocate RequestContext for Oid=0x%x", Oid ); + break; + } + Request->OidHandler = OidHandler; + // + // Perform buffer validation + // + switch( OidRequest->RequestType ) + { + case NdisRequestQueryInformation: + case NdisRequestQueryStatistics: + { + if( OidHandler->IsQueryable == FALSE ) + { + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + // + // Minimum buffer size for query is NOT required for + // requests that are completed via status indications. + // + if( OidHandler->IsIndicationRequired != TRUE && + OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < OidHandler->MinQueryOutBufferSize ) + { + OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = OidHandler->MinQueryOutBufferSize; + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + } + break; + + case NdisRequestSetInformation: + { + if( OidHandler->IsSettable == FALSE ) + { + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + if( OidRequest->DATA.SET_INFORMATION.InformationBufferLength < OidHandler->MinSetInBufferSize ) + { + OidRequest->DATA.SET_INFORMATION.BytesNeeded = OidHandler->MinSetInBufferSize; + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + } + break; + + case NdisRequestMethod: + { + if( OidHandler->IsQueryable == FALSE ) + { + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + if( OidRequest->DATA.METHOD_INFORMATION.InputBufferLength < OidHandler->MinQueryInBufferSize || + OidRequest->DATA.METHOD_INFORMATION.OutputBufferLength < OidHandler->MinQueryOutBufferSize ) + { + OidRequest->DATA.METHOD_INFORMATION.BytesNeeded = MAX( OidHandler->MinQueryInBufferSize, OidHandler->MinQueryOutBufferSize ); + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + } + break; + + default: + { + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + } + break; + } + // + // If buffer validation failed or the OID Handler failed, bail out. + // + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + break; + } + // + // Dispatch the request to the queue for processing. + // If the request completes synchronously cleanup + // the request context. Else the completion routine + // will be called at a later time. + // + MbbReqMgrGetSetOidState( + Request, + MbbNdisOidStatePending + ); + NdisStatus = MbbReqMgrDispatchRequest( + Request, + (OidHandler->IsSerialized == 1), + MbbNdisProcessSerializedOidRequest, + MbbNdisMiniportOidRequestCompletion, + MbbNdisIndicateStatus + ); + } while( FALSE ); + + if( NdisStatus != NDIS_STATUS_PENDING && + NdisStatus != NDIS_STATUS_INDICATION_REQUIRED ) + { + if( Request != NULL ) + { + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + } + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + + if( NdisStatus != NDIS_STATUS_PENDING ) + { + MbbWriteEvent( + &REQUEST_NOT_PENDING_EXIT_EVENT, + NULL, + NULL, + 10, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &OidRequest, + sizeof(OidRequest), + &OidRequest->DATA.QUERY_INFORMATION.Oid, + sizeof(OidRequest->DATA.QUERY_INFORMATION.Oid), + (PVOID)OidName, + OidNameLength, + &OidRequest->RequestId, + sizeof(OidRequest->RequestId), + &OidRequest->RequestHandle, + sizeof(OidRequest->RequestHandle), + &OidRequest->RequestType, + sizeof(OidRequest->RequestType), + &OidRequest->DATA.QUERY_INFORMATION.BytesWritten, + sizeof(OidRequest->DATA.QUERY_INFORMATION.BytesWritten), + &OidRequest->DATA.QUERY_INFORMATION.BytesNeeded, + sizeof(OidRequest->DATA.QUERY_INFORMATION.BytesNeeded), + &NdisStatus, + sizeof(NdisStatus) + ); + + + } + else + { + MbbWriteEvent( + &REQUEST_PENDING_EXIT_EVENT, + NULL, + NULL, + 3, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &OidRequest, + sizeof(OidRequest), + &NdisStatus, + sizeof(NdisStatus) + ); + + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisProcessSerializedOidRequest( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +/*++ + Description + This is the internal serialized routine that calls OID handlers. + Only one instance of this routine will run at any time. + If an OID is associated with this request, NDIS is called to + notify about the OID completion via NdisMOidRequestComplete( ). + + Parameters + __in PMBB_REQUEST_CONTEXT Request + The request to process. This is the internal request representation. + The request + + Return Value + NDIS_STATUS_SUCCESS + The request was successfully processed and the OID, if any, + was successfully completed to NDIS. + + NDIS_STATUS_NOT_SUPPORTED + The request is an invalid request and could not be processed. + + NDIS_STATUS_PENDING + Request completion is deferred by the OID handler. + The OID handler will call NdisMOidRequestComplete( ). +--*/ +{ + NDIS_STATUS NdisStatus = STATUS_SUCCESS; + NDIS_OID Oid = MbbNdisGetOid( Request->OidContext.OidRequest ); + MBB_NDIS_OID_STATE OidState; + PMBB_OID_HANDLER_ENTRY OidHandlerEntry = Request->OidHandler; + PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)AdapterHandle; + + TraceInfo(WMBCLASS_OID, "Entered OID=%08lx ", Oid ); + + MbbReqMgrGetSetOidState( + Request, + MbbNdisOidStateDispatching + ); + // + // Buffers have already been validated. Call the handler. + // + switch( OidRequest->RequestType ) + { + case NdisRequestQueryInformation: + case NdisRequestQueryStatistics: + { + OidRequest->DATA.QUERY_INFORMATION.BytesWritten = OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength; + // + // Ideally, Query requests do not contain an InBuffer. + // SMS_READ,VISIBLE_PROVIDERS and DEVICE_SERVICE_COMMAND overloads + // the OutBuffer as an InBuffer. + // The correct approach would have been to use Method + // request instead of Query but deal with it anyways. + // + switch(Oid) + { + case OID_WWAN_SMS_READ: + case OID_WWAN_DEVICE_SERVICE_COMMAND: + case OID_WWAN_VISIBLE_PROVIDERS: + case OID_WWAN_AUTH_CHALLENGE: + case OID_WWAN_SLOT_INFO_STATUS: + case OID_WWAN_BASE_STATIONS_INFO: + + if( OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < OidHandlerEntry->MinQueryInBufferSize ) + { + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + + + NdisStatus = OidHandlerEntry->QueryHandler( + Request, + OidRequest->DATA.QUERY_INFORMATION.InformationBuffer, + &OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength, + OidRequest->DATA.QUERY_INFORMATION.InformationBuffer, + &OidRequest->DATA.QUERY_INFORMATION.BytesWritten + ); + + break; + + default: + NdisStatus = OidHandlerEntry->QueryHandler( + Request, + NULL, + NULL, + OidRequest->DATA.QUERY_INFORMATION.InformationBuffer, + &OidRequest->DATA.QUERY_INFORMATION.BytesWritten + ); + + break; + } + } + break; + + case NdisRequestSetInformation: + { + OidRequest->DATA.SET_INFORMATION.BytesRead = OidRequest->DATA.SET_INFORMATION.InformationBufferLength; + + NdisStatus = OidHandlerEntry->SetHandler( + Request, + OidRequest->DATA.SET_INFORMATION.InformationBuffer, + &OidRequest->DATA.SET_INFORMATION.BytesRead + ); + } + break; + + case NdisRequestMethod: + { + OidRequest->DATA.METHOD_INFORMATION.BytesRead = OidRequest->DATA.METHOD_INFORMATION.InputBufferLength; + OidRequest->DATA.METHOD_INFORMATION.BytesWritten = OidRequest->DATA.METHOD_INFORMATION.OutputBufferLength; + + NdisStatus = OidHandlerEntry->QueryHandler( + Request, + OidRequest->DATA.METHOD_INFORMATION.InformationBuffer, + &OidRequest->DATA.METHOD_INFORMATION.BytesRead, + OidRequest->DATA.METHOD_INFORMATION.InformationBuffer, + &OidRequest->DATA.METHOD_INFORMATION.BytesWritten + ); + } + break; + + default: + { + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + } + break; + } + // + // Complete the OID request if the Oid completion happened before this point. + // + OidState = MbbReqMgrGetSetOidState( + Request, + MbbNdisOidStateDispatched + ); + if( OidState == MbbNdisOidStateComplete ) + { + PCSTR OidName=NULL; + ULONG OidNameLength=0; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Delay completing OID request to NDIS with status=%!status!", + Request->RequestId, Request->OidContext.OidStatus + ); + + OidName = GetOidName(OidRequest->DATA.QUERY_INFORMATION.Oid); + OidNameLength = strlen(OidName)+1; + + MbbWriteEvent( + &REQUEST_COMPLETE_EVENT, + NULL, + NULL, + 10, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &OidRequest, + sizeof(OidRequest), + &OidRequest->DATA.QUERY_INFORMATION.Oid, + sizeof(OidRequest->DATA.QUERY_INFORMATION.Oid), + (PVOID)OidName, + OidNameLength, + &OidRequest->RequestId, + sizeof(OidRequest->RequestId), + &OidRequest->RequestHandle, + sizeof(OidRequest->RequestHandle), + &OidRequest->RequestType, + sizeof(OidRequest->RequestType), + &OidRequest->DATA.QUERY_INFORMATION.BytesWritten, + sizeof(OidRequest->DATA.QUERY_INFORMATION.BytesWritten), + &OidRequest->DATA.QUERY_INFORMATION.BytesNeeded, + sizeof(OidRequest->DATA.QUERY_INFORMATION.BytesNeeded), + &Request->OidContext.OidStatus, + sizeof(Request->OidContext.OidStatus) + ); + + NdisMOidRequestComplete( + Adapter->MiniportAdapterHandle, + OidRequest, + Request->OidContext.OidStatus + ); + } + + return NdisStatus; +} + +VOID +MbbNdisMiniportCancelOidRequest( + __in NDIS_HANDLE MiniportAdapter, + __in PVOID RequestId // PVOID is of actual type PNDIS_OID_REQUEST + ) + +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapter; + PMBB_REQUEST_MANAGER RequestManager = NULL; + PMBB_REQUEST_CONTEXT Request; + + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis] FAILED to reference RequestManager to cancel OID RequestId=0x%p", RequestId ); + return; + } + + if( (Request = MbbReqMgrGetRequestByOidRequestId( RequestManager, RequestId )) != NULL ) + { + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Received cancel for OID RequestId=0x%p. Submitting cancel to FSM.", Request->RequestId, RequestId ); + + MbbReqMgrQueueEvent( + RequestManager, + Request, + MbbRequestEventCancel, + NULL, + 0 + ); + MbbReqMgrDerefRequest( Request ); + } + else + { + TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to find request with OID RequestId=0x%p for cancellation", RequestId ); + } + MbbReqMgrDeref( RequestManager ); +} + +// +// RESPONSE HANDLING +// + +/*++ + RequestManager->FragmentBuffer is a shared buffer used + to retrieve response fragments. Even if there are multiple + interrupts on the interrupt pipe there will be only one + request active doing a GET_ENCAPSULATED_RESPONSE. + Hence access to the buffer is synchronized. + The synchronisation is guaranteed by MbbReqMgrCompleteRequest( ) + since it queues the SendComplete for the current active + request first before queuing the Start for the next request. + + MbbNdisGetResponseFragment( ) uses the same buffer for reading + each fragment. + + MbbNdisParseCommandResponse( ) reassembles the fragments in + per request response buffer. If the per request pre-allocated + response buffer is not sufficient, re-allocation is attempted. + + MbbNdisParseIndicateStatus( ) reassembles the fragments in + the shared RequestManager->ResponseBuffer. +--*/ + + +VOID +MbbNdisIndicateStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + PMBB_OID_HANDLER_ENTRY OidHandler; + + // + // If the request already has a Oid handler use that. + // Else if this request is doing a status indication it will not have a OidHandler. + // In status indication case + // + if( (OidHandler = Request->OidHandler) == NULL && + (OidHandler = MbbNdisGetOidHandlerByCommand( &(Request->HandlerContext.Response.Command) )) == NULL ) + { + if( !MbbUtilIsNativeMbnService( &Request->HandlerContext.Response.Command.ServiceId ) ) + { + OidHandler = MbbNdisGetOidHandler( OID_WWAN_DEVICE_SERVICE_COMMAND ); + } + } + if( OidHandler == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to find response Handler for ServiceId=%!GUID! Cid=%02d", + Request->RequestId, + &Request->HandlerContext.Response.Command.ServiceId, + Request->HandlerContext.Response.Command.CommandId + ); + NdisStatus = NDIS_STATUS_FAILURE; + } + // + // No NDIS specific work needed. + // Call the common handler to do cleanup. + // + MbbUtilCommonCIDResponse( + Request, + NdisStatus, + MbbStatus, + InBuffer, + InBufferSize, + OidHandler + ); +} + + +NDIS_STATUS +MbbNdisReassembleResponseFragment( + __in_bcount(FragmentLength) PUCHAR FragmentBuffer, + __in ULONG FragmentLength, + __in PMBB_REASSEMBLE_CONTEXT ReassembleContext, + __in BOOLEAN DoReassemble, + __in PMBB_REQUEST_MANAGER RequestManager, + __in GUID ActivityId + ) +/*++ + Return Value + STATUS_SUCCESS + All fragments of the message was successfully reassembled. + STATUS_PENDING + This fragment was successfully reassembled but there are more. + Other + The fragment could not be reassembled. +--*/ +{ + ULONG TransactionId; + ULONG PayloadLength; + ULONG PayloadOffset = 0; + PCHAR ReassembleBuffer = NULL; + ULONG ReassembleBufferOffset = 0; + ULONG ReassembleDataLength = 0; + ULONG FragmentCount; + ULONG CurrentFragment; + NTSTATUS NtStatus = STATUS_SUCCESS; + MBB_COMMAND Command = {0}; + MBB_STATUS MbbStatus = {0}; + PMBB_INDICATE_STATUS_HEADER IndicateStatusHeader; + PMBB_COMMAND_DONE_HEADER CommandDoneHeader; + PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader = (PMBB_COMMAND_FRAGMENT_HEADER)FragmentBuffer; + + + PayloadLength = MessageFragmentHeader->MessageHeader.MessageLength; + TransactionId = MessageFragmentHeader->MessageHeader.MessageTransactionId; + FragmentCount = MessageFragmentHeader->FragmentHeader.TotalFragments; + CurrentFragment = MessageFragmentHeader->FragmentHeader.CurrentFragment; + + do + { + // + // Get extra information from the first fragment + // + if( CurrentFragment == 0 ) + { + if( MessageFragmentHeader->MessageHeader.MessageType == MBB_MESSAGE_TYPE_COMMAND_DONE ) + { + if( FragmentLength < sizeof(MBB_COMMAND_DONE_HEADER) ) + { + return STATUS_NDIS_INVALID_LENGTH; + } + CommandDoneHeader = (PMBB_COMMAND_DONE_HEADER)FragmentBuffer; + + Command.CommandId = CommandDoneHeader->Command.CommandId; + MBB_UUID_TO_HOST( + &Command.ServiceId, + &CommandDoneHeader->Command.ServiceId + ); + MbbStatus = CommandDoneHeader->MbbStatus; + PayloadOffset = sizeof(MBB_COMMAND_DONE_HEADER); + ReassembleDataLength = CommandDoneHeader->InformationBufferLength; + } + else if( MessageFragmentHeader->MessageHeader.MessageType == MBB_MESSAGE_TYPE_INDICATE_STATUS ) + { + if( FragmentLength < sizeof(MBB_INDICATE_STATUS_HEADER) ) + { + return STATUS_NDIS_INVALID_LENGTH; + } + IndicateStatusHeader = (PMBB_INDICATE_STATUS_HEADER)FragmentBuffer; + + Command.CommandId = IndicateStatusHeader->Command.CommandId; + MBB_UUID_TO_HOST( + &Command.ServiceId, + &IndicateStatusHeader->Command.ServiceId + ); + MbbStatus = MBB_STATUS_SUCCESS; + PayloadOffset = sizeof(MBB_INDICATE_STATUS_HEADER); + ReassembleDataLength = IndicateStatusHeader->InformationBufferLength; + } + else + { + NtStatus = STATUS_NDIS_INVALID_DATA; + } + + if( ReassembleDataLength > ReassembleContext->BufferLength ) + { + NtStatus = STATUS_BUFFER_OVERFLOW; + break; + } + // + // Cache the info in the reassemble context for later use. + // + if( DoReassemble ) + { + ReassembleBuffer = ReassembleContext->Buffer; + ReassembleBufferOffset = 0; + } + ReassembleContext->MbbStatus = MbbStatus; + ReassembleContext->DataLength = ReassembleDataLength; + } + // + // For subsequent fragments read savved state from the reassemble context + // + else + { + Command = ReassembleContext->Command; + PayloadOffset = sizeof(MBB_COMMAND_FRAGMENT_HEADER); + + if( DoReassemble ) + { + ReassembleBuffer = ReassembleContext->Buffer; + ReassembleDataLength = ReassembleContext->DataLength; + ReassembleBufferOffset = ReassembleContext->BufferOffset; + } + } + + if( PayloadLength > FragmentLength || + PayloadLength < PayloadOffset ) + { + TraceError( WMBCLASS_OID, + "[MbbNdis][TID=0x%08x] INVALID MessageLength[Receieved=0x%08x < Expected=0x%08x] in Fragment=%02d/%02d", + TransactionId, + FragmentLength, + PayloadLength, + CurrentFragment, + FragmentCount + ); + MbbUtilSendMbimError( + TransactionId, + MBB_ERROR_LENGTH_MISMATCH, + RequestManager->AdapterContext, + ActivityId, + &Command + ); + NtStatus = STATUS_BUFFER_OVERFLOW; + break; + } + + if( DoReassemble ) + { + PayloadLength -= PayloadOffset; + + if( ( PayloadLength + ReassembleBufferOffset ) > ReassembleDataLength ) + { + TraceError( WMBCLASS_OID, + "[MbbNdis][TID=0x%08x] INVALID PayloadLength=0x%08x in Fragment=%02d/%02d. TRUNCATING Response.", + TransactionId, PayloadLength, CurrentFragment, FragmentCount + ); + } + TraceInfo( WMBCLASS_OID, + "[MbbNdis][TID=0x%08x] Received Fragment=%02d/%02d", + TransactionId, CurrentFragment, FragmentCount + ); + RtlCopyMemory( + ReassembleBuffer + ReassembleBufferOffset, + FragmentBuffer + PayloadOffset, + MIN( PayloadLength, (ReassembleDataLength-ReassembleBufferOffset) ) + ); + ReassembleBufferOffset += MIN( PayloadLength, (ReassembleDataLength-ReassembleBufferOffset) ); + + ReassembleContext->BufferOffset = ReassembleBufferOffset; + } + } + while( FALSE ); + + if( NtStatus == STATUS_SUCCESS ) + { + if( (CurrentFragment + 1) < FragmentCount ) + { + NtStatus = STATUS_PENDING; + } + } + // + // If there are more fragments to come arm the inter-fragment timer. + // Else set the final status in the reassemble context. + // + if( NtStatus != STATUS_PENDING ) + { + ReassembleContext->NdisStatus = NtStatus; + } + else + { + MbbReqMgrTimerArm( + RequestManager, + MbbTimerTypeFragment, + 0, + 0, + 0, + FALSE + ); + } + + return NtStatus; +} + +NDIS_STATUS +MbbNdisParseCommandResponse( + __in ULONG TransactionId, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + ULONG MessageFragmentLength; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PMBB_REQUEST_CONTEXT OriginalRequest = NULL; + PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; + PMBB_REASSEMBLE_CONTEXT ReassembleContext = NULL; + PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader; + + do + { + MessageFragmentLength = Request->HandlerContext.Response.FragmentLength; + MessageFragmentHeader = (PMBB_COMMAND_FRAGMENT_HEADER)(Request->HandlerContext.Response.FragmentBuffer); + // + // If the context cannot be acquired that means that another transaction + // is using the context. Indicate an out of order fragment to the device + // and hope it sends the right fragment soon. If not the inter-fragment + // timeout will clean things up. + // + // If fragment is in order but there isnt a request reassemble the + // fragment and then drop it. Reassembly is done to detect errors. + // + if( (ReassembleContext = MbbReqMgrAcquireSharedReassembleContext( + RequestManager, + MessageFragmentHeader, + MessageFragmentLength, + Request->ActivityId + )) != NULL ) + { + GUID ActivityId = {0}; + + OriginalRequest = MbbReqMgrGetRequestByTransactionId( + RequestManager, + TransactionId + ); + + // if there is an OriginalRequest corresponding to this response received + // then we should use the original request activity id so that the original + // request and its response can be traced end to end. If there is no + // OriginalRequest then we will use the activity Id of the current request + + ActivityId = (OriginalRequest) ? OriginalRequest->ActivityId : Request->ActivityId; + + NdisStatus = MbbNdisReassembleResponseFragment( + (PUCHAR)MessageFragmentHeader, + MessageFragmentLength, + ReassembleContext, + OriginalRequest? TRUE: FALSE, // Reassemble + RequestManager, + ActivityId + ); + } + else + { + NdisStatus = NDIS_STATUS_INVALID_DATA; + } + } + while( FALSE ); + + if( NdisStatus != NDIS_STATUS_PENDING ) + { + if( OriginalRequest != NULL ) + { + // + // Copy the common reassemble context used by the request manager + // in to the per request reassemble context. + // + OriginalRequest->HandlerContext.Response = *ReassembleContext; + + MbbReqMgrQueueEvent( + RequestManager, + OriginalRequest, + MbbRequestEventResponseReceived, + OriginalRequest->HandlerContext.Response.Buffer, + OriginalRequest->HandlerContext.Response.DataLength + ); + } + + if( ReassembleContext != NULL ) + { + MbbReqMgrReleaseSharedReassembleContext( RequestManager ); + } + } + + if( OriginalRequest ) + { + MbbReqMgrDerefRequest( OriginalRequest ); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisParseStatusIndication( + __in ULONG TransactionId, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + ULONG MessageFragmentLength; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + MBB_COMMAND Command; + PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; + PMBB_REASSEMBLE_CONTEXT ReassembleContext; + PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader; + + do + { + MessageFragmentLength = Request->HandlerContext.Response.FragmentLength; + MessageFragmentHeader = (PMBB_COMMAND_FRAGMENT_HEADER)(Request->HandlerContext.Response.FragmentBuffer); + // + // If the context cannot be acquired that means that another transaction + // is using the context. Indicate an out of order fragment to the device + // and hope it sends the right fragment soon. If not the inter-fragment + // timeout will clean things up. + // + if( (ReassembleContext = MbbReqMgrAcquireSharedReassembleContext( + RequestManager, + MessageFragmentHeader, + MessageFragmentLength, + Request->ActivityId + )) != NULL ) + { + NdisStatus = MbbNdisReassembleResponseFragment( + (PUCHAR)MessageFragmentHeader, + MessageFragmentLength, + ReassembleContext, + TRUE, // Reassemble + RequestManager, + Request->ActivityId + ); + } + else + { + NdisStatus = NDIS_STATUS_INVALID_DATA; + } + } + while( FALSE ); + + if( NdisStatus == NDIS_STATUS_SUCCESS ) + { + // + // Copy the common reassemble context used by the request manager + // in to the per request reassemble context. + // + Request->HandlerContext.Response = RequestManager->Fragmentation.Reassemble; + // + // Track that this is an indication and not a response. + // + MbbReqMgrSetUnsolicitedIndication( Request ); + + MbbReqMgrQueueEvent( + RequestManager, + Request, + MbbRequestEventResponseReceived, + Request->HandlerContext.Response.Buffer, + Request->HandlerContext.Response.DataLength + ); + } + + if( NdisStatus != NDIS_STATUS_PENDING ) + { + if( ReassembleContext != NULL ) + { + MbbReqMgrReleaseSharedReassembleContext( RequestManager ); + } + } + + // + // Tell the caller whether to keep or destroy the request + // + if( NdisStatus == NDIS_STATUS_SUCCESS ) + NdisStatus = NDIS_STATUS_PENDING; + else if( NdisStatus == NDIS_STATUS_PENDING ) + NdisStatus = NDIS_STATUS_SUCCESS; + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisParseFunctionError( + __in ULONG TransactionId, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + PMBB_ERROR_MESSAGE ErrorMessage = (PMBB_ERROR_MESSAGE)(Request->HandlerContext.Response.FragmentBuffer); +// ULONG ErrorMessageLength = Request->HandlerContext.Response.FragmentLength; + PMBB_REQUEST_CONTEXT OriginalRequest = NULL; + MBB_COMMAND Command = {0}; + PCHAR CommandName; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ); + + do + { + if( (OriginalRequest = MbbReqMgrGetRequestByTransactionId( + Request->RequestManager, + TransactionId + )) != NULL ) + { + TraceError( WMBCLASS_OID, "[MBIM_ERR][ReqID=0x%04x][TID=0x%08x] Received %!MbbError!. Cancelling request.", + OriginalRequest->RequestId, + TransactionId, + ErrorMessage->ErrorCode + ); + // + // MBB_UUID_TO_HOST( ) is not needed here since + // the command is being copied from the original + // request where it is already in the host format. + // + RtlCopyMemory( + &Command, + &OriginalRequest->HandlerContext.Command.Command, + sizeof(MBB_COMMAND) + ); + MbbReqMgrQueueEvent( + OriginalRequest->RequestManager, + OriginalRequest, + MbbRequestEventCancel, + (PVOID)(NDIS_STATUS_REQUEST_ABORTED), + 0 + ); + MbbReqMgrDerefRequest( OriginalRequest ); + } + else + { + TraceError( WMBCLASS_OID, "[MBIM_ERR][ReqID=0x%04x][TID=0x%08x] Received %!MbbError! for non-existing request", + Request->RequestId, + TransactionId, + ErrorMessage->ErrorCode + ); + } + + CommandName = MbbUtilGetCommandString( &Command ); + + MbbWriteEvent( + &MBIM_FUNCTION_ERROR_EVENT, + OriginalRequest ? &(OriginalRequest->ActivityId) : NULL, + NULL, + 6, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &ErrorMessage->ErrorCode, + sizeof(MBB_ERROR), + &ErrorMessage->MessageHeader.MessageTransactionId, + sizeof(ULONG), + &Command.ServiceId, + sizeof(GUID), + &Command.CommandId, + sizeof(ULONG), + CommandName, + strlen(CommandName) + 1 + ); + } + while( FALSE ); + + return NDIS_STATUS_SUCCESS; +} + +VOID +MbbNdisParseResponseFragment( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + ULONG RequestId = Request->RequestId; + BOOLEAN DestroyRequest = TRUE; + PVOID MessageBuffer; + ULONG MessageLength; + PMBB_MESSAGE_HEADER MessageHeader; + + do + { + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] GetEncapsulatedResponse FAILED, NdisStatus=%!STATUS!", + RequestId, + NdisStatus + ); + break; + } + + MessageBuffer = Request->HandlerContext.Response.FragmentBuffer; + MessageLength = Request->HandlerContext.Response.FragmentLength; + MessageHeader = (PMBB_MESSAGE_HEADER)MessageBuffer; + + if( MessageLength < sizeof(MBB_MESSAGE_HEADER) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT MessageBuffer Expected=%d > Received=%d", + RequestId, + sizeof(MBB_MESSAGE_HEADER), + MessageLength + ); + break; + } + + switch( MessageHeader->MessageType ) + { + case MBB_MESSAGE_TYPE_COMMAND_DONE: + { + if( MessageLength >= sizeof(MBB_COMMAND_FRAGMENT_HEADER) ) + { + MbbNdisParseCommandResponse( MessageHeader->MessageTransactionId, Request ); + } + else + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x][TID=0x%08x] INSUFFICIENT MessageBuffer for %!MbbMsgType! Expected=%d > Received=%d", + RequestId, + MessageHeader->MessageTransactionId, + MessageHeader->MessageType, + sizeof(MBB_COMMAND_FRAGMENT_HEADER), + MessageLength + ); + } + } + break; + + case MBB_MESSAGE_TYPE_INDICATE_STATUS: + { + if( MessageLength >= sizeof(MBB_COMMAND_FRAGMENT_HEADER) ) + { + if( MbbNdisParseStatusIndication( MessageHeader->MessageTransactionId, Request ) == NDIS_STATUS_PENDING ) + { + DestroyRequest = FALSE; + } + } + else + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x][TID=0x%08x] INSUFFICIENT MessageBuffer for %!MbbMsgType! Expected=%d > Received=%d", + RequestId, + MessageHeader->MessageTransactionId, + MessageHeader->MessageType, + sizeof(MBB_COMMAND_FRAGMENT_HEADER), + MessageLength + ); + } + } + break; + + case MBB_MESSAGE_TYPE_FUNCTION_ERROR: + { + if( MessageLength >= sizeof(MBB_ERROR_MESSAGE) && MessageHeader->MessageTransactionId > 0) + { + if( MbbNdisParseFunctionError( MessageHeader->MessageTransactionId, Request ) == NDIS_STATUS_PENDING ) + { + DestroyRequest = FALSE; + } + } + else if(MessageLength < sizeof(MBB_ERROR_MESSAGE)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x][TID=0x%08x] INSUFFICIENT MessageBuffer for %!MbbMsgType! Expected=%d > Received=%d", + RequestId, + MessageHeader->MessageTransactionId, + MessageHeader->MessageType, + sizeof(MBB_ERROR_MESSAGE), + MessageLength + ); + break; + } + else + { + TraceWarn(WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x][TID=0x%08x] MessageTransactionId is 0 for %!MbbMsgType! and ErrorCode %!MbbError!", + RequestId, + MessageHeader->MessageTransactionId, + MessageHeader->MessageType, + ((PMBB_ERROR_MESSAGE)MessageHeader)->ErrorCode + ); + break; + } + } + break; + + case MBB_MESSAGE_TYPE_OPEN_DONE: __fallthrough; + case MBB_MESSAGE_TYPE_CLOSE_DONE: __fallthrough; + default: + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x][TID=0x%08x] UNEXPECTED MessageType=%!MbbMsgType!", + RequestId, + MessageHeader->MessageTransactionId, + MessageHeader->MessageType + ); + } + break; + } + } + while( FALSE ); + + if( DestroyRequest == TRUE ) + { + MbbReqMgrDestroyRequest( Request->RequestManager, Request ); + } +} + +VOID +MbbNdisProcessResponseFragementWorker( + __in PVOID Context1, + __in PVOID Context2, + __in PVOID Context3, + __in PVOID Context4 + ) +{ + PMBB_REQUEST_CONTEXT Request = (PMBB_REQUEST_CONTEXT)Context1; + PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; + + MbbReqMgrQueueEvent( + RequestManager, + Request, + MbbRequestEventSendComplete, + (PVOID)(Request->HandlerContext.Response.NdisStatus), + 0 + ); + MbbReqMgrDerefRequest( Request ); +} + +VOID +MbbNdisGetResponseFragementComplete( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in MBB_REQUEST_HANDLE RequestHandle, + __in NTSTATUS Status, + __in ULONG_PTR ReceivedLength + ) +{ + NDIS_STATUS NdisStatus; + PMBB_REQUEST_CONTEXT Request; + PMBB_REQUEST_MANAGER RequestManager; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; + + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[MbbNdis][ReqId=0x%04x] FAILED to reference RequestManager to process request fragment", (ULONG)RequestHandle ); + return; + } + if( (Request = MbbReqMgrGetRequestById( RequestManager, (ULONG)RequestHandle )) != NULL ) + { + Request->HandlerContext.Response.NdisStatus = Status; + Request->HandlerContext.Response.FragmentLength = (ULONG)ReceivedLength; + // + // Queue a work item so that the processing happens at PASSIVE_LEVEL. + // On the response receive path string routines are called which require PASSIVE_LEVEL. + // + if( (NdisStatus = MbbWorkMgrQueueWorkItem( + RequestManager->WorkItemManagerHandle, + Request, + NULL, + NULL, + NULL, + MbbNdisProcessResponseFragementWorker + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[MbbNdis][ReqId=0x%04x] FAILED to queue work item to process request", Request->RequestId ); + } + } + else + { + TraceError( WMBCLASS_REQUEST_MANAGER, "[MbbNdis] UNABLE to find request, dropping fragment. Handle=%p", RequestHandle ); + } + MbbReqMgrDeref( RequestManager ); +} + +NDIS_STATUS +MbbNdisGetResponseFragment( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + ULONG RequestId; + NTSTATUS NtStatus; + NDIS_STATUS NdisStatus; + + RequestId = Request->RequestId; + + NtStatus = MbbBusReceiveMessageFragment( + MbbNdisGetBusHandle( MbbReqMgrGetAdapterHandle( Request ) ), + (MBB_REQUEST_HANDLE)RequestId, + Request->HandlerContext.Response.FragmentBuffer, + Request->HandlerContext.Response.FragmentBufferLength, + &(Request->ActivityId), + MbbNdisGetResponseFragementComplete + ); + if( NtStatus == STATUS_PENDING ) + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Waiting to retrieve response fragment", RequestId ); + return NDIS_STATUS_PENDING; + } + else + { + ASSERT( NtStatus != STATUS_SUCCESS ); + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to retrieve response fragment with status=%!status!", RequestId, NtStatus ); + return NDIS_STATUS_FAILURE; + } +} + +VOID +MbbNdisResponseFragmentAvailable( + __in MBB_PROTOCOL_HANDLE ProtocolHandle + ) +{ + ULONG RequestId; + NDIS_STATUS NdisStatus; + NTSTATUS NtStatus; + PMBB_REQUEST_CONTEXT Request; + PMBB_REQUEST_MANAGER RequestManager = NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to reference RequestManager for GetResponse" ); + break; + } + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to allocate RequestContext for GetResponse" ); + break; + } + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Created request to retrieve response.", Request->RequestId ); + + Request->HandlerContext.Response.FragmentBuffer = Request->RequestManager->Fragmentation.Reassemble.FragmentBuffer; + Request->HandlerContext.Response.FragmentBufferLength = Request->RequestManager->Fragmentation.Reassemble.FragmentBufferLength; + + // Get an activity id to associate with this request + NtStatus = MbbEventActivityIdCtl(&(Request->ActivityId)); + + if(!NT_SUCCESS(NtStatus)) + { + // Clear out the activity Id of the request + NdisZeroMemory(&(Request->ActivityId),sizeof(GUID)); + TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Failed to create an activity Id for request to retrieve response.NtStatus = %d.", Request->RequestId, NtStatus ); + } + else + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Created an activity id %!GUID! for the request",Request->RequestId, &(Request->ActivityId)); + } + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, + MbbNdisGetResponseFragment, + MbbNdisParseResponseFragment, + MbbNdisIndicateStatus + ); + if( NdisStatus != NDIS_STATUS_PENDING ) + { + MbbReqMgrDestroyRequest( + RequestManager, + Request + ); + } + } + while( FALSE ); + + if( RequestManager != NULL ) + MbbReqMgrDeref( RequestManager ); +} + + +// +// Get Handlers +// + + +NDIS_STATUS +MbbNdisGetMediaSupported( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PULONG MediaSupported = (PULONG)OutBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + + *MediaSupported = NdisMediumWirelessWan; + *OutBufferSize = sizeof(ULONG); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetInterruptModeration( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PNDIS_INTERRUPT_MODERATION_PARAMETERS InterruptModeration = (PNDIS_INTERRUPT_MODERATION_PARAMETERS)OutBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS) ); + + InterruptModeration->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + InterruptModeration->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1; + InterruptModeration->Header.Size = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); + InterruptModeration->Flags = NDIS_INTERRUPT_MODERATION_CHANGE_NEEDS_RESET; + InterruptModeration->InterruptModeration= NdisInterruptModerationNotSupported; + + *OutBufferSize = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetVendorDriverVersion( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PULONG DriverVersion = (PULONG)OutBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + + *DriverVersion = (WWAN_MAJOR_VERSION << 16) | (WWAN_MINOR_VERSION & 0xffff); + *OutBufferSize = sizeof(ULONG); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetVendorId( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PULONG VendorId = (PULONG)OutBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + + // + // no mac address + // + *VendorId = 0xFFFFFF; + *OutBufferSize = sizeof(ULONG); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetVendorDescription( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; + NDIS_STATUS Status; + ULONG SourceLength=0; + + Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + // + // make sure the buffer is big enough to hold the string and a null since the counted string + // might not have null + // + SourceLength=(ULONG)Adapter->FriendlyName.Length + 1; + + if (*OutBufferSize >= SourceLength ) + { + RtlZeroMemory(OutBuffer, SourceLength); + RtlCopyMemory(OutBuffer, Adapter->FriendlyName.Buffer, Adapter->FriendlyName.Length); + + Status = NDIS_STATUS_SUCCESS; + } + else + { + Status = NDIS_STATUS_BUFFER_TOO_SHORT; + } + + *OutBufferSize = SourceLength; + + return Status; +} + +NDIS_STATUS +MbbNdisGetCurrentLookahead( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PULONG Lookahead = (PULONG)OutBuffer; + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + // + // Todo: Return a value. + // + *Lookahead = 0; + *OutBufferSize = sizeof(ULONG); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetReceiveBlockSize( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; + PULONG BlockSize=(PULONG)OutBuffer; + + Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + + if (Adapter->BusParams.IsErrataDevice) + { + *BlockSize=Adapter->BusParams.MTU; + } else { + *BlockSize=Adapter->BusParams.MaxSegmentSize; + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetReceiveBufferSpace( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; + PULONG BufferSpace=(PULONG)OutBuffer; + + Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + + *BufferSpace=Adapter->BusParams.MaxOutNtb; + + return NDIS_STATUS_SUCCESS; + +} + +NDIS_STATUS +MbbNdisGetTransmitBlockSize( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; + PULONG BlockSize=(PULONG)OutBuffer; + + Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + + if (Adapter->BusParams.IsErrataDevice) + { + *BlockSize=Adapter->BusParams.MTU; + } else { + *BlockSize=Adapter->BusParams.MaxSegmentSize; + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetTransmitBufferSpace( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; + PULONG BufferSpace=(PULONG)OutBuffer; + + Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + + *BufferSpace=Adapter->BusParams.MaxOutNtb; + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetMaximumTotalSize( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; + PULONG BlockSize=(PULONG)OutBuffer; + + Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); + + if (Adapter->BusParams.IsErrataDevice) + { + *BlockSize=Adapter->BusParams.MTU; + } else { + *BlockSize=Adapter->BusParams.MaxSegmentSize; + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetFramesReceived( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PULONGLONG ReceivedFrames = (PULONGLONG)(OutBuffer); + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONGLONG) ); + + *ReceivedFrames = Adapter->GenRcvFramesOk; + *OutBufferSize = sizeof(ULONGLONG); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetFramesTransmitted( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PULONGLONG TransmittedFrames = (PULONGLONG)(OutBuffer); + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(ULONGLONG) ); + + *TransmittedFrames = Adapter->GenXmitFramesOk; + *OutBufferSize = sizeof(ULONGLONG); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetDriverCaps( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); + + PNDIS_WWAN_DRIVER_CAPS DriverCaps = (PNDIS_WWAN_DRIVER_CAPS)OutBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(NDIS_WWAN_DRIVER_CAPS) ); + + DriverCaps->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + DriverCaps->Header.Revision = NDIS_WWAN_DRIVER_CAPS_REVISION_1 ; + DriverCaps->Header.Size = sizeof(NDIS_WWAN_DRIVER_CAPS); + DriverCaps->DriverCaps.ulMajorVersion = WWAN_MAJOR_VERSION; + DriverCaps->DriverCaps.ulMinorVersion = WWAN_MINOR_VERSION; + DriverCaps->DriverCaps.ulDriverCaps = WWAN_DRIVER_CAPS_NONE; + + if (MbbBusIsUde(Adapter->BusHandle)) + { + DriverCaps->DriverCaps.ulDriverCaps = WWAN_DRIVER_CAPS_UDE; + } + *OutBufferSize = sizeof(NDIS_WWAN_DRIVER_CAPS); + return NDIS_STATUS_SUCCESS; +} + + +NDIS_STATUS +MbbNdisGetConnectState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); + PMBB_CONTEXT_STATE MbbGetContextState = NULL; + PMBB_PORT Port = NULL; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferSize); + + if( (MbbGetContextState = (PMBB_CONTEXT_STATE) ALLOCATE_NONPAGED_POOL( sizeof(MBB_CONTEXT_STATE) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbGetContextState; + + Port = MbbWwanTranslatePortNumberToPort( + Adapter, + Request->OidContext.OidRequest->PortNumber); + + if(Port!= NULL) + { + ULONG MaxActivatedContexts = 0; + ULONG SessionId = MBB_INVALID_SESSION_ID; + + MbbAdapterPortsLock(Adapter); + MaxActivatedContexts = Adapter->MaxActivatedContexts; + MbbAdapterPortsUnlock(Adapter); + + RtlZeroMemory(MbbGetContextState, sizeof(MBB_CONTEXT_STATE)); + + SessionId = MbbWwanGetPortSessionId(Port); + + if(SessionId < MaxActivatedContexts) + { + MbbGetContextState->SessionId = SessionId; + + Status = MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR) MbbGetContextState, + sizeof(MBB_CONTEXT_STATE) + ); + } + else + { + // Fail this OID request because we cannot query the device with an invalid session ID. + // If we want to send a context deactivated indication instead of failure, we need to do it outside the + // context of this OID request because it may lead to deadlocks. Currently returning a failure here + // because it is equivalent and less complicated. Note that Wwansvc is not sending OID_WWAN_CONNECT + // query for disconnected additional PDP contexts. The only case when this OID request may come is for + // a disconnected Port 0 context, which is not an issue because we are setting session ID as 0 for Port 0 + // always and will never end up here. + + Status = NDIS_STATUS_FAILURE; + + ASSERT(IS_ALLOCATED_PORT_NUMBER(Request->OidContext.OidRequest->PortNumber)); + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbNdisGetConnectState failed for a Port: [%lu]. Requested sessionId: [%lu] Status=%!status!", + Request->RequestId, + Request->OidContext.OidRequest->PortNumber, + SessionId, + Status + ); + } + + // Remove the reference added during find + Dereference(Port); + } + else + { + Status = NDIS_STATUS_INVALID_PORT; + } + + return Status; +} + +NDIS_STATUS +MbbIpGetConfiguration( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMBB_IP_ADDRESS_INFO MbbGetIpAddressInfo = NULL; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferSize); + + if( (MbbGetIpAddressInfo = (PMBB_IP_ADDRESS_INFO) ALLOCATE_NONPAGED_POOL( sizeof(MBB_IP_ADDRESS_INFO) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbGetIpAddressInfo; + + RtlZeroMemory(MbbGetIpAddressInfo, sizeof(MBB_IP_ADDRESS_INFO)); + + MbbGetIpAddressInfo->SessionId = Request->HandlerContext.Parameters.IpAddress.SessionId; + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR) MbbGetIpAddressInfo, + sizeof(MBB_IP_ADDRESS_INFO) + ); +} + +NDIS_STATUS +MbbNdisGetVisibleProviders( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PNDIS_WWAN_GET_VISIBLE_PROVIDERS NdisGetVisibleProviders = (PNDIS_WWAN_GET_VISIBLE_PROVIDERS)InBuffer; + PMBB_GET_VISIBLE_PROVIDERS MbbGetVisible; + NDIS_STATUS NdisStatus; + + if( (MbbGetVisible = (PMBB_GET_VISIBLE_PROVIDERS) ALLOCATE_NONPAGED_POOL( sizeof(MBB_GET_VISIBLE_PROVIDERS) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbGetVisible; + + NdisStatus = MbbUtilWwanToMbbGetVisible( + &NdisGetVisibleProviders->VisibleProviders, + MbbGetVisible + ); + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to convert GET_VISIBLE_PROVIDER with status=%!status!", + Request->RequestId, + NdisStatus + ); + return NdisStatus; + } + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR) MbbGetVisible, + sizeof(MBB_GET_VISIBLE_PROVIDERS) + ); +} + + +NDIS_STATUS +MbbNdisSmsRead( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PNDIS_WWAN_SMS_READ NdisSmsRead = (PNDIS_WWAN_SMS_READ)InBuffer; + PMBB_SMS_READ MbbSmsRead; + + if( (MbbSmsRead = (PMBB_SMS_READ) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SMS_READ) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSmsRead; + + MbbUtilWwanToMbbSmsRead( + &NdisSmsRead->SmsRead, + MbbSmsRead + ); + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR) MbbSmsRead, + sizeof(MBB_SMS_READ) + ); +} + + +NDIS_STATUS +MbbNdisEnumerateDeviceServices( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG DeviceElementCount = 0; + ULONG NdisDeviceServicesInfoSize; + PNDIS_WWAN_SUPPORTED_DEVICE_SERVICES NdisDeviceServicesInfo = NULL; + PWWAN_DEVICE_SERVICE_ENTRY NdisDeviceServiceEntry = NULL; + ULONG devIndex = 0; + ULONG oidIndex = 0; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + NDIS_STATUS_INDICATION StatusIndication; + + // Return the device services list from the cached state + do + { + // + // For OID queries, get the device service list from the cache + // + Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )); + + // We start with allocating memory for all entries. We would only report the non-native list to the OS + DeviceElementCount = Adapter->DeviceServiceState.ServicesCount; + NdisDeviceServicesInfoSize = sizeof(NDIS_WWAN_SUPPORTED_DEVICE_SERVICES) + ( DeviceElementCount * sizeof(WWAN_DEVICE_SERVICE_ENTRY) ); + + if( (NdisDeviceServicesInfo = ALLOCATE_NONPAGED_POOL(NdisDeviceServicesInfoSize)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES, Source Service Count=%d", + Request->RequestId, + NdisDeviceServicesInfoSize, + DeviceElementCount + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + // Start populating the indication + NdisDeviceServicesInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceServicesInfo->Header.Size = SIZEOF_NDIS_WWAN_SUPPORTED_DEVICE_SERVICES_1; + NdisDeviceServicesInfo->Header.Revision = NDIS_WWAN_SUPPORTED_DEVICE_SERVICES_REVISION_1; + + // Always reporting success + NdisDeviceServicesInfo->uStatus = WWAN_STATUS_SUCCESS; + + NdisDeviceServicesInfo->DeviceServices.uMaxCommandDataSize = Adapter->BusParams.FragmentSize; + NdisDeviceServicesInfo->DeviceServices.uMaxSessionDataSize = MBB_FRAGMENATION_BULK_BUFFER_LENGTH; + NdisDeviceServicesInfo->DeviceServices.uMaxSessionCount = Adapter->DeviceServiceState.MaxDSSSessions; + + NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementType = WwanStructDeviceServiceEntry; + NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementCount = 0; + + // Populate the device service entries + NdisDeviceServiceEntry = (PWWAN_DEVICE_SERVICE_ENTRY)(((PUCHAR)NdisDeviceServicesInfo) + + sizeof(NDIS_WWAN_SUPPORTED_DEVICE_SERVICES)); + for (devIndex = 0; devIndex < DeviceElementCount; devIndex++) + { + if (!MbbUtilIsNativeMbnService(&(NdisDeviceServiceEntry[devIndex].DeviceServiceGuid))) + { + // Cache is already in host format + RtlCopyMemory(&(NdisDeviceServiceEntry[oidIndex].DeviceServiceGuid), + &(Adapter->DeviceServiceState.ServicesList[devIndex].DeviceServiceId), + sizeof(GUID) + ); + + NdisDeviceServiceEntry[oidIndex].SessionCapability = + Adapter->DeviceServiceState.ServicesList[devIndex].DSSCapability; + NdisDeviceServiceEntry[oidIndex].uMaxSessionInstances = + Adapter->DeviceServiceState.ServicesList[devIndex].MaxDSSInstances; + + NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementCount++; + oidIndex++; + } + } + + // + // Indicate ndis status + // + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES + ); + + StatusIndication.StatusBuffer = NdisDeviceServicesInfo; + // Use the actual size for + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SUPPORTED_DEVICE_SERVICES) + + ( NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementCount * sizeof(WWAN_DEVICE_SERVICE_ENTRY) ); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES with %d entries", + Request->RequestId, + NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementCount + ); + + // + // a special status that the oid completion handler will fix-up and complete the request instead of waiting + // a response from the device that is not coming. + // + NdisStatus=MBB_STATUS_INDICATION_ALREADY_SENT ; + + NdisMIndicateStatusEx( + ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ))->MiniportAdapterHandle, + &StatusIndication + ); + + } + while( FALSE ); + + // + // Local Cleanup + // + if( NdisDeviceServicesInfo != NULL ) + { + FREE_POOL( NdisDeviceServicesInfo ); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisGetDeviceServiceCommand( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + return MbbUtilDeviceServiceCommand( + Request, + InBuffer, + InBufferSize + ); +} + + +NDIS_STATUS +MbbNdisEnumerateDeviceServiceCommands( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + // The input data comes in as OutBuffer + PNDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS pRequestBuffer = (PNDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS )OutBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + NDIS_STATUS_INDICATION StatusIndication; + PMBB_DS deviceServiceEntry = NULL; + ULONG NdisCommandsInfoSize; + PNDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS NdisCommandsInfo = NULL; + + do + { + // + // For CID list queries, use the info from the cache + // + Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )); + + // Find the device service for this GUID + deviceServiceEntry = MbbUtilFindDeviceService(Adapter, + &pRequestBuffer->DeviceServiceGuid + ); + if (deviceServiceEntry == NULL) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Enumerate COMMANDs request for invalid device service ID", + Request->RequestId + ); + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + // Allocate the buffer for the indication + NdisCommandsInfoSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS) + + + ( deviceServiceEntry->CIDCount * sizeof(ULONG) ); + + if( (NdisCommandsInfo = ALLOCATE_NONPAGED_POOL(NdisCommandsInfoSize)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS, Source Service Count=%d", + Request->RequestId, + NdisCommandsInfoSize, + deviceServiceEntry->CIDCount + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + // Start populating the indication + NdisCommandsInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisCommandsInfo->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS_1; + NdisCommandsInfo->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS_REVISION_1; + + // Always reporting success + NdisCommandsInfo->uStatus = WWAN_STATUS_SUCCESS; + + RtlCopyMemory(&NdisCommandsInfo->SupportedCommands.DeviceServiceGuid, + &pRequestBuffer->DeviceServiceGuid, + sizeof(GUID) + ); + + NdisCommandsInfo->SupportedCommands.ListHeader.ElementCount = deviceServiceEntry->CIDCount; + NdisCommandsInfo->SupportedCommands.ListHeader.ElementType = WwanStructDeviceServiceCommandId; + + // Populate the command list + RtlCopyMemory(((PUCHAR)NdisCommandsInfo) + sizeof(NDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS), + deviceServiceEntry->CIDList, + deviceServiceEntry->CIDCount * sizeof(ULONG) + ); + + // + // Indicate ndis status + // + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS + ); + + StatusIndication.StatusBuffer = NdisCommandsInfo; + StatusIndication.StatusBufferSize = NdisCommandsInfoSize; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS with %d entries", + Request->RequestId, + NdisCommandsInfo->SupportedCommands.ListHeader.ElementCount + ); + + // + // a special status that the oid completion handler will fix-up and complete the request instead of waiting + // a response from the device that is not coming. + // + NdisStatus=MBB_STATUS_INDICATION_ALREADY_SENT ; + + NdisMIndicateStatusEx( + ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ))->MiniportAdapterHandle, + &StatusIndication + ); + + } + while( FALSE ); + + // + // Local Cleanup + // + if( NdisCommandsInfo != NULL ) + { + FREE_POOL( NdisCommandsInfo ); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisGetMultiCarrierDsCidList( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +/*++ + HACK - The input parameter is passed in the Request instead of the above parameters. + The hack is necessary since there is no good way to pass parameters to handlers from + an internal request. +--*/ +{ + MBB_COMMAND Command; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferSize); + UNREFERENCED_PARAMETER(OutBuffer); + UNREFERENCED_PARAMETER(OutBufferSize); + + do + { + Command = Request->OidHandler->ResponseCommand; + + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Command, + MBB_COMMAND_TYPE_QUERY, + (PUCHAR)&Request->HandlerContext.Parameters.DeviceCaps.CurrentQueriedDeviceService, + sizeof(UUID) + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to setup command message for MbbNdisGetMultiCarrierDsCidList with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to send message fragments for MbbNdisGetMultiCarrierDsCidList with status=%!status!", + Request->RequestId, NdisStatus ); + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisGetUiccFileStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PNDIS_WWAN_UICC_FILE_PATH NdisUiccFilePath = (PNDIS_WWAN_UICC_FILE_PATH)InBuffer; + PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; + NDIS_STATUS NdisStatus; + ULONG BufferSize = 0; + + NdisStatus = MbbUtilWwanToMbbUiccFilePath( + &NdisUiccFilePath->UiccFilePath, + &MbbUiccFilePath, + &BufferSize + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbUiccFilePath; + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR) MbbUiccFilePath, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisUiccReadBinary( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + return MbbUtilUiccAccessBinary( + Request, + InBuffer, + InBufferSize + ); +} + +NDIS_STATUS +MbbNdisUiccReadRecord( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + return MbbUtilUiccAccessRecord( + Request, + InBuffer, + InBufferSize + ); +} + +NDIS_STATUS +MbbNdisGetPinInfoEx( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + PNDIS_WWAN_PIN_APP NdisPinApp = (PNDIS_WWAN_PIN_APP)InBuffer; + PMBB_PIN_APP MbbPinApp = NULL; + NDIS_STATUS NdisStatus; + ULONG BufferSize = 0; + + NdisStatus = MbbUtilWwanToMbbPinApp( + &NdisPinApp->PinApp, + &MbbPinApp, + &BufferSize + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbPinApp; + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR)MbbPinApp, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisGetMbimVersion( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + + PNDIS_WWAN_MBIM_VERSION MbbMbimVersion = (PNDIS_WWAN_MBIM_VERSION)OutBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *OutBufferSize >= sizeof(NDIS_WWAN_MBIM_VERSION) ); + + MbbMbimVersion->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + MbbMbimVersion->Header.Revision = NDIS_WWAN_MBIM_VERSION_REVISION_1 ; + MbbMbimVersion->Header.Size = SIZEOF_NDIS_WWAN_MBIM_VERSION_1; + + Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request)); + + MbbMbimVersion->MbimVersion.MbimVersion = Adapter->BusParams.MbimVersion; + + *OutBufferSize = sizeof(NDIS_WWAN_MBIM_VERSION); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetSlotInfoStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + PNDIS_WWAN_GET_SLOT_INFO NdisGetSlotInfo = (PNDIS_WWAN_GET_SLOT_INFO)InBuffer; + PMBB_MS_SLOT_INFO_REQ MbbSlotInfoReq = NULL; + + MbbSlotInfoReq = (PMBB_MS_SLOT_INFO_REQ)(ALLOCATE_NONPAGED_POOL(sizeof(MBB_MS_SLOT_INFO_REQ))); + if (NULL == MbbSlotInfoReq) + { + return NDIS_STATUS_RESOURCES; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSlotInfoReq; + + RtlZeroMemory(MbbSlotInfoReq, sizeof(MBB_MS_SLOT_INFO_REQ)); + + MbbSlotInfoReq->SlotIndex = NdisGetSlotInfo->GetSlotInfo.SlotIndex; + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR)MbbSlotInfoReq, + sizeof(MBB_MS_SLOT_INFO_REQ) + ); +} + +NDIS_STATUS +MbbNdisGetAtr( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterLock(Adapter); + BOOL IsUiccLowLevelCapable = Adapter->AdapterFlags.IsUiccLowLevelCapable; + MbbAdapterUnlock(Adapter); + + if (!IsUiccLowLevelCapable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support UICC low level operations (GET_ATR)"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + return MbbUtilQueryAttributeWithParameter( + Request, + NULL, + 0 + ); +} + +NDIS_STATUS +MbbNdisGetUiccReset( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize, + _Out_writes_bytes_to_opt_(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + _Inout_ PULONG OutBufferSize +) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterLock(Adapter); + BOOL IsUiccLowLevelCapable = Adapter->AdapterFlags.IsUiccLowLevelCapable; + MbbAdapterUnlock(Adapter); + + if (!IsUiccLowLevelCapable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support UICC low level operations (GET_UICC_RESET)"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + return MbbUtilQueryAttributeWithParameter( + Request, + NULL, + 0 + ); +} + +NDIS_STATUS +MbbNdisGetProvisionedContextsV2( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterLock(Adapter); + BOOL IsProvisionedContextV2Capable = Adapter->AdapterFlags.IsProvisionedContextV2Capable; + MbbAdapterUnlock(Adapter); + + if (!IsProvisionedContextV2Capable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support ProvisionedContextsV2"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + return MbbUtilQueryAttributeWithParameter( + Request, + NULL, + 0 + ); +} + +NDIS_STATUS +MbbNdisGetPcoStatus( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferSize); + + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + PMBB_PORT Port = NULL; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + MBB_MS_PCO_VALUE MbbPcoValue = { 0 }; + + MbbAdapterLock(Adapter); + BOOL IsPcoCapable = Adapter->AdapterFlags.IsPcoCapable; + MbbAdapterUnlock(Adapter); + + if (!IsPcoCapable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support PCO"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + Port = MbbWwanTranslatePortNumberToPort( + Adapter, + Request->OidContext.OidRequest->PortNumber); + + if (Port != NULL) + { + ULONG MaxActivatedContexts = 0; + ULONG SessionId = MBB_INVALID_SESSION_ID; + + MbbAdapterPortsLock(Adapter); + MaxActivatedContexts = Adapter->MaxActivatedContexts; + MbbAdapterPortsUnlock(Adapter); + + SessionId = MbbWwanGetPortSessionId(Port); + + if (SessionId < MaxActivatedContexts) + { + MbbPcoValue.SessionId = SessionId; + + Status = MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR)&MbbPcoValue, + sizeof(MBB_MS_PCO_VALUE) + ); + } + else + { + // Fail this OID request because we cannot query the device with an invalid session ID. + + Status = NDIS_STATUS_FAILURE; + + ASSERT(IS_ALLOCATED_PORT_NUMBER(Request->OidContext.OidRequest->PortNumber)); + + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbNdisGetPcoStatus failed for a Port: [%lu]. Requested sessionId: [%lu] Status=%!status!", + Request->RequestId, + Request->OidContext.OidRequest->PortNumber, + SessionId, + Status + ); + } + + // Remove the reference added during find + Dereference(Port); + } + else + { + Status = NDIS_STATUS_INVALID_PORT; + } + + return Status; +} + +NDIS_STATUS +MbbNdisGetSysCapsInfo( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterLock(Adapter); + BOOL IsMultiSIMCapable = Adapter->AdapterFlags.IsMultiSIMCapable; + MbbAdapterUnlock(Adapter); + + if (!IsMultiSIMCapable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support system caps"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + return MbbUtilQueryAttributeWithParameter( + Request, + NULL, + 0 + ); +} + +NDIS_STATUS +MbbNdisGetDeviceCapsEx( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterLock(Adapter); + BOOL IsDeviceCapsV2Capable = Adapter->AdapterFlags.IsDeviceCapsV2Capable; + MbbAdapterUnlock(Adapter); + + if (!IsDeviceCapsV2Capable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support system caps, so assume it doesn't support device caps extention either"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + return MbbUtilQueryAttributeWithParameter( + Request, + NULL, + 0 + ); +} + +NDIS_STATUS +MbbNdisGetBaseStationsInfo( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize +) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterLock(Adapter); + BOOL IsBaseStationsInfoCapable = Adapter->AdapterFlags.IsBaseStationsInfoCapable; + MbbAdapterUnlock(Adapter); + + if (!IsBaseStationsInfoCapable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support base station information"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + PNDIS_WWAN_BASE_STATIONS_INFO_REQ NdisGetBaseStationsInfoRequest = (PNDIS_WWAN_BASE_STATIONS_INFO_REQ)InBuffer; + PWWAN_BASE_STATIONS_INFO_REQ WwanBaseStationsInfoRequest = &(NdisGetBaseStationsInfoRequest->BaseStationsInfoRequest); + PMBB_MS_BASE_STATIONS_INFO_REQ MbbBaseStationsInfoReq = NULL; + + MbbBaseStationsInfoReq = (PMBB_MS_BASE_STATIONS_INFO_REQ)(ALLOCATE_NONPAGED_POOL(sizeof(MBB_MS_BASE_STATIONS_INFO_REQ))); + + Request->HandlerContext.DataToFreeOnCompletion = MbbBaseStationsInfoReq; + + RtlZeroMemory(MbbBaseStationsInfoReq, sizeof(MBB_MS_BASE_STATIONS_INFO_REQ)); + + MbbBaseStationsInfoReq->MaxGSMCount = WwanBaseStationsInfoRequest->MaxGSMCount; + MbbBaseStationsInfoReq->MaxUMTSCount = WwanBaseStationsInfoRequest->MaxUMTSCount; + MbbBaseStationsInfoReq->MaxTDSCDMACount = WwanBaseStationsInfoRequest->MaxTDSCDMACount; + MbbBaseStationsInfoReq->MaxLTECount = WwanBaseStationsInfoRequest->MaxLTECount; + MbbBaseStationsInfoReq->MaxCDMACount = WwanBaseStationsInfoRequest->MaxCDMACount; + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR)MbbBaseStationsInfoReq, + sizeof(MBB_MS_BASE_STATIONS_INFO_REQ) + ); +} + +// +// Set Handlers +// + + +NDIS_STATUS +MbbNdisSetCurrentLookahead( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(ULONG) ); + // + // Todo: Record this value. + // + *InBufferSize = sizeof(ULONG); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSetInterruptModeration( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS) ); + + *InBufferSize = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSetRadioState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + MBB_RADIO_STATE* MbbRadioState; + PNDIS_WWAN_SET_RADIO_STATE NdisRadioState = (PNDIS_WWAN_SET_RADIO_STATE)InBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_RADIO_STATE) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_RADIO_STATE); + + if( (MbbRadioState = (MBB_RADIO_STATE*) ALLOCATE_NONPAGED_POOL( sizeof(MBB_RADIO_STATE) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbRadioState; + + // Save the setting so that when the request completes we know what + // action was performed + Request->HandlerContext.Parameters.RadioState.SetAction = NdisRadioState->RadioAction; + + MbbUtilWwanToMbbRadioState( + &NdisRadioState->RadioAction, + MbbRadioState + ); + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbRadioState, + sizeof(MBB_RADIO_STATE) + ); +} + +NDIS_STATUS +MbbNdisSetPinInfo( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMBB_PIN_ACTION MbbPinAction=NULL; + PNDIS_WWAN_SET_PIN NdisSetPin = (PNDIS_WWAN_SET_PIN)InBuffer; + NTSTATUS Status; + ULONG BufferSize=0; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PIN) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_PIN); + + + + Status=MbbUtilWwanToMbbPinAction( + &NdisSetPin->PinAction, + &MbbPinAction, + &BufferSize + ); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbPinAction; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbPinAction, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetPinInfoEx2( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMBB_PIN_ACTION_EX2 MbbPinAction=NULL; + PNDIS_WWAN_SET_PIN_EX2 NdisSetPin = (PNDIS_WWAN_SET_PIN_EX2)InBuffer; + NTSTATUS Status; + ULONG BufferSize=0; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PIN_EX2) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_PIN_EX2); + + + + Status=MbbUtilWwanToMbbPinActionEx2( + &NdisSetPin->PinAction, + &MbbPinAction, + &BufferSize + ); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbPinAction; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbPinAction, + BufferSize + ); +} + + +NDIS_STATUS +MbbNdisSetPreferredProviders( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + ULONG ElementIndex; + ULONG ElementCount; + ULONG ValidDataSize; + ULONGLONG MbbPreferredProvidersSize; + ULONGLONG NdisSetPreferredProvidersSize; + PWWAN_PROVIDER2 WwanProvider; + NDIS_STATUS NdisStatus; + PMBB_PROVIDER_LIST MbbPreferredProviders = NULL; + MBB_CELLULAR_CLASS MbbCellularClass; + PNDIS_WWAN_SET_PREFERRED_PROVIDERS NdisSetPreferredProviders = (PNDIS_WWAN_SET_PREFERRED_PROVIDERS)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); + BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PREFERRED_PROVIDERS) ); + do + { + // + // Verify input buffer + // + if( NdisSetPreferredProviders->PreferredListHeader.ElementType != WwanStructProvider2 ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] INVALID WWAN_LIST Expecting=%d Received=%d", + Request->RequestId, + WwanStructProvider2, + NdisSetPreferredProviders->PreferredListHeader.ElementType + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + ElementCount = NdisSetPreferredProviders->PreferredListHeader.ElementCount; + + NdisSetPreferredProvidersSize = sizeof(NDIS_WWAN_SET_PREFERRED_PROVIDERS) ; + + NdisSetPreferredProvidersSize += ((ULONGLONG)ElementCount) * sizeof(WWAN_PROVIDER2); + + if( *InBufferSize < NdisSetPreferredProvidersSize ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] INSUFFICIENT buffer size for NDIS_WWAN_SET_PREFERRED_PROVIDERS, Expecting=%d Received=%d, ProviderCount=%d", + Request->RequestId, + (ULONG)NdisSetPreferredProvidersSize, + *InBufferSize, + ElementCount + ); + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + // + // Query for the required size + // + WwanProvider = (PWWAN_PROVIDER2)(((PCHAR)NdisSetPreferredProviders) + RTL_SIZEOF_THROUGH_FIELD( NDIS_WWAN_SET_PREFERRED_PROVIDERS, PreferredListHeader )); + + MbbPreferredProvidersSize = FIELD_OFFSET(MBB_PROVIDER_LIST, Providers); + MbbPreferredProvidersSize += (ULONGLONG)ElementCount * sizeof(MBB_ARRAY_ELEMENT); + + for( ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex ++ ) + { + SIZE_T StringCbLength; + + MbbPreferredProvidersSize = ROUND_UP_COUNT( MbbPreferredProvidersSize, ALIGN_DWORD ); + MbbPreferredProvidersSize += sizeof(MBB_PROVIDER); + + if( (NdisStatus = RtlStringCbLengthW( + WwanProvider->Provider.ProviderId, + sizeof(WwanProvider->Provider.ProviderId), + &StringCbLength + )) != STATUS_SUCCESS ) + { + StringCbLength = sizeof(WwanProvider->Provider.ProviderId); + } + MbbPreferredProvidersSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); + + if( (NdisStatus = RtlStringCbLengthW( + WwanProvider->Provider.ProviderName, + sizeof(WwanProvider->Provider.ProviderName), + &StringCbLength + )) != STATUS_SUCCESS ) + { + StringCbLength = sizeof(WwanProvider->Provider.ProviderName); + } + MbbPreferredProvidersSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); + WwanProvider++; + } + // + // Allocate & setup Mbb buffer + // + if( MbbPreferredProvidersSize > ULONG_MAX || + (MbbPreferredProviders = ALLOCATE_NONPAGED_POOL( (ULONG)MbbPreferredProvidersSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate MBB_PROVIDER_LIST of Size=%d for ProviderCount=%d", + Request->RequestId, + (ULONG)MbbPreferredProvidersSize, + ElementCount + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbPreferredProviders; + // + // Convert from WWAN to MBB + // + if( IsMultiCarrierCapable == TRUE ) + MbbCellularClass = MbbCellularClassInvalid; + else + MbbCellularClass = MbbAdapterGetSupportedCellularClass( Adapter ); + + ValidDataSize = (ULONG)MbbPreferredProvidersSize; + + if( (NdisStatus = MbbUtilWwanToMbbProviderList( + &NdisSetPreferredProviders->PreferredListHeader, + IsMultiCarrierCapable, + MbbCellularClass, + MbbPreferredProviders, + &ValidDataSize + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to convert WWAN_PROVIDER_LIST to MBB_PROVIDER_LIST ", Request->RequestId ); + break; + } + // + // Send the data + // + NdisStatus = MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbPreferredProviders, + ValidDataSize + ); + if( NdisStatus == NDIS_STATUS_SUCCESS || + NdisStatus == NDIS_STATUS_PENDING ) + { + *InBufferSize = (ULONG)NdisSetPreferredProvidersSize; + } + } + while( FALSE ); + + return NdisStatus; +} + + +NDIS_STATUS +MbbNdisSetRegisterState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMBB_SET_REGISTER_STATE MbbSetRegisterState; + PNDIS_WWAN_SET_REGISTER_STATE NdisSetRegisterState = (PNDIS_WWAN_SET_REGISTER_STATE)InBuffer; + ULONG BufferSize=0; + NDIS_STATUS Status; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_REGISTER_STATE) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_REGISTER_STATE); + + + Status=MbbUtilWwanToMbbSetRegisterState( + &NdisSetRegisterState->SetRegisterState, + &MbbSetRegisterState, + &BufferSize + ); + + if (!NT_SUCCESS(Status)) + { + + return Status; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetRegisterState; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSetRegisterState, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetPacketService( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS NdisStatus; + PMBB_SET_PACKET_SERVICE MbbSetPacketService; + PNDIS_WWAN_SET_PACKET_SERVICE NdisSetPacketService = (PNDIS_WWAN_SET_PACKET_SERVICE)InBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PACKET_SERVICE) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_PACKET_SERVICE); + + if( (MbbSetPacketService = (PMBB_SET_PACKET_SERVICE) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SET_PACKET_SERVICE) )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate MBB_SET_PACKET_SERVICE", Request->RequestId ); + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSetPacketService; + + NdisStatus = MbbUtilWwanToMbbSetPacketService( + NdisSetPacketService->PacketServiceAction, + MbbSetPacketService + ); + if( NT_ERROR( NdisStatus ) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to convert WWAN_PACKET_SERVICE_ACTION, NdisStatus=%!STATUS!", Request->RequestId, NdisStatus ); + return NdisStatus; + } + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSetPacketService, + sizeof(MBB_SET_PACKET_SERVICE) + ); +} + +NDIS_STATUS +MbbNdisSetSignalState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMBB_SET_SIGNAL_INDICATION MbbSetSignalStateIndication; + PNDIS_WWAN_SET_SIGNAL_INDICATION NdisSetSignalStateIndication = (PNDIS_WWAN_SET_SIGNAL_INDICATION)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION); + + if( (MbbSetSignalStateIndication = (PMBB_SET_SIGNAL_INDICATION) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SET_SIGNAL_INDICATION) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSetSignalStateIndication; + + // + // Adjust signal state configuration if needed + // + Adapter = MbbReqMgrGetAdapterHandle( Request ); + + MbbUtilAdjustSignalStateConfigurationForDevice( + Adapter, + &NdisSetSignalStateIndication->SignalIndication + ); + + // + // Map to MBB values + // + MbbUtilWwanToMbbSetSignalStateIndication( + &NdisSetSignalStateIndication->SignalIndication, + MbbSetSignalStateIndication + ); + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSetSignalStateIndication, + sizeof(MBB_SET_SIGNAL_INDICATION) + ); +} + +NDIS_STATUS +MbbNdisSetConnectState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS NdisStatus; + PNDIS_WWAN_SET_CONTEXT_STATE NdisSetContextState = (PNDIS_WWAN_SET_CONTEXT_STATE)InBuffer; + PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); + NDIS_PORT_NUMBER PortNumber = OidRequest->PortNumber; + PMBB_PORT Port = NULL; + ULONG SessionId; + BOOLEAN PortSessionIdSet = FALSE; + + // Find the port corresponding to the port number + Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); + + if(!Port) + { + return NDIS_STATUS_INVALID_PORT; + } + + do + { + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_CONTEXT_STATE) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_CONTEXT_STATE); + // + // Cache values for later use + // + Adapter = MbbReqMgrGetAdapterHandle( Request ); + + if( NdisSetContextState->SetContextState.ActivationCommand == WwanActivationCommandActivate ) + { + // Set a session ID + NdisStatus = MbbWwanSetPortSessionId(Port); + + if(NdisStatus != NDIS_STATUS_SUCCESS) + { + PortSessionIdSet = FALSE; + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to obtain a session id for the connection", Request->RequestId); + break; + } + else + { + PortSessionIdSet = TRUE; + } + + Request->HandlerContext.Parameters.Connect.Activate = TRUE; + // + // Henceforth any context_state indication \ reponse coming from the device + // will be reported using this ConnectionId. The ConnectionId is valid till + // the time the context is not de-activated or the activation fails. + // + MbbWwanSetPortConnectionId( + Port, + NdisSetContextState->SetContextState.ConnectionId + ); + + } + else + if( NdisSetContextState->SetContextState.ActivationCommand == WwanActivationCommandDeactivate ) + { + ULONG ConnectionId = MbbWwanGetPortConnectionId(Port); + + // + // If the ConnectionId isnt activated then fail the request. + // + if( ConnectionId != NdisSetContextState->SetContextState.ConnectionId ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to de-activate invalid ConnectionId[Received=%d, Expected=%d]", + Request->RequestId, + NdisSetContextState->SetContextState.ConnectionId, + ConnectionId + ); + NdisStatus = WWAN_STATUS_CONTEXT_NOT_ACTIVATED; + break; + } + + // always assume that the session id is set for a valid deactivate context request + PortSessionIdSet = TRUE; + } + else + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] bad Command = %d", + Request->RequestId, + NdisSetContextState->SetContextState.ActivationCommand + ); + + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + SessionId = MbbWwanGetPortSessionId(Port); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] Processing set context request = %d for port number = %d with session id = %d", + Request->RequestId, + NdisSetContextState->SetContextState.ActivationCommand, + PortNumber, + SessionId + ); + + Request->HandlerContext.Parameters.Connect.SessionId = SessionId; + + NdisStatus = MbbUtilProcessSetConnectState(Request, &(NdisSetContextState->SetContextState), SessionId); + + if(NdisStatus != NDIS_STATUS_SUCCESS + && NdisStatus != NDIS_STATUS_PENDING) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbProcessSetConnectState failed with status=%!STATUS!",Request->RequestId, NdisStatus); + break; + } + } + while( FALSE ); + // + // If the ACTIVATION request was not successful then wipe out the connectionid. + // + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING && + NdisSetContextState->SetContextState.ActivationCommand == WwanActivationCommandActivate ) + { + MbbWwanSetPortConnectionId( + Port, + 0 + ); + + // Return the session id to the pool only when it was actually set for the port + MbbWwanResetPortSessionId( + Port, + PortSessionIdSet + ); + } + + //Remove the reference added during find + Dereference(Port); + + return NdisStatus; +} + + +NDIS_STATUS +MbbNdisGetStatistics( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + + PNDIS_STATISTICS_INFO Stats=(PNDIS_STATISTICS_INFO)OutBuffer; + + __analysis_assume( *OutBufferSize >= sizeof(NDIS_STATISTICS_INFO) ); + + *OutBufferSize = sizeof(*Stats); + + RtlCopyMemory(Stats, &Adapter->Stats, sizeof(*Stats)); + + Stats->Header.Type=NDIS_OBJECT_TYPE_DEFAULT; + Stats->Header.Revision=NDIS_STATISTICS_INFO_REVISION_1; + Stats->Header.Size=NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; + + Stats->SupportedStatistics = NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV | + NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | + NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV; + + + return STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisCreateMac( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; + PNDIS_OID_REQUEST oidRequest = Request->OidContext.OidRequest; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferSize); + + OutBuffer = oidRequest->DATA.METHOD_INFORMATION.InformationBuffer; + + do + { + oidRequest->DATA.METHOD_INFORMATION.BytesWritten = 0; + oidRequest->DATA.METHOD_INFORMATION.BytesRead = 0; + oidRequest->DATA.METHOD_INFORMATION.BytesNeeded = 0; + + if (oidRequest->RequestType != NdisRequestMethod) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] Invalid request type %d for OID_WWAN_CREATE_MAC\n", + Request->RequestId, + oidRequest->RequestType + ); + ndisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + ASSERT(oidRequest->DATA.METHOD_INFORMATION.OutputBufferLength >= sizeof(NDIS_WWAN_MAC_INFO)); + + // + // Since OID calls are serialized, we do not expect the NumberOfPorts to change + // while we are checking the following until this OID is completed. So we do not need + // to protect the NumberOfPorts in any way + // + if (Adapter->NumberOfPorts >= Adapter->MaxActivatedContexts) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] Number of existing ports exceed max supported. Failing new port creation\n", + Request->RequestId); + ndisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + ndisStatus = MbbUtilWwanCreateMac(Request); + + if (ndisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbUtilWwanCreateMac failed. Status = 0x%08x\n", + Request->RequestId,ndisStatus); + break; + } + } while (FALSE); + + + *OutBufferSize = oidRequest->DATA.METHOD_INFORMATION.BytesWritten; + + return ndisStatus; +} + + + +NDIS_STATUS +MbbNdisSetPower( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) + +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + NDIS_STATUS Status; + PSTATE_CHANGE_EVENT StateChange=NULL; + + PULONG PowerState=(PULONG)InBuffer; + + TraceInfo( WMBCLASS_POWER, "SetPower D%d", *PowerState - NetDeviceStateD0); + + *InBufferSize=sizeof(*PowerState); + + + StateChange=AllocateStateChangeEvent(&Adapter->AdapterState); + + if (StateChange != NULL) + { + StateChange->EventType=STATE_CHANGE_TYPE_POWER; + StateChange->Context1=Adapter; + StateChange->Power.Request=Request; + StateChange->Power.NewPower=*PowerState; + + QueueStateChangeEvent(&Adapter->AdapterState,StateChange); + + return STATUS_PENDING; + + } + + return STATUS_INSUFFICIENT_RESOURCES; + +} + +NDIS_STATUS +MbbNdisSetHomeProvider( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + ULONG ValidDataSize; + ULONGLONG MbbHomeProviderSize; + ULONG NdisSetHomeProvidersSize; + NDIS_STATUS NdisStatus; + PMBB_PROVIDER MbbHomeProvider = NULL; + WWAN_PROVIDER2 HomeProvider; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); + BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); + PNDIS_WWAN_SET_HOME_PROVIDER NdisSetHomeProvider = (PNDIS_WWAN_SET_HOME_PROVIDER)InBuffer; + SIZE_T StringCbLength= 0; + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_HOME_PROVIDER) ); + do + { + // + // Verify input buffer + // + if( !IsMultiCarrierCapable) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] SetHome unsupported for non-Multicarrier", + Request->RequestId + ); + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + NdisSetHomeProvidersSize = sizeof(NDIS_WWAN_SET_HOME_PROVIDER); + + if( *InBufferSize < NdisSetHomeProvidersSize ) + { + TraceError( WMBCLASS_OID, + "[MbbNdis][ReqID=0x%04x] INSUFFICIENT buffer size for NDIS_WWAN_SET_HOME_PROVIDER, Expecting=%d Received=%d", + Request->RequestId, + (ULONG)NdisSetHomeProvidersSize, + *InBufferSize + ); + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + // + // Query for the required size + // + HomeProvider = NdisSetHomeProvider->HomeProvider; + + MbbHomeProviderSize = sizeof(MBB_PROVIDER); + + if( (NdisStatus = RtlStringCbLengthW( + HomeProvider.Provider.ProviderId, + sizeof(HomeProvider.Provider.ProviderId), + &StringCbLength + )) != STATUS_SUCCESS ) + { + StringCbLength = sizeof(HomeProvider.Provider.ProviderId); + } + + MbbHomeProviderSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); + + if( (NdisStatus = RtlStringCbLengthW( + HomeProvider.Provider.ProviderName, + sizeof(HomeProvider.Provider.ProviderName), + &StringCbLength + )) != STATUS_SUCCESS ) + { + StringCbLength = sizeof(HomeProvider.Provider.ProviderName); + } + MbbHomeProviderSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); + + // + // Allocate & setup Mbb buffer + // + if( MbbHomeProviderSize > ULONG_MAX || + (MbbHomeProvider = ALLOCATE_NONPAGED_POOL( (ULONG)MbbHomeProviderSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate MBB_PROVIDER_LIST of Size=%d", + Request->RequestId, + (ULONG)MbbHomeProviderSize + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbHomeProvider; + + + // + // Convert from WWAN to MBB + // + if( (MbbHomeProviderSize = MbbUtilWwanToMbbProvider2( + &HomeProvider, + (ULONG)MbbHomeProviderSize, + MbbHomeProvider + )) == 0 ) + { + TraceError( WMBCLASS_OID, "[Util] FAILED to convert WWAN_PROVIDER2 to MBB_PROVIDER"); + break; + } + + // + // Send the data + // + NdisStatus = MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbHomeProvider, + (ULONG)MbbHomeProviderSize + ); + if( NdisStatus == NDIS_STATUS_SUCCESS || + NdisStatus == NDIS_STATUS_PENDING ) + { + *InBufferSize = (ULONG)NdisSetHomeProvidersSize; + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisSetMulticarrierProviders( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + ULONG ElementIndex; + ULONG ElementCount; + ULONG ValidDataSize; + ULONGLONG MbbPreferredProvidersSize; + ULONGLONG NdisSetPreferredProvidersSize; + PWWAN_PROVIDER2 WwanProvider; + NDIS_STATUS NdisStatus; + PMBB_PROVIDER_LIST MbbPreferredProviders = NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); + BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); + + PNDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS NdisSetPreferredProviders = (PNDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS)InBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS) ); + do + { + // + // Verify input buffer + // + if( NdisSetPreferredProviders->PreferredListHeader.ElementType != WwanStructProvider2 ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] INVALID WWAN_LIST Expecting=%d Received=%d", + Request->RequestId, + WwanStructProvider2, + NdisSetPreferredProviders->PreferredListHeader.ElementType + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + ElementCount = NdisSetPreferredProviders->PreferredListHeader.ElementCount; + NdisSetPreferredProvidersSize = sizeof(NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS) + (((ULONGLONG)ElementCount) * sizeof(WWAN_PROVIDER2)); + + if( *InBufferSize < NdisSetPreferredProvidersSize ) + { + TraceError( WMBCLASS_OID, + "[MbbNdis][ReqID=0x%04x] INSUFFICIENT buffer size for NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS, Expecting=%d Received=%d, ProviderCount=%d", + Request->RequestId, + (ULONG)NdisSetPreferredProvidersSize, + *InBufferSize, + ElementCount + ); + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + // + // Query for the required size + // + WwanProvider = (PWWAN_PROVIDER2)(((PCHAR)NdisSetPreferredProviders) + + RTL_SIZEOF_THROUGH_FIELD( NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS, PreferredListHeader )); + + MbbPreferredProvidersSize = FIELD_OFFSET(MBB_PROVIDER_LIST, Providers); + MbbPreferredProvidersSize += (ULONGLONG)ElementCount * sizeof(MBB_ARRAY_ELEMENT); + + for( ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex ++ ) + { + SIZE_T StringCbLength; + + MbbPreferredProvidersSize = ROUND_UP_COUNT( MbbPreferredProvidersSize, ALIGN_DWORD ); + MbbPreferredProvidersSize += sizeof(MBB_PROVIDER); + + if( (NdisStatus = RtlStringCbLengthW( + WwanProvider->Provider.ProviderId, + sizeof(WwanProvider->Provider.ProviderId), + &StringCbLength + )) != STATUS_SUCCESS ) + { + StringCbLength = sizeof(WwanProvider->Provider.ProviderId); + } + MbbPreferredProvidersSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); + + if( (NdisStatus = RtlStringCbLengthW( + WwanProvider->Provider.ProviderName, + sizeof(WwanProvider->Provider.ProviderName), + &StringCbLength + )) != STATUS_SUCCESS ) + { + StringCbLength = sizeof(WwanProvider->Provider.ProviderName); + } + MbbPreferredProvidersSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); + WwanProvider++; + } + // + // Allocate & setup Mbb buffer + // + if( MbbPreferredProvidersSize > ULONG_MAX || + (MbbPreferredProviders = (PMBB_PROVIDER_LIST)ALLOCATE_NONPAGED_POOL( (ULONG)MbbPreferredProvidersSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate MBB_PROVIDER_LIST of Size=%d for ProviderCount=%d", + Request->RequestId, + (ULONG)MbbPreferredProvidersSize, + ElementCount + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbPreferredProviders; + // + // Convert from WWAN to MBB + // + ValidDataSize = (ULONG)MbbPreferredProvidersSize; + + if( (NdisStatus = MbbUtilWwanToMbbProviderList( + &NdisSetPreferredProviders->PreferredListHeader, + IsMultiCarrierCapable, + MbbCellularClassInvalid, + MbbPreferredProviders, + &ValidDataSize + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to convert WWAN_PROVIDER_LIST to MBB_PROVIDER_LIST ", Request->RequestId ); + break; + } + // + // Send the data + // + NdisStatus = MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbPreferredProviders, + ValidDataSize + ); + if( NdisStatus == NDIS_STATUS_SUCCESS || + NdisStatus == NDIS_STATUS_PENDING ) + { + *InBufferSize = (ULONG)NdisSetPreferredProvidersSize; + } + } + while( FALSE ); + + return NdisStatus; +} + + +NDIS_STATUS +MbbNdisSetPmParameters( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) + +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + PMBB_PACKET_FILTERS MbbPacketFilters=NULL; + ULONG BufferSize=0; + NDIS_STATUS Status=STATUS_SUCCESS; + PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; + NDIS_PORT_NUMBER PortNumber = OidRequest->PortNumber; + PMBB_PORT Port = NULL; + ULONG SessionId = MBB_INVALID_SESSION_ID; + PNDIS_PM_PARAMETERS PmParameters=(PNDIS_PM_PARAMETERS)InBuffer; + + *InBufferSize=sizeof(*PmParameters); + + //Only honor this request when its received on port number 0. This is because + // this OID is sent by NDIS only during low power transitions <=D2. This should be seen + // by the miniport only during low power transitions as NDIS absorbs it in other cases. + // As per the current design, the WWAN virtual miniports are also going to send OID_PM_PARAMETERS + // to the filter driver, after every OID_PM_ADD/REMOVE_WOL_PATTERN OID request. In this case also + // OID_PM_PARAMETERS will be absorbed by NDIS and sent to the physical miniport on port 0. + + if(IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + ASSERT(FALSE); + TraceError( WMBCLASS_POWER, "Unexpected: OID_PM_PARAMETERS received on port number %lu instead of port number 0. Not handling and returning success", PortNumber); + return NDIS_STATUS_SUCCESS; + } + + if ((PmParameters->WakeUpFlags & NDIS_PM_SELECTIVE_SUSPEND_ENABLED) != 0) + { + TraceInfo( WMBCLASS_POWER, "Set PM Params: enable SS"); + } + else + { + TraceInfo( WMBCLASS_POWER, "Set PM Params: enabling wake: events= %08lx, enabled patterns=%d", + PmParameters->MediaSpecificWakeUpEvents, + (PmParameters->EnabledWoLPacketPatterns & NDIS_PM_WOL_BITMAP_PATTERN_ENABLED) != 0 + ); + + Status = MbbAdapterConfigurePacketFilters(Adapter,((PmParameters->EnabledWoLPacketPatterns & NDIS_PM_WOL_BITMAP_PATTERN_ENABLED) != 0)); + + if (!NT_SUCCESS(Status)) + { + TraceError( WMBCLASS_POWER, "Could not arm patterns"); + + return Status; + } + + Status=MbbAdapterConfigureDeviceServiceSubscription(Adapter, FALSE, PmParameters->MediaSpecificWakeUpEvents, PmParameters->WakeUpFlags); + + if (!NT_SUCCESS(Status)) + { + TraceError( WMBCLASS_POWER, "Could not enabled wake events"); + return Status; + } + // + // tell the device we expect to not be sending traffic for awhile + // + Status = MbbAdapterSendNetworkIdleHint(Adapter); + } + + return Status; +} + +NDIS_STATUS +MbbNdisSetAddWolPattern( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + NDIS_STATUS Status; + ULONGLONG BufferEnd; + PNDIS_PM_WOL_PATTERN Pattern=(PNDIS_PM_WOL_PATTERN)InBuffer; + NDIS_PORT_NUMBER PortNumber = Request->OidContext.OidRequest->PortNumber; + + TraceInfo( WMBCLASS_POWER, "Entered MbbNdisSetAddWolPattern for NDIS port number %lu", PortNumber); + + if (Pattern->WoLPacketType != NdisPMWoLPacketBitmapPattern) + { + TraceError( WMBCLASS_POWER, "Unsupported packet type"); + + return NDIS_STATUS_NOT_SUPPORTED; + } + + BufferEnd = (ULONGLONG)Pattern->WoLPattern.WoLBitMapPattern.MaskOffset + Pattern->WoLPattern.WoLBitMapPattern.MaskSize; + + if (BufferEnd > *InBufferSize) + { + TraceError( WMBCLASS_POWER, "buffer overflow in mask"); + + return NDIS_STATUS_INVALID_PARAMETER; + } + + BufferEnd = (ULONGLONG)Pattern->WoLPattern.WoLBitMapPattern.PatternOffset + Pattern->WoLPattern.WoLBitMapPattern.PatternSize; + + if (BufferEnd > *InBufferSize) + { + TraceError( WMBCLASS_POWER, "buffer overflow in pattern"); + + return NDIS_STATUS_INVALID_PARAMETER; + } + + // + // Each bit in the ndis mask represents a byte of data. For NCM each byte of mask is a bit filter for the pattern + // + if (Pattern->WoLPattern.WoLBitMapPattern.MaskSize * 8 > Adapter->BusParams.MaxPowerFilterSize) + { + TraceError( WMBCLASS_POWER, "Mask size is larger than supported by the device"); + + return NDIS_STATUS_INVALID_PARAMETER; + } + + // This request can arrive on disconnected connections too. Hence we just add the WOL + // pattern to the adapter power filter table without looking at the connection state of the port. + // During low power transition, only WOL patterns corresponding to connected ports will be + // plumbed to the device. + + Status = MbbUtilSetPowerFilterPattern( + Adapter, + PortNumber, + Pattern->PatternId, + InBuffer + Pattern->WoLPattern.WoLBitMapPattern.MaskOffset, + Pattern->WoLPattern.WoLBitMapPattern.MaskSize, + InBuffer + Pattern->WoLPattern.WoLBitMapPattern.PatternOffset, + Pattern->WoLPattern.WoLBitMapPattern.PatternSize + ); + + return Status; +} + +NDIS_STATUS +MbbNdisSetRemoveAddWolPattern( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + ULONG PatternId=*(PULONG)InBuffer; + NDIS_STATUS Status; + NDIS_PORT_NUMBER PortNumber = Request->OidContext.OidRequest->PortNumber; + + TraceInfo( WMBCLASS_POWER, "Entered MbbNdisSetRemoveAddWolPattern for PatternId=%d and NDIS port number %lu", PatternId, PortNumber ); + + Status = MbbUtilSetPowerFilterPattern( + Adapter, + PortNumber, + PatternId, + 0, + 0, + 0, + 0 + ); + + return Status; +} + + +NDIS_STATUS +MbbNdisQueryPower( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) + +{ + PULONG PowerState=(PULONG)OutBuffer; + + TraceInfo( WMBCLASS_POWER, "Query power D%d", *PowerState - NetDeviceStateD0); + + __analysis_assume( *OutBufferSize >= sizeof(*PowerState) ); + + *OutBufferSize=sizeof(*PowerState); + + return NDIS_STATUS_SUCCESS; + +} + +NDIS_STATUS +MbbNdisSetLteAttachContexts( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG MbbSetLteAttachContext = NULL; + PNDIS_WWAN_SET_LTE_ATTACH_CONTEXT NdisSetLteAttachContext= (PNDIS_WWAN_SET_LTE_ATTACH_CONTEXT)InBuffer; + ULONG BufferSize=0; + NDIS_STATUS Status; + PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; + + MbbAdapterLock(Adapter); + BOOL IsLteAttachCapable = Adapter->AdapterFlags.IsLTEAttachConfigCapable; + MbbAdapterUnlock(Adapter); + + if (!IsLteAttachCapable) + { + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support set LTE Attach configurations"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_LTE_ATTACH_CONTEXT) ); + + // LTE attach scenario + Status=MbbUtilWwanToMbbSetLteAttachContext( + &NdisSetLteAttachContext->SetLteAttachContext, + &MbbSetLteAttachContext, + &BufferSize + ); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetLteAttachContext; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSetLteAttachContext, + BufferSize + ); + +} + +NDIS_STATUS +MbbNdisSetProvisionedContexts( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMBB_SET_CONTEXT MbbSetContext=NULL; + PNDIS_WWAN_SET_PROVISIONED_CONTEXT NdisSetProvisionedContext= (PNDIS_WWAN_SET_PROVISIONED_CONTEXT)InBuffer; + ULONG BufferSize=0; + NDIS_STATUS Status; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT) ); + + *InBufferSize = sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT); + + Status=MbbUtilWwanToMbbSetContext( + &NdisSetProvisionedContext->ProvisionedContext, + &MbbSetContext, + &BufferSize + ); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetContext; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSetContext, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetProvisionedContextsV2( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 MbbSetContext = NULL; + PNDIS_WWAN_SET_PROVISIONED_CONTEXT_V2 NdisSetProvisionedContext = (PNDIS_WWAN_SET_PROVISIONED_CONTEXT_V2)InBuffer; + ULONG BufferSize = 0; + NDIS_STATUS Status; + PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; + + MbbAdapterLock(Adapter); + BOOL IsProvisionedContextV2Capable = Adapter->AdapterFlags.IsProvisionedContextV2Capable; + MbbAdapterUnlock(Adapter); + + if (!IsProvisionedContextV2Capable) + { + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support ProvisionedContextV2"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT_V2)); + + *InBufferSize = sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT_V2); + + Status = MbbUtilWwanToMbbSetContextV2( + &NdisSetProvisionedContext->ProvisionedContext, + &MbbSetContext, + &BufferSize + ); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetContext; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbSetContext, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetServiceActivation( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG MbbServiceActivationSize; + PMBB_SERVICE_ACTIVATION MbbServiceActivation = NULL; + PNDIS_WWAN_SERVICE_ACTIVATION NdisServiceActivation = (PNDIS_WWAN_SERVICE_ACTIVATION)InBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SERVICE_ACTIVATION) ); + *InBufferSize = sizeof(NDIS_WWAN_SERVICE_ACTIVATION); + + do + { + MbbServiceActivationSize = NdisServiceActivation->ServiceActivation.uVendorSpecificBufferSize; + + if (MbbServiceActivationSize > MBB_MAX_SERVICE_ACTIVATION_BUFFER) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] actrivation buffer too big %d", Request->RequestId, MbbServiceActivationSize ); + + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + + if (MbbServiceActivationSize + RTL_SIZEOF_THROUGH_FIELD( NDIS_WWAN_SERVICE_ACTIVATION, ServiceActivation.uVendorSpecificBufferSize ) > *InBufferSize) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] activation buffer larger than Input Buffer %d", Request->RequestId, MbbServiceActivationSize ); + + NdisStatus = NDIS_STATUS_BUFFER_TOO_SHORT; + break; + } + + + if( (MbbServiceActivation = ALLOCATE_NONPAGED_POOL( MbbServiceActivationSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate SERVICE_ACTIVATION buffer", Request->RequestId ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbServiceActivation; + + RtlCopyMemory( + MbbServiceActivation->VendorSpecificBuffer, + NdisServiceActivation + 1, + MbbServiceActivationSize + ); + + NdisStatus = MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)(MbbServiceActivation), + MbbServiceActivationSize + ); + } + while( FALSE ); + + return NdisStatus; +} + +// SMS + +NDIS_STATUS +MbbNdisSmsSetConfiguration( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + ULONG MbbBufferSize; + SIZE_T ScAddressSize; + NTSTATUS NtStatus; + PMBB_SET_SMS_CONFIGURATION MbbSetSmsConfiguration; + PNDIS_WWAN_SET_SMS_CONFIGURATION NdisSmsSetConfiguration = (PNDIS_WWAN_SET_SMS_CONFIGURATION)InBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_SMS_CONFIGURATION) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_SMS_CONFIGURATION); + + NtStatus = RtlStringCbLengthA( + NdisSmsSetConfiguration->SetSmsConfiguration.ScAddress, + WWAN_SMS_ADDRESS_MAX_LEN, + &ScAddressSize + ); + + if ( NtStatus != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] INVALID ScAddress OID_WWAN_SMS_CONFIGURATION SET, status=%!STATUS!", + Request->RequestId, + NtStatus + ); + + return NtStatus; + } + + NtStatus=MbbUtilWwanToMbbSmsSetConfiguration( + &NdisSmsSetConfiguration->SetSmsConfiguration, + (ULONG)ScAddressSize, + &MbbSetSmsConfiguration, + &MbbBufferSize + ); + + if ( NtStatus != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] could not convert SMS config to MBB, status=%!STATUS!", + Request->RequestId, + NtStatus + ); + + return NtStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetSmsConfiguration; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSetSmsConfiguration, + MbbBufferSize + ); +} + +NDIS_STATUS +MbbNdisSmsSend( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + ULONG MbbSmsSendSize; + NDIS_STATUS NdisStatus; + PMBB_SMS_SEND MbbSmsSend; + PNDIS_WWAN_SMS_SEND NdisSmsSend = (PNDIS_WWAN_SMS_SEND)InBuffer; + MBB_CELLULAR_CLASS CellularClass = MbbAdapterGetCurrentCellularClass( MbbReqMgrGetAdapterHandle( Request ) ); + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SMS_SEND) ); + *InBufferSize = sizeof(NDIS_WWAN_SMS_SEND); + + if (MbbAdapterIsMultimodeCapable(MbbReqMgrGetAdapterHandle( Request ))) + { + // + // multimode device always use GSM PDU's + // + CellularClass = MbbCellularClassGsm; + } + + + if( NdisSmsSend->SmsSend.SmsFormat == WwanSmsFormatPdu ) + { + + NdisStatus=MbbUtilWwanToMbbSmsSendPdu( + &NdisSmsSend->SmsSend.u.Pdu, + CellularClass, + &MbbSmsSend, + &MbbSmsSendSize + ); + + } + else + { + + NdisStatus=MbbUtilWwanToMbbSmsSendCdma( + &NdisSmsSend->SmsSend.u.Cdma, + &MbbSmsSend, + &MbbSmsSendSize + ); + + + } + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to convert data for OID_WWAN_SMS_SEND, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + return NdisStatus; + + } + + MbbSmsSend->SmsFormat = MbbUtilWwanToMbbSmsFormat( NdisSmsSend->SmsSend.SmsFormat ); + Request->HandlerContext.DataToFreeOnCompletion = MbbSmsSend; + + // + // Send CID + // + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSmsSend, + MbbSmsSendSize + ); +} + +NDIS_STATUS +MbbNdisSmsDelete( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMBB_SMS_DELETE MbbSmsDelete; + PNDIS_WWAN_SMS_DELETE NdisSmsDelete = (PNDIS_WWAN_SMS_DELETE)InBuffer; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SMS_DELETE) ); + *InBufferSize = sizeof(NDIS_WWAN_SMS_DELETE); + // + // TODO: If WWAN_SMS_FILTER and MBB_SMS_DELETE are of the same layout. + // avoid unneccesary data copy and use the passed in + // NDIS format and do not convert to MBB format. + // + if( (MbbSmsDelete = (PMBB_SMS_DELETE) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SMS_DELETE) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSmsDelete; + + MbbUtilWwanToMbbSmsDelete( + &NdisSmsDelete->SmsFilter, + MbbSmsDelete + ); + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSmsDelete, + sizeof(MBB_SMS_DELETE) + ); +} + +// DEVICE SERVICE + +NDIS_STATUS +MbbNdisSubscribeDeviceServiceEvents( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG OidSubscribeListSize = 0; + PMBB_SUBSCRIBE_EVENT_LIST OidSubscribeList = NULL; + PNDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS NdisSubscribeEvents = (PNDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS)InBuffer; + GUID* NdisSubscribeGuid = NULL; + PMBB_SUBSCRIBE_EVENT_LIST MbbSubscribeList = NULL; + ULONG MbbSubscribeListSize = 0; + ULONGLONG RequiredInputSize = 0; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + + + do + { + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS) ); + + // + // First, for the specified device services, generate the list + // of device service + CIDs that we want to subscribe to + // + RequiredInputSize = sizeof(NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS) + + (ULONGLONG)NdisSubscribeEvents->DeviceServiceListHeader.ElementCount * sizeof(GUID); + + if (*InBufferSize < RequiredInputSize) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS, BufferSize[Received=%d Expected=%I64d]", + Request->RequestId, + *InBufferSize, + RequiredInputSize + ); + + if (RequiredInputSize > ULONG_MAX) + { + *InBufferSize = ULONG_MAX; + } + else + { + *InBufferSize = (ULONG)RequiredInputSize; + } + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + + Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )); + + if (NdisSubscribeEvents->DeviceServiceListHeader.ElementCount != 0) + { + // Get the specified GUIDs + NdisSubscribeGuid = (GUID *)((PUCHAR)InBuffer + + sizeof(NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS)); + + // Generate the Mbb structure for this request + NdisStatus = MbbUtilWwanToMbbSubscribeEvents(Adapter, + NdisSubscribeGuid, + NdisSubscribeEvents->DeviceServiceListHeader.ElementCount, + TRUE, // External request, so validate + NULL, + 0, // No padding + &OidSubscribeList, + &OidSubscribeListSize + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to convert OID subscribe list to MBB subscribe list", + Request->RequestId + ); + break; + } + } + else + { + OidSubscribeList = NULL; + OidSubscribeListSize = 0; + } + + // Save this as the OID configured subscribe list till we finish the + // transaction. If the transaction succeeds, we will persist this list + Request->HandlerContext.Parameters.EventSubscribe.ExtList = OidSubscribeList; + Request->HandlerContext.Parameters.EventSubscribe.ExtSize = OidSubscribeListSize; + + // Save the pointer to the buffer so that it gets freed automatically on failure paths + Request->HandlerContext.DataToFreeOnResponse = OidSubscribeList; + + // + // Now, merge this with the internally generated list + // that we want to subscribe to + // + NdisStatus = MbbUtilGenerateSubscribeEventList( + (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext), + TRUE, // Awake + 0, + 0, + OidSubscribeList, + OidSubscribeListSize, + &MbbSubscribeList, + &MbbSubscribeListSize + ); + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to generate merged MBB_SUBSCRIBE_EVENT_LIST, status=%!STATUS!", + Request->RequestId, NdisStatus + ); + break; + } + + // The buffer we are using for the request is saved for freeing on completion + Request->HandlerContext.DataToFreeOnCompletion = MbbSubscribeList; + + NdisStatus = MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSubscribeList, + MbbSubscribeListSize + ); + if ((NdisStatus != NDIS_STATUS_SUCCESS) && + (NdisStatus != NDIS_STATUS_PENDING)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to submit merged MBB_SUBSCRIBE_EVENT_LIST, status=%!STATUS!", + Request->RequestId, NdisStatus + ); + break; + } + + + } while (FALSE); + + if ((NdisStatus != NDIS_STATUS_SUCCESS) && + (NdisStatus != NDIS_STATUS_PENDING)) + { + if (Request->HandlerContext.DataToFreeOnCompletion) + FREE_POOL(Request->HandlerContext.DataToFreeOnCompletion); + + if (Request->HandlerContext.DataToFreeOnResponse) + FREE_POOL(Request->HandlerContext.DataToFreeOnResponse); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisSetDeviceServiceCommand( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + return MbbUtilDeviceServiceCommand( + Request, + InBuffer, + InBufferSize + ); +} + +NDIS_STATUS +MbbNdisSetVendorSpecific( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS NdisStatus; + MBB_COMMAND MbbCommand; + PNDIS_WWAN_VENDOR_SPECIFIC NdisVendorSpecific; + + do + { + if( *InBufferSize < sizeof(NDIS_WWAN_VENDOR_SPECIFIC) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INSUFFICIENT InputBufferSize=%d Bytes for VENDOR_SPECIFIC, Expected=%d Bytes", + Request->RequestId, *InBufferSize, sizeof(NDIS_WWAN_VENDOR_SPECIFIC) ); + + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + *InBufferSize = sizeof(NDIS_WWAN_VENDOR_SPECIFIC); + break; + } + + NdisVendorSpecific = (PNDIS_WWAN_VENDOR_SPECIFIC) InBuffer; + + + if( NdisVendorSpecific->Header.Type != NDIS_OBJECT_TYPE_DEFAULT || + NdisVendorSpecific->Header.Size < sizeof(NDIS_WWAN_VENDOR_SPECIFIC) || + NdisVendorSpecific->Header.Revision < NDIS_WWAN_VENDOR_SPECIFIC_REVISION_1 ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INVALID ndis header for VENDOR_SPECIFIC, Type=0x%x Size=%d Revision=%d", + Request->RequestId, + NdisVendorSpecific->Header.Type, + NdisVendorSpecific->Header.Size, + NdisVendorSpecific->Header.Revision + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + if (NdisVendorSpecific->VendorSpecificData.uVendorSpecificBufferSize + + RTL_SIZEOF_THROUGH_FIELD(NDIS_WWAN_VENDOR_SPECIFIC,VendorSpecificData.uVendorSpecificBufferSize) > *InBufferSize ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INSUFFICIENT InputBufferSize=%d Bytes for VENDOR_SPECIFIC, Expected=%d Bytes", + Request->RequestId, *InBufferSize, sizeof(NDIS_WWAN_VENDOR_SPECIFIC) ); + + *InBufferSize = NdisVendorSpecific->VendorSpecificData.uVendorSpecificBufferSize + + RTL_SIZEOF_THROUGH_FIELD(NDIS_WWAN_VENDOR_SPECIFIC,VendorSpecificData.uVendorSpecificBufferSize); + + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + + RtlCopyMemory( + &MbbCommand.ServiceId, + &MBB_UUID_MS_VENDOR_EXTENSION, + sizeof(GUID) + ); + + MbbCommand.CommandId = MBIM_CID_VENDORSPECIFIC; + // + // Call the wrapper routine to allocate + // and format the message buffers. + // + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &MbbCommand, + MbbReqMgrIsSetOid( Request )? MBB_COMMAND_TYPE_SET: MBB_COMMAND_TYPE_QUERY, + (PUCHAR)(NdisVendorSpecific + 1), + NdisVendorSpecific->VendorSpecificData.uVendorSpecificBufferSize + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to setup command message for VENDOR_SPECIFIC with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to send message fragments for VENDOR_SPECIFIC with status=%!status!", + Request->RequestId, NdisStatus ); + } + + } while( FALSE ); + + return NdisStatus; +} + + +NDIS_STATUS +MbbNdisSetDeviceServiceSession( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + MBB_SET_DSS_CONNECT MbbDssConnect; + + PNDIS_WWAN_SET_DEVICE_SERVICE_SESSION NdisDssRequest = (PNDIS_WWAN_SET_DEVICE_SERVICE_SESSION)InBuffer; + NDIS_STATUS Status; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_DEVICE_SERVICE_SESSION) ); + *InBufferSize = sizeof(NDIS_WWAN_SET_DEVICE_SERVICE_SESSION); + + if (MbbUtilIsNativeMbnService(&(NdisDssRequest->Session.DeviceServiceGuid))) + { + // Native device services cannot be used using this path + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED because of request for native device service %!GUID!", + Request->RequestId, + &(NdisDssRequest->Session.DeviceServiceGuid) + ); + + return NDIS_STATUS_INVALID_DATA; + } + + // + // Save stuff about the request in the set so that we can send the relevant + // info in the indication + // + RtlCopyMemory( + &Request->HandlerContext.Parameters.DssSession.DeviceServiceGuid, + &(NdisDssRequest->Session.DeviceServiceGuid), + sizeof(GUID) + ); + Request->HandlerContext.Parameters.DssSession.SessionId = NdisDssRequest->Session.uSessionID; + + + if ((NdisDssRequest->Session.State == WwanDeviceServiceSessionOpen) + || + (NdisDssRequest->Session.State == WwanDeviceServiceSessionClosed)) + { + + // Send the Open Request + + // Copy the device service in device format + MBB_UUID_TO_NET(&MbbDssConnect.DeviceServiceId, + &(NdisDssRequest->Session.DeviceServiceGuid) + ); + + MbbDssConnect.DssSessionId = NdisDssRequest->Session.uSessionID; + + MbbDssConnect.DssLinkState = (NdisDssRequest->Session.State == WwanDeviceServiceSessionOpen) ? MbbDssLinkActivate : MbbDssLinkDeactivate; + + Request->HandlerContext.Parameters.DssSession.LinkState = MbbDssConnect.DssLinkState; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)(&MbbDssConnect), + sizeof(MbbDssConnect) + ); + } + else + { + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Device Service Session state specified is invalid, %d", + Request->RequestId, + NdisDssRequest->Session.State); + + return NDIS_STATUS_INVALID_PARAMETER; + } +} + +NDIS_STATUS +MbbNdisDssWrite( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS NdisStatus; + MBB_COMMAND MbbCommand; + PNDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE NdisDssWriteRequest; + + // The session write gets pushed through the send path to the device + do + { + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE) ); + *InBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE); + + NdisDssWriteRequest = (PNDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE) InBuffer; + + if (NdisDssWriteRequest->WriteData.uDataSize == 0) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Invalid size for device service session write", + Request->RequestId); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + // Ref this request so that we can pass a reference to it to send path. When + // the send path completes the request, we will release the ref + MbbReqMgrRefRequest(Request); + + NdisStatus = MbbSendDeviceServiceSessionData( + ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )), + Request, + Request->RequestId, + NdisDssWriteRequest->WriteData.uSessionID, + NdisDssWriteRequest->WriteData.uDataSize, + (PUCHAR)(NdisDssWriteRequest + 1) + ); + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + MbbReqMgrDerefRequest(Request); + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to write device service data with status=%!status!", + Request->RequestId, NdisStatus ); + } + + } while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisDeleteMac( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; + PNDIS_WWAN_MAC_INFO ndisWwanMacInfo = NULL; + PNDIS_OID_REQUEST oidRequest = Request->OidContext.OidRequest; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferSize); + + do + { + oidRequest->DATA.SET_INFORMATION.BytesRead = 0; + oidRequest->DATA.SET_INFORMATION.BytesNeeded = 0; + + if (oidRequest->RequestType != NdisRequestSetInformation) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] Invalid request type %d for OID_WWAN_DELETE_MAC\n", + Request->RequestId, + oidRequest->RequestType + ); + ndisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + ASSERT(oidRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof(NDIS_WWAN_MAC_INFO)); + + ndisWwanMacInfo = (PNDIS_WWAN_MAC_INFO)oidRequest->DATA.SET_INFORMATION.InformationBuffer; + + if (!IS_ALLOCATED_PORT_NUMBER(ndisWwanMacInfo->uNdisPortNumber)) + { + TraceError (WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] The port number (%d) being passed in is invalid", + Request->RequestId, + ndisWwanMacInfo->uNdisPortNumber); + + ndisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + ndisStatus = MbbUtilWwanDeleteMac(Request); + + if (ndisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID,"MbbNdis][ReqID=0x%04x] MbbUtilWwanDeleteMac failed. Status = 0x%08x\n", + Request->RequestId,ndisStatus); + break; + } + }while (FALSE); + + return ndisStatus; +} + +NDIS_STATUS +MbbNdisUiccUpdateBinary( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + return MbbUtilUiccAccessBinary( + Request, + InBuffer, + InBufferSize + ); +} + +NDIS_STATUS +MbbNdisUiccUpdateRecord( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + return MbbUtilUiccAccessRecord( + Request, + InBuffer, + InBufferSize + ); +} + +NDIS_STATUS +MbbNdisSetSysSlotMappings( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PNDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO NdisSetDeviceSlotMappingInfo = (PNDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO)InBuffer; + PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbSetDeviceSlotMappingInfo = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG BufferSize = 0; + + NdisStatus = MbbUtilWwanToMbbSetDeviceSlotMappingInfo( + &(NdisSetDeviceSlotMappingInfo->SetDeviceSlotMappingInfo), + &MbbSetDeviceSlotMappingInfo, + &BufferSize); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetDeviceSlotMappingInfo; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbSetDeviceSlotMappingInfo, + BufferSize); +} + +NDIS_STATUS +MbbNdisSetDeviceBindings( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PNDIS_WWAN_SET_DEVICE_BINDINGS_INFO NdisSetDeviceBindingsInfo = (PNDIS_WWAN_SET_DEVICE_BINDINGS_INFO)InBuffer; + PMBB_DEVICE_BINDINGS_INFO MbbSetDeviceBindingsInfo = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG BufferSize = 0; + + NdisStatus = MbbUtilWwanToMbbSetDeviceBindingsInfo( + &(NdisSetDeviceBindingsInfo->SetDeviceBindingsInfo), + &MbbSetDeviceBindingsInfo, + &BufferSize); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetDeviceBindingsInfo; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbSetDeviceBindingsInfo, + BufferSize); +} + +NDIS_STATUS +MbbNdisSetRegisterStateEx( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PNDIS_WWAN_SET_REGISTER_STATE_EX NdisSetRegisterStateEx = (PNDIS_WWAN_SET_REGISTER_STATE_EX)InBuffer; + PMBB_SET_REGISTER_STATE_V2 MbbSetRegisterStateV2 = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG BufferSize = 0; + + NdisStatus = MbbUtilWwanToMbbSetRegisterStateEx( + &(NdisSetRegisterStateEx->SetRegisterState), + &MbbSetRegisterStateV2, + &BufferSize); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetRegisterStateV2; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbSetRegisterStateV2, + BufferSize); +} + +NDIS_STATUS +MbbNdisSetImsVoiceState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PNDIS_WWAN_SET_IMS_VOICE_STATE NdisSetImsVoiceState = (PNDIS_WWAN_SET_IMS_VOICE_STATE)InBuffer; + PMBB_SET_IMS_VOICE_STATE MbbSetImsVoiceState = NULL; + ULONG BufferSize = sizeof(MBB_SET_IMS_VOICE_STATE); + + MbbSetImsVoiceState = ALLOCATE_NONPAGED_POOL(BufferSize); + if (NULL == MbbSetImsVoiceState) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSetImsVoiceState; + + RtlZeroMemory(MbbSetImsVoiceState, BufferSize); + + MbbSetImsVoiceState->ImsVoiceStatus = (MBB_IMS_VOICE_STATUS)(NdisSetImsVoiceState->SetImsVoiceState.ImsVoiceStatus); + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR)MbbSetImsVoiceState, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetSignalStateEx( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PNDIS_WWAN_SET_SIGNAL_INDICATION_EX NdisSetSignalIndicationEx = (PNDIS_WWAN_SET_SIGNAL_INDICATION_EX)InBuffer; + PMBB_SET_SIGNAL_INDICATION_V2 MbbSetSignalIndicationV2 = NULL; + ULONG BufferSize = sizeof(MBB_SET_SIGNAL_INDICATION_V2); + + MbbSetSignalIndicationV2 = ALLOCATE_NONPAGED_POOL(BufferSize); + if (NULL == MbbSetSignalIndicationV2) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSetSignalIndicationV2; + + RtlZeroMemory(MbbSetSignalIndicationV2, BufferSize); + + RtlCopyMemory(MbbSetSignalIndicationV2, &(NdisSetSignalIndicationEx->SignalIndication), BufferSize); + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR)MbbSetSignalIndicationV2, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetLocationState( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PNDIS_WWAN_LOCATION_TRIGGER_MODE NdisLocationTriggerMode = (PNDIS_WWAN_LOCATION_TRIGGER_MODE)InBuffer; + PMBB_SET_LOCATION_STATE MbbSetLocationState = NULL; + ULONG BufferSize = sizeof(MBB_SET_LOCATION_STATE); + + MbbSetLocationState = ALLOCATE_NONPAGED_POOL(BufferSize); + if (NULL == MbbSetLocationState) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSetLocationState; + + RtlZeroMemory(MbbSetLocationState, BufferSize); + + MbbSetLocationState->Trigger = (MBB_LOCATION_TRIGGER_MODE)(NdisLocationTriggerMode->SetLocationState.Trigger); + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR)MbbSetLocationState, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetNetworkIdleHint( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PNDIS_WWAN_NETWORK_IDLE_HINT NdisNetworkIdleHint = (PNDIS_WWAN_NETWORK_IDLE_HINT)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; + NDIS_PORT_NUMBER PortNumber = OidRequest->PortNumber; + NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; + + // Honor this OID Request only if we get the request on the Physical Miniport which is on Port 0 + + do + { + if (IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] OID_WWAN_NETWORK_IDLE_HINT received on port number %lu instead of port number 0. Not handling and returning success\n", + Request->RequestId, + PortNumber + ); + ndisStatus = NDIS_STATUS_SUCCESS; + break; + } + + // if we are getting a call from above to put the device into Network Idle mode, then do so + if (NdisNetworkIdleHint->IdleHint.IsEnabled) + { + ndisStatus = MbbAdapterSendNetworkIdleHint(Adapter); + } + + } while (FALSE); + + return ndisStatus; +} + +NDIS_STATUS +MbbNdisSetPreshutdown( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + PNDIS_WWAN_PRESHUTDOWN_STATE NdisPreshutdownState = (PNDIS_WWAN_PRESHUTDOWN_STATE)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; + NDIS_PORT_NUMBER PortNumber = OidRequest->PortNumber; + BOOLEAN IsPreshutdownCapable = FALSE; + + do + { + // Honor this OID Request only if we get the request on the Physical Miniport (i.e. Port 0) + if (IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] OID_WWAN_PRESHUTDOWN received on port number %lu instead of port number 0. Not handling and returning success\n", + Request->RequestId, + PortNumber + ); + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + // Check for device support and bail if not supported + MbbAdapterLock(Adapter); + IsPreshutdownCapable = (TRUE == Adapter->AdapterFlags.IsPreshutdownCapable); + MbbAdapterUnlock(Adapter); + + if (!IsPreshutdownCapable) + { + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] OID_WWAN_PRESHUTDOWN - Device does not support preshutdown)", + Request->RequestId + ); + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + NdisStatus = MbbUtilSetAttributeWithParameter( + Request, + NULL, + 0); + if ((NdisStatus != NDIS_STATUS_SUCCESS) && + (NdisStatus != NDIS_STATUS_PENDING)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] OID_WWAN_PRESHUTDOWN Device SET failed", + Request->RequestId + ); + break; + } + + TraceLoggingWrite( + g_hLoggingProvider, + "OID_Wwan_Preshutdown_Request", + TraceLoggingUInt64(Request->RequestId, "RequestID"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); + + } while (FALSE); + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisSetUiccOpenChannel( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PNDIS_WWAN_SET_UICC_OPEN_CHANNEL NdisSetUiccOpenChannel = (PNDIS_WWAN_SET_UICC_OPEN_CHANNEL)InBuffer; + PMBB_SET_UICC_OPEN_CHANNEL MbbSetUiccOpenChannel = NULL; + NDIS_STATUS NdisStatus; + ULONG BufferSize = 0; + + __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_OPEN_CHANNEL)); + + NdisStatus = MbbUtilWwanToMbbSetUiccOpenChannel( + &NdisSetUiccOpenChannel->SetUiccOpenChannel, + &MbbSetUiccOpenChannel, + &BufferSize + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccOpenChannel; + + return MbbUtilSetAttributeWithParameter( + Request, + (PUCHAR) MbbSetUiccOpenChannel, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetUiccCloseChannel( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PNDIS_WWAN_SET_UICC_CLOSE_CHANNEL NdisSetUiccCloseChannel = (PNDIS_WWAN_SET_UICC_CLOSE_CHANNEL)InBuffer; + PMBB_SET_UICC_CLOSE_CHANNEL MbbSetUiccCloseChannel = NULL; + + __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_CLOSE_CHANNEL)); + + if( (MbbSetUiccCloseChannel = (PMBB_SET_UICC_CLOSE_CHANNEL) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SET_UICC_CLOSE_CHANNEL) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + MbbUtilWwanToMbbSetUiccCloseChannel( + &NdisSetUiccCloseChannel->SetUiccCloseChannel, + MbbSetUiccCloseChannel + ); + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccCloseChannel; + + return MbbUtilSetAttributeWithParameter( + Request, + (PUCHAR) MbbSetUiccCloseChannel, + sizeof(MBB_SET_UICC_CLOSE_CHANNEL) + ); +} + +NDIS_STATUS +MbbNdisSetUiccApdu( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PNDIS_WWAN_SET_UICC_APDU NdisSetUiccApdu = (PNDIS_WWAN_SET_UICC_APDU)InBuffer; + PMBB_SET_UICC_APDU MbbSetUiccApdu = NULL; + NDIS_STATUS NdisStatus; + ULONG BufferSize = 0; + + __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_APDU)); + + NdisStatus = MbbUtilWwanToMbbSetUiccApdu( + &NdisSetUiccApdu->SetUiccApdu, + &MbbSetUiccApdu, + &BufferSize + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccApdu; + + return MbbUtilSetAttributeWithParameter( + Request, + (PUCHAR) MbbSetUiccApdu, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetUiccTerminalCapability( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PNDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY NdisSetUiccTerminalCapability = (PNDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY)InBuffer; + PMBB_SET_UICC_TERMINAL_CAPABILITY MbbSetUiccTerminalCapability = NULL; + NDIS_STATUS NdisStatus; + ULONG BufferSize = 0; + + __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY)); + + NdisStatus = MbbUtilWwanToMbbSetUiccTerminalCapability( + &NdisSetUiccTerminalCapability->SetUiccTerminalCapability.CapabilityListHeader, + &MbbSetUiccTerminalCapability, + &BufferSize + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccTerminalCapability; + + return MbbUtilSetAttributeWithParameter( + Request, + (PUCHAR) MbbSetUiccTerminalCapability, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetUiccReset( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize + ) +{ + PNDIS_WWAN_SET_UICC_RESET NdisSetUiccReset = (PNDIS_WWAN_SET_UICC_RESET)InBuffer; + PMBB_SET_UICC_RESET MbbSetUiccReset = NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterLock(Adapter); + BOOL IsUiccLowLevelCapable = Adapter->AdapterFlags.IsUiccLowLevelCapable; + MbbAdapterUnlock(Adapter); + + if (!IsUiccLowLevelCapable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support UICC low level operations (SET_UICC_RESET)"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_RESET)); + + if( (MbbSetUiccReset = (PMBB_SET_UICC_RESET) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SET_UICC_RESET) )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + MbbSetUiccReset->PassThroughAction = (MBB_UICC_PASSTHROUGH_ACTION)NdisSetUiccReset->SetUiccReset.PassThroughAction; + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccReset; + + return MbbUtilSetAttributeWithParameter( + Request, + (PUCHAR) MbbSetUiccReset, + sizeof(MBB_SET_UICC_RESET) + ); +} + +// SAR backoff set +NDIS_STATUS +MbbNdisSetSarConfig( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize + ) +{ + PMBB_SET_SAR_CONFIG MbbSetSarConfig = NULL; + PNDIS_WWAN_SET_SAR_CONFIG NdisSetSarConfig = (PNDIS_WWAN_SET_SAR_CONFIG)InBuffer; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG BufferSize = 0; + PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; + + MbbAdapterLock(Adapter); + BOOL IsSARCapable = Adapter->AdapterFlags.IsSARCapable; + MbbAdapterUnlock(Adapter); + + if (!IsSARCapable) + { + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support SAR control service"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + NdisStatus = MbbUtilWwanToMbbSetSarConfig( + &(NdisSetSarConfig->SetSarConfig), + &MbbSetSarConfig, + &BufferSize); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetSarConfig; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbSetSarConfig, + BufferSize); +} + +NDIS_STATUS +MbbNdisSetSarTransmissionStatus( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize + ) +{ + PMBB_SET_SAR_TRANSMISSION_STATUS MbbSetSarTransmissionStatus = NULL; + PNDIS_WWAN_SET_SAR_TRANSMISSION_STATUS NdisSetSarTransmissionStatus = (PNDIS_WWAN_SET_SAR_TRANSMISSION_STATUS)InBuffer; + ULONG BufferSize = sizeof(MBB_SET_SAR_TRANSMISSION_STATUS); + + MbbSetSarTransmissionStatus = ALLOCATE_NONPAGED_POOL(BufferSize); + if (NULL == MbbSetSarTransmissionStatus) + { + return NDIS_STATUS_RESOURCES; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbSetSarTransmissionStatus; + + RtlZeroMemory(MbbSetSarTransmissionStatus, BufferSize); + + MbbSetSarTransmissionStatus->ChannelNotification = + (MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE)(NdisSetSarTransmissionStatus->SetTransmissionStatus.ChannelNotification); + MbbSetSarTransmissionStatus->HysteresisTimer = NdisSetSarTransmissionStatus->SetTransmissionStatus.HysteresisTimer; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbSetSarTransmissionStatus, + BufferSize); +} + +NDIS_STATUS +MbbNdisSetNetworkBlacklist( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize +) +{ + PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist = NULL; + PNDIS_WWAN_SET_NETWORK_BLACKLIST NdisSetNetworkBlacklist = (PNDIS_WWAN_SET_NETWORK_BLACKLIST)InBuffer; + ULONG BufferSize = 0; + NDIS_STATUS Status; + PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; + + MbbAdapterLock(Adapter); + BOOL IsNetworkBlacklistCapable = Adapter->AdapterFlags.IsNetworkBlacklistCapable; + MbbAdapterUnlock(Adapter); + + if (!IsNetworkBlacklistCapable) + { + TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support network blacklist"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_NETWORK_BLACKLIST)); + + *InBufferSize = sizeof(NDIS_WWAN_SET_NETWORK_BLACKLIST); + + Status = MbbUtilWwanToMbbSetNetworkBlacklist( + &NdisSetNetworkBlacklist->SetNetworkBlacklist, + &MbbNetworkBlacklist, + &BufferSize + ); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbNetworkBlacklist; + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbNetworkBlacklist, + BufferSize + ); +} + +NDIS_STATUS +MbbNdisSetDeviceReset( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, + _In_ PULONG InBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); + + UNREFERENCED_PARAMETER(InBuffer); + + MbbAdapterLock(Adapter); + BOOL IsDeviceResetCapable = Adapter->AdapterFlags.IsDeviceResetCapable; + MbbAdapterUnlock(Adapter); + + if (!IsDeviceResetCapable) + { + TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support device reset"); + return NDIS_STATUS_NOT_SUPPORTED; + } + + __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_DEVICE_RESET)); + + return MbbUtilSetAttributeWithParameter( + Request, + NULL, + 0 + ); +} + + +// +// Status Handlers +// + +/*++ +General handling of responses \ indications: + If the response \ indication couldnt be retrieved at all i.e. + NdisStatus != NDIS_STATUS_SUCCESS then bail out immediately. + + If the operational status is unsuccessful i.e. MbbStatus != + MBB_STATUS_SUCCESS the device may or may not have returned + additional data. In case it has propagate that data to svc. + If not then preserve the device returned failure code. + +Parameters + NdisStatus + Conveys whether the response was successfully retrieved. + + MbbStatus + The MBIM specification based operational status that the device returned. +--*/ + +VOID +MbbNdisIndicateDeviceCaps( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + BOOLEAN IndicateFailure = TRUE; + ULONG NdisDeviceCapsSize = Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCapsSize; + PMINIPORT_ADAPTER_CONTEXT Adapter; + PNDIS_WWAN_DEVICE_CAPS NdisDeviceCaps = Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCaps; + NDIS_WWAN_DEVICE_CAPS LocalNdisDeviceCaps; + NDIS_STATUS_INDICATION StatusIndication; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_CAPS + ); + + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ); + // + // If the CID response wasnt receieved then bail out. + // + if( NDIS_STATUS_SUCCESS != NdisStatus || + NULL == NdisDeviceCaps ) + { + break; + } + // + // Translate device services to caps. + // + if( Request->HandlerContext.Parameters.DeviceCaps.IsUssdCapsValid == 0 || + Request->HandlerContext.Parameters.DeviceCaps.IsAuthCapsValid == 0 ) + { + NdisStatus = MbbAdapterFWDeviceServicesToCapabilities( + Adapter, + Request + ); + if( NDIS_STATUS_PENDING == NdisStatus ) + { + // + // The status handler will take care of the rest. + // + NdisDeviceCaps = NULL; + IndicateFailure = FALSE; + break; + } + else if( NDIS_STATUS_SUCCESS != NdisStatus ) + { + break; + } + } + // + // All information is available. Indicate status. + // + NdisDeviceCaps->DeviceCaps.WwanAuthAlgoCaps = WWAN_AUTH_ALGO_CAPS_NONE; + if( Adapter->AdapterFlags.IsUssdCapable == TRUE ) + NdisDeviceCaps->DeviceCaps.WwanControlCaps |= WWAN_CTRL_CAPS_USSD; + if( Adapter->AdapterFlags.IsAkaAuthCapable == TRUE ) + NdisDeviceCaps->DeviceCaps.WwanAuthAlgoCaps |= WWAN_AUTH_ALGO_CAPS_AKA; + if( Adapter->AdapterFlags.IsAkapAuthCapable == TRUE ) + NdisDeviceCaps->DeviceCaps.WwanAuthAlgoCaps |= WWAN_AUTH_ALGO_CAPS_AKAPRIME; + if( Adapter->AdapterFlags.IsSimAuthCapable == TRUE ) + NdisDeviceCaps->DeviceCaps.WwanAuthAlgoCaps |= WWAN_AUTH_ALGO_CAPS_SIM; + // + // By default set this flag. When ready info comes later, + // MBCD will send a ReadyInfoFlag indication clearing the flag + // if its not set. The flag is set by default for buggy apps that + // may be caching the device caps. To prevent buggy apps from + // violating ProtectId laws this conservative approach is taken. + // + if( Adapter->AdapterFlags.IsShowIMSI == FALSE ) + NdisDeviceCaps->DeviceCaps.WwanControlCaps |= WWAN_CTRL_CAPS_PROTECT_UNIQUEID; + + NdisDeviceCaps->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceCaps->Header.Size = (USHORT)NdisDeviceCapsSize; + NdisDeviceCaps->Header.Revision = NDIS_WWAN_DEVICE_CAPS_REVISION_2; + NdisDeviceCaps->uStatus = WWAN_STATUS_SUCCESS; + + StatusIndication.StatusBuffer = NdisDeviceCaps; + StatusIndication.StatusBufferSize = NdisDeviceCapsSize; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_CAPS size=%d", Request->RequestId, NdisDeviceCapsSize ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + IndicateFailure = FALSE; + } + while( FALSE ); + + if( IndicateFailure ) + { + RtlZeroMemory( &LocalNdisDeviceCaps, sizeof(LocalNdisDeviceCaps) ); + + LocalNdisDeviceCaps.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisDeviceCaps.Header.Size = sizeof(LocalNdisDeviceCaps); + LocalNdisDeviceCaps.Header.Revision = NDIS_WWAN_DEVICE_CAPS_REVISION_2; + LocalNdisDeviceCaps.uStatus = NdisStatus; + + StatusIndication.StatusBuffer = &LocalNdisDeviceCaps; + StatusIndication.StatusBufferSize = sizeof(LocalNdisDeviceCaps); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to indicate NDIS_STATUS_WWAN_DEVICE_CAPS WwanStatus=%!WwanStatus!", Request->RequestId, NdisStatus ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + } + + if( NdisDeviceCaps != NULL ) + { + FREE_POOL( NdisDeviceCaps ); + } +} + +NDIS_STATUS +MbbNdisDeviceCapsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + PMBB_DEVICE_CAPS MbbDeviceCaps = (PMBB_DEVICE_CAPS)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + ULONG i = 0; + NDIS_WWAN_DEVICE_CAPS LocalNdisDeviceCaps; + PNDIS_WWAN_DEVICE_CAPS NdisDeviceCaps = NULL; + USHORT NdisDeviceCapsSize = (USHORT)sizeof(NDIS_WWAN_DEVICE_CAPS); + BOOL fMultimode = FALSE; + + do + { + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterResetCapabilities( Adapter ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_CAPS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!STATUS!", + Request->RequestId, + WwanStatus + ); + + break; + } + + + if( MbbDeviceCaps == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_DEVICE_CAPS, DataBuffer) ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_DEVICE_CAPS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + (ULONG)FIELD_OFFSET(MBB_DEVICE_CAPS, DataBuffer) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbDeviceCaps->CustomDataClass.Offset, + MbbDeviceCaps->CustomDataClass.Size, + MBB_MAXIMUM_DATA_CLASS_NAME_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] Bad custom data field, Offset=%d, Size=%d", + Request->RequestId, + MbbDeviceCaps->CustomDataClass.Offset, + MbbDeviceCaps->CustomDataClass.Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbDeviceCaps->DeviceIdString.Offset, + MbbDeviceCaps->DeviceIdString.Size, + MBB_MAXIMUM_DEVICE_ID_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] DeviceId data field, Offset=%d, Size=%d", + Request->RequestId, + MbbDeviceCaps->DeviceIdString.Offset, + MbbDeviceCaps->DeviceIdString.Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbDeviceCaps->FirmwareInfo.Offset, + MbbDeviceCaps->FirmwareInfo.Size, + MBB_MAXIMUM_FIRMWARE_INFO_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FirmwareInfo data field, Offset=%d, Size=%d", + Request->RequestId, + MbbDeviceCaps->FirmwareInfo.Offset, + MbbDeviceCaps->FirmwareInfo.Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + MbbAdapterSetSupportedCellularClass( Adapter, MbbDeviceCaps->CellularClass ); + MbbAdapterSetMaxActivatedContexts(Adapter,MbbDeviceCaps->dwMaxSessions); + fMultimode = MbbAdapterIsMultimodeCapable( Adapter ); + + // + // Remember whether this adapter is multi-carrier capable and also the data class. + // This information is used in reporting home and preferred and visible provider. + // + if( MbbDeviceCaps->ControlCaps & MbbControlCapsMultiCarrier ) + MbbAdapterSetMultiCarrierCapable( Adapter, TRUE ); + + MbbAdapterSetDataClass( Adapter, MbbDeviceCaps->DataClass ); + + if(!fMultimode) + { + MbbAdapterSetCurrentCellularClass( Adapter, MbbDeviceCaps->CellularClass ); + } + + // + // If this is an internal request then cache the device id and exit out. + // Internal query is generated from the miniport initialize path to query + // the device id. + // + if( MbbReqMgrIsInternalRequest( Request ) ) + { + MbbUtilPopulateStaticString( + Request->HandlerContext.Parameters.DeviceCaps.DeviceId, + MbbDeviceCaps, + DeviceIdString + ); + // + // If this is a test device the DeviceId may be absent. + // In this case fabricate an IMEI for GSM or ESN for CDMA. + // + if( Request->HandlerContext.Parameters.DeviceCaps.DeviceId[0] == 0 ) + { + if( fMultimode || + MbbDeviceCaps->CellularClass == MbbCellularClassGsm ) + { + RtlStringCbCopyW( + Request->HandlerContext.Parameters.DeviceCaps.DeviceId, + sizeof(Request->HandlerContext.Parameters.DeviceCaps.DeviceId), + MBB_PSEUDO_IMEI + ); + } + else + if( MbbDeviceCaps->CellularClass == MbbCellularClassCdma ) + { + RtlStringCbCopyW( + Request->HandlerContext.Parameters.DeviceCaps.DeviceId, + sizeof(Request->HandlerContext.Parameters.DeviceCaps.DeviceId), + MBB_PSEUDO_ESN + ); + } + else + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to get DeviceId, invalid CellularClass=%!MbbCellularClass!", + Request->RequestId, + MbbDeviceCaps->CellularClass + ); + return NDIS_STATUS_FAILURE; + } + } + return NDIS_STATUS_SUCCESS; + } + + //calculate variable buffer size for multimode devices + if(fMultimode) + { + //for now we support only GSM and CDMA so keep it simple + NdisDeviceCapsSize+= sizeof(WWAN_CELLULAR_CLASS) * (MbbCellularClassMaximum - 1); + } + + if( (NdisDeviceCaps = ALLOCATE_NONPAGED_POOL(NdisDeviceCapsSize)) == NULL ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_WWAN_DEVICE_CAPS", + Request->RequestId, + NdisDeviceCapsSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanDeviceCaps( + MbbDeviceCaps, + Adapter->BusParams.Manufacturer, + MAX_PARAMETER_STRING, + Adapter->BusParams.Model, + MAX_PARAMETER_STRING, + &NdisDeviceCaps->DeviceCaps, + fMultimode + ); + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCaps = NdisDeviceCaps; + Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCapsSize = NdisDeviceCapsSize; + + MbbNdisIndicateDeviceCaps( + Request, + WwanStatus + ); + + return NDIS_STATUS_SUCCESS; +} + +VOID +MbbNdisIndicateReadyInfoFailure( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_READY_INFO LocalNdisReadyInfo; + PMINIPORT_ADAPTER_CONTEXT Adapter; + + + Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle( Request ); + Adapter->AdapterFlags.IsShowIMSI = FALSE; + + RtlZeroMemory( + &LocalNdisReadyInfo, + sizeof(LocalNdisReadyInfo) + ); + + LocalNdisReadyInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisReadyInfo.Header.Size = sizeof(NDIS_WWAN_READY_INFO); + LocalNdisReadyInfo.Header.Revision = NDIS_WWAN_READY_INFO_REVISION_1; + LocalNdisReadyInfo.ReadyInfo.ReadyState = WwanReadyStateFailure; + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_READY_INFO + ); + + StatusIndication.StatusBuffer = &LocalNdisReadyInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_READY_INFO); + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] READY_STATE_FAILURE", Request->RequestId ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); +} + +VOID +MbbNdisIndicateReadyInfo( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + BOOLEAN IndicateReadyInfoFailure = TRUE; + ULONG NdisReadyInfoSize = Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfoSize; + PNDIS_WWAN_READY_INFO NdisReadyInfo = Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo; + + do + { + MBB_COMMAND NewCommand; + PMBB_REQUEST_CONTEXT NewRequest; + + // + // Track whether this is a indication or a response to a query. + // If this is a response to a query readyinfo then ndis indication needs to + // happen on any failure. In case of indications ignore failures. + // + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsFirstCid == 0 ) + { + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsFirstCid = 1; + + if( memcmp( + &Request->HandlerContext.Response.Command.ServiceId, + &MBB_UUID_BASIC_CONNECT, + sizeof(GUID) + ) == 0 + && + Request->HandlerContext.Response.Command.CommandId == MBB_BASIC_CID_SUBSCRIBER_READY_INFO + && + MbbReqMgrIsUnsolicitedIndication( Request ) == FALSE ) + { + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsQueryReadyInfo = 1; + } + } + // + // If the CID response wasnt receieved then bail out. + // + if( NdisStatus != NDIS_STATUS_SUCCESS ) + break; + // + // When switching FW in multi-carrier scenario the device + // indicates readystateoff and then re-enumerates. + // Thus the class driver will fail to query for emergencymode + // and smsconfiguration in this scenario and hence fail to + // indicate readystateoff. To forward the readystateoff + // indication to service fill in defaults on ReadyStateOff. + // + if( NdisReadyInfo != NULL && + WwanReadyStateOff == NdisReadyInfo->ReadyInfo.ReadyState ) + { + if( 0 == Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid ) + { + Request->HandlerContext.Parameters.SubscriberReadyInfo.WwanEmergencyMode = WwanEmergencyModeOff; + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid = 1; + } + + if( 0 == Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid ) + { + Request->HandlerContext.Parameters.SubscriberReadyInfo.CdmaShortMsgSize = WWAN_CDMA_SHORT_MSG_SIZE_UNKNOWN; + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid = 1; + } + } + // + // If we have all the information then indicate ready_info. + // + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo != NULL && + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid != 0 && + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid != 0 ) + { + ULONG ReadyInfoFlags; + PMINIPORT_ADAPTER_CONTEXT Adapter; + NDIS_STATUS_INDICATION StatusIndication; + + // + // Indicate NDIS_STATUS_WWAN_READY_INFO_FLAGS first. + // This is always a status indication. + // + Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle( Request ); + + if( 0 == Adapter->AdapterFlags.IsShowIMSI ) + ReadyInfoFlags = WWAN_CTRL_CAPS_PROTECT_UNIQUEID; + else + ReadyInfoFlags = 0; + + MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION( + &StatusIndication, + Adapter->MiniportAdapterHandle, + NDIS_STATUS_WWAN_RESERVED_2 + ); + StatusIndication.DestinationHandle = NULL; + StatusIndication.RequestId = 0; + StatusIndication.StatusBuffer = &ReadyInfoFlags; + StatusIndication.StatusBufferSize = sizeof(ULONG); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_READY_INFO_FLAGS", Request->RequestId ); + + NdisMIndicateStatusEx( + Adapter->MiniportAdapterHandle, + &StatusIndication + ); + // + // Now indicate NDIS_STATUS_WWAN_READY_INFO + // + NdisReadyInfo->ReadyInfo.EmergencyMode = Request->HandlerContext.Parameters.SubscriberReadyInfo.WwanEmergencyMode; + NdisReadyInfo->ReadyInfo.CdmaShortMsgSize = Request->HandlerContext.Parameters.SubscriberReadyInfo.CdmaShortMsgSize; + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_READY_INFO + ); + + StatusIndication.StatusBuffer = NdisReadyInfo; + StatusIndication.StatusBufferSize = NdisReadyInfoSize; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_READY_INFO size=%d", Request->RequestId, NdisReadyInfoSize ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + IndicateReadyInfoFailure = FALSE; + break; + } + // + // If we dont have any info then only indicate failure if this was a ready_info oid query. + // Fail the request in this case. + // + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo == NULL && + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid == 0 && + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid == 0 ) + { + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsQueryReadyInfo != 1 ) + { + IndicateReadyInfoFailure = FALSE; + } + break; + } + // + // We have something, get the other information. + // Select the next command to query + // + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo == NULL ) + { + NewCommand.ServiceId = MBB_UUID_BASIC_CONNECT; + NewCommand.CommandId = MBB_BASIC_CID_SUBSCRIBER_READY_INFO; + } else + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid == 0 ) + { + NewCommand.ServiceId = MBB_UUID_BASIC_CONNECT; + NewCommand.CommandId = MBB_BASIC_CID_EMERGENCY_MODE; + } else + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid == 0 ) + { + NewCommand.ServiceId = MBB_UUID_SMS; + NewCommand.CommandId = MBB_SMS_CID_CONFIGURATION; + } + + if( (NewRequest = MbbReqMgrCreateRequest( + Request->RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate Request for retrieving %s", + Request->RequestId, + MbbUtilGetCommandString( &NewCommand ) + ); + break; + } + NewRequest->OidHandler = MbbNdisGetOidHandlerByCommand( &NewCommand ); + // + // Cache the context from the previous request since it will be destroyed + // + NewRequest->OidContext.OidRequestId = Request->OidContext.OidRequestId; + NewRequest->OidContext.OidRequestHandle = Request->OidContext.OidRequestHandle; + NewRequest->HandlerContext.Parameters.SubscriberReadyInfo = Request->HandlerContext.Parameters.SubscriberReadyInfo; + // + // Dispatch the new CID request + // + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Dispatching Request[ReqId=0x%04x] for %s", + Request->RequestId, + NewRequest->RequestId, + MbbUtilGetCommandString( &NewCommand ) + ); + NdisStatus = MbbReqMgrDispatchRequest( + NewRequest, + (NewRequest->OidHandler->IsSerialized == 1), + MbbUtilInternalCIDQuery, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If dispatch failed, then indicate ReadyInfoFailure + // + if( NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to dispatch %s, NdisStatus=%!STATUS!", + NewRequest->RequestId, + MbbUtilGetCommandString( &NewCommand ), + NdisStatus + ); + MbbReqMgrDestroyRequest( + NewRequest->RequestManager, + NewRequest + ); + break; + } + // + // The status handler will take care of the rest. + // + NdisReadyInfo = NULL; + IndicateReadyInfoFailure = FALSE; + } + while( FALSE ); + + if( IndicateReadyInfoFailure && + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsQueryReadyInfo == 1 ) + { + MbbNdisIndicateReadyInfoFailure( Request ); + } + + if( NdisReadyInfo != NULL ) + FREE_POOL( NdisReadyInfo ); +} + +NDIS_STATUS +MbbNdisReadyInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + ULONG ElementIndex; + ULONG ElementCount; + ULONGLONG NdisReadyInfoSize = 0; + ULONGLONG MbbReadyInfoSize; + PNDIS_WWAN_READY_INFO NdisReadyInfo = NULL; + PMBB_SUBSCRIBER_READY_INFO MbbReadyInfo = (PMBB_SUBSCRIBER_READY_INFO)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter; + + // + // Extract partial ready_info from the response / indication buffer + // + do + { + Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle( Request ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_READY_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, WwanStatus=%!WwanStatus!. MbbStatus=%!MbbStatus!", + Request->RequestId, + WwanStatus, + MbbStatus + ); + + NdisStatus=WwanStatus; + + break; + } + + + if( MbbReadyInfo == NULL || + InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBER_READY_INFO, TelephoneNumberCount) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_READY_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBER_READY_INFO, TelephoneNumberCount) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + + ElementCount = MbbReadyInfo->TelephoneNumberCount; + + if (ElementCount > MBB_MAX_READY_INFO_PHONE_NUMBERS) + { + TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Too many phone numbers NDIS_STATUS_WWAN_READY_INFO, %d Truncating", + Request->RequestId, + ElementCount + ); + + ElementCount = MBB_MAX_READY_INFO_PHONE_NUMBERS; + } + + + MbbReadyInfoSize = FIELD_OFFSET(MBB_SUBSCRIBER_READY_INFO, TelephoneNumbers) + ((ULONGLONG)ElementCount * sizeof(MBB_STRING)); + NdisReadyInfoSize = sizeof(NDIS_WWAN_READY_INFO) + ((ULONGLONG)ElementCount * WWAN_TN_LEN * sizeof(WCHAR)); + + if( InBufferSize < MbbReadyInfoSize ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_READY_INFO, BufferSize[Received=%d Expected=%I64u] TNCount=%d", + Request->RequestId, + InBufferSize, + MbbReadyInfoSize, + MbbReadyInfo->TelephoneNumberCount + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + +#ifndef MBIM081d + if (MbbReadyInfo->SubscriberId.Size > (MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH) * sizeof(WCHAR)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] truncating SubScriberSize from %d to %d", Request->RequestId, MbbReadyInfo->SubscriberId.Size, (MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH) * sizeof(WCHAR)); + + MbbReadyInfo->SubscriberId.Size=(MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH) * sizeof(WCHAR); + } +#endif + + if( MbbIsVariableFieldValid( + InBufferSize, + MbbReadyInfo->SubscriberId.Offset, + MbbReadyInfo->SubscriberId.Size, + MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH, + sizeof(WCHAR) + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID MBB_SUBSCRIBER_READY_INFO.SubscriberId Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + Request->RequestId, + MbbReadyInfo->SubscriberId.Offset, + InBufferSize, + MbbReadyInfo->SubscriberId.Size, + MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH * sizeof(WCHAR) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + +#ifndef MBIM081d + if (MbbReadyInfo->SimIccId.Size > (MBB_MAXIMUM_SIM_ICC_ID_LENGTH) * sizeof(WCHAR)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] truncating SimIcci from %d to %d", Request->RequestId, MbbReadyInfo->SimIccId.Size, (MBB_MAXIMUM_SIM_ICC_ID_LENGTH) * sizeof(WCHAR)); + + MbbReadyInfo->SimIccId.Size=(MBB_MAXIMUM_SIM_ICC_ID_LENGTH) * sizeof(WCHAR); + } +#endif + + if( MbbIsVariableFieldValid( + InBufferSize, + MbbReadyInfo->SimIccId.Offset, + MbbReadyInfo->SimIccId.Size, + MBB_MAXIMUM_SIM_ICC_ID_LENGTH, + sizeof(WCHAR) + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID MBB_SUBSCRIBER_READY_INFO.SimIccId Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + Request->RequestId, + MbbReadyInfo->SimIccId.Offset, + InBufferSize, + MbbReadyInfo->SimIccId.Size, + MBB_MAXIMUM_SIM_ICC_ID_LENGTH * sizeof(WCHAR) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + for( ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex ++ ) + { + ULONG TelNumLen = Adapter->BusParams.IsErrataDevice ? MBB_MAXIMUM_TELEPHONE_NUMBER_ERRATA_LENGTH : MBB_MAXIMUM_TELEPHONE_NUMBER_LENGTH; + + if( MbbIsVariableFieldValid( + InBufferSize, + MbbReadyInfo->TelephoneNumbers[ElementIndex].Offset, + MbbReadyInfo->TelephoneNumbers[ElementIndex].Size, + TelNumLen, + sizeof(WCHAR) + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID MBB_SUBSCRIBER_READY_INFO.TelephoneNumber[%d] Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + Request->RequestId, + ElementIndex, + MbbReadyInfo->TelephoneNumbers[ElementIndex].Offset, + InBufferSize, + MbbReadyInfo->TelephoneNumbers[ElementIndex].Size, + TelNumLen * sizeof(WCHAR) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + } + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + break; + } + + if( (NdisReadyInfo = ALLOCATE_NONPAGED_POOL( (SIZE_T)NdisReadyInfoSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %I64u bytes for NDIS_STATUS_WWAN_READY_INFO, TNCount=%d", + Request->RequestId, + NdisReadyInfoSize, + MbbReadyInfo->TelephoneNumberCount + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + NdisReadyInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisReadyInfo->Header.Size = sizeof(NDIS_WWAN_READY_INFO); + NdisReadyInfo->Header.Revision = NDIS_WWAN_READY_INFO_REVISION_1; + + Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfoSize = (ULONG)NdisReadyInfoSize; + Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo = NdisReadyInfo; + + MbbUtilMbbToWwanReadyInfo( + MbbReadyInfo, + &NdisReadyInfo->ReadyInfo + ); + + if( ( + MbbReadyInfo->ReadyState == MbbReadyStateInitialized || + MbbReadyInfo->ReadyState == MbbReadyStateNotActivated || + MbbReadyInfo->ReadyState == MbbReadyStateDeviceLocked + ) && + ! ( MbbReadyInfo->ReadyInfoFlags & MbbReadyInfoFlagsUniqueId ) ) + { + Adapter->AdapterFlags.IsShowIMSI = TRUE; + } + else + { + Adapter->AdapterFlags.IsShowIMSI = FALSE; + } + } + while( FALSE ); + + MbbNdisIndicateReadyInfo( + Request, + NdisStatus + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisEmergencyModeStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +/*++ + Description: + This routine does not do a NDIS indication for a CID indication + because there is no EMERGENCY_MODE ndis indication. EmergencyMode + is indicated via ReadyInfo. This routine instead does a ReadyInfo + indication. To do so this routine will query ReadyInfo and SmsConfiguration. +--*/ +{ + MBB_EMERGENCY_MODE* MbbEmergencyMode = (MBB_EMERGENCY_MODE*)InBuffer; + + do + { + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for MBB_BASIC_CID_EMERGENCY_MODE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + if( MbbStatus != MBB_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for MBB_BASIC_CID_EMERGENCY_MODE, status=%!MbbStatus!", + Request->RequestId, + MbbStatus + ); + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + + if( MbbEmergencyMode == NULL || + InBufferSize < sizeof(MBB_EMERGENCY_MODE) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_BASIC_CID_EMERGENCY_MODE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_EMERGENCY_MODE) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] EMERGENCY_MODE=%d indication received", + Request->RequestId, + *MbbEmergencyMode + ); + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid = 1; + Request->HandlerContext.Parameters.SubscriberReadyInfo.WwanEmergencyMode = (WWAN_EMERGENCY_MODE)*MbbEmergencyMode; + } + while( FALSE ); + // + // Internal requests are created for indicating ready info. + // Do not fail ready info if emergency mode cannot be queried. + // + if( MbbReqMgrIsInternalRequest( Request ) == TRUE || + NdisStatus != NDIS_STATUS_SUCCESS ) + { + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid = 1; + Request->HandlerContext.Parameters.SubscriberReadyInfo.WwanEmergencyMode = WwanEmergencyModeOff; + NdisStatus = NDIS_STATUS_SUCCESS; + } + + MbbNdisIndicateReadyInfo( + Request, + NdisStatus + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisRadioStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS HandlerNdisStatus = NDIS_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_RADIO_STATE NdisRadioState; + PMBB_QUERY_RADIO_STATE MbbRadioState = (PMBB_QUERY_RADIO_STATE)InBuffer; + NDIS_STRING RadioOffRegString = RTL_CONSTANT_STRING(MBB_REGVAL_RADIO_OFF); + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + + do + { + RtlZeroMemory(&NdisRadioState, sizeof(NdisRadioState)); + + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_RADIO_STATE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!STATUS!", + Request->RequestId, + WwanStatus + ); + + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + + if( MbbRadioState == NULL || + InBufferSize < sizeof(MBB_QUERY_RADIO_STATE) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_RADIO_STATE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_QUERY_RADIO_STATE) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MBIM radio state hw=%d, sw=%d", + Request->RequestId, + MbbRadioState->HwRadioState, + MbbRadioState->SwRadioState + ); + + + // + // We will be sending the radio state notification up. + // If this is a set requested by the OS and the request + // succeeded, persist the radio state in registry and locally + // + if ((Request->OidContext.OidRequestId != 0) && + (MbbReqMgrIsSetOid( Request )) && + (WwanStatus == WWAN_STATUS_SUCCESS) ) + { + // + // OS initiated SET request that succeeded. The set action + // was saved in the Parameters portion of the request. + // Persist it + // + if (Request->HandlerContext.Parameters.RadioState.SetAction == WwanRadioOff) + { + // Radio OFF was requested & has successfully completed + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Persisting RadioState OFF", + Request->RequestId + ); + Request->RequestManager->AdapterContext->RadioOff = TRUE; + } + else + { + // Radio ON was requested & has successfully completed + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Persisting RadioState ON", + Request->RequestId + ); + Request->RequestManager->AdapterContext->RadioOff = FALSE; + } + + HandlerNdisStatus = MbbNdisAdapterWriteBoolParameter( + Adapter, + Adapter->RadioOff, + &RadioOffRegString + ); + if (HandlerNdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Failed to persist Radio state in registry, status=%!STATUS!", + Request->RequestId, + HandlerNdisStatus + ); + // We still indicate the current radio state to the OS + } + + } + + MbbUtilMbbToWwanRadioState( + &MbbRadioState->HwRadioState, + &NdisRadioState.RadioState.HwRadioState + ); + + MbbUtilMbbToWwanRadioState( + &MbbRadioState->SwRadioState, + &NdisRadioState.RadioState.SwRadioState + ); + } + while( FALSE ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceLoggingWrite( + g_hLoggingProvider, + "RadioStateFailure", + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + PMBB_SEND_QUEUE SendQueue = &((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request))->SendQueue; + TryQueueStallState(SendQueue); + } + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if( MbbReqMgrIsInternalRequest( Request ) == FALSE || + ( + MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE && + NdisStatus == NDIS_STATUS_SUCCESS + ) ) + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_RADIO_STATE + ); + + NdisRadioState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisRadioState.Header.Size = sizeof(NDIS_WWAN_RADIO_STATE); + NdisRadioState.Header.Revision = NDIS_WWAN_RADIO_STATE_REVISION_1; + NdisRadioState.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisRadioState; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_RADIO_STATE); + + if ((Request->RequestManager->AdapterContext->RadioOff && (NdisRadioState.RadioState.SwRadioState != WwanRadioOff)) + || + (!Request->RequestManager->AdapterContext->RadioOff && (NdisRadioState.RadioState.SwRadioState != WwanRadioOn))) + { + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] reported radio state does not match it was configured to. config=%!BOOLEAN!, reported=%d", + Request->RequestId, + Request->RequestManager->AdapterContext->RadioOff, + NdisRadioState.RadioState.SwRadioState + ); + } + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_RADIO_STATE SwState=%u with status=%!WwanStatus!", + Request->RequestId, + NdisRadioState.RadioState.SwRadioState, + WwanStatus + ); + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + } + // + // If this request was submitted internally during adapter init + // then check if the radio state is set correctly. + // NOTE: Assumption that only adapter init path submits internal radio state request. + // + if( MbbReqMgrIsInternalRequest( Request ) == TRUE && + NdisStatus == NDIS_STATUS_SUCCESS ) + { + // Check if we are in the right state now + if (Adapter->RadioOff) + { + // We configured Software Radio OFF + if (MbbRadioState->SwRadioState != MbbRadioStateOff) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] Invalid radio state after ConfigureRadioState, Received ON Expected OFF"); + HandlerNdisStatus = NDIS_STATUS_INVALID_STATE; + } + } + else + { + // We configured Software Radio ON + if (MbbRadioState->SwRadioState != MbbRadioStateOn) + { + TraceError( WMBCLASS_INIT, "[MbbAdapter] Invalid radio state after ConfigureRadioState, Received OFF Expected ON"); + HandlerNdisStatus = NDIS_STATUS_INVALID_STATE; + } + } + } + + return HandlerNdisStatus; +} + +NDIS_STATUS +MbbNdisPinInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_PIN_INFO NdisPinInfo; + PMBB_PIN_INFO MbbPinInfo = (PMBB_PIN_INFO)InBuffer; + + do + { + RtlZeroMemory(&NdisPinInfo, sizeof(NdisPinInfo)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PIN_INFO + ); + + NdisPinInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisPinInfo.Header.Size = sizeof(NDIS_WWAN_PIN_INFO); + NdisPinInfo.Header.Revision = NDIS_WWAN_PIN_INFO_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PIN_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + + if( MbbPinInfo == NULL || + InBufferSize < sizeof(MBB_PIN_INFO) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PIN_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_PIN_INFO) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanPinInfo( + MbbPinInfo, + &NdisPinInfo.PinInfo + ); + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisPinInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisPinInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PIN_INFO); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PIN_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisPinListStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_PIN_LIST NdisPinList; + PMBB_PIN_LIST MbbPinList = (PMBB_PIN_LIST)InBuffer; + + do + { + RtlZeroMemory(&NdisPinList, sizeof(NdisPinList)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PIN_LIST + ); + + NdisPinList.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisPinList.Header.Size = sizeof(NDIS_WWAN_PIN_LIST); + NdisPinList.Header.Revision = NDIS_WWAN_PIN_LIST_REVISION_1; + NdisPinList.uStatus = NdisStatus; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PIN_LIST, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!STATUS!", + Request->RequestId, + WwanStatus + ); + + break; + } + + + if( MbbPinList == NULL || + InBufferSize < sizeof(MBB_PIN_LIST) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PIN_LIST, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_PIN_DESCRIPTION) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanPinList( + MbbPinList, + &NdisPinList.PinList + ); + } while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisPinList.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisPinList; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PIN_LIST); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PIN_LIST with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisHomeProviderStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_WWAN_HOME_PROVIDER2 NdisHomeProvider2; + NDIS_STATUS_INDICATION StatusIndication; + PMBB_PROVIDER MbbProvider = (PMBB_PROVIDER)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); + BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); + ULONG AdapterDataClass; + + do + { + RtlZeroMemory(&NdisHomeProvider2, sizeof(NdisHomeProvider2)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + MbbReqMgrIsSetOid( Request )? NDIS_STATUS_WWAN_SET_HOME_PROVIDER_COMPLETE : NDIS_STATUS_WWAN_HOME_PROVIDER + ); + + NdisHomeProvider2.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisHomeProvider2.Header.Size = sizeof(NDIS_WWAN_HOME_PROVIDER2); + NdisHomeProvider2.Header.Revision = NDIS_WWAN_HOME_PROVIDER_REVISION_2; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_HOME_PROVIDER, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!STATUS!", + Request->RequestId, + WwanStatus + ); + break; + } + + if( MbbUtilValidateMbbProvider( + InBufferSize, + MbbProvider + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to validate data for NDIS_STATUS_WWAN_HOME_PROVIDER", + Request->RequestId + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbAdapterGetDataClass( Adapter, &AdapterDataClass ); + + MbbUtilMbbToWwanProvider2( + MbbProvider, + AdapterDataClass, + &NdisHomeProvider2.Provider + ); + } + while( FALSE); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisHomeProvider2.uStatus = WwanStatus; + StatusIndication.StatusBuffer = &NdisHomeProvider2; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_HOME_PROVIDER2); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_HOME_PROVIDER for %s-carrier with status=%!WwanStatus!", + Request->RequestId, + IsMultiCarrierCapable? "Multi": "Single", + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisPreferredProviderStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + ULONG AdapterDataClass; + PMBB_PROVIDER_LIST MbbPreferredProviders = (PMBB_PROVIDER_LIST)InBuffer; + NDIS_STATUS_INDICATION StatusIndication; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); + BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); + ULONGLONG NdisPreferredProvidersSize = 0; + PNDIS_WWAN_PREFERRED_PROVIDERS NdisPreferredProviders = NULL; + NDIS_WWAN_PREFERRED_PROVIDERS LocalNdisPreferredProviders; + ULONG MulTemp = 0; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + RtlZeroMemory(&LocalNdisPreferredProviders, sizeof(LocalNdisPreferredProviders)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PREFERRED_PROVIDERS + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PREFERRED_PROVIDERS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + // + // On error there is no data buffer. + // + if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + break; + } + // + // On set requests the MB Driver Model requires that the preferred provider list is empty. + // + if( MbbReqMgrIsSetOid( Request ) == TRUE ) + { + break; + } + // + // Validate the received data and every provider structure in the list. + // + if( MbbUtilValidateMbbProviderList( + InBufferSize, + MbbPreferredProviders + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to validate MBB_PROVIDER_LIST", + Request->RequestId + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + // + // Convert the provider_list to the WWAN format. + // + if (MbbPreferredProviders->ProviderCount > MBB_MAX_PROVIDER_LIST_SIZE) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Provider count exceeds max, MbbPreferredProviders->ProviderCount=%d", + Request->RequestId, + MbbPreferredProviders->ProviderCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + + NtStatus = RtlULongMult( + MbbPreferredProviders->ProviderCount, + sizeof(WWAN_PROVIDER2), + &MulTemp + ); + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbPreferredProviders->ProviderCount=%d WWAN_PROVIDER2 size=%d", + Request->RequestId, + MbbPreferredProviders->ProviderCount, + sizeof(WWAN_PROVIDER2) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisPreferredProvidersSize = sizeof(NDIS_WWAN_PREFERRED_PROVIDERS); + NdisPreferredProvidersSize += MulTemp; + + if( NdisPreferredProvidersSize > ULONG_MAX || + (NdisPreferredProviders = (PNDIS_WWAN_PREFERRED_PROVIDERS)ALLOCATE_NONPAGED_POOL( (ULONG)NdisPreferredProvidersSize ) ) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_PREFERRED_PROVIDERS, ProviderCount=%d", + Request->RequestId, + (ULONG)NdisPreferredProvidersSize, + MbbPreferredProviders->ProviderCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisPreferredProviders->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisPreferredProviders->Header.Size = sizeof(NDIS_WWAN_PREFERRED_PROVIDERS); + NdisPreferredProviders->Header.Revision = NDIS_WWAN_PREFERRED_PROVIDERS_REVISION_1; + + MbbAdapterGetDataClass( Adapter, &AdapterDataClass ); + + MbbUtilMbbToWwanProviderList( + MbbPreferredProviders, + AdapterDataClass, + IsMultiCarrierCapable, + &NdisPreferredProviders->PreferredListHeader + ); + } + while( FALSE ); + + if( NdisPreferredProviders == NULL ) + { + LocalNdisPreferredProviders.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisPreferredProviders.Header.Size = sizeof(NDIS_WWAN_PREFERRED_PROVIDERS); + LocalNdisPreferredProviders.Header.Revision = NDIS_WWAN_PREFERRED_PROVIDERS_REVISION_1; + + LocalNdisPreferredProviders.PreferredListHeader.ElementCount = 0; + LocalNdisPreferredProviders.PreferredListHeader.ElementType = WwanStructProvider2; + + StatusIndication.StatusBuffer = &LocalNdisPreferredProviders; + StatusIndication.StatusBufferSize = sizeof(LocalNdisPreferredProviders); + } + else + { + StatusIndication.StatusBuffer = NdisPreferredProviders; + StatusIndication.StatusBufferSize = (ULONG)NdisPreferredProvidersSize; + } + ((PNDIS_WWAN_PREFERRED_PROVIDERS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PREFERRED_PROVIDERS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if( NdisPreferredProviders != NULL ) + FREE_POOL( NdisPreferredProviders ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisVisibleProviderStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + ULONG AdapterDataClass; + PMBB_PROVIDER_LIST MbbVisibleProviders = (PMBB_PROVIDER_LIST)InBuffer; + NDIS_STATUS_INDICATION StatusIndication; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); + BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); + ULONGLONG NdisVisibleProvidersSize = 0; + PNDIS_WWAN_VISIBLE_PROVIDERS NdisVisibleProviders = NULL; + NDIS_WWAN_VISIBLE_PROVIDERS LocalNdisVisibleProviders; + ULONG MulTemp = 0; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + RtlZeroMemory(&LocalNdisVisibleProviders, sizeof(LocalNdisVisibleProviders)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_VISIBLE_PROVIDERS + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_VISIBLE_PROVIDERS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + // + // On error there is no data buffer. + // + if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + break; + } + // + // Validate the received data and every provider structure in the list. + // + if( MbbUtilValidateMbbProviderList( + InBufferSize, + MbbVisibleProviders + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to validate MBB_PROVIDER_LIST", + Request->RequestId + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // + // Convert the provider_list to the WWAN format. + // + if (MbbVisibleProviders->ProviderCount > MBB_MAX_PROVIDER_LIST_SIZE) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Provider count exceeds max, MbbPreferredProviders->ProviderCount=%d", + Request->RequestId, + MbbVisibleProviders->ProviderCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + + // + // Convert the provider_list to the WWAN format. + // + NtStatus = RtlULongMult( + MbbVisibleProviders->ProviderCount, + sizeof(WWAN_PROVIDER2), + &MulTemp + ); + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbVisibleProviders->ProviderCount=%d WWAN_PROVIDER2 size=%d", + Request->RequestId, + MbbVisibleProviders->ProviderCount, + sizeof(WWAN_PROVIDER2) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisVisibleProvidersSize = sizeof(NDIS_WWAN_VISIBLE_PROVIDERS); + NdisVisibleProvidersSize += MulTemp; + + if( NdisVisibleProvidersSize > ULONG_MAX || + (NdisVisibleProviders = (PNDIS_WWAN_VISIBLE_PROVIDERS)ALLOCATE_NONPAGED_POOL( (ULONG)NdisVisibleProvidersSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_VISIBLE_PROVIDERS, ProviderCount=%d", + Request->RequestId, + (ULONG)NdisVisibleProvidersSize, + MbbVisibleProviders->ProviderCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisVisibleProviders->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisVisibleProviders->Header.Size = sizeof(NDIS_WWAN_VISIBLE_PROVIDERS); + NdisVisibleProviders->Header.Revision = NDIS_WWAN_VISIBLE_PROVIDERS_REVISION_1; + + MbbAdapterGetDataClass( Adapter, &AdapterDataClass ); + + MbbUtilMbbToWwanProviderList( + MbbVisibleProviders, + AdapterDataClass, + IsMultiCarrierCapable, + &NdisVisibleProviders->VisibleListHeader + ); + } + while( FALSE ); + + if( NdisVisibleProviders == NULL ) + { + LocalNdisVisibleProviders.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisVisibleProviders.Header.Size = sizeof(NDIS_WWAN_VISIBLE_PROVIDERS); + LocalNdisVisibleProviders.Header.Revision = NDIS_WWAN_VISIBLE_PROVIDERS_REVISION_1; + + LocalNdisVisibleProviders.VisibleListHeader.ElementCount = 0; + LocalNdisVisibleProviders.VisibleListHeader.ElementType = WwanStructProvider2; + + StatusIndication.StatusBuffer = &LocalNdisVisibleProviders; + StatusIndication.StatusBufferSize = sizeof(LocalNdisVisibleProviders); + } + else + { + StatusIndication.StatusBuffer = NdisVisibleProviders; + StatusIndication.StatusBufferSize = (ULONG)NdisVisibleProvidersSize; + } + ((PNDIS_WWAN_VISIBLE_PROVIDERS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_VISIBLE_PROVIDERS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if( NdisVisibleProviders != NULL ) + FREE_POOL( NdisVisibleProviders ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisRegisterStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_REGISTRATION_STATE NdisRegistrationState; + PMBB_REGISTRATION_STATE MbbRegistrationState = (PMBB_REGISTRATION_STATE)InBuffer; + + do + { + RtlZeroMemory(&NdisRegistrationState,sizeof(NdisRegistrationState)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_REGISTER_STATE + ); + + NdisRegistrationState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisRegistrationState.Header.Size = sizeof(NDIS_WWAN_REGISTRATION_STATE); + NdisRegistrationState.Header.Revision = NDIS_WWAN_REGISTRATION_STATE_REVISION_2; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_REGISTER_STATE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + + if( MbbRegistrationState == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_REGISTRATION_STATE, DataBuffer) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_REGISTER_STATE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_REGISTRATION_STATE) + ); + WwanStatus = WWAN_STATUS_FAILURE; + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + // + // pick this up now so we can return it in the case of an error + // + NdisRegistrationState.RegistrationState.uNwError=MbbRegistrationState->NetworkError; + + if ( WwanStatus != WWAN_STATUS_SUCCESS ) + { + NdisStatus = NDIS_STATUS_FAILURE; + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad status for NDIS_STATUS_WWAN_REGISTER_STATE, mbbstatus=%!MbbStatus!", + Request->RequestId, + MbbStatus + ); + + break; + } + + + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbRegistrationState->ProviderId.Offset, + MbbRegistrationState->ProviderId.Size, + MBB_MAXIMUM_PROVIDER_ID_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad provider id field, Offset=%d, Size=%d", + Request->RequestId, + MbbRegistrationState->ProviderId.Offset, + MbbRegistrationState->ProviderId.Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + + } + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbRegistrationState->ProviderName.Offset, + MbbRegistrationState->ProviderName.Size, + MBB_MAXIMUM_PROVIDER_NAME_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad provider Name field, Offset=%d, Size=%d", + Request->RequestId, + MbbRegistrationState->ProviderName.Offset, + MbbRegistrationState->ProviderName.Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + + } + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbRegistrationState->RoamingText.Offset, + MbbRegistrationState->RoamingText.Size, + MBB_MAXIMUM_ROAMING_TEXT_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad provider roaming text, Offset=%d, Size=%d", + Request->RequestId, + MbbRegistrationState->RoamingText.Offset, + MbbRegistrationState->RoamingText.Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + + } + + if( ( + MBB_IS_DEVICE_REGISTERED( MbbRegistrationState->RegisterState ) && + MbbRegistrationState->CurrentCellularClass == MbbCellularClassInvalid + ) || + MbbRegistrationState->CurrentCellularClass >= MbbCellularClassMaximum ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID CurrentCellularClass=0x%x", + Request->RequestId, + MbbRegistrationState->CurrentCellularClass + ); + WwanStatus = WWAN_STATUS_FAILURE; + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + MbbUtilMbbToWwanRegistrationState( + MbbRegistrationState, + &NdisRegistrationState.RegistrationState + ); + + Adapter->AvailableDataClassValid=TRUE; + Adapter->AvailableDataClass=MbbRegistrationState->AvailableDataClasses; + + MbbAdapterSetCurrentCellularClass(Adapter, MbbRegistrationState->CurrentCellularClass); + } + while( FALSE ); + + // + // When to do SMS Configuration indication - + // - This is a response to a OID query + // - This is an unsolicited indication + // When to do Ready Info indication - + // - This is a response to an internal query + // - This is an unsolicited indication + // + + + + if (!MbbReqMgrIsInternalRequest( Request ) || MbbReqMgrIsUnsolicitedIndication( Request )) + { + + // + // Not an internal request, external reaponse or indication + // + if (!MbbReqMgrIsUnsolicitedIndication( Request ) || (NdisStatus == NDIS_STATUS_SUCCESS)) + { + + // + // response or it is an unsolicited indication the was processed without error, + // don't propagate indication that don't parse + // + + NdisRegistrationState.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisRegistrationState; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_REGISTRATION_STATE); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_REGISTER_STATE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + } + } + + if( MbbReqMgrIsInternalRequest( Request ) || + ( + ( NdisStatus == NDIS_STATUS_SUCCESS ) && + MBB_IS_DEVICE_REGISTERED( MbbRegistrationState->RegisterState ) + ) ) + { + // + // it is an internal request which needs to be complete regardless, or it external or unsolictied indication that succeeded + // and is in a registered state. + // run the packet service locic to send a packet service with updated data classes. + // + + Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid = 1; + Request->HandlerContext.Parameters.PacketServiceState.AvailableDataClass = WWAN_DATA_CLASS_NONE; + + if( NdisStatus == NDIS_STATUS_SUCCESS ) + { + Request->HandlerContext.Parameters.PacketServiceState.AvailableDataClass = MbbRegistrationState->AvailableDataClasses; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Saving AvailableDataClass %08lx for Packet Service in registerstate=%d", + Request->RequestId, + MbbRegistrationState->AvailableDataClasses, + MbbRegistrationState->RegisterState + ); + + + } + + + MbbNdisIndicatePacketService( + Request, + NdisStatus + ); + + } + + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisMulticarrierProviderStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + ULONG AdapterDataClass; + PMBB_PROVIDER_LIST MbbPreferredProviders = (PMBB_PROVIDER_LIST)InBuffer; + NDIS_STATUS_INDICATION StatusIndication; + PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); + BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); + ULONGLONG NdisPreferredProvidersSize = 0; + + PNDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS NdisPreferredProviders = NULL; + NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS LocalNdisPreferredProviders; + + do + { + RtlZeroMemory(&LocalNdisPreferredProviders, sizeof(LocalNdisPreferredProviders)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, + "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + // + // On error there is no data buffer. + // + if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) + { + break; + } + // + // On set requests the MB Driver Model requires that the preferred provider list is empty. + // + if( MbbReqMgrIsSetOid( Request ) == TRUE ) + { + break; + } + + if(!IsMultiCarrierCapable) + { + break; + } + + // + // Validate the received data and every provider structure in the list. + // + if( MbbUtilValidateMbbProviderList( + InBufferSize, + MbbPreferredProviders + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to validate MBB_PROVIDER_LIST", + Request->RequestId + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // + // Convert the provider_list to the WWAN format. + // + if (MbbPreferredProviders->ProviderCount > MBB_MAX_PROVIDER_LIST_SIZE) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Provider count exceeds max, MbbPreferredProviders->ProviderCount=%d", + Request->RequestId, + MbbPreferredProviders->ProviderCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + // + // Convert the provider_list to the WWAN format. + // + NdisPreferredProvidersSize = sizeof(NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS); + NdisPreferredProvidersSize += ( (ULONGLONG)MbbPreferredProviders->ProviderCount * sizeof(WWAN_PROVIDER2) ); + + if( NdisPreferredProvidersSize > ULONG_MAX || + (NdisPreferredProviders = (PNDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS)ALLOCATE_NONPAGED_POOL( (ULONG)NdisPreferredProvidersSize ) ) == NULL ) + { + TraceError( WMBCLASS_OID, + "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS, ProviderCount=%d", + Request->RequestId, + (ULONG)NdisPreferredProvidersSize, + MbbPreferredProviders->ProviderCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisPreferredProviders->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisPreferredProviders->Header.Size = sizeof(NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS); + NdisPreferredProviders->Header.Revision = NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS_REVISION_1; + + MbbAdapterGetDataClass( Adapter, &AdapterDataClass ); + + MbbUtilMbbToWwanProviderList( + MbbPreferredProviders, + AdapterDataClass, + TRUE, + &NdisPreferredProviders->PreferredListHeader + ); + } + while( FALSE ); + + if( NdisPreferredProviders == NULL ) + { + LocalNdisPreferredProviders.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisPreferredProviders.Header.Size = sizeof(NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS); + LocalNdisPreferredProviders.Header.Revision = NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS_REVISION_1; + + LocalNdisPreferredProviders.PreferredListHeader.ElementCount = 0; + LocalNdisPreferredProviders.PreferredListHeader.ElementType = WwanStructProvider2; + + StatusIndication.StatusBuffer = &LocalNdisPreferredProviders; + StatusIndication.StatusBufferSize = sizeof(LocalNdisPreferredProviders); + } + else + { + StatusIndication.StatusBuffer = NdisPreferredProviders; + StatusIndication.StatusBufferSize = (ULONG)NdisPreferredProvidersSize; + } + ((PNDIS_WWAN_PREFERRED_PROVIDERS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if( NdisPreferredProviders != NULL ) + FREE_POOL( NdisPreferredProviders ); + + return NDIS_STATUS_SUCCESS; +} + +VOID +MbbNdisIndicatePacketServiceFailure( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS Status + ) +{ + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_PACKET_SERVICE_STATE LocalNdisPacketService; + + RtlZeroMemory( + &LocalNdisPacketService, + sizeof(LocalNdisPacketService) + ); + + LocalNdisPacketService.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisPacketService.Header.Size = sizeof(NDIS_WWAN_PACKET_SERVICE_STATE); + LocalNdisPacketService.Header.Revision = NDIS_WWAN_PACKET_SERVICE_STATE_REVISION_1; + + LocalNdisPacketService.uStatus=Status; + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PACKET_SERVICE + ); + + StatusIndication.StatusBuffer = &LocalNdisPacketService; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PACKET_SERVICE_STATE); + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] PACKET_SERVICE_FAILURE", Request->RequestId ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); +} + +VOID +MbbNdisIndicatePacketService( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + + BOOLEAN IndicateFailure = TRUE; + ULONG NdisPacketServiceStateSize = Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceStateSize; + PNDIS_WWAN_PACKET_SERVICE_STATE NdisPacketServiceState = Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState; + + do + { + MBB_COMMAND NewCommand; + PMBB_REQUEST_CONTEXT NewRequest; + + // + // Track whether this is a indication or a response to a query. + // If this is a response to a query readyinfo then ndis indication needs to + // happen on any failure. In case of indications ignore failures. + // + if( Request->HandlerContext.Parameters.PacketServiceState.IsFirstCid == 0 ) + { + Request->HandlerContext.Parameters.PacketServiceState.IsFirstCid = 1; + + if( memcmp( + &Request->HandlerContext.Response.Command.ServiceId, + &MBB_UUID_BASIC_CONNECT, + sizeof(GUID) + ) == 0 + && + Request->HandlerContext.Response.Command.CommandId == MBB_BASIC_CID_PACKET_SERVICE + && + !MbbReqMgrIsUnsolicitedIndication( Request ) ) + { + Request->HandlerContext.Parameters.PacketServiceState.IsQuery = 1; + } + } + + // + // If the CID response wasnt receieved then bail out. + // + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + break; + } + + // + // If we have all the information then indicate ready_info. + // + if( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState != NULL && + Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid != 0 ) + { + NDIS_STATUS_INDICATION StatusIndication; + + NdisPacketServiceState->PacketService.AvailableDataClass = Request->HandlerContext.Parameters.PacketServiceState.AvailableDataClass; + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PACKET_SERVICE + ); + + StatusIndication.StatusBuffer = NdisPacketServiceState; + StatusIndication.StatusBufferSize = NdisPacketServiceStateSize; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PACKET_SERVICE size=%d", Request->RequestId, NdisPacketServiceStateSize ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + IndicateFailure = FALSE; + break; + } + // + // If we dont have any info then only indicate failure if this was a ready_info oid query. + // Fail the request in this case. + // + if( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState == NULL && + Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid == 0 ) + { + if( Request->HandlerContext.Parameters.PacketServiceState.IsQuery != 1 ) + { + IndicateFailure = FALSE; + } + break; + } + // + // We have something, get the other information. + // Select the next command to query + // + if( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState == NULL ) + { + NewCommand.ServiceId = MBB_UUID_BASIC_CONNECT; + NewCommand.CommandId = MBB_BASIC_CID_PACKET_SERVICE; + } else + if( Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid == 0 ) + { + NewCommand.ServiceId = MBB_UUID_BASIC_CONNECT; + NewCommand.CommandId = MBB_BASIC_CID_REGISTER_STATE; + } + + if( (NewRequest = MbbReqMgrCreateRequest( + Request->RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate Request for retrieving %s", + Request->RequestId, + MbbUtilGetCommandString( &NewCommand ) + ); + break; + } + NewRequest->OidHandler = MbbNdisGetOidHandlerByCommand( &NewCommand ); + // + // Cache the context from the previous request since it will be destroyed + // + if (Request->HandlerContext.Parameters.PacketServiceState.IsQuery) + { + // + // if this is the packet service query, save this since the context will be destroyed + // + NewRequest->OidContext.OidRequestId = Request->OidContext.OidRequestId; + NewRequest->OidContext.OidRequestHandle = Request->OidContext.OidRequestHandle; + } + + NewRequest->HandlerContext.Parameters.PacketServiceState = Request->HandlerContext.Parameters.PacketServiceState; + // + // Dispatch the new CID request + // + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Dispatching Request[ReqId=0x%04x] for %s", + Request->RequestId, + NewRequest->RequestId, + MbbUtilGetCommandString( &NewCommand ) + ); + + NdisStatus = MbbReqMgrDispatchRequest( + NewRequest, + (NewRequest->OidHandler->IsSerialized == 1), + MbbUtilInternalCIDQuery, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + // + // If dispatch failed, then indicate ReadyInfoFailure + // + if( NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to dispatch %s, NdisStatus=%!STATUS!", + NewRequest->RequestId, + MbbUtilGetCommandString( &NewCommand ), + NdisStatus + ); + MbbReqMgrDestroyRequest( + NewRequest->RequestManager, + NewRequest + ); + break; + } + // + // The status handler will take care of the rest. + // + NdisPacketServiceState = NULL; + IndicateFailure = FALSE; + } + while( FALSE ); + + if( IndicateFailure && + Request->HandlerContext.Parameters.PacketServiceState.IsQuery == 1 ) + { + MbbNdisIndicatePacketServiceFailure( Request , NdisStatus); + } + + if( NdisPacketServiceState != NULL ) + { + FREE_POOL( NdisPacketServiceState ); + } +} + +NDIS_STATUS +MbbNdisPacketServiceStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + PNDIS_WWAN_PACKET_SERVICE_STATE NdisPacketServiceState=NULL; + PMBB_PACKET_SERVICE MbbPacketService = (PMBB_PACKET_SERVICE)InBuffer; + + + do + { + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PACKET_SERVICE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + if( MbbPacketService == NULL || (InBufferSize < sizeof(MBB_PACKET_SERVICE) ) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PACKET_SERVICE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_PACKET_SERVICE) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + NdisPacketServiceState =(PNDIS_WWAN_PACKET_SERVICE_STATE) ALLOCATE_NONPAGED_POOL(sizeof(*NdisPacketServiceState)); + + if (NdisPacketServiceState == NULL) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate ndis structure", + Request->RequestId + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + RtlZeroMemory(NdisPacketServiceState, sizeof(*NdisPacketServiceState)); + + NdisPacketServiceState->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisPacketServiceState->Header.Size = sizeof(NDIS_WWAN_PACKET_SERVICE_STATE); + NdisPacketServiceState->Header.Revision = NDIS_WWAN_PACKET_SERVICE_STATE_REVISION_1; + + Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceStateSize=sizeof(*NdisPacketServiceState); + Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState=NdisPacketServiceState; + + + NdisPacketServiceState->PacketService.uNwError = MbbPacketService->NetworkError; + + NdisPacketServiceState->uStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if ( MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + break; + } + + MbbUtilMbbToWwanPacketService( + MbbPacketService, + &NdisPacketServiceState->PacketService + ); + + Adapter->UplinkSpeed = MbbPacketService->UplinkSpeed; + Adapter->DownlinkSpeed = MbbPacketService->DownlinkSpeed; + + if (Adapter->AvailableDataClassValid) + { + // + // if we have a current data class fill it in. + // + Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid = 1; + Request->HandlerContext.Parameters.PacketServiceState.AvailableDataClass=Adapter->AvailableDataClass; + } + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( NdisStatus != NDIS_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + NdisStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PACKET_SERVICE with status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + + MbbNdisIndicatePacketService( + Request, + NdisStatus + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSignalStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_SIGNAL_STATE NdisSignalState; + PMBB_SIGNAL_STATE MbbSignalState = (PMBB_SIGNAL_STATE)InBuffer; + + do + { + RtlZeroMemory(&NdisSignalState, sizeof(NdisSignalState)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SIGNAL_STATE + ); + + NdisSignalState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSignalState.Header.Size = sizeof(NDIS_WWAN_SIGNAL_STATE); + NdisSignalState.Header.Revision = NDIS_WWAN_SIGNAL_STATE_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SIGNAL_STATE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + + if( MbbSignalState == NULL || + InBufferSize < sizeof(MBB_SIGNAL_STATE) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SIGNAL_STATE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_SIGNAL_STATE) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanSignalState( + MbbSignalState, + &NdisSignalState.SignalState + ); + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisSignalState.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisSignalState; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SIGNAL_STATE); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SIGNAL_STATE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + + +NDIS_STATUS +MbbNdisConnectStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_CONTEXT_STATE NdisContextState; + PMBB_CONTEXT_STATE MbbContextState = (PMBB_CONTEXT_STATE)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ); + PMBB_PORT Port = NULL; + NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; + BOOLEAN ResetPort = FALSE; + + do + { + RtlZeroMemory(&NdisContextState, sizeof(NdisContextState)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_CONTEXT_STATE + ); + + NdisContextState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisContextState.Header.Size = SIZEOF_NDIS_WWAN_CONTEXT_STATE_REVISION_2; + NdisContextState.Header.Revision = NDIS_WWAN_CONTEXT_STATE_REVISION_2; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_CONTEXT_STATE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + // + // A MBB_CONTEXT_STATE structure may follow even when MBB_STATUS + // is not successful. It is required, for example, to communicate + // the Network specific error. + // + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if ((WwanStatus != WWAN_STATUS_SUCCESS) && ((InBufferSize < sizeof(MBB_CONTEXT_STATE) || (MbbContextState == NULL)))) + { + // + // if the request failed and the buffer returned is too small, break out now and return the error. + // In the case of an error with a valid buffer, continue to try to get the uNwError to return + // + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus not successful, WwanStatus=%!WwanStatus!, MbbStatus=%!MbbStatus!", + Request->RequestId, + WwanStatus, + MbbStatus + ); + break; + } + + if( MbbContextState == NULL || InBufferSize < sizeof(MBB_CONTEXT_STATE) ) + { + // + // because of the check above, this is only hit for the success case. + // + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_CONTEXT_STATE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_CONTEXT_STATE) + ); + // + // only change the error if the current status is success + // + if (WwanStatus == WWAN_STATUS_SUCCESS) + { + WwanStatus = WWAN_STATUS_FAILURE; + } + break; + } + + // Get the port. Always rely on the session id returned by the device as this + // responsehandler may be triggered due to an OID request from above + // or some MB device specific notification from below. Session Id is set in both cases. + Port = MbbWwanTranslateSessionIdToPort(Adapter, MbbContextState->SessionId); + + if( Port == NULL ) + { + // invalid port context + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Received invalid port context in MbbNdisConnectStatusHandler", Request->RequestId); + + if( MbbContextState->ActivationState == MbbActivationStateDeactivated ) + { + // Handling the case when port ( virtual interface) may have been brought down before context deactivation. In that + // case the port will not be found but the session Id is still valid. Hence return the session id here. It will be returned + // successfully if its a valid session Id. Else this will be a no-op. + MbbWwanReturnSessionId(Adapter, MbbContextState->SessionId); + + TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Returned session id for CONTEXT DEACTIVATION response for session Id[%lu] for an invalid port context in MbbNdisConnectStatusHandler", + Request->RequestId, + MbbContextState->SessionId); + } + else + { + // This means that we have the port removed while the context activation was queued. + TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Not returning session id for context request: [%d] response for session Id[%lu] for an invalid port context in MbbNdisConnectStatusHandler", + Request->RequestId, + (int)MbbContextState->ActivationState, + MbbContextState->SessionId); + } + + if (WwanStatus == WWAN_STATUS_SUCCESS) + { + WwanStatus = WWAN_STATUS_FAILURE; + } + + break; + } + + // Get the port number + MBB_ACQUIRE_PORT_LOCK(Port); + PortNumber = Port->PortNumber; + MBB_RELEASE_PORT_LOCK(Port); + + MbbUtilMbbToWwanContextState( + MbbContextState, + MbbWwanGetPortConnectionId(Port), + &NdisContextState.ContextState + ); + } + while( FALSE ); + + if( (MbbContextState == NULL || InBufferSize < sizeof(MBB_CONTEXT_STATE)) && + (MbbReqMgrIsInternalRequest( Request ) == FALSE) && + (MbbReqMgrIsUnsolicitedIndication( Request ) == FALSE) + ) + { + // + // We cannot get the SessionId from the MbbContextState because it is invalid. + // Since this is a transactional response, we do a best-effort to send the response up + // on the default port. + // NOTE: Unsolicited indications with invalid context state are dropped. + // + + MBB_CONTEXT_STATE DummyMbbContextState = {0}; + + PortNumber = NDIS_DEFAULT_PORT_NUMBER; + Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); + + if (Port != NULL) + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbContextState is invalid. Using NDIS_DEFAULT_PORT_NUMBER (%lu) to indicate response", + Request->RequestId, + PortNumber + ); + + MbbUtilMbbToWwanContextState( + &DummyMbbContextState, + MbbWwanGetPortConnectionId(Port), + &NdisContextState.ContextState + ); + } + else + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbContextState is invalid AND we failed to retrieve the default port info", + Request->RequestId); + } + } + + // + // If this is an ACTIVATION failure reset the port + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbReqMgrIsSetOid( Request ) == TRUE && + Request->HandlerContext.Parameters.Connect.Activate == TRUE && + Port != NULL + ) + { + ResetPort = TRUE; + } + + if(Port != NULL) + { + // Indicate status indication on the correct port. If port is not found + // we dont know which port number to indicate the status on. + + NdisContextState.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisContextState; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_CONTEXT_STATE); + StatusIndication.PortNumber = PortNumber; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_CONTEXT_STATE with status=%!WwanStatus! for Port number=%lu", + Request->RequestId, + WwanStatus, + PortNumber + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + } + else + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Not indicating OID_WWAN_CONNECT completion as the port context is invalid.", Request->RequestId); + } + + // + // TODO: Get the speed information from the adpater. + // The adpater caches the information received from packet_service. + // + if( MbbContextState != NULL && + Port != NULL && + NdisStatus == NDIS_STATUS_SUCCESS && + WwanStatus == WWAN_STATUS_SUCCESS + ) + { + if( MbbContextState->ActivationState == MbbActivationStateActivated ) + { + MBB_CONNECTION_STATE ConnectionState; + + // + // Verify that the device is reporting the correct SessionId. + // There isnt much to do apart from logging. + // + ASSERT(MbbContextState->SessionId == MbbWwanGetPortSessionId(Port)); + + if(MbbContextState->SessionId != MbbWwanGetPortSessionId(Port)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID SessionId[Receieved=%d Expected=%d] on Connect", + Request->RequestId, + MbbContextState->SessionId, + MbbWwanGetPortSessionId(Port) + ); + } + + ConnectionState.ConnectionUp = TRUE; + ConnectionState.UpStreamBitRate = Adapter->UplinkSpeed; + ConnectionState.DownStreamBitRate = Adapter->DownlinkSpeed; + + MbbAdapterConnectionChange( + MbbReqMgrGetAdapterHandle( Request ), + &ConnectionState, + PortNumber + ); + } + else if( MbbContextState->ActivationState == MbbActivationStateDeactivated ) + { + MBB_CONNECTION_STATE ConnectionState; + + ConnectionState.ConnectionUp = FALSE; + ConnectionState.UpStreamBitRate = 0; + ConnectionState.DownStreamBitRate = 0; + + MbbAdapterConnectionChange( + MbbReqMgrGetAdapterHandle( Request ), + &ConnectionState, + PortNumber + ); + + // this is a successful deactivation. Reset the port + ResetPort = (MbbReqMgrIsUnsolicitedIndication( Request ) /*Unsolicited deactivate context*/ + || MbbReqMgrIsSetOid( Request )); /*Solicited deactivate context*/ + + } + } + + if(Port) + { + if(ResetPort) + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Resetting port with port number= %d", + Request->RequestId, + PortNumber); + + MbbWwanSetPortConnectionId( + Port, + 0 + ); + + MbbWwanResetPortSessionId( + Port, + TRUE // session id should be returned to the session pool + ); + + MBB_ACQUIRE_PORT_LOCK(Port); + + if(Port->IpAddressInfo != NULL) + { + FREE_POOL(Port->IpAddressInfo); + Port->IpAddressInfo = NULL; + } + + MBB_RELEASE_PORT_LOCK(Port); + } + + // Remove the reference added during find + Dereference(Port); + } + + // Return the session id to the adapter session id pool if- + // + // a) This was a context activation request + // b) Current state of the request is "MbbRequestStateCancelled" + // c) Last state of the request < MbbRequestStateResponseReceived. + // + // This will ensure that we are processing the request for whom the response hasnt been received as yet. + // + // If the response is received for these cancelled requests, that will be a no-op. + // + // Requests whose responses have already been received will be ( or are being ) processed by their + // respective response handlers and the upper layers are responsible for further actions. + // + + if(Adapter + && Request->HandlerContext.Parameters.Connect.Activate == TRUE) + { + // return session id to the session id pool of the adapter + // for the cancelled request. Otherwise this session id + // will leak. + + MBB_REQUEST_STATE CurrentRequestState = MbbRequestStateInvalid; + MBB_REQUEST_STATE LastRequestState = MbbRequestStateInvalid; + ULONG SessionId = MBB_INVALID_SESSION_ID; + + MbbReqMgrGetState( + Request, + &CurrentRequestState, + &LastRequestState + ); + + if(CurrentRequestState == MbbRequestStateCancelled) + { + if(LastRequestState < MbbRequestStateResponseReceived) + { + SessionId = Request->HandlerContext.Parameters.Connect.SessionId; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Attempting to return the session id of the cancelled context activation request to adapter session id pool.Session Id = %d, Current request state = %!MbbRequestState!, Last request state = %!MbbRequestState!", + Request->RequestId, + SessionId, + CurrentRequestState, + LastRequestState + ); + + MbbWwanReturnSessionId(Adapter, SessionId); + } + else + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Not attempting to return the session id of the cancelled context activation request to adapter session id pool. Session Id = %d, Current request state = %!MbbRequestState!, Last request state = %!MbbRequestState!", + Request->RequestId, + SessionId, + CurrentRequestState, + LastRequestState + ); + } + } + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisLteAttachConfigHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + ULONG NdisLteAttachContextSize = sizeof(NDIS_WWAN_LTE_ATTACH_CONTEXTS); + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication; + PNDIS_WWAN_LTE_ATTACH_CONTEXTS NdisLteAttachContext = NULL; + PMBB_MS_LTE_ATTACH_CONFIG_INFO MbbLteAttchConfigInfo = (PMBB_MS_LTE_ATTACH_CONFIG_INFO)InBuffer; + PMBB_MS_LTE_ATTACH_CONTEXT MbbContext=NULL; + ULONGLONG TempSize=0; + ULONG MulTempSize=0; + ULONG i; + + NdisLteAttachContext = ALLOCATE_NONPAGED_POOL( NdisLteAttachContextSize ); + + if ( NdisLteAttachContext == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_WWAN_LTE_ATTACH_CONTEXTS, ContextCount=%d", + Request->RequestId, + NdisLteAttachContextSize, + MbbLteAttchConfigInfo->ElementCount + ); + return NDIS_STATUS_RESOURCES; + } + RtlZeroMemory(NdisLteAttachContext, NdisLteAttachContextSize); + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_LTE_ATTACH_CONFIG + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_LTE_ATTACH_CONFIG, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + TempSize = RTL_SIZEOF_THROUGH_FIELD(MBB_MS_LTE_ATTACH_CONFIG_INFO, Contexts); + + if( MbbLteAttchConfigInfo == NULL || + InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_MS_LTE_ATTACH_CONFIG_INFO, Contexts) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_LTE_ATTACH_CONFIG, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_MS_LTE_ATTACH_CONFIG_INFO, Contexts) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbLteAttchConfigInfo->ElementCount != TotalRoamingConditions) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] wrong size element count returned, MbbLteAttchConfigInfo->ContextCount=%d, exepcting=%d", + Request->RequestId, + MbbLteAttchConfigInfo->ElementCount, + TotalRoamingConditions + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + // + // make sure it is big enough for the array of elements + // + NdisStatus = RtlULongMult( + MbbLteAttchConfigInfo->ElementCount, + sizeof(MBB_ARRAY_ELEMENT), + &MulTempSize + ); + + if ( NT_ERROR(NdisStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbLteAttchConfigInfo->ContextCount=%d MBB_ARRAY_ELEMENT size=%d", + Request->RequestId, + MbbLteAttchConfigInfo->ElementCount, + sizeof(MBB_ARRAY_ELEMENT) + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + TempSize += MulTempSize; + + if( InBufferSize < TempSize ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_LTE_ATTACH_CONFIG, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + (ULONG)TempSize + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // validation of the data buffer + for (i = 0; i < MbbLteAttchConfigInfo->ElementCount; i++) + { + // The max buffer size couldn't be larger than the maximum string length defined in WWAN struct + // otherwise, the conversion from MBB to WWAN could fail + ULONG maxContextSize = + (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer) + + WWAN_ACCESSSTRING_LEN + + WWAN_USERNAME_LEN + + WWAN_PASSWORD_LEN; + + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbLteAttchConfigInfo->Contexts[i].Offset, + MbbLteAttchConfigInfo->Contexts[i].Size, + maxContextSize, + sizeof(UCHAR) + ); + + if (!NT_SUCCESS(NdisStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad array element in MBB_MS_LTE_ATTACH_CONFIG_INFO", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbLteAttchConfigInfo->Contexts[i].Size < (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_CONTEXT, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + MbbLteAttchConfigInfo->Contexts[i].Size, + (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer) + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbContext = (PMBB_MS_LTE_ATTACH_CONTEXT)(InBuffer + MbbLteAttchConfigInfo->Contexts[i].Offset); + ULONG MbbContextSize = (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer); + + NdisStatus = MbbIsVariableFieldValid( + MbbLteAttchConfigInfo->Contexts[i].Size, + MbbContext->AccessString.Offset, + MbbContext->AccessString.Size, + MBB_MAXIMUM_ACCESS_STRING_LENGTH, + sizeof(WCHAR) + ); + + if (!NT_SUCCESS(NdisStatus)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + MbbContextSize += ROUND_UP_COUNT(MbbContext->AccessString.Size, ALIGN_DWORD); + + NdisStatus = MbbIsVariableFieldValid( + MbbLteAttchConfigInfo->Contexts[i].Size, + MbbContext->UserName.Offset, + MbbContext->UserName.Size, + MBB_MAXIMUM_USERNAME_LENGTH, + sizeof(WCHAR) + ); + + if ( !NT_SUCCESS(NdisStatus)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + MbbContextSize += ROUND_UP_COUNT(MbbContext->UserName.Size, ALIGN_DWORD); + + NdisStatus = MbbIsVariableFieldValid( + MbbLteAttchConfigInfo->Contexts[i].Size, + MbbContext->Password.Offset, + MbbContext->Password.Size, + MBB_MAXIMUM_PASSWORD_LENGTH, + sizeof(WCHAR) + ); + + if ( !NT_SUCCESS(NdisStatus)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + MbbContextSize += ROUND_UP_COUNT(MbbContext->Password.Size, ALIGN_DWORD); + + if (MbbLteAttchConfigInfo->Contexts[i].Size != MbbContextSize) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Incorrect BufferSize for MBB_MS_LTE_ATTACH_CONTEXT, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + MbbLteAttchConfigInfo->Contexts[i].Size, + MbbContextSize + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + } + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + NdisLteAttachContext->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisLteAttachContext->Header.Size = sizeof(NDIS_WWAN_LTE_ATTACH_CONTEXTS); + NdisLteAttachContext->Header.Revision = NDIS_WWAN_LTE_ATTACH_CONTEXT_REVISION_1; + NdisLteAttachContext->LteAttachContext.ElementCount = MbbLteAttchConfigInfo->ElementCount; + + MbbUtilMbbToWwanLteAttachConfigInfo( + MbbLteAttchConfigInfo, + &NdisLteAttachContext->LteAttachContext + ); + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + StatusIndication.StatusBuffer = NdisLteAttachContext; + StatusIndication.StatusBufferSize = NdisLteAttachContextSize; + ((PNDIS_WWAN_LTE_ATTACH_CONTEXTS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + FREE_POOL( NdisLteAttachContext ); + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisLteAttachStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + ULONG NdisLteAttachStatusSize = sizeof(NDIS_WWAN_LTE_ATTACH_STATUS); + PNDIS_WWAN_LTE_ATTACH_STATUS NdisLteAttachStatus = NULL; + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication; + PMBB_MS_LTE_ATTACH_STATUS MbbLteAttchStatus = (PMBB_MS_LTE_ATTACH_STATUS)InBuffer; + ULONGLONG TempSize=0; + + NdisLteAttachStatus = ALLOCATE_NONPAGED_POOL(NdisLteAttachStatusSize); + + if ( NdisLteAttachStatus == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_WWAN_LTE_ATTACH_STATUS", + Request->RequestId, + NdisLteAttachStatusSize + ); + return NDIS_STATUS_RESOURCES; + } + + RtlZeroMemory(NdisLteAttachStatus, NdisLteAttachStatusSize); + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_LTE_ATTACH_STATUS + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_LTE_ATTACH_STATUS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + if( MbbReqMgrIsSetOid( Request ) == TRUE ) + { + break; + } + + TempSize = (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_STATUS, DataBuffer); + + if( MbbLteAttchStatus == NULL || + InBufferSize < TempSize ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_LTE_ATTACH_STATUS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + (ULONG)TempSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbLteAttchStatus->AccessString.Offset, + MbbLteAttchStatus->AccessString.Size, + MBB_MAXIMUM_ACCESS_STRING_LENGTH, + sizeof(WCHAR) + ); + + if ( !NT_SUCCESS(NdisStatus)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbLteAttchStatus->UserName.Offset, + MbbLteAttchStatus->UserName.Size, + MBB_MAXIMUM_USERNAME_LENGTH, + sizeof(WCHAR) + ); + + if ( !NT_SUCCESS(NdisStatus)) + { + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbLteAttchStatus->Password.Offset, + MbbLteAttchStatus->Password.Size, + MBB_MAXIMUM_PASSWORD_LENGTH, + sizeof(WCHAR) + ); + + if ( !NT_SUCCESS(NdisStatus)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + NdisLteAttachStatus->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisLteAttachStatus->Header.Size = sizeof(NDIS_WWAN_LTE_ATTACH_STATUS); + NdisLteAttachStatus->Header.Revision = NDIS_WWAN_LTE_ATTACH_STATUS_REVISION_1; + + MbbUtilMbbToWwanLteAttachStatus( + MbbLteAttchStatus, + &NdisLteAttachStatus->LteAttachStatus + ); + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + StatusIndication.StatusBuffer = NdisLteAttachStatus; + StatusIndication.StatusBufferSize = NdisLteAttachStatusSize; + + ((PNDIS_WWAN_LTE_ATTACH_STATUS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + FREE_POOL( NdisLteAttachStatus ); + return NdisStatus; +} + +NDIS_STATUS +MbbNdisProvisionedContextStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + ULONG NdisProvisionedContextSize = 0; + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + PNDIS_WWAN_PROVISIONED_CONTEXTS NdisProvisionedContext = NULL; + NDIS_WWAN_PROVISIONED_CONTEXTS LocalNdisProvisionedContext; + PMBB_CONTEXT_LIST MbbContextList = (PMBB_CONTEXT_LIST)InBuffer; + PMBB_CONTEXT MbbContext=NULL; + ULONGLONG TempSize=0; + ULONG MulTempSize=0; + ULONG i; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + RtlZeroMemory(&LocalNdisProvisionedContext, sizeof(LocalNdisProvisionedContext)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + + if( MbbReqMgrIsSetOid( Request ) == TRUE ) + { + break; + } + + TempSize = RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount); + + if( MbbContextList == NULL || + InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbContextList->ContextCount > MBB_MAX_PROVISIONED_CONTEXTS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Too many contexts returned, MbbContextList->ContextCount=%d", + Request->RequestId, + MbbContextList->ContextCount + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + // + // make sure it is big enough for the array of elements + // + NtStatus = RtlULongMult( + MbbContextList->ContextCount, + sizeof(MBB_ARRAY_ELEMENT), + &MulTempSize + ); + + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbContextList->ContextCount=%d MBB_ARRAY_ELEMENT size=%d", + Request->RequestId, + MbbContextList->ContextCount, + sizeof(MBB_ARRAY_ELEMENT) + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + TempSize += MulTempSize; + + if( InBufferSize < TempSize ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + (ULONG)TempSize + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + for (i=0; i < MbbContextList->ContextCount; i++) + { + + NtStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbContextList->Contexts[i].Offset, + MbbContextList->Contexts[i].Size, + 2048, // some reasonable upper limit + sizeof(UCHAR) + ); + + if ( !NT_SUCCESS(NtStatus)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad array element in MBB_CONTEXT_LIST", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbContextList->Contexts[i].Size < (ULONG)FIELD_OFFSET(MBB_CONTEXT, DataBuffer)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_CONTEXT, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + MbbContextList->Contexts[i].Size, + (ULONG)FIELD_OFFSET(MBB_CONTEXT, DataBuffer) + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + + + } + + MbbContext=(PMBB_CONTEXT)(InBuffer+MbbContextList->Contexts[i].Offset); + + NtStatus = MbbIsVariableFieldValid( + MbbContextList->Contexts[i].Size, + MbbContext->AccessString.Offset, + MbbContext->AccessString.Size, + MBB_MAXIMUM_ACCESS_STRING_LENGTH, + sizeof(WCHAR) + ); + + if ( !NT_SUCCESS(NtStatus)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + + NtStatus = MbbIsVariableFieldValid( + MbbContextList->Contexts[i].Size, + MbbContext->UserName.Offset, + MbbContext->UserName.Size, + MBB_MAXIMUM_USERNAME_LENGTH, + sizeof(WCHAR) + ); + + if ( !NT_SUCCESS(NtStatus)) + { + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + + NtStatus = MbbIsVariableFieldValid( + MbbContextList->Contexts[i].Size, + MbbContext->Password.Offset, + MbbContext->Password.Size, + MBB_MAXIMUM_PASSWORD_LENGTH, + sizeof(WCHAR) + ); + + if ( !NT_SUCCESS(NtStatus)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_CONTEXT", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + } + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + NtStatus = RtlULongMult( + MbbContextList->ContextCount, + sizeof(WWAN_CONTEXT), + &NdisProvisionedContextSize + ); + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbContextList->ContextCount=%d WWAN_CONTEXT size=%d", + Request->RequestId, + MbbContextList->ContextCount, + sizeof(WWAN_CONTEXT) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NtStatus = RtlULongAdd( + NdisProvisionedContextSize, + sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS), + &NdisProvisionedContextSize + ); + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, NdisProvisionedContextSize=%d NDIS_WWAN_PROVISIONED_CONTEXTS size=%d", + Request->RequestId, + NdisProvisionedContextSize, + sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisProvisionedContext = ALLOCATE_NONPAGED_POOL( NdisProvisionedContextSize ); + + if ( NdisProvisionedContext == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, ContextCount=%d", + Request->RequestId, + NdisProvisionedContextSize, + MbbContextList->ContextCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisProvisionedContext, NdisProvisionedContextSize); + + NdisProvisionedContext->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisProvisionedContext->Header.Size = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); + NdisProvisionedContext->Header.Revision = NDIS_WWAN_PROVISIONED_CONTEXTS_REVISION_1; + + MbbUtilMbbToWwanContextList( + MbbContextList, + &NdisProvisionedContext->ContextListHeader + ); + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if( NdisProvisionedContext == NULL ) + { + LocalNdisProvisionedContext.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisProvisionedContext.Header.Size = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); + LocalNdisProvisionedContext.Header.Revision = NDIS_WWAN_PROVISIONED_CONTEXTS_REVISION_1; + + LocalNdisProvisionedContext.ContextListHeader.ElementType = WwanStructContext; + LocalNdisProvisionedContext.ContextListHeader.ElementCount = 0; + + StatusIndication.StatusBuffer = &LocalNdisProvisionedContext; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); + } + else + { + StatusIndication.StatusBuffer = NdisProvisionedContext; + StatusIndication.StatusBufferSize = NdisProvisionedContextSize; + } + + ((PNDIS_WWAN_PROVISIONED_CONTEXTS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if( NdisProvisionedContext != NULL ) + { + FREE_POOL( NdisProvisionedContext ); + } + return NDIS_STATUS_SUCCESS; +} + + +NDIS_STATUS +MbbNdisProvisionedContextV2StatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +) +{ + ULONG NdisProvisionedContextSize = 0; + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + PNDIS_WWAN_PROVISIONED_CONTEXTS NdisProvisionedContext = NULL; + NDIS_WWAN_PROVISIONED_CONTEXTS LocalNdisProvisionedContext; + PMBB_CONTEXT_LIST MbbContextList = (PMBB_CONTEXT_LIST)InBuffer; + PMBB_MS_CONTEXT_V2 MbbContext = NULL; + ULONGLONG TempSize = 0; + ULONG MulTempSize = 0; + ULONG i; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + RtlZeroMemory(&LocalNdisProvisionedContext, sizeof(LocalNdisProvisionedContext)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + + if (MbbReqMgrIsSetOid(Request) == TRUE) + { + break; + } + + TempSize = RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount); + + if (MbbContextList == NULL || + InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbContextList->ContextCount > MBB_MAX_PROVISIONED_CONTEXTS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Too many contexts returned, MbbContextList->ContextCount=%d", + Request->RequestId, + MbbContextList->ContextCount + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + // + // make sure it is big enough for the array of elements + // + NtStatus = RtlULongMult( + MbbContextList->ContextCount, + sizeof(MBB_ARRAY_ELEMENT), + &MulTempSize + ); + + if (NT_ERROR(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbContextList->ContextCount=%d MBB_ARRAY_ELEMENT size=%d", + Request->RequestId, + MbbContextList->ContextCount, + sizeof(MBB_ARRAY_ELEMENT) + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + TempSize += MulTempSize; + + if (InBufferSize < TempSize) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + (ULONG)TempSize + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + for (i = 0; i < MbbContextList->ContextCount; i++) + { + + NtStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbContextList->Contexts[i].Offset, + MbbContextList->Contexts[i].Size, + 2048, // some reasonable upper limit + sizeof(UCHAR) + ); + + if (!NT_SUCCESS(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad array element in MBB_CONTEXT_LIST", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbContextList->Contexts[i].Size < (ULONG)FIELD_OFFSET(MBB_MS_CONTEXT_V2, DataBuffer)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_MS_CONTEXT_V2, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + MbbContextList->Contexts[i].Size, + (ULONG)FIELD_OFFSET(MBB_MS_CONTEXT_V2, DataBuffer) + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + + + } + + MbbContext = (PMBB_MS_CONTEXT_V2)(InBuffer + MbbContextList->Contexts[i].Offset); + + NtStatus = MbbIsVariableFieldValid( + MbbContextList->Contexts[i].Size, + MbbContext->AccessString.Offset, + MbbContext->AccessString.Size, + MBB_MAXIMUM_ACCESS_STRING_LENGTH, + sizeof(WCHAR) + ); + + if (!NT_SUCCESS(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_CONTEXT_V2", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + + NtStatus = MbbIsVariableFieldValid( + MbbContextList->Contexts[i].Size, + MbbContext->UserName.Offset, + MbbContext->UserName.Size, + MBB_MAXIMUM_USERNAME_LENGTH, + sizeof(WCHAR) + ); + + if (!NT_SUCCESS(NtStatus)) + { + + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_CONTEXT_V2", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + + NtStatus = MbbIsVariableFieldValid( + MbbContextList->Contexts[i].Size, + MbbContext->Password.Offset, + MbbContext->Password.Size, + MBB_MAXIMUM_PASSWORD_LENGTH, + sizeof(WCHAR) + ); + + if (!NT_SUCCESS(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_CONTEXT_V2", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + } + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + NtStatus = RtlULongMult( + MbbContextList->ContextCount, + sizeof(WWAN_CONTEXT_V2), + &NdisProvisionedContextSize + ); + if (NT_ERROR(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbContextList->ContextCount=%d MBB_MS_CONTEXT_V2 size=%d", + Request->RequestId, + MbbContextList->ContextCount, + sizeof(WWAN_CONTEXT_V2) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NtStatus = RtlULongAdd( + NdisProvisionedContextSize, + sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS), + &NdisProvisionedContextSize + ); + if (NT_ERROR(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, NdisProvisionedContextSize=%d NDIS_WWAN_PROVISIONED_CONTEXTS size=%d", + Request->RequestId, + NdisProvisionedContextSize, + sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisProvisionedContext = ALLOCATE_NONPAGED_POOL(NdisProvisionedContextSize); + + if (NdisProvisionedContext == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, ContextCount=%d", + Request->RequestId, + NdisProvisionedContextSize, + MbbContextList->ContextCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisProvisionedContext, NdisProvisionedContextSize); + + NdisProvisionedContext->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisProvisionedContext->Header.Size = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); + NdisProvisionedContext->Header.Revision = NDIS_WWAN_PROVISIONED_CONTEXTS_REVISION_2; + + MbbUtilMbbToWwanContextV2List( + MbbContextList, + &NdisProvisionedContext->ContextListHeader + ); + } while (FALSE); + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + if (NdisProvisionedContext == NULL) + { + LocalNdisProvisionedContext.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisProvisionedContext.Header.Size = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); + LocalNdisProvisionedContext.Header.Revision = NDIS_WWAN_PROVISIONED_CONTEXTS_REVISION_2; + + LocalNdisProvisionedContext.ContextListHeader.ElementType = WwanStructContextV2; + LocalNdisProvisionedContext.ContextListHeader.ElementCount = 0; + + StatusIndication.StatusBuffer = &LocalNdisProvisionedContext; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); + } + else + { + StatusIndication.StatusBuffer = NdisProvisionedContext; + StatusIndication.StatusBufferSize = NdisProvisionedContextSize; + } + + ((PNDIS_WWAN_PROVISIONED_CONTEXTS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisProvisionedContext != NULL) + { + FREE_POOL(NdisProvisionedContext); + } + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisServiceActivationStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + ULONG VendorSpecificBufferSize; + ULONG NdisServiceActivationStatusSize = 0; + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + PNDIS_WWAN_SERVICE_ACTIVATION_STATUS NdisServiceActivationStatus = NULL; + NDIS_WWAN_SERVICE_ACTIVATION_STATUS LocalNdisServiceActivationStatus; + PMBB_SERVICE_ACTIVATION_STATUS MbbServiceActivationStatus = (PMBB_SERVICE_ACTIVATION_STATUS)InBuffer; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + RtlZeroMemory(&LocalNdisServiceActivationStatus, sizeof(LocalNdisServiceActivationStatus)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SERVICE_ACTIVATION + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SERVICE_ACTIVATION, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( MbbServiceActivationStatus == NULL || + InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SERVICE_ACTIVATION_STATUS, NetworkError) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SERVICE_ACTIVATION, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_SERVICE_ACTIVATION_STATUS, NetworkError) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + VendorSpecificBufferSize = InBufferSize - RTL_SIZEOF_THROUGH_FIELD(MBB_SERVICE_ACTIVATION_STATUS, NetworkError); + + NtStatus = RtlULongAdd( + VendorSpecificBufferSize, + sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS), + &NdisServiceActivationStatusSize + ); + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, VendorSpecificBufferSize=%d NDIS_WWAN_SERVICE_ACTIVATION_STATUS size=%d", + Request->RequestId, + VendorSpecificBufferSize, + sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( (NdisServiceActivationStatus = ALLOCATE_NONPAGED_POOL( NdisServiceActivationStatusSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_SERVICE_ACTIVATION", + Request->RequestId, + NdisServiceActivationStatusSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisServiceActivationStatus->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisServiceActivationStatus->Header.Size = sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS); + NdisServiceActivationStatus->Header.Revision = NDIS_WWAN_SERVICE_ACTIVATION_STATUS_REVISION_1; + + MbbUtilMbbToWwanServiceActivationStatus( + MbbServiceActivationStatus, + VendorSpecificBufferSize, + &NdisServiceActivationStatus->ServiceActivationStatus + ); + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if( NdisServiceActivationStatus == NULL ) + { + LocalNdisServiceActivationStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisServiceActivationStatus.Header.Size = sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS); + LocalNdisServiceActivationStatus.Header.Revision = NDIS_WWAN_SERVICE_ACTIVATION_STATUS_REVISION_1; + + LocalNdisServiceActivationStatus.ServiceActivationStatus.uNwError = 0; + LocalNdisServiceActivationStatus.ServiceActivationStatus.uVendorSpecificBufferSize = 0; + + StatusIndication.StatusBuffer = &LocalNdisServiceActivationStatus; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS); + } + else + { + StatusIndication.StatusBuffer = NdisServiceActivationStatus; + StatusIndication.StatusBufferSize = NdisServiceActivationStatusSize; + } + + ((PNDIS_WWAN_SERVICE_ACTIVATION_STATUS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SERVICE_ACTIVATION with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if( NdisServiceActivationStatus != NULL ) + { + FREE_POOL( NdisServiceActivationStatus ); + } + return NDIS_STATUS_SUCCESS; +} + +// SMS + +NDIS_STATUS +MbbNdisSmsConfigurationStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_SMS_CONFIGURATION NdisSmsConfiguration; + PMBB_SMS_CONFIGURATION MbbSmsConfiguration = (PMBB_SMS_CONFIGURATION)InBuffer; + + do + { + RtlZeroMemory(&NdisSmsConfiguration, sizeof(NdisSmsConfiguration)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SMS_CONFIGURATION + ); + + NdisSmsConfiguration.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSmsConfiguration.Header.Size = sizeof(NDIS_WWAN_SMS_CONFIGURATION); + NdisSmsConfiguration.Header.Revision = NDIS_WWAN_SMS_CONFIGURATION_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_CONFIGURATION, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) + { + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + + if( MbbSmsConfiguration == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_SMS_CONFIGURATION, DataBuffer) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SMS_CONFIGURATION, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_SMS_CONFIGURATION, ScAddress) + ); + WwanStatus = WWAN_STATUS_FAILURE; + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + + + // + // If the SMS store is not initialized then other fields are not valid. + // + if( MbbSmsConfiguration->SmsStorageState != MbbSmsStorageInitialized ) + { + NdisStatus = NDIS_STATUS_FAILURE; + WwanStatus = WWAN_STATUS_BUSY; + break; + } + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbSmsConfiguration->ScAddress.Offset, + MbbSmsConfiguration->ScAddress.Size, + MBB_MAXIMUM_SMS_ADDRESS_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] ScAddress data field, Offset=%d, Size=%d", + Request->RequestId, + MbbSmsConfiguration->ScAddress.Offset, + MbbSmsConfiguration->ScAddress.Size + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + MbbUtilMbbToWwanSmsConfiguration( + MbbSmsConfiguration, + &NdisSmsConfiguration.SmsConfiguration + ); + } + while( FALSE ); + // + // When to do SMS Configuration indication - + // - This is a response to a OID query + // - This is an unsolicited indication + // When to do Ready Info indication - + // - This is a response to an internal query + // - This is an unsolicited indication + // + if( MbbReqMgrIsInternalRequest( Request ) == FALSE || + ( + MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE && + NdisStatus == NDIS_STATUS_SUCCESS + ) ) + { + NdisSmsConfiguration.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisSmsConfiguration; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_CONFIGURATION); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_CONFIGURATION with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + } + + if( MbbReqMgrIsInternalRequest( Request ) == TRUE || + ( + MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE && + NdisStatus == NDIS_STATUS_SUCCESS + ) ) + { + Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid = 1; + Request->HandlerContext.Parameters.SubscriberReadyInfo.CdmaShortMsgSize = WWAN_CDMA_SHORT_MSG_SIZE_UNKNOWN; + + if( NdisStatus == NDIS_STATUS_SUCCESS ) + Request->HandlerContext.Parameters.SubscriberReadyInfo.CdmaShortMsgSize = (UCHAR)MbbSmsConfiguration->CdmaShortMessageSize; + // + // Ignore SMS Configuration failures and return UNKNOWN CdmaShrotMessageSize + // when SMS_CONFIGURATION was queried internally for a READY_INFO. + // + MbbNdisIndicateReadyInfo( + Request, + NDIS_STATUS_SUCCESS + ); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSmsReadStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + ULONG WwanMessageSize; + ULONG NdisSmsReceiveSize = 0; + ULONG MessageBufferSize = 0; + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_SMS_RECEIVE LocalNdisSmsReceive; + PNDIS_WWAN_SMS_RECEIVE NdisSmsReceive = NULL; + PMBB_SMS_RECEIVE MbbSmsReceive = (PMBB_SMS_RECEIVE)InBuffer; + NTSTATUS Status; + MBB_CELLULAR_CLASS CellularClass; + + CellularClass = MbbAdapterGetCurrentCellularClass( MbbReqMgrGetAdapterHandle( Request ) ); + + if (MbbAdapterIsMultimodeCapable(MbbReqMgrGetAdapterHandle( Request ))) + { + // + // multimode device always use GSM PDU's + // + CellularClass = MbbCellularClassGsm; + } + + do + { + RtlZeroMemory(&LocalNdisSmsReceive, sizeof(LocalNdisSmsReceive)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SMS_RECEIVE + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_RECEIVE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + + // + // Validate received buffer + // + if( MbbUtilValidateMbbSmsReceive( + CellularClass, + InBufferSize, + MbbSmsReceive + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to validate data for MBB_SMS_RECEIVE", Request->RequestId ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbSmsReceive->SmsFormat == MbbSmsFormatPdu ) + WwanMessageSize = sizeof(WWAN_SMS_PDU_RECORD); + else + WwanMessageSize = sizeof(WWAN_SMS_CDMA_RECORD); + + + Status=RtlULongMult(MbbSmsReceive->MessageCount, WwanMessageSize, &MessageBufferSize); + + if (!NT_SUCCESS(Status)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] overflow Count=%d, Size=%d", Request->RequestId, MbbSmsReceive->MessageCount, WwanMessageSize ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + Status=RtlULongAdd( sizeof(NDIS_WWAN_SMS_RECEIVE), MessageBufferSize, &NdisSmsReceiveSize); + + if (!NT_SUCCESS(Status)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] overflow fixed=%d, MessageSize=%d", Request->RequestId, sizeof(NDIS_WWAN_SMS_RECEIVE), MessageBufferSize ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisSmsReceive = (PNDIS_WWAN_SMS_RECEIVE)ALLOCATE_NONPAGED_POOL( (ULONG)NdisSmsReceiveSize ); + + if( NdisSmsReceive == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to allocate %u bytes for NDIS_STATUS_WWAN_SMS_RECEIVE, MessageCount=%d", + Request->RequestId, + NdisSmsReceiveSize, + MbbSmsReceive->MessageCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisSmsReceive->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSmsReceive->Header.Size = sizeof(NDIS_WWAN_SMS_RECEIVE); + NdisSmsReceive->Header.Revision = NDIS_WWAN_SMS_RECEIVE_REVISION_1; + + if( (NdisStatus = MbbUtilMbbToWwanSmsReceive( + MbbSmsReceive, + InBufferSize, + CellularClass, + &NdisSmsReceive->SmsListHeader + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to convert data for NDIS_STATUS_WWAN_SMS_RECEIVE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if( WwanStatus != WWAN_STATUS_SUCCESS && + WwanStatus != WWAN_STATUS_SMS_MORE_DATA ) + { + StatusIndication.StatusBuffer = &LocalNdisSmsReceive; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_RECEIVE); + + LocalNdisSmsReceive.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisSmsReceive.Header.Size = sizeof(NDIS_WWAN_SMS_RECEIVE); + LocalNdisSmsReceive.Header.Revision = NDIS_WWAN_SMS_RECEIVE_REVISION_1; + + LocalNdisSmsReceive.SmsListHeader.ElementType = WwanStructSmsPdu; + LocalNdisSmsReceive.SmsListHeader.ElementCount = 0; + } + else + { + StatusIndication.StatusBuffer = NdisSmsReceive; + StatusIndication.StatusBufferSize = (ULONG)NdisSmsReceiveSize; + } + + ((PNDIS_WWAN_SMS_RECEIVE)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_RECEIVE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if( NdisSmsReceive != NULL ) + FREE_POOL( NdisSmsReceive ); + + if( WwanStatus == WWAN_STATUS_SMS_MORE_DATA ) + return NDIS_STATUS_PENDING; + else + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSmsSendStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_SMS_SEND_STATUS NdisSmsSendStatus; + PMBB_SMS_SEND_STATUS MbbSmsSendStatus = (PMBB_SMS_SEND_STATUS)InBuffer; + + do + { + RtlZeroMemory(&NdisSmsSendStatus, sizeof(NdisSmsSendStatus)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SMS_SEND + ); + + NdisSmsSendStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSmsSendStatus.Header.Size = sizeof(NDIS_WWAN_SMS_SEND_STATUS); + NdisSmsSendStatus.Header.Revision = NDIS_WWAN_SMS_SEND_STATUS_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_SEND, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + if( MbbSmsSendStatus == NULL || + InBufferSize < sizeof(MBB_SMS_SEND_STATUS) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SMS_SEND, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_SMS_SEND_STATUS) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisSmsSendStatus.MessageReference = MbbSmsSendStatus->MessageReference; + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisSmsSendStatus.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisSmsSendStatus; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_SEND_STATUS); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_SEND with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSmsDeleteStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_SMS_DELETE_STATUS NdisSmsDeleteStatus; + + do + { + RtlZeroMemory(&NdisSmsDeleteStatus, sizeof(NdisSmsDeleteStatus)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SMS_DELETE + ); + + NdisSmsDeleteStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSmsDeleteStatus.Header.Size = sizeof(NDIS_WWAN_SMS_DELETE_STATUS); + NdisSmsDeleteStatus.Header.Revision = NDIS_WWAN_SMS_DELETE_STATUS_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_DELETE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + while( FALSE ); + + NdisSmsDeleteStatus.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisSmsDeleteStatus; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_DELETE_STATUS); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_DELETE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSmsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_SMS_STATUS NdisSmsStatus; + PMBB_SMS_STATUS MbbSmsStatus = (PMBB_SMS_STATUS)InBuffer; + + do + { + RtlZeroMemory(&NdisSmsStatus, sizeof(NdisSmsStatus)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SMS_STATUS + ); + + NdisSmsStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSmsStatus.Header.Size = sizeof(NDIS_WWAN_SMS_STATUS); + NdisSmsStatus.Header.Revision = NDIS_WWAN_SMS_STATUS_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_STATUS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + if( MbbSmsStatus == NULL || + InBufferSize < sizeof(MBB_SMS_STATUS) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SMS_STATUS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_SMS_STATUS) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanSmsStatus( MbbSmsStatus, &NdisSmsStatus.SmsStatus ); + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisSmsStatus.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisSmsStatus; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_STATUS); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_STATUS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +#if 0 +NDIS_STATUS +MbbNdisGetStatsHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) + +{ + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); + PNDIS_STATISTICS_INFO Stats=NULL; + PMBB_PACKET_STATISTICS MbbStats=NULL; + PCSTR OidName=NULL; + ULONG OidNameLength=0; + + PNDIS_OID_REQUEST NdisRequest=NULL; + + if ((NdisStatus != NDIS_STATUS_SUCCESS) || (MbbStatus != MBB_STATUS_SUCCESS) || (InBufferSize < sizeof(*MbbStats))) + { + TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Device failed OID_GEN_STATISTICS", + Request->RequestId + ); + + } + + NdisRequest=InterlockedExchangePointer(&Request->OidContext.OidRequest,(PNDIS_OID_REQUEST)-1); + + if (NdisRequest !=(PNDIS_OID_REQUEST)-1) + { + MBB_NDIS_OID_STATE OldOidState; + + // + // The oid has not been competed + // + + Stats=(PNDIS_STATISTICS_INFO)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer; + + if (NdisStatus == NDIS_STATUS_SUCCESS) + { + + RtlZeroMemory(Stats, sizeof(*Stats)); + + Stats->Header.Type=NDIS_OBJECT_TYPE_DEFAULT; + Stats->Header.Revision=NDIS_STATISTICS_INFO_REVISION_1; + Stats->Header.Size=NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; + + Stats->SupportedStatistics = NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV | + NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS | + NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR | + NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV | + NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | + NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS | + NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT; + + + if (InBufferSize >= sizeof(*MbbStats)) + { + + MbbStats=(PMBB_PACKET_STATISTICS)InBuffer; + + Stats->ifHCInOctets = MbbStats->InOctets; + Stats->ifInDiscards = MbbStats->InDiscards; + Stats->ifInErrors = MbbStats->InErrors; + Stats->ifHCInUcastPkts = MbbStats->InPackets; + + Stats->ifHCOutOctets = MbbStats->OutOctets; + Stats->ifOutDiscards = MbbStats->OutDiscards; + Stats->ifOutErrors = MbbStats->OutErrors; + Stats->ifHCOutUcastPkts = MbbStats->OutPackets; + + NdisRequest->DATA.QUERY_INFORMATION.BytesWritten=sizeof(*Stats); + } + else + { + NdisStatus=NDIS_STATUS_FAILURE; + } + } + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Completing OID request to NDIS with status=%!status!", + Request->RequestId, NdisStatus + ); + + + RtlCopyMemory(Stats, &Adapter->Stats, sizeof(*Stats)); + + Stats->Header.Type=NDIS_OBJECT_TYPE_DEFAULT; + Stats->Header.Revision=NDIS_STATISTICS_INFO_REVISION_1; + Stats->Header.Size=NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; + + Stats->SupportedStatistics = NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV | + NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | + NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV; + + + NdisRequest->DATA.QUERY_INFORMATION.BytesWritten=sizeof(*Stats); + + NdisStatus = NDIS_STATUS_SUCCESS; + + } + + Request->OidContext.OidStatus = NdisStatus; + // + // Do not complete the OID request if the Oid handler is still running. + // Defer the OID completion to the Oid handler + // + OldOidState = MbbReqMgrGetSetOidState( + Request, + MbbNdisOidStateComplete + ); + if( OldOidState == MbbNdisOidStatePending || + OldOidState == MbbNdisOidStateDispatched ) + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Completing OID request in %!MbbOidState! to NDIS with status=%!status!", + Request->RequestId, OldOidState, NdisStatus + ); + OidName=GetOidName(NdisRequest->DATA.QUERY_INFORMATION.Oid); + OidNameLength=strlen(OidName)+1; + + MbbWriteEvent( + &REQUEST_COMPLETE_EVENT, + NULL, + NULL, + 10, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &NdisRequest, + sizeof(NdisRequest), + &NdisRequest->DATA.QUERY_INFORMATION.Oid, + sizeof(NdisRequest->DATA.QUERY_INFORMATION.Oid), + (PVOID)OidName, + OidNameLength, + &NdisRequest->RequestId, + sizeof(NdisRequest->RequestId), + &NdisRequest->RequestHandle, + sizeof(NdisRequest->RequestHandle), + &NdisRequest->RequestType, + sizeof(NdisRequest->RequestType), + &NdisRequest->DATA.QUERY_INFORMATION.BytesWritten, + sizeof(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten), + &NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded, + sizeof(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded), + &NdisStatus, + sizeof(NdisStatus) + ); + NdisMOidRequestComplete( + Adapter->MiniportAdapterHandle, + NdisRequest, + NdisStatus + ); + NdisRequest=NULL; + } + else + { + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Deferring oid completion in %!MbbOidState!", + Request->RequestId, OldOidState + ); + } + } + else + { + TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Oid already completed", + Request->RequestId + ); + + + } + + + return NDIS_STATUS_SUCCESS; + +} +#endif + + +// Device Services +#pragma warning(disable:6014) +NDIS_STATUS +MbbNdisDeviceServiceListStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + ULONG ElementCount = 0; + ULONG RequiredLength = 0; + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + PMBB_DEVICE_SERVICES_HEADER MbbDeviceServicesInfo = (PMBB_DEVICE_SERVICES_HEADER)InBuffer; + PMBB_DEVICE_SERVICE_ELEMENT MbbDeviceServiceElement = NULL; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + PMBB_DS CachedDSInfo = NULL; + ULONG i; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + // + // This function should only be called once when we initialize for caching + // the supported device list. From that point on, we should only be using + // the cached list (from MbbNdisEnumerateDeviceServices) + // + if( (MbbReqMgrIsInternalRequest( Request ) == FALSE) || + (MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE) ) + { + // Ignore unsolicited indications or stuff not due to internal requests + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] UNEXPECTED DEVICE_SERVICES list notification", + Request->RequestId + ); + NdisStatus = NDIS_STATUS_NOT_ACCEPTED; + break; + } + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + // + // There is no device service list on failure. + // + if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED DeviceServices request MbbStatus=%!MbbStatus!", + Request->RequestId, + MbbStatus + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + if( MbbDeviceServicesInfo == NULL || + InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_DEVICE_SERVICES_HEADER, MaxDSSSessions) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_DEVICE_SERVICES_HEADER, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_DEVICE_SERVICES_HEADER, MaxDSSSessions) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + // + // Cache everything in the device services state + // + Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )); + + ElementCount = MbbDeviceServicesInfo->DeviceServicesCount; + + if (ElementCount == 0) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Zero device services supported", + Request->RequestId + ); + + Adapter->DeviceServiceState.ServicesList = NULL; + Adapter->DeviceServiceState.ServicesCount = 0; + Adapter->DeviceServiceState.MaxDSSSessions = 0; + ASSERT(FALSE); + + NdisStatus = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + // Not worrying about the CIDs yet. Those will be checked in a bit + NtStatus = RtlULongMult( + ElementCount, + sizeof(MBB_DEVICE_SERVICE_ELEMENT), + &RequiredLength + ); + + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, ElementCount=%d MBB_DEVICE_SERVICE_ELEMENT size=%d", + Request->RequestId, + ElementCount, + sizeof(MBB_DEVICE_SERVICE_ELEMENT) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + NtStatus = RtlULongAdd( + RequiredLength, + FIELD_OFFSET(MBB_DEVICE_SERVICES_HEADER, ArrayElement), + &RequiredLength + ); + + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, RequiredLength=%d FIELD_OFFSET=%d", + Request->RequestId, + RequiredLength, + FIELD_OFFSET(MBB_DEVICE_SERVICES_HEADER, ArrayElement) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + if( InBufferSize < RequiredLength ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_DEVICE_SERVICES_HEADER, BufferSize[Received=%d Expected=%d] ServiceCount=%d", + Request->RequestId, + InBufferSize, + RequiredLength, + ElementCount + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + CachedDSInfo = ALLOCATE_NONPAGED_POOL(ElementCount * sizeof(MBB_DS)); + + if ( CachedDSInfo == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for MBB_DS list, ServiceCount=%d", + Request->RequestId, + ElementCount * sizeof(MBB_DS), + ElementCount + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + RtlZeroMemory(CachedDSInfo, ElementCount * sizeof(MBB_DS)); + + // Presaved so that we can cleanup easier + Adapter->DeviceServiceState.ServicesList = CachedDSInfo; + Adapter->DeviceServiceState.ServicesCount = 0; // Will be incremented as we add stuff in + Adapter->DeviceServiceState.MaxDSSSessions = MbbDeviceServicesInfo->MaxDSSSessions; + + + for (i = 0; i < ElementCount; i++) + { + + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbDeviceServicesInfo->ArrayElement[i].Offset, + MbbDeviceServicesInfo->ArrayElement[i].Size, + 512, + sizeof(ULONG) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Array element %d is not valid", Request->RequestId, i); + break; + } + + MbbDeviceServiceElement = (PMBB_DEVICE_SERVICE_ELEMENT)(((PUCHAR)MbbDeviceServicesInfo) + + MbbDeviceServicesInfo->ArrayElement[i].Offset); + + RequiredLength = FIELD_OFFSET(MBB_DEVICE_SERVICE_ELEMENT, CIDList) + + MbbDeviceServiceElement->CIDCount * sizeof(ULONG); + + if ( InBufferSize < RequiredLength + MbbDeviceServicesInfo->ArrayElement[i].Offset) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT remaining size for MBB_DEVICE_SERVICE_HEADER, BufferSize[Received=%d Expected=%d] ServiceIndex=%d", + Request->RequestId, + InBufferSize, + RequiredLength, + i + ); + + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + + // + // Copy it while swapping order + // + MBB_UUID_TO_HOST(&(CachedDSInfo[i].DeviceServiceId), + &MbbDeviceServiceElement->DeviceServiceId + ); + + // + // This is a direct mapping + // + CachedDSInfo[i].DSSCapability = MbbDeviceServiceElement->DSSPayload; + + CachedDSInfo[i].MaxDSSInstances = MbbDeviceServiceElement->MaxDSSInstances; + + if (MbbDeviceServiceElement->CIDCount != 0) + { + CachedDSInfo[i].CIDList = ALLOCATE_NONPAGED_POOL(MbbDeviceServiceElement->CIDCount * sizeof(ULONG)); + + if( CachedDSInfo[i].CIDList == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for CID list, ServiceIndex=%d", + Request->RequestId, + MbbDeviceServiceElement->CIDCount * sizeof(ULONG), + i + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + // + // Copy the CID list + // + CachedDSInfo[i].CIDCount = MbbDeviceServiceElement->CIDCount; + + RtlCopyMemory(CachedDSInfo[i].CIDList, + MbbDeviceServiceElement->CIDList, + MbbDeviceServiceElement->CIDCount * sizeof(ULONG) + ); + } + + // + // One more entry added + // + Adapter->DeviceServiceState.ServicesCount++; + + } + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + break; + } + } + while( FALSE ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + if (Adapter != NULL) + { + // Free anything that we have ended up allocating + FreeDeviceServiceState(&(Adapter->DeviceServiceState)); + } + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisDeviceServiceResponseStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + ULONG NdisDeviceServiceResponseSize = 0; + NDIS_WWAN_DEVICE_SERVICE_RESPONSE LocalNdisDeviceServiceResponse; + PNDIS_WWAN_DEVICE_SERVICE_RESPONSE NdisDeviceServiceResponse = NULL; + + do + { + RtlZeroMemory(&LocalNdisDeviceServiceResponse, sizeof(LocalNdisDeviceServiceResponse)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS ) + { + break; + } + + + if (InBufferSize > (ULONG_MAX - sizeof(NDIS_WWAN_DEVICE_SERVICE_RESPONSE))) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Device service response too big for NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE, VendorDataSize=%dBytes", + Request->RequestId, + InBufferSize + + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisDeviceServiceResponseSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_RESPONSE) + InBufferSize; + + if( (NdisDeviceServiceResponse = (PNDIS_WWAN_DEVICE_SERVICE_RESPONSE) ALLOCATE_NONPAGED_POOL(NdisDeviceServiceResponseSize)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to allocate memory for NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE, VendorDataSize=%dBytes", + Request->RequestId, + InBufferSize + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisDeviceServiceResponse->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceServiceResponse->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_RESPONSE_1; + NdisDeviceServiceResponse->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_RESPONSE_REVISION_1; + + NdisDeviceServiceResponse->Response.DeviceServiceGuid = Request->HandlerContext.Response.Command.ServiceId; + NdisDeviceServiceResponse->Response.ResponseID = Request->HandlerContext.Response.Command.CommandId; + NdisDeviceServiceResponse->Response.uDataSize = InBufferSize; + + // No fragmentation support + + if( InBufferSize != 0 ) + { + RtlCopyMemory( + NdisDeviceServiceResponse + 1, + InBuffer, + InBufferSize + ); + } + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if( NdisDeviceServiceResponse != NULL ) + { + StatusIndication.StatusBuffer = NdisDeviceServiceResponse; + StatusIndication.StatusBufferSize = NdisDeviceServiceResponseSize; + } + else + { + LocalNdisDeviceServiceResponse.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisDeviceServiceResponse.Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_RESPONSE_1; + LocalNdisDeviceServiceResponse.Header.Revision = NDIS_WWAN_DEVICE_SERVICE_RESPONSE_REVISION_1; + + LocalNdisDeviceServiceResponse.Response.DeviceServiceGuid = Request->HandlerContext.Response.Command.ServiceId; + LocalNdisDeviceServiceResponse.Response.ResponseID = Request->HandlerContext.Response.Command.CommandId; + LocalNdisDeviceServiceResponse.Response.uDataSize = 0; + + StatusIndication.StatusBuffer = &LocalNdisDeviceServiceResponse; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_RESPONSE); + } + ((PNDIS_WWAN_DEVICE_SERVICE_RESPONSE)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if( NdisDeviceServiceResponse != NULL ) + { + FREE_POOL( NdisDeviceServiceResponse ); + } + return (WwanStatus == WWAN_STATUS_SMS_MORE_DATA)? NDIS_STATUS_PENDING: NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisDeviceServiceEventStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + ULONG NdisDeviceServiceEventSize; + PNDIS_WWAN_DEVICE_SERVICE_EVENT NdisDeviceServiceEvent = NULL; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + NtStatus = RtlULongAdd( + InBufferSize, + sizeof(NDIS_WWAN_DEVICE_SERVICE_EVENT), + &NdisDeviceServiceEventSize + ); + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Addition overflow occured, InBufferSize=%d NDIS_WWAN_DEVICE_SERVICE_EVENT size=%d", + Request->RequestId, + InBufferSize, + sizeof(NDIS_WWAN_DEVICE_SERVICE_EVENT) + ); + break; + } + + if( (NdisDeviceServiceEvent = (PNDIS_WWAN_DEVICE_SERVICE_EVENT) ALLOCATE_NONPAGED_POOL(NdisDeviceServiceEventSize)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to allocate memory for NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT, VendorDataSize=%dBytes", + Request->RequestId, + InBufferSize + ); + break; + } + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + NdisDeviceServiceEvent->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceServiceEvent->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_EVENT_1; + NdisDeviceServiceEvent->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_EVENT_REVISION_1; + + NdisDeviceServiceEvent->Event.DeviceServiceGuid = Request->HandlerContext.Response.Command.ServiceId; + NdisDeviceServiceEvent->Event.EventID = Request->HandlerContext.Response.Command.CommandId; + NdisDeviceServiceEvent->Event.uDataSize = InBufferSize; + + if( InBufferSize != 0 ) + { + RtlCopyMemory( + NdisDeviceServiceEvent + 1, + InBuffer, + InBufferSize + ); + } + + StatusIndication.StatusBuffer = NdisDeviceServiceEvent; + StatusIndication.StatusBufferSize = NdisDeviceServiceEventSize; + + TraceInfo( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT", + Request->RequestId + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + } + while( FALSE ); + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + + if( NdisDeviceServiceEvent != NULL ) + { + FREE_POOL( NdisDeviceServiceEvent ); + } + return (WwanStatus == WWAN_STATUS_SMS_MORE_DATA)? NDIS_STATUS_PENDING: NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisDeviceServiceStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + if (!MbbUtilIsValidDeviceService(&(Request->HandlerContext.Response.Command.ServiceId))) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Dropping indication with invalid device service %!GUID!", + Request->RequestId, + &(Request->HandlerContext.Response.Command.ServiceId) + ); + return NDIS_STATUS_INVALID_DATA; + } + + if (MbbReqMgrIsUnsolicitedIndication(Request)) + { + // This is an event + return MbbNdisDeviceServiceEventStatusHandler(Request, + NdisStatus, + MbbStatus, + InBuffer, + InBufferSize + ); + } + else + { + // This is a response + return MbbNdisDeviceServiceResponseStatusHandler(Request, + NdisStatus, + MbbStatus, + InBuffer, + InBufferSize + ); + } +} + +NDIS_STATUS +MbbNdisVendorSpecificStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + ULONG NdisVendorSpecificResponseSize = 0; + NDIS_WWAN_VENDOR_SPECIFIC LocalNdisVendorSpecific; + PNDIS_WWAN_VENDOR_SPECIFIC NdisVendorSpecific = NULL; + + do + { + RtlZeroMemory(&LocalNdisVendorSpecific, sizeof(LocalNdisVendorSpecific)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_VENDOR_SPECIFIC + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_VENDOR_SPECIFIC, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if( WwanStatus != WWAN_STATUS_SUCCESS ) + { + break; + } + + + if (InBufferSize > (ULONG_MAX - sizeof(NDIS_WWAN_VENDOR_SPECIFIC))) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Vendor specific response too big for NDIS_STATUS_WWAN_VENDOR_SPECIFIC, VendorDataSize=%dBytes", + Request->RequestId, + InBufferSize + + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisVendorSpecificResponseSize = sizeof(NDIS_WWAN_VENDOR_SPECIFIC) + InBufferSize; + + if( (NdisVendorSpecific = (PNDIS_WWAN_VENDOR_SPECIFIC) ALLOCATE_NONPAGED_POOL(NdisVendorSpecificResponseSize)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to allocate memory for NDIS_STATUS_WWAN_VENDOR_SPECIFIC, VendorDataSize=%dBytes", + Request->RequestId, + InBufferSize + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisVendorSpecific->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisVendorSpecific->Header.Size = sizeof(NDIS_WWAN_VENDOR_SPECIFIC); + NdisVendorSpecific->Header.Revision = NDIS_WWAN_VENDOR_SPECIFIC_REVISION_1; + + NdisVendorSpecific->VendorSpecificData.uVendorSpecificBufferSize = InBufferSize; + + if( InBufferSize != 0 ) + { + RtlCopyMemory( + NdisVendorSpecific + 1, + InBuffer, + InBufferSize + ); + } + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if( NdisVendorSpecific != NULL ) + { + StatusIndication.StatusBuffer = NdisVendorSpecific; + StatusIndication.StatusBufferSize = NdisVendorSpecificResponseSize; + } + else + { + LocalNdisVendorSpecific.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisVendorSpecific.Header.Size = sizeof(NDIS_WWAN_VENDOR_SPECIFIC); + LocalNdisVendorSpecific.Header.Revision = NDIS_WWAN_VENDOR_SPECIFIC_REVISION_1; + + LocalNdisVendorSpecific.VendorSpecificData.uVendorSpecificBufferSize = 0; + + StatusIndication.StatusBuffer = &LocalNdisVendorSpecific; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_VENDOR_SPECIFIC); + } + + // WwanStatus is only used for trace purpose. NDIS_WWAN_VENDOR_SPECIFIC doesn't have uStaus field. + TraceInfo( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_VENDOR_SPECIFIC with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if( NdisVendorSpecific != NULL ) + { + FREE_POOL( NdisVendorSpecific ); + } + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSubscribeDeviceServiceEventsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_DEVICE_SERVICE_SUBSCRIPTION NdisDeviceServiceSubscription; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + + do + { + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + // + // We will be sending the notification up. + // If this is a set requested by the OS and the request + // succeeded, persist the radio state in registry and locally + // + if ((Request->OidContext.OidRequestId != 0) && + (MbbReqMgrIsSetOid( Request )) && + (WwanStatus == WWAN_STATUS_SUCCESS) ) + { + // + // OS initiated SET request that succeeded. The subscription + // list from the OS has been persisted in DataToFreeOnResponse + // Save it + // + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + MbbAdapterLock(Adapter); + if (Adapter->DeviceServiceState.ExtSubscribeList != NULL) + FREE_POOL( Adapter->DeviceServiceState.ExtSubscribeList ); + + Adapter->DeviceServiceState.ExtSubscribeList = + Request->HandlerContext.Parameters.EventSubscribe.ExtList; + Adapter->DeviceServiceState.ExtSubscribeListBufferSize = + Request->HandlerContext.Parameters.EventSubscribe.ExtSize; + + MbbAdapterUnlock(Adapter); + + // We have taken ownership of the pointer + Request->HandlerContext.DataToFreeOnResponse = NULL; + } + + } + while (FALSE); + + // + // If this is for an OS request, send the notification up + // + if( (MbbReqMgrIsInternalRequest( Request ) == FALSE)) + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION + ); + + NdisDeviceServiceSubscription.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceServiceSubscription.Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SUBSCRIPTION_1; + NdisDeviceServiceSubscription.Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SUBSCRIPTION_REVISION_1; + + NdisDeviceServiceSubscription.DeviceServiceListHeader.ElementType = WwanStructDeviceServiceGuid; + NdisDeviceServiceSubscription.DeviceServiceListHeader.ElementCount = 0; + + + NdisDeviceServiceSubscription.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisDeviceServiceSubscription; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SUBSCRIPTION); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + } + + return NdisStatus; +} + + +NDIS_STATUS +MbbNdisSetUSSD( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PMBB_SET_USSD MbbSetUSSD; + PNDIS_WWAN_USSD_REQUEST NdisUSSDRequest = (PNDIS_WWAN_USSD_REQUEST)InBuffer; + NDIS_STATUS Status; + ULONG MbbSetUSSDSize; + ULONG UssdStringLengthRounded; + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_USSD_REQUEST) ); + *InBufferSize = sizeof(NDIS_WWAN_USSD_REQUEST); + UssdStringLengthRounded = NdisUSSDRequest->UssdRequest.UssdString.StringLength; + UssdStringLengthRounded = ROUND_UP_COUNT( UssdStringLengthRounded, ALIGN_DWORD ); + // + // Both lengths are checked to detect overflow. + // + if( NdisUSSDRequest->UssdRequest.UssdString.StringLength > MBB_USSD_STRING_LEN_MAX || + UssdStringLengthRounded > MBB_USSD_STRING_LEN_MAX ) + { + TraceError( WMBCLASS_OID, "[MbbNdis] USSD string too long: 0x%x", + NdisUSSDRequest->UssdRequest.UssdString.StringLength + ); + Status = NDIS_STATUS_INVALID_LENGTH; + return Status; + } + + //determine length of buffer + MbbSetUSSDSize = FIELD_OFFSET(MBB_SET_USSD, DataBuffer); + MbbSetUSSDSize = ROUND_UP_COUNT( MbbSetUSSDSize, ALIGN_DWORD ); + MbbSetUSSDSize += UssdStringLengthRounded; + + if( (MbbSetUSSD = (PMBB_SET_USSD) ALLOCATE_NONPAGED_POOL( MbbSetUSSDSize )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSetUSSD; + + RtlZeroMemory( MbbSetUSSD, MbbSetUSSDSize ); + + Status = MbbUtilWwanToMbbSetUSSD( + MbbSetUSSD, + &NdisUSSDRequest->UssdRequest + ); + if (Status != NDIS_STATUS_SUCCESS){ + return Status; + } + + + return MbbUtilSetAttributeWithParameter( + Request, + (PCHAR)MbbSetUSSD, + MbbSetUSSDSize + ); +} + + + +NDIS_STATUS +MbbNdisUSSDStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_USSD_EVENT NdisWWanUSSDEvt; + PMBB_USSD MbbUSSDResponse = (PMBB_USSD)InBuffer; + NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; + + do + { + + RtlZeroMemory(&NdisWWanUSSDEvt, sizeof(NdisWWanUSSDEvt)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_USSD + ); + + NdisWWanUSSDEvt.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisWWanUSSDEvt.Header.Size = sizeof(NDIS_WWAN_USSD_EVENT); + NdisWWanUSSDEvt.Header.Revision = NDIS_WWAN_USSD_EVENT_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_USSD, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + // + // If the device returned MBIM error status and didnt provide any data + // propagate the error code to the service. Sometimes data can be sent + // by the device even if the device reports error. + // + if ( (WwanStatus != WWAN_STATUS_SUCCESS) && + InBufferSize < (ULONG)FIELD_OFFSET(MBB_USSD,DataBuffer) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Device FAILED USSD request, status=%!MbbStatus!", + Request->RequestId, + MbbStatus + ); + break; + } + + // + // the request succeeded, or if failed and returned a minimal valid buffer + // + + // + // Check for min or max data size from device + // + if( MbbUSSDResponse == NULL + || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_USSD,DataBuffer) + + ) + { + + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Insufficient BufferSize for NDIS_STATUS_WWAN_USSD, BufferSize[Received=%d Min Expected=%d", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_USSD,DataBuffer) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisStatus=MbbIsVariableFieldValid( + InBufferSize, + MbbUSSDResponse->USSDPayload.Offset, + MbbUSSDResponse->USSDPayload.Size, + MBB_USSD_STRING_LEN_MAX, + sizeof(UCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Incorrect BufferSize for NDIS_STATUS_WWAN_USSD, BufferSize[Received=%d Min Expected=%d payload=%d", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_USSD,DataBuffer), + MbbUSSDResponse->USSDPayload.Size + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + + } + + + LocalNdisStatus = MbbUtilMbbToWwanUSSDEvent( + MbbUSSDResponse, + &NdisWWanUSSDEvt.UssdEvent + ); + + if( LocalNdisStatus != NDIS_STATUS_SUCCESS ) + { + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + } + while( FALSE ); + + NdisWWanUSSDEvt.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisWWanUSSDEvt; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_USSD_EVENT); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_USSD with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisGetAuthChallenge( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + MBB_SIM_AUTH_CHALLENGE MbbSimAuthChallenge; + MBB_AKA_AUTH_CHALLENGE MbbAKAAuthChallenge; + PMBB_AKAP_AUTH_CHALLENGE MbbAKAPAuthChallenge; + + PNDIS_WWAN_AUTH_CHALLENGE NdisAuthRequest = (PNDIS_WWAN_AUTH_CHALLENGE)InBuffer; + NDIS_STATUS Status; + + // + // Size is already verified in MbbNdisMiniportOidRequest( ) + // + __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_AUTH_CHALLENGE) ); + *InBufferSize = sizeof(NDIS_WWAN_AUTH_CHALLENGE); + + if(NdisAuthRequest->AuthChallenge.AuthMethod == WwanAuthAka){ + RtlCopyMemory( &MbbAKAAuthChallenge, + &NdisAuthRequest->AuthChallenge.u.AuthAka, + sizeof(MbbAKAAuthChallenge) ); + + return MbbUtilQueryAttributeWithParameter( + Request, + (PCHAR)(&MbbAKAAuthChallenge), + sizeof(MbbAKAAuthChallenge) + ); + } + else if (NdisAuthRequest->AuthChallenge.AuthMethod == WwanAuthAkaPrime) + { + ULONG MbbSize; + ULONG UTF16ByteCount; + // + // Calculate required length + // + if (NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkNameLength > WWAN_AUTH_NETWORK_NAME_MAX_LEN) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] NetworkNameLength invalid, %d", + Request->RequestId, + NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkNameLength + ); + + return NDIS_STATUS_INVALID_PARAMETER; + } + + Status = RtlUTF8ToUnicodeN( + NULL, + 0, + &UTF16ByteCount, + (PCCH)(NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkName), + NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkNameLength + ); + if( STATUS_SUCCESS != Status ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED RtlUTF8ToUnicodeN(%s)=%!STATUS!, ignoring=%!BOOLEAN!", + Request->RequestId, + NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkName, + Status, + (STATUS_SOME_NOT_MAPPED == Status) + ); + if( STATUS_SOME_NOT_MAPPED != Status ) + return Status; + else + Status = STATUS_SUCCESS; + } + + MbbSize = ROUND_UP_COUNT( FIELD_OFFSET( MBB_AKAP_AUTH_CHALLENGE, DataBuffer ), ALIGN_DWORD ); + MbbSize += ROUND_UP_COUNT( UTF16ByteCount, ALIGN_DWORD ); + + // + // Allocate the buffer and convert + // + if( (MbbAKAPAuthChallenge = (PMBB_AKAP_AUTH_CHALLENGE) ALLOCATE_NONPAGED_POOL( MbbSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate AuthAkapChallenge for %dbytes", + Request->RequestId, + MbbSize + ); + return NDIS_STATUS_RESOURCES; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbAKAPAuthChallenge; + + if( (Status = MbbUtilWwanToMbbAkapAuthChallenge( + &NdisAuthRequest->AuthChallenge.u.AuthAkap, + UTF16ByteCount, + MbbSize, + MbbAKAPAuthChallenge + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to convert AuthAkapChallenge, NtStatus=%!STATUS!", + Request->RequestId, + Status + ); + return Status; + } + return MbbUtilQueryAttributeWithParameter( + Request, + (PCHAR)MbbAKAPAuthChallenge, + MbbSize + ); + } + else if (NdisAuthRequest->AuthChallenge.AuthMethod == WwanAuthSim){ + RtlCopyMemory( &MbbSimAuthChallenge, + &NdisAuthRequest->AuthChallenge.u.AuthSim, + sizeof(MbbSimAuthChallenge) ); + + return MbbUtilQueryAttributeWithParameter( + Request, + (PCHAR)(&MbbSimAuthChallenge), + sizeof(MbbSimAuthChallenge) + ); + } + else{ + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] AUTH CHALLENGE specified is invalid, %d", + Request->RequestId, + NdisAuthRequest->AuthChallenge.AuthMethod); + return NDIS_STATUS_INVALID_PARAMETER; + } +} + +NDIS_STATUS +MbbNdisAuthAKAStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_AUTH_RESPONSE NdisWWanAuthRes; + PMBB_AKA_AUTH_RESPONSE MbbAuthResponse = (PMBB_AKA_AUTH_RESPONSE)InBuffer; + NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; + + do + { + RtlZeroMemory(&NdisWWanAuthRes, sizeof(NdisWWanAuthRes)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_AUTH_RESPONSE + ); + + NdisWWanAuthRes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisWWanAuthRes.Header.Size = sizeof(NDIS_WWAN_AUTH_RESPONSE); + NdisWWanAuthRes.Header.Revision = NDIS_WWAN_AUTH_CHALLENGE_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_AUTH_RESPONSE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + // + // On certain error statuses there might be valid data + // + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + if( WwanStatus != WWAN_STATUS_SUCCESS && + WwanStatus != WWAN_STATUS_AUTH_SYNC_FAILURE ) + { + break; + } + + if( MbbAuthResponse == NULL || + InBufferSize < sizeof(*MbbAuthResponse) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_WWAN_AUTH_RESPONSE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(*MbbAuthResponse) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // + // Convert from MBB to WWAN messages. + // + RtlCopyMemory( &NdisWWanAuthRes.AuthResponse.u.AuthAka, + MbbAuthResponse, + sizeof(*MbbAuthResponse) ); + + + } + while( FALSE ); + // + // On internal error do not restore the device returned operational status + // since the service may be expecting certain data on certain status. + // + NdisWWanAuthRes.uStatus = WwanStatus; + NdisWWanAuthRes.AuthResponse.AuthMethod = WwanAuthAka; + + StatusIndication.StatusBuffer = &NdisWWanAuthRes; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_AUTH_RESPONSE); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_WWAN_AUTH_RESPONSE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + + +NDIS_STATUS +MbbNdisAuthAKAPStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_AUTH_RESPONSE NdisWWanAuthRes; + PMBB_AKAP_AUTH_RESPONSE MbbAuthResponse = (PMBB_AKAP_AUTH_RESPONSE)InBuffer; + NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; + + do + { + RtlZeroMemory(&NdisWWanAuthRes, sizeof(NdisWWanAuthRes)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_AUTH_RESPONSE + ); + + NdisWWanAuthRes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisWWanAuthRes.Header.Size = sizeof(NDIS_WWAN_AUTH_RESPONSE); + NdisWWanAuthRes.Header.Revision = NDIS_WWAN_AUTH_CHALLENGE_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_AUTH_RESPONSE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + // + // On certain error statuses there might be valid data + // + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + if( WwanStatus != WWAN_STATUS_SUCCESS && + WwanStatus != WWAN_STATUS_AUTH_SYNC_FAILURE ) + { + break; + } + + if( MbbAuthResponse == NULL || + InBufferSize < sizeof(*MbbAuthResponse) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_WWAN_AUTH_RESPONSE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(*MbbAuthResponse) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // + // Convert from MBB to WWAN messages. + // + RtlCopyMemory( &NdisWWanAuthRes.AuthResponse.u.AuthAkap, + MbbAuthResponse, + sizeof(*MbbAuthResponse) ); + + + } + while( FALSE ); + // + // On internal error do not restore the device returned operational status + // since the service may be expecting certain data on certain status. + // + NdisWWanAuthRes.uStatus = WwanStatus; + NdisWWanAuthRes.AuthResponse.AuthMethod = WwanAuthAkaPrime; + + StatusIndication.StatusBuffer = &NdisWWanAuthRes; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_AUTH_RESPONSE); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_WWAN_AUTH_RESPONSE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + + +NDIS_STATUS +MbbNdisAuthSIMStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_AUTH_RESPONSE NdisWWanAuthRes; + PMBB_SIM_AUTH_RESPONSE MbbAuthResponse = (PMBB_SIM_AUTH_RESPONSE)InBuffer; + NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; + + do + { + RtlZeroMemory(&NdisWWanAuthRes, sizeof(NdisWWanAuthRes)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_AUTH_RESPONSE + ); + + NdisWWanAuthRes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisWWanAuthRes.Header.Size = sizeof(NDIS_WWAN_AUTH_RESPONSE); + NdisWWanAuthRes.Header.Revision = NDIS_WWAN_AUTH_CHALLENGE_REVISION_1; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_AUTH_RESPONSE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + if (WwanStatus != WWAN_STATUS_SUCCESS){ + break; + } + + if( MbbAuthResponse == NULL || + InBufferSize < sizeof(*MbbAuthResponse) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_WWAN_AUTH_RESPONSE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(*MbbAuthResponse) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // + // Convert from MBB to WWAN messages. + // + RtlCopyMemory( &NdisWWanAuthRes.AuthResponse.u.AuthSim, + MbbAuthResponse, + sizeof(*MbbAuthResponse) ); + + + } + while( FALSE ); + + NdisWWanAuthRes.uStatus = WwanStatus; + NdisWWanAuthRes.AuthResponse.AuthMethod = WwanAuthSim; + + StatusIndication.StatusBuffer = &NdisWWanAuthRes; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_AUTH_RESPONSE); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_WWAN_AUTH_RESPONSE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + + + +NDIS_STATUS +MbbNdisDssStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize, + __in WWAN_DEVICE_SERVICE_SESSION_STATE NewState + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_DEVICE_SERVICE_SESSION_INFO NdisWWanSessionInfo; + NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; + + if (MbbReqMgrIsUnsolicitedIndication(Request)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Dropping unsolicited Device Service Session state notification", + Request->RequestId + ); + return NDIS_STATUS_NOT_ACCEPTED; + } + + do + { + + RtlZeroMemory(&NdisWWanSessionInfo, sizeof(NdisWWanSessionInfo)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION + ); + + NdisWWanSessionInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisWWanSessionInfo.Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_INFO_1; + NdisWWanSessionInfo.Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SESSION_INFO_REVISION_1; + + // + // Populate the saved info for the request + // + NdisWWanSessionInfo.Session.State = Request->HandlerContext.Parameters.DssSession.LinkState == MbbDssLinkActivate ? + WwanDeviceServiceSessionOpen : WwanDeviceServiceSessionClosed; + + RtlCopyMemory( + &NdisWWanSessionInfo.Session.DeviceServiceGuid, + &Request->HandlerContext.Parameters.DssSession.DeviceServiceGuid, + sizeof(GUID) + ); + + NdisWWanSessionInfo.Session.uSessionID = Request->HandlerContext.Parameters.DssSession.SessionId; + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + if (WwanStatus != WWAN_STATUS_SUCCESS){ + break; + } + + } + while( FALSE ); + + NdisWWanSessionInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisWWanSessionInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_INFO); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + + + +NDIS_STATUS +MbbNdisDssOpenStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + // Forward to the generic handler + return MbbNdisDssStateStatusHandler( + Request, + NdisStatus, + MbbStatus, + InBuffer, + InBufferSize, + WwanDeviceServiceSessionOpen + ); +} + + +NDIS_STATUS +MbbNdisDssCloseStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + // Forward to the generic handler + return MbbNdisDssStateStatusHandler( + Request, + NdisStatus, + MbbStatus, + InBuffer, + InBufferSize, + WwanDeviceServiceSessionClosed + ); + +} + + +NDIS_STATUS +MbbNdisDssWriteCompleteStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE NdisDssWriteComplete; + + do + { + + RtlZeroMemory(&NdisDssWriteComplete, sizeof(NdisDssWriteComplete)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE + ); + + NdisDssWriteComplete.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDssWriteComplete.Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE_1; + NdisDssWriteComplete.Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE_REVISION_1; + + WwanStatus = MbbUtilNdisToWwanStatus( NdisStatus ); + if (WwanStatus != WWAN_STATUS_SUCCESS) + break; + + } + while( FALSE ); + + NdisDssWriteComplete.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisDssWriteComplete; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + // Derefence the request + MbbReqMgrDerefRequest(Request); + + return NDIS_STATUS_SUCCESS; +} + + +VOID +MbbNdisDeviceServiceSessionSendComplete( + __in MBB_REQUEST_HANDLE RequestHandle, + __in NDIS_STATUS NdisStatus + ) +{ + PMBB_OID_HANDLER_ENTRY OidHandler; + + OidHandler = MbbNdisGetOidHandler(OID_WWAN_DEVICE_SERVICE_SESSION_WRITE); + + if (OidHandler) + { + // Call the common handler to handle the indication + MbbUtilCommonCIDResponse( + (PMBB_REQUEST_CONTEXT)RequestHandle, + NdisStatus, + WWAN_STATUS_SUCCESS, + NULL, + 0, + OidHandler + ); + } +} + +NDIS_STATUS +MbbNdisDeviceServiceSessionReceive( + __in PMINIPORT_ADAPTER_CONTEXT AdapterContext, + __in ULONG SessionId, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + NDIS_STATUS_INDICATION StatusIndication; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ NdisWwanDssRead = NULL; + ULONG TotalNdisWwanSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_READ) + InBufferSize; + + do + { + // Allocate memory for the output buffer + if( (NdisWwanDssRead = (PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ) ALLOCATE_NONPAGED_POOL( TotalNdisWwanSize )) == NULL ) + { + TraceError( WMBCLASS_RECEIVE, "[Receive][DSS Read] FAILED to allocate for PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ %d bytes", + TotalNdisWwanSize + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + NdisWwanDssRead->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisWwanDssRead->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_READ_1; + NdisWwanDssRead->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SESSION_READ_REVISION_1; + + NdisWwanDssRead->ReadData.uDataSize = InBufferSize; + NdisWwanDssRead->ReadData.uSessionID = SessionId; + + // Copy the data. We cannot use the original buffer because it doesnt + // have space for the session Id, etc + RtlCopyMemory( + (PUCHAR)(NdisWwanDssRead + 1), + InBuffer, + InBufferSize + ); + + // Create the status indication + MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION( + &StatusIndication, + AdapterContext->MiniportAdapterHandle, + NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ + ); + + StatusIndication.StatusBuffer = NdisWwanDssRead; + StatusIndication.StatusBufferSize = TotalNdisWwanSize; + + TraceInfo( WMBCLASS_RECEIVE, "[Receive][DSS Read] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ"); + + MbbUtilNdisMiniportIndicateStatusEx( + AdapterContext, + &StatusIndication + ); + + } + while( FALSE ); + + if (NdisWwanDssRead) + { + FREE_POOL(NdisWwanDssRead); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisMultiCarrierDsCidListStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + GUID DsServiceId; + ULONG CidIndex; + ULONG ExpectedSize; + WWAN_STATUS WwanStatus; + PMINIPORT_ADAPTER_CONTEXT Adapter; + PMBB_MULTICARRIER_CURRENT_CID_LIST MbbMulticarrierCidList; + + do + { + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ); + // + // If we couldnt retrieve the data then bail out. + // + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to get data for MBB_MULTICARRIER_CID_CURRENT_CID_LIST, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + if( WWAN_STATUS_SUCCESS != WwanStatus ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to get data for MBB_MULTICARRIER_CID_CURRENT_CID_LIST, status=%!STATUS!", + Request->RequestId, + WwanStatus + ); + break; + } + // + // Verify the received data + // + MbbMulticarrierCidList = (PMBB_MULTICARRIER_CURRENT_CID_LIST)InBuffer; + ExpectedSize = RTL_SIZEOF_THROUGH_FIELD(MBB_MULTICARRIER_CURRENT_CID_LIST, CIDCount); + + if( MbbMulticarrierCidList == NULL || + InBufferSize < ExpectedSize ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_MULTICARRIER_CID_CURRENT_CID_LIST, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + ExpectedSize + ); + break; + } + + NdisStatus = RtlULongMult( + sizeof(ULONG), + MbbMulticarrierCidList->CIDCount, + &ExpectedSize + ); + if( NT_ERROR( NdisStatus ) ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INTEGER OVERFLOW : 0x%x * 0x%x = 0x%I64x", + Request->RequestId, + MbbMulticarrierCidList->CIDCount, + sizeof(ULONG), + ((ULONGLONG)(MbbMulticarrierCidList->CIDCount)) * sizeof(ULONG) + ); + break; + } + + NdisStatus = RtlULongAdd( + ExpectedSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_MULTICARRIER_CURRENT_CID_LIST, CIDCount), + &ExpectedSize + ); + if( NT_ERROR( NdisStatus ) ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INTEGER OVERFLOW : 0x%x + 0x%x = 0x%I64x", + Request->RequestId, + ExpectedSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_MULTICARRIER_CURRENT_CID_LIST, CIDCount), + ((ULONGLONG)ExpectedSize) + RTL_SIZEOF_THROUGH_FIELD(MBB_MULTICARRIER_CURRENT_CID_LIST, CIDCount) + ); + break; + } + + if( InBufferSize < ExpectedSize ) + { + TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_MULTICARRIER_CID_CURRENT_CID_LIST, CidCount=%d BufferSize[Received=%d Expected=%d]", + Request->RequestId, + MbbMulticarrierCidList->CIDCount, + InBufferSize, + ExpectedSize + ); + break; + } + // + // There is valid data, convert the CIDList to capabilities + // + MBB_UUID_TO_NET( + &DsServiceId, + &Request->HandlerContext.Parameters.DeviceCaps.CurrentQueriedDeviceService + ); + if( RtlCompareMemory( + &DsServiceId, + &MBB_UUID_USSD, + sizeof(GUID) + ) == sizeof(GUID) ) + { + if( MbbMulticarrierCidList->CIDCount > 0 ) + { + MbbAdapterLock( Adapter ); + Adapter->AdapterFlags.IsUssdCapable = TRUE; + MbbAdapterUnlock( Adapter ); + } + Request->HandlerContext.Parameters.DeviceCaps.IsUssdCapsValid = 1; + } else if( RtlCompareMemory( + &DsServiceId, + &MBB_UUID_AUTH, + sizeof(GUID) + ) == sizeof(GUID) ) + { + MbbAdapterLock( Adapter ); + for(CidIndex = 0; + CidIndex < MbbMulticarrierCidList->CIDCount; + CidIndex++ ) + { + switch( MbbMulticarrierCidList->CIDList[CidIndex] ) + { + case MBB_AUTH_CID_AKA: + { + Adapter->AdapterFlags.IsAkaAuthCapable = TRUE; + } + break; + + case MBB_AUTH_CID_AKAP: + { + Adapter->AdapterFlags.IsAkapAuthCapable = TRUE; + } + break; + + case MBB_AUTH_CID_SIM: + { + Adapter->AdapterFlags.IsSimAuthCapable = TRUE; + } + break; + } + } + MbbAdapterUnlock( Adapter ); + Request->HandlerContext.Parameters.DeviceCaps.IsAuthCapsValid = 1; + } + } + while( FALSE ); + + MbbNdisIndicateDeviceCaps( + Request, + NdisStatus + ); + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisUiccAppListStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +) +{ + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_UICC_APP_LIST NdisUiccAppList; + PMBB_UICC_APP_LIST MbbUiccAppList = (PMBB_UICC_APP_LIST)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_UICC_APP_LIST + ); + + RtlZeroMemory(&NdisUiccAppList, sizeof(NdisUiccAppList)); + + NdisUiccAppList.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisUiccAppList.Header.Size = sizeof(NDIS_WWAN_UICC_APP_LIST); + NdisUiccAppList.Header.Revision = NDIS_WWAN_UICC_APP_LIST_REVISION_1; + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_APP_LIST, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbUiccAppList == NULL || + InBufferSize < sizeof(MBB_UICC_APP_LIST)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_APP_LIST, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_UICC_APP_LIST) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanUiccAppList( + MbbUiccAppList, + &NdisUiccAppList.UiccAppList + ); + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisUiccAppList.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisUiccAppList; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_APP_LIST); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_APP_LIST with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisUiccFileStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_UICC_FILE_STATUS NdisUiccFileStatus; + PMBB_UICC_FILE_STATUS MbbUiccFileStatus = (PMBB_UICC_FILE_STATUS)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_UICC_FILE_STATUS + ); + + RtlZeroMemory(&NdisUiccFileStatus, sizeof(NdisUiccFileStatus)); + + NdisUiccFileStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisUiccFileStatus.Header.Size = sizeof(NDIS_WWAN_UICC_FILE_STATUS); + NdisUiccFileStatus.Header.Revision = NDIS_WWAN_UICC_FILE_STATUS_REVISION_1; + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_FILE_STATUS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbUiccFileStatus == NULL || + InBufferSize < sizeof(MBB_UICC_FILE_STATUS) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_FILE_STATUS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_UICC_FILE_STATUS) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanUiccFileStatus( + MbbUiccFileStatus, + &NdisUiccFileStatus.UiccFileStatus + ); + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisUiccFileStatus.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisUiccFileStatus; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_FILE_STATUS); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_FILE_STATUS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisUiccAccessStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + ULONG NdisUiccResponseSize = 0; + PNDIS_WWAN_UICC_RESPONSE NdisUiccResponse = NULL; + NDIS_WWAN_UICC_RESPONSE LocalNdisUiccResponse; + PMBB_UICC_RESPONSE MbbUiccResponse = (PMBB_UICC_RESPONSE)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_UICC_RESPONSE + ); + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_RESPONSE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbUiccResponse == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_UICC_RESPONSE, DataBuffer)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_RESPONSE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_UICC_RESPONSE, DataBuffer) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisUiccResponseSize = FIELD_OFFSET(NDIS_WWAN_UICC_RESPONSE, UiccResponse.ResponseData); + NdisUiccResponseSize += MbbUiccResponse->ResponseData.Size; + + NdisUiccResponse = (PNDIS_WWAN_UICC_RESPONSE)ALLOCATE_NONPAGED_POOL( NdisUiccResponseSize ); + + if( NdisUiccResponse == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_UICC_RESPONSE", + Request->RequestId, + NdisUiccResponseSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisUiccResponse, NdisUiccResponseSize); + + NdisUiccResponse->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisUiccResponse->Header.Size = sizeof(NDIS_WWAN_UICC_RESPONSE); + NdisUiccResponse->Header.Revision = NDIS_WWAN_UICC_RESPONSE_REVISION_1; + + MbbUtilMbbToWwanUiccResponse( + MbbUiccResponse, + &NdisUiccResponse->UiccResponse + ); + IndicationFailure = FALSE; + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if (!IndicationFailure) + { + NdisUiccResponse->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisUiccResponse; + StatusIndication.StatusBufferSize = NdisUiccResponseSize; + } + else + { + RtlZeroMemory(&LocalNdisUiccResponse, sizeof(NDIS_WWAN_UICC_RESPONSE)); + + LocalNdisUiccResponse.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisUiccResponse.Header.Size = sizeof(NDIS_WWAN_UICC_RESPONSE); + LocalNdisUiccResponse.Header.Revision = NDIS_WWAN_UICC_RESPONSE_REVISION_1; + LocalNdisUiccResponse.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisUiccResponse; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_RESPONSE); + } + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_RESPONSE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisUiccResponse != NULL) + { + FREE_POOL(NdisUiccResponse); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSysCapsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + NDIS_WWAN_SYS_CAPS_INFO NdisSysCapsInfo = { 0 }; + PMBB_MS_SYS_CAPS_INFO MbbSysCapsInfo = (PMBB_MS_SYS_CAPS_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SYS_CAPS_INFO + ); + + RtlZeroMemory(&NdisSysCapsInfo, sizeof(NDIS_WWAN_SYS_CAPS_INFO)); + + NdisSysCapsInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSysCapsInfo.Header.Size = sizeof(NDIS_WWAN_SYS_CAPS_INFO); + NdisSysCapsInfo.Header.Revision = NDIS_WWAN_SYS_CAPS_INFO_REVISION_1; + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SYS_CAPS_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbSysCapsInfo == NULL || + InBufferSize < sizeof(MBB_MS_SYS_CAPS_INFO)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SYS_CAPS_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_MS_SYS_CAPS_INFO) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanSysCapsInfo( + MbbSysCapsInfo, + &(NdisSysCapsInfo.SysCapsInfo) + ); + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisSysCapsInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisSysCapsInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SYS_CAPS_INFO); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SYS_CAPS_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisDeviceCapsExStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + BOOLEAN IsMultiMode = FALSE; + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + ULONG NdisDeviceCapsExSize = 0; + PNDIS_WWAN_DEVICE_CAPS_EX NdisDeviceCapsEx = NULL; + NDIS_WWAN_DEVICE_CAPS_EX LocalNdisDeviceCapsEx = { 0 }; + PMBB_MS_DEVICE_CAPS_INFO_V2 MbbDeviceCapsEx2 = (PMBB_MS_DEVICE_CAPS_INFO_V2)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_CAPS_EX + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_CAPS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbDeviceCapsEx2 == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_MS_DEVICE_CAPS_INFO_V2, DataBuffer)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_DEVICE_CAPS_EX, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_MS_DEVICE_CAPS_INFO_V2, DataBuffer) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbDeviceCapsEx2->CustomDataClass.Offset, + MbbDeviceCapsEx2->CustomDataClass.Size, + MBB_MAXIMUM_DATA_CLASS_NAME_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad custom data field, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + MbbDeviceCapsEx2->CustomDataClass.Offset, + MbbDeviceCapsEx2->CustomDataClass.Size, + InBufferSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbDeviceCapsEx2->DeviceIdString.Offset, + MbbDeviceCapsEx2->DeviceIdString.Size, + MBB_MAXIMUM_DEVICE_ID_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] DeviceId data field, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + MbbDeviceCapsEx2->DeviceIdString.Offset, + MbbDeviceCapsEx2->DeviceIdString.Size, + InBufferSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbDeviceCapsEx2->FirmwareInfo.Offset, + MbbDeviceCapsEx2->FirmwareInfo.Size, + MBB_MAXIMUM_FIRMWARE_INFO_LENGTH, + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FirmwareInfo data field, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + MbbDeviceCapsEx2->FirmwareInfo.Offset, + MbbDeviceCapsEx2->FirmwareInfo.Size, + InBufferSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisDeviceCapsExSize = sizeof(NDIS_WWAN_DEVICE_CAPS_EX); + // If only a single bit is set in CellularClass then the following expression should be zero. + // Otherwise the following expression should be non-zero. + IsMultiMode = (((MbbDeviceCapsEx2->CellularClass) & (MbbDeviceCapsEx2->CellularClass - 1)) != 0); + if (IsMultiMode) + { + NdisDeviceCapsExSize += sizeof(WWAN_CELLULAR_CLASS) * (MbbCellularClassMaximum - 1); + } + + NdisDeviceCapsEx = (PNDIS_WWAN_DEVICE_CAPS_EX)ALLOCATE_NONPAGED_POOL(NdisDeviceCapsExSize); + + if (NdisDeviceCapsEx == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_DEVICE_CAPS", + Request->RequestId, + NdisDeviceCapsExSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisDeviceCapsEx, NdisDeviceCapsExSize); + + NdisDeviceCapsEx->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceCapsEx->Header.Size = sizeof(NDIS_WWAN_DEVICE_CAPS_EX); + NdisDeviceCapsEx->Header.Revision = NDIS_WWAN_DEVICE_CAPS_EX_REVISION_1; + + // We need the Adapter to retrieve the Manufacturer and Model which are absent in MBB_MS_DEVICE_CAPS_INFO_V2. + Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + + MbbUtilMbbToWwanDeviceCapsV2( + MbbDeviceCapsEx2, + Adapter->BusParams.Manufacturer, + MAX_PARAMETER_STRING, + Adapter->BusParams.Model, + MAX_PARAMETER_STRING, + &(NdisDeviceCapsEx->DeviceCaps), + IsMultiMode + ); + + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps = WWAN_OPTIONAL_SERVICE_CAPS_NONE; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsProvisionedContextV2Capable ? WWAN_OPTIONAL_SERVICE_CAPS_PROVISIONED_CONTEXT_MGMT : 0; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsNetworkBlacklistCapable ? WWAN_OPTIONAL_SERVICE_CAPS_NETWORK_BLACKLIST : 0; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsLTEAttachConfigCapable ? WWAN_OPTIONAL_SERVICE_CAPS_LTE_ATTACH : 0; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsMultiSIMCapable ? WWAN_OPTIONAL_SERVICE_CAPS_MULTI_SIM : 0; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsSARCapable ? WWAN_OPTIONAL_SERVICE_CAPS_SAR : 0; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsPcoCapable ? WWAN_OPTIONAL_SERVICE_CAPS_PCO : 0; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsUiccLowLevelCapable ? WWAN_OPTIONAL_SERVICE_CAPS_UICC_RESET : 0; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsDeviceResetCapable ? WWAN_OPTIONAL_SERVICE_CAPS_DEVICE_RESET : 0; + NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= + Adapter->AdapterFlags.IsBaseStationsInfoCapable ? WWAN_OPTIONAL_SERVICE_CAPS_BASE_STATIONS_INFO : 0; + + IndicationFailure = FALSE; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + if (!IndicationFailure) + { + NdisDeviceCapsEx->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisDeviceCapsEx; + StatusIndication.StatusBufferSize = NdisDeviceCapsExSize; + } + else + { + RtlZeroMemory(&LocalNdisDeviceCapsEx, sizeof(NDIS_WWAN_DEVICE_CAPS_EX)); + + LocalNdisDeviceCapsEx.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisDeviceCapsEx.Header.Size = sizeof(NDIS_WWAN_DEVICE_CAPS_EX); + LocalNdisDeviceCapsEx.Header.Revision = NDIS_WWAN_DEVICE_CAPS_EX_REVISION_1; + LocalNdisDeviceCapsEx.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisDeviceCapsEx; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_CAPS_EX); + } + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_CAPS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisDeviceCapsEx != NULL) + { + FREE_POOL(NdisDeviceCapsEx); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSysSlotMappingsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + ULONG NdisDeviceSlotMappingInfoSize = 0; + PNDIS_WWAN_DEVICE_SLOT_MAPPING_INFO NdisDeviceSlotMappingInfo = NULL; + NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO LocalNdisDeviceSlotMappingInfo = { 0 }; + PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbDeviceSlotMappingInfo = (PMBB_MS_DEVICE_SLOT_MAPPING_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbDeviceSlotMappingInfo == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_MS_DEVICE_SLOT_MAPPING_INFO, SlotMapList)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_MS_DEVICE_SLOT_MAPPING_INFO, SlotMapList) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisStatus = MbbIsArrayFieldValid( + InBufferSize, + MbbDeviceSlotMappingInfo->SlotMapList[0].Offset, + MbbDeviceSlotMappingInfo->MapCount, + sizeof(ULONG) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad slot map list, Offset=%d, ElementCount=%d, ElementSize=%d, ReceivedSize=%d", + Request->RequestId, + MbbDeviceSlotMappingInfo->SlotMapList[0].Offset, + MbbDeviceSlotMappingInfo->MapCount, + sizeof(ULONG), + InBufferSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisDeviceSlotMappingInfoSize = sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO); + NdisDeviceSlotMappingInfoSize += sizeof(ULONG) * (MbbDeviceSlotMappingInfo->MapCount); + + NdisDeviceSlotMappingInfo = (PNDIS_WWAN_DEVICE_SLOT_MAPPING_INFO)ALLOCATE_NONPAGED_POOL(NdisDeviceSlotMappingInfoSize); + + if (NdisDeviceSlotMappingInfo == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO", + Request->RequestId, + NdisDeviceSlotMappingInfoSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisDeviceSlotMappingInfo, NdisDeviceSlotMappingInfoSize); + + NdisDeviceSlotMappingInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceSlotMappingInfo->Header.Size = sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO); + NdisDeviceSlotMappingInfo->Header.Revision = NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO_REVISION_1; + + MbbUtilMbbToWwanDeviceSlotMappingInfo( + MbbDeviceSlotMappingInfo, + &(NdisDeviceSlotMappingInfo->DeviceSlotMappingInfo) + ); + IndicationFailure = FALSE; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + if (!IndicationFailure) + { + NdisDeviceSlotMappingInfo->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisDeviceSlotMappingInfo; + StatusIndication.StatusBufferSize = NdisDeviceSlotMappingInfoSize; + } + else + { + RtlZeroMemory(&LocalNdisDeviceSlotMappingInfo, sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO)); + + LocalNdisDeviceSlotMappingInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisDeviceSlotMappingInfo.Header.Size = sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO); + LocalNdisDeviceSlotMappingInfo.Header.Revision = NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO_REVISION_1; + LocalNdisDeviceSlotMappingInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisDeviceSlotMappingInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO); + } + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisDeviceSlotMappingInfo != NULL) + { + FREE_POOL(NdisDeviceSlotMappingInfo); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSlotInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + NDIS_WWAN_SLOT_INFO NdisSlotInfo = { 0 }; + PMBB_MS_SLOT_INFO MbbSlotInfo = (PMBB_MS_SLOT_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SLOT_INFO + ); + + RtlZeroMemory(&NdisSlotInfo, sizeof(NDIS_WWAN_SLOT_INFO)); + + NdisSlotInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSlotInfo.Header.Size = sizeof(NDIS_WWAN_SLOT_INFO); + NdisSlotInfo.Header.Revision = NDIS_WWAN_SLOT_INFO_REVISION_1; + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SLOT_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbSlotInfo == NULL || + InBufferSize < sizeof(MBB_MS_SLOT_INFO)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SLOT_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_MS_SLOT_INFO) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanSlotInfo( + MbbSlotInfo, + &(NdisSlotInfo.SlotInfo) + ); + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisSlotInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisSlotInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SLOT_INFO); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SLOT_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisDeviceBindingsStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + ULONG NdisDeviceBindingsInfoSize = 0; + PNDIS_WWAN_DEVICE_BINDINGS_INFO NdisDeviceBindingsInfo = NULL; + NDIS_WWAN_DEVICE_BINDINGS_INFO LocalNdisDeviceBindingsInfo = { 0 }; + PMBB_DEVICE_BINDINGS_INFO MbbDeviceBindingsInfo = (PMBB_DEVICE_BINDINGS_INFO)InBuffer; + ULONG AppCount = 0; + ULONG AppIndex = 0; + PMBB_ARRAY_ELEMENT AppId = NULL; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbDeviceBindingsInfo == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_DEVICE_BINDINGS_INFO, ApplicationList)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_DEVICE_BINDINGS_INFO, ApplicationList) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + AppCount = MbbDeviceBindingsInfo->ApplicationCount; + for (AppIndex = 0; AppIndex < AppCount; AppIndex++) + { + // Check whether the struct MBB_UICC_FILE_PATH is valid. + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Offset, + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Size, + FIELD_OFFSET(MBB_UICC_FILE_PATH, DataBuffer) + sizeof(BYTE) * WWAN_UICC_APP_ID_MAX_LEN + sizeof(USHORT) * WWAN_UICC_FILE_PATH_MAX_LEN, + sizeof(BYTE) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad MBB_UICC_FILE_PATH for app %d, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + AppIndex, + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Offset, + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Size, + InBufferSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // Check whether the AppId in the struct MBB_UICC_FILE_PATH is valid. Note that the FilePath in the struct MBB_UICC_FILE_PATH is not used. + AppId = &(((PMBB_UICC_FILE_PATH)((PUCHAR)MbbDeviceBindingsInfo + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Offset))->AppId); + NdisStatus = MbbIsVariableFieldValid( + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Size, + AppId->Offset, + AppId->Size, + WWAN_UICC_APP_ID_MAX_LEN, + sizeof(BYTE) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad AppId for app %d, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + AppIndex, + AppId->Offset, + AppId->Size, + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + } + + NdisDeviceBindingsInfoSize = sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO); + NdisDeviceBindingsInfoSize += sizeof(WWAN_UICC_FILE_PATH) * AppCount; + + NdisDeviceBindingsInfo = (PNDIS_WWAN_DEVICE_BINDINGS_INFO)ALLOCATE_NONPAGED_POOL(NdisDeviceBindingsInfoSize); + + if (NdisDeviceBindingsInfo == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO", + Request->RequestId, + NdisDeviceBindingsInfoSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisDeviceBindingsInfo, NdisDeviceBindingsInfoSize); + + NdisDeviceBindingsInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceBindingsInfo->Header.Size = sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO); + NdisDeviceBindingsInfo->Header.Revision = NDIS_WWAN_DEVICE_BINDINGS_INFO_REVISION_1; + + MbbUtilMbbToWwanDeviceBindingsInfo( + MbbDeviceBindingsInfo, + &(NdisDeviceBindingsInfo->DeviceBindingsInfo) + ); + IndicationFailure = FALSE; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + if (!IndicationFailure) + { + NdisDeviceBindingsInfo->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisDeviceBindingsInfo; + StatusIndication.StatusBufferSize = NdisDeviceBindingsInfoSize; + } + else + { + RtlZeroMemory(&LocalNdisDeviceBindingsInfo, sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO)); + + LocalNdisDeviceBindingsInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisDeviceBindingsInfo.Header.Size = sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO); + LocalNdisDeviceBindingsInfo.Header.Revision = NDIS_WWAN_DEVICE_BINDINGS_INFO_REVISION_1; + LocalNdisDeviceBindingsInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisDeviceBindingsInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO); + } + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisDeviceBindingsInfo != NULL) + { + FREE_POOL(NdisDeviceBindingsInfo); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisRegisterStateExStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + ULONG NdisRegistrationStateInfosExSize = 0; + PNDIS_WWAN_REGISTRATION_STATE_INFOS_EX NdisRegistrationStateInfosEx = NULL; + NDIS_WWAN_REGISTRATION_STATE_INFOS_EX LocalNdisRegistrationStateInfosEx = { 0 }; + PMBB_REGISTRATION_STATE_INFOS_V2 MbbRegistrationStateInfosV2 = (PMBB_REGISTRATION_STATE_INFOS_V2)InBuffer; + ULONG RegistrationStateCount = 0; + ULONG RegistrationStateIndex = 0; + PMBB_REGISTRATION_STATE_V2 RegistrationState = NULL; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_REGISTER_STATE + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_REGISTER_STATE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbRegistrationStateInfosV2 == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_REGISTRATION_STATE_INFOS_V2, RegistrationStateList)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_REGISTER_STATE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_REGISTRATION_STATE_INFOS_V2, RegistrationStateList) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RegistrationStateCount = MbbRegistrationStateInfosV2->ElementCount; + for (RegistrationStateIndex = 0; RegistrationStateIndex < RegistrationStateCount; RegistrationStateIndex++) + { + // Check whether the struct MBB_REGISTRATION_STATE_V2 is valid. + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Offset, + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, + FIELD_OFFSET(MBB_REGISTRATION_STATE_V2, DataBuffer) + sizeof(WCHAR) * (WWAN_PROVIDERID_LEN + WWAN_PROVIDERNAME_LEN + WWAN_ROAMTEXT_LEN - 3), // Minus 3 null terminators. + sizeof(BYTE) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad MBB_REGISTRATION_STATE_V2 for RegistrationState %d, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + RegistrationStateIndex, + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Offset, + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, + InBufferSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // Check whether the ProviderId in the struct MBB_REGISTRATION_STATE_V2 is valid. + RegistrationState = (PMBB_REGISTRATION_STATE_V2)((PUCHAR)MbbRegistrationStateInfosV2 + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Offset); + NdisStatus = MbbIsVariableFieldValid( + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, + RegistrationState->ProviderId.Offset, + RegistrationState->ProviderId.Size, + WWAN_PROVIDERID_LEN - 1, // Minus the null terminator. + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad ProviderId for RegistrationState %d, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + RegistrationStateIndex, + RegistrationState->ProviderId.Offset, + RegistrationState->ProviderId.Size, + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // Check whether the ProviderName in the struct MBB_REGISTRATION_STATE_V2 is valid. + NdisStatus = MbbIsVariableFieldValid( + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, + RegistrationState->ProviderName.Offset, + RegistrationState->ProviderName.Size, + WWAN_PROVIDERNAME_LEN - 1, // Minus the null terminator. + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad ProviderName for RegistrationState %d, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + RegistrationStateIndex, + RegistrationState->ProviderName.Offset, + RegistrationState->ProviderName.Size, + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // Check whether the RoamingText in the struct MBB_REGISTRATION_STATE_V2 is valid. + NdisStatus = MbbIsVariableFieldValid( + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, + RegistrationState->RoamingText.Offset, + RegistrationState->RoamingText.Size, + WWAN_ROAMTEXT_LEN - 1, // Minus the null terminator. + sizeof(WCHAR) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad RoamingText for RegistrationState %d, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + RegistrationStateIndex, + RegistrationState->RoamingText.Offset, + RegistrationState->RoamingText.Size, + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + } + + NdisRegistrationStateInfosExSize = sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX); + NdisRegistrationStateInfosExSize += sizeof(WWAN_REGISTRATION_STATE_EX) * RegistrationStateCount; + + NdisRegistrationStateInfosEx = (PNDIS_WWAN_REGISTRATION_STATE_INFOS_EX)ALLOCATE_NONPAGED_POOL(NdisRegistrationStateInfosExSize); + + if (NdisRegistrationStateInfosEx == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_REGISTER_STATE", + Request->RequestId, + NdisRegistrationStateInfosExSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisRegistrationStateInfosEx, NdisRegistrationStateInfosExSize); + + NdisRegistrationStateInfosEx->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisRegistrationStateInfosEx->Header.Size = sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX); + NdisRegistrationStateInfosEx->Header.Revision = NDIS_WWAN_REGISTRATION_STATE_REVISION_2; + + MbbUtilMbbToWwanRegistrationStateInfoV2( + MbbRegistrationStateInfosV2, + &(NdisRegistrationStateInfosEx->RegistrationStateInfos) + ); + IndicationFailure = FALSE; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + if (!IndicationFailure) + { + NdisRegistrationStateInfosEx->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisRegistrationStateInfosEx; + StatusIndication.StatusBufferSize = NdisRegistrationStateInfosExSize; + } + else + { + RtlZeroMemory(&LocalNdisRegistrationStateInfosEx, sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX)); + + LocalNdisRegistrationStateInfosEx.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisRegistrationStateInfosEx.Header.Size = sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX); + LocalNdisRegistrationStateInfosEx.Header.Revision = NDIS_WWAN_REGISTRATION_STATE_REVISION_2; + LocalNdisRegistrationStateInfosEx.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisRegistrationStateInfosEx; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX); + } + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_REGISTER_STATE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisRegistrationStateInfosEx != NULL) + { + FREE_POOL(NdisRegistrationStateInfosEx); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisImsVoiceStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + NDIS_WWAN_IMS_VOICE_STATE NdisImsVoiceStatus = { 0 }; + PMBB_IMS_VOICE_STATE MbbImsVoiceStatus = (PMBB_IMS_VOICE_STATE)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_IMS_VOICE_STATE + ); + + RtlZeroMemory(&NdisImsVoiceStatus, sizeof(NdisImsVoiceStatus)); + + NdisImsVoiceStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisImsVoiceStatus.Header.Size = sizeof(NDIS_WWAN_IMS_VOICE_STATE); + NdisImsVoiceStatus.Header.Revision = NDIS_WWAN_IMS_VOICE_STATE_REVISION_1; + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_IMS_VOICE_STATE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbImsVoiceStatus == NULL || + InBufferSize < sizeof(MBB_IMS_VOICE_STATE)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_IMS_VOICE_STATE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_IMS_VOICE_STATE) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisImsVoiceStatus.ImsVoiceState.ImsVoiceStatus = (WWAN_IMS_VOICE_STATUS)(MbbImsVoiceStatus->ImsVoiceStatus); + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisImsVoiceStatus.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisImsVoiceStatus; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_IMS_VOICE_STATE); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_IMS_VOICE_STATE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSignalStateExStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + ULONG NdisSignalStateInfosExSize = 0; + PNDIS_WWAN_SIGNAL_STATE_INFOS_EX NdisSignalStateInfosEx = NULL; + NDIS_WWAN_SIGNAL_STATE_INFOS_EX LocalNdisSignalStateInfosEx = { 0 }; + PMBB_SIGNAL_STATE_INFOS_V2 MbbSignalStateInfosV2 = (PMBB_SIGNAL_STATE_INFOS_V2)InBuffer; + ULONG SignalStateCount = 0; + ULONG SignalStateIndex = 0; + PMBB_SIGNAL_STATE_V2 SignalState = NULL; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SIGNAL_STATE + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SIGNAL_STATE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbSignalStateInfosV2 == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_SIGNAL_STATE_INFOS_V2, SignalStateList)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SIGNAL_STATE, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_SIGNAL_STATE_INFOS_V2, SignalStateList) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + SignalStateCount = MbbSignalStateInfosV2->ElementCount; + for (SignalStateIndex = 0; SignalStateIndex < SignalStateCount; SignalStateIndex++) + { + // Check whether the struct MBB_SIGNAL_STATE_V2 is valid. + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Offset, + MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Size, + 1, + sizeof(MBB_SIGNAL_STATE_V2) + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad MBB_SIGNAL_STATE_V2 for SignalStateIndex %d, Offset=%d, Size=%d, ReceivedSize=%d", + Request->RequestId, + SignalStateIndex, + MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Offset, + MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Size, + InBufferSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + } + + NdisSignalStateInfosExSize = sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX); + NdisSignalStateInfosExSize += sizeof(WWAN_SIGNAL_STATE_EX) * SignalStateCount; + + NdisSignalStateInfosEx = (PNDIS_WWAN_SIGNAL_STATE_INFOS_EX)ALLOCATE_NONPAGED_POOL(NdisSignalStateInfosExSize); + + if (NdisSignalStateInfosEx == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_SIGNAL_STATE", + Request->RequestId, + NdisSignalStateInfosExSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisSignalStateInfosEx, NdisSignalStateInfosExSize); + + NdisSignalStateInfosEx->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSignalStateInfosEx->Header.Size = sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX); + NdisSignalStateInfosEx->Header.Revision = NDIS_WWAN_SIGNAL_STATE_REVISION_2; + + MbbUtilMbbToWwanSignalStateInfoV2( + MbbSignalStateInfosV2, + &(NdisSignalStateInfosEx->SignalStateInfos) + ); + IndicationFailure = FALSE; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + if (!IndicationFailure) + { + NdisSignalStateInfosEx->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisSignalStateInfosEx; + StatusIndication.StatusBufferSize = NdisSignalStateInfosExSize; + } + else + { + RtlZeroMemory(&LocalNdisSignalStateInfosEx, sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX)); + + LocalNdisSignalStateInfosEx.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisSignalStateInfosEx.Header.Size = sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX); + LocalNdisSignalStateInfosEx.Header.Revision = NDIS_WWAN_SIGNAL_STATE_REVISION_2; + LocalNdisSignalStateInfosEx.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisSignalStateInfosEx; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX); + } + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SIGNAL_STATE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisSignalStateInfosEx != NULL) + { + FREE_POOL(NdisSignalStateInfosEx); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisLocationStateStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + NDIS_WWAN_LOCATION_STATE_INFO NdisLocationStateInfo = { 0 }; + PMBB_LOCATION_STATE_INFO MbbLocationStateInfo = (PMBB_LOCATION_STATE_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_LOCATION_STATE_INFO + ); + + RtlZeroMemory(&NdisLocationStateInfo, sizeof(NdisLocationStateInfo)); + + NdisLocationStateInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisLocationStateInfo.Header.Size = sizeof(NDIS_WWAN_LOCATION_STATE_INFO); + NdisLocationStateInfo.Header.Revision = NDIS_WWAN_LOCATION_STATE_INFO_REVISION_1; + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_LOCATION_STATE_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbLocationStateInfo == NULL || + InBufferSize < sizeof(MBB_LOCATION_STATE_INFO)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_LOCATION_STATE_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_LOCATION_STATE_INFO) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisLocationStateInfo.LocationStateInfo.Trigger = (WWAN_LOCATION_TRIGGER_MODE)(MbbLocationStateInfo->Trigger); + NdisLocationStateInfo.LocationStateInfo.DataClass = MbbLocationStateInfo->DataClass; + NdisLocationStateInfo.LocationStateInfo.AreaCode = MbbLocationStateInfo->AreaCode; + NdisLocationStateInfo.LocationStateInfo.CellId = MbbLocationStateInfo->CellId; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisLocationStateInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisLocationStateInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_LOCATION_STATE_INFO); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_LOCATION_STATE_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisNitzStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + NDIS_WWAN_NITZ_INFO NdisNitzInfo = { 0 }; + PMBB_NITZ_INFO MbbNitzInfo = (PMBB_NITZ_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_NITZ_INFO + ); + + RtlZeroMemory(&NdisNitzInfo, sizeof(NdisNitzInfo)); + + NdisNitzInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisNitzInfo.Header.Size = sizeof(NDIS_WWAN_NITZ_INFO); + NdisNitzInfo.Header.Revision = NDIS_WWAN_NITZ_INFO_REVISION_1; + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_NITZ_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbNitzInfo == NULL || + InBufferSize < sizeof(MBB_NITZ_INFO)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_NITZ_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_NITZ_INFO) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisNitzInfo.NitzInfo.Year = MbbNitzInfo->Year; + NdisNitzInfo.NitzInfo.Month = MbbNitzInfo->Month; + NdisNitzInfo.NitzInfo.Day = MbbNitzInfo->Day; + NdisNitzInfo.NitzInfo.Hour = MbbNitzInfo->Hour; + NdisNitzInfo.NitzInfo.Minute = MbbNitzInfo->Minute; + NdisNitzInfo.NitzInfo.Second = MbbNitzInfo->Second; + NdisNitzInfo.NitzInfo.TimeZoneOffsetMinutes = MbbNitzInfo->TimeZoneOffsetMinutes; + NdisNitzInfo.NitzInfo.DaylightSavingTimeOffsetMinutes = MbbNitzInfo->DaylightSavingTimeOffsetMinutes; + NdisNitzInfo.NitzInfo.DataClasses = MbbNitzInfo->DataClasses; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisNitzInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisNitzInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_NITZ_INFO); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_NITZ_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisPreshutdownHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; + NDIS_STATUS_INDICATION StatusIndication = { 0 }; + NDIS_WWAN_PRESHUTDOWN_STATE NdisPreshutdownState = { 0 }; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferSize); + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PRESHUTDOWN_STATE + ); + + RtlZeroMemory(&NdisPreshutdownState, sizeof(NdisPreshutdownState)); + + NdisPreshutdownState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisPreshutdownState.Header.Size = SIZEOF_NDIS_WWAN_PRESHUTDOWN_STATE_1; + NdisPreshutdownState.Header.Revision = NDIS_WWAN_PRESHUTDOWN_STATE_REVISION_1; + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PRESHUTDOWN_STATE, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisPreshutdownState.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisPreshutdownState; + StatusIndication.StatusBufferSize = sizeof(NdisPreshutdownState); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PRESHUTDOWN_STATE with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + TraceLoggingWrite( + g_hLoggingProvider, + "OID_Wwan_Preshutdown_Response", + TraceLoggingUInt64(Request->RequestId, "RequestID"), + TraceLoggingUInt64(WwanStatus, "WwanStatus"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisAtrInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_ATR_INFO NdisAtrInfo; + PMBB_ATR_INFO MbbAtrInfo = (PMBB_ATR_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_ATR_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_ATR_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbAtrInfo == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_ATR_INFO, DataBuffer)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_ATR_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_ATR_INFO, DataBuffer) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(&NdisAtrInfo, sizeof(NdisAtrInfo)); + + NdisAtrInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisAtrInfo.Header.Size = sizeof(NDIS_WWAN_ATR_INFO); + NdisAtrInfo.Header.Revision = NDIS_WWAN_ATR_INFO_REVISION_1; + + MbbUtilMbbToWwanAtrInfo( + MbbAtrInfo, + &NdisAtrInfo.AtrInfo + ); + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisAtrInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisAtrInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_ATR_INFO); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_ATR_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisUiccOpenChannelInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + ULONG NdisUiccOpenChannelInfoSize = 0; + PNDIS_WWAN_UICC_OPEN_CHANNEL_INFO NdisUiccOpenChannelInfo = NULL; + NDIS_WWAN_UICC_OPEN_CHANNEL_INFO LocalNdisUiccOpenChannelInfo; + PMBB_UICC_OPEN_CHANNEL_INFO MbbUiccOpenChannelInfo = (PMBB_UICC_OPEN_CHANNEL_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbUiccOpenChannelInfo == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_UICC_OPEN_CHANNEL_INFO, DataBuffer)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_UICC_OPEN_CHANNEL_INFO, DataBuffer) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisUiccOpenChannelInfoSize = FIELD_OFFSET(NDIS_WWAN_UICC_OPEN_CHANNEL_INFO, UiccOpenChannelInfo.Response); + NdisUiccOpenChannelInfoSize += MbbUiccOpenChannelInfo->Response.Size; + + NdisUiccOpenChannelInfo = (PNDIS_WWAN_UICC_OPEN_CHANNEL_INFO)ALLOCATE_NONPAGED_POOL( NdisUiccOpenChannelInfoSize ); + + if( NdisUiccOpenChannelInfo == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO", + Request->RequestId, + NdisUiccOpenChannelInfoSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisUiccOpenChannelInfo, NdisUiccOpenChannelInfoSize); + + // Open channel can have a response payload even when the command fails + NdisUiccOpenChannelInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisUiccOpenChannelInfo->Header.Size = (USHORT)NdisUiccOpenChannelInfoSize; + NdisUiccOpenChannelInfo->Header.Revision = NDIS_WWAN_UICC_OPEN_CHANNEL_INFO_REVISION_1; + NdisUiccOpenChannelInfo->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisUiccOpenChannelInfo; + StatusIndication.StatusBufferSize = NdisUiccOpenChannelInfoSize; + + MbbUtilMbbToWwanUiccOpenChannelInfo( + MbbUiccOpenChannelInfo, + &NdisUiccOpenChannelInfo->UiccOpenChannelInfo + ); + IndicationFailure = FALSE; + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if (IndicationFailure) + { + RtlZeroMemory(&LocalNdisUiccOpenChannelInfo, sizeof(NDIS_WWAN_UICC_OPEN_CHANNEL_INFO)); + + LocalNdisUiccOpenChannelInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisUiccOpenChannelInfo.Header.Size = sizeof(NDIS_WWAN_UICC_OPEN_CHANNEL_INFO); + LocalNdisUiccOpenChannelInfo.Header.Revision = NDIS_WWAN_UICC_OPEN_CHANNEL_INFO_REVISION_1; + LocalNdisUiccOpenChannelInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisUiccOpenChannelInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_OPEN_CHANNEL_INFO); + } + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisUiccOpenChannelInfo != NULL) + { + FREE_POOL(NdisUiccOpenChannelInfo); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisUiccCloseChannelInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_UICC_CLOSE_CHANNEL_INFO NdisUiccCloseChannelInfo; + PMBB_UICC_CLOSE_CHANNEL_INFO MbbUiccCloseChannelInfo = (PMBB_UICC_CLOSE_CHANNEL_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_UICC_CLOSE_CHANNEL_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_CLOSE_CHANNEL_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbUiccCloseChannelInfo == NULL || + InBufferSize < sizeof(MBB_UICC_CLOSE_CHANNEL_INFO) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_CLOSE_CHANNEL_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_UICC_CLOSE_CHANNEL_INFO) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(&NdisUiccCloseChannelInfo, sizeof(NdisUiccCloseChannelInfo)); + + NdisUiccCloseChannelInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisUiccCloseChannelInfo.Header.Size = sizeof(NDIS_WWAN_UICC_CLOSE_CHANNEL_INFO); + NdisUiccCloseChannelInfo.Header.Revision = NDIS_WWAN_UICC_CLOSE_CHANNEL_INFO_REVISION_1; + + MbbUtilMbbToWwanUiccCloseChannelInfo( + MbbUiccCloseChannelInfo, + &NdisUiccCloseChannelInfo.UiccCloseChannelInfo + ); + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisUiccCloseChannelInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisUiccCloseChannelInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_CLOSE_CHANNEL_INFO); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_CLOSE_CHANNEL_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisUiccApduInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + ULONG NdisUiccApduInfoSize = 0; + PNDIS_WWAN_UICC_APDU_INFO NdisUiccApduInfo = NULL; + NDIS_WWAN_UICC_APDU_INFO LocalNdisUiccApduInfo; + PMBB_UICC_APDU_INFO MbbUiccApduInfo = (PMBB_UICC_APDU_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_UICC_APDU_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_APDU_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbUiccApduInfo == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_UICC_APDU_INFO, DataBuffer)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_APDU_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_UICC_APDU_INFO, DataBuffer) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisUiccApduInfoSize = FIELD_OFFSET(NDIS_WWAN_UICC_APDU_INFO, UiccApduInfo.Response); + NdisUiccApduInfoSize += MbbUiccApduInfo->Response.Size; + + NdisUiccApduInfo = (PNDIS_WWAN_UICC_APDU_INFO)ALLOCATE_NONPAGED_POOL( NdisUiccApduInfoSize ); + + if( NdisUiccApduInfo == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_UICC_APDU_INFO", + Request->RequestId, + NdisUiccApduInfoSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisUiccApduInfo, NdisUiccApduInfoSize); + + NdisUiccApduInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisUiccApduInfo->Header.Size = (USHORT)NdisUiccApduInfoSize; + NdisUiccApduInfo->Header.Revision = NDIS_WWAN_UICC_OPEN_CHANNEL_INFO_REVISION_1; + NdisUiccApduInfo->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisUiccApduInfo; + StatusIndication.StatusBufferSize = NdisUiccApduInfoSize; + + MbbUtilMbbToWwanUiccApduInfo( + MbbUiccApduInfo, + &NdisUiccApduInfo->UiccApduInfo + ); + IndicationFailure = FALSE; + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if (IndicationFailure) + { + RtlZeroMemory(&LocalNdisUiccApduInfo, sizeof(NDIS_WWAN_UICC_APDU_INFO)); + + LocalNdisUiccApduInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisUiccApduInfo.Header.Size = sizeof(NDIS_WWAN_UICC_APDU_INFO); + LocalNdisUiccApduInfo.Header.Revision = NDIS_WWAN_UICC_APDU_INFO_REVISION_1; + LocalNdisUiccApduInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisUiccApduInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_APDU_INFO); + } + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_APDU_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisUiccApduInfo != NULL) + { + FREE_POOL(NdisUiccApduInfo); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisUiccTerminalCapabilityInfoStatusHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + ULONG NdisUiccTerminalCapabilityInfoSize = 0; + PNDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO NdisUiccTerminalCapabilityInfo = NULL; + NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO LocalNdisUiccTerminalCapabilityInfo; + PMBB_UICC_TERMINAL_CAPABILITY_INFO MbbUiccTerminalCapabilityInfo = (PMBB_UICC_TERMINAL_CAPABILITY_INFO)InBuffer; + ULONG CapabilityCount = 0; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbUiccTerminalCapabilityInfo == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_UICC_TERMINAL_CAPABILITY_INFO, CapabilityList)) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_UICC_TERMINAL_CAPABILITY_INFO, CapabilityList) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + CapabilityCount = MbbUiccTerminalCapabilityInfo->ElementCount; + + NdisUiccTerminalCapabilityInfoSize = sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO); + NdisUiccTerminalCapabilityInfoSize += sizeof(WWAN_UICC_TERMINAL_CAPABILITY_TLV) * CapabilityCount; + + NdisUiccTerminalCapabilityInfo = (PNDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO)ALLOCATE_NONPAGED_POOL( NdisUiccTerminalCapabilityInfoSize ); + + if( NdisUiccTerminalCapabilityInfo == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO", + Request->RequestId, + NdisUiccTerminalCapabilityInfoSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisUiccTerminalCapabilityInfo, NdisUiccTerminalCapabilityInfoSize); + + NdisUiccTerminalCapabilityInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisUiccTerminalCapabilityInfo->Header.Size = (USHORT)NdisUiccTerminalCapabilityInfoSize; + NdisUiccTerminalCapabilityInfo->Header.Revision = NDIS_WWAN_UICC_OPEN_CHANNEL_INFO_REVISION_1; + NdisUiccTerminalCapabilityInfo->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisUiccTerminalCapabilityInfo; + StatusIndication.StatusBufferSize = NdisUiccTerminalCapabilityInfoSize; + + MbbUtilMbbToWwanUiccTerminalCapabilityInfo( + MbbUiccTerminalCapabilityInfo, + &NdisUiccTerminalCapabilityInfo->UiccCapabilityInfo.CapabilityListHeader + ); + IndicationFailure = FALSE; + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + if (IndicationFailure) + { + RtlZeroMemory(&LocalNdisUiccTerminalCapabilityInfo, sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO)); + + LocalNdisUiccTerminalCapabilityInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisUiccTerminalCapabilityInfo.Header.Size = sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO); + LocalNdisUiccTerminalCapabilityInfo.Header.Revision = NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO_REVISION_1; + LocalNdisUiccTerminalCapabilityInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisUiccTerminalCapabilityInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO); + } + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisUiccTerminalCapabilityInfo != NULL) + { + FREE_POOL(NdisUiccTerminalCapabilityInfo); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisUiccResetInfoStatusHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_UICC_RESET_INFO NdisUiccResetInfo; + PMBB_UICC_RESET_INFO MbbUiccResetInfo = (PMBB_UICC_RESET_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_UICC_RESET_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_RESET_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if( MbbUiccResetInfo == NULL || + InBufferSize < sizeof(MBB_UICC_RESET_INFO) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_RESET_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_UICC_RESET_INFO) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(&NdisUiccResetInfo, sizeof(NdisUiccResetInfo)); + + NdisUiccResetInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisUiccResetInfo.Header.Size = sizeof(NDIS_WWAN_UICC_RESET_INFO); + NdisUiccResetInfo.Header.Revision = NDIS_WWAN_UICC_RESET_INFO_REVISION_1; + + NdisUiccResetInfo.UiccResetInfo.PassThroughStatus = (WWAN_UICC_PASSTHROUGH_STATUS)MbbUiccResetInfo->PassThroughStatus; + } + while( FALSE ); + + // + // Restore the device returned operational status, if any. + // + if( WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) + { + WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); + } + + NdisUiccResetInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisUiccResetInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_RESET_INFO); + + TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_RESET_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSarConfigHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize + ) +{ + BOOLEAN IndicateFailure = TRUE; + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + ULONG ElementIndex; + ULONG ElementCount; + ULONG NdisSarConfigSize = 0; + ULONG MbbSarConfigSize = 0; + NDIS_STATUS_INDICATION StatusIndication; + PNDIS_WWAN_SAR_CONFIG_INFO NdisSarConfigInfo = NULL; + NDIS_WWAN_SAR_CONFIG_INFO LocalNdisSarConfigInfo; + PMBB_SAR_CONFIG_INFO MbbSarConfigInfo = (PMBB_SAR_CONFIG_INFO)InBuffer; + + do + { + RtlZeroMemory(&LocalNdisSarConfigInfo, sizeof(LocalNdisSarConfigInfo)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SAR_CONFIG + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SAR_CONFIG, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, WwanStatus=%!WwanStatus!. MbbStatus=%!MbbStatus!", + Request->RequestId, + WwanStatus, + MbbStatus + ); + NdisStatus = WwanStatus; + break; + } + + if (MbbSarConfigInfo == NULL || + InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SAR_CONFIG_INFO, Configurations)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SAR_CONFIG, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_SAR_CONFIG_INFO, ElementCount) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + ElementCount = MbbSarConfigInfo->ElementCount; + MbbSarConfigSize = FIELD_OFFSET(MBB_SAR_CONFIG_INFO, Configurations) + (ULONG)ElementCount * sizeof(MBB_ARRAY_ELEMENT); + NdisSarConfigSize = sizeof(NDIS_WWAN_SAR_CONFIG_INFO) + (ULONG)ElementCount * sizeof(WWAN_SAR_CONFIG_INDICES); + + if (InBufferSize < MbbSarConfigSize) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SAR_CONFIG, BufferSize[Received=%d Expected=%I64u] ElementCount=%d", + Request->RequestId, + InBufferSize, + MbbSarConfigSize, + MbbSarConfigInfo->ElementCount + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + for (ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex++) + { + if (MbbIsVariableFieldValid( + InBufferSize, + MbbSarConfigInfo->Configurations[ElementIndex].Offset, + MbbSarConfigInfo->Configurations[ElementIndex].Size, + 2, // Expect two indices in a configuration + sizeof(ULONG) + ) != STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID MBB_SAR_CONFIG_INFO.Configurations[%d] Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + Request->RequestId, + ElementIndex, + MbbSarConfigInfo->Configurations[ElementIndex].Offset, + InBufferSize, + MbbSarConfigInfo->Configurations[ElementIndex].Size, + 2 * sizeof(ULONG) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + } + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + break; + } + + if ((NdisSarConfigInfo = ALLOCATE_NONPAGED_POOL(NdisSarConfigSize)) == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %I64u bytes for NDIS_STATUS_WWAN_SAR_CONFIG, ElementCount=%d", + Request->RequestId, + NdisSarConfigSize, + MbbSarConfigInfo->ElementCount + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + NdisSarConfigInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisSarConfigInfo->Header.Size = sizeof(NDIS_WWAN_SAR_CONFIG_INFO); + NdisSarConfigInfo->Header.Revision = NDIS_WWAN_SAR_CONFIG_INFO_REVISION_1; + NdisSarConfigInfo->uStatus = WWAN_STATUS_SUCCESS; + + StatusIndication.StatusBuffer = NdisSarConfigInfo; + StatusIndication.StatusBufferSize = NdisSarConfigSize; + + MbbUtilMbbToWwanSarConfigInfo( + MbbSarConfigInfo, + &NdisSarConfigInfo->SarConfig + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + IndicateFailure = FALSE; + + } while (FALSE); + + if (IndicateFailure) + { + + LocalNdisSarConfigInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisSarConfigInfo.Header.Size = sizeof(LocalNdisSarConfigInfo); + LocalNdisSarConfigInfo.Header.Revision = NDIS_WWAN_SAR_CONFIG_INFO_REVISION_1; + LocalNdisSarConfigInfo.uStatus = NdisStatus; + + StatusIndication.StatusBuffer = &LocalNdisSarConfigInfo; + StatusIndication.StatusBufferSize = sizeof(LocalNdisSarConfigInfo); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to indicate NDIS_STATUS_WWAN_SAR_CONFIG WwanStatus=%!WwanStatus!", Request->RequestId, NdisStatus); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + } + + if (NdisSarConfigInfo != NULL) + { + FREE_POOL(NdisSarConfigInfo); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisSarTransmissionStatusHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO NdisTransmissionStatusInfo; + PMBB_SAR_TRANSMISSION_STATUS_INFO MbbTransmissionStatusInfo = (PMBB_SAR_TRANSMISSION_STATUS_INFO)InBuffer; + + do + { + RtlZeroMemory(&NdisTransmissionStatusInfo, sizeof(NdisTransmissionStatusInfo)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_SAR_TRANSMISSION_STATUS + ); + + NdisTransmissionStatusInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisTransmissionStatusInfo.Header.Size = sizeof(NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO); + NdisTransmissionStatusInfo.Header.Revision = NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO_REVISION_1; + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SAR_TRANSMISSION_STATUS_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, WwanStatus=%!WwanStatus!. MbbStatus=%!MbbStatus!", + Request->RequestId, + WwanStatus, + MbbStatus + ); + NdisStatus = WwanStatus; + break; + } + + if (MbbTransmissionStatusInfo == NULL || + InBufferSize < sizeof(MBB_SAR_TRANSMISSION_STATUS_INFO)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SAR_TRANSMISSION_STATUS_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_SAR_TRANSMISSION_STATUS_INFO) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbUtilMbbToWwanTransmissionStatusInfo( + MbbTransmissionStatusInfo, + &NdisTransmissionStatusInfo.TransmissionStatus + ); + } while (FALSE); + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisTransmissionStatusInfo.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisTransmissionStatusInfo; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SAR_TRANSMISSION_STATUS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + + +NDIS_STATUS +MbbNdisNetworkBlacklistHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize +) +{ + ULONG NdisNetworkBlacklistSize = 0; + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + PNDIS_WWAN_NETWORK_BLACKLIST NdisNetworkBlacklist = NULL; + NDIS_WWAN_NETWORK_BLACKLIST LocalNdisNetworkBlacklist; + PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist = (PMBB_MS_NETWORK_BLACKLIST_INFO)InBuffer; + PMBB_MS_NETWORK_BLACKLIST_PROVIDER MbbNetworkBlacklistProvider = NULL; + ULONGLONG TempSize = 0; + ULONG MulTempSize = 0; + ULONG i; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + RtlZeroMemory(&LocalNdisNetworkBlacklist, sizeof(LocalNdisNetworkBlacklist)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_NETWORK_BLACKLIST + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_NETWORK_BLACKLIST, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + + if (MbbReqMgrIsSetOid(Request) == TRUE) + { + break; + } + + TempSize = RTL_SIZEOF_THROUGH_FIELD(MBB_MS_NETWORK_BLACKLIST_INFO, ElementCount); + + if (MbbNetworkBlacklist == NULL || + InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_MS_NETWORK_BLACKLIST_INFO, ElementCount)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_NETWORK_BLACKLIST, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_MS_NETWORK_BLACKLIST_INFO, ElementCount) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // + // make sure it is big enough for the array of elements + // + NtStatus = RtlULongMult( + MbbNetworkBlacklist->ElementCount, + sizeof(MBB_ARRAY_ELEMENT), + &MulTempSize + ); + + if (NT_ERROR(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbNetworkBlacklist->ElementCount=%d MBB_ARRAY_ELEMENT size=%d", + Request->RequestId, + MbbNetworkBlacklist->ElementCount, + sizeof(MBB_ARRAY_ELEMENT) + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + TempSize += MulTempSize; + + if (InBufferSize < TempSize) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_NETWORK_BLACKLIST, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + (ULONG)TempSize + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + for (i = 0; i < MbbNetworkBlacklist->ElementCount; i++) + { + + NdisStatus = MbbIsVariableFieldValid( + InBufferSize, + MbbNetworkBlacklist->Contexts[i].Offset, + MbbNetworkBlacklist->Contexts[i].Size, + 2048, // some reasonable upper limit + sizeof(UCHAR) + ); + + if (!NT_SUCCESS(NdisStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad array element in MBB_MS_NETWORK_BLACKLIST_INFO", + Request->RequestId + ); + + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + MbbNetworkBlacklistProvider = (PMBB_MS_NETWORK_BLACKLIST_PROVIDER)(InBuffer + MbbNetworkBlacklist->Contexts[i].Offset); + } + + if (WwanStatus != WWAN_STATUS_SUCCESS) + { + break; + } + + NtStatus = RtlULongMult( + MbbNetworkBlacklist->ElementCount, + sizeof(MBB_MS_NETWORK_BLACKLIST_PROVIDER), + &NdisNetworkBlacklistSize + ); + if (NT_ERROR(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbNetworkBlacklist->ElementCount=%d MBB_MS_NETWORK_BLACKLIST_PROVIDER size=%d", + Request->RequestId, + MbbNetworkBlacklist->ElementCount, + sizeof(WWAN_CONTEXT) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NtStatus = RtlULongAdd( + NdisNetworkBlacklistSize, + sizeof(NDIS_WWAN_NETWORK_BLACKLIST), + &NdisNetworkBlacklistSize + ); + if (NT_ERROR(NtStatus)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, NdisNetworkBlacklistSize=%d NDIS_WWAN_NETWORK_BLACKLIST size=%d", + Request->RequestId, + NdisNetworkBlacklistSize, + sizeof(NDIS_WWAN_NETWORK_BLACKLIST) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + NdisNetworkBlacklist = ALLOCATE_NONPAGED_POOL(NdisNetworkBlacklistSize); + + if (NdisNetworkBlacklist == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_NETWORK_BLACKLIST, ElementCount=%d", + Request->RequestId, + NdisNetworkBlacklistSize, + MbbNetworkBlacklist->ElementCount + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisNetworkBlacklist, NdisNetworkBlacklistSize); + + NdisNetworkBlacklist->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisNetworkBlacklist->Header.Size = sizeof(NDIS_WWAN_NETWORK_BLACKLIST); + NdisNetworkBlacklist->Header.Revision = NDIS_WWAN_NETWORK_BLACKLIST_REVISION_1; + + NdisNetworkBlacklist->NetworkBlacklistInfo.BlacklistState = MbbNetworkBlacklist->BlacklistState; + + MbbUtilMbbToWwanNetworkBlackList( + MbbNetworkBlacklist, + &NdisNetworkBlacklist->NetworkBlacklistInfo.BlacklistProviderList + ); + } while (FALSE); + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + if (NdisNetworkBlacklist == NULL) + { + LocalNdisNetworkBlacklist.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisNetworkBlacklist.Header.Size = sizeof(NDIS_WWAN_NETWORK_BLACKLIST); + LocalNdisNetworkBlacklist.Header.Revision = NDIS_WWAN_NETWORK_BLACKLIST_REVISION_1; + + LocalNdisNetworkBlacklist.NetworkBlacklistInfo.BlacklistProviderList.ElementType = WwanStructNetworkBlacklistProvider; + LocalNdisNetworkBlacklist.NetworkBlacklistInfo.BlacklistProviderList.ElementCount = 0; + + StatusIndication.StatusBuffer = &LocalNdisNetworkBlacklist; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_NETWORK_BLACKLIST); + } + else + { + StatusIndication.StatusBuffer = NdisNetworkBlacklist; + StatusIndication.StatusBufferSize = NdisNetworkBlacklistSize; + } + + ((PNDIS_WWAN_PROVISIONED_CONTEXTS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_NETWORK_BLACKLIST with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisNetworkBlacklist != NULL) + { + FREE_POOL(NdisNetworkBlacklist); + } + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisPcoStatusHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize + ) +{ + WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_PCO_STATUS NdisPcoStatus; + PMBB_MS_PCO_VALUE pMbbPcoValue = (PMBB_MS_PCO_VALUE)InBuffer; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); + PMBB_PORT Port = NULL; + NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; + BOOLEAN ResetPort = FALSE; + + do + { + RtlZeroMemory(&NdisPcoStatus, sizeof(NdisPcoStatus)); + + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_PCO_STATUS + ); + + NdisPcoStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisPcoStatus.Header.Size = sizeof(NDIS_WWAN_PCO_STATUS); + NdisPcoStatus.Header.Revision = NDIS_WWAN_PCO_STATUS_REVISION_1; + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PCO_STATUS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + + if ((WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus)) != WWAN_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, WwanStatus=%!WwanStatus!. MbbStatus=%!MbbStatus!", + Request->RequestId, + WwanStatus, + MbbStatus + ); + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + + if (pMbbPcoValue == NULL || + InBufferSize < sizeof(MBB_MS_PCO_VALUE)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PCO_STATUS, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + sizeof(MBB_MS_PCO_VALUE) + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // Get the port. Always rely on the session id returned by the device as this + // responsehandler may be triggered due to an OID request from above + // or some MB device specific notification from below. Session Id is set in both cases. + Port = MbbWwanTranslateSessionIdToPort(Adapter, pMbbPcoValue->SessionId); + + if (Port == NULL) + { + // invalid port context + NdisStatus = NDIS_STATUS_INVALID_PORT; + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // Get the port number + MBB_ACQUIRE_PORT_LOCK(Port); + PortNumber = Port->PortNumber; + MBB_RELEASE_PORT_LOCK(Port); + + // Copy PCO data from MBB payload to NDIS payload + NdisPcoStatus.PcoValue.Size = pMbbPcoValue->PcoDataSize; + NdisPcoStatus.PcoValue.Type = pMbbPcoValue->PcoDataType; + RtlCopyMemory( + (PBYTE)&NdisPcoStatus.PcoValue.PcoData[0], + (PBYTE)&pMbbPcoValue->PcoDataBuffer[0], + pMbbPcoValue->PcoDataSize); + + } while (FALSE); + + if ((NDIS_STATUS_INVALID_DATA == NdisStatus) && !MbbReqMgrIsUnsolicitedIndication(Request)) + { + // + // We cannot get the SessionId from the MbbContextState because it is invalid. + // Since this is a transactional response, we do a best-effort to send the response up + // on the port from OidRequest. + // NOTE: Unsolicited indications with invalid SessionId are dropped. + // + + PortNumber = Request->OidContext.OidRequest->PortNumber; + Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); + + if (Port != NULL) + { + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbPcoValue is invalid. Using NDIS_DEFAULT_PORT_NUMBER (%lu) to indicate response", + Request->RequestId, + PortNumber); + + NdisPcoStatus.PcoValue.Size = 0; + NdisPcoStatus.PcoValue.Type = WwanPcoTypeMax; + } + else + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbPcoValue is invalid AND we failed to retrieve the default port info", + Request->RequestId); + } + } + + if (Port != NULL) + { + // Indicate status indication on the correct port. + + NdisPcoStatus.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisPcoStatus; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PCO_STATUS); + StatusIndication.PortNumber = PortNumber; + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PCO_STATUS with status=%!WwanStatus! for Port number=%lu", + Request->RequestId, + WwanStatus, + PortNumber); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication); + + Dereference(Port); + } + else + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Not indicating OID_WWAN_PCO completion as the port context is invalid.", + Request->RequestId); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbNdisDeviceResetStatusHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize +) +{ + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + NDIS_WWAN_DEVICE_RESET_STATUS NdisDeviceResetStatus; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferSize); + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_DEVICE_RESET_STATUS + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_RESET_STATUS, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(&NdisDeviceResetStatus, sizeof(NdisDeviceResetStatus)); + + NdisDeviceResetStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisDeviceResetStatus.Header.Size = sizeof(NDIS_WWAN_DEVICE_RESET_STATUS); + NdisDeviceResetStatus.Header.Revision = NDIS_WWAN_DEVICE_RESET_STATUS_REVISION_1; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + NdisDeviceResetStatus.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &NdisDeviceResetStatus; + StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_RESET_STATUS); + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_RESET_STATUS with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbNdisBaseStationsInfoHandler( + _In_ PMBB_REQUEST_CONTEXT Request, + _In_ NDIS_STATUS NdisStatus, + _In_ MBB_STATUS MbbStatus, + _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, + _In_ ULONG InBufferSize +) +{ + BOOLEAN IndicationFailure = TRUE; + WWAN_STATUS WwanStatus; + NDIS_STATUS_INDICATION StatusIndication; + ULONG NdisBaseStationsInfoSize = 0; + PNDIS_WWAN_BASE_STATIONS_INFO NdisBaseStationsInfoResponse = NULL; + PMBB_MS_BASE_STATIONS_INFO MbbBaseStationInfoResponse = (PMBB_MS_BASE_STATIONS_INFO)InBuffer; + + do + { + MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( + &StatusIndication, + Request, + NDIS_STATUS_WWAN_BASE_STATIONS_INFO + ); + + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_BASE_STATIONS_INFO, status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + if (MbbBaseStationInfoResponse == NULL || + InBufferSize < (ULONG)FIELD_OFFSET(MBB_MS_BASE_STATIONS_INFO, DataBuffer)) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_BASE_STATIONS_INFO, BufferSize[Received=%d Expected=%d]", + Request->RequestId, + InBufferSize, + FIELD_OFFSET(MBB_MS_BASE_STATIONS_INFO, DataBuffer) + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + // ---------------------------------------------------------- + // NDIS_WWAN_BASE_STATIONS_INFO + // |---- header + // |---- uStatus + // |---- BaseStationsInfo (WWAN_BASE_STATIONS_INFO) ------------+ + // | |---- SystemTypes (ULONG) | + // | |---- Offsets and sizes (ULONGs) + Same content + // | |---- BaseStationsData (ANYSIZE_ARRAY) | + // ------------------------------- | + // MBB_MS_BASE_STATIONS_INFO -----------------------------------+ + // |---- SystemType (MBB_DATA_CLASS_VALUE) + // |---- Offsets and sizes (MBB_ARRAY_ELEMENTs) + // |---- DataBuffer[1] + // ---------------------------------------------------------- + NdisBaseStationsInfoSize = FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData); + ULONG MbbBaseStationDataSize = + MbbBaseStationInfoResponse->GSMServingCell.Size + + MbbBaseStationInfoResponse->UMTSServingCell.Size + + MbbBaseStationInfoResponse->TDSCDMAServingCell.Size + + MbbBaseStationInfoResponse->LTEServingCell.Size + + MbbBaseStationInfoResponse->GSMNmr.Size + + MbbBaseStationInfoResponse->UMTSMrl.Size + + MbbBaseStationInfoResponse->TDSCDMAMrl.Size + + MbbBaseStationInfoResponse->LTEMrl.Size + + MbbBaseStationInfoResponse->CDMAMrl.Size; + NdisBaseStationsInfoSize += MbbBaseStationDataSize; + + NdisBaseStationsInfoResponse = (PNDIS_WWAN_BASE_STATIONS_INFO)ALLOCATE_NONPAGED_POOL(NdisBaseStationsInfoSize); + + if (NdisBaseStationsInfoResponse == NULL) + { + TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_BASE_STATIONS_INFO", + Request->RequestId, + NdisBaseStationsInfoSize + ); + WwanStatus = WWAN_STATUS_FAILURE; + break; + } + + RtlZeroMemory(NdisBaseStationsInfoResponse, NdisBaseStationsInfoSize); + + NdisBaseStationsInfoResponse->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NdisBaseStationsInfoResponse->Header.Size = (USHORT)NdisBaseStationsInfoSize; + NdisBaseStationsInfoResponse->Header.Revision = NDIS_WWAN_BASE_STATIONS_INFO_REVISION_1; + + // Copy MBB_MS_BASE_STATIONS_INFO to WWAN_BASE_STATIONS_INFO + RtlCopyMemory( + &NdisBaseStationsInfoResponse->BaseStationsInfo, + MbbBaseStationInfoResponse, + FIELD_OFFSET(WWAN_BASE_STATIONS_INFO, BaseStationsData) + MbbBaseStationDataSize); + + IndicationFailure = FALSE; + } while (FALSE); + + // + // Restore the device returned operational status, if any. + // + if (WwanStatus != WWAN_STATUS_SUCCESS && + MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) + { + WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); + } + + if (!IndicationFailure) + { + NdisBaseStationsInfoResponse->uStatus = WwanStatus; + + StatusIndication.StatusBuffer = NdisBaseStationsInfoResponse; + StatusIndication.StatusBufferSize = NdisBaseStationsInfoSize; + } + else + { + NDIS_WWAN_BASE_STATIONS_INFO LocalNdisBaseStationsInfoResponse; + RtlZeroMemory(&LocalNdisBaseStationsInfoResponse, FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData)); + + LocalNdisBaseStationsInfoResponse.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + LocalNdisBaseStationsInfoResponse.Header.Size = FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData); + LocalNdisBaseStationsInfoResponse.Header.Revision = NDIS_WWAN_BASE_STATIONS_INFO_REVISION_1; + LocalNdisBaseStationsInfoResponse.uStatus = WwanStatus; + + StatusIndication.StatusBuffer = &LocalNdisBaseStationsInfoResponse; + StatusIndication.StatusBufferSize = FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData); + } + + TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_BASE_STATIONS_INFO with status=%!WwanStatus!", + Request->RequestId, + WwanStatus + ); + + MbbNdisMiniportIndicateRequestStatus( + Request, + &StatusIndication + ); + + if (NdisBaseStationsInfoResponse != NULL) + { + FREE_POOL(NdisBaseStationsInfoResponse); + } + + return NDIS_STATUS_SUCCESS; +} + +// +// Completion Handlers +// + +VOID +MbbNdisReadyInfoCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsQueryReadyInfo == 1 ) + MbbNdisIndicateReadyInfoFailure( Request ); + + if( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo != NULL ) + FREE_POOL( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo ); + } +} + + +VOID +MbbNdisPacketServiceStateCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +/*++ +Description: + This is the completion handler for both PacketService CIDs + and RegisterState CIDs. RegisterState CID is issued when a + packet service response or indication is received since some + fields in the PacketService OID (OID model) require data not + present in the PacketService CID but present in the + RegisterState CID. +--*/ +{ + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + if( Request->HandlerContext.Parameters.PacketServiceState.IsQuery == 1 ) + { + MbbNdisIndicatePacketServiceFailure( Request, NdisStatus ); + } + + if( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState != NULL ) + { + FREE_POOL( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState ); + Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState=NULL; + } + } +} + +VOID +MbbNdisMultiCarrierDsCidListCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + MbbNdisIndicateDeviceCaps( + Request, + NdisStatus + ); + } +} + +VOID +MbbNdisCreateMacCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); + NDIS_PORT_NUMBER PortNumber = DEFAULT_NDIS_PORT_NUMBER; + PMBB_PORT Port = NULL; + BOOLEAN fInAdapterPortList = FALSE; + + Port = Request->HandlerContext.Parameters.NdisPortContext.Port; + + if(Port) + { + MBB_ACQUIRE_PORT_LOCK(Port); + PortNumber = Port->PortNumber; + MBB_RELEASE_PORT_LOCK(Port); + + if(IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + // We should never activate the default port + + // Check whether the port is in the adapter port list + PMBB_PORT PortToCheck = NULL; + + fInAdapterPortList = (PortToCheck = MbbWwanTranslatePortNumberToPort(Adapter,PortNumber))!= NULL; + + if(fInAdapterPortList) + { + // Remove the reference added for port find + Dereference(PortToCheck); + + Status = MbbUtilWwanCreateMacComplete( + Adapter, + Port, + NdisStatus); + } + } + + // Remove the reference added when port was added to handlercontext + Dereference(Port); + } + else + { + Status = NDIS_STATUS_INVALID_PORT; + } + + if(Status != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbNdisCreateMacCompletionHandler failed. Status = 0x%08x\n", + Request->RequestId,Status); + } + else + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbNdisCreateMacCompletionHandler completed successfully.\n", + Request->RequestId); + } +} + + +VOID +MbbNdisDeleteMacCompletionHandler( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); + NDIS_PORT_NUMBER PortNumber = DEFAULT_NDIS_PORT_NUMBER; + PMBB_PORT Port = Request->HandlerContext.Parameters.NdisPortContext.Port; + + if(Port) + { + MBB_ACQUIRE_PORT_LOCK(Port); + PortNumber = Port->PortNumber; + MBB_RELEASE_PORT_LOCK(Port); + + if(IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + Status = MbbUtilWwanDeleteMacComplete( + Adapter, + Port, + NdisStatus); + } + else + { + Status = NDIS_STATUS_INVALID_PORT; + } + + // Remove the reference added when the port context was + // passed on as the handlercontext + Dereference(Port); + } + + if(Status != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbNdisDeleteMacCompletionHandler failed. Status = 0x%08x\n", + Request->RequestId,Status); + } + else + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbNdisDeleteMacCompletionHandler completed successfully.\n", + Request->RequestId); + } +} + +#pragma prefast(pop) \ No newline at end of file diff --git a/network/wwan/cxwmbclass/send.c b/network/wwan/cxwmbclass/send.c new file mode 100644 index 000000000..5f82e0aec --- /dev/null +++ b/network/wwan/cxwmbclass/send.c @@ -0,0 +1,2744 @@ +/*************************************************************************** + +Copyright (c) 2010 Microsoft Corporation + +Module Name: + + send.c + +Abstract: + + This file contains + 1. Queuing of send NBLs + 2. Conversion of NBL to NTBs + 3. Completion of NBLs + +Environment: + + kernel mode only + +Notes: + + +Revision History: + + 3/20/2010 : TriRoy : Changed queuing to use NblContext, added conversion routines. + +Authors: + + BrianL + TriRoy + +****************************************************************************/ + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" +#include "send.tmh" +#include "WMBClassTelemetry.h" + + + +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#define MBB_NDP_DATAGRAM_INDEX_INVALID ((ULONG)-1) + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// TYPEDEFS +// +//////////////////////////////////////////////////////////////////////////////// +typedef enum +{ + MbbNdpTypeNoCrc = 0, + MbbNdpTypeCrc, + MbbNdpTypeIps, + MbbNdpTypeVendor_1, // Vendor with session id X (need not be 1) + MbbNdpTypeVendor_2, // Vendor with session id Y (need not be X + 1) + MbbNdpTypeVendor_3, + MbbNdpTypeVendor_Max, // Max 4 vendor sessions in one NTB + MbbNdpTypeMax + +} MBB_NDP_TYPE; + +typedef struct _MBB_NB_CONTEXT +{ + PMDL DataStartMdl; + PMDL DataEndMdl; + PMDL PaddingMdl; + PMDL ModifiedMdl; + MDL OriginalMdl; + PNPAGED_LOOKASIDE_LIST NbLookasideList; + +} MBB_NB_CONTEXT, +*PMBB_NB_CONTEXT; + +typedef +__callback VOID +(*MBB_NBL_CLEANUP_CALLBACK)( + __in PNET_BUFFER_LIST NetBufferList, + __in PVOID Context + ); + +typedef struct _MBB_NBL_CONTEXT +{ + // + // Protected by send queue lock + // + LIST_ENTRY NblQLink; + LIST_ENTRY DispatchQLink; + PNET_BUFFER_LIST NetBufferList; + PNET_BUFFER CurrentNb; + BOOLEAN Failed; + ULONG NbTotalCount; + ULONG NbDispatchCount; + ULONG SessionId; + // + // Protected by Interlock + // + ULONG NbCompleteCount; + + MBB_NBL_CLEANUP_CALLBACK CleanupCallback; + PVOID CleanupCallbackContext; + PNPAGED_LOOKASIDE_LIST NblLookasideList; + PNPAGED_LOOKASIDE_LIST NbLookasideList; + + // + // State for Dss data + // + MBB_REQUEST_HANDLE DssRequestHandle; + ULONG DssSessionId; + + +} MBB_NBL_CONTEXT, +*PMBB_NBL_CONTEXT; + +__inline +BOOLEAN +MbbNblContextIsDssData( + __in PMBB_NBL_CONTEXT NblContext + ) +{ + if( NblContext->DssSessionId != (ULONG)(-1)) + return TRUE; + else + return FALSE; +} + + +typedef struct _MBB_NDP_HEADER_ENTRY +{ + MBB_NDP_TYPE NdpType; + ULONG SessionId; + ULONG DatagramOffset; + ULONG DatagramLength; + ULONG NextEntryIndex; + PNET_BUFFER NetBuffer; + PNET_BUFFER_LIST NetBufferList; + +} MBB_NDP_HEADER_ENTRY, +*PMBB_NDP_HEADER_ENTRY; + +typedef struct _MBB_NTB_BUILD_CONTEXT +{ + LIST_ENTRY NtbQLink; + // + // Read-only values + // + BOOLEAN IsNtb32Bit; + ULONG NtbHeaderSize; + ULONG NdpHeaderFixedSize; + ULONG NdpDatagramEntrySize; + ULONG NtbOutMaxSize; + USHORT NtbOutMaxDatagrams; + USHORT NdpOutDivisor; + USHORT NdpOutPayloadRemainder; + USHORT NdpOutAlignment; + NDIS_HANDLE MiniportHandle; + PVOID PaddingBuffer; + PNPAGED_LOOKASIDE_LIST NtbLookasideList; + // + // Network Transfer Header(NTH) + // + union { + NCM_NTH16 Nth16; + NCM_NTH32 Nth32; + }; + PMDL NthMdl; + // + // NDP Header + // + PMDL NdpMdl; + ULONG NdpSize; + PVOID NdpBuffer; + // + // NDP Datagrams + // + ULONG DatagramCount; + ULONG DatagramLength; + PMDL DatagramLastMdl; + // + // NDP Headers. Varialble length array is limited + // to NdpMaxDatagrams. NdpFirstDatagramEntry of -1 + // is invalid. + // + ULONG NdpFirstDatagramEntry[MbbNdpTypeMax]; + MBB_NDP_HEADER_ENTRY NdpDatagramEntries[ANYSIZE_ARRAY]; + +} MBB_NTB_BUILD_CONTEXT, +*PMBB_NTB_BUILD_CONTEXT; + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// PROTOTYPES +// +//////////////////////////////////////////////////////////////////////////////// + +// +// NTB Context +// + +PMBB_NTB_BUILD_CONTEXT +MbbNtbAllocateContext( + __in NDIS_HANDLE MiniportHandle, + __in PNPAGED_LOOKASIDE_LIST NtbLookasideList, + __in PMBB_BUS_PARAMETERS BusParams, + __in PVOID PaddingBuffer, + __in ULONG NtbSequence + ); + +VOID +MbbNtbCleanupContext( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in NTSTATUS NtStatus + ); + +NDIS_STATUS +MbbNtbAddNdpHeaders( + __in PMBB_NTB_BUILD_CONTEXT NtbContext + ); + +ULONG +MbbNtbMapNdpTypeToSignature( + __in MBB_NDP_TYPE MbbNdpType, + __in BOOLEAN Is32Bit, + __in ULONG SessionId + ); + +VOID +MbbNtbFillNdp32Header( + __in PNCM_NDP32 Ndp, + __in MBB_NDP_TYPE NdpType, + __in PMBB_NTB_BUILD_CONTEXT NtbContext + ); + +VOID +MbbNtbFillNdp16Header( + __in PNCM_NDP16 Ndp, + __in MBB_NDP_TYPE NdpType, + __in PMBB_NTB_BUILD_CONTEXT NtbContext + ); + +FORCEINLINE +PMDL +MbbNtbGetMdlChainHead( + __in PMBB_NTB_BUILD_CONTEXT NtbContext + ); + +NDIS_STATUS +MbbNtbAddNbl( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in PNET_BUFFER_LIST NetBufferList + ); + +NDIS_STATUS +MbbNtbAddNb( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in PNPAGED_LOOKASIDE_LIST NbLookasideList, + __in PNET_BUFFER NetBuffer, + __in PNET_BUFFER_LIST NetBufferList, + __in MBB_NDP_TYPE CurrentNdpType, + __in ULONG SessionId + ); + +VOID +MbbNtbChainNb( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in PNET_BUFFER NetBuffer + ); + +// Test + +NDIS_STATUS +MbbNtbValidate( + __in PVOID Nth, + __in ULONG BufferLength, + __in BOOLEAN Is32Bit + ); + +#if DBG + +NDIS_STATUS +MbbTestValidateNtb( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in_bcount(ScratchLength) PCHAR ScratchBuffer, + __in ULONG ScratchLength + ); +#endif + +// +// NB Context +// + +PMBB_NB_CONTEXT +MbbNbAllocateContext( + __in PNET_BUFFER NetBuffer, + __in ULONG DatagramLength, + __in PVOID PaddingBuffer, + __in ULONG PaddingLength, + __in PNPAGED_LOOKASIDE_LIST NbLookasideList, + __in NDIS_HANDLE MiniportHandle + ); + +VOID +MbbNbCleanupContext( + __in PNET_BUFFER NetBuffer + ); + +FORCEINLINE +PMDL +MbbNbGetFirstMdl( + __in PNET_BUFFER NetBuffer + ); + +FORCEINLINE +PMDL +MbbNbGetLastMdl( + __in PNET_BUFFER NetBuffer + ); + +VOID +MbbNbSaveAndSetMdl( + __in PNET_BUFFER NetBuffer, + __in PMDL MdlToSave, + __in PMDL MdlToSet + ); + +VOID +MbbNbRestoreMdl( + __in PNET_BUFFER NetBuffer + ); + +// +// NBL Context +// + +PMBB_NBL_CONTEXT +MbbNblAllocateContext( + __in PNET_BUFFER_LIST NetBufferList, + __in PNPAGED_LOOKASIDE_LIST NblLookasideList, + __in PNPAGED_LOOKASIDE_LIST NbLookasideList, + __in MBB_NBL_CLEANUP_CALLBACK CleanupCallback, + __in PVOID CleanupCallbackContext + ); + +VOID +MbbNblFinalizeContext( + __in PNET_BUFFER_LIST NetBufferList, + __in ULONG NbCount, + __in NTSTATUS NtStatus + ); + +FORCEINLINE +PNET_BUFFER +MbbNblGetNextDispatchNb( + __in PNET_BUFFER_LIST NetBufferList + ); + +FORCEINLINE +PNET_BUFFER +MbbNblAdvanceDispatchNb( + __in PNET_BUFFER_LIST NetBufferList + ); + +// +// Send Queue +// + +_Acquires_lock_( SendQueue->Lock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, SendQueue ) +FORCEINLINE +VOID +MbbSendQLock( + __in PMBB_SEND_QUEUE SendQueue, + __in BOOLEAN DispatchLevel + ); + +_Releases_lock_( SendQueue->Lock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, SendQueue ) +FORCEINLINE +VOID +MbbSendQUnlock( + __in PMBB_SEND_QUEUE SendQueue, + __in BOOLEAN DispatchLevel + ); + +FORCEINLINE +VOID +MbbSendQResetNtbSequence( + __in PMBB_SEND_QUEUE SendQueue + ); + +FORCEINLINE +ULONG +MbbSendQGetNtbSequence( + __in PMBB_SEND_QUEUE SendQueue + ); + +VOID +MbbSendQProcess( + __in PMBB_SEND_QUEUE SendQueue, + __in BOOLEAN DispatchLevel + ); + +_Requires_lock_held_(SendQueue->Lock) +NDIS_STATUS +MbbSendQQueueNbl( + __in PMBB_SEND_QUEUE SendQueue, + __in PNET_BUFFER_LIST NetBufferList, + __in ULONG SessionId + ); + +VOID +MbbSendQDequeueNbl( + __in PNET_BUFFER_LIST NetBufferList, + __in PVOID Context + ); + +VOID +MbbSendQCompleteNtb( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in MBB_REQUEST_HANDLE RequestHandle, + __in NTSTATUS NtStatus, + __in PMDL Mdl + ); + +VOID +MbbSendQCancelRequests( + __in PMBB_SEND_QUEUE SendQueue, + __in NDIS_STATUS Status, + __in BOOLEAN WaitForCompletion, + __in BOOLEAN ExternalDataOnly + ); + +_Requires_lock_held_(SendQueue->Lock) +NDIS_STATUS +MbbSendQQueueDssData( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_SEND_QUEUE SendQueue, + __in MBB_REQUEST_HANDLE RequestHandle, + __in ULONG RequestId, + __in ULONG SessionId, + __in ULONG DataSize, + __in PVOID Data + ); + +VOID +MbbSendQDequeueDssData( + __in PNET_BUFFER_LIST NetBufferList, + __in PVOID Context + ); + +//////////////////////////////////////////////////////////////////////////////// +// +// IMPLEMENTATION +// +//////////////////////////////////////////////////////////////////////////////// +_Acquires_lock_( SendQueue->Lock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, SendQueue ) +FORCEINLINE +VOID +MbbSendQLock( + __in PMBB_SEND_QUEUE SendQueue, + __in BOOLEAN DispatchLevel + ) +{ + if( DispatchLevel == TRUE ) + { + NdisDprAcquireSpinLock( &SendQueue->Lock ); + } + else + { + NdisAcquireSpinLock( &SendQueue->Lock ); + } +} + +_Releases_lock_( SendQueue->Lock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, SendQueue ) +FORCEINLINE +VOID +MbbSendQUnlock( + __in PMBB_SEND_QUEUE SendQueue, + __in BOOLEAN DispatchLevel + ) +{ + if( DispatchLevel == TRUE ) + { + NdisDprReleaseSpinLock( &SendQueue->Lock ); + } + else + { + NdisReleaseSpinLock( &SendQueue->Lock ); + } +} + +NDIS_STATUS +MbbSendQInitialize( + __in PMBB_SEND_QUEUE SendQueue, + __in ULONG MaxConcurrentSends, + __in MBB_DRAIN_COMPLETE DrainCompleteCallback, + __in PVOID DrainCompleteCallbackContext, + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_BUS_HANDLE BusHandle, + __in NDIS_HANDLE MiniportHandle + ) +{ + ULONG PaddingLength; + ULONG NtbSize; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + NET_BUFFER_POOL_PARAMETERS NbPoolParameters; + NET_BUFFER_LIST_POOL_PARAMETERS NblPoolParameters; + + do + { + RtlZeroMemory( SendQueue, sizeof(MBB_SEND_QUEUE) ); + + NdisAllocateSpinLock( &SendQueue->Lock ); + InitializeListHead( &SendQueue->NtbQueue ); + InitializeListHead( &SendQueue->NblTrackList ); + InitializeListHead( &SendQueue->NblDispatchQueue ); + + KeInitializeEvent( + &SendQueue->NblQueueEmptyEvent, + NotificationEvent, + TRUE + ); + PaddingLength = MAX( Adapter->BusParams.NdpOutAlignment, Adapter->BusParams.NdpOutDivisor ); + if( (SendQueue->PaddingBuffer = ALLOCATE_NONPAGED_POOL( PaddingLength )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } +#if DBG + SendQueue->ScratchLength = Adapter->BusParams.MaxOutNtb; + if( (SendQueue->ScratchBuffer = (PCHAR)ALLOCATE_NONPAGED_POOL( SendQueue->ScratchLength )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } +#endif + + RtlZeroMemory( SendQueue->PaddingBuffer, PaddingLength ); + + SendQueue->NblPool = NULL; + + NblPoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NblPoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; + NblPoolParameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; + NblPoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; + NblPoolParameters.fAllocateNetBuffer = TRUE; + NblPoolParameters.ContextSize = 0; + NblPoolParameters.PoolTag = MbbPoolTagNblPool; + NblPoolParameters.DataSize = 0; + + if( (SendQueue->NblPool = NdisAllocateNetBufferListPool( + MiniportHandle, + &NblPoolParameters + )) == NULL ) + { + TraceError( WMBCLASS_SEND, "[Send] FAILED to allocate NetBufferListPool" ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + SendQueue->MaxConcurrentSends = MaxConcurrentSends; + SendQueue->AdapterContext = Adapter; + SendQueue->BusHandle = BusHandle; + + NtbSize = FIELD_OFFSET(MBB_NTB_BUILD_CONTEXT,NdpDatagramEntries); + NtbSize += (Adapter->BusParams.MaxOutDatagrams * sizeof(MBB_NDP_HEADER_ENTRY)); + NdisInitializeNPagedLookasideList( + &SendQueue->NtbLookasideList, + NULL, + NULL, + 0, // Flags + NtbSize, + MbbPoolTagNtbSend, + 0 // Depth + ); + NdisInitializeNPagedLookasideList( + &SendQueue->NblLookasideList, + NULL, + NULL, + 0, // Flags + sizeof(MBB_NBL_CONTEXT), + MbbPoolTagNblSend, + 0 // Depth + ); + NdisInitializeNPagedLookasideList( + &SendQueue->NbLookasideList, + NULL, + NULL, + 0, // Flags + sizeof(MBB_NB_CONTEXT), + MbbPoolTagNbSend, + 0 // Depth + ); + InitDrainObject( + &SendQueue->QueueDrainObject, + DrainCompleteCallback, + DrainCompleteCallbackContext + ); + TraceInfo( WMBCLASS_SEND, "[Send] Initialization complete" ); + } + while( FALSE ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + if( SendQueue->NblPool != NULL ) + { + NdisFreeNetBufferListPool( SendQueue->NblPool ); + SendQueue->NblPool = NULL; + } + + if( SendQueue->PaddingBuffer != NULL ) + FREE_POOL( SendQueue->PaddingBuffer ); + +#if DBG + if( SendQueue->ScratchBuffer != NULL ) + FREE_POOL( SendQueue->ScratchBuffer ); +#endif + + } + return NdisStatus; +} + +VOID +MbbSendQCleanup( + __in PMBB_SEND_QUEUE SendQueue + ) +/*++ + Description + Frees all resources allocated for the queue. + This is called from MiniportHalt so the queue should + already be empty. This routine does not call cancel + or wait for pending requests to complete since there + should not be any. +--*/ +{ + ASSERT( IsListEmpty( &SendQueue->NblTrackList ) == TRUE ); + + NdisDeleteNPagedLookasideList( &SendQueue->NtbLookasideList ); + NdisDeleteNPagedLookasideList( &SendQueue->NblLookasideList ); + NdisDeleteNPagedLookasideList( &SendQueue->NbLookasideList ); + + if( SendQueue->PaddingBuffer != NULL ) + FREE_POOL( SendQueue->PaddingBuffer ); + +#if DBG + if( SendQueue->ScratchBuffer != NULL ) + FREE_POOL( SendQueue->ScratchBuffer ); +#endif + + if( SendQueue->NblPool != NULL ) + { + NdisFreeNetBufferListPool( SendQueue->NblPool ); + SendQueue->NblPool = NULL; + } + + TraceInfo( WMBCLASS_SEND, "[Send] Cleanup complete" ); +} + +VOID +MbbSendQCancel( + __in PMBB_SEND_QUEUE SendQueue, + __in NDIS_STATUS Status, + __in BOOLEAN WaitForCompletion + ) +{ + StartDrain( &SendQueue->QueueDrainObject ); + + // + // NBLs + // + MbbSendQCancelRequests( + SendQueue, + Status, + WaitForCompletion, + FALSE + ); + + TraceInfo( WMBCLASS_SEND, "[Send] Cancel complete" ); +} + +VOID +MbbSendQCancelRequests( + __in PMBB_SEND_QUEUE SendQueue, + __in NDIS_STATUS Status, + __in BOOLEAN WaitForCompletion, + __in BOOLEAN ExternalDataOnly + ) +{ + PLIST_ENTRY ListEntry = NULL; + PLIST_ENTRY NextEntry = NULL; + LIST_ENTRY TempList; + PLIST_ENTRY QueueHead; + PKEVENT QueueEmptyEvent; + PMBB_NBL_CONTEXT NblContext; + PMBB_REQUEST_CONTEXT Request; + + TraceInfo( WMBCLASS_SEND, "[Send] Cancelling %s requests", (ExternalDataOnly? "External": "All") ); + + QueueHead = &SendQueue->NblDispatchQueue; + QueueEmptyEvent = &SendQueue->NblQueueEmptyEvent; + + InitializeListHead( &TempList ); + + MbbSendQLock( SendQueue, FALSE ); + for( ListEntry = QueueHead->Flink; + ListEntry != QueueHead; + ListEntry = NextEntry ) + { + NextEntry = ListEntry->Flink; + RemoveEntryList( ListEntry ); + InsertTailList( &TempList, ListEntry ); + } + MbbSendQUnlock( SendQueue, FALSE ); + + for( ListEntry = TempList.Flink; + ListEntry != &TempList; + ListEntry = NextEntry ) + { + NextEntry = ListEntry->Flink; + RemoveEntryList( ListEntry ); + NblContext = CONTAINING_RECORD( ListEntry, MBB_NBL_CONTEXT, DispatchQLink ); + MbbNblFinalizeContext( + NblContext->NetBufferList, + NblContext->NbTotalCount - NblContext->NbDispatchCount, + Status + ); + } + + if( WaitForCompletion ) + { + TraceInfo( WMBCLASS_SEND, "[Send] Cancel, waiting for %s requests to complete", (ExternalDataOnly? "External": "All") ); + + KeWaitForSingleObject( + QueueEmptyEvent, + Executive, + KernelMode, + FALSE, + NULL + ); + } +} + +VOID +MbbSendQProcess( + __in PMBB_SEND_QUEUE SendQueue, + __in BOOLEAN DispatchLevel + ) +{ + NTSTATUS NtStatus; + NDIS_STATUS NdisStatus; + BOOLEAN AbortDataQueue; + BOOLEAN CompleteNBs; + PMBB_NBL_CONTEXT NblContext; + PMBB_NTB_BUILD_CONTEXT NtbContext; + PMBB_REQUEST_CONTEXT Request; + + // + // Synchronize with other instances of this routine called from completion handlers. + // + MbbSendQLock( SendQueue, DispatchLevel ); + if( SendQueue->ProcessingQueue != FALSE ) + { + MbbSendQUnlock( SendQueue, DispatchLevel ); + return; + } + SendQueue->ProcessingQueue = TRUE; + + while( SendQueue->ConcurrentSends < SendQueue->MaxConcurrentSends && + ! IsListEmpty( &SendQueue->NblDispatchQueue )) + { + // + // Process the data queue + // Try to add as many NBLs as possible to the NTB + // + NtbContext = NULL; + NdisStatus = NDIS_STATUS_SUCCESS; + AbortDataQueue = FALSE; + + while( IsListEmpty(&SendQueue->NblDispatchQueue) == FALSE && + NdisStatus == NDIS_STATUS_SUCCESS ) + { + CompleteNBs = FALSE; + + if( NtbContext == NULL ) + { + if( (NtbContext = MbbNtbAllocateContext( + SendQueue->AdapterContext->MiniportAdapterHandle, + &SendQueue->NtbLookasideList, + &SendQueue->AdapterContext->BusParams, + SendQueue->PaddingBuffer, + MbbSendQGetNtbSequence( SendQueue ) + )) == NULL ) + { + TraceError( WMBCLASS_SEND, "[Send] FAILED to allocate NTB" ); + AbortDataQueue = TRUE; + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + InsertTailList( &SendQueue->NtbQueue, &NtbContext->NtbQLink ); + SendQueue->ConcurrentSends++; + } + NblContext = CONTAINING_RECORD( + RemoveHeadList( &SendQueue->NblDispatchQueue ), + MBB_NBL_CONTEXT, + DispatchQLink + ); + // + // Drop lock for send processing + // + MbbSendQUnlock( SendQueue, DispatchLevel ); + // + // Add NetBuffers from the NetBufferList to the NTB + // + if( (NdisStatus = MbbNtbAddNbl( + NtbContext, + NblContext->NetBufferList + )) == NDIS_STATUS_SUCCESS ) + { + // + // If all NBs in the current NBL can be + // added to the NTB, then try another NBL. + // + } + else if( NdisStatus == NDIS_STATUS_BUFFER_OVERFLOW ) + { + // + // If the NTB was empty and this NBL couldnt be added + // then fail the NBL to prevent retrying forever. + // If all NBs in the current NBL couldnt be + // added then requeue the NBL to the head of the queue. + // + if( NtbContext->DatagramCount == 0 ) + { + TraceError( WMBCLASS_SEND, "[Send][Seq=0x%04x][NBL=0x%p] FAILED to add NBL to empty NTB, status=%!STATUS!", + MBB_NTB_GET_SEQUENCE( &NtbContext->Nth32 ), + NblContext->NetBufferList, + NdisStatus + ); + CompleteNBs = TRUE; + } + else + { + MbbSendQLock( SendQueue, DispatchLevel ); + InsertHeadList( &SendQueue->NblDispatchQueue, &NblContext->DispatchQLink ); + MbbSendQUnlock( SendQueue, DispatchLevel ); + } + } + else + { + TraceError( WMBCLASS_SEND, "[Send][Seq=0x%04x][NBL=0x%p] FAILED to send NBL, status=%!STATUS!", + MBB_NTB_GET_SEQUENCE( &NtbContext->Nth32 ), + NblContext->NetBufferList, + NdisStatus + ); + CompleteNBs = TRUE; + } + // + // If the call failed for complete the remaining NBs with failure. + // + if( CompleteNBs ) + { + MbbNblFinalizeContext( + NblContext->NetBufferList, + NblContext->NbTotalCount - NblContext->NbDispatchCount, + NdisStatus + ); + } + // + // Reacquire lock for re-evaluating the send queue. + // + MbbSendQLock( SendQueue, DispatchLevel ); + } + MbbSendQUnlock( SendQueue, DispatchLevel ); + // + // Send this NTB to the bus and continue processing other requests. + // + if( NtbContext != NULL ) + { + if( NtbContext->DatagramCount > 0 ) + { + MbbNtbAddNdpHeaders( NtbContext ); +#if DBG + if( MbbTestValidateNtb( + NtbContext, + SendQueue->ScratchBuffer, + SendQueue->ScratchLength + ) != NDIS_STATUS_SUCCESS ) + { + ASSERT( FALSE ); + TraceError( WMBCLASS_SEND, "[Send][Seq=0x%04x] FAILED NTB validation, sending anyway", MBB_NTB_GET_SEQUENCE( &NtbContext->Nth32 ) ); + } +#endif + // + // Send the data. On failure, cleanup. + // + NtStatus = MbbBusWriteData( + SendQueue->BusHandle, + NtbContext, + MbbNtbGetMdlChainHead( NtbContext ), + MbbSendQCompleteNtb + ); + } + else + { + TraceError( WMBCLASS_SEND, "[Send][Seq=0x%04x] NTB has no datagrams", MBB_NTB_GET_SEQUENCE( &NtbContext->Nth32 ) ); + NtStatus = STATUS_UNSUCCESSFUL; + } + + if( ! NT_SUCCESS( NtStatus ) ) + { + MbbSendQCompleteNtb( + SendQueue->AdapterContext, + NtbContext, + NtStatus, + MbbNtbGetMdlChainHead( NtbContext ) + ); + } + } + if( AbortDataQueue == TRUE ) + { + MbbSendQCancel( SendQueue, NdisStatus, FALSE ); + } + // + // Reacquire lock for re-evaluating the send queue. + // + MbbSendQLock( SendQueue, DispatchLevel ); + } + // + // Processing complete + // + SendQueue->ProcessingQueue = FALSE; + MbbSendQUnlock( SendQueue, DispatchLevel ); +} + +_Requires_lock_held_(SendQueue->Lock) +NDIS_STATUS +MbbSendQQueueNbl( + __in PMBB_SEND_QUEUE SendQueue, + __in PNET_BUFFER_LIST NetBufferList, + __in ULONG SessionId + ) +{ + PMBB_NBL_CONTEXT NblContext; + + if( (NblContext = MbbNblAllocateContext( + NetBufferList, + &SendQueue->NblLookasideList, + &SendQueue->NbLookasideList, + MbbSendQDequeueNbl, + SendQueue + )) == NULL ) + { + TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] FAILED to allocated context", NetBufferList ); + return NDIS_STATUS_RESOURCES; + } + + // Set the session Id + NblContext->SessionId = SessionId; + + if( IsListEmpty( &SendQueue->NblTrackList ) ) + KeResetEvent( &SendQueue->NblQueueEmptyEvent ); + + InsertTailList( &SendQueue->NblTrackList, &NblContext->NblQLink ); + InsertTailList( &SendQueue->NblDispatchQueue, &NblContext->DispatchQLink ); + + MbbWriteEvent( + &NBL_QUEUED_EVENT, + NULL, + NULL, + 2, + &SendQueue->AdapterContext->TraceInstance, + sizeof(SendQueue->AdapterContext->TraceInstance), + &NetBufferList, + sizeof(NetBufferList) + ); + + return NDIS_STATUS_SUCCESS; +} + +VOID +MbbSendQDequeueNbl( + __in PNET_BUFFER_LIST NetBufferList, + __in PVOID Context + ) +{ + PMBB_SEND_QUEUE SendQueue = (PMBB_SEND_QUEUE)Context; + PMBB_NBL_CONTEXT NblContext = (PMBB_NBL_CONTEXT)NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; + + NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0] = NULL; + + if( NetBufferList->Status != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] Completed with failed NdisStatus=%!STATUS!", + NetBufferList, + NetBufferList->Status + ); + } + else + { + PNET_BUFFER NetBuffer; + for( NetBuffer = NET_BUFFER_LIST_FIRST_NB( NetBufferList ); + NetBuffer != NULL; + NetBuffer = NET_BUFFER_NEXT_NB( NetBuffer ) ) + { + InterlockedAdd64(&SendQueue->AdapterContext->Stats.ifHCOutOctets, NET_BUFFER_DATA_LENGTH(NetBuffer)); + InterlockedIncrement64(&SendQueue->AdapterContext->GenXmitFramesOk); + } + } + + NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0] = NULL; + NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[1] = NblContext; + + MbbWriteEvent( + &NBL_COMPLETED_EVENT, + NULL, + NULL, + 3, + &SendQueue->AdapterContext->TraceInstance, + sizeof(SendQueue->AdapterContext->TraceInstance), + &NetBufferList, + sizeof(NetBufferList), + &NetBufferList->Status, + sizeof(NetBufferList->Status) + ); + + NdisMSendNetBufferListsComplete( + SendQueue->AdapterContext->MiniportAdapterHandle, + NetBufferList, + 0 + ); + DrainRelease( &SendQueue->QueueDrainObject ); + + MbbSendQLock(SendQueue, FALSE); + if (RemoveEntryList(&NblContext->NblQLink)) + KeSetEvent(&SendQueue->NblQueueEmptyEvent, 0, FALSE); + MbbSendQUnlock(SendQueue, FALSE); +} + +VOID +MbbSendQCompleteNtb( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in MBB_REQUEST_HANDLE RequestHandle, + __in NTSTATUS NtStatus, + __in PMDL Mdl + ) +{ + PMBB_SEND_QUEUE SendQueue = &((PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle)->SendQueue; + PMBB_NTB_BUILD_CONTEXT NtbContext = (PMBB_NTB_BUILD_CONTEXT)RequestHandle; + PSTATE_CHANGE_EVENT StateChange=NULL; + + UNREFERENCED_PARAMETER( Mdl ); + + if (!NT_SUCCESS(NtStatus)) + { + if (NtStatus == STATUS_NDIS_ADAPTER_NOT_READY) + { + TraceError(WMBCLASS_SEND, "%!FUNC!: MbbSendQCompleteNtb failed because the data pipes is being reset"); + } + else if (NtStatus == STATUS_CANCELLED) + { + TraceWarn(WMBCLASS_SEND, "%!FUNC!: MbbSendQCompleteNtb failed because the request is cancelled"); + } + else + { + if (InterlockedExchange((LONG*)&SendQueue->LastDataPathTelemetryStatus, MbbDataPathTelmetryStatusReportHang) != MbbDataPathTelmetryStatusReportHang) + { + TraceLoggingWrite( + g_hLoggingProvider, + "WmbclassTxDataPathStatus", + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TraceLoggingWideString(L"Hung", "Status") + ); + } + TraceError(WMBCLASS_SEND, "%!FUNC!: MbbSendQCompleteNtb failed with %!STATUS!, data pipe will restart", NtStatus); + TryQueueStallState(SendQueue); + } + } + else + { + if (InterlockedExchange((LONG*)&SendQueue->LastDataPathTelemetryStatus, MbbDataPathTelmetryStatusReportSuccess) != MbbDataPathTelmetryStatusReportSuccess) + { + TraceLoggingWrite( + g_hLoggingProvider, + "WmbclassTxDataPathStatus", + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TraceLoggingWideString(L"Success", "Status") + ); + } + } + + MbbSendQLock( SendQueue, FALSE ); + RemoveEntryList( &NtbContext->NtbQLink ); + SendQueue->ConcurrentSends--; + MbbSendQUnlock( SendQueue, FALSE ); + + MbbNtbCleanupContext( + NtbContext, + NtStatus + ); + MbbSendQProcess( SendQueue, FALSE ); +} + + +// +// TODO: Needs to be called from Adapter reset +// +FORCEINLINE +VOID +MbbSendQResetNtbSequence( + __in PMBB_SEND_QUEUE SendQueue + ) +{ + InterlockedExchange( &SendQueue->NtbSequence, 0 ); +} + +FORCEINLINE +ULONG +MbbSendQGetNtbSequence( + __in PMBB_SEND_QUEUE SendQueue + ) +{ + return InterlockedIncrement( &SendQueue->NtbSequence ); +} + +// +// NTB Context +// + +PMBB_NTB_BUILD_CONTEXT +MbbNtbAllocateContext( + __in NDIS_HANDLE MiniportHandle, + __in PNPAGED_LOOKASIDE_LIST NtbLookasideList, + __in PMBB_BUS_PARAMETERS BusParams, + __in PVOID PaddingBuffer, + __in ULONG NtbSequence + ) +{ + MBB_NDP_TYPE NdpType; + ULONG DatagramEntryIndex; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG NtbSize; + PMBB_NTB_BUILD_CONTEXT NtbContext; + + do + { + NtbSize = FIELD_OFFSET(MBB_NTB_BUILD_CONTEXT,NdpDatagramEntries); + NtbSize += (BusParams->MaxOutDatagrams * sizeof(MBB_NDP_HEADER_ENTRY)); +#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate ntb context from lookaside pool, released when send queue completes.") + if( (NtbContext = ALLOCATE_LOOKASIDE( NtbLookasideList )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + RtlZeroMemory( NtbContext, NtbSize ); + NtbContext->MiniportHandle = MiniportHandle; + NtbContext->PaddingBuffer = PaddingBuffer; + NtbContext->NtbLookasideList = NtbLookasideList; + // + // Initialize the NTH and the NTH MDL. + // + if( (NtbContext->IsNtb32Bit = BusParams->CurrentMode32Bit) == TRUE ) + { + if( (NtbContext->NthMdl = NdisAllocateMdl( + MiniportHandle, + &NtbContext->Nth32, + sizeof(NtbContext->Nth32) + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + NtbContext->Nth32.dwSignature = NCM_NTH32_SIG; + NtbContext->Nth32.wHeaderLength = sizeof(NCM_NTH32); + NtbContext->Nth32.wSequence = (USHORT)NtbSequence; + + NtbContext->NtbHeaderSize = sizeof(NCM_NTH32); + NtbContext->NdpHeaderFixedSize = sizeof(NCM_NDP32); + NtbContext->NdpDatagramEntrySize = sizeof(NCM_NDP32_DATAGRAM); + } + else + { + if( (NtbContext->NthMdl = NdisAllocateMdl( + MiniportHandle, + &NtbContext->Nth16, + sizeof(NtbContext->Nth16) + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + NtbContext->Nth16.dwSignature = NCM_NTH16_SIG; + NtbContext->Nth16.wHeaderLength = sizeof(NCM_NTH16); + NtbContext->Nth16.wSequence = (USHORT)NtbSequence; + + NtbContext->NtbHeaderSize = sizeof(NCM_NTH16); + NtbContext->NdpHeaderFixedSize = sizeof(NCM_NDP16); + NtbContext->NdpDatagramEntrySize = sizeof(NCM_NDP16_DATAGRAM); + } + // + // Initialize NextEntryIndex + // + for( NdpType = 0; + NdpType < MbbNdpTypeMax; + NdpType++ ) + { + NtbContext->NdpFirstDatagramEntry[NdpType] = MBB_NDP_DATAGRAM_INDEX_INVALID; + } + for( DatagramEntryIndex = 0; + DatagramEntryIndex < BusParams->MaxOutDatagrams; + DatagramEntryIndex ++ ) + { + NtbContext->NdpDatagramEntries[DatagramEntryIndex].NextEntryIndex = MBB_NDP_DATAGRAM_INDEX_INVALID; + } + + NtbContext->NtbOutMaxSize = BusParams->MaxOutNtb; + NtbContext->NtbOutMaxDatagrams = BusParams->MaxOutDatagrams; + NtbContext->NdpOutDivisor = BusParams->NdpOutDivisor; + NtbContext->NdpOutPayloadRemainder = BusParams->NdpOutRemainder; + NtbContext->NdpOutAlignment = BusParams->NdpOutAlignment; + } + while( FALSE ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + if( NtbContext != NULL ) + { + MbbNtbCleanupContext( NtbContext, NdisStatus ); + } + NtbContext = NULL; + } + return NtbContext; +} + +VOID +MbbNtbCleanupContext( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in NTSTATUS NtStatus + ) +{ + ULONG DatagramIndex; + PNET_BUFFER NetBuffer; + PNET_BUFFER_LIST NetBufferList; + + for( DatagramIndex = 0; + DatagramIndex < NtbContext->DatagramCount; + DatagramIndex ++ ) + { + NetBuffer = NtbContext->NdpDatagramEntries[DatagramIndex].NetBuffer; + NetBufferList = NtbContext->NdpDatagramEntries[DatagramIndex].NetBufferList; + + MbbNbCleanupContext( NetBuffer ); + MbbNblFinalizeContext( NetBufferList, 1, NtStatus ); + } + if( NtbContext->NdpMdl != NULL ) + { + NdisFreeMdl( NtbContext->NdpMdl ); + } + if( NtbContext->NthMdl != NULL ) + { + NdisFreeMdl( NtbContext->NthMdl ); + } + if( NtbContext->NdpBuffer != NULL ) + { + FREE_POOL( NtbContext->NdpBuffer ); + } + FREE_LOOKASIDE( NtbContext, NtbContext->NtbLookasideList ); +} + +NDIS_STATUS +MbbNtbAddNbl( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in PNET_BUFFER_LIST NetBufferList + ) +{ + ULONG NbIndex; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PNET_BUFFER NetBuffer; + MBB_NDP_TYPE CurrentNdpType; + PMBB_NBL_CONTEXT NblContext = NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList)[0]; + ULONG SessionId = MBB_DEFAULT_SESSION_ID; + do + { + // + // Pick the NDP type. NoCRC, CRC are not yet used. + // + if (MbbNblContextIsDssData(NblContext)) + { + SessionId = NblContext->DssSessionId; + + // Vendor NDP. Determine if we are already have a NDP for + // this session ID. If yes, add this datagram into that NDP. Else + // assign new NDP for this datagram + for( CurrentNdpType = MbbNdpTypeVendor_1; + CurrentNdpType <= MbbNdpTypeVendor_Max; + CurrentNdpType ++ ) + { + if( NtbContext->NdpFirstDatagramEntry[CurrentNdpType] != MBB_NDP_DATAGRAM_INDEX_INVALID ) + { + // Entry is used. Does it match the session ID I am using? + if (NtbContext->NdpDatagramEntries[NtbContext->NdpFirstDatagramEntry[CurrentNdpType]].SessionId + == SessionId) + { + // Matching session ID. We can use this type + break; + } + } + else + { + // Entry is not used. We will use it + break; + } + } + + if (CurrentNdpType > MbbNdpTypeVendor_Max) + { + // Didnt find an empty slot in this NTB + NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; + break; + } + } + else + { + CurrentNdpType = MbbNdpTypeIps; + + SessionId = NblContext->SessionId; + + ASSERT(NblContext->SessionId != MBB_INVALID_SESSION_ID); + + if( NtbContext->NdpFirstDatagramEntry[CurrentNdpType] != MBB_NDP_DATAGRAM_INDEX_INVALID ) + { + if(NtbContext->NdpDatagramEntries[NtbContext->NdpFirstDatagramEntry[CurrentNdpType]].SessionId + != SessionId) + { + NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; + break; + } + } + } + + // + // Add as many NBs as can fit. + // + for( NetBuffer = MbbNblGetNextDispatchNb( NetBufferList ); + NetBuffer != NULL; + NetBuffer = MbbNblAdvanceDispatchNb( NetBufferList ) ) + { + if( (NdisStatus = MbbNtbAddNb( + NtbContext, + NblContext->NbLookasideList, + NetBuffer, + NetBufferList, + CurrentNdpType, + SessionId + )) != NDIS_STATUS_SUCCESS ) + { + break; + } + } + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbNtbAddNb( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in PNPAGED_LOOKASIDE_LIST NbLookasideList, + __in PNET_BUFFER NetBuffer, + __in PNET_BUFFER_LIST NetBufferList, + __in MBB_NDP_TYPE CurrentNdpType, + __in ULONG SessionId + ) +{ + ULONG DatagramLength; + ULONG DatagramOffset; + ULONG PaddingLength; + ULONG NdpSize; + ULONG NdpIndex; + PMBB_NB_CONTEXT NbContext = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG TotalLength; + ULONG CurrentNdpLastEntryIndex = MBB_NDP_DATAGRAM_INDEX_INVALID; + + do + { + if( (NtbContext->DatagramCount + 1) > NtbContext->NtbOutMaxDatagrams ) + { + NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; + break; + } + + // + // Size of passed in NET_BUFFER, to be updated later in the NDP Context. + // + TotalLength = NtbContext->NtbHeaderSize + NtbContext->DatagramLength; + DatagramLength = NET_BUFFER_DATA_LENGTH( NetBuffer ); + PaddingLength = ALIGN_AT_OFFSET( + TotalLength, + NtbContext->NdpOutDivisor, + NtbContext->NdpOutPayloadRemainder + ) - TotalLength; + // + // Calculate the new NTB size based on the passed in NET_BUFFER + // + + // + // Fixed size NTH & DatagramSize along with Padding for all NDPs + // + DatagramOffset = TotalLength + PaddingLength; + TotalLength += DatagramLength + PaddingLength; + // + // Calculate NDP HeaderSize for all NDPs + // + NdpSize = TotalLength; + for( NdpIndex = 0; + NdpIndex < MbbNdpTypeMax; + NdpIndex ++ ) + { + ULONG NdpDatagramCount = ( NdpIndex == CurrentNdpType )? 1: 0; + ULONG NextEntryIndex = NtbContext->NdpFirstDatagramEntry[NdpIndex]; + + while( NextEntryIndex != MBB_NDP_DATAGRAM_INDEX_INVALID ) + { + if( NdpIndex == CurrentNdpType ) + CurrentNdpLastEntryIndex = NextEntryIndex; + + NdpDatagramCount++; + NextEntryIndex = NtbContext->NdpDatagramEntries[NextEntryIndex].NextEntryIndex; + } + + if( NdpDatagramCount != 0 ) + { + TotalLength = ALIGN( TotalLength, NtbContext->NdpOutAlignment ); + TotalLength += NtbContext->NdpHeaderFixedSize; + TotalLength += (NdpDatagramCount * NtbContext->NdpDatagramEntrySize); + } + } + NdpSize = TotalLength - NdpSize; + // + // Can everything fit? + // + if( TotalLength > NtbContext->NtbOutMaxSize ) + { + NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; + break; + } + if( (NbContext = MbbNbAllocateContext( + NetBuffer, + DatagramLength, + NtbContext->PaddingBuffer, + PaddingLength, + NbLookasideList, + NtbContext->MiniportHandle + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + // + // Update the NTB Context for the new NET_BUFFER. + // + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].DatagramOffset = DatagramOffset; + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].DatagramLength = DatagramLength; + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NdpType = CurrentNdpType; + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].SessionId = SessionId; + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NetBuffer = NetBuffer; + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NetBufferList = NetBufferList; + + if( CurrentNdpLastEntryIndex != MBB_NDP_DATAGRAM_INDEX_INVALID ) + NtbContext->NdpDatagramEntries[CurrentNdpLastEntryIndex].NextEntryIndex = NtbContext->DatagramCount; + + if( NtbContext->NdpFirstDatagramEntry[CurrentNdpType] == MBB_NDP_DATAGRAM_INDEX_INVALID ) + NtbContext->NdpFirstDatagramEntry[CurrentNdpType] = NtbContext->DatagramCount; + + NtbContext->NdpSize = NdpSize; + NtbContext->DatagramCount += 1; + NtbContext->DatagramLength += (DatagramLength + PaddingLength); + + MbbNtbChainNb( NtbContext, NetBuffer ); + } + while( FALSE ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + if( NbContext != NULL ) + MbbNbCleanupContext( NetBuffer ); + } + return NdisStatus; +} + +VOID +MbbNtbChainNb( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in PNET_BUFFER NetBuffer + ) +{ + PMDL MdlToChain; + + if( NtbContext->DatagramLastMdl != NULL ) + { + TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Chaining Mdl=0x%p -> Mdl=0x%p", + NetBuffer, NtbContext->DatagramLastMdl, MbbNbGetFirstMdl( NetBuffer ) + ); + NtbContext->DatagramLastMdl->Next = MbbNbGetFirstMdl( NetBuffer ); + } + else + { + TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Chaining Mdl=0x%p -> Mdl=0x%p", + NetBuffer, NtbContext->NthMdl, MbbNbGetFirstMdl( NetBuffer ) + ); + NtbContext->NthMdl->Next = MbbNbGetFirstMdl( NetBuffer ); + } + + NtbContext->DatagramLastMdl = MbbNbGetLastMdl( NetBuffer ); +} + +ULONG +MbbNtbMapNdpTypeToSignature( + __in MBB_NDP_TYPE MbbNdpType, + __in BOOLEAN Is32Bit, + __in ULONG SessionId + ) +{ + ULONG SessionMask = ( SessionId << NCM_NDP_SESSION_SHIFT ); + + switch( MbbNdpType ) + { + case MbbNdpTypeIps : return (( Is32Bit==TRUE )? NCM_NDP32_IPS | SessionMask + : NCM_NDP16_IPS | SessionMask); + default : + if ((MbbNdpType >= MbbNdpTypeVendor_1) && (MbbNdpType <= MbbNdpTypeVendor_Max)) + { + return (( Is32Bit==TRUE )? NCM_NDP32_VENDOR | SessionMask + : NCM_NDP16_VENDOR | SessionMask); + } + } + return 0; +} + +VOID +MbbNtbFillNdp32Header( + __in PNCM_NDP32 Ndp, + __in MBB_NDP_TYPE NdpType, + __in PMBB_NTB_BUILD_CONTEXT NtbContext + ) +{ + ULONG DatagramIndex; + ULONG NdpDatagramCount; + ULONG NdpDatagramIndex; + PNCM_NDP32_DATAGRAM NdpDatagramEntries; + + DatagramIndex = NtbContext->NdpFirstDatagramEntry[NdpType]; + + // Caller ensured we are OK here + ASSERT(DatagramIndex != MBB_NDP_DATAGRAM_INDEX_INVALID); + + Ndp->dwSignature = MbbNtbMapNdpTypeToSignature( + NdpType, + TRUE, + NtbContext->NdpDatagramEntries[DatagramIndex].SessionId + ); + Ndp->dwNextFpIndex = 0; + NdpDatagramEntries = Ndp->Datagram; + // + // Add datagram entries to the NDP Table + // + NdpDatagramIndex = 0; + NdpDatagramCount = 0; + + for( DatagramIndex = NtbContext->NdpFirstDatagramEntry[NdpType]; + DatagramIndex != MBB_NDP_DATAGRAM_INDEX_INVALID; + DatagramIndex = NtbContext->NdpDatagramEntries[DatagramIndex].NextEntryIndex ) + { + NdpDatagramEntries[NdpDatagramIndex].dwDatagramIndex = NtbContext->NdpDatagramEntries[DatagramIndex].DatagramOffset; + NdpDatagramEntries[NdpDatagramIndex].dwDatagramLength = NtbContext->NdpDatagramEntries[DatagramIndex].DatagramLength; + NdpDatagramIndex++; + NdpDatagramCount++; + } + // + // Terminating entry is taken in to account + // in the fixed size NDP Header. + // + NdpDatagramEntries[NdpDatagramIndex].dwDatagramIndex = 0; + NdpDatagramEntries[NdpDatagramIndex].dwDatagramLength = 0; + + Ndp->wLength = (USHORT)(NtbContext->NdpHeaderFixedSize + (NdpDatagramIndex * NtbContext->NdpDatagramEntrySize)); +} + +VOID +MbbNtbFillNdp16Header( + __in PNCM_NDP16 Ndp, + __in MBB_NDP_TYPE NdpType, + __in PMBB_NTB_BUILD_CONTEXT NtbContext + ) +{ + ULONG DatagramIndex; + ULONG NdpDatagramCount; + ULONG NdpDatagramIndex; + PNCM_NDP16_DATAGRAM NdpDatagramEntries; + + DatagramIndex = NtbContext->NdpFirstDatagramEntry[NdpType]; + + // Caller ensured we are OK here + ASSERT(DatagramIndex != MBB_NDP_DATAGRAM_INDEX_INVALID); + + Ndp->dwSignature = MbbNtbMapNdpTypeToSignature( + NdpType, + FALSE, + NtbContext->NdpDatagramEntries[DatagramIndex].SessionId + ); + + Ndp->wNextFpIndex = 0; + NdpDatagramEntries = Ndp->Datagram; + // + // Add datagram entries to the NDP Table + // + NdpDatagramIndex = 0; + NdpDatagramCount = 0; + + for( DatagramIndex = NtbContext->NdpFirstDatagramEntry[NdpType]; + DatagramIndex != MBB_NDP_DATAGRAM_INDEX_INVALID; + DatagramIndex = NtbContext->NdpDatagramEntries[DatagramIndex].NextEntryIndex ) + { + NdpDatagramEntries[NdpDatagramIndex].wDatagramIndex = (USHORT)NtbContext->NdpDatagramEntries[DatagramIndex].DatagramOffset; + NdpDatagramEntries[NdpDatagramIndex].wDatagramLength = (USHORT)NtbContext->NdpDatagramEntries[DatagramIndex].DatagramLength; + NdpDatagramIndex++; + NdpDatagramCount++; + } + // + // Terminating entry is taken in to account + // in the fixed size NDP Header. + // + NdpDatagramEntries[NdpDatagramIndex].wDatagramIndex = 0; + NdpDatagramEntries[NdpDatagramIndex].wDatagramLength = 0; + + Ndp->wLength = (USHORT)(NtbContext->NdpHeaderFixedSize + (NdpDatagramCount * NtbContext->NdpDatagramEntrySize)); +} + +NDIS_STATUS +MbbNtbAddNdpHeaders( + __in PMBB_NTB_BUILD_CONTEXT NtbContext + ) +{ + // Offset from the start of the NTB buffer to the start of NDP headers + ULONG NdpStartOffset; + // Offset from the start of the NTB Buffer to the current position. + ULONG NtbOffset; + PCHAR NdpBuffer; + MBB_NDP_TYPE NdpType; + PNCM_NDP16 Ndp16; + PNCM_NDP32 Ndp32; + PNCM_NDP16 PreviousNdp16 = NULL; + PNCM_NDP32 PreviousNdp32 = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + do + { + // + // Allocate buffer for all NDP headers. + // This includes padding for NDP Header alignment. + // + if( (NtbContext->NdpBuffer = ALLOCATE_NONPAGED_POOL( + NtbContext->NdpSize + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + NdpBuffer = (PCHAR)(NtbContext->NdpBuffer); + // + // Chain the NDP Header through its MDL to datagram MDL + // + if( (NtbContext->NdpMdl = NdisAllocateMdl( + NtbContext->MiniportHandle, + NtbContext->NdpBuffer, + NtbContext->NdpSize + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + NtbContext->DatagramLastMdl->Next = NtbContext->NdpMdl; + NdpStartOffset = NtbContext->NtbHeaderSize + NtbContext->DatagramLength; + + if( NtbContext->IsNtb32Bit ) + NtbContext->Nth32.dwFpIndex = ALIGN( NdpStartOffset, NtbContext->NdpOutAlignment ); + else + NtbContext->Nth16.wFpIndex = (USHORT)ALIGN( NdpStartOffset, NtbContext->NdpOutAlignment ); + + NtbOffset = NdpStartOffset; + + for( NdpType = 0; + NdpType < MbbNdpTypeMax; + NdpType ++ ) + { + if( NtbContext->NdpFirstDatagramEntry[NdpType] == MBB_NDP_DATAGRAM_INDEX_INVALID ) + continue; + + NtbOffset = ALIGN( NtbOffset, NtbContext->NdpOutAlignment ); + + if( NtbContext->IsNtb32Bit == TRUE ) + { + Ndp32 = (PNCM_NDP32)(NdpBuffer + (NtbOffset - NdpStartOffset)); + + MbbNtbFillNdp32Header( + Ndp32, + NdpType, + NtbContext + ); + + if( PreviousNdp32 != NULL ) + PreviousNdp32->dwNextFpIndex = NtbOffset; + + NtbOffset += Ndp32->wLength; + PreviousNdp32 = Ndp32; + } + else + { + Ndp16 = (PNCM_NDP16)(NdpBuffer + (NtbOffset - NdpStartOffset)); + + MbbNtbFillNdp16Header( + Ndp16, + NdpType, + NtbContext + ); + + if( PreviousNdp16 != NULL ) + PreviousNdp16->wNextFpIndex = (USHORT)NtbOffset; + + NtbOffset += Ndp16->wLength; + PreviousNdp16 = Ndp16; + } + } + + if( NtbContext->IsNtb32Bit == TRUE ) + { + NtbContext->Nth32.dwBlockLength = NtbContext->NtbHeaderSize; + NtbContext->Nth32.dwBlockLength += NtbContext->DatagramLength; + NtbContext->Nth32.dwBlockLength += NtbContext->NdpSize; + } + else + { + NtbContext->Nth16.wBlockLength = (USHORT)(NtbContext->NtbHeaderSize); + NtbContext->Nth16.wBlockLength += (USHORT)(NtbContext->DatagramLength); + NtbContext->Nth16.wBlockLength += (USHORT)(NtbContext->NdpSize); + } + } + while( FALSE ); + // + // No cleanup. Cleanup done by caller. + // + return NdisStatus; +} + +FORCEINLINE +PMDL +MbbNtbGetMdlChainHead( + __in PMBB_NTB_BUILD_CONTEXT NtbContext + ) +{ + return NtbContext->NthMdl; +} + +// Test +#if DBG +NDIS_STATUS +MbbTestValidateNtb( + __in PMBB_NTB_BUILD_CONTEXT NtbContext, + __in_bcount(ScratchLength) PCHAR ScratchBuffer, + __in ULONG ScratchLength + ) +{ + PMDL CurrentMdl; + ULONGLONG NtbLength; + ULONG MdlLength; + PVOID MdlVa; + PVOID Nth; + + Nth = ScratchBuffer; + NtbLength = 0; + + for( CurrentMdl = MbbNtbGetMdlChainHead( NtbContext ); + CurrentMdl != NULL; + CurrentMdl = CurrentMdl->Next ) + { + MdlLength = MmGetMdlByteCount( CurrentMdl ); + + if( (MdlVa = MmGetSystemAddressForMdlSafe( + CurrentMdl, + NormalPagePriority | MdlMappingNoExecute + )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + if( (NtbLength+MdlLength) > ScratchLength ) + { + return NDIS_STATUS_BUFFER_OVERFLOW; + } + + RtlCopyMemory( ScratchBuffer, MdlVa, MdlLength ); + + ScratchBuffer += MdlLength; + NtbLength += MdlLength; + } + + return MbbNtbValidate( + Nth, + (ULONG)NtbLength, + NtbContext->IsNtb32Bit + ); +} +#endif + +// +// NB Context +// + +PMBB_NB_CONTEXT +MbbNbAllocateContext( + __in PNET_BUFFER NetBuffer, + __in ULONG DatagramLength, + __in PVOID PaddingBuffer, + __in ULONG PaddingLength, + __in PNPAGED_LOOKASIDE_LIST NbLookasideList, + __in NDIS_HANDLE MiniportHandle + ) +{ + PMDL NbDataStartMdl = NET_BUFFER_CURRENT_MDL( NetBuffer ); + ULONG NbDataStartMdlDataOffset = NET_BUFFER_CURRENT_MDL_OFFSET( NetBuffer ); + ULONG NbDataStartMdlDataLength; + PCHAR NbDataStartBuffer; + PMDL NbDataEndMdl; + ULONG NbDataEndMdlDataLength; + PCHAR NbDataEndBuffer; + PMDL NbMdl; + ULONG NbMdlOffset; + ULONG NbMdlLength; + PMDL NbPenultimateMdl; + PMBB_NB_CONTEXT NbContext = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + do + { + // + // Allocate the NbContext + // + if( (NbContext = ALLOCATE_LOOKASIDE(NbLookasideList)) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + RtlZeroMemory( NbContext, sizeof(MBB_NB_CONTEXT) ); + NbContext->NbLookasideList = NbLookasideList; + + NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0] = NbContext; + + if( (NbDataStartBuffer = (PCHAR) MmGetSystemAddressForMdlSafe( + NbDataStartMdl, + NormalPagePriority | MdlMappingNoExecute + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + NbDataStartBuffer += NbDataStartMdlDataOffset; + // + // Create new DataStart and DataEnd Mdls + // to remove the unused data space. + // + NbDataStartMdlDataLength = MmGetMdlByteCount( NbDataStartMdl ); + NbDataStartMdlDataLength -= NbDataStartMdlDataOffset; + + if( (NbContext->DataStartMdl = NdisAllocateMdl( + MiniportHandle, + NbDataStartBuffer, + MIN( DatagramLength, NbDataStartMdlDataLength ) + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Creating DataStartMdl[OrigMdl=0x%p,NewMdl=0x%p]", NetBuffer, NbDataStartMdl, NbContext->DataStartMdl ); + NbContext->DataStartMdl->Next = NbDataStartMdl->Next; + // + // Find the end MDL and the amount of data in the end MDL + // + NbMdl = NbDataStartMdl; + NbMdlOffset = NbDataStartMdlDataOffset; + NbPenultimateMdl = NULL; + + for( NbDataEndMdlDataLength = DatagramLength; + NbDataEndMdlDataLength > (MmGetMdlByteCount( NbMdl ) - NbMdlOffset); + NbDataEndMdlDataLength -= NbMdlLength ) + { + NbPenultimateMdl = NbMdl; + NbMdlLength = MmGetMdlByteCount( NbMdl ) - NbMdlOffset; + NbMdlOffset = 0; + NbMdl = NbMdl->Next; + } + NbDataEndMdl = NbMdl; + // + // If the starting and ending MDLs are not the same + // then build another partial MDL removing any unused + // data space. + // + if( NbDataEndMdl != NbDataStartMdl ) + { + if( (NbDataEndBuffer = MmGetSystemAddressForMdlSafe( + NbDataEndMdl, + NormalPagePriority | MdlMappingNoExecute + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + if( (NbContext->DataEndMdl = NdisAllocateMdl( + MiniportHandle, + NbDataEndBuffer, + NbDataEndMdlDataLength + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Creating DataEndMdl[OrigMdl=0x%p,NewMdl=0x%p]", NetBuffer, NbDataEndMdl, NbContext->DataEndMdl ); + NbContext->DataEndMdl->Next = NULL; + + if( NbPenultimateMdl != NbDataStartMdl ) + { + MDL TempMdl = *NbPenultimateMdl; + TempMdl.Next = NbContext->DataEndMdl; + + MbbNbSaveAndSetMdl( + NetBuffer, + NbPenultimateMdl, + &TempMdl + ); + } + + if( NbContext->DataStartMdl->Next == NbDataEndMdl ) + { + NbContext->DataStartMdl->Next = NbContext->DataEndMdl; + } + } + // + // Allocate padding, if needed. The padding buffer is a share buffer. + // Every padding MDL points to this same buffer. The buffer contains + // all 0s. + // + if( PaddingLength != 0 ) + { + if( (NbContext->PaddingMdl = NdisAllocateMdl( + MiniportHandle, + PaddingBuffer, + PaddingLength + )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Creating PaddingMdl=0x%p", NetBuffer, NbContext->PaddingMdl ); + NbContext->PaddingMdl->Next = NbContext->DataStartMdl; + } + } + while( FALSE ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + if( NbContext != NULL ) + { + MbbNbCleanupContext( NetBuffer ); + NbContext = NULL; + } + } + return NbContext; +} + +VOID +MbbNbCleanupContext( + __in PNET_BUFFER NetBuffer + ) +{ + PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; + + MbbNbRestoreMdl( NetBuffer ); + + if( NbContext->PaddingMdl != NULL ) + { + NdisFreeMdl( NbContext->PaddingMdl ); + } + if( NbContext->DataEndMdl != NULL ) + { + NdisFreeMdl( NbContext->DataEndMdl ); + } + if( NbContext->DataStartMdl != NULL ) + { + NdisFreeMdl( NbContext->DataStartMdl ); + } + NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0] = NULL; + NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[1] = NbContext; + + FREE_LOOKASIDE( NbContext, NbContext->NbLookasideList ); +} + +FORCEINLINE +PMDL +MbbNbGetFirstMdl( + __in PNET_BUFFER NetBuffer + ) +{ + PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; + + if( NbContext->PaddingMdl != NULL ) + return NbContext->PaddingMdl; + else + return NbContext->DataStartMdl; +} + +FORCEINLINE +PMDL +MbbNbGetLastMdl( + __in PNET_BUFFER NetBuffer + ) +{ + PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; + + if( NbContext->DataEndMdl != NULL ) + return NbContext->DataEndMdl; + else + return NbContext->DataStartMdl; +} + +VOID +MbbNbSaveAndSetMdl( + __in PNET_BUFFER NetBuffer, + __in PMDL MdlToSave, + __in PMDL MdlToSet + ) +{ + PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; + + if( NbContext->ModifiedMdl == NULL ) + { + NbContext->ModifiedMdl = MdlToSave; + NbContext->OriginalMdl = *MdlToSave; + TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Saving Mdl=0x%p", NetBuffer, NbContext->ModifiedMdl ); + } + *MdlToSave = *MdlToSet; +} + +VOID +MbbNbRestoreMdl( + __in PNET_BUFFER NetBuffer + ) +{ + PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; + + if( NbContext->ModifiedMdl != NULL ) + { + TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Restoring Mdl=0x%p", NetBuffer, NbContext->ModifiedMdl ); + *NbContext->ModifiedMdl = NbContext->OriginalMdl; + NbContext->ModifiedMdl = NULL; + } +} + +// +// NBL Context +// + +PMBB_NBL_CONTEXT +MbbNblAllocateContext( + __in PNET_BUFFER_LIST NetBufferList, + __in PNPAGED_LOOKASIDE_LIST NblLookasideList, + __in PNPAGED_LOOKASIDE_LIST NbLookasideList, + __in MBB_NBL_CLEANUP_CALLBACK CleanupCallback, + __in PVOID CleanupCallbackContext + ) +{ + PMBB_NBL_CONTEXT NblContext = NULL; + PNET_BUFFER NetBuffer; + ULONG NbCount; + + do + { + if( (NblContext = ALLOCATE_LOOKASIDE(NblLookasideList)) == NULL ) + { + break; + } + + InitializeListHead( &NblContext->NblQLink ); + InitializeListHead( &NblContext->DispatchQLink ); + + NblContext->NetBufferList = NetBufferList; + NblContext->NblLookasideList = NblLookasideList; + NblContext->NbLookasideList = NbLookasideList; + + NbCount = 0; + for( NetBuffer = NET_BUFFER_LIST_FIRST_NB( NetBufferList ); + NetBuffer != NULL; + NetBuffer = NET_BUFFER_NEXT_NB( NetBuffer ) ) + { + NbCount++; + } + NblContext->Failed = FALSE; + NblContext->NbTotalCount = NbCount; + NblContext->NbDispatchCount = 0; + NblContext->NbCompleteCount = 0; + NblContext->CleanupCallback = CleanupCallback; + NblContext->CleanupCallbackContext = CleanupCallbackContext; + NblContext->CurrentNb = NET_BUFFER_LIST_FIRST_NB( NetBufferList ); + NblContext->DssRequestHandle = NULL; + NblContext->DssSessionId = (ULONG)(-1); + NblContext->SessionId = MBB_INVALID_SESSION_ID; + + NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList)[0] = NblContext; + } + while( FALSE ); + + return NblContext; +} + +VOID +MbbNblFinalizeContext( + __in PNET_BUFFER_LIST NetBufferList, + __in ULONG NbCount, + __in NTSTATUS NtStatus + ) +{ + PMBB_NBL_CONTEXT NblContext = (PMBB_NBL_CONTEXT)NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; + ULONG OriginalCount; + ULONG NewCount; + + OriginalCount = NblContext->NbCompleteCount; + NewCount = OriginalCount + NbCount; + + while( InterlockedCompareExchange( + &NblContext->NbCompleteCount, + NewCount, + OriginalCount + ) != OriginalCount ) + { + OriginalCount = NblContext->NbCompleteCount; + NewCount = OriginalCount + NbCount; + } + + if( NtStatus != STATUS_SUCCESS ) + { + NblContext->Failed = TRUE; + } + + if( NewCount == NblContext->NbTotalCount ) + { + ASSERT( NblContext->NbCompleteCount == NblContext->NbTotalCount ); + + if( NblContext->Failed == TRUE ) + NetBufferList->Status = NDIS_STATUS_FAILURE; + else + NetBufferList->Status = NDIS_STATUS_SUCCESS; + + NblContext->CleanupCallback( + NetBufferList, + NblContext->CleanupCallbackContext + ); + // + // To catch double completions + // + NblContext->CleanupCallback = MBB_BAD_POINTER; + NblContext->CleanupCallbackContext = MBB_BAD_POINTER; + FREE_LOOKASIDE( NblContext, NblContext->NblLookasideList ); + } +} + +FORCEINLINE +PNET_BUFFER +MbbNblGetNextDispatchNb( + __in PNET_BUFFER_LIST NetBufferList + ) +{ + PMBB_NBL_CONTEXT NblContext = NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; + return NblContext->CurrentNb; +} + +FORCEINLINE +PNET_BUFFER +MbbNblAdvanceDispatchNb( + __in PNET_BUFFER_LIST NetBufferList + ) +{ + PMBB_NBL_CONTEXT NblContext = NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; + + if( NblContext->CurrentNb != NULL ) + { + NblContext->NbDispatchCount++; + NblContext->CurrentNb = NET_BUFFER_NEXT_NB( NblContext->CurrentNb ); + } + return NblContext->CurrentNb; +} + +// +// Miniport handlers +// + +VOID +MbbNdisMiniportSendNetBufferLists( + __in NDIS_HANDLE MiniportAdapterContext, + __in PNET_BUFFER_LIST NetBufferList, + __in NDIS_PORT_NUMBER PortNumber, + __in ULONG SendFlags + ) +{ + NDIS_STATUS NdisStatus; + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + PMBB_SEND_QUEUE SendQueue=&Adapter->SendQueue; + PNET_BUFFER_LIST NextNetBufferList=NULL; + PNET_BUFFER_LIST CurrentNetBufferList; + BOOLEAN DispatchLevel= (SendFlags & NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL) == NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL; + BOOLEAN CompleteNow=FALSE; + ULONG SessionId = MBB_INVALID_SESSION_ID; + PMBB_PORT Port = NULL; + BOOLEAN IsConnected = FALSE; + BOOLEAN CompleteNBLsOnFailure = FALSE; + + + // Get the session id for the corresponding portnumber + Port = MbbWwanTranslatePortNumberToPort( + Adapter, + PortNumber); + + if(!Port) + { + TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] DROPPING all. Received on invalid port %lu", NetBufferList,PortNumber); + CompleteNBLsOnFailure = TRUE; + } + else + { + // Get the connection status and session id for the port. + MBB_ACQUIRE_PORT_LOCK(Port); + + IsConnected = Port->ConnectionState.ConnectionUp; + SessionId = Port->SessionId; + + MBB_RELEASE_PORT_LOCK(Port); + + if(!IsConnected + || SessionId == MBB_INVALID_SESSION_ID ) + { + TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] DROPPING all. Received on disconnected port %lu", NetBufferList, PortNumber); + CompleteNBLsOnFailure = TRUE; + } + } + + if (MbbBusIsFastIO(Adapter->BusHandle) && CompleteNBLsOnFailure == FALSE) + { + USHORT NblContextSize = ALIGN(sizeof(MBB_NBL_TYPE), MEMORY_ALLOCATION_ALIGNMENT); + MBB_NBL_TYPE* NblContext; + for (CurrentNetBufferList = NetBufferList; + CurrentNetBufferList != NULL; + CurrentNetBufferList = NextNetBufferList) + { + if (NdisAllocateNetBufferListContext( + NetBufferList, + NblContextSize, + 0, + MbbPoolTagNblFastIOContext) != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_RECEIVE, "[FastIOSend][DSS NBL=0x%p] FAILED to allocate NetBufferListContext", NetBufferList); + CompleteNBLsOnFailure = TRUE; + break; + } + NblContext = (MBB_NBL_TYPE*)NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); + *NblContext = MBB_NBL_TYPE_IP; + } + } + + if(CompleteNBLsOnFailure) + { + for (CurrentNetBufferList = NetBufferList; + CurrentNetBufferList != NULL; + CurrentNetBufferList = NextNetBufferList) + { + // fail all NBLs + NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(CurrentNetBufferList); + NET_BUFFER_LIST_STATUS(CurrentNetBufferList) = NDIS_STATUS_FAILURE; + + InterlockedIncrement64(&Adapter->Stats.ifOutDiscards); + } + + NdisMSendNetBufferListsComplete( + Adapter->MiniportAdapterHandle, + NetBufferList, + DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0 + ); + } + else if (MbbBusIsFastIO(Adapter->BusHandle)) + { + MbbBusSendNetBufferLists(Adapter->BusHandle, NetBufferList, SessionId, SendFlags); + } + else + { + MbbSendQLock( SendQueue, DispatchLevel ); + + + for( CurrentNetBufferList = NetBufferList; + CurrentNetBufferList != NULL; + CurrentNetBufferList = NextNetBufferList ) + { + NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL( CurrentNetBufferList ); + NET_BUFFER_LIST_NEXT_NBL(CurrentNetBufferList) = NULL; + + CompleteNow = !DrainAddRef( &SendQueue->QueueDrainObject ); + + if( CompleteNow ) + { + CurrentNetBufferList->Status = NDIS_STATUS_PAUSED; + TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] DROPPING", CurrentNetBufferList ); + + MbbSendQUnlock( SendQueue, DispatchLevel ); + + NdisMSendNetBufferListsComplete( + Adapter->MiniportAdapterHandle, + CurrentNetBufferList, + DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0 + ); + + CurrentNetBufferList=NULL; + + InterlockedIncrement64( &Adapter->Stats.ifOutDiscards ); + + MbbSendQLock( SendQueue, DispatchLevel ); + + } + else + { + + if( (NdisStatus = MbbSendQQueueNbl( + SendQueue, + CurrentNetBufferList, + SessionId + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] DROPPING, queuing failed", CurrentNetBufferList ); + CurrentNetBufferList->Status = NdisStatus; + + MbbSendQUnlock( SendQueue, DispatchLevel ); + + NdisMSendNetBufferListsComplete( + Adapter->MiniportAdapterHandle, + CurrentNetBufferList, + DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0 + ); + + // + // a ref was added for this nbl, removed it + // + DrainRelease( &SendQueue->QueueDrainObject ); + + InterlockedIncrement64( &Adapter->Stats.ifOutDiscards ); + MbbSendQLock( SendQueue, DispatchLevel ); + } + CurrentNetBufferList=NULL; + } + } + + MbbSendQUnlock( SendQueue, DispatchLevel ); + + MbbSendQProcess( SendQueue, DispatchLevel ); + + } + + if(Port) + { + //Remove the reference added during find + Dereference(Port); + } + + return; +} + +VOID +MbbNdisMiniportCancelSend( + __in NDIS_HANDLE MiniportAdapterContext, + __in PVOID CancelId + ) +{ + PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; + PMBB_SEND_QUEUE SendQueue=&Adapter->SendQueue; + PLIST_ENTRY ListEntry; + PLIST_ENTRY NextEntry; + LIST_ENTRY TempList; + PMBB_NBL_CONTEXT NblContext = NULL; + + if (MbbBusIsFastIO(Adapter->BusHandle)) + { + MbbBusCancelSendHandler(Adapter->BusHandle, CancelId); + return; + } + + InitializeListHead( &TempList ); + + MbbSendQLock( SendQueue, FALSE ); + for( ListEntry = SendQueue->NblDispatchQueue.Flink; + ListEntry != &SendQueue->NblDispatchQueue; + ListEntry = NextEntry ) + { + NextEntry = ListEntry->Flink; + NblContext = CONTAINING_RECORD( ListEntry, MBB_NBL_CONTEXT, DispatchQLink ); + if( NDIS_GET_NET_BUFFER_LIST_CANCEL_ID( NblContext->NetBufferList ) == CancelId ) + { + RemoveEntryList( ListEntry ); + InsertHeadList( &TempList, ListEntry ); + } + } + MbbSendQUnlock( SendQueue, FALSE ); + + for( ListEntry = TempList.Flink; + ListEntry != &TempList; + ListEntry = NextEntry ) + { + NextEntry = ListEntry->Flink; + RemoveEntryList( ListEntry ); + NblContext = CONTAINING_RECORD( ListEntry, MBB_NBL_CONTEXT, DispatchQLink ); + + TraceInfo( WMBCLASS_SEND, "[Send][NBL=0x%p] Cancelling for CancelId=0x%p", NblContext->NetBufferList, CancelId ); + + MbbNblFinalizeContext( + NblContext->NetBufferList, + NblContext->NbTotalCount - NblContext->NbDispatchCount, + NDIS_STATUS_SEND_ABORTED + ); + } +} + +PNET_BUFFER_LIST +MbbAllocateDssNbl( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_SEND_QUEUE SendQueue, + __in ULONG RequestId, + __in ULONG DataSize, + __in PVOID Data + ) +{ + PMDL Mdl = NULL; + PNET_BUFFER_LIST Nbl = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PVOID CopiedData = NULL; + + do + { + // Make a copy of the data. We need to do this + // since the OID may already be freed +#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate memory for data copy, released when data dequeued from send queue.") + if( (CopiedData = ALLOCATE_NONPAGED_POOL(DataSize)) == NULL) + { + TraceError( WMBCLASS_SEND, "[Send][DSS Write %d] FAILED to create copy of data", RequestId ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + RtlCopyMemory(CopiedData, Data, DataSize); + + if( (Mdl = NdisAllocateMdl( + Adapter->MiniportAdapterHandle, + CopiedData, + DataSize + )) == NULL ) + { + TraceError( WMBCLASS_SEND, "[Send][DSS Write %d] FAILED to allocated Mdl", RequestId ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + if( (Nbl = NdisAllocateNetBufferAndNetBufferList( + SendQueue->NblPool, + 0, + 0, + Mdl, + 0, + DataSize + )) == NULL ) + { + TraceError( WMBCLASS_SEND, "[Send][DSS Write %d] FAILED to allocated Nbl & Nb", RequestId ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + // Log the converted values + TraceInfo( WMBCLASS_SEND, "[Send][Dss Write %d] mapped to [NBL=0x%p] and [NB=0x%p]", + RequestId, Nbl, NET_BUFFER_LIST_FIRST_NB(Nbl)); + + } + while( FALSE ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + if (Nbl) + { + NdisFreeNetBufferList( Nbl ); + Nbl = NULL; + } + + if (Mdl) + { + NdisFreeMdl( Mdl ); + Mdl = NULL; + } + + if (CopiedData) + { + FREE_POOL(CopiedData); + } + } + return Nbl; +} + +VOID +MbbCleanupDssNbl( + _In_ PMBB_SEND_QUEUE SendQueue, + _In_ PNET_BUFFER_LIST NetBufferList + ) +{ + PMDL Mdl = NULL; + PVOID CopiedData = NULL; + ULONG Length; + + Mdl = NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(NetBufferList)); + NdisQueryMdl (Mdl, &CopiedData, &Length, NormalPagePriority | MdlMappingNoExecute); + if (CopiedData) + FREE_POOL(CopiedData); + + // The MDL is self allocated + NdisFreeMdl( Mdl ); + NdisFreeNetBufferList( NetBufferList ); +} + +_Requires_lock_held_(SendQueue->Lock) +NDIS_STATUS +MbbSendQQueueDssData( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_SEND_QUEUE SendQueue, + __in MBB_REQUEST_HANDLE RequestHandle, + __in ULONG RequestId, + __in ULONG SessionId, + __in ULONG DataSize, + __in PVOID Data + ) +{ + PMBB_NBL_CONTEXT NblContext; + PNET_BUFFER_LIST NetBufferList = NULL; + + if( (NetBufferList = MbbAllocateDssNbl( + Adapter, + SendQueue, + RequestId, + DataSize, + Data + )) == NULL ) + { + TraceError( WMBCLASS_SEND, "[Send][DSS Write %d] FAILED to allocated Nbl", RequestId ); + return NDIS_STATUS_RESOURCES; + } + + if( (NblContext = MbbNblAllocateContext( + NetBufferList, + &SendQueue->NblLookasideList, + &SendQueue->NbLookasideList, + MbbSendQDequeueDssData, + SendQueue + )) == NULL ) + { + TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] FAILED to allocated context", NetBufferList ); + MbbCleanupDssNbl(SendQueue, NetBufferList); + return NDIS_STATUS_RESOURCES; + } + + // Save the DSS specific information for completion + NblContext->DssSessionId = SessionId; + NblContext->DssRequestHandle = RequestHandle; + + if( IsListEmpty( &SendQueue->NblTrackList ) ) + KeResetEvent( &SendQueue->NblQueueEmptyEvent ); + + InsertTailList( &SendQueue->NblTrackList, &NblContext->NblQLink ); + InsertTailList( &SendQueue->NblDispatchQueue, &NblContext->DispatchQLink ); + + return NDIS_STATUS_SUCCESS; +} + +VOID +MbbSendQDequeueDssData( + __in PNET_BUFFER_LIST NetBufferList, + __in PVOID Context + ) +{ + PMBB_SEND_QUEUE SendQueue = (PMBB_SEND_QUEUE)Context; + PMBB_NBL_CONTEXT NblContext = (PMBB_NBL_CONTEXT)NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; + + NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0] = NULL; + + if( NetBufferList->Status != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] Completed with failed NdisStatus=%!STATUS!", + NetBufferList, + NetBufferList->Status + ); + } + + NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0] = NULL; + NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[1] = NblContext; + + // Call the completion handler + MbbNdisDeviceServiceSessionSendComplete( + NblContext->DssRequestHandle, + NetBufferList->Status + ); + + // Free the Nbl & stuff associate with the request + MbbCleanupDssNbl(SendQueue, NetBufferList); + + DrainRelease( &SendQueue->QueueDrainObject ); + + MbbSendQLock(SendQueue, FALSE); + if (RemoveEntryList(&NblContext->NblQLink)) + KeSetEvent(&SendQueue->NblQueueEmptyEvent, 0, FALSE); + MbbSendQUnlock(SendQueue, FALSE); +} + +// +// Miniport handlers +// + +NDIS_STATUS +MbbSendDeviceServiceSessionData( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_REQUEST_HANDLE RequestHandle, + __in ULONG RequestId, + __in ULONG SessionId, + __in ULONG DataSize, + __in PVOID Data + ) +{ + NDIS_STATUS NdisStatus; + PMBB_SEND_QUEUE SendQueue=&Adapter->SendQueue; + if (MbbBusIsFastIO(Adapter->BusHandle)) + { + PNET_BUFFER_LIST NetBufferList = NULL; + PVOID NblContext = NULL; + USHORT NblContextSize = ALIGN(sizeof(MBB_NBL_TYPE), MEMORY_ALLOCATION_ALIGNMENT); + MBB_NBL_TYPE NblType; + + if ((NetBufferList = MbbAllocateDssNbl( + Adapter, + SendQueue, + RequestId, + DataSize, + Data)) == NULL) + { + TraceError(WMBCLASS_SEND, "[FastIOSend][DSS Write %d] FAILED to allocate Nbl", RequestId); + return NDIS_STATUS_RESOURCES; + } + +#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate NetBufferList from SendQueue->NblPool, released when FastIOSendNetBufferListsComplete.") + if (NdisAllocateNetBufferListContext( + NetBufferList, + NblContextSize, + 0, + MbbPoolTagNblFastIOContext) != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_RECEIVE, "[FastIOSend][DSS NBL=0x%p] FAILED to allocate NetBufferListContext", NetBufferList); + MbbCleanupDssNbl(SendQueue, NetBufferList); + return NDIS_STATUS_RESOURCES; + } + + NblContext = NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); + *((MBB_NBL_TYPE*)NblContext) = MBB_NBL_TYPE_DSS; + + NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList)[0] = RequestHandle; + + MbbBusSendNetBufferLists(Adapter->BusHandle, NetBufferList, SessionId, 0); + } + else { + MbbSendQLock(SendQueue, FALSE); + + if (!DrainAddRef(&SendQueue->QueueDrainObject)) + { + TraceError(WMBCLASS_SEND, "[Send][DSS Write %d] DROPPING", RequestId); + MbbSendQUnlock(SendQueue, FALSE); + return NDIS_STATUS_ADAPTER_NOT_READY; + } + + if ((NdisStatus = MbbSendQQueueDssData( + Adapter, + SendQueue, + RequestHandle, + RequestId, + SessionId, + DataSize, + Data + )) != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_SEND, "[Send][DSS Write %d] DROPPING, queuing failed", RequestId); + + MbbSendQUnlock(SendQueue, FALSE); + + // + // a ref was added for this DSS data, removed it + // + DrainRelease(&SendQueue->QueueDrainObject); + return NdisStatus; + } + MbbSendQUnlock(SendQueue, FALSE); + + MbbSendQProcess(SendQueue, FALSE); + } + return NDIS_STATUS_SUCCESS; +} + diff --git a/network/wwan/cxwmbclass/send.h b/network/wwan/cxwmbclass/send.h new file mode 100644 index 000000000..36fa6e096 --- /dev/null +++ b/network/wwan/cxwmbclass/send.h @@ -0,0 +1,42 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +NDIS_STATUS +MbbSendQInitialize( + __in PMBB_SEND_QUEUE SendQueue, + __in ULONG MaxConcurrentSends, + __in MBB_DRAIN_COMPLETE DrainCompleteCallback, + __in PVOID DrainCompleteContext, + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_BUS_HANDLE BusHandle, + __in NDIS_HANDLE MiniportHandle + ); + +VOID +MbbSendQCleanup( + __in PMBB_SEND_QUEUE SendQueue + ); + +VOID +MbbSendQCancel( + __in PMBB_SEND_QUEUE SendQueue, + __in NDIS_STATUS Status, + __in BOOLEAN WaitForCompletion + ); + + +NDIS_STATUS +MbbSendDeviceServiceSessionData( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in MBB_REQUEST_HANDLE RequestHandle, + __in ULONG RequestId, + __in ULONG SessionId, + __in ULONG DataSize, + __in PVOID Data + ); + +VOID +MbbCleanupDssNbl( + _In_ PMBB_SEND_QUEUE SendQueue, + _In_ PNET_BUFFER_LIST NetBufferList +); diff --git a/network/wwan/cxwmbclass/tmpMbbMessages.h b/network/wwan/cxwmbclass/tmpMbbMessages.h new file mode 100644 index 000000000..3d73b4df2 --- /dev/null +++ b/network/wwan/cxwmbclass/tmpMbbMessages.h @@ -0,0 +1,3306 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + +/* File created by MIDL compiler version 8.01.0625 */ +/* at Mon Jan 18 19:14:07 2038 + */ +/* @@MIDL_FILE_HEADING( ) */ + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef __MbbMessages_h__ +#define __MbbMessages_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#ifndef DECLSPEC_XFGVIRT +#if _CONTROL_FLOW_GUARD_XFG +#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func)) +#else +#define DECLSPEC_XFGVIRT(base, func) +#endif +#endif + +/* Forward Declarations */ + +/* header files for imported files */ +// #include "wtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* interface __MIDL_itf_MbbMessages_0000_0000 */ +/* [local] */ + +// +// Copyright (C) Microsoft. All rights reserved. +// +#include +// +// Service Ids +// +// Invald GUID +// 00000000-0000-0000-0000-000000000000 +DEFINE_GUID(MBB_UUID_INVALID, 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); +#define MBB_UUID_INVALID_CONSTANT \ + { \ + 0x00000000, 0x0000, 0x0000, \ + { \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ + } \ + } +// Basic IP Connectivity +// a289cc33-bcbb-8b4f-b6b0-133ec2aae6df +DEFINE_GUID(MBB_UUID_BASIC_CONNECT, 0xa289cc33, 0xbcbb, 0x8b4f, 0xb6, 0xb0, 0x13, 0x3e, 0xc2, 0xaa, 0xe6, 0xdf); +#define MBB_UUID_BASIC_CONNECT_CONSTANT \ + { \ + 0xa289cc33, 0xbcbb, 0x8b4f, \ + { \ + 0xb6, 0xb0, 0x13, 0x3e, 0xc2, 0xaa, 0xe6, 0xdf \ + } \ + } +// SMS +// 533fbeeb-14fe-4467-9f90-33a223e56c3f +DEFINE_GUID(MBB_UUID_SMS, 0x533fbeeb, 0x14fe, 0x4467, 0x9f, 0x90, 0x33, 0xa2, 0x23, 0xe5, 0x6c, 0x3f); +#define MBB_UUID_SMS_CONSTANT \ + { \ + 0x533fbeeb, 0x14fe, 0x4467, \ + { \ + 0x9f, 0x90, 0x33, 0xa2, 0x23, 0xe5, 0x6c, 0x3f \ + } \ + } +// USSD +// e550a0c8-5e82-479e-82f7-10abf4c3351f +DEFINE_GUID(MBB_UUID_USSD, 0xe550a0c8, 0x5e82, 0x479e, 0x82, 0xf7, 0x10, 0xab, 0xf4, 0xc3, 0x35, 0x1f); +#define MBB_UUID_USSD_CONSTANT \ + { \ + 0xe550a0c8, 0x5e82, 0x479e, \ + { \ + 0x82, 0xf7, 0x10, 0xab, 0xf4, 0xc3, 0x35, 0x1f \ + } \ + } +// Phonebook +// 4bf38476-1e6a-41db-b1d8-bed289c25bdb +DEFINE_GUID(MBB_UUID_PHONEBOOK, 0x4bf38476, 0x1e6a, 0x41db, 0xb1, 0xd8, 0xbe, 0xd2, 0x89, 0xc2, 0x5b, 0xdb); +#define MBB_UUID_PHONEBOOK_CONSTANT \ + { \ + 0x4bf38476, 0x1e6a, 0x41db, \ + { \ + 0xb1, 0xd8, 0xbe, 0xd2, 0x89, 0xc2, 0x5b, 0xdb \ + } \ + } +// SIM Application Toolkit +// d8f20131-fcb5-4e17-8602-d6ed3816164c +DEFINE_GUID(MBB_UUID_SAT, 0xd8f20131, 0xfcb5, 0x4e17, 0x86, 0x02, 0xd6, 0xed, 0x38, 0x16, 0x16, 0x4c); +#define MBB_UUID_SAT_CONSTANT \ + { \ + 0xd8f20131, 0xfcb5, 0x4e17, \ + { \ + 0x86, 0x02, 0xd6, 0xed, 0x38, 0x16, 0x16, 0x4c \ + } \ + } +// Windows 7 Vendor Extension +// b492e7e2-adba-499d-8401-7794bb913c1c +DEFINE_GUID(MBB_UUID_MS_VENDOR_EXTENSION, 0xb492e7e2, 0xadba, 0x499d, 0x84, 0x01, 0x77, 0x94, 0xbb, 0x91, 0x3c, 0x1c); +#define MBB_UUID_MS_VENDOR_EXTENSION_CONSTANT \ + { \ + 0xb492e7e2, 0xadba, 0x499d, \ + { \ + 0x84, 0x01, 0x77, 0x94, 0xbb, 0x91, 0x3c, 0x1c \ + } \ + } +// Authentication +// 1d2b5ff7-0aa1-48b2-aa52-50f15767174e +DEFINE_GUID(MBB_UUID_AUTH, 0x1d2b5ff7, 0x0aa1, 0x48b2, 0xaa, 0x52, 0x50, 0xf1, 0x57, 0x67, 0x17, 0x4e); +#define MBB_UUID_AUTH_CONSTANT \ + { \ + 0x1d2b5ff7, 0x0aa1, 0x48b2, \ + { \ + 0xaa, 0x52, 0x50, 0xf1, 0x57, 0x67, 0x17, 0x4e \ + } \ + } +// Device Service Stream +// c08a26dd-7718-4382-8482-6e0d583c4d0e +DEFINE_GUID(MBB_UUID_DSS, 0xc08a26dd, 0x7718, 0x4382, 0x84, 0x82, 0x6e, 0x0d, 0x58, 0x3c, 0x4d, 0x0e); +#define MBB_UUID_DSS_CONSTANT \ + { \ + 0xc08a26dd, 0x7718, 0x4382, \ + { \ + 0x84, 0x82, 0x6e, 0x0d, 0x58, 0x3c, 0x4d, 0x0e \ + } \ + } +// Multi-carrier device service +// 8b569648-628d-4653-9b9f-1025404424e1 +DEFINE_GUID(MBB_UUID_MULTICARRIER, 0x8b569648, 0x628d, 0x4653, 0x9b, 0x9f, 0x10, 0x25, 0x40, 0x44, 0x24, 0xe1); +#define MBB_UUID_MULTICARRIER_CONSTANT \ + { \ + 0x8b569648, 0x628d, 0x4653, \ + { \ + 0x9b, 0x9f, 0x10, 0x25, 0x40, 0x44, 0x24, 0xe1 \ + } \ + } +// Host Shutdown device service +// 883b7c26-985f-43fa-9804-27d7fb80959c +DEFINE_GUID(MBB_UUID_HOSTSHUTDOWN, 0x883b7c26, 0x985f, 0x43fa, 0x98, 0x04, 0x27, 0xd7, 0xfb, 0x80, 0x95, 0x9c); +#define MBB_UUID_HOSTSHUTDOWN_CONSTANT \ + { \ + 0x883b7c26, 0x985f, 0x43fa, \ + { \ + 0x98, 0x04, 0x27, 0xd7, 0xfb, 0x80, 0x95, 0x9c \ + } \ + } +// MBIM 2.0 voice extensions +// 8d8b9eba-37be-449b-8f1e-61cb034a702e +DEFINE_GUID(MBB_UUID_VOICEEXTENSIONS, 0x8d8b9eba, 0x37be, 0x449b, 0x8f, 0x1e, 0x61, 0xcb, 0x03, 0x4a, 0x70, 0x2e); +#define MBB_UUID_VOICEEXTENSIONS_CONSTANT \ + { \ + 0x8d8b9eba, 0x37be, 0x449b, \ + { \ + 0x8f, 0x1e, 0x61, 0xcb, 0x03, 0x4a, 0x70, 0x2e \ + } \ + } +// Low-Level UICC Access +// c2f6588e-f037-4bc9-8665-f4d44bd09367 +DEFINE_GUID(MBB_UUID_UICC_LOW_LEVEL, 0xc2f6588e, 0xf037, 0x4bc9, 0x86, 0x65, 0xf4, 0xd4, 0x4b, 0xd0, 0x93, 0x67); +#define MBB_UUID_UICC_LOW_LEVEL_CONSTANT \ + { \ + 0xc2f6588e, 0xf037, 0x4bc9, \ + { \ + 0x86, 0x65, 0xf4, 0xd4, 0x4b, 0xd0, 0x93, 0x67 \ + } \ + } +// Selective Absorption Rate (SAR) control +// 68223d04-9f6c-4e0f-822d-28441fb72340 +DEFINE_GUID(MBB_UUID_SARCONTROL, 0x68223d04, 0x9f6c, 0x4e0f, 0x82, 0x2d, 0x28, 0x44, 0x1f, 0xb7, 0x23, 0x40); +#define MBB_UUID_SARCONTROL_CONSTANT \ + { \ + 0x68223d04, 0x9f6c, 0x4e0f, \ + { \ + 0x82, 0x2d, 0x28, 0x44, 0x1f, 0xb7, 0x23, 0x40 \ + } \ + } +// Basic IP Connectivity Extensions (a private Microsoft service not approved by MBIM USB forum as of 2016/11/09) +// 3d01dcc5-fef5-4d05-0d3a-bef7058e9aaf +DEFINE_GUID(MBB_UUID_BASIC_CONNECT_EXTENSIONS, 0x3d01dcc5, 0xfef5, 0x4d05, 0x0d, 0x3a, 0xbe, 0xf7, 0x05, 0x8e, 0x9a, 0xaf); +#define MBB_UUID_BASIC_CONNECT_EXT_CONSTANT \ + { \ + 0x3d01dcc5, 0xfef5, 0x4d05, \ + { \ + 0x0d, 0x3a, 0xbe, 0xf7, 0x05, 0x8e, 0x9a, 0xaf \ + } \ + } +// DeviceService GUID for Modem Log Transfer (parameter for DSS connect/disconnect request to open/close DSS data channel) +// 0ebb1ceb-af2d-484d-8df3-53bc51fd162c +DEFINE_GUID(MBB_UUID_MODEM_LOG_TRANSFER, 0x0ebb1ceb, 0xaf2d, 0x484d, 0x8d, 0xf3, 0x53, 0xbc, 0x51, 0xfd, 0x16, 0x2c); +#define MBB_UUID_MODEM_LOG_TRANSFER_CONSTANT \ + { \ + 0x0ebb1ceb, 0xaf2d, 0x484d, \ + { \ + 0x8d, 0xf3, 0x53, 0xbc, 0x51, 0xfd, 0x16, 0x2c \ + } \ + } +// +// Context Type GUIDs +// +// MBIMContextTypeNone +// B43F758C-A560-4B46-B35E-C5869641FB54 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_NONE, 0xB43F758C, 0xA560, 0x4B46, 0xB3, 0x5E, 0xC5, 0x86, 0x96, 0x41, 0xFB, 0x54); +// MBIMContextTypeInternet +// 7E5E2A7E-4E6F-7272-736B-656E7E5E2A7E +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_INTERNET, 0x7E5E2A7E, 0x4E6F, 0x7272, 0x73, 0x6B, 0x65, 0x6E, 0x7E, 0x5E, 0x2A, 0x7E); +// MBIMContextTypeVpn +// 9B9F7BBE-8952-44B7-83AC-CA41318DF7A0 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_VPN, 0x9B9F7BBE, 0x8952, 0x44B7, 0x83, 0xAC, 0xCA, 0x41, 0x31, 0x8D, 0xF7, 0xA0); +// MBIMContextTypeVoice +// 88918294-0EF4-4396-8CCA-A8588FBC02B2 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_VOICE, 0x88918294, 0x0EF4, 0x4396, 0x8C, 0xCA, 0xA8, 0x58, 0x8F, 0xBC, 0x02, 0xB2); +// MBIMContextTypeVideoShare +// 05A2A716-7C34-4B4D-9A91-C5EF0C7AAACC +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_VIDEO_SHARE, 0x05A2A716, 0x7C34, 0x4B4D, 0x9A, 0x91, 0xC5, 0xEF, 0x0C, 0x7A, 0xAA, 0xCC); +// MBIMContextTypePurchase +// B3272496-AC6C-422B-A8C0-ACF687A27217 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_PURCHASE, 0xB3272496, 0xAC6C, 0x422B, 0xA8, 0xC0, 0xAC, 0xF6, 0x87, 0xA2, 0x72, 0x17); +// MBIMContextTypeIMS +// 21610D01-3074-4BCE-9425-B53A07D697D6 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_IMS, 0x21610D01, 0x3074, 0x4BCE, 0x94, 0x25, 0xB5, 0x3A, 0x07, 0xD6, 0x97, 0xD6); +// MBIMContextTypeMMS +// 46726664-7269-6BC6-9624-D1D35389ACA9 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MMS, 0x46726664, 0x7269, 0x6BC6, 0x96, 0x24, 0xD1, 0xD3, 0x53, 0x89, 0xAC, 0xA9); +// MBIMContextTypeLocal +// A57A9AFC-B09F-45D7-BB40-033C39F60DB9 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_LOCAL, 0xA57A9AFC, 0xB09F, 0x45D7, 0xBB, 0x40, 0x03, 0x3C, 0x39, 0xF6, 0x0D, 0xB9); +// MBIMMsContextTypeAdmin +// 5f7e4c2e-e80b-40a9-a239-f0abcfd11f4b +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_ADMIN, 0x5f7e4c2e, 0xe80b, 0x40a9, 0xa2, 0x39, 0xf0, 0xab, 0xcf, 0xd1, 0x1f, 0x4b); +// MBIMMSContextTypeApp +// 74d88a3d-dfbd-4799-9a8c-7310a37bb2ee +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_APP, 0x74d88a3d, 0xdfbd, 0x4799, 0x9a, 0x8c, 0x73, 0x10, 0xa3, 0x7b, 0xb2, 0xee); +// MBIMMsContextTypeXcap +// 50d378a7-baa5-4a50-b872-3fe5bb463411 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_XCAP, 0x50d378a7, 0xbaa5, 0x4a50, 0xb8, 0x72, 0x3f, 0xe5, 0xbb, 0x46, 0x34, 0x11); +// MBIMMsContextTypeTethering +// 5e4e0601-48dc-4e2b-acb8-08b4016bbaac +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_TETHERING, 0x5e4e0601, 0x48dc, 0x4e2b, 0xac, 0xb8, 0x08, 0xb4, 0x01, 0x6b, 0xba, 0xac); +// MBIMMsContextTypeEmergencyCalling +// 5f41adb8-204e-4d31-9da8-b3c970e360f2 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_EMERGENCYCALL, 0x5f41adb8, 0x204e, 0x4d31, 0x9d, 0xa8, 0xb3, 0xc9, 0x70, 0xe3, 0x60, 0xf2); +// 9C494542-A43B-4EA5-B8B7-53310E71DF10 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_CUSTOM, 0x9C494542, 0xA43B, 0x4EA5, 0xB8, 0xB7, 0x53, 0x31, 0x0E, 0x71, 0xDF, 0x10); +// 64F65862-6954-4FB3-B6E1-807461ABEBA0 +DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_SUPL, 0x64F65862, 0x6954, 0x4FB3, 0xB6, 0xE1, 0x80, 0x74, 0x61, 0xAB, 0xEB, 0xA0); +// 146FED19-EB71-42A7-B3EB-3875DEA61D92 +DEFINE_GUID(GUID_USB_CAPABILITY_DEVICE_TYPE, 0x146FED19, 0xEB71, 0x42A7, 0xB3, 0xEB, 0x38, 0x75, 0xDE, 0xA6, 0x1D, 0x92); + +#define MBB_STATUS_SUCCESS(STATUS) (((STATUS) == MBB_STATUS_SUCCESS) || ((STATUS) == MBB_STATUS_SMS_MORE_DATA)) +#define MBB_STATUS_IS_BASIC(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_BASIC_START) && ((MBBSTATUS) < MBB_STATUS_BASIC_END)) +#define MBB_STATUS_BASIC_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_BASIC_START) +#define MBB_STATUS_BASIC_COUNT() (MBB_STATUS_BASIC_END - MBB_STATUS_BASIC_START) +#define MBB_STATUS_IS_SMS(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_SMS_START) && ((MBBSTATUS) < MBB_STATUS_SMS_END)) +#define MBB_STATUS_SMS_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_SMS_START) +#define MBB_STATUS_SMS_COUNT() (MBB_STATUS_SMS_END - MBB_STATUS_SMS_START) +#define MBB_STATUS_IS_UICC(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_UICC_START) && ((MBBSTATUS) < MBB_STATUS_UICC_END)) +#define MBB_STATUS_UICC_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_UICC_START) +#define MBB_STATUS_UICC_COUNT() (MBB_STATUS_UICC_END - MBB_STATUS_UICC_START) +#define MBB_STATUS_IS_4_0(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_4_0_START) && ((MBBSTATUS) < MBB_STATUS_4_0_END)) +#define MBB_STATUS_4_0_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_4_0_START) +#define MBB_STATUS_4_0_COUNT() (MBB_STATUS_4_0_END - MBB_STATUS_4_0_START) +#define MBB_UUID_TO_NET(_dest, _src) \ + { \ + (_dest)->Data1 = RtlUlongByteSwap((_src)->Data1); \ + (_dest)->Data2 = RtlUshortByteSwap((_src)->Data2); \ + (_dest)->Data3 = RtlUshortByteSwap((_src)->Data3); \ + RtlCopyMemory((_dest)->Data4, (_src)->Data4, sizeof((_src)->Data4)); \ + } +#define MBB_UUID_TO_HOST(_dest, _src) MBB_UUID_TO_NET(_dest, _src) +#define MBB_IS_DEVICE_REGISTERED(_State_) \ + (((_State_) == MbbRegisterStateHome) || ((_State_) == MbbRegisterStateRoaming) || ((_State_) == MbbRegisterStatePartner)) +#include +#define MBB_MAXIMUM_DATA_CLASS_NAME_LENGTH (11) + +#define MBB_MAXIMUM_DEVICE_ID_LENGTH (17) + +#define MBB_MAXIMUM_FIRMWARE_INFO_LENGTH (31) + +#define MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH (15) + +#define MBB_MAXIMUM_SIM_ICC_ID_LENGTH (20) + +#define MBB_MAXIMUM_TELEPHONE_NUMBER_LENGTH (15) + +#define MBB_MAXIMUM_TELEPHONE_NUMBER_ERRATA_LENGTH (22) + +#define MBB_MAXIMUM_PIN_LENGTH (16) + +#define MBB_MAXIMUM_PROVIDER_ID_LENGTH (6) + +#define MBB_MAXIMUM_PROVIDER_NAME_LENGTH (20) + +#define MBB_MAXIMUM_ROAMING_TEXT_LENGTH (63) + +#define MBB_MAXIMUM_ACCESS_STRING_LENGTH (100) + +#define MBB_MAXIMUM_USERNAME_LENGTH (255) + +#define MBB_MAXIMUM_PASSWORD_LENGTH (255) + +#define MBB_MAXIMUM_SMS_ADDRESS_LENGTH (20) + +#define MBB_MAXIMUM_SMS_CDMA_ADDRESS_LENGTH (49) + +#define MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH (21) + +#define MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH (160) + +#define MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH (183) + +#define MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH (255) + +#define MBB_USSD_STRING_LEN_MAX (160) + +#define MBB_RSSI_DISABLE (0xffffffff) + +#define MBB_RSSI_DEFAULT (0) + +#define MBB_SET_CONTEXT_STATE_EX3_MIN_TLV_CNT (3) + +#define MBB_CONTEXT_STATE_EX3_MIN_TLV_CNT (1) + +#define MBIM_VERSION_1_0 (0x100) + +#define MBIM_MS_EXTENDED_VER_1_0 (0x100) + +#define MBIM_MS_EXTENDED_VER_2_0 (0x200) + +#define MBIM_MS_EXTENDED_VER_3_0 (0x300) + +#define MBIM_MS_EXTENDED_VER_4_0 (0x400) + +#define MBB_MS_DEVICE_CAPS_INFO_V3_MIN_TLV_CNT (6) + +#define MBB_TLV_TYPE_RESERVED (0) + +#define MBB_TLV_TYPE_UE_POLICIES (1) + +#define MBB_TLV_TYPE_SINGLE_NSSAI (2) + +#define MBB_TLV_TYPE_ALLOWED_NSSAI (3) + +#define MBB_TLV_TYPE_CFG_NSSAI (4) + +#define MBB_TLV_TYPE_DFLT_CFG_NSSAI (5) + +#define MBB_TLV_TYPE_PRECFG_DFLT_CFG_NSSAI (6) + +#define MBB_TLV_TYPE_REJ_NSSAI (7) + +#define MBB_TLV_TYPE_LADN (8) + +#define MBB_TLV_TYPE_TAI (9) + +#define MBB_TLV_TYPE_WCHAR_STR (10) + +#define MBB_TLV_TYPE_UINT16_TBL (11) + +#define MBB_TLV_TYPE_EAP_PACKET (12) + +#define MBB_TLV_TYPE_PCO (13) + +#define MBB_TLV_TYPE_ROUTE_SELECTION_DESCRIPTORS (14) + +#define MBB_TLV_TYPE_TRAFFIC_PARAMETERS (15) + +#define MBB_TLV_TYPE_WAKE_COMMAND (16) + +#define MBB_TLV_TYPE_WAKE_PACKET (17) + +#define MBB_TLV_TYPE_OSID (18) + +#define MBB_TLV_TYPE_3GPP_REL_VERSION (19) + +#define MBB_TLV_TYPE_URSP_RULES_TD_ONLY (20) + +#define MBB_TLV_TYPE_SESSION_ID (21) + +#define MBB_NW_PARAMS_INFO_CONFIG_TLV_CNT (6) + +#define MBB_NW_PARAMS_INFO_UE_POLICIES_TLV_CNT (1) + +typedef unsigned short MBB_TLV_TYPE; + +typedef struct _MBB_TLV_IE +{ + MBB_TLV_TYPE Type; + UCHAR Reserved; + UCHAR PaddingLength; + ULONG DataLength; +} MBB_TLV_IE; + +typedef struct _MBB_TLV_IE* PMBB_TLV_IE; + +typedef enum _USB_CAP_DEVICE_TYPE +{ + USB_CAP_DEVICE_TYPE_USB = 0, + USB_CAP_DEVICE_TYPE_UDE_MBIM = 1, + USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO = 2, + USB_CAP_DEVICE_TYPE_MAXIMUM = (USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO + 1) +} USB_CAP_DEVICE_TYPE; + +typedef struct _USB_CAP_DEVICE_INFO_HEADER +{ + USB_CAP_DEVICE_TYPE DeviceType; + UCHAR DeviceMinorVersion; + UCHAR DeviceMajorVersion; + ULONG Reserved; +} USB_CAP_DEVICE_INFO_HEADER; + +typedef struct _USB_CAP_DEVICE_INFO_HEADER* PUSB_CAP_DEVICE_INFO_HEADER; + +typedef struct _USB_CAP_DEVICE_INFO +{ + USB_CAP_DEVICE_INFO_HEADER DeviceInfoHeader; +} USB_CAP_DEVICE_INFO; + +typedef struct _USB_CAP_DEVICE_INFO* PUSB_CAP_DEVICE_INFO; + +typedef enum _MBB_NBL_TYPE +{ + MBB_NBL_TYPE_IP = 0, + MBB_NBL_TYPE_DSS = 1, + MBB_NBL_TYPE_MAXIMUM = (MBB_NBL_TYPE_DSS + 1) +} MBB_NBL_TYPE; + +typedef enum _MBB_STATUS +{ + MBB_STATUS_SUCCESS = 0, + MBB_STATUS_BASIC_START = 0, + MBB_STATUS_BUSY = 1, + MBB_STATUS_FAILURE = 2, + MBB_STATUS_SIM_NOT_INSERTED = 3, + MBB_STATUS_BAD_SIM = 4, + MBB_STATUS_PIN_REQUIRED = 5, + MBB_STATUS_PIN_DISABLED = 6, + MBB_STATUS_NOT_REGISTERED = 7, + MBB_STATUS_PROVIDERS_NOT_FOUND = 8, + MBB_STATUS_NO_DEVICE_SUPPORT = 9, + MBB_STATUS_PROVIDER_NOT_VISIBLE = 10, + MBB_STATUS_DATA_CLASS_NOT_AVAILABLE = 11, + MBB_STATUS_PACKET_SVC_DETACHED = 12, + MBB_STATUS_MAX_ACTIVATED_CONTEXTS = 13, + MBB_STATUS_NOT_INITIALIZED = 14, + MBB_STATUS_VOICE_CALL_IN_PROGRESS = 15, + MBB_STATUS_CONTEXT_NOT_ACTIVATED = 16, + MBB_STATUS_SERVICE_NOT_ACTIVATED = 17, + MBB_STATUS_INVALID_ACCESS_STRING = 18, + MBB_STATUS_INVALID_USER_NAME_PWD = 19, + MBB_STATUS_RADIO_POWER_OFF = 20, + MBB_STATUS_INVALID_PARAMETERS = 21, + MBB_STATUS_READ_FAILURE = 22, + MBB_STATUS_WRITE_FAILURE = 23, + MBB_STATUS_DENIED_POLICY = 24, + MBB_STATUS_NO_PHONEBOOK = 25, + MBB_STATUS_PARAMETER_TOO_LONG = 26, + MBB_STATUS_STK_BUSY = 27, + MBB_STATUS_OPERATION_NOT_ALLOWED = 28, + MBB_STATUS_MEMORY_FAILURE = 29, + MBB_STATUS_INVALID_MEMORY_INDEX = 30, + MBB_STATUS_MEMORY_FULL = 31, + MBB_STATUS_FILTER_NOT_SUPPORTED = 32, + MBB_STATUS_DSS_INSTANCE_LIMIT = 33, + MBB_STATUS_INVALID_DEVICE_SERVICE_OPERATION = 34, + MBB_STATUS_AUTH_INCORRECT_AUTN = 35, + MBB_STATUS_AUTH_SYNC_FAILURE = 36, + MBB_STATUS_AUTH_AMF_NOT_SET = 37, + MBB_STATUS_CONTEXT_NOT_SUPPORTED = 38, + MBB_STATUS_SHAREABILITY_CONDITION_ERROR = 39, + MBB_STATUS_PIN_FAILURE = 40, + MBB_STATUS_NO_LTE_ATTACH_CONFIG = 41, + MBB_STATUS_SESSION_ALREADY_EXISTS = 42, + MBB_STATUS_BASIC_END = (MBB_STATUS_SESSION_ALREADY_EXISTS + 1), + MBB_STATUS_SMS_UNKNOWN_SMSC_ADDRESS = 100, + MBB_STATUS_SMS_START = 100, + MBB_STATUS_SMS_NETWORK_TIMEOUT = 101, + MBB_STATUS_SMS_LANG_NOT_SUPPORTED = 102, + MBB_STATUS_SMS_ENCODING_NOT_SUPPORTED = 103, + MBB_STATUS_SMS_FORMAT_NOT_SUPPORTED = 104, + MBB_STATUS_SMS_MORE_DATA = 105, + MBB_STATUS_SMS_END = (MBB_STATUS_SMS_MORE_DATA + 1), + MBB_STATUS_4_0_START = 200, + MBB_STATUS_MATCHING_PDU_SESSION_FOUND = MBB_STATUS_4_0_START, + MBB_STATUS_DESSOCIATION_NEEDED_FOR_APPLICATION = 201, + MBB_STATUS_ERROR_INVALID_SLOT = 202, + MBB_STATUS_NO_MATCHING_URSP_RULE = 203, + MBB_STATUS_NO_DEFAULT_URSP_RULE = 204, + MBB_STATUS_4_0_END = (MBB_STATUS_NO_DEFAULT_URSP_RULE + 1), + MBB_STATUS_UICC_NO_LOGICAL_CHANNELS = 0x87430001, + MBB_STATUS_UICC_START = 0x87430001, + MBB_STATUS_UICC_SELECT_FAILED = 0x87430002, + MBB_STATUS_UICC_INVALID_LOGICAL_CHANNEL = 0x87430003, + MBB_STATUS_UICC_END = (MBB_STATUS_UICC_INVALID_LOGICAL_CHANNEL + 1) +} MBB_STATUS; + +typedef enum _MBB_ERROR +{ + MBB_ERROR_NONE = 0, + MBB_ERROR_TIMEOUT_FRAGMENT = 1, + MBB_ERROR_FRAGMENT_OUT_OF_SEQUENCE = 2, + MBB_ERROR_LENGTH_MISMATCH = 3, + MBB_ERROR_DUPLICATE_TID = 4, + MBB_ERROR_NOT_OPENED = 5, + MBB_ERROR_UNKNOWN = 6, + MBB_ERROR_CANCEL = 7, + MBB_ERROR_MAX_TRANSFER = 8 +} MBB_ERROR; + +typedef enum _MBB_MESSAGE_TYPE +{ + MBB_MESSAGE_TYPE_NONE = 0, + MBB_MESSAGE_TYPE_OPEN = 0x1, + MBB_MESSAGE_TYPE_CLOSE = 0x2, + MBB_MESSAGE_TYPE_COMMAND = 0x3, + MBB_MESSAGE_TYPE_HOST_ERROR = 0x4, + MBB_MESSAGE_TYPE_OPEN_DONE = 0x80000001, + MBB_MESSAGE_TYPE_CLOSE_DONE = 0x80000002, + MBB_MESSAGE_TYPE_COMMAND_DONE = 0x80000003, + MBB_MESSAGE_TYPE_FUNCTION_ERROR = 0x80000004, + MBB_MESSAGE_TYPE_INDICATE_STATUS = 0x80000007 +} MBB_MESSAGE_TYPE; + +typedef enum _MBB_COMMAND_TYPE +{ + MBB_COMMAND_TYPE_QUERY = 0, + MBB_COMMAND_TYPE_SET = 1 +} MBB_COMMAND_TYPE; + +typedef struct _MBB_MESSAGE_HEADER +{ + MBB_MESSAGE_TYPE MessageType; + ULONG MessageLength; + ULONG MessageTransactionId; +} MBB_MESSAGE_HEADER; + +typedef struct _MBB_MESSAGE_HEADER* PMBB_MESSAGE_HEADER; + +typedef struct _MBB_FRAGMENT_HEADER +{ + ULONG TotalFragments; + ULONG CurrentFragment; +} MBB_FRAGMENT_HEADER; + +typedef struct _MBB_FRAGMENT_HEADER* PMBB_FRAGMENT_HEADER; + +typedef struct _MBB_COMMAND +{ + GUID ServiceId; + ULONG CommandId; +} MBB_COMMAND; + +typedef struct _MBB_COMMAND* PMBB_COMMAND; + +typedef struct _MBB_COMMAND_HEADER +{ + MBB_MESSAGE_HEADER MessageHeader; + MBB_FRAGMENT_HEADER FragmentHeader; + MBB_COMMAND Command; + MBB_COMMAND_TYPE CommandType; + ULONG InformationBufferLength; +} MBB_COMMAND_HEADER; + +typedef struct _MBB_COMMAND_HEADER* PMBB_COMMAND_HEADER; + +typedef struct _MBB_COMMAND_FRAGMENT_HEADER +{ + MBB_MESSAGE_HEADER MessageHeader; + MBB_FRAGMENT_HEADER FragmentHeader; +} MBB_COMMAND_FRAGMENT_HEADER; + +typedef struct _MBB_COMMAND_FRAGMENT_HEADER* PMBB_COMMAND_FRAGMENT_HEADER; + +typedef struct _MBB_COMMAND_DONE_HEADER +{ + MBB_MESSAGE_HEADER MessageHeader; + MBB_FRAGMENT_HEADER FragmentHeader; + MBB_COMMAND Command; + MBB_STATUS MbbStatus; + ULONG InformationBufferLength; +} MBB_COMMAND_DONE_HEADER; + +typedef struct _MBB_COMMAND_DONE_HEADER* PMBB_COMMAND_DONE_HEADER; + +typedef struct _MBB_INDICATE_STATUS_HEADER +{ + MBB_MESSAGE_HEADER MessageHeader; + MBB_FRAGMENT_HEADER FragmentHeader; + MBB_COMMAND Command; + ULONG InformationBufferLength; +} MBB_INDICATE_STATUS_HEADER; + +typedef struct _MBB_INDICATE_STATUS_HEADER* PMBB_INDICATE_STATUS_HEADER; + +typedef struct _MBB_OPEN_MESSAGE +{ + MBB_MESSAGE_HEADER MessageHeader; + ULONG MaximumControlTransfer; +} MBB_OPEN_MESSAGE; + +typedef struct _MBB_OPEN_MESSAGE* PMBB_OPEN_MESSAGE; + +typedef struct _MBB_OPEN_MESSAGE_FASTIO +{ + MBB_MESSAGE_HEADER MessageHeader; + ULONG MaximumControlTransfer; + PVOID AdapterContext; + PVOID SendNetBufferListsCompleteHandler; + PVOID ReceiveNetBufferListsHandler; +} MBB_OPEN_MESSAGE_FASTIO; + +typedef struct _MBB_OPEN_MESSAGE_FASTIO* PMBB_OPEN_MESSAGE_FASTIO; + +typedef struct _MBB_CLOSE_MESSAGE +{ + MBB_MESSAGE_HEADER MessageHeader; +} MBB_CLOSE_MESSAGE; + +typedef struct _MBB_CLOSE_MESSAGE* PMBB_CLOSE_MESSAGE; + +typedef struct _MBB_OPEN_DONE +{ + MBB_MESSAGE_HEADER MessageHeader; + MBB_STATUS MbbStatus; +} MBB_OPEN_DONE; + +typedef struct _MBB_OPEN_DONE* PMBB_OPEN_DONE; + +typedef struct _MBB_OPEN_DONE_FASTIO +{ + MBB_MESSAGE_HEADER MessageHeader; + MBB_STATUS MbbStatus; + PVOID ModemContext; + PVOID SendNetBufferListsHandler; + PVOID ReturnNetBufferListsHandler; + PVOID CancelSendHandler; + PVOID HaltHandler; + PVOID PauseHandler; + PVOID ShutdownHandler; + PVOID ResetHandler; + PVOID RestartHandler; +} MBB_OPEN_DONE_FASTIO; + +typedef struct _MBB_OPEN_DONE_FASTIO* PMBB_OPEN_DONE_FASTIO; + +typedef struct _MBB_CLOSE_DONE +{ + MBB_MESSAGE_HEADER MessageHeader; + MBB_STATUS MbbStatus; +} MBB_CLOSE_DONE; + +typedef struct _MBB_CLOSE_DONE* PMBB_CLOSE_DONE; + +typedef struct _MBB_ERROR_MESSAGE +{ + MBB_MESSAGE_HEADER MessageHeader; + MBB_ERROR ErrorCode; +} MBB_ERROR_MESSAGE; + +typedef struct _MBB_ERROR_MESSAGE* PMBB_ERROR_MESSAGE; + +typedef enum _MBB_BASIC_CID +{ + MBB_BASIC_CID_DEVICE_CAPS = 1, + MBB_BASIC_CID_SUBSCRIBER_READY_INFO = 2, + MBB_BASIC_CID_RADIO_STATE = 3, + MBB_BASIC_CID_PIN_INFO = 4, + MBB_BASIC_CID_PIN_LIST = 5, + MBB_BASIC_CID_HOME_PROVIDER = 6, + MBB_BASIC_CID_PREFERRED_PROVIDERS = 7, + MBB_BASIC_CID_VISIBLE_PROVIDERS = 8, + MBB_BASIC_CID_REGISTER_STATE = 9, + MBB_BASIC_CID_PACKET_SERVICE = 10, + MBB_BASIC_CID_SIGNAL_STATE = 11, + MBB_BASIC_CID_CONNECT = 12, + MBB_BASIC_CID_PROVISIONED_CONTEXTS = 13, + MBB_BASIC_CID_SERVICE_ACTIVATION = 14, + MBB_BASIC_CID_IP_ADDRESS_INFO = 15, + MBB_BASIC_CID_DEVICE_SERVICES = 16, + MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES = 19, + MBB_BASIC_CID_PACKET_STATISTICS = 20, + MBB_BASIC_CID_NETWORK_IDLE_HINT = 21, + MBB_BASIC_CID_EMERGENCY_MODE = 22, + MBB_BASIC_CID_PACKET_FILTERS = 23, + MBB_BASIC_CID_MULTICARRIER_PROVIDERS = 24, + MBB_BASIC_CID_MAXIMUM = (MBB_BASIC_CID_MULTICARRIER_PROVIDERS + 1) +} MBB_BASIC_CID; + +typedef enum _MBB_SMS_CID +{ + MBB_SMS_CID_CONFIGURATION = 1, + MBB_SMS_CID_READ = 2, + MBB_SMS_CID_SEND = 3, + MBB_SMS_CID_DELETE = 4, + MBB_SMS_CID_STATUS = 5, + MBB_SMS_CID_MAXIMUM = (MBB_SMS_CID_STATUS + 1) +} MBB_SMS_CID; + +typedef enum _MBB_VENDOR_CID +{ + MBB_VENDOR_CID_MS_VENDOR_SPECIFIC = 1, + MBB_VENDOR_CID_MAXIMUM = (MBB_VENDOR_CID_MS_VENDOR_SPECIFIC + 1) +} MBB_VENDOR_CID; + +typedef enum _MBB_USSD_CID +{ + MBB_USSD_CID_USSD = 1, + MBB_USSD_CID_MAXIMUM = (MBB_USSD_CID_USSD + 1) +} MBB_USSD_CID; + +typedef enum _MBB_PHONEBOOK_CID +{ + MBB_PHONEBOOK_CID_CONFIGURATION = 1, + MBB_PHONEBOOK_CID_READ = 2, + MBB_PHONEBOOK_CID_DELETE = 3, + MBB_PHONEBOOK_CID_SAVE = 4, + MBB_PHONEBOOK_CID_MAXIMUM = (MBB_PHONEBOOK_CID_SAVE + 1) +} MBB_PHONEBOOK_CID; + +typedef enum _MBB_SAT_CID +{ + MBB_SAT_CID_PAC = 1, + MBB_SAT_CID_TERMINAL_RESPONSE = 2, + MBB_SAT_CID_ENVELOPE = 3, + MBB_SAT_CID_MAXIMUM = (MBB_SAT_CID_ENVELOPE + 1) +} MBB_SAT_CID; + +typedef enum _MBB_AUTH_CID +{ + MBB_AUTH_CID_AKA = 1, + MBB_AUTH_CID_AKAP = 2, + MBB_AUTH_CID_SIM = 3, + MBB_AUTH_CID_MAXIUM = (MBB_AUTH_CID_SIM + 1) +} MBB_AUTH_CID; + +typedef enum _MBB_DSS_CID +{ + MBB_DSS_CID_CONNECT = 1, + MBB_DSS_CID_MAXIUM = (MBB_DSS_CID_CONNECT + 1) +} MBB_DSS_CID; + +typedef enum _MBB_MULTICARRIER_CID +{ + MBB_MULTICARRIER_CID_CAPABILITIES = 1, + MBB_MULTICARRIER_CID_LOCATION_INFO = 2, + MBB_MULTICARRIER_CID_CURRENT_CID_LIST = 3, + MBB_MULTICARRIER_CID_MAXIMUM = (MBB_MULTICARRIER_CID_CURRENT_CID_LIST + 1) +} MBB_MULTICARRIER_CID; + +typedef enum _MBB_HOSTSHUTDOWN_CID +{ + MBB_HOSTSHUTDOWN_CID_ONE = 1, + MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN = 2, + MBB_HOSTSHUTDOWN_CID_MAX = (MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN + 1) +} MBB_HOSTSHUTDOWN_CID; + +typedef enum _MBB_VOICEEXTENSIONS_CID +{ + MBB_VOICEEXTENSIONS_CID_SYS_CAPS = 1, + MBB_VOICEEXTENSIONS_CID_DEVICE_CAPS_V2 = 2, + MBB_VOICEEXTENSIONS_CID_SYS_SLOTMAPPINGS = 3, + MBB_VOICEEXTENSIONS_CID_SLOT_INFO_STATUS = 4, + MBB_VOICEEXTENSIONS_CID_DEVICE_BINDINGS = 5, + MBB_VOICEEXTENSIONS_CID_REGISTER_STATE_V2 = 6, + MBB_VOICEEXTENSIONS_CID_IMS_VOICE_STATE = 7, + MBB_VOICEEXTENSIONS_CID_SIGNAL_STATE_V2 = 8, + MBB_VOICEEXTENSIONS_CID_LOCATION_STATE = 9, + MBB_VOICEEXTENSIONS_CID_NITZ = 10, + MBB_VOICEEXTENSIONS_CID_MAX = (MBB_VOICEEXTENSIONS_CID_NITZ + 1) +} MBB_VOICEEXTENSIONS_CID; + +typedef enum _MBB_UICC_CID +{ + MBB_UICC_CID_ATR = 1, + MBB_UICC_CID_OPEN_CHANNEL = 2, + MBB_UICC_CID_CLOSE_CHANNEL = 3, + MBB_UICC_CID_APDU = 4, + MBB_UICC_CID_TERMINAL_CAPABILITY = 5, + MBB_UICC_CID_RESET = 6, + MBB_UICC_CID_APP_LIST = 7, + MBB_UICC_CID_FILE_STATUS = 8, + MBB_UICC_CID_ACCESS_BINARY = 9, + MBB_UICC_CID_ACCESS_RECORD = 10, + MBB_UICC_CID_MAXIMUM = (MBB_UICC_CID_ACCESS_RECORD + 1) +} MBB_UICC_CID; + +typedef enum _MBB_SAR_CID +{ + MBB_SAR_CID_CONFIG = 1, + MBB_SAR_CID_TRANSMISSION_STATUS = 2, + MBB_SAR_CID_MAXIMUM = (MBB_SAR_CID_TRANSMISSION_STATUS + 1) +} MBB_SAR_CID; + +typedef enum _MBB_BASICCONNECTEXT_CID +{ + MBB_BASICCONNECTEXT_CID_PROVISIONED_CONTEXT_V2 = 1, + MBB_BASICCONNECTEXT_CID_NETWORK_BLACKLIST = 2, + MBB_BASICCONNECTEXT_CID_LTE_ATTACH_CONFIG = 3, + MBB_BASICCONNECTEXT_CID_LTE_ATTACH_STATUS = 4, + MBB_BASICCONNECTEXT_CID_SYS_CAPS = 5, + MBB_BASICCONNECTEXT_CID_DEVICE_CAPS_V2 = 6, + MBB_BASICCONNECTEXT_CID_DEVICE_SLOT_MAPPINGS = 7, + MBB_BASICCONNECTEXT_CID_SLOT_INFO_STATUS = 8, + MBB_BASICCONNECTEXT_CID_PCO = 9, + MBB_BASICCONNECTEXT_CID_DEVICE_RESET = 10, + MBB_BASICCONNECTEXT_CID_BASE_STATIONS_INFO = 11, + MBB_BASICCONNECTEXT_CID_LOCATION_INFO_STATUS = 12, + MBB_BASICCONNECTEXT_CID_MODEM_LOGGING_CONFIG = 13, + MBB_BASICCONNECTEXT_CID_PIN_INFO_EX2 = 14, + MBB_BASICCONNECTEXT_CID_VERSION = 15, + MBB_BASICCONNECTEXT_CID_MODEM_CONFIG = 16, + MBB_BASICCONNECTEXT_CID_REGISTRATION_PARAMS = 17, + MBB_BASICCONNECTEXT_CID_NETWORK_PARAMS = 18, + MBB_BASICCONNECTEXT_CID_WAKE_REASON = 19, + MBB_BASICCONNECTEXT_CID_UE_POLICY = 20, + MBB_BASICCONNECTEXT_CID_MAXIMUM = (MBB_BASICCONNECTEXT_CID_WAKE_REASON + 1) +} MBB_BASICCONNECTEXT_CID; + +typedef enum _MBB_DEVICE_TYPE +{ + MbbDeviceTypeUnknown = 0, + MbbDeviceTypeEmbedded = 1, + MbbDeviceTypeRemovable = 2, + MbbDeviceTypeRemote = 3, + MbbDeviceTypeMaximum = (MbbDeviceTypeRemote + 1) +} MBB_DEVICE_TYPE; + +typedef enum _MBB_CELLULAR_CLASS +{ + MbbCellularClassInvalid = 0, + MbbCellularClassGsm = 1, + MbbCellularClassCdma = 2, + MbbCellularClassMaximum = (MbbCellularClassCdma + 1) +} MBB_CELLULAR_CLASS; + +typedef enum _MBB_VOICE_CLASS +{ + MbbVoiceClassInvalid = 0, + MbbVoiceClassNoVoice = 1, + MbbVoiceClassSeparateVoiceData = 2, + MbbVoiceClassSimultaneousVoiceData = 3, + MbbVoiceClassMaximum = (MbbVoiceClassSimultaneousVoiceData + 1) +} MBB_VOICE_CLASS; + +typedef enum _MBB_SIM_CLASS +{ + MbbSimClassInvalid = 0, + MbbSimClassSimLogical = 1, + MbbSimClassSimRemovable = 2, + MbbSimClassMaximum = (MbbSimClassSimRemovable + 1) +} MBB_SIM_CLASS; + +typedef enum _MBB_DATA_CLASS_VALUE +{ + MbbDataClassNone = 0, + MbbDataClassGprs = 0x1, + MbbDataClassEdge = 0x2, + MbbDataClassUmts = 0x4, + MbbDataClassHsdpa = 0x8, + MbbDataClassHsupa = 0x10, + MbbDataClassLte = 0x20, + MbbDataClass5G = 0x40, + MbbDataClass_UNUSED = 0x80, + MbbDataClassTdScdma = 0x1000, + MbbDataClass1xRtt = 0x10000, + MbbDataClass1xEvdo = 0x20000, + MbbDataClass1xEvdoReva = 0x40000, + MbbDataClass1xEvdv = 0x80000, + MbbDataClass3xRtt = 0x100000, + MbbDataClass1xEvdoRevb = 0x200000, + MbbDataClassUmb = 0x400000, + MbbDataClassCustom = 0x80000000 +} MBB_DATA_CLASS_VALUE; + +typedef enum _MBB_DATA_SUBCLASS_VALUE +{ + MbbDataSubClassNone = 0, + MbbDataSubClass5GENDC = 0x1, + MbbDataSubClass5GNR = 0x2, + MbbDataSubClass5GNEDC = 0x4, + MbbDataSubClass5GELTE = 0x8, + MbbDataSubClassNGENDC = 0x10 +} MBB_DATA_SUBCLASS_VALUE; + +typedef enum _MBB_FREQUENCY_RANGE +{ + MbbFrequencyRangeUnknown = 0, + MbbFrequencyRange1 = 1, + MbbFrequencyRange2 = 2, + MbbFrequencyRange1AndRange2 = 3, + MbbFrequencyRangeMaximum = (MbbFrequencyRange1AndRange2 + 1) +} MBB_FREQUENCY_RANGE; + +typedef enum _MBB_BAND_CLASS_VALUE +{ + MbbBandClassUnknown = 0, + MbbBandClass0 = 0x1, + MbbBandClassI = 0x2, + MbbBandClassII = 0x4, + MbbBandClassIII = 0x8, + MbbBandClassIV = 0x10, + MbbBandClassV = 0x20, + MbbBandClassVI = 0x40, + MbbBandClassVII = 0x80, + MbbBandClassVIII = 0x100, + MbbBandClassIX = 0x200, + MbbBandClassX = 0x400, + MbbBandClassXI = 0x800, + MbbBandClassXII = 0x1000, + MbbBandClassXIII = 0x2000, + MbbBandClassXIV = 0x4000, + MbbBandClassXV = 0x8000, + MbbBandClassXVI = 0x10000, + MbbBandClassXVII = 0x20000, + MbbBandClassCustom = 0x80000000 +} MBB_BAND_CLASS_VALUE; + +typedef enum _MBB_SMS_CAPS_VALUE +{ + MbbSmsCapsNone = 0, + MbbSmsCapsPduReceive = 0x1, + MbbSmsCapsPduSend = 0x2, + MbbSmsCapsTextReceive = 0x4, + MbbSmsCapsTextSend = 0x8 +} MBB_SMS_CAPS_VALUE; + +typedef enum _MBB_CONTROL_CAPS_VALUE +{ + MbbControlCapsNone = 0, + MbbControlCapsRegManual = 0x1, + MbbControlCapsHwRadioSwitch = 0x2, + MbbControlCapsCdmaMobileIp = 0x4, + MbbControlCapsCdmaSimpleIp = 0x8, + MbbControlCapsMultiCarrier = 0x10, + MbbControlCapsESIM = 0x20, + MbbControlCapsUEPolicyRouteSelection = 0x40, + MbbControlCapsSIMHotSwapCapable = 0x80 +} MBB_CONTROL_CAPS_VALUE; + +typedef enum _MBB_READY_STATE +{ + MbbReadyStateOff = 0, + MbbReadyStateInitialized = 1, + MbbReadyStateSimNotInserted = 2, + MbbReadyStateBadSim = 3, + MbbReadyStateFailure = 4, + MbbReadyStateNotActivated = 5, + MbbReadyStateDeviceLocked = 6, + MbbReadyStateNoEsimProfile = 7, + MbbReadyStateMaximum = (MbbReadyStateNoEsimProfile + 1) +} MBB_READY_STATE; + +typedef enum _MBB_READY_INFO_FLAGS +{ + MbbReadyInfoFlagsNone = 0, + MbbReadyInfoFlagsUniqueId = 1 +} MBB_READY_INFO_FLAGS; + +typedef enum _MBB_EMERGENCY_MODE +{ + MbbEmergencyModeOff = 0, + MbbEmergencyModeOn = 1, + MbbEmergencyModeMaximum = (MbbEmergencyModeOn + 1) +} MBB_EMERGENCY_MODE; + +typedef enum _MBB_RADIO_STATE +{ + MbbRadioStateOff = 0, + MbbRadioStateOn = 1, + MbbRadioStateMaximum = (MbbRadioStateOn + 1) +} MBB_RADIO_STATE; + +typedef enum _MBB_PIN_TYPE +{ + MbbPinTypeNone = 0, + MbbPinTypeCustom = 1, + MbbPinTypePin1 = 2, + MbbPinTypePin2 = 3, + MbbPinTypeDeviceSimPin = 4, + MbbPinTypeDeviceFirstSimPin = 5, + MbbPinTypeNetworkPin = 6, + MbbPinTypeNetworkSubsetPin = 7, + MbbPinTypeSvcProviderPin = 8, + MbbPinTypeCorporatePin = 9, + MbbPinTypeSubsidyLock = 10, + MbbPinTypePuk1 = 11, + MbbPinTypePuk2 = 12, + MbbPinTypeDeviceFirstSimPuk = 13, + MbbPinTypeNetworkPuk = 14, + MbbPinTypeNetworkSubsetPuk = 15, + MbbPinTypeSvcProviderPuk = 16, + MbbPinTypeCorporatePuk = 17, + MbbPinTypeNev = 18, + MbbPinTypeAdm = 19, + MbbPinTypeMaximum = (MbbPinTypeAdm + 1) +} MBB_PIN_TYPE; + +typedef enum _MBB_PIN_STATE +{ + MbbPinStateUnlocked = 0, + MbbPinStateLocked = 1, + MbbPinStateMaximum = (MbbPinStateLocked + 1) +} MBB_PIN_STATE; + +typedef enum _MBB_PIN_OPERATION +{ + MbbPinOperationEnter = 0, + MbbPinOperationEnable = 1, + MbbPinOperationDisable = 2, + MbbPinOperationChange = 3, + MbbPinOperationMaximum = (MbbPinOperationChange + 1) +} MBB_PIN_OPERATION; + +typedef enum _MBB_PIN_MODE +{ + MbbPinModeNotSupported = 0, + MbbPinModeEnabled = 1, + MbbPinModeDisabled = 2, + MbbPinModeMaximum = (MbbPinModeDisabled + 1) +} MBB_PIN_MODE; + +typedef enum _MBB_PIN_FORMAT +{ + MbbPinFormatUnknown = 0, + MbbPinFormatNumeric = 1, + MbbPinFormatAlphaNumeric = 2, + MbbPinFormatMaximum = (MbbPinFormatAlphaNumeric + 1) +} MBB_PIN_FORMAT; + +typedef enum _MBB_PROVIDER_STATE_VALUE +{ + MbbProviderStateHome = 0x1, + MbbProviderStateForbidden = 0x2, + MbbProviderStatePreferred = 0x4, + MbbProviderStateVisible = 0x8, + MbbProviderStateRegistered = 0x10, + MbbProviderStatePreferredMulticarrier = 0x20 +} MBB_PROVIDER_STATE_VALUE; + +typedef enum _MBB_REGISTER_ACTION +{ + MbbRegisterActionAutomatic = 0, + MbbRegisterActionManual = 1, + MbbRegisterActionMaximum = (MbbRegisterActionManual + 1) +} MBB_REGISTER_ACTION; + +typedef enum _MBB_REGISTER_STATE +{ + MbbRegisterStateUnknown = 0, + MbbRegisterStateDeregistered = 1, + MbbRegisterStateSearching = 2, + MbbRegisterStateHome = 3, + MbbRegisterStateRoaming = 4, + MbbRegisterStatePartner = 5, + MbbRegisterStateDenied = 6, + MbbRegisterStateMaximum = (MbbRegisterStateDenied + 1) +} MBB_REGISTER_STATE; + +typedef enum _MBB_REGISTER_MODE +{ + MbbRegisterModeUnknown = 0, + MbbRegisterModeAutomatic = 1, + MbbRegisterModeManual = 2, + MbbRegisterModeMaximum = (MbbRegisterModeManual + 1) +} MBB_REGISTER_MODE; + +typedef enum _MBB_PACKET_SERVICE_ACTION +{ + MbbPacketServiceActionAttach = 0, + MbbPacketServiceActionDetach = 1, + MbbPacketServiceActionMaximum = (MbbPacketServiceActionDetach + 1) +} MBB_PACKET_SERVICE_ACTION; + +typedef enum _MBB_PACKET_SERVICE_STATE +{ + MbbPacketServiceStateUnknown = 0, + MbbPacketServiceStateAttaching = 1, + MbbPacketServiceStateAttached = 2, + MbbPacketServiceStateDetaching = 3, + MbbPacketServiceStateDetached = 4, + MbbPacketServiceStateMaximum = (MbbPacketServiceStateDetached + 1) +} MBB_PACKET_SERVICE_STATE; + +typedef enum _MBB_CONTEXT_IP_TYPE +{ + MbbContextIPTypeDefault = 0, + MbbContextIPTypeIPv4 = 1, + MbbContextIPTypeIPv6 = 2, + MbbContextIPTypeIPv4v6 = 3, + MbbContextIPTypeIPv4AndIPv6 = 4, + MbbContextIPTypeMaximum = (MbbContextIPTypeIPv4AndIPv6 + 1) +} MBB_CONTEXT_IP_TYPE; + +typedef enum _MBB_ACTIVATION_COMMAND +{ + MbbActivationCommandDeactivate = 0, + MbbActivationCommandActivate = 1, + MbbActivationCommandCancel = 2, + MbbActivationCommandMaximum = (MbbActivationCommandCancel + 1) +} MBB_ACTIVATION_COMMAND; + +typedef enum _MBB_COMPRESSION +{ + MbbCompressionNone = 0, + MbbCompressionEnable = 1, + MbbCompressionMaximum = (MbbCompressionEnable + 1) +} MBB_COMPRESSION; + +typedef enum _MBB_AUTH_PROTOCOL +{ + MbbAuthProtocolNone = 0, + MbbAuthProtocolPap = 1, + MbbAuthProtocolChap = 2, + MbbAuthProtocolMsChapV2 = 3, + MbbAuthProtocolMaximum = (MbbAuthProtocolMsChapV2 + 1) +} MBB_AUTH_PROTOCOL; + +typedef enum _MBB_ACTIVATION_STATE +{ + MbbActivationStateUnknown = 0, + MbbActivationStateActivated = 1, + MbbActivationStateActivating = 2, + MbbActivationStateDeactivated = 3, + MbbActivationStateDeactivating = 4, + MbbActivationStateMaximum = (MbbActivationStateDeactivating + 1) +} MBB_ACTIVATION_STATE; + +typedef enum _MBB_VOICE_CALL_STATE +{ + MbbVoiceCallStateNone = 0, + MbbVoiceCallStateInProgress = 1, + MbbVoiceCallStateHangUp = 2, + MbbVoiceCallStateMaximum = (MbbVoiceCallStateHangUp + 1) +} MBB_VOICE_CALL_STATE; + +typedef enum _MBB_SMS_FORMAT +{ + MbbSmsFormatPdu = 0, + MbbSmsFormatCdma = 1, + MbbSmsFormatMaximum = (MbbSmsFormatCdma + 1) +} MBB_SMS_FORMAT; + +typedef enum _MBB_SMS_FLAG +{ + MbbSmsFlagAll = 0, + MbbSmsFlagIndex = 1, + MbbSmsFlagNew = 2, + MbbSmsFlagOld = 3, + MbbSmsFlagSent = 4, + MbbSmsFlagDraft = 5, + MbbSmsFlagMaximum = (MbbSmsFlagDraft + 1) +} MBB_SMS_FLAG; + +typedef enum _MBB_SMS_CDMA_LANGUAGE +{ + MbbSmsCdmaLanguageUnknown = 0, + MbbSmsCdmaLanguageEnglish = 1, + MbbSmsCdmaLanguageFrench = 2, + MbbSmsCdmaLanguageSpanish = 3, + MbbSmsCdmaLanguageJapanese = 4, + MbbSmsCdmaLanguageKorean = 5, + MbbSmsCdmaLanguageChinese = 6, + MbbSmsCdmaLanguageHebrew = 7, + MbbSmsCdmaLanguageMaximum = (MbbSmsCdmaLanguageHebrew + 1) +} MBB_SMS_CDMA_LANGUAGE; + +typedef enum _MBB_SMS_CDMA_ENCODING +{ + MbbSmsCdmaEncodingOctet = 0, + MbbSmsCdmaEncodingEpm = 1, + MbbSmsCdmaEncoding7BitAscii = 2, + MbbSmsCdmaEncodingIa5 = 3, + MbbSmsCdmaEncodingUnicode = 4, + MbbSmsCdmaEncodingShiftJis = 5, + MbbSmsCdmaEncodingKorean = 6, + MbbSmsCdmaEncodingLatinHebrew = 7, + MbbSmsCdmaEncodingLatin = 8, + MbbSmsCdmaEncodingGsm7Bit = 9, + MbbSmsCdmaEncodingMaximum = (MbbSmsCdmaEncodingGsm7Bit + 1) +} MBB_SMS_CDMA_ENCODING; + +typedef enum _MBB_SMS_MESSAGE_STATUS +{ + MbbSmsMessageStatusNew = 0, + MbbSmsMessageStatusOld = 1, + MbbSmsMessageStatusDraft = 2, + MbbSmsMessageStatusSent = 3, + MbbSmsMessageStatusMaximum = (MbbSmsMessageStatusSent + 1) +} MBB_SMS_MESSAGE_STATUS; + +typedef enum _MBB_REG_FLAGS_VALUE +{ + MbbRegFlagsNone = 0, + MbbRegFlagsNoManualReg = 0x1, + MbbRegFlagsPSAutoAttach = 0x2 +} MBB_REG_FLAGS_VALUE; + +typedef enum _MBB_SMS_STATUS_FLAGS_VALUE +{ + MbbSmsFlagNone = 0, + MbbSmsFlagMessageStoreFull = 1, + MbbSmsFlagNewMessage = 2 +} MBB_SMS_STATUS_FLAGS_VALUE; + +typedef struct _MBB_STRING +{ + ULONG Offset; + ULONG Size; +} MBB_STRING; + +typedef struct _MBB_STRING* PMBB_STRING; + +typedef struct _MBB_ARRAY_ELEMENT +{ + ULONG Offset; + ULONG Size; +} MBB_ARRAY_ELEMENT; + +typedef struct _MBB_ARRAY_ELEMENT* PMBB_ARRAY_ELEMENT; + +typedef struct _MBB_ARRAY_ELEMENT2 +{ + ULONG Size; + ULONG Offset; +} MBB_ARRAY_ELEMENT2; + +typedef struct _MBB_ARRAY_ELEMENT2* PMBB_ARRAY_ELEMENT2; + +typedef enum _MBB_DSS_PAYLOAD_SUPPORT +{ + MbbDssPayloadNone = 0, + MbbDssPayloadHostToDevice = 0x1, + MbbDssPayloadDeviceToHost = 0x2 +} MBB_DSS_PAYLOAD_SUPPORT; + +typedef enum _MBB_DSS_LINK_STATE +{ + MbbDssLinkDeactivate = 0, + MbbDssLinkActivate = 0x1 +} MBB_DSS_LINK_STATE; + +typedef enum _MBB_IP_CONFIGURATION_FLAGS_VALUE +{ + MbbIpFlagsNone = 0, + MbbIpFlagsAddressAvailable = 0x1, + MbbIpFlagsGatewayAvailable = 0x2, + MbbIpFlagsDnsServerAvailable = 0x4, + MbbIpFlagsMTUAvailable = 0x8 +} MBB_IP_CONFIGURATION_FLAGS_VALUE; + +typedef enum _MBB_NETWORK_IDLE_HINT_STATE +{ + MbbNetworkIdleHintDisabled = 0, + MbbNetworkIdleHintEnabled = 1 +} MBB_NETWORK_IDLE_HINT_STATE; + +typedef enum _MBB_SAR_BACKOFF_STATE +{ + MbbSarBackoffStatusDisabled = 0, + MbbSarBackoffStatusEnabled = 1, + MbbSarBackoffStatusMaximum = (MbbSarBackoffStatusEnabled + 1) +} MBB_SAR_BACKOFF_STATE; + +typedef enum _MBB_SAR_CONTROL_MODE +{ + MbbSarControlModeDevice = 0, + MbbSarControlModeOS = 1, + MbbSarControlModeMaximum = (MbbSarControlModeOS + 1) +} MBB_SAR_CONTROL_MODE; + +typedef enum _MBB_SAR_WIFI_HARDWARE_INTEGRATION +{ + MbbSarWifiHardwareNotIntegrated = 0, + MbbSarWifiHardwareIntegrated = 1, + MbbSarWifiHardwareIntegrationMaximum = (MbbSarWifiHardwareIntegrated + 1) +} MBB_SAR_WIFI_HARDWARE_INTEGRATION; + +typedef enum _MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE +{ + MbbTransmissionNotificationDisabled = 0, + MbbTransmissionNotificationEnabled = 1, + MbbTransmissionNotificationMaximum = (MbbTransmissionNotificationEnabled + 1) +} MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE; + +typedef enum _MBB_SAR_TRANSMISSION_STATUS +{ + MbbTransmissionStateInactive = 0, + MbbTransmissionStateActive = 1, + MbbTransmissionStateMaximum = (MbbTransmissionStateActive + 1) +} MBB_SAR_TRANSMISSION_STATUS; + +typedef enum _MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL +{ + MbbMsContextRoamingControlHomeOnly = 0, + MbbMsContextRoamingControlPartnerOnly = 1, + MbbMsContextRoamingControlNonPartnerOnly = 2, + MbbMsContextRoamingControlHomeAndPartner = 3, + MbbMsContextRoamingControlHomeAndNonPartner = 4, + MbbMsContextRoamingControlPartnerAndNonPartner = 5, + MbbMsContextRoamingControlAllowAll = 6, + MbbMsContextRoamingControlMaximum = (MbbMsContextRoamingControlAllowAll + 1) +} MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL; + +typedef enum _MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE +{ + MbbMsContextMediaTypeCellularOnly = 0, + MbbMsContextMediaTypeWifiOnly = 1, + MbbMsContextMediaTypeAll = 2, + MbbMsContextMediaTypeMaximum = (MbbMsContextMediaTypeAll + 1) +} MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE; + +typedef enum _MBB_BASICCONNECTEXT_CONTEXT_ENABLE +{ + MbbMsContextDisabled = 0, + MbbMsContextEnabled = 1, + MbbMsContextEnableMaximum = (MbbMsContextEnabled + 1) +} MBB_BASICCONNECTEXT_CONTEXT_ENABLE; + +typedef enum _MBB_BASICCONNECTEXT_CONTEXT_SOURCE +{ + MbbMsContextSourceAdmin = 0, + MbbMsContextSourceUser = 1, + MbbMsContextSourceOperator = 2, + MbbMsContextSourceModem = 3, + MbbMsContextSourceDevice = 4, + MbbMsContextSourceMaximum = (MbbMsContextSourceDevice + 1) +} MBB_BASICCONNECTEXT_CONTEXT_SOURCE; + +typedef enum _MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS +{ + MbbMsContextOperationDefault = 0, + MbbMsContextOperationDelete = 1, + MbbMsContextOperationRestoreFactory = 2, + MbbMsContextOperationMaximum = (MbbMsContextOperationRestoreFactory + 1) +} MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS; + +typedef enum _MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE +{ + MbbMsNetworkBlacklistStateNotActuated = 0, + MbbMsNetworkBlacklistSIMProviderActuated = 1, + MbbMsNetworkBlacklistNetworkProviderActuated = 2, + MbbMsNetworkBlacklistStateMaximum = (MbbMsNetworkBlacklistNetworkProviderActuated + 1) +} MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE; + +typedef enum _MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE +{ + MbbMsNetworkBlacklistTypeSIM = 0, + MbbMsNetworkBlacklistTypeNetwork = 1, + MbbMsNetworkBlacklistTypeMaximum = (MbbMsNetworkBlacklistTypeNetwork + 1) +} MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE; + +typedef enum _MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL +{ + MbbMsLteAttachContextRoamingControlHome = 0, + MbbMsLteAttachContextRoamingControlPartner = 1, + MbbMsLteAttachContextRoamingControlNonPartner = 2, + MbbMsLteAttachContextRoamingControlMaximum = (MbbMsLteAttachContextRoamingControlNonPartner + 1) +} MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL; + +typedef enum _MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS +{ + MbbMsLteAttachContextOperationDefault = 0, + MbbMsLteAttachContextOperationRestoreFactory = 1, + MbbMsLteAttachContextOperationMaximum = (MbbMsLteAttachContextOperationRestoreFactory + 1) +} MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS; + +typedef enum _MBB_BASICCONNECTEXT_LTEATTACH_STATE +{ + MbbMsLteAttachStateDetached = 0, + MbbMsLteAttachStateAttached = 1, + MbbMsLteAttachStateMaximum = (MbbMsLteAttachStateAttached + 1) +} MBB_BASICCONNECTEXT_LTEATTACH_STATE; + +typedef enum _MBB_BASICCONNECTEXT_UICCSLOT_STATE +{ + MbbMsUiccSlotStateUnknown = 0, + MbbMsUiccSlotStateOffEmpty = 1, + MbbMsUiccSlotStateOff = 2, + MbbMsUiccSlotStateEmpty = 3, + MbbMsUiccSlotStateNotReady = 4, + MbbMsUiccSlotStateActive = 5, + MbbMsUiccSlotStateError = 6, + MbbMsUiccSlotStateActiveEsim = 7, + MbbMsUiccSlotStateActiveEsimNoProfiles = 8 +} MBB_BASICCONNECTEXT_UICCSLOT_STATE; + +typedef enum _MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG +{ + MbbMsModemLoggingLevelProd = 0, + MbbMsModemLoggingLevelLabVerbose = 1, + MbbMsModemLoggingLevelLabMedium = 2, + MbbMsModemLoggingLevelLabLow = 3, + MbbMsModemLoggingLevelOem = 4, + MbbMsModemLoggingLevelMaximum = (MbbMsModemLoggingLevelOem + 1) +} MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG; + +typedef enum _MBB_PCO_TYPE +{ + MbbPcoTypeComplete = 0, + MbbPcoTypePartial = 1, + MbbPcoTypeMaximum = (MbbPcoTypePartial + 1) +} MBB_PCO_TYPE; + +typedef struct _MBB_DEVICE_CAPS +{ + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + MBB_SIM_CLASS SimClass; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONG dwMaxSessions; + MBB_STRING CustomDataClass; + MBB_STRING DeviceIdString; + MBB_STRING FirmwareInfo; + MBB_STRING HardwareInfo; + UCHAR DataBuffer[1]; +} MBB_DEVICE_CAPS; + +typedef struct _MBB_DEVICE_CAPS* PMBB_DEVICE_CAPS; + +typedef struct _MBB_SUBSCRIBER_READY_INFO +{ + MBB_READY_STATE ReadyState; + MBB_STRING SubscriberId; + MBB_STRING SimIccId; + MBB_READY_INFO_FLAGS ReadyInfoFlags; + ULONG TelephoneNumberCount; + MBB_STRING TelephoneNumbers[1]; +} MBB_SUBSCRIBER_READY_INFO; + +typedef struct _MBB_SUBSCRIBER_READY_INFO* PMBB_SUBSCRIBER_READY_INFO; + +typedef enum _MBB_SUBSCRIBER_READY_STATUS_FLAGS +{ + MbbSubscriberReadyStatusFlagNone = 0, + MbbSubscriberReadyStatusFlagESim = 0x1, + MbbSubscriberReadyStatusFlagSIMRemovabilityKnown = 0x2, + MbbSubscriberReadyStatusFlagSIMRemovable = 0x4 +} MBB_SUBSCRIBER_READY_STATUS_FLAGS; + +typedef struct _MBB_SUBSCRIBER_READY_INFO_EX3 +{ + MBB_READY_STATE ReadyState; + MBB_SUBSCRIBER_READY_STATUS_FLAGS StatusFlags; + MBB_STRING SubscriberId; + MBB_STRING SimIccId; + MBB_READY_INFO_FLAGS ReadyInfoFlags; + ULONG TelephoneNumberCount; + MBB_STRING TelephoneNumbers[1]; +} MBB_SUBSCRIBER_READY_INFO_EX3; + +typedef struct _MBB_SUBSCRIBER_READY_INFO_EX3* PMBB_SUBSCRIBER_READY_INFO_EX3; + +typedef struct _MBB_QUERY_RADIO_STATE +{ + MBB_RADIO_STATE HwRadioState; + MBB_RADIO_STATE SwRadioState; +} MBB_QUERY_RADIO_STATE; + +typedef struct _MBB_QUERY_RADIO_STATE* PMBB_QUERY_RADIO_STATE; + +typedef struct _MBB_PIN_INFO +{ + MBB_PIN_TYPE PinType; + MBB_PIN_STATE PinState; + ULONG AttemptsRemaining; +} MBB_PIN_INFO; + +typedef struct _MBB_PIN_INFO* PMBB_PIN_INFO; + +typedef struct _MBB_PIN_ACTION +{ + MBB_PIN_TYPE PinType; + MBB_PIN_OPERATION PinOperation; + MBB_STRING Pin; + MBB_STRING NewPin; + UCHAR DataBuffer[1]; +} MBB_PIN_ACTION; + +typedef struct _MBB_PIN_ACTION* PMBB_PIN_ACTION; + +typedef struct _MBB_PIN_DESCRIPTION +{ + MBB_PIN_MODE PinMode; + MBB_PIN_FORMAT PinFormat; + ULONG PinLengthMin; + ULONG PinLengthMax; +} MBB_PIN_DESCRIPTION; + +typedef struct _MBB_PIN_DESCRIPTION* PMBB_PIN_DESCRIPTION; + +typedef struct _MBB_PIN_LIST +{ + MBB_PIN_DESCRIPTION PinDescPin1; + MBB_PIN_DESCRIPTION PinDescPin2; + MBB_PIN_DESCRIPTION PinDescDeviceSimPin; + MBB_PIN_DESCRIPTION PinDescDeviceFirstSimPin; + MBB_PIN_DESCRIPTION PinDescNetworkPin; + MBB_PIN_DESCRIPTION PinDescNetworkSubsetPin; + MBB_PIN_DESCRIPTION PinDescSvcProviderPin; + MBB_PIN_DESCRIPTION PinDescCorporatePin; + MBB_PIN_DESCRIPTION PinDescSubsidyLock; + MBB_PIN_DESCRIPTION PinDescCustom; +} MBB_PIN_LIST; + +typedef struct _MBB_PIN_LIST* PMBB_PIN_LIST; + +typedef struct _MBB_PROVIDER +{ + MBB_STRING ProviderId; + ULONG ProviderState; + MBB_STRING ProviderName; + MBB_CELLULAR_CLASS CellularClass; + ULONG Rssi; + ULONG ErrorRate; +} MBB_PROVIDER; + +typedef struct _MBB_PROVIDER* PMBB_PROVIDER; + +typedef struct _MBB_PROVIDER_LIST +{ + ULONG ProviderCount; + MBB_ARRAY_ELEMENT Providers[1]; +} MBB_PROVIDER_LIST; + +typedef struct _MBB_PROVIDER_LIST* PMBB_PROVIDER_LIST; + +typedef struct _MBB_REGISTRATION_STATE +{ + ULONG NetworkError; + MBB_REGISTER_STATE RegisterState; + MBB_REGISTER_MODE RegisterMode; + ULONG AvailableDataClasses; + MBB_CELLULAR_CLASS CurrentCellularClass; + MBB_STRING ProviderId; + MBB_STRING ProviderName; + MBB_STRING RoamingText; + ULONG RegFlags; + UCHAR DataBuffer[1]; +} MBB_REGISTRATION_STATE; + +typedef struct _MBB_REGISTRATION_STATE* PMBB_REGISTRATION_STATE; + +typedef struct _MBB_SET_REGISTER_STATE +{ + MBB_STRING ProviderId; + MBB_REGISTER_ACTION RegisterAction; + ULONG DataClass; + UCHAR DataBuffer[1]; +} MBB_SET_REGISTER_STATE; + +typedef struct _MBB_SET_REGISTER_STATE* PMBB_SET_REGISTER_STATE; + +typedef struct _MBB_SET_PACKET_SERVICE +{ + MBB_PACKET_SERVICE_ACTION PacketServiceAction; +} MBB_SET_PACKET_SERVICE; + +typedef struct _MBB_SET_PACKET_SERVICE* PMBB_SET_PACKET_SERVICE; + +typedef struct _MBB_PACKET_SERVICE +{ + ULONG NetworkError; + MBB_PACKET_SERVICE_STATE PacketServiceState; + ULONG HighestAvailableDataClass; + ULONGLONG UplinkSpeed; + ULONGLONG DownlinkSpeed; +} MBB_PACKET_SERVICE; + +typedef struct _MBB_PACKET_SERVICE* PMBB_PACKET_SERVICE; + +typedef struct _MBB_PACKET_SERVICE_INFO_V2 +{ + ULONG NetworkError; + MBB_PACKET_SERVICE_STATE PacketServiceState; + MBB_DATA_CLASS_VALUE CurrentDataClass; + ULONGLONG UplinkSpeed; + ULONGLONG DownlinkSpeed; + MBB_FREQUENCY_RANGE FrequencyRange; +} MBB_PACKET_SERVICE_INFO_V2; + +typedef struct _MBB_PACKET_SERVICE_INFO_V2* PMBB_PACKET_SERVICE_INFO_V2; + +typedef struct _MBB_PLMN +{ + USHORT Mcc; + USHORT Mnc; +} MBB_PLMN; + +typedef struct _MBB_PLMN* PMBB_PLMN; + +typedef struct _MBB_TAI +{ + MBB_PLMN Plmn; + ULONG Tac; +} MBB_TAI; + +typedef struct _MBB_TAI* PMBB_TAI; + +typedef struct _MBB_PACKET_SERVICE_INFO_V3 +{ + ULONG NetworkError; + MBB_PACKET_SERVICE_STATE PacketServiceState; + MBB_DATA_CLASS_VALUE CurrentDataClass; + ULONGLONG UplinkSpeed; + ULONGLONG DownlinkSpeed; + MBB_FREQUENCY_RANGE FrequencyRange; + MBB_DATA_SUBCLASS_VALUE CurrentDataSubClass; + MBB_TAI TrackingAreaId; +} MBB_PACKET_SERVICE_INFO_V3; + +typedef struct _MBB_PACKET_SERVICE_INFO_V3* PMBB_PACKET_SERVICE_INFO_V3; + +typedef struct _MBB_SET_SIGNAL_INDICATION +{ + ULONG RssiInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; +} MBB_SET_SIGNAL_INDICATION; + +typedef struct _MBB_SET_SIGNAL_INDICATION* PMBB_SET_SIGNAL_INDICATION; + +typedef struct _MBB_SIGNAL_STATE +{ + ULONG Rssi; + ULONG ErrorRate; + ULONG RssiInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; +} MBB_SIGNAL_STATE; + +typedef struct _MBB_SIGNAL_STATE* PMBB_SIGNAL_STATE; + +typedef struct _MBB_SET_CONTEXT_STATE +{ + ULONG SessionId; + MBB_ACTIVATION_COMMAND ActivationCommand; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + MBB_CONTEXT_IP_TYPE IPType; + GUID ContextType; + CHAR DataBuffer[1]; +} MBB_SET_CONTEXT_STATE; + +typedef struct _MBB_SET_CONTEXT_STATE* PMBB_SET_CONTEXT_STATE; + +typedef enum _MBB_ACCESS_MEDIA_PREF +{ + MbbAccessMediaPrefNone = 0, + MbbAccessMediaPref3GPP = 1, + MbbAccessMediaPref3GPPPreferred = 2, + MbbAccessMediaPrefMaximum = (MbbAccessMediaPref3GPPPreferred + 1) +} MBB_ACCESS_MEDIA_PREF; + +typedef struct _MBB_SET_CONTEXT_STATE_EX3 +{ + ULONG SessionId; + MBB_ACTIVATION_COMMAND ActivationCommand; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + MBB_CONTEXT_IP_TYPE IPType; + GUID ContextType; + MBB_ACCESS_MEDIA_PREF MediaPreference; +} MBB_SET_CONTEXT_STATE_EX3; + +typedef struct _MBB_SET_CONTEXT_STATE_EX3* PMBB_SET_CONTEXT_STATE_EX3; + +typedef struct _MBB_QUERY_CONTEXT_EX3 +{ + ULONG SessionId; +} MBB_QUERY_CONTEXT_EX3; + +typedef struct _MBB_QUERY_CONTEXT_EX3* PMBB_QUERY_CONTEXT_EX3; + +typedef struct _MBB_CONTEXT_STATE +{ + ULONG SessionId; + MBB_ACTIVATION_STATE ActivationState; + MBB_VOICE_CALL_STATE VoiceCallState; + MBB_CONTEXT_IP_TYPE IPType; + GUID ContextType; + ULONG NetworkError; +} MBB_CONTEXT_STATE; + +typedef struct _MBB_CONTEXT_STATE* PMBB_CONTEXT_STATE; + +typedef struct _MBB_CONTEXT_STATE_EX3 +{ + ULONG SessionId; + MBB_ACTIVATION_STATE ActivationState; + MBB_VOICE_CALL_STATE VoiceCallState; + MBB_CONTEXT_IP_TYPE IPType; + GUID ContextType; + ULONG NetworkError; + MBB_ACCESS_MEDIA_PREF MediaPreference; +} MBB_CONTEXT_STATE_EX3; + +typedef struct _MBB_CONTEXT_STATE_EX3* PMBB_CONTEXT_STATE_EX3; + +typedef struct _MBB_SET_CONTEXT +{ + ULONG ContextId; + GUID ContextType; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + MBB_STRING ProviderId; + UCHAR DataBuffer[1]; +} MBB_SET_CONTEXT; + +typedef struct _MBB_SET_CONTEXT* PMBB_SET_CONTEXT; + +typedef struct _MBB_CONTEXT +{ + ULONG ContextId; + GUID ContextType; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[1]; +} MBB_CONTEXT; + +typedef struct _MBB_CONTEXT* PMBB_CONTEXT; + +typedef struct _MBB_CONTEXT_LIST +{ + ULONG ContextCount; + MBB_ARRAY_ELEMENT Contexts[1]; +} MBB_CONTEXT_LIST; + +typedef struct _MBB_CONTEXT_LIST* PMBB_CONTEXT_LIST; + +typedef struct _MBB_SERVICE_ACTIVATION +{ + CHAR VendorSpecificBuffer[1]; +} MBB_SERVICE_ACTIVATION; + +typedef struct _MBB_SERVICE_ACTIVATION* PMBB_SERVICE_ACTIVATION; + +typedef struct _MBB_SERVICE_ACTIVATION_STATUS +{ + ULONG NetworkError; + CHAR VendorSpecificBuffer[1]; +} MBB_SERVICE_ACTIVATION_STATUS; + +typedef struct _MBB_SERVICE_ACTIVATION_STATUS* PMBB_SERVICE_ACTIVATION_STATUS; + +typedef struct _MBB_IPV4_ADDRESS +{ + ULONG OnLinkPrefixLength; + UCHAR IPV4Address[4]; +} MBB_IPV4_ADDRESS; + +typedef struct _MBB_IPV4_ADDRESS* PMBB_IPV4_ADDRESS; + +typedef struct _MBB_IPV6_ADDRESS +{ + ULONG OnLinkPrefixLength; + UCHAR IPV6Address[16]; +} MBB_IPV6_ADDRESS; + +typedef struct _MBB_IPV6_ADDRESS* PMBB_IPV6_ADDRESS; + +typedef struct _MBB_IP_ADDRESS_INFO +{ + ULONG SessionId; + ULONG IPv4Flags; + ULONG IPv6Flags; + ULONG IPv4AddressCount; + ULONG IPv4AddressOffset; + ULONG IPv6AddressCount; + ULONG IPv6AddressOffset; + ULONG IPv4GatewayOffset; + ULONG IPv6GatewayOffset; + ULONG IPv4DnsServerCount; + ULONG IPv4DnsServerOffset; + ULONG IPv6DnsServerCount; + ULONG IPv6DnsServerOffset; + ULONG IPv4MTU; + ULONG IPv6MTU; +} MBB_IP_ADDRESS_INFO; + +typedef struct _MBB_IP_ADDRESS_INFO* PMBB_IP_ADDRESS_INFO; + +typedef struct _MBB_PACKET_STATISTICS +{ + ULONG InDiscards; + ULONG InErrors; + ULONGLONG InOctets; + ULONGLONG InPackets; + ULONGLONG OutOctets; + ULONGLONG OutPackets; + ULONG OutErrors; + ULONG OutDiscards; +} MBB_PACKET_STATISTICS; + +typedef struct _MBB_PACKET_STATISTICS* PMBB_PACKET_STATISTICS; + +typedef enum _MBB_VISIBLE_PROVIDERS_ACTION_VALUE +{ + MbbVisibleProvidersActionFull = 0, + MbbVisibleProvidersActionMulticarrier = 0x1, + MbbVisibleProvidersActionMax = (MbbVisibleProvidersActionMulticarrier + 1) +} MBB_VISIBLE_PROVIDERS_ACTION_VALUE; + +typedef struct _MBB_GET_VISIBLE_PROVIDERS +{ + ULONG Action; +} MBB_GET_VISIBLE_PROVIDERS; + +typedef struct _MBB_GET_VISIBLE_PROVIDERS* PMBB_GET_VISIBLE_PROVIDERS; + +typedef enum _MBB_SMS_STORAGE_STATE +{ + MbbSmsStorageNotInitialized = 0, + MbbSmsStorageInitialized = 1 +} MBB_SMS_STORAGE_STATE; + +typedef struct _MBB_SET_SMS_CONFIGURATION +{ + MBB_SMS_FORMAT SmsFormat; + MBB_STRING ScAddress; + UCHAR DataBuffer[1]; +} MBB_SET_SMS_CONFIGURATION; + +typedef struct _MBB_SET_SMS_CONFIGURATION* PMBB_SET_SMS_CONFIGURATION; + +typedef struct _MBB_SMS_CONFIGURATION +{ + MBB_SMS_STORAGE_STATE SmsStorageState; + MBB_SMS_FORMAT SmsFormat; + ULONG MaxMessages; + ULONG CdmaShortMessageSize; + MBB_STRING ScAddress; + UCHAR DataBuffer[1]; +} MBB_SMS_CONFIGURATION; + +typedef struct _MBB_SMS_CONFIGURATION* PMBB_SMS_CONFIGURATION; + +typedef struct _MBB_SMS_READ +{ + MBB_SMS_FORMAT SmsFormat; + MBB_SMS_FLAG SmsFlag; + ULONG MessageIndex; +} MBB_SMS_READ; + +typedef struct _MBB_SMS_READ* PMBB_SMS_READ; + +typedef struct _MBB_SMS_CDMA_RECORD +{ + ULONG MessageIndex; + MBB_SMS_MESSAGE_STATUS MessageStatus; + MBB_STRING Address; + MBB_STRING TimeStamp; + MBB_SMS_CDMA_ENCODING EncodingId; + MBB_SMS_CDMA_LANGUAGE LanguageId; + MBB_ARRAY_ELEMENT EncodedMessage; + ULONG SizeInCharacters; + UCHAR DataBuffer[1]; +} MBB_SMS_CDMA_RECORD; + +typedef struct _MBB_SMS_CDMA_RECORD* PMBB_SMS_CDMA_RECORD; + +typedef struct _MBB_SMS_PDU_RECORD +{ + ULONG MessageIndex; + MBB_SMS_MESSAGE_STATUS MessageStatus; + MBB_ARRAY_ELEMENT PduData; + UCHAR DataBuffer[1]; +} MBB_SMS_PDU_RECORD; + +typedef struct _MBB_SMS_PDU_RECORD* PMBB_SMS_PDU_RECORD; + +typedef struct _MBB_SMS_RECEIVE +{ + MBB_SMS_FORMAT SmsFormat; + ULONG MessageCount; + MBB_ARRAY_ELEMENT MessageElement[1]; +} MBB_SMS_RECEIVE; + +typedef struct _MBB_SMS_RECEIVE* PMBB_SMS_RECEIVE; + +typedef struct _MBB_SMS_SEND_PDU +{ + MBB_ARRAY_ELEMENT PduData; + UCHAR DataBuffer[1]; +} MBB_SMS_SEND_PDU; + +typedef struct _MBB_SMS_SEND_PDU* PMBB_SMS_SEND_PDU; + +typedef struct _MBB_SMS_SEND_CDMA +{ + MBB_SMS_CDMA_ENCODING EncodingId; + MBB_SMS_CDMA_LANGUAGE LanguageId; + MBB_STRING Address; + MBB_ARRAY_ELEMENT EncodedMessage; + ULONG SizeInCharacters; + UCHAR DataBuffer[1]; +} MBB_SMS_SEND_CDMA; + +typedef struct _MBB_SMS_SEND_CDMA* PMBB_SMS_SEND_CDMA; + +typedef struct _MBB_SMS_SEND +{ + MBB_SMS_FORMAT SmsFormat; + /* [switch_is] */ /* [switch_type] */ union __MIDL___MIDL_itf_MbbMessages_0000_0000_0001 + { + /* [case()] */ MBB_SMS_SEND_PDU Pdu; + /* [case()] */ MBB_SMS_SEND_CDMA Cdma; + } u; +} MBB_SMS_SEND; + +typedef struct _MBB_SMS_SEND* PMBB_SMS_SEND; + +typedef struct _MBB_SMS_SEND_STATUS +{ + ULONG MessageReference; +} MBB_SMS_SEND_STATUS; + +typedef struct _MBB_SMS_SEND_STATUS* PMBB_SMS_SEND_STATUS; + +typedef struct _MBB_SMS_DELETE +{ + MBB_SMS_FLAG SmsFlags; + ULONG MessageIndex; +} MBB_SMS_DELETE; + +typedef struct _MBB_SMS_DELETE* PMBB_SMS_DELETE; + +typedef struct _MBB_SMS_STATUS +{ + ULONG StatusFlags; + ULONG MessageIndex; +} MBB_SMS_STATUS; + +typedef struct _MBB_SMS_STATUS* PMBB_SMS_STATUS; + +typedef enum _MBB_USSD_ACTION +{ + MbbUSSDInitiate = 0, + MbbUSSDContinue = 1, + MbbUSSDCancel = 2 +} MBB_USSD_ACTION; + +typedef enum _MBB_USSD_RESPONSE +{ + MbbUSSDNoActionRequired = 0, + MbbUSSDActionRequired = 1, + MbbUSSDTerminated = 2, + MbbUSSDOtherLocalClient = 3, + MbbUSSDOperationNotSupported = 4, + MbbUSSDNetworkTimeOut = 5 +} MBB_USSD_RESPONSE; + +typedef enum _MBB_USSD_SESSION_STATE +{ + MbbUSSDNewSession = 0, + MbbUSSDExistingSession = 1 +} MBB_USSD_SESSION_STATE; + +typedef struct _MBB_SET_USSD +{ + MBB_USSD_ACTION USSDAction; + ULONG USSDDataCodingScheme; + MBB_ARRAY_ELEMENT USSDPayload; + UCHAR DataBuffer[1]; +} MBB_SET_USSD; + +typedef struct _MBB_SET_USSD* PMBB_SET_USSD; + +typedef struct _MBB_USSD +{ + MBB_USSD_RESPONSE USSDResponse; + MBB_USSD_SESSION_STATE USSDSessionState; + ULONG USSDDataCodingScheme; + MBB_ARRAY_ELEMENT USSDPayload; + UCHAR DataBuffer[1]; +} MBB_USSD; + +typedef struct _MBB_USSD* PMBB_USSD; + +typedef struct _MBB_AKA_AUTH_CHALLENGE +{ + UCHAR Rand[16]; + UCHAR Autn[16]; +} MBB_AKA_AUTH_CHALLENGE; + +typedef struct _MBB_AKA_AUTH_CHALLENGE* PMBB_AKA_AUTH_CHALLENGE; + +typedef struct _MBB_AKA_AUTH_RESPONSE +{ + UCHAR Res[16]; + ULONG ResLength; + UCHAR IK[16]; + UCHAR CK[16]; + UCHAR Auts[14]; +} MBB_AKA_AUTH_RESPONSE; + +typedef struct _MBB_AKA_AUTH_RESPONSE* PMBB_AKA_AUTH_RESPONSE; + +typedef struct _MBB_AKAP_AUTH_CHALLENGE +{ + UCHAR Rand[16]; + UCHAR Autn[16]; + MBB_STRING NetworkName; + UCHAR DataBuffer[1]; +} MBB_AKAP_AUTH_CHALLENGE; + +typedef struct _MBB_AKAP_AUTH_CHALLENGE* PMBB_AKAP_AUTH_CHALLENGE; + +typedef struct _MBB_AKAP_AUTH_RESPONSE +{ + UCHAR Res[16]; + ULONG ResLength; + UCHAR IK[16]; + UCHAR CK[16]; + UCHAR Auts[14]; +} MBB_AKAP_AUTH_RESPONSE; + +typedef struct _MBB_AKAP_AUTH_RESPONSE* PMBB_AKAP_AUTH_RESPONSE; + +typedef struct _MBB_SIM_AUTH_CHALLENGE +{ + UCHAR Rand1[16]; + UCHAR Rand2[16]; + UCHAR Rand3[16]; + ULONG n; +} MBB_SIM_AUTH_CHALLENGE; + +typedef struct _MBB_SIM_AUTH_CHALLENGE* PMBB_SIM_AUTH_CHALLENGE; + +typedef struct _MBB_SIM_AUTH_RESPONSE +{ + UCHAR Sres1[4]; + UCHAR Kc1[8]; + UCHAR Sres2[4]; + UCHAR Kc2[8]; + UCHAR Sres3[4]; + UCHAR Kc3[8]; + ULONG n; +} MBB_SIM_AUTH_RESPONSE; + +typedef struct _MBB_SIM_AUTH_RESPONSE* PMBB_SIM_AUTH_RESPONSE; + +typedef struct _MBB_PACKET_FILTERS +{ + ULONG SessionId; + ULONG PacketFiltersCount; + MBB_ARRAY_ELEMENT ArrayElement[1]; +} MBB_PACKET_FILTERS; + +typedef struct _MBB_PACKET_FILTERS* PMBB_PACKET_FILTERS; + +typedef struct _MBB_SINGLE_PACKET_FILTER +{ + ULONG FilterSize; + ULONG PacketFilterOffset; + ULONG PacketMaskOffset; + UCHAR DataBuffer[1]; +} MBB_SINGLE_PACKET_FILTER; + +typedef struct _MBB_SINGLE_PACKET_FILTER* PMBB_SINGLE_PACKET_FILTER; + +typedef struct _MBB_SINGLE_PACKET_FILTER_V2 +{ + ULONG FilterSize; + ULONG PacketFilterOffset; + ULONG PacketMaskOffset; + ULONG FilterId; + UCHAR DataBuffer[1]; +} MBB_SINGLE_PACKET_FILTER_V2; + +typedef struct _MBB_SINGLE_PACKET_FILTER_V2* PMBB_SINGLE_PACKET_FILTER_V2; + +typedef struct _MBB_NETWORK_IDLE_HINT +{ + MBB_NETWORK_IDLE_HINT_STATE NetworkIdleHintState; +} MBB_NETWORK_IDLE_HINT; + +typedef struct _MBB_NETWORK_IDLE_HINT* PMBB_NETWORK_IDLE_HINT; + +typedef struct _MBB_DEVICE_SERVICE_ELEMENT +{ + GUID DeviceServiceId; + MBB_DSS_PAYLOAD_SUPPORT DSSPayload; + ULONG MaxDSSInstances; + ULONG CIDCount; + ULONG CIDList[1]; +} MBB_DEVICE_SERVICE_ELEMENT; + +typedef struct _MBB_DEVICE_SERVICE_ELEMENT* PMBB_DEVICE_SERVICE_ELEMENT; + +typedef struct _MBB_DEVICE_SERVICES_HEADER +{ + ULONG DeviceServicesCount; + ULONG MaxDSSSessions; + MBB_ARRAY_ELEMENT ArrayElement[1]; +} MBB_DEVICE_SERVICES_HEADER; + +typedef struct _MBB_DEVICE_SERVICES_HEADER* PMBB_DEVICE_SERVICES_HEADER; + +typedef struct _MBB_SUBSCRIBE_EVENT_ENTRY +{ + GUID DeviceServiceId; + ULONG CIDCount; + ULONG CIDList[1]; +} MBB_SUBSCRIBE_EVENT_ENTRY; + +typedef struct _MBB_SUBSCRIBE_EVENT_ENTRY* PMBB_SUBSCRIBE_EVENT_ENTRY; + +typedef struct _MBB_SUBSCRIBE_EVENT_LIST +{ + ULONG Count; + MBB_ARRAY_ELEMENT ArrayElement[1]; +} MBB_SUBSCRIBE_EVENT_LIST; + +typedef struct _MBB_SUBSCRIBE_EVENT_LIST* PMBB_SUBSCRIBE_EVENT_LIST; + +typedef struct _MBB_SET_DSS_CONNECT +{ + GUID DeviceServiceId; + ULONG DssSessionId; + MBB_DSS_LINK_STATE DssLinkState; +} MBB_SET_DSS_CONNECT; + +typedef struct _MBB_SET_DSS_CONNECT* PMBB_SET_DSS_CONNECT; + +typedef struct _MBB_SET_DSS_CLOSE +{ + ULONG DssSessionId; +} MBB_SET_DSS_CLOSE; + +typedef struct _MBB_SET_DSS_CLOSE* PMBB_SET_DSS_CLOSE; + +typedef struct _MBB_MULTICARRIER_CURRENT_CID_LIST +{ + ULONG CIDCount; + ULONG CIDList[1]; +} MBB_MULTICARRIER_CURRENT_CID_LIST; + +typedef struct _MBB_MULTICARRIER_CURRENT_CID_LIST* PMBB_MULTICARRIER_CURRENT_CID_LIST; + +typedef enum _MBB_UICC_APP_TYPE +{ + MbbUiccAppTypeUnknown = 0, + MbbUiccAppTypeMf = 1, + MbbUiccAppTypeMfSIM = 2, + MbbUiccAppTypeMfRUIM = 3, + MbbUiccAppTypeUSIM = 4, + MbbUiccAppTypeCSIM = 5, + MbbUiccAppTypeISIM = 6, + MbbUiccAppTypeMax = (MbbUiccAppTypeISIM + 1) +} MBB_UICC_APP_TYPE; + +typedef struct _MBB_UICC_APP_INFO +{ + MBB_UICC_APP_TYPE AppType; + MBB_ARRAY_ELEMENT AppId; + MBB_ARRAY_ELEMENT AppName; + ULONG NumPins; + MBB_ARRAY_ELEMENT PinRef; + UCHAR DataBuffer[1]; +} MBB_UICC_APP_INFO; + +typedef struct _MBB_UICC_APP_INFO* PMBB_UICC_APP_INFO; + +typedef struct _MBB_UICC_APP_LIST +{ + ULONG Version; + ULONG AppCount; + ULONG ActiveAppIndex; + ULONG AppListSize; + MBB_ARRAY_ELEMENT DataBuffer[1]; +} MBB_UICC_APP_LIST; + +typedef struct _MBB_UICC_APP_LIST* PMBB_UICC_APP_LIST; + +typedef enum _MBB_UICC_FILE_ACCESSIBILITY +{ + MbbUiccFileAccessibilityUnknown = 0, + MbbUiccFileAccessibilityNotShareable = 1, + MbbUiccFileAccessibilityShareable = 2, + MbbUiccFileAccessibilityMax = (MbbUiccFileAccessibilityShareable + 1) +} MBB_UICC_FILE_ACCESSIBILITY; + +typedef enum _MBB_UICC_FILE_TYPE +{ + MbbUiccFileTypeUnknown = 0, + MbbUiccFileTypeWorkingEf = 1, + MbbUiccFileTypeInternalEf = 2, + MbbUiccFileTypeDfOrAdf = 3, + MbbUiccFileTypeMax = (MbbUiccFileTypeDfOrAdf + 1) +} MBB_UICC_FILE_TYPE; + +typedef enum _MBB_UICC_FILE_STRUCTURE +{ + MbbUiccFileStructureUnknown = 0, + MbbUiccFileStructureTransparent = 1, + MbbUiccFileStructureCyclic = 2, + MbbUiccFileStructureLinear = 3, + MbbUiccFileStructureBertlv = 4, + MbbUiccFileStructureMax = (MbbUiccFileStructureBertlv + 1) +} MBB_UICC_FILE_STRUCTURE; + +typedef struct _MBB_UICC_FILE_PATH +{ + ULONG Version; + MBB_ARRAY_ELEMENT AppId; + MBB_ARRAY_ELEMENT FilePath; + UCHAR DataBuffer[1]; +} MBB_UICC_FILE_PATH; + +typedef struct _MBB_UICC_FILE_PATH* PMBB_UICC_FILE_PATH; + +typedef struct _MBB_UICC_FILE_STATUS +{ + ULONG Version; + ULONG StatusWord1; + ULONG StatusWord2; + MBB_UICC_FILE_ACCESSIBILITY FileAccessibility; + MBB_UICC_FILE_TYPE FileType; + MBB_UICC_FILE_STRUCTURE FileStructure; + ULONG ItemCount; + ULONG ItemSize; + MBB_PIN_TYPE FileLockStatus[4]; +} MBB_UICC_FILE_STATUS; + +typedef struct _MBB_UICC_FILE_STATUS* PMBB_UICC_FILE_STATUS; + +typedef struct _MBB_UICC_ACCESS_BINARY +{ + ULONG Version; + MBB_ARRAY_ELEMENT AppId; + MBB_ARRAY_ELEMENT UiccFilePath; + ULONG FileOffset; + ULONG NumberOfBytes; + MBB_ARRAY_ELEMENT LocalPin; + MBB_ARRAY_ELEMENT BinaryData; + UCHAR DataBuffer[1]; +} MBB_UICC_ACCESS_BINARY; + +typedef struct _MBB_UICC_ACCESS_BINARY* PMBB_UICC_ACCESS_BINARY; + +typedef struct _MBB_UICC_ACCESS_RECORD +{ + ULONG Version; + MBB_ARRAY_ELEMENT AppId; + MBB_ARRAY_ELEMENT UiccFilePath; + ULONG RecordNumber; + MBB_ARRAY_ELEMENT LocalPin; + MBB_ARRAY_ELEMENT RecordData; + UCHAR DataBuffer[1]; +} MBB_UICC_ACCESS_RECORD; + +typedef struct _MBB_UICC_ACCESS_RECORD* PMBB_UICC_ACCESS_RECORD; + +typedef struct _MBB_UICC_RESPONSE +{ + ULONG Version; + ULONG StatusWord1; + ULONG StatusWord2; + MBB_ARRAY_ELEMENT ResponseData; + UCHAR DataBuffer[1]; +} MBB_UICC_RESPONSE; + +typedef struct _MBB_UICC_RESPONSE* PMBB_UICC_RESPONSE; + +typedef struct _MBB_PIN_APP +{ + ULONG Version; + MBB_ARRAY_ELEMENT AppId; + UCHAR DataBuffer[1]; +} MBB_PIN_APP; + +typedef struct _MBB_PIN_APP* PMBB_PIN_APP; + +typedef struct _MBB_PIN_ACTION_EX2 +{ + MBB_PIN_TYPE PinType; + MBB_PIN_OPERATION PinOperation; + MBB_STRING Pin; + MBB_STRING NewPin; + MBB_ARRAY_ELEMENT AppId; + UCHAR DataBuffer[1]; +} MBB_PIN_ACTION_EX2; + +typedef struct _MBB_PIN_ACTION_EX2* PMBB_PIN_ACTION_EX2; + +typedef struct _MBB_SYS_CAPS_INFO +{ + ULONG NumberOfExecutors; + ULONG NumberOfSlots; + ULONG Concurrency; +} MBB_SYS_CAPS_INFO; + +typedef struct _MBB_SYS_CAPS_INFO* PMBB_SYS_CAPS_INFO; + +typedef struct _MBB_DEVICE_CAPS_V2 +{ + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + MBB_SIM_CLASS SimClass; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONG dwMaxSessions; + MBB_STRING CustomDataClass; + MBB_STRING DeviceIdString; + MBB_STRING FirmwareInfo; + MBB_STRING HardwareInfo; + ULONG DeviceIndex; + UCHAR DataBuffer[1]; +} MBB_DEVICE_CAPS_V2; + +typedef struct _MBB_DEVICE_CAPS_V2* PMBB_DEVICE_CAPS_V2; + +typedef struct _MBB_DEVICE_SLOT_MAPPING_INFO +{ + ULONG MapCount; + MBB_ARRAY_ELEMENT SlotMapList[1]; +} MBB_DEVICE_SLOT_MAPPING_INFO; + +typedef struct _MBB_DEVICE_SLOT_MAPPING_INFO* PMBB_DEVICE_SLOT_MAPPING_INFO; + +typedef enum _MBB_UICCSLOT_STATE +{ + MbbUiccSlotStateOffEmpty = 0, + MbbUiccSlotStateOff = 1, + MbbUiccSlotStateEmpty = 2, + MbbUiccSlotStateNotReady = 3, + MbbUiccSlotStateActive = 4, + MbbUiccSlotStateError = 5 +} MBB_UICCSLOT_STATE; + +typedef struct _MBB_SLOT_INFO_REQ +{ + ULONG SlotIndex; +} MBB_SLOT_INFO_REQ; + +typedef struct _MBB_SLOT_INFO_REQ* PMBB_SLOT_INFO_REQ; + +typedef struct _MBB_SLOT_INFO +{ + ULONG SlotIndex; + MBB_UICCSLOT_STATE State; +} MBB_SLOT_INFO; + +typedef struct _MBB_SLOT_INFO* PMBB_SLOT_INFO; + +typedef struct _MBB_DEVICE_BINDINGS_INFO +{ + ULONG ApplicationCount; + MBB_ARRAY_ELEMENT ApplicationList[1]; +} MBB_DEVICE_BINDINGS_INFO; + +typedef struct _MBB_DEVICE_BINDINGS_INFO* PMBB_DEVICE_BINDINGS_INFO; + +typedef enum _MBB_REGISTRATION_VOICE_CLASS +{ + MbbRegistrationVoiceClassVoiceCentric = 0, + MbbRegistrationVoiceClassDataCentric = 1 +} MBB_REGISTRATION_VOICE_CLASS; + +typedef enum _MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE +{ + MbbRegistrationVoiceDomainPreferenceCsOnly = 0, + MbbRegistrationVoiceDomainPreferenceCsPreferred = 1, + MbbRegistrationVoiceDomainPreferenceImsPreferred = 2, + MbbRegistrationVoiceDomainPreferenceImsOnly = 3 +} MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE; + +typedef enum _MBB_REGISTRATION_VOICE_SUPPORT +{ + MbbRegistrationVoiceSupportNone = 0, + MbbRegistrationVoiceSupportIms = 0x1, + MbbRegistrationVoiceSupportEmergencyAttach = 0x2, + MbbRegistrationVoiceSupportCs = 0x4, + MbbRegistrationVoiceSupportCsfb = 0x8, + MbbRegistrationVoiceSupport1xCsfb = 0x10, + MbbRegistrationVoiceSupportCsEmergency = 0x20 +} MBB_REGISTRATION_VOICE_SUPPORT; + +typedef enum _MBB_REGISTRATION_CDMA_ROAM_MODE +{ + MbbRegistrationCdmaRoamModeAutomatic = 0, + MbbRegistrationCdmaRoamModeHomeOnly = 1 +} MBB_REGISTRATION_CDMA_ROAM_MODE; + +typedef struct _MBB_SET_REGISTER_STATE_V2 +{ + MBB_STRING ProviderId; + MBB_REGISTER_ACTION RegisterAction; + ULONG DataClass; + MBB_REGISTRATION_VOICE_CLASS VoiceClass; + MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE VoiceDomain; + MBB_REGISTRATION_CDMA_ROAM_MODE CdmaRoamMode; + MBB_ARRAY_ELEMENT AcquisitionOrder[1]; +} MBB_SET_REGISTER_STATE_V2; + +typedef struct _MBB_SET_REGISTER_STATE_V2* PMBB_SET_REGISTER_STATE_V2; + +typedef struct _MBB_REGISTRATION_STATE_V2 +{ + ULONG NetworkError; + MBB_REGISTER_STATE RegisterState; + MBB_REGISTER_MODE RegisterMode; + ULONG AvailableDataClasses; + MBB_CELLULAR_CLASS CurrentCellularClass; + MBB_STRING ProviderId; + MBB_STRING ProviderName; + MBB_STRING RoamingText; + ULONG RegFlags; + MBB_REGISTRATION_VOICE_SUPPORT VoiceSupport; + ULONG CurrentRATClass; + UCHAR DataBuffer[1]; +} MBB_REGISTRATION_STATE_V2; + +typedef struct _MBB_REGISTRATION_STATE_V2* PMBB_REGISTRATION_STATE_V2; + +typedef struct _MBB_REGISTRATION_STATE_INFOS_V2 +{ + ULONG ElementCount; + MBB_ARRAY_ELEMENT RegistrationStateList[1]; +} MBB_REGISTRATION_STATE_INFOS_V2; + +typedef struct _MBB_REGISTRATION_STATE_INFOS_V2* PMBB_REGISTRATION_STATE_INFOS_V2; + +typedef struct _MBB_REGISTRATION_STATE_INFO_V2 +{ + ULONG NetworkError; + MBB_REGISTER_STATE RegisterState; + MBB_REGISTER_MODE RegisterMode; + ULONG AvailableDataClasses; + MBB_CELLULAR_CLASS CurrentCellularClass; + MBB_STRING ProviderId; + MBB_STRING ProviderName; + MBB_STRING RoamingText; + ULONG RegistrationFlag; + ULONG PreferredDataClasses; + UCHAR DataBuffer[1]; +} MBB_REGISTRATION_STATE_INFO_V2; + +typedef struct _MBB_REGISTRATION_STATE_INFO_V2* PMBB_REGISTRATION_STATE_INFO_V2; + +typedef enum _MBB_IMS_VOICE_STATUS +{ + MbbImsVoiceStatusUnknown = 0, + MbbImsVoiceStatusUnregistered = 1, + MbbImsVoiceStatusRegistered = 2 +} MBB_IMS_VOICE_STATUS; + +typedef struct _MBB_SET_IMS_VOICE_STATE +{ + MBB_IMS_VOICE_STATUS ImsVoiceStatus; +} MBB_SET_IMS_VOICE_STATE; + +typedef struct _MBB_SET_IMS_VOICE_STATE* PMBB_SET_IMS_VOICE_STATE; + +typedef struct _MBB_IMS_VOICE_STATE +{ + MBB_IMS_VOICE_STATUS ImsVoiceStatus; +} MBB_IMS_VOICE_STATE; + +typedef struct _MBB_IMS_VOICE_STATE* PMBB_IMS_VOICE_STATE; + +typedef struct _MBB_SET_SIGNAL_INDICATION_V2 +{ + ULONG RssiInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; + ULONG SnrThreshold; +} MBB_SET_SIGNAL_INDICATION_V2; + +typedef struct _MBB_SET_SIGNAL_INDICATION_V2* PMBB_SET_SIGNAL_INDICATION_V2; + +typedef struct _MBB_SIGNAL_STATE_V2 +{ + ULONG Rssi; + ULONG ErrorRate; + ULONG RssiInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; + ULONG Snr; + ULONG SnrThreshold; + ULONG DataClass; +} MBB_SIGNAL_STATE_V2; + +typedef struct _MBB_SIGNAL_STATE_V2* PMBB_SIGNAL_STATE_V2; + +typedef struct _MBB_RSRP_SNR_INFO +{ + ULONG RSRP; + ULONG SNR; + ULONG RSRPThreshold; + ULONG SNRThreshold; + MBB_DATA_CLASS_VALUE SystemType; +} MBB_RSRP_SNR_INFO; + +typedef struct _MBB_RSRP_SNR_INFO* PMBB_RSRP_SNR_INFO; + +typedef struct _MBB_RSRP_SNR +{ + ULONG ElementCount; + MBB_RSRP_SNR_INFO DataBuffer[1]; +} MBB_RSRP_SNR; + +typedef struct _MBB_RSRP_SNR* PMBB_RSRP_SNR; + +typedef struct _MBB_SIGNAL_STATE_INFO_V2 +{ + ULONG Rssi; + ULONG ErrorRate; + ULONG SignalStrengthInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; + ULONG RsrpSnrOffset; + ULONG RsrpSnrSize; + MBB_RSRP_SNR DataBuffer; +} MBB_SIGNAL_STATE_INFO_V2; + +typedef struct _MBB_SIGNAL_STATE_INFO_V2* PMBB_SIGNAL_STATE_INFO_V2; + +typedef struct _MBB_SIGNAL_STATE_INFOS_V2 +{ + ULONG ElementCount; + MBB_ARRAY_ELEMENT SignalStateList[1]; +} MBB_SIGNAL_STATE_INFOS_V2; + +typedef struct _MBB_SIGNAL_STATE_INFOS_V2* PMBB_SIGNAL_STATE_INFOS_V2; + +typedef enum _MBB_LOCATION_TRIGGER_MODE +{ + MbbLocationTriggerNone = 0, + MbbLocationTriggerAreaCode = 1, + MbbLocationTriggerAreaCellId = 2 +} MBB_LOCATION_TRIGGER_MODE; + +typedef struct _MBB_SET_LOCATION_STATE +{ + MBB_LOCATION_TRIGGER_MODE Trigger; +} MBB_SET_LOCATION_STATE; + +typedef struct _MBB_SET_LOCATION_STATE* PMBB_SET_LOCATION_STATE; + +typedef struct _MBB_LOCATION_STATE_INFO +{ + MBB_LOCATION_TRIGGER_MODE Trigger; + ULONG DataClass; + ULONG AreaCode; + ULONG CellId; +} MBB_LOCATION_STATE_INFO; + +typedef struct _MBB_LOCATION_STATE_INFO* PMBB_LOCATION_STATE_INFO; + +typedef struct _MBB_NITZ_INFO +{ + ULONG Year; + ULONG Month; + ULONG Day; + ULONG Hour; + ULONG Minute; + ULONG Second; + ULONG TimeZoneOffsetMinutes; + ULONG DaylightSavingTimeOffsetMinutes; + ULONG DataClasses; +} MBB_NITZ_INFO; + +typedef struct _MBB_NITZ_INFO* PMBB_NITZ_INFO; + +typedef struct _MBB_ATR_INFO +{ + MBB_ARRAY_ELEMENT2 Atr; + UCHAR DataBuffer[1]; +} MBB_ATR_INFO; + +typedef struct _MBB_ATR_INFO* PMBB_ATR_INFO; + +typedef struct _MBB_SET_UICC_OPEN_CHANNEL +{ + MBB_ARRAY_ELEMENT2 AppId; + ULONG SelectP2Arg; + ULONG ChannelGroup; + UCHAR DataBuffer[1]; +} MBB_SET_UICC_OPEN_CHANNEL; + +typedef struct _MBB_SET_UICC_OPEN_CHANNEL* PMBB_SET_UICC_OPEN_CHANNEL; + +typedef struct _MBB_UICC_OPEN_CHANNEL_INFO +{ + UCHAR Status[4]; + ULONG Channel; + MBB_ARRAY_ELEMENT2 Response; + UCHAR DataBuffer[1]; +} MBB_UICC_OPEN_CHANNEL_INFO; + +typedef struct _MBB_UICC_OPEN_CHANNEL_INFO* PMBB_UICC_OPEN_CHANNEL_INFO; + +typedef struct _MBB_SET_UICC_CLOSE_CHANNEL +{ + ULONG Channel; + ULONG ChannelGroup; + ULONG SelectP2Arg; +} MBB_SET_UICC_CLOSE_CHANNEL; + +typedef struct _MBB_SET_UICC_CLOSE_CHANNEL* PMBB_SET_UICC_CLOSE_CHANNEL; + +typedef struct _MBB_UICC_CLOSE_CHANNEL_INFO +{ + UCHAR Status[4]; +} MBB_UICC_CLOSE_CHANNEL_INFO; + +typedef struct _MBB_UICC_CLOSE_CHANNEL_INFO* PMBB_UICC_CLOSE_CHANNEL_INFO; + +typedef enum _MBB_UICC_SECURE_MESSAGING +{ + MbbUiccSecureMessagingNone = 0, + MbbUiccSecureMessagingNoHdrAuth = 1 +} MBB_UICC_SECURE_MESSAGING; + +typedef enum _MBB_UICC_CLASS_BYTE_TYPE +{ + MbbUiccClassByteTypeInterindustry = 0, + MbbUiccClassByteTypeExtended = 1 +} MBB_UICC_CLASS_BYTE_TYPE; + +typedef struct _MBB_SET_UICC_APDU +{ + ULONG Channel; + MBB_UICC_SECURE_MESSAGING SecureMessaging; + MBB_UICC_CLASS_BYTE_TYPE Type; + MBB_ARRAY_ELEMENT2 Command; + UCHAR DataBuffer[1]; +} MBB_SET_UICC_APDU; + +typedef struct _MBB_SET_UICC_APDU* PMBB_SET_UICC_APDU; + +typedef struct _MBB_UICC_APDU_INFO +{ + UCHAR Status[4]; + MBB_ARRAY_ELEMENT2 Response; + UCHAR DataBuffer[1]; +} MBB_UICC_APDU_INFO; + +typedef struct _MBB_UICC_APDU_INFO* PMBB_UICC_APDU_INFO; + +typedef struct _MBB_UICC_TERMINAL_CAPABILITY_TLV +{ + UCHAR Data[3]; +} MBB_UICC_TERMINAL_CAPABILITY_TLV; + +typedef struct _MBB_UICC_TERMINAL_CAPABILITY_TLV* PMBB_UICC_TERMINAL_CAPABILITY_TLV; + +typedef struct _MBB_SET_UICC_TERMINAL_CAPABILITY +{ + ULONG ElementCount; + MBB_ARRAY_ELEMENT CapabilityList[1]; +} MBB_SET_UICC_TERMINAL_CAPABILITY; + +typedef struct _MBB_SET_UICC_TERMINAL_CAPABILITY* PMBB_SET_UICC_TERMINAL_CAPABILITY; + +typedef struct _MBB_UICC_TERMINAL_CAPABILITY_INFO +{ + ULONG ElementCount; + MBB_ARRAY_ELEMENT CapabilityList[1]; +} MBB_UICC_TERMINAL_CAPABILITY_INFO; + +typedef struct _MBB_UICC_TERMINAL_CAPABILITY_INFO* PMBB_UICC_TERMINAL_CAPABILITY_INFO; + +typedef enum _MBB_UICC_PASSTHROUGH_ACTION +{ + MbbUiccPassThroughDisable = 0, + MbbUiccPassThroughEnable = 1 +} MBB_UICC_PASSTHROUGH_ACTION; + +typedef enum _MBB_UICC_PASSTHROUGH_STATUS +{ + MbbUiccPassThroughDisabled = 0, + MbbUiccPassThroughEnabled = 1 +} MBB_UICC_PASSTHROUGH_STATUS; + +typedef struct _MBB_SET_UICC_RESET +{ + MBB_UICC_PASSTHROUGH_ACTION PassThroughAction; +} MBB_SET_UICC_RESET; + +typedef struct _MBB_SET_UICC_RESET* PMBB_SET_UICC_RESET; + +typedef struct _MBB_UICC_RESET_INFO +{ + MBB_UICC_PASSTHROUGH_STATUS PassThroughStatus; +} MBB_UICC_RESET_INFO; + +typedef struct _MBB_UICC_RESET_INFO* PMBB_UICC_RESET_INFO; + +typedef struct _MBB_SAR_CONFIG_INDICES +{ + ULONG SarAntennaIndex; + ULONG SarBackoffIndex; +} MBB_SAR_CONFIG_INDICES; + +typedef struct _MBB_SAR_CONFIG_INDICES* PMBB_SAR_CONFIG_INDICES; + +typedef struct _MBB_SAR_CONFIG_INFO +{ + MBB_SAR_CONTROL_MODE SarMode; + MBB_SAR_BACKOFF_STATE SarBackoffStatus; + MBB_SAR_WIFI_HARDWARE_INTEGRATION SarWifiIntegration; + ULONG ElementCount; + MBB_ARRAY_ELEMENT Configurations[1]; +} MBB_SAR_CONFIG_INFO; + +typedef struct _MBB_SAR_CONFIG_INFO* PMBB_SAR_CONFIG_INFO; + +typedef struct _MBB_SET_SAR_CONFIG +{ + MBB_SAR_CONTROL_MODE SarMode; + MBB_SAR_BACKOFF_STATE SarBackoffStatus; + ULONG ElementCount; + MBB_ARRAY_ELEMENT Configurations[1]; +} MBB_SET_SAR_CONFIG; + +typedef struct _MBB_SET_SAR_CONFIG* PMBB_SET_SAR_CONFIG; + +typedef struct _MBB_SAR_TRANSMISSION_STATUS_INFO +{ + MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE ChannelNotification; + MBB_SAR_TRANSMISSION_STATUS TransmissionStatus; + ULONG HysteresisTimer; +} MBB_SAR_TRANSMISSION_STATUS_INFO; + +typedef struct _MBB_SAR_TRANSMISSION_STATUS_INFO* PMBB_SAR_TRANSMISSION_STATUS_INFO; + +typedef struct _MBB_SET_SAR_TRANSMISSION_STATUS +{ + MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE ChannelNotification; + ULONG HysteresisTimer; +} MBB_SET_SAR_TRANSMISSION_STATUS; + +typedef struct _MBB_SET_SAR_TRANSMISSION_STATUS* PMBB_SET_SAR_TRANSMISSION_STATUS; + +typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 +{ + MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS Operation; + GUID ContextType; + MBB_CONTEXT_IP_TYPE IPType; + MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; + MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; + MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; + MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[1]; +} MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2; + +typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2* PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2; + +typedef struct _MBB_MS_CONTEXT_V2 +{ + ULONG ContextId; + GUID ContextType; + MBB_CONTEXT_IP_TYPE IPType; + MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; + MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; + MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; + MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[1]; +} MBB_MS_CONTEXT_V2; + +typedef struct _MBB_MS_CONTEXT_V2* PMBB_MS_CONTEXT_V2; + +typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2_EX4 +{ + MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS Operation; + GUID ContextType; + MBB_CONTEXT_IP_TYPE IPType; + MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; + MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; + MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; + MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + MBB_TLV_IE Snssai; + UCHAR DataBuffer[1]; +} MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2_EX4; + +typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2_EX4* PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2_EX4; + +typedef struct _MBB_MS_CONTEXT_V2_EX4 +{ + ULONG ContextId; + GUID ContextType; + MBB_CONTEXT_IP_TYPE IPType; + MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; + MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; + MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; + MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + MBB_TLV_IE Snssai; + UCHAR DataBuffer[1]; +} MBB_MS_CONTEXT_V2_EX4; + +typedef struct _MBB_MS_CONTEXT_V2_EX4* PMBB_MS_CONTEXT_V2_EX4; + +typedef struct _MBB_MS_NETWORK_BLACKLIST_PROVIDER +{ + ULONG MCC; + ULONG MNC; + MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE NetworkBlacklistType; +} MBB_MS_NETWORK_BLACKLIST_PROVIDER; + +typedef struct _MBB_MS_NETWORK_BLACKLIST_PROVIDER* PMBB_MS_NETWORK_BLACKLIST_PROVIDER; + +typedef struct _MBB_MS_NETWORK_BLACKLIST_INFO +{ + MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE BlacklistState; + ULONG ElementCount; + MBB_ARRAY_ELEMENT Contexts[1]; +} MBB_MS_NETWORK_BLACKLIST_INFO; + +typedef struct _MBB_MS_NETWORK_BLACKLIST_INFO* PMBB_MS_NETWORK_BLACKLIST_INFO; + +typedef struct _MBB_MS_VERSION_INFO +{ + USHORT bcdMBIMVersion; + USHORT bcdMBIMExtendedVersion; +} MBB_MS_VERSION_INFO; + +typedef struct _MBB_MS_VERSION_INFO* PMBB_MS_VERSION_INFO; + +typedef struct _MBB_MS_LTE_ATTACH_CONTEXT +{ + MBB_CONTEXT_IP_TYPE IPType; + MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL Roaming; + MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[1]; +} MBB_MS_LTE_ATTACH_CONTEXT; + +typedef struct _MBB_MS_LTE_ATTACH_CONTEXT* PMBB_MS_LTE_ATTACH_CONTEXT; + +typedef struct _MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG +{ + MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS Operation; + ULONG ElementCount; + MBB_ARRAY_ELEMENT Contexts[1]; +} MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG; + +typedef struct _MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG* PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG; + +typedef struct _MBB_MS_LTE_ATTACH_CONFIG_INFO +{ + ULONG ElementCount; + MBB_ARRAY_ELEMENT Contexts[1]; +} MBB_MS_LTE_ATTACH_CONFIG_INFO; + +typedef struct _MBB_MS_LTE_ATTACH_CONFIG_INFO* PMBB_MS_LTE_ATTACH_CONFIG_INFO; + +typedef struct _MBB_MS_LTE_ATTACH_STATUS +{ + MBB_BASICCONNECTEXT_LTEATTACH_STATE LteAttachState; + MBB_CONTEXT_IP_TYPE IPType; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[1]; +} MBB_MS_LTE_ATTACH_STATUS; + +typedef struct _MBB_MS_LTE_ATTACH_STATUS* PMBB_MS_LTE_ATTACH_STATUS; + +typedef struct _MBB_MS_LTE_ATTACH_STATUS_V2 +{ + MBB_BASICCONNECTEXT_LTEATTACH_STATE LteAttachState; + ULONG NetworkError; + MBB_CONTEXT_IP_TYPE IPType; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[1]; +} MBB_MS_LTE_ATTACH_STATUS_V2; + +typedef struct _MBB_MS_LTE_ATTACH_STATUS_V2* PMBB_MS_LTE_ATTACH_STATUS_V2; + +typedef struct _MBB_MS_SYS_CAPS_INFO +{ + ULONG NumberOfExecutors; + ULONG NumberOfSlots; + ULONG Concurrency; + ULONG64 ModemId; +} MBB_MS_SYS_CAPS_INFO; + +typedef struct _MBB_MS_SYS_CAPS_INFO* PMBB_MS_SYS_CAPS_INFO; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V2 +{ + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + MBB_SIM_CLASS SimClass; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONG dwMaxSessions; + MBB_STRING CustomDataClass; + MBB_STRING DeviceIdString; + MBB_STRING FirmwareInfo; + MBB_STRING HardwareInfo; + ULONG ExecutorIndex; + UCHAR DataBuffer[1]; +} MBB_MS_DEVICE_CAPS_INFO_V2; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V2* PMBB_MS_DEVICE_CAPS_INFO_V2; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3_OBS +{ + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + ULONG SimClassBitMasks; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONGLONG MiscCaps; + ULONG dwMaxSessions; + ULONG ExecutorIndex; + ULONG WcdmaBandClass; +} MBB_MS_DEVICE_CAPS_INFO_V3_OBS; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3_OBS* PMBB_MS_DEVICE_CAPS_INFO_V3_OBS; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3 +{ + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + ULONG SimClassBitMasks; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONGLONG DataSubClass; + ULONG dwMaxSessions; + ULONG ExecutorIndex; + ULONG WcdmaBandClass; +} MBB_MS_DEVICE_CAPS_INFO_V3; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3* PMBB_MS_DEVICE_CAPS_INFO_V3; + +typedef struct _MBB_MS_DEVICE_SLOT_MAPPING_INFO +{ + ULONG MapCount; + MBB_ARRAY_ELEMENT SlotMapList[1]; +} MBB_MS_DEVICE_SLOT_MAPPING_INFO; + +typedef struct _MBB_MS_DEVICE_SLOT_MAPPING_INFO* PMBB_MS_DEVICE_SLOT_MAPPING_INFO; + +typedef struct _MBB_MS_SLOT_INFO_REQ +{ + ULONG SlotIndex; +} MBB_MS_SLOT_INFO_REQ; + +typedef struct _MBB_MS_SLOT_INFO_REQ* PMBB_MS_SLOT_INFO_REQ; + +typedef struct _MBB_MS_SLOT_INFO +{ + ULONG SlotIndex; + MBB_BASICCONNECTEXT_UICCSLOT_STATE State; +} MBB_MS_SLOT_INFO; + +typedef struct _MBB_MS_SLOT_INFO* PMBB_MS_SLOT_INFO; + +typedef struct _MBB_MS_PCO_VALUE +{ + ULONG SessionId; + ULONG PcoDataSize; + MBB_PCO_TYPE PcoDataType; + UCHAR PcoDataBuffer[1]; +} MBB_MS_PCO_VALUE; + +typedef struct _MBB_MS_PCO_VALUE* PMBB_MS_PCO_VALUE; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ +{ + ULONG MaxGSMCount; + ULONG MaxUMTSCount; + ULONG MaxTDSCDMACount; + ULONG MaxLTECount; + ULONG MaxCDMACount; +} MBB_MS_BASE_STATIONS_INFO_REQ; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ* PMBB_MS_BASE_STATIONS_INFO_REQ; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ_V2 +{ + ULONG MaxGSMCount; + ULONG MaxUMTSCount; + ULONG MaxTDSCDMACount; + ULONG MaxLTECount; + ULONG MaxCDMACount; + ULONG MaxNRCount; +} MBB_MS_BASE_STATIONS_INFO_REQ_V2; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ_V2* PMBB_MS_BASE_STATIONS_INFO_REQ_V2; + +typedef struct _MBB_MS_BASE_STATIONS_INFO +{ + MBB_DATA_CLASS_VALUE SystemType; + MBB_ARRAY_ELEMENT GSMServingCell; + MBB_ARRAY_ELEMENT UMTSServingCell; + MBB_ARRAY_ELEMENT TDSCDMAServingCell; + MBB_ARRAY_ELEMENT LTEServingCell; + MBB_ARRAY_ELEMENT GSMNmr; + MBB_ARRAY_ELEMENT UMTSMrl; + MBB_ARRAY_ELEMENT TDSCDMAMrl; + MBB_ARRAY_ELEMENT LTEMrl; + MBB_ARRAY_ELEMENT CDMAMrl; + UCHAR DataBuffer[1]; +} MBB_MS_BASE_STATIONS_INFO; + +typedef struct _MBB_MS_BASE_STATIONS_INFO* PMBB_MS_BASE_STATIONS_INFO; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_V2 +{ + MBB_DATA_CLASS_VALUE SystemType; + MBB_DATA_SUBCLASS_VALUE SystemSubType; + MBB_ARRAY_ELEMENT GSMServingCell; + MBB_ARRAY_ELEMENT UMTSServingCell; + MBB_ARRAY_ELEMENT TDSCDMAServingCell; + MBB_ARRAY_ELEMENT LTEServingCell; + MBB_ARRAY_ELEMENT GSMNmr; + MBB_ARRAY_ELEMENT UMTSMrl; + MBB_ARRAY_ELEMENT TDSCDMAMrl; + MBB_ARRAY_ELEMENT LTEMrl; + MBB_ARRAY_ELEMENT CDMAMrl; + MBB_ARRAY_ELEMENT NRServingCells; + MBB_ARRAY_ELEMENT NRNeighborCells; + UCHAR DataBuffer[1]; +} MBB_MS_BASE_STATIONS_INFO_V2; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_V2* PMBB_MS_BASE_STATIONS_INFO_V2; + +typedef struct _MBB_MODEM_LOGGING_CONFIG +{ + ULONG Version; + ULONG MaxSegmentSize; + ULONG MaxFlushTime; + MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG LevelConfig; +} MBB_MODEM_LOGGING_CONFIG; + +typedef struct _MBB_MODEM_LOGGING_CONFIG* PMBB_MODEM_LOGGING_CONFIG; + +typedef enum _MBB_ACCESS_TYPE +{ + MbbAccessUnknown = 0, + MbbAccess3GPP = 1, + MbbAccessNon3GPP = 2, + MbbAccessMaximum = (MbbAccessNon3GPP + 1) +} MBB_ACCESS_TYPE; + +typedef struct _MBB_PRE_DFLT_NSSAI_INFO +{ + MBB_ACCESS_TYPE AccessType; + MBB_TLV_IE PreferredNSSAI; +} MBB_PRE_DFLT_NSSAI_INFO; + +typedef struct _MBB_PRE_DFLT_NSSAI_INFO* PMBB_PRE_DFLT_NSSAI_INFO; + +typedef struct _MBB_SNSSAI_INFO +{ + UCHAR SnssaiLength; + UCHAR Sst; +} MBB_SNSSAI_INFO; + +typedef struct _MBB_SNSSAI_INFO* PMBB_SNSSAI_INFO; + +typedef struct _MBB_TAI_LIST_SINGLE_PLMN +{ + MBB_PLMN Plmn; + UCHAR ElementCount; + ULONG TacList[1]; +} MBB_TAI_LIST_SINGLE_PLMN; + +typedef struct _MBB_TAI_LIST_SINGLE_PLMN* PMBB_TAI_LIST_SINGLE_PLMN; + +typedef struct _MBB_TAI_LIST_MULTI_PLMNS +{ + UCHAR ElementCount; + MBB_TAI TaiList[1]; +} MBB_TAI_LIST_MULTI_PLMNS; + +typedef struct _MBB_TAI_LIST_MULTI_PLMNS* PMBB_TAI_LIST_MULTI_PLMNS; + +typedef struct _MBB_TAI_LIST_INFO +{ + UCHAR ListType; + /* [switch_is] */ /* [switch_type] */ union __MIDL___MIDL_itf_MbbMessages_0000_0000_0002 + { + /* [case()] */ MBB_TAI_LIST_SINGLE_PLMN SinglePlmnTaiList; + /* [case()] */ MBB_TAI_LIST_MULTI_PLMNS MultiPlmnsTaiList; + } u; +} MBB_TAI_LIST_INFO; + +typedef struct _MBB_TAI_LIST_INFO* PMBB_TAI_LIST_INFO; + +typedef struct _MBB_DNN +{ + UCHAR DnnLength; +} MBB_DNN; + +typedef struct _MBB_DNN* PMBB_DNN; + +typedef struct _MBB_LADN +{ + MBB_DNN Dnn; +} MBB_LADN; + +typedef struct _MBB_LADN* PMBB_LADN; + +typedef enum _MBB_MODEM_CONFIG_STATUS +{ + ModemConfigStatusUnknown = 0, + ModemConfigStatusStarted = 1, + ModemConfigStatusCompleted = 2, + ModemConfigStatusMaximum = (ModemConfigStatusCompleted + 1) +} MBB_MODEM_CONFIG_STATUS; + +typedef struct _MBB_MODEM_CONFIG_INFO +{ + MBB_MODEM_CONFIG_STATUS ConfigStatus; + MBB_TLV_IE ConfigName; +} MBB_MODEM_CONFIG_INFO; + +typedef struct _MBB_MODEM_CONFIG_INFO* PMBB_MODEM_CONFIG_INFO; + +typedef enum _MBB_MICO_MODE +{ + MicoModeDisabled = 0, + MicoModeEnabled = 1, + MicoModeUnsupported = 2, + MBIMMicoModeDefault = 3, + MicoModeMaximum = (MBIMMicoModeDefault + 1) +} MBB_MICO_MODE; + +typedef enum _MBB_DRX_PARAMS +{ + DRXNotSpecified = 0, + MBIMDRXNotSupported = 1, + DRXCycle32 = 2, + DRXCycle64 = 3, + DRXCycle128 = 4, + DRXCycle256 = 5, + DRXCycleMaximum = (DRXCycle256 + 1) +} MBB_DRX_PARAMS; + +typedef enum _MBB_DEFAULT_PDU_HINT +{ + MBIMDefaultPDUSessionActivationUnlikely = 0, + MBIMDefaultPDUSessionActivationLikely = 1, + DefaultPDUMaximum = (MBIMDefaultPDUSessionActivationLikely + 1) +} MBB_DEFAULT_PDU_HINT; + +typedef enum _MBB_MS_LADN_IND +{ + LADNInfoNotNeeded = 0, + LADNInfoRequested = 1, + LADNInfoMaximum = (LADNInfoRequested + 1) +} MBB_MS_LADN_IND; + +typedef struct _MBB_REGISTRATION_PARAMS_INFO +{ + MBB_MICO_MODE MicoMode; + MBB_DRX_PARAMS DRXParams; + MBB_MS_LADN_IND LADNInfo; + MBB_DEFAULT_PDU_HINT DefaultPDUHint; + ULONG ReRegisterIfNeeded; +} MBB_REGISTRATION_PARAMS_INFO; + +typedef struct _MBB_REGISTRATION_PARAMS_INFO* PMBB_REGISTRATION_PARAMS_INFO; + +typedef enum _MBB_MICO_IND +{ + RaaiTypeRaNotAllocated = 0, + RaaiTypeRaAllocated = 1, + RaaiTypeNotAvailable = 0xffffffff +} MBB_MICO_IND; + +typedef struct _MBB_NW_PARAMS_QUERY_INFO +{ + USHORT AreConfigurationsNeeded; + USHORT AreUEPoliciesNeeded; +} MBB_NW_PARAMS_QUERY_INFO; + +typedef struct _MBB_NW_PARAMS_QUERY_INFO* PMBB_NW_PARAMS_QUERY_INFO; + +typedef struct _MBB_NW_PARAMS_INFO +{ + MBB_MICO_IND MicoInd; + MBB_DRX_PARAMS DRXParams; +} MBB_NW_PARAMS_INFO; + +typedef struct _MBB_NW_PARAMS_INFO* PMBB_NW_PARAMS_INFO; + +typedef enum _MBB_WAKE_TYPE +{ + WakeTypeCIDResponse = 0, + WakeTypeCIDIndication = 1, + WakeTypePacket = 2 +} MBB_WAKE_TYPE; + +typedef struct _MBB_WAKE_REASON +{ + MBB_WAKE_TYPE WakeType; + ULONG SessionId; +} MBB_WAKE_REASON; + +typedef struct _MBB_WAKE_REASON* PMBB_WAKE_REASON; + +typedef struct _MBB_WAKE_COMMAND +{ + MBB_COMMAND Command; + ULONG PayloadOffset; + ULONG PayloadSize; + UCHAR DataBuffer[1]; +} MBB_WAKE_COMMAND; + +typedef struct _MBB_WAKE_COMMAND* PMBB_WAKE_COMMAND; + +typedef struct _MBB_WAKE_PACKET +{ + ULONG FilterId; + ULONG OriginalPacketSize; + ULONG SavedPacketOffset; + ULONG SavedPacketSize; + UCHAR DataBuffer[1]; +} MBB_WAKE_PACKET; + +typedef struct _MBB_WAKE_PACKET* PMBB_WAKE_PACKET; + +#include + +extern RPC_IF_HANDLE __MIDL_itf_MbbMessages_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_MbbMessages_0000_0000_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/network/wwan/cxwmbclass/util.c b/network/wwan/cxwmbclass/util.c new file mode 100644 index 000000000..6b3d9a5cb --- /dev/null +++ b/network/wwan/cxwmbclass/util.c @@ -0,0 +1,9090 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" +#include "util.tmh" +#include +#include "WMBClassTelemetry.h" + + + +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#define WMBCLASS_MAX_EVENT_DATA_DESCRIPTORS (10) + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// TYPEDEFS +// +//////////////////////////////////////////////////////////////////////////////// +// this is for translating a code into an ASCII string +typedef struct Code2Ascii +{ + NDIS_OID Oid; + PCHAR OidName; +} Code2Ascii; + +typedef struct _MBB_ALLOC_MANAGER +{ + NPAGED_LOOKASIDE_LIST LookasideList; + NDIS_SPIN_LOCK Lock; + LIST_ENTRY AllocatedList; + LIST_ENTRY PreAllocatedFreeList; + MBB_ALLOC_FLAGS Flags; + +} MBB_ALLOC_MANAGER, +*PMBB_ALLOC_MANAGER; + +typedef struct _MBB_ALLOC_ENTRY +{ + LIST_ENTRY TrackLink; + LIST_ENTRY FreeLink; + BOOLEAN IsPreAllocated; + PMBB_ALLOC_MANAGER AllocMgr; + +} MBB_ALLOC_ENTRY, +*PMBB_ALLOC_ENTRY; + +typedef struct _MBB_BUFFER_MANAGER +{ + PVOID AllocMgrHandle; + ULONG BufferLength; + +} MBB_BUFFER_MANAGER, +*PMBB_BUFFER_MANAGER; + +typedef struct _MBB_BUFFER_CONTEXT +{ + PMBB_BUFFER_MANAGER BufferManager; + PVOID OwnerContext; + +} MBB_BUFFER_CONTEXT, +*PMBB_BUFFER_CONTEXT; + +typedef struct _MBB_WORKITEM_ENTRY +{ + LIST_ENTRY QueueLink; + PVOID Context1; + PVOID Context2; + PVOID Context3; + PVOID Context4; + MBB_WORKITEM_ROUTINE Routine; + +} MBB_WORKITEM_ENTRY, +*PMBB_WORKITEM_ENTRY; + +typedef struct _MBB_WORKITEM_MANAGER +{ + NDIS_SPIN_LOCK Lock; + PVOID AllocMgrHandle; + KEVENT ThreadExitEvent; + KEVENT WorkItemEvent; + LIST_ENTRY WorkItemQueue; + HANDLE ThreadHandle; + +} MBB_WORKITEM_MANAGER, +*PMBB_WORKITEM_MANAGER; + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// GLOBALS +// +//////////////////////////////////////////////////////////////////////////////// +const Code2Ascii OidList[] = +{ + OID_GEN_SUPPORTED_LIST, "OID_GEN_SUPPORTED_LIST", + OID_GEN_HARDWARE_STATUS, "OID_GEN_HARDWARE_STATUS", + OID_GEN_MEDIA_SUPPORTED, "OID_GEN_MEDIA_SUPPORTED", + OID_GEN_MEDIA_IN_USE, "OID_GEN_MEDIA_IN_USE", + OID_GEN_MAXIMUM_LOOKAHEAD, "OID_GEN_MAXIMUM_LOOKAHEAD", + OID_GEN_MAXIMUM_FRAME_SIZE, "OID_GEN_MAXIMUM_FRAME_SIZE", + OID_GEN_LINK_SPEED, "OID_GEN_LINK_SPEED", + OID_GEN_TRANSMIT_BUFFER_SPACE, "OID_GEN_TRANSMIT_BUFFER_SPACE", + OID_GEN_RECEIVE_BUFFER_SPACE, "OID_GEN_RECEIVE_BUFFER_SPACE", + OID_GEN_TRANSMIT_BLOCK_SIZE, "OID_GEN_TRANSMIT_BLOCK_SIZE", + OID_GEN_RECEIVE_BLOCK_SIZE, "OID_GEN_RECEIVE_BLOCK_SIZE", + OID_GEN_VENDOR_ID, "OID_GEN_VENDOR_ID", + OID_GEN_VENDOR_DESCRIPTION, "OID_GEN_VENDOR_DESCRIPTION", + OID_GEN_CURRENT_PACKET_FILTER, "OID_GEN_CURRENT_PACKET_FILTER", + OID_GEN_TRANSPORT_HEADER_OFFSET, "OID_GEN_TRANSPORT_HEADER_OFFSET", + OID_GEN_CURRENT_LOOKAHEAD, "OID_GEN_CURRENT_LOOKAHEAD", + OID_GEN_DRIVER_VERSION, "OID_GEN_DRIVER_VERSION", + OID_GEN_VENDOR_DRIVER_VERSION, "OID_GEN_VENDOR_DRIVER_VERSION", + OID_GEN_MAXIMUM_TOTAL_SIZE, "OID_GEN_MAXIMUM_TOTAL_SIZE", + OID_GEN_PROTOCOL_OPTIONS, "OID_GEN_PROTOCOL_OPTIONS", + OID_GEN_MAC_OPTIONS, "OID_GEN_MAC_OPTIONS", + OID_GEN_MEDIA_CONNECT_STATUS, "OID_GEN_MEDIA_CONNECT_STATUS", + OID_GEN_MAXIMUM_SEND_PACKETS, "OID_GEN_MAXIMUM_SEND_PACKETS", + OID_GEN_SUPPORTED_GUIDS, "OID_GEN_SUPPORTED_GUIDS", + OID_GEN_XMIT_OK, "OID_GEN_XMIT_OK", + OID_GEN_RCV_OK, "OID_GEN_RCV_OK", + OID_GEN_XMIT_ERROR, "OID_GEN_XMIT_ERROR", + OID_GEN_RCV_ERROR, "OID_GEN_RCV_ERROR", + OID_GEN_RCV_NO_BUFFER, "OID_GEN_RCV_NO_BUFFER", + OID_GEN_RCV_CRC_ERROR, "OID_GEN_RCV_CRC_ERROR", + OID_GEN_TRANSMIT_QUEUE_LENGTH, "OID_GEN_TRANSMIT_QUEUE_LENGTH", + OID_802_3_PERMANENT_ADDRESS, "OID_802_3_PERMANENT_ADDRESS", + OID_802_3_CURRENT_ADDRESS, "OID_802_3_CURRENT_ADDRESS", + OID_802_3_MULTICAST_LIST, "OID_802_3_MULTICAST_LIST", + OID_802_3_MAXIMUM_LIST_SIZE, "OID_802_3_MAXIMUM_LIST_SIZE", + OID_802_3_RCV_ERROR_ALIGNMENT, "OID_802_3_RCV_ERROR_ALIGNMENT", + OID_802_3_XMIT_ONE_COLLISION, "OID_802_3_XMIT_ONE_COLLISION", + OID_802_3_XMIT_MORE_COLLISIONS, "OID_802_3_XMIT_MORE_COLLISIONS", + OID_802_3_XMIT_DEFERRED, "OID_802_3_XMIT_DEFERRED", + OID_802_3_XMIT_MAX_COLLISIONS, "OID_802_3_XMIT_MAX_COLLISIONS", + OID_802_3_RCV_OVERRUN, "OID_802_3_RCV_OVERRUN", + OID_802_3_XMIT_UNDERRUN, "OID_802_3_XMIT_UNDERRUN", + OID_802_3_XMIT_HEARTBEAT_FAILURE, "OID_802_3_XMIT_HEARTBEAT_FAILURE", + OID_802_3_XMIT_TIMES_CRS_LOST, "OID_802_3_XMIT_TIMES_CRS_LOST", + OID_802_3_XMIT_LATE_COLLISIONS, "OID_802_3_XMIT_LATE_COLLISIONS", + OID_802_3_MAC_OPTIONS, "OID_802_3_MAC_OPTIONS", + OID_TCP_TASK_OFFLOAD, "OID_TCP_TASK_OFFLOAD", + OID_PNP_CAPABILITIES, "OID_PNP_CAPABILITIES", + OID_PNP_SET_POWER, "OID_PNP_SET_POWER", + OID_PNP_QUERY_POWER, "OID_PNP_QUERY_POWER", + OID_PNP_ADD_WAKE_UP_PATTERN, "OID_PNP_ADD_WAKE_UP_PATTERN", + OID_PNP_REMOVE_WAKE_UP_PATTERN, "OID_PNP_REMOVE_WAKE_UP_PATTERN", + OID_PNP_ENABLE_WAKE_UP, "OID_PNP_ENABLE_WAKE_UP", + OID_GEN_STATISTICS, "OID_GEN_STATISTICS", + OID_GEN_MEDIA_SUPPORTED, "OID_GEN_MEDIA_SUPPORTED", + OID_WWAN_DRIVER_CAPS, "OID_WWAN_DRIVER_CAPS", + OID_WWAN_DEVICE_CAPS, "OID_WWAN_DEVICE_CAPS", + OID_WWAN_READY_INFO, "OID_WWAN_READY_INFO", + OID_WWAN_RADIO_STATE, "OID_WWAN_RADIO_STATE", + OID_WWAN_PIN_EX, "OID_WWAN_PIN_EX", + OID_WWAN_PIN_LIST, "OID_WWAN_PIN_LIST", + OID_WWAN_HOME_PROVIDER, "OID_WWAN_HOME_PROVIDER", + OID_WWAN_PREFERRED_PROVIDERS, "OID_WWAN_PREFERRED_PROVIDERS", + OID_WWAN_VISIBLE_PROVIDERS, "OID_WWAN_VISIBLE_PROVIDERS", + OID_WWAN_REGISTER_STATE, "OID_WWAN_REGISTER_STATE", + OID_WWAN_PACKET_SERVICE, "OID_WWAN_PACKET_SERVICE", + OID_WWAN_SIGNAL_STATE, "OID_WWAN_SIGNAL_STATE", + OID_WWAN_CONNECT, "OID_WWAN_CONNECT", + OID_WWAN_PROVISIONED_CONTEXTS, "OID_WWAN_PROVISIONED_CONTEXTS", + OID_WWAN_SERVICE_ACTIVATION, "OID_WWAN_SERVICE_ACTIVATION", + OID_WWAN_ENUMERATE_DEVICE_SERVICES, "OID_WWAN_ENUMERATE_DEVICE_SERVICES", + OID_WWAN_DEVICE_SERVICE_COMMAND, "OID_WWAN_DEVICE_SERVICE_COMMAND", + OID_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS,"OID_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS", + OID_WWAN_SMS_CONFIGURATION, "OID_WWAN_SMS_CONFIGURATION", + OID_WWAN_SMS_READ, "OID_WWAN_SMS_READ", + OID_WWAN_SMS_SEND, "OID_WWAN_SMS_SEND", + OID_WWAN_SMS_DELETE, "OID_WWAN_SMS_DELETE", + OID_WWAN_SMS_STATUS, "OID_WWAN_SMS_STATUS", + OID_WWAN_VENDOR_SPECIFIC, "OID_WWAN_VENDOR_SPECIFIC", + OID_WWAN_USSD, "OID_WWAN_USSD", + OID_WWAN_AUTH_CHALLENGE, "OID_WWAN_AUTH_CHALLENGE", + OID_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS,"OID_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS", + OID_WWAN_DEVICE_SERVICE_SESSION, "OID_WWAN_DEVICE_SERVICE_SESSION", + OID_WWAN_DEVICE_SERVICE_SESSION_WRITE, "OID_WWAN_DEVICE_SERVICE_SESSION_WRITE", + OID_WWAN_DEVICE_SERVICE_SESSION_WRITE, "OID_WWAN_DEVICE_SERVICE_SESSION_WRITE", + OID_WWAN_CREATE_MAC, "OID_WWAN_CREATE_MAC", + OID_WWAN_DELETE_MAC, "OID_WWAN_DELETE_MAC", + OID_WWAN_UICC_FILE_STATUS, "OID_WWAN_UICC_FILE_STATUS", + OID_WWAN_UICC_ACCESS_BINARY, "OID_WWAN_UICC_ACCESS_BINARY", + OID_WWAN_UICC_ACCESS_RECORD, "OID_WWAN_UICC_ACCESS_RECORD", + OID_WWAN_PIN_EX2, "OID_WWAN_PIN_EX2", + OID_WWAN_MBIM_VERSION, "OID_WWAN_MBIM_VERSION", + OID_WWAN_SYS_CAPS, "OID_WWAN_SYS_CAPS", + OID_WWAN_DEVICE_CAPS_EX, "OID_WWAN_DEVICE_CAPS_EX", + OID_WWAN_SYS_SLOTMAPPINGS, "OID_WWAN_SYS_SLOTMAPPINGS", + OID_WWAN_SLOT_INFO_STATUS, "OID_WWAN_SLOT_INFO_STATUS", + OID_WWAN_DEVICE_BINDINGS, "OID_WWAN_DEVICE_BINDINGS", + OID_WWAN_REGISTER_STATE_EX, "OID_WWAN_REGISTER_STATE_EX", + OID_WWAN_IMS_VOICE_STATE, "OID_WWAN_IMS_VOICE_STATE", + OID_WWAN_SIGNAL_STATE_EX, "OID_WWAN_SIGNAL_STATE_EX", + OID_WWAN_LOCATION_STATE, "OID_WWAN_LOCATION_STATE", + OID_WWAN_NITZ, "OID_WWAN_NITZ", + OID_WWAN_NETWORK_IDLE_HINT, "OID_WWAN_NETWORK_IDLE_HINT", + OID_WWAN_PRESHUTDOWN, "OID_WWAN_PRESHUTDOWN", + OID_WWAN_UICC_ATR, "OID_WWAN_UICC_ATR", + OID_WWAN_UICC_OPEN_CHANNEL, "OID_WWAN_UICC_OPEN_CHANNEL", + OID_WWAN_UICC_CLOSE_CHANNEL, "OID_WWAN_UICC_CLOSE_CHANNEL", + OID_WWAN_UICC_APDU, "OID_WWAN_UICC_APDU", + OID_WWAN_UICC_TERMINAL_CAPABILITY, "OID_WWAN_UICC_TERMINAL_CAPABILITY", + OID_WWAN_SAR_CONFIG, "OID_WWAN_SAR_CONFIG", + OID_WWAN_SAR_TRANSMISSION_STATUS, "OID_WWAN_SAR_TRANSMISSION_STATUS", + OID_WWAN_LTE_ATTACH_CONFIG, "OID_WWAN_LTE_ATTACH_CONFIG", + OID_WWAN_LTE_ATTACH_STATUS, "OID_WWAN_LTE_ATTACH_STATUS", + OID_WWAN_NETWORK_BLACKLIST, "OID_WWAN_NETWORK_BLACKLIST", + OID_WWAN_UICC_RESET, "OID_WWAN_UICC_RESET", + OID_WWAN_DEVICE_RESET, "OID_WWAN_DEVICE_RESET", + OID_WWAN_UICC_APP_LIST, "OID_WWAN_UICC_APP_LIST", +}; + +const UINT NumOid = sizeof(OidList) / sizeof(Code2Ascii); + +const Code2Ascii IndicationList[] = +{ + NDIS_STATUS_WWAN_DEVICE_CAPS, "NDIS_STATUS_WWAN_DEVICE_CAPS", + NDIS_STATUS_WWAN_READY_INFO, "NDIS_STATUS_WWAN_READY_INFO", + NDIS_STATUS_WWAN_RADIO_STATE, "NDIS_STATUS_WWAN_RADIO_STATE", + NDIS_STATUS_WWAN_PIN_INFO, "NDIS_STATUS_WWAN_PIN_INFO", + NDIS_STATUS_WWAN_PIN_LIST, "NDIS_STATUS_WWAN_PIN_LIST", + NDIS_STATUS_WWAN_HOME_PROVIDER, "NDIS_STATUS_WWAN_HOME_PROVIDER", + NDIS_STATUS_WWAN_PREFERRED_PROVIDERS, "NDIS_STATUS_WWAN_PREFERRED_PROVIDERS", + NDIS_STATUS_WWAN_VISIBLE_PROVIDERS, "NDIS_STATUS_WWAN_VISIBLE_PROVIDERS", + NDIS_STATUS_WWAN_REGISTER_STATE, "NDIS_STATUS_WWAN_REGISTER_STATE", + NDIS_STATUS_WWAN_PACKET_SERVICE, "NDIS_STATUS_WWAN_PACKET_SERVICE", + NDIS_STATUS_WWAN_SIGNAL_STATE, "NDIS_STATUS_WWAN_SIGNAL_STATE", + NDIS_STATUS_WWAN_CONTEXT_STATE, "NDIS_STATUS_WWAN_CONTEXT_STATE", + NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, "NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS", + NDIS_STATUS_WWAN_SERVICE_ACTIVATION, "NDIS_STATUS_WWAN_SERVICE_ACTIVATION", + NDIS_STATUS_WWAN_SMS_CONFIGURATION, "NDIS_STATUS_WWAN_SMS_CONFIGURATION", + NDIS_STATUS_WWAN_SMS_RECEIVE, "NDIS_STATUS_WWAN_SMS_RECEIVE", + NDIS_STATUS_WWAN_SMS_SEND, "NDIS_STATUS_WWAN_SMS_SEND", + NDIS_STATUS_WWAN_SMS_DELETE, "NDIS_STATUS_WWAN_SMS_DELETE", + NDIS_STATUS_WWAN_SMS_STATUS, "NDIS_STATUS_WWAN_SMS_STATUS", + NDIS_STATUS_WWAN_DNS_ADDRESS, "NDIS_STATUS_WWAN_DNS_ADDRESS", + + NDIS_STATUS_WWAN_VENDOR_SPECIFIC, "NDIS_STATUS_WWAN_VENDOR_SPECIFIC", + + NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES, "NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES", + NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION", + NDIS_STATUS_WWAN_SET_HOME_PROVIDER_COMPLETE, "NDIS_STATUS_WWAN_SET_HOME_PROVIDER_COMPLETE", + NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE, "NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE", + NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT, "NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT", + NDIS_STATUS_WWAN_USSD, "NDIS_STATUS_WWAN_USSD", + NDIS_STATUS_WWAN_AUTH_RESPONSE, "NDIS_STATUS_WWAN_AUTH_RESPONSE", + NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS", + NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION", + NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE", + NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ", + NDIS_STATUS_WWAN_PRESHUTDOWN_STATE, "NDIS_STATUS_WWAN_PRESHUTDOWN_STATE", + NDIS_STATUS_WWAN_SYS_CAPS_INFO, "NDIS_STATUS_WWAN_SYS_CAPS_INFO", + NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO, "NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO", + NDIS_STATUS_WWAN_SLOT_INFO, "NDIS_STATUS_WWAN_SLOT_INFO", + NDIS_STATUS_WWAN_DEVICE_CAPS_EX, "NDIS_STATUS_WWAN_DEVICE_CAPS_EX", +}; + +const UINT NumIndications = sizeof(IndicationList) / sizeof(Code2Ascii); + +CHAR CommandStringTableBasic[MBB_BASIC_CID_MAXIMUM][48] = +{ + "BASIC_UNKNOWN_0", + "BASIC_DEVICE_CAPS", + "BASIC_SUBSCRIBER_READY_INFO", + "BASIC_RADIO_STATE", + "BASIC_PIN_INFO", + "BASIC_PIN_LIST", + "BASIC_HOME_PROVIDER", + "BASIC_PREFERRED_PROVIDERS", + "BASIC_VISIBLE_PROVIDERS", + "BASIC_REGISTER_STATE", + "BASIC_PACKET_SERVICE", + "BASIC_SIGNAL_STATE", + "BASIC_CONNECT", + "BASIC_PROVISIONED_CONTEXTS", + "BASIC_SERVICE_ACTIVATION", + "BASIC_IP_ADDRESS_INFO", + "BASIC_CID_DEVICE_SERVICES", + "BASIC_UNKNOWN_17", + "BASIC_UNKNOWN_18", + "BASIC_NOTIFY_DEVICE_SERVICE_UPDATES", + "BASIC_PACKET_STATISTICS", + "BASIC_NETWORK_IDLE_HINT", + "BASIC_EMERGENCY_MODE", + "BASIC_PACKET_FILTERS" +}; + +CHAR CommandStringTableSMS[MBB_SMS_CID_MAXIMUM][32] = +{ + "SMS_UNKNOWN", + "SMS_CONFIGURATION", + "SMS_READ", + "SMS_SEND", + "SMS_DELETE", + "SMS_STATUS" +}; + +CHAR CommandStringTableVendor[MBB_VENDOR_CID_MAXIMUM][32] = +{ + "VENDOR_UNKNOWN", + "VENDOR_MS_SPECIFIC", +}; + +CHAR CommandStringTableUSSD[MBB_USSD_CID_MAXIMUM][32] = +{ + "USSD_UNKNOWN", + "USSD_USSD" +}; + +CHAR CommandStringTablePhoneBook[MBB_PHONEBOOK_CID_MAXIMUM][32] = +{ + "PHONEBOOK_UNKNOWN", + "PHONEBOOK_CONFIGURATION", + "PHONEBOOK_READ", + "PHONEBOOK_DELETE", + "PHONEBOOK_SAVE" +}; + +CHAR CommandStringTableSAT[MBB_SAT_CID_MAXIMUM][32] = +{ + "SAT_UNKNOWN", + "SAT_PAC", + "SAT_TERMINAL_RESPONSE", + "SAT_ENVELOPE" +}; + + +CHAR CommandStringTableAuth[MBB_AUTH_CID_MAXIUM][32]= +{ + "AUTH_UNKNOWN", + "AUTH_AKA", + "AUTH_AKAP", + "AUTH_SIM" +}; + +CHAR CommandStringTableMulticarrier[MBB_MULTICARRIER_CID_MAXIMUM][32]= +{ + "MULTICARRIER_UNKNOWN", + "MULTICARRIER_CAPABILITIES", + "MULTICARRIER_LOCATION_INFO", + "MULTICARRIER_CURRENT_CID_LIST" +}; + +CHAR CommandStringTableDss[MBB_DSS_CID_MAXIUM][32]= +{ + "DSS_CID_UNKNOWN", + "DSS_CID_CONNECT" +}; + +CHAR CommandStringTableHostShutdown[MBB_HOSTSHUTDOWN_CID_MAX][32]= +{ + "HOSTSHUTDOWN_UNKNOWN", + "HOSTSHUTDOWN_CID_ONE", + "HOSTSHUTDOWN_CID_PRESHUTDOWN", +}; + +CHAR CommandStringTableUicc[MBB_UICC_CID_MAXIMUM][32] = +{ + "UICC_UNKNOWN", + "UICC_CID_ATR", + "UICC_CID_OPEN_CHANNEL", + "UICC_CID_CLOSE_CHANNEL", + "UICC_CID_APDU", + "UICC_CID_TERMINAL_CAPABILITY", + "UICC_CID_RESET" + "UICC_APP_LIST", + "UICC_FILE_STATUS", + "UICC_ACCESS_BINARY", + "UICC_ACCESS_RECORD", +}; + +CHAR CommandStringTableSar[MBB_SAR_CID_MAXIMUM][32] = +{ + "SAR_UNKNOWN", + "SAR_CONFIG", + "SAR_TRANSMISSION_STATUS" +}; + +CHAR CommandStringTableBasicExt[MBB_BASICCONNECTEXT_CID_MAXIMUM][32] = +{ + "BASICEXT_UNKNOWN", + "BASICEXT_PROVISIONED_CONTEXT_V2", + "BASICEXT_NETWORK_BLACKLIST", + "BASICEXT_LTE_ATTACH_CONFIG", + "BASICEXT_LTE_ATTACH_STATUS", + "BASICEXT_CID_SYS_CAPS", + "BASICEXT_CID_DEVICE_CAPS_V2", + "BASICEXT_CID_SLOT_MAPPINGS", + "BASICEXT_CID_SLOT_INFO_STATUS", + "BASICEXT_CID_PCO", + "BASICEXT_CID_DEVICE_RESET" +}; + + +//////////////////////////////////////////////////////////////////////////////// +// +// PROTOTYPES +// +//////////////////////////////////////////////////////////////////////////////// + +// +// FRAGMENT ROUTINES +// + +NTSTATUS +MbbUtilBusSendMessageFragment( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_HANDLE FragmentBufferHandle, + __in PVOID MessageFragment, + __in ULONG FragmentLength + ); + +VOID +MbbUtilSendMessageFragmentComplete( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in MBB_REQUEST_HANDLE RequestHandle, + __in NTSTATUS NtStatus + ); + +// +// WORK ITEM +// + +__drv_sameIRQL +__drv_functionClass(KSTART_ROUTINE) +VOID +MbbWorkMgrProcessWorkItem( + __in PVOID StartContext + ); + + + + +//////////////////////////////////////////////////////////////////////////////// +// +// IMPLEMENTATION +// +//////////////////////////////////////////////////////////////////////////////// + +/****************************************************************************/ +/* GetOidName */ +/****************************************************************************/ +/* */ +/* Routine Description: */ +/* */ +/* Returns string with OID name */ +/* */ +/* Arguments: */ +/* */ +/* Oid - OID to find */ +/* */ +/* Return: */ +/* */ +/* PCHAR */ +/* */ +/****************************************************************************/ +PCSTR +GetOidName( + __in NDIS_OID Oid + ) +{ + UINT Index; + + // + // see if the matching Oid and string are in the list + // + for(Index = 0; Index < NumOid; Index++) + { + if(Oid == OidList[Index].Oid) + { + return OidList[Index].OidName; + } + } + +// TraceWarn(WMBCLASS_OID, " unknown OID %08lx", Oid); + + return "Unknown OID"; + +} // GetOidName + +BOOLEAN +IsSameGuid(GUID * pgGuid1, GUID *pgGuid2) +{ + ASSERT (pgGuid1); + ASSERT(pgGuid2); + + return (!memcmp(pgGuid1, pgGuid2, sizeof(GUID))); +} + +BOOLEAN +IsZeroGuid( + __in GUID* pGuid + ) +{ + GUID ZeroGuid = {0}; + return IsSameGuid(pGuid,&ZeroGuid);; +} + +PCSTR +MbbUtilGetWwanIndicationString( + __in NDIS_STATUS Indication + ) +{ + UINT Index; + + // + // see if the matching Oid and string are in the list + // + for(Index = 0; Index < NumOid; Index++) + { + if(Indication == IndicationList[Index].Oid) + { + return OidList[Index].OidName; + } + } + +// TraceWarn(WMBCLASS_OID, " unknown OID %08lx", Oid); + + return "Unknown Indication"; + +} // GetOidName + + + +/****************************************************************************/ +/* GetDeviceFriendlyName */ +/****************************************************************************/ +/* */ +/* Routine Description: */ +/* */ +/* Return the friendly name associated with the given Adapter. */ +/* */ +/* Arguments: */ +/* */ +/* MiniportAdapterHandle - NDIS context for the adapter */ +/* */ +/* Return: */ +/* */ +/* NTSTATUS */ +/* */ +/****************************************************************************/ +NDIS_STATUS +GetDeviceFriendlyName( + __in NDIS_HANDLE MiniportAdapterHandle, + __out PANSI_STRING AnsiName + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + NTSTATUS NtStatus; + UNICODE_STRING UnicodeString = {0, 0, NULL}; + ANSI_STRING AnsiString = {0, 0, NULL}; + USHORT AnsiMaxLength; + + + + do + { + RtlInitAnsiString(AnsiName,NULL); + + Status = NdisMQueryAdapterInstanceName(&UnicodeString, MiniportAdapterHandle); + + if (Status != NDIS_STATUS_SUCCESS) + { + break; + } + + // + // Allocate space for ANSI version. + // + AnsiMaxLength = UnicodeString.MaximumLength+sizeof(WCHAR) / sizeof(WCHAR); + + AnsiString.Buffer = ALLOCATE_NONPAGED_POOL( AnsiMaxLength ); + + if (AnsiString.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + AnsiString.MaximumLength = AnsiMaxLength; + AnsiString.Length = 0; + RtlZeroMemory(AnsiString.Buffer, AnsiString.MaximumLength); + + NtStatus = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); + + if (!NT_SUCCESS(NtStatus)) + { + ASSERT(FALSE); + Status = NDIS_STATUS_FAILURE; + break; + } + + *AnsiName = AnsiString; + AnsiString.Buffer=NULL; + Status = NDIS_STATUS_SUCCESS; + + break; + } + while (FALSE); + + if (UnicodeString.Buffer != NULL) + { + NdisFreeMemory(UnicodeString.Buffer, 0, 0); + } + + if (AnsiString.Buffer != NULL) + { + FREE_POOL(AnsiString.Buffer); + } + + + return (Status); +} + + +VOID +FreeAdapterBlock( + _In_ __drv_freesMem(Mem) PMINIPORT_ADAPTER_CONTEXT Adapter + ) + +{ + ULONG i; + + if ( Adapter != NULL) + { + ShutdownAdapterStateObject(&Adapter->AdapterState); + + FreeDeviceServiceState(&Adapter->DeviceServiceState); + + if (Adapter->FriendlyName.Buffer != NULL) + { + FREE_POOL(Adapter->FriendlyName.Buffer); + Adapter->FriendlyName.Buffer=NULL; + } + + if (Adapter->BusHandle != NULL) + { + MbbBusCleanup(Adapter->BusHandle); + Adapter->BusHandle=NULL; + } + + if (Adapter->PowerFilterTable != NULL) + { + + for (i=0; iBusParams.PowerFiltersSupported; i++) + { + if (Adapter->PowerFilterTable[i].InUse) + { + // all the WOL patterns should have been removed by now + ASSERT(FALSE); + + FREE_POOL(Adapter->PowerFilterTable[i].Mask); + Adapter->PowerFilterTable[i].Mask=NULL; + FREE_POOL(Adapter->PowerFilterTable[i].Pattern); + Adapter->PowerFilterTable[i].Pattern=NULL; + } + } + + FREE_POOL(Adapter->PowerFilterTable); + Adapter->PowerFilterTable=NULL; + + } + + NdisFreeSpinLock(&Adapter->PortsLock); + + NdisFreeSpinLock(&Adapter->SessionIdPortTableLock); + + FREE_POOL(Adapter); + Adapter=NULL; + } + + return; +} + +PCHAR +MbbUtilGetCommandString( + __in PMBB_COMMAND Command + ) +{ + if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_BASIC_CONNECT, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_BASIC_CID_MAXIMUM ) + return CommandStringTableBasic[0]; + else + return CommandStringTableBasic[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_SMS, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_SMS_CID_MAXIMUM ) + return CommandStringTableSMS[0]; + else + return CommandStringTableSMS[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_USSD, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_USSD_CID_MAXIMUM ) + return CommandStringTableUSSD[0]; + else + return CommandStringTableUSSD[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_PHONEBOOK, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_PHONEBOOK_CID_MAXIMUM ) + return CommandStringTablePhoneBook[0]; + else + return CommandStringTablePhoneBook[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_SAT, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_SAT_CID_MAXIMUM ) + return CommandStringTableSAT[0]; + else + return CommandStringTableSAT[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_MS_VENDOR_EXTENSION, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_VENDOR_CID_MAXIMUM ) + return CommandStringTableVendor[0]; + else + return CommandStringTableVendor[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_AUTH, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_AUTH_CID_MAXIUM) + return CommandStringTableAuth[0]; + else + return CommandStringTableAuth[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_MULTICARRIER, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_MULTICARRIER_CID_MAXIMUM) + return CommandStringTableMulticarrier[0]; + else + return CommandStringTableMulticarrier[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_DSS, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_DSS_CID_MAXIUM) + return CommandStringTableDss[0]; + else + return CommandStringTableDss[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_HOSTSHUTDOWN, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_HOSTSHUTDOWN_CID_MAX) + return CommandStringTableHostShutdown[0]; + else + return CommandStringTableHostShutdown[Command->CommandId]; + } + else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_UICC_LOW_LEVEL, sizeof(GUID) ) == sizeof(GUID) ) + { + if( Command->CommandId >= MBB_UICC_CID_MAXIMUM) + return CommandStringTableUicc[0]; + else + return CommandStringTableUicc[Command->CommandId]; + } + else if (RtlCompareMemory(&Command->ServiceId, &MBB_UUID_SARCONTROL, sizeof(GUID)) == sizeof(GUID)) + { + if (Command->CommandId >= MBB_SAR_CID_MAXIMUM) + return CommandStringTableSar[0]; + else + return CommandStringTableSar[Command->CommandId]; + } + else if (RtlCompareMemory(&Command->ServiceId, &MBB_UUID_BASIC_CONNECT_EXTENSIONS, sizeof(GUID)) == sizeof(GUID)) + { + if (Command->CommandId >= MBB_BASICCONNECTEXT_CID_MAXIMUM) + return CommandStringTableBasicExt[0]; + else + return CommandStringTableBasicExt[Command->CommandId]; + } + else + { + return "UNKNOWN"; + } +} + +BOOLEAN +MbbUtilIsBasicCommand( + __in PMBB_COMMAND Command + ) +{ + if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_BASIC_CONNECT, sizeof(GUID) ) == sizeof(GUID) ) + return TRUE; + else + return FALSE; +} + +BOOLEAN +MbbUtilIsValidDeviceService( + __in GUID* DeviceServiceGuid + ) +{ + // We could check list of supported services. However we only do one check + + if(RtlCompareMemory( &DeviceServiceGuid, &MBB_UUID_INVALID, sizeof(GUID) ) == sizeof(GUID) ) + { + return FALSE; + } + + return TRUE; +} + + +// +// ALLOCATOR +// + +__drv_allocatesMem(Mem) +__drv_aliasesMem +PVOID +MbbAllocMgrInitialize( + __in ULONG AllocationSize, + __in ULONG AllocationCount, + __in ULONG PoolTag, + __in MBB_ALLOC_FLAGS Flags + ) +{ + ULONG i; + PMBB_ALLOC_MANAGER AllocMgr; + PMBB_ALLOC_ENTRY AllocEntry; + + if( (AllocMgr = (PMBB_ALLOC_MANAGER) ALLOCATE_NONPAGED_POOL(sizeof(MBB_ALLOC_MANAGER))) == NULL ) + { + return NULL; + } + + NdisAllocateSpinLock( &AllocMgr->Lock ); + + NdisInitializeNPagedLookasideList( + &AllocMgr->LookasideList, + NULL, // allocate function + NULL, // free function + 0, // Flags + AllocationSize + sizeof(MBB_ALLOC_ENTRY), + PoolTag, + 0 // Depth + ); + + InitializeListHead( &AllocMgr->AllocatedList ); + InitializeListHead( &AllocMgr->PreAllocatedFreeList ); + + AllocMgr->Flags.Value = Flags.Value; + + for( i = 0; + i < AllocationCount; + i ++ ) + { + if( (AllocEntry = (PMBB_ALLOC_ENTRY) NdisAllocateFromNPagedLookasideList( &AllocMgr->LookasideList )) == NULL ) + { + break; + } + AllocEntry->AllocMgr = AllocMgr; + AllocEntry->IsPreAllocated = TRUE; + + InsertTailList( &AllocMgr->AllocatedList, &AllocEntry->TrackLink ); + InsertTailList( &AllocMgr->PreAllocatedFreeList, &AllocEntry->FreeLink ); + } + + if( i < AllocationCount ) + { + MbbAllocMgrCleanup( AllocMgr ); + AllocMgr = NULL; + } + + return AllocMgr; +} + +VOID +MbbAllocMgrCleanup( + __in __drv_freesMem(Mem) PVOID AllocMgrHandle + ) +/*++ + Description + The function assumes that all entries are already freed. +--*/ +{ + PLIST_ENTRY ListEntry; + PLIST_ENTRY NextEntry; + PMBB_ALLOC_MANAGER AllocMgr = (PMBB_ALLOC_MANAGER) AllocMgrHandle; + PMBB_ALLOC_ENTRY AllocEntry; + + NdisAcquireSpinLock( &AllocMgr->Lock ); + + for( ListEntry = AllocMgr->PreAllocatedFreeList.Flink; + ListEntry != &AllocMgr->PreAllocatedFreeList; + ListEntry = NextEntry ) + { + NextEntry = ListEntry->Flink; + AllocEntry = CONTAINING_RECORD( ListEntry, MBB_ALLOC_ENTRY, FreeLink ); + RemoveEntryList( &AllocEntry->FreeLink ); + RemoveEntryList( &AllocEntry->TrackLink ); + NdisFreeToNPagedLookasideList( &AllocMgr->LookasideList, AllocEntry ); + } + + ASSERT( IsListEmpty( &AllocMgr->AllocatedList ) ); + + NdisReleaseSpinLock( &AllocMgr->Lock ); + + NdisDeleteNPagedLookasideList( &AllocMgr->LookasideList ); + NdisFreeSpinLock( &AllocMgr->Lock ); + + FREE_POOL( AllocMgr ); +} + +PVOID +MbbAllocMgrAllocate( + __in PVOID AllocMgrHandle + ) +{ + PLIST_ENTRY ListEntry; + PVOID AllocHandle = NULL; + PMBB_ALLOC_MANAGER AllocMgr = (PMBB_ALLOC_MANAGER) AllocMgrHandle; + PMBB_ALLOC_ENTRY AllocEntry = NULL; + + NdisAcquireSpinLock( &AllocMgr->Lock ); + + // MbbAllocMgrFree puts the free entry to the head of the list, here we just allocate from the tail of the list + if( (ListEntry = RemoveTailList( &AllocMgr->PreAllocatedFreeList )) != &AllocMgr->PreAllocatedFreeList ) + { + AllocEntry = CONTAINING_RECORD( ListEntry, MBB_ALLOC_ENTRY, FreeLink ); + } + else if( AllocMgr->Flags.NoPostAllocation == 0 ) + { + if( (AllocEntry = (PMBB_ALLOC_ENTRY) NdisAllocateFromNPagedLookasideList( &AllocMgr->LookasideList )) != NULL ) + { + AllocEntry->AllocMgr = AllocMgr; + AllocEntry->IsPreAllocated = FALSE; + + InsertTailList( &AllocMgr->AllocatedList, &AllocEntry->TrackLink ); + } + } + + NdisReleaseSpinLock( &AllocMgr->Lock ); + + if( AllocEntry != NULL ) + AllocHandle = AllocEntry + 1; + + return AllocHandle; +} + +VOID +MbbAllocMgrFree( + __in PVOID AllocHandle + ) +{ + PLIST_ENTRY ListEntry; + PMBB_ALLOC_ENTRY AllocEntry = ((PMBB_ALLOC_ENTRY)AllocHandle) - 1; + #pragma prefast(suppress: 26001, "Accessing abstracted header.") + PMBB_ALLOC_MANAGER AllocMgr = AllocEntry->AllocMgr; + + NdisAcquireSpinLock( &AllocMgr->Lock ); + + if( AllocEntry->IsPreAllocated ) + { + InsertHeadList( &AllocMgr->PreAllocatedFreeList, &AllocEntry->FreeLink ); + } + else + { + RemoveEntryList( &AllocEntry->TrackLink ); + NdisFreeToNPagedLookasideList( &AllocMgr->LookasideList, AllocEntry ); + } + + NdisReleaseSpinLock( &AllocMgr->Lock ); +} + + +// +// BUFFER MANAGER +// + +__drv_allocatesMem(Mem) +__drv_aliasesMem +PVOID +MbbBufMgrInitialize( + __in ULONG BufferCount, + __in ULONG BufferLength + ) +{ + PMBB_BUFFER_MANAGER BufferManager; + MBB_ALLOC_FLAGS AllocFlags = { 0 }; + + if( (BufferManager = (PMBB_BUFFER_MANAGER) ALLOCATE_NONPAGED_POOL( sizeof(MBB_BUFFER_MANAGER) )) == NULL ) + { + return NULL; + } + BufferManager->BufferLength = BufferLength; + + AllocFlags.NoPostAllocation = 1; + + if( (BufferManager->AllocMgrHandle = MbbAllocMgrInitialize( + BufferLength + sizeof(MBB_BUFFER_CONTEXT), + BufferCount, + MbbPoolTagDefault, + AllocFlags + )) == NULL ) + { + TraceError( WMBCLASS_UTIL, "[BufMgr] FAILED to initialize allocation manager" ); + MbbBufMgrCleanup( BufferManager ); + BufferManager = NULL; + } + + return BufferManager; +} + +VOID +MbbBufMgrCleanup( + __in __drv_freesMem(Mem) PVOID ManagerHandle + ) +{ + PMBB_BUFFER_MANAGER BufferManager = (PMBB_BUFFER_MANAGER)ManagerHandle; + + if( BufferManager->AllocMgrHandle != NULL ) + MbbAllocMgrCleanup( BufferManager->AllocMgrHandle ); + + FREE_POOL( BufferManager ); +} + +PVOID +MbbBufMgrAllocateBuffer( + __in PVOID ManagerHandle + ) +{ + PVOID BufferHandle = NULL; + PMBB_BUFFER_MANAGER BufferManager = (PMBB_BUFFER_MANAGER)ManagerHandle; + PMBB_BUFFER_CONTEXT BufferEntry = NULL; + + if( (BufferEntry = (PMBB_BUFFER_CONTEXT) MbbAllocMgrAllocate( BufferManager->AllocMgrHandle )) != NULL ) + { + BufferEntry->BufferManager = BufferManager; + BufferHandle = BufferEntry + 1; + } + return BufferHandle; +} + +VOID +MbbBufMgrFreeBuffer( + __in PVOID BufferHandle + ) +{ + PMBB_BUFFER_CONTEXT BufferEntry = ((PMBB_BUFFER_CONTEXT)BufferHandle) - 1; + + MbbAllocMgrFree( BufferEntry ); +} + +FORCEINLINE +ULONG +MbbBufMgrGetBufferLength( + __in PVOID BufferHandle + ) +{ + PMBB_BUFFER_CONTEXT BufferEntry = ((PMBB_BUFFER_CONTEXT)BufferHandle) - 1; + + #pragma prefast(suppress: 26001, "Accessing abstracted header.") + return BufferEntry->BufferManager->BufferLength; +} + +FORCEINLINE +VOID +MbbBufMgrSetBufferContext( + __in PVOID BufferHandle, + __in PVOID Context + ) +{ + PMBB_BUFFER_CONTEXT BufferEntry = ((PMBB_BUFFER_CONTEXT)BufferHandle) - 1; + + #pragma prefast(suppress: 26001, "Accessing abstracted header.") + BufferEntry->OwnerContext = Context; +} + +FORCEINLINE +PVOID +MbbBufMgrGetBufferContext( + __in PVOID BufferHandle + ) +{ + PMBB_BUFFER_CONTEXT BufferEntry = ((PMBB_BUFFER_CONTEXT)BufferHandle) - 1; + + #pragma prefast(suppress: 26001, "Accessing abstracted header.") + return BufferEntry->OwnerContext; +} + + +// +// WORK ITEMS +// + +__drv_allocatesMem(Mem) +__drv_aliasesMem +PVOID +MbbWorkMgrInitialize( + __in ULONG InitialWorkItemCount + ) +{ + BOOLEAN Success = FALSE; + NTSTATUS NtStatus; + PMBB_WORKITEM_MANAGER WorkItemManager; + MBB_ALLOC_FLAGS AllocFlags = { 0 }; + + do + { + if( (WorkItemManager = (PMBB_WORKITEM_MANAGER) ALLOCATE_NONPAGED_POOL( sizeof(MBB_WORKITEM_MANAGER) )) == NULL ) + { + TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to allocate work item manager" ); + break; + } + + InitializeListHead( &WorkItemManager->WorkItemQueue ); + + NdisAllocateSpinLock( &WorkItemManager->Lock ); + + KeInitializeEvent( + &(WorkItemManager->WorkItemEvent), + NotificationEvent, + FALSE + ); + KeInitializeEvent( + &(WorkItemManager->ThreadExitEvent), + NotificationEvent, + FALSE + ); + WorkItemManager->ThreadHandle = NULL; + + if( (WorkItemManager->AllocMgrHandle = MbbAllocMgrInitialize( + sizeof(MBB_WORKITEM_ENTRY), + InitialWorkItemCount, + MbbPoolTagDefault, + AllocFlags + )) == NULL ) + { + TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to initialize allocation manager" ); + break; + } + + NtStatus = PsCreateSystemThread( + &(WorkItemManager->ThreadHandle), + STANDARD_RIGHTS_REQUIRED, + NULL, + NULL, + NULL, + MbbWorkMgrProcessWorkItem, + WorkItemManager + ); + if( ! NT_SUCCESS( NtStatus ) ) + { + TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to create worker thread, status=%!status!", NtStatus ); + break; + } + Success = TRUE; + } + while( FALSE ); + + if( !Success && WorkItemManager ) + { + MbbWorkMgrCleanup( WorkItemManager ); + WorkItemManager = NULL; + } + return WorkItemManager; +} + +VOID +MbbWorkMgrCleanup( + __in __drv_freesMem(Mem) PVOID WorkItemManagerHandle + ) +{ + NTSTATUS NtStatus; + PMBB_WORKITEM_MANAGER WorkItemManager = (PMBB_WORKITEM_MANAGER)WorkItemManagerHandle; + PVOID ThreadObject; + + // + // Ask the event thread to cleanup and exit. + // + NdisAcquireSpinLock( &WorkItemManager->Lock ); + KeSetEvent( &WorkItemManager->ThreadExitEvent, IO_NO_INCREMENT, FALSE ); + NdisReleaseSpinLock( &WorkItemManager->Lock ); + TraceInfo( WMBCLASS_UTIL, "[WorkMgr] Waiting for worker thread to exit" ); + // + // Wait for the worker thread to exit + // + if( WorkItemManager->ThreadHandle != NULL ) + { + NtStatus = ObReferenceObjectByHandle( + WorkItemManager->ThreadHandle, + STANDARD_RIGHTS_REQUIRED, + *PsThreadType, + KernelMode, + &ThreadObject, + NULL + ); + if( NT_SUCCESS( NtStatus ) ) + { + NtStatus = KeWaitForSingleObject( + ThreadObject, + Executive, + KernelMode, + TRUE, + NULL + ); + if( NtStatus != STATUS_WAIT_0 ) + { + TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to wait for worker thread with status=%!status!", NtStatus ); + } + ObDereferenceObject( ThreadObject ); + } + else + { + TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to reference worker thread with status=%!status!", NtStatus ); + } + ZwClose( WorkItemManager->ThreadHandle ); + } + + ASSERT( IsListEmpty( &WorkItemManager->WorkItemQueue ) ); + + if( WorkItemManager->AllocMgrHandle != NULL ) + MbbAllocMgrCleanup( WorkItemManager->AllocMgrHandle ); + + NdisFreeSpinLock( &WorkItemManager->Lock ); + + FREE_POOL( WorkItemManager ); +} + +NDIS_STATUS +MbbWorkMgrQueueWorkItem( + __in PVOID WorkItemManagerHandle, + __in_opt PVOID Context1, + __in_opt PVOID Context2, + __in_opt PVOID Context3, + __in_opt PVOID Context4, + __in MBB_WORKITEM_ROUTINE Routine + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_RESOURCES; + PMBB_WORKITEM_ENTRY WorkItemEntry = NULL; + PMBB_WORKITEM_MANAGER WorkItemManager = (PMBB_WORKITEM_MANAGER)WorkItemManagerHandle; + + if( (WorkItemEntry = MbbAllocMgrAllocate( WorkItemManager->AllocMgrHandle )) != NULL ) + { + WorkItemEntry->Context1 = Context1; + WorkItemEntry->Context2 = Context2; + WorkItemEntry->Context3 = Context3; + WorkItemEntry->Context4 = Context4; + WorkItemEntry->Routine = Routine; + + NdisAcquireSpinLock( &WorkItemManager->Lock ); + InsertTailList( &WorkItemManager->WorkItemQueue, &WorkItemEntry->QueueLink ); + KeSetEvent( &WorkItemManager->WorkItemEvent, IO_NO_INCREMENT, FALSE ); + NdisReleaseSpinLock( &WorkItemManager->Lock ); + NdisStatus = NDIS_STATUS_SUCCESS; + } + + return NdisStatus; +} + +__drv_sameIRQL +__drv_functionClass(KSTART_ROUTINE) +KSTART_ROUTINE MbbWorkMgrProcessWorkItem; + +__drv_sameIRQL +__drv_functionClass(KSTART_ROUTINE) +VOID +MbbWorkMgrProcessWorkItem( + __in PVOID StartContext + ) +{ + NTSTATUS NtStatus; + PKEVENT EventArray[2]; + LIST_ENTRY ListHead; + PLIST_ENTRY ListEntry; + PMBB_WORKITEM_ENTRY WorkItemEntry; + PMBB_WORKITEM_MANAGER WorkItemManager = (PMBB_WORKITEM_MANAGER)StartContext; + + EventArray[0] = &(WorkItemManager->ThreadExitEvent); + EventArray[1] = &(WorkItemManager->WorkItemEvent); + + while( TRUE ) + { + NtStatus = KeWaitForMultipleObjects( + 2, + EventArray, + WaitAny, + Executive, + KernelMode, + TRUE, + NULL, + NULL + ); + if( NtStatus == STATUS_WAIT_0 ) + { + // + // Thread exit + // + break; + } + else if( NtStatus == STATUS_WAIT_1 ) + { + InitializeListHead( &ListHead ); + NdisAcquireSpinLock( &WorkItemManager->Lock ); + InsertTailList( &WorkItemManager->WorkItemQueue, &ListHead ); + RemoveEntryList( &WorkItemManager->WorkItemQueue ); + InitializeListHead( &WorkItemManager->WorkItemQueue ); + KeResetEvent( &WorkItemManager->WorkItemEvent ); + NdisReleaseSpinLock( &WorkItemManager->Lock ); + + for( ListEntry = RemoveHeadList( &ListHead ); + ListEntry != &ListHead; + ListEntry = RemoveHeadList( &ListHead ) ) + { + WorkItemEntry = CONTAINING_RECORD( ListEntry, MBB_WORKITEM_ENTRY, QueueLink ); + + WorkItemEntry->Routine( + WorkItemEntry->Context1, + WorkItemEntry->Context2, + WorkItemEntry->Context3, + WorkItemEntry->Context4 + ); + + MbbAllocMgrFree( WorkItemEntry ); + } + } + } + PsTerminateSystemThread( STATUS_SUCCESS ); +} + + +// +// CID MESSAGE FRAGMENTS +// + + +NDIS_STATUS +MbbUtilSetupCommandMessage( + __in PMBB_REQUEST_CONTEXT Request, + __in PMBB_COMMAND Command, + __in MBB_COMMAND_TYPE CommandType, + __in_bcount_opt(InputBufferLength) PUCHAR InputBuffer, + __in ULONG InputBufferLength + ) +{ + ULONG FragmentCount; + ULONG FragmentDataLength; + ULONG FragmentLength; + NTSTATUS NtStatus; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + do + { + // + // OS supported commands are sent over the control pipe. + // + FragmentLength = Request->RequestManager->Fragmentation.ControlFragmentLength; + FragmentDataLength = FragmentLength; + + // + // Query the amount of fragment buffers required for the command message. + // + FragmentCount = 0; + + if( (NtStatus = MbbLibFragmentBufferToCommandMessages( + Command, + CommandType, + InputBuffer, + InputBufferLength, + &Request->TransactionId, + 0, // StartingFragment + &FragmentCount, + &FragmentDataLength, + NULL // FragmentBuffers + )) != STATUS_SUCCESS ) + { + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + Request->HandlerContext.Command.Data = InputBuffer; + Request->HandlerContext.Command.DataLength = InputBufferLength; + Request->HandlerContext.Command.Command = *Command; + Request->HandlerContext.Command.CommandType = CommandType; + Request->HandlerContext.Command.FragmentCount = FragmentCount; + Request->HandlerContext.Command.FragmentLength = FragmentLength; + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilSendMessageFragmentsAndLog( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + PCHAR CommandName = MbbUtilGetCommandString(&(Request->HandlerContext.Command.Command)); + NTSTATUS Status = STATUS_SUCCESS; + LPGUID ActivityId = NULL; + MBB_MESSAGE_TYPE MessageType = MBB_MESSAGE_TYPE_COMMAND; + ULONG MessageLength = Request->HandlerContext.Command.DataLength + sizeof(MBB_COMMAND_HEADER); + DWORD TotalFragments = 1; + DWORD CurrentFragment = 0; + + // Create an activity Id to be associated with this message + // This activity Id will be associated with the USB IRP for sending + // this message so that we can associate USB traces with our traces. + // Also note that there is one activity Id for sending all the fragments + // of a message. + + Status = MbbEventActivityIdCtl(&(Request->ActivityId)); + + if(NT_SUCCESS(Status)) + { + ActivityId = &(Request->ActivityId); + } + + // Etw Trace send + MbbWriteEvent( + &CID_COMMAND_SEND, + ActivityId, + NULL, + 7, + &(Request->OidContext.OidRequestId), + sizeof(Request->OidContext.OidRequestId), + &(Request->RequestId), + sizeof(ULONG), + &(Request->HandlerContext.Command.Command.ServiceId), + sizeof(GUID), + CommandName, + strlen(CommandName) + 1, + &(Request->HandlerContext.Command.Command.CommandId), + sizeof(ULONG), + &(Request->HandlerContext.Command.DataLength), + sizeof(ULONG), + Request->HandlerContext.Command.Data, + Request->HandlerContext.Command.DataLength + ); + + // Etw Trace for MBB OPN. Log an event that renders the entire MBIM message + MbbWriteEventOpn( + &COMMAND_MSG, + ActivityId, + NULL, + 10, + &MessageType, + sizeof(MessageType), + &MessageLength, + sizeof(MessageLength), + &(Request->TransactionId), + sizeof(Request->TransactionId), + &TotalFragments, + sizeof(TotalFragments), + &CurrentFragment, + sizeof(CurrentFragment), + &(Request->HandlerContext.Command.Command.ServiceId), + sizeof(Request->HandlerContext.Command.Command.ServiceId), + &(Request->HandlerContext.Command.Command.CommandId), + sizeof(Request->HandlerContext.Command.Command.CommandId), + &(Request->HandlerContext.Command.CommandType), + sizeof(Request->HandlerContext.Command.CommandType), + &(Request->HandlerContext.Command.DataLength), + sizeof(Request->HandlerContext.Command.DataLength), + Request->HandlerContext.Command.Data, + Request->HandlerContext.Command.DataLength + ); + + return MbbUtilSendMessageFragments( Request ); +} + + +NDIS_STATUS +MbbUtilSendMessageFragments( + __in PMBB_REQUEST_CONTEXT Request + ) +/*++ + Synchronization: + Fields updated by the SendCompletion routine + and the Send routine are protected by the + RequestManager lock e.g. NextFrameIndex. + + Some fields are static and need no protection + e.g. FragmentCount. + + At any time only one instance of the Send + routine is processing fragments since the + routines are synchronized by the RequestManager lock. + + Return Value: + NDIS_STATUS_SUCCESS + Successfully sent all fragments, SendComplete event is queued to the request. + NDIS_STATUS_FAILURE + Failed to send all fragments, SendComplete event is queued to the request. + NDIS_STATUS_PENDING + SendComplete event will be queued later. +--*/ +{ + ULONG FragmentIndex; + ULONG FragmentLength; + ULONG FragmentCount; + ULONG FragmentSentCount; + ULONG FragmentBufferCount; + PVOID BufferManagerHandle; + PCHAR FragmentBuffer; + NTSTATUS NtStatus; + NDIS_STATUS NdisStatus; + PMBB_REQUEST_MANAGER RequestManager; + + // + // Cache values for easy access. + // + RequestManager = Request->RequestManager; + BufferManagerHandle = RequestManager->Fragmentation.BufferManager; + FragmentCount = Request->HandlerContext.Command.FragmentCount; + // + // Synchronize with other instances of the same routine + // invoked from completion handlers. + // + MbbReqMgrLockManager( RequestManager ); + if( Request->HandlerContext.Command.IsProcessing == TRUE ) + { + MbbReqMgrUnlockManager( RequestManager ); + return NDIS_STATUS_PENDING; + } + Request->HandlerContext.Command.IsProcessing = TRUE; + // + // If some fragments failed to be sent then no point + // sending more. Fail the request right away. + // + FragmentSentCount = 0; + NdisStatus = Request->HandlerContext.Command.SendStatus; + + for( FragmentIndex = Request->HandlerContext.Command.NextFragmentIndex; + FragmentIndex < FragmentCount && NdisStatus == NDIS_STATUS_SUCCESS; + FragmentIndex ++ ) + { + // + // Allocate fragment buffer. If there are no buffers then wait + // for the SendCompletion routine to return the buffers. + // + if( (FragmentBuffer= MbbBufMgrAllocateBuffer( BufferManagerHandle )) == NULL ) + { + // + // If the first fragment couldnt be sent then fail the send. + // This should never happen, this is an indication of a buffer leak. + // + if( FragmentIndex == 0 ) + { + ASSERT( FragmentBuffer != NULL ); + NdisStatus = NDIS_STATUS_RESOURCES; + } + break; + } + // + // Format fragments one at a time. + // + FragmentLength = Request->HandlerContext.Command.FragmentLength; + FragmentBufferCount = 1; + + ASSERT( FragmentLength <= MbbBufMgrGetBufferLength( FragmentBuffer ) ); + + NtStatus = MbbLibFragmentBufferToCommandMessages( + &Request->HandlerContext.Command.Command, + Request->HandlerContext.Command.CommandType, + Request->HandlerContext.Command.Data, + Request->HandlerContext.Command.DataLength, + &Request->TransactionId, + FragmentIndex, + &FragmentBufferCount, + &FragmentLength, + &FragmentBuffer + ); + if( NtStatus != STATUS_SUCCESS && + NtStatus != STATUS_MORE_PROCESSING_REQUIRED ) + { + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + // + // Ensure library formatted the data correctly + // + ASSERT( FragmentBufferCount == 1 ); + ASSERT( FragmentLength <= Request->HandlerContext.Command.FragmentLength ); + // + // Save context required by the completion handler. + // + MbbBufMgrSetBufferContext( FragmentBuffer, Request ); + // + // Call the wrapper that will sent the fragment over the control or bulk pipe. + // Drop the lock before calling in to the bus layer. + // + MbbReqMgrUnlockManager( RequestManager ); + + NtStatus = MbbUtilBusSendMessageFragment( + Request, + (MBB_REQUEST_HANDLE)FragmentBuffer, + FragmentBuffer, + FragmentLength + ); + if( NtStatus != STATUS_PENDING ) + { + MbbBufMgrFreeBuffer( FragmentBuffer ); + } + + if( NtStatus == STATUS_SUCCESS ) + { + TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x][TID=0x%08x] Sent Fragment %02d/%02d", + Request->RequestId, Request->TransactionId, FragmentIndex, FragmentCount + ); + FragmentSentCount++; + } + else if( NtStatus != STATUS_PENDING ) + { + TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x][TID=0x%08x] FAILED to send Fragment %02d/%02d status=%!status!", + Request->RequestId, Request->TransactionId, FragmentIndex, FragmentCount, NtStatus + ); + NdisStatus = NDIS_STATUS_FAILURE; + } + else + { + TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x][TID=0x%08x] Pending send Fragment %02d/%02d", + Request->RequestId, Request->TransactionId, FragmentIndex, FragmentCount + ); + } + // + // Reacquire lock for evaluating the queue + // + MbbReqMgrLockManager( RequestManager ); + } // for + + // + // On failure, update the status field. + // Dont send any more fragments, fake remaining fragments are sent. + // + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + Request->HandlerContext.Command.SendStatus = NdisStatus; + FragmentSentCount += FragmentCount - FragmentIndex; + } + // + // Update the Request fields + // Protected by RequestManager lock. + // + Request->HandlerContext.Command.NextFragmentIndex = FragmentIndex; + Request->HandlerContext.Command.FragmentSentCount += FragmentSentCount; + Request->HandlerContext.Command.IsProcessing = FALSE; + // + // If any fragments were completed synchronously then check if + // the request can move to SendComplete + // + if( FragmentSentCount > 0 ) + FragmentSentCount = Request->HandlerContext.Command.FragmentSentCount; + MbbReqMgrUnlockManager( RequestManager ); + // + // Queue SendComplete event if no fragments are pending + // + if( FragmentSentCount == FragmentCount ) + { + PCHAR CommandName = MbbUtilGetCommandString(&(Request->HandlerContext.Command.Command)); + + // Etw Trace send complete + MbbWriteEvent( + &CID_SEND_COMPLETE, + &(Request->ActivityId), + NULL, + 8, + &(Request->OidContext.OidRequestId), + sizeof(Request->OidContext.OidRequestId), + &(Request->RequestId), + sizeof(ULONG), + &(Request->HandlerContext.Command.Command.ServiceId), + sizeof(GUID), + CommandName, + strlen(CommandName) + 1, + &(Request->HandlerContext.Command.Command.CommandId), + sizeof(ULONG), + &(Request->HandlerContext.Command.DataLength), + sizeof(ULONG), + Request->HandlerContext.Command.Data, + Request->HandlerContext.Command.DataLength, + &NdisStatus, + sizeof(NDIS_STATUS) + ); + + MbbReqMgrQueueEvent( + Request->RequestManager, + Request, + MbbRequestEventSendComplete, + (PVOID)(NdisStatus), + 0 + ); + } + else + { + NdisStatus = NDIS_STATUS_PENDING; + } + + return NdisStatus; +} + +NTSTATUS +MbbUtilBusSendMessageFragment( + __in PMBB_REQUEST_CONTEXT Request, + __in MBB_REQUEST_HANDLE FragmentBuffer, + __in PVOID MessageFragment, + __in ULONG FragmentLength + ) +{ + PMDL Mdl; + NTSTATUS NtStatus; + MBB_BUS_HANDLE BusHandle = MbbNdisGetBusHandle( MbbReqMgrGetAdapterHandle( Request ) ); + + // + // OS supported commands are sent over the control pipe. + // Vendor device service commands are send also sent over the control pipe + // + NtStatus = MbbBusSendMessageFragment( + BusHandle, + FragmentBuffer, + MessageFragment, + FragmentLength, + !IsZeroGuid(&(Request->ActivityId)) ? &(Request->ActivityId) : NULL, + MbbUtilSendMessageFragmentComplete + ); + + return NtStatus; +} + +VOID +MbbUtilSendMessageFragmentComplete( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in MBB_REQUEST_HANDLE FragmentBuffer, + __in NTSTATUS NtStatus + ) +{ + ULONG FragmentCount; + ULONG FragmentSentCount; + NDIS_STATUS NdisStatus; + PMBB_REQUEST_CONTEXT Request; + PMBB_REQUEST_MANAGER RequestManager; + + if( NtStatus == STATUS_SUCCESS ) + NdisStatus = NDIS_STATUS_SUCCESS; + else + NdisStatus = NDIS_STATUS_FAILURE; + + Request = (PMBB_REQUEST_CONTEXT) MbbBufMgrGetBufferContext( FragmentBuffer ); + RequestManager = Request->RequestManager; + FragmentCount = Request->HandlerContext.Command.FragmentCount; + // + // Update fields that need synchronization. + // Note the buffer should be returned with RequestManager lock held. + // + MbbReqMgrLockManager( RequestManager ); + MbbBufMgrFreeBuffer( FragmentBuffer ); + FragmentSentCount = ++Request->HandlerContext.Command.FragmentSentCount; + if( NdisStatus != NDIS_STATUS_SUCCESS ) + Request->HandlerContext.Command.SendStatus = NdisStatus; + MbbReqMgrUnlockManager( RequestManager ); + + TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x][TID=0x%08x] %02d/%02d fragment completed with status=%!status!", + Request->RequestId, Request->TransactionId, FragmentSentCount, FragmentCount, NdisStatus + ); + // + // If all fragments have completed sending then complete the request. + // If not, then try to send more fragments. + // + if( FragmentSentCount == FragmentCount ) + { + PCHAR CommandName = MbbUtilGetCommandString(&(Request->HandlerContext.Command.Command)); + + // Etw Trace send complete + MbbWriteEvent( + &CID_SEND_COMPLETE, + &(Request->ActivityId), + NULL, + 8, + &(Request->OidContext.OidRequestId), + sizeof(Request->OidContext.OidRequestId), + &(Request->RequestId), + sizeof(ULONG), + &(Request->HandlerContext.Command.Command.ServiceId), + sizeof(GUID), + CommandName, + strlen(CommandName) + 1, + &(Request->HandlerContext.Command.Command.CommandId), + sizeof(ULONG), + &(Request->HandlerContext.Command.DataLength), + sizeof(ULONG), + Request->HandlerContext.Command.Data, + Request->HandlerContext.Command.DataLength, + &NdisStatus, + sizeof(NDIS_STATUS) + ); + + MbbReqMgrQueueEvent( + Request->RequestManager, + Request, + MbbRequestEventSendComplete, + (PVOID)(NdisStatus), + 0 + ); + + if (NtStatus == STATUS_IO_TIMEOUT && Request->OidHandler != NULL) + { + PMBB_SEND_QUEUE SendQueue = &((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request))->SendQueue; + switch (Request->OidHandler->Oid) + { + case OID_WWAN_CONNECT: + TraceLoggingWrite( + g_hLoggingProvider, + "ConnectSendTimeout", + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + TryQueueStallState(SendQueue); + break; + // Remove OID_WWAN_PIN_EX since there is an observed case that the OID_WWAN_PIN_EX failed but data path is still working + // case OID_WWAN_PIN_EX: __fallthrough; + //case OID_WWAN_RADIO_STATE: + // TraceLoggingWrite( + // g_hLoggingProvider, + // "RadioStateSendTimeout", + // TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + // TryQueueStallState(SendQueue); + // break; + } + } + } + else + { + // + // All fragments might be already send but some may be inflight. + // If all fragments are sent then below call will be a no-op. + // + MbbUtilSendMessageFragments( Request ); + } +} + +VOID +MbbUtilSendMbimErrorComplete( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in MBB_REQUEST_HANDLE SendBuffer, + __in NTSTATUS NtStatus + ) +{ + PMBB_ERROR_MESSAGE ErrorMessage = (PMBB_ERROR_MESSAGE)SendBuffer; + + if( ! NT_SUCCESS( NtStatus ) ) + { + TraceError( WMBCLASS_UTIL, "[Util][MBIM_ERR][TID=0x%08x] FAILED to send error message to device, Error=%!MbbError!", + ErrorMessage->MessageHeader.MessageTransactionId, + ErrorMessage->ErrorCode + ); + } + FREE_POOL( ErrorMessage ); +} + +VOID +MbbUtilSendMbimError( + __in ULONG TransactionId, + __in MBB_ERROR ErrorCode, + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in GUID ActivityId, + __in PMBB_COMMAND Command + ) +/*++ +Description + Helper routine to send a MBB error message to the MBIM device. + This also logs an ETW event in the event log. +--*/ +{ + NTSTATUS NtStatus; + PCHAR CommandName; + PMBB_ERROR_MESSAGE ErrorMessage; + +#pragma prefast(suppress: __WARNING_MEMORY_LEAK, "Released by MbbUtilSendMbimErrorComplete") + if( (ErrorMessage = (PMBB_ERROR_MESSAGE) ALLOCATE_NONPAGED_POOL( sizeof(MBB_ERROR_MESSAGE) )) == NULL ) + { + TraceError( WMBCLASS_UTIL, "[MBIM_ERR][TID=0x%08x] FAILED to allocate error message for, Error=%!MbbError!", + TransactionId, + ErrorCode + ); + return; + } + + ErrorMessage->MessageHeader.MessageType = MBB_MESSAGE_TYPE_HOST_ERROR; + ErrorMessage->MessageHeader.MessageLength = sizeof(*ErrorMessage); + ErrorMessage->MessageHeader.MessageTransactionId= TransactionId; + ErrorMessage->ErrorCode = ErrorCode; + + TraceError( WMBCLASS_UTIL, "[MBIM_ERR][TID=0x%08x] Sending MBIM error message for %!MbbError! to device", + TransactionId, + ErrorCode + ); + + NtStatus = MbbBusSendMessageFragment( + MbbNdisGetBusHandle( Adapter ), + ErrorMessage, + ErrorMessage, + sizeof(*ErrorMessage), + !IsZeroGuid(&ActivityId) ? &ActivityId : NULL, + MbbUtilSendMbimErrorComplete + ); + if( ! NT_SUCCESS( NtStatus ) ) + { + TraceError( WMBCLASS_UTIL, "[MBIM_ERR][TID=0x%08x] FAILED to send error message to bus layer, Error=%!MbbError!", + TransactionId, + ErrorCode + ); + } + + if( NtStatus != STATUS_PENDING ) + { + MbbUtilSendMbimErrorComplete( + NULL, + ErrorMessage, + NtStatus + ); + } + + CommandName = MbbUtilGetCommandString( Command ); + + MbbWriteEvent( + &MBIM_HOST_ERROR_EVENT, + NULL, + NULL, + 6, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &ErrorCode, + sizeof(MBB_ERROR), + &TransactionId, + sizeof(ULONG), + &Command->ServiceId, + sizeof(Command->ServiceId), + &Command->CommandId, + sizeof(Command->CommandId), + CommandName, + strlen(CommandName) + 1 + ); +} + + +// +// CID QUERY \ SET WRAPPER +// + + +NDIS_STATUS +MbbUtilInternalCIDQuery( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +/*++ + Description + This is the internal serialized routine that calls CID handlers. + Only one instance of this routine will run at any time. + This is different than MbbNdisProcessSerializeOidRequest( ) + in that it is not related to OIDs. Internal request submissions + that do not have a OID use this wrapper routine as their dispatch routine. + + Parameters + __in PMBB_REQUEST_CONTEXT Request + The request to process. This is the internal request representation. +--*/ +{ + TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x] Internal query dispatch for CID %s", + Request->RequestId, + MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ) + ); + + return Request->OidHandler->QueryHandler( + Request, + NULL, + NULL, + NULL, + NULL + ); +} + +VOID +MbbUtilInternalCIDCompletion( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ) +/*++ + Description: + This routine is used by internal CID requestors. This is the default + handler for SendCompletion that handles common cleanup work. +--*/ +{ + if( Request->OidHandler->CompletionHandler != NULL ) + { + Request->OidHandler->CompletionHandler( + Request, + NdisStatus + ); + } + + TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x] Internal SendComplete cleanup for CID %s. Status=%!status! DataToFree=0x%p", + Request->RequestId, + MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), + NdisStatus, + Request->HandlerContext.DataToFreeOnCompletion + ); + + if( Request->HandlerContext.DataToFreeOnCompletion != NULL ) + FREE_POOL( Request->HandlerContext.DataToFreeOnCompletion ); + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + if( Request->HandlerContext.DataToFreeOnResponse != NULL ) + FREE_POOL( Request->HandlerContext.DataToFreeOnResponse ); + + KeSetEvent( + &Request->WaitEvent, + IO_NO_INCREMENT, + FALSE + ); + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } +} + +VOID +MbbUtilCommonCIDResponse( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize, + __in_opt PMBB_OID_HANDLER_ENTRY OidHandler + ) +{ + NDIS_STATUS HandlerStatus = NDIS_STATUS_SUCCESS; + PCHAR ResponseType = (MbbReqMgrIsUnsolicitedIndication( Request )) ? "Unsolicited":"Solicited"; + PCHAR CommandName = NULL; + GUID ServiceId = MBB_UUID_INVALID_CONSTANT; + ULONG CommandId = 0; + MBB_MESSAGE_TYPE MessageType; + ULONG MessageLength; + DWORD TotalFragments = 1; + DWORD CurrentFragment = 0; + + if( OidHandler != NULL && + OidHandler->ResponseHandler != NULL ) + { + HandlerStatus = OidHandler->ResponseHandler( + Request, + NdisStatus, + MbbStatus, + InBuffer, + InBufferSize + ); + // + // Let the handler overwrite the status + // + NdisStatus = HandlerStatus; + + CommandName = MbbUtilGetCommandString(&OidHandler->ResponseCommand); + ServiceId = OidHandler->ResponseCommand.ServiceId; + CommandId = OidHandler->ResponseCommand.CommandId; + } + + // Etw trace response received + MbbWriteEvent( + &CID_RESPONSE_RECVD, + &(Request->ActivityId), + NULL, + 10, + ResponseType, + strlen(ResponseType) + 1, + &(Request->OidContext.OidRequestId), + sizeof(Request->OidContext.OidRequestId), + &(Request->RequestId), + sizeof(ULONG), + &ServiceId, + sizeof(GUID), + CommandName, + (CommandName == NULL) ? 0 : (strlen(CommandName) + 1), + &CommandId, + sizeof(ULONG), + &MbbStatus, + sizeof(MBB_STATUS), + &NdisStatus, + sizeof(NDIS_STATUS), + &InBufferSize, + sizeof(ULONG), + InBuffer, + InBufferSize + ); + + // Etw Trace for MBB OPN. Log an event that renders the entire MBIM message + if( MbbReqMgrIsUnsolicitedIndication( Request ) ) + { + MessageType = MBB_MESSAGE_TYPE_INDICATE_STATUS; + MessageLength = InBufferSize + sizeof(MBB_INDICATE_STATUS_HEADER); + MbbWriteEventOpn( + &INDICATE_STATUS_MSG, + &(Request->ActivityId), + NULL, + 9, + &MessageType, + sizeof(MessageType), + &MessageLength, + sizeof(MessageLength), + &(Request->TransactionId), + sizeof(Request->TransactionId), + &TotalFragments, + sizeof(TotalFragments), + &CurrentFragment, + sizeof(CurrentFragment), + &(ServiceId), + sizeof(ServiceId), + &(CommandId), + sizeof(CommandId), + &InBufferSize, + sizeof(InBufferSize), + InBuffer, + InBufferSize + ); + } + else + { + MessageType = MBB_MESSAGE_TYPE_COMMAND_DONE; + MessageLength = InBufferSize + sizeof(MBB_COMMAND_DONE_HEADER); + MbbWriteEventOpn( + &COMMAND_DONE_MSG, + &(Request->ActivityId), + NULL, + 10, + &MessageType, + sizeof(MessageType), + &MessageLength, + sizeof(MessageLength), + &(Request->TransactionId), + sizeof(Request->TransactionId), + &TotalFragments, + sizeof(TotalFragments), + &CurrentFragment, + sizeof(CurrentFragment), + &(ServiceId), + sizeof(ServiceId), + &(CommandId), + sizeof(CommandId), + &MbbStatus, + sizeof(MbbStatus), + &InBufferSize, + sizeof(InBufferSize), + InBuffer, + InBufferSize + ); + } + + // + // If the handler wants to keep the request around for MoreData + // then do not cleanup the request yet. + // + if( HandlerStatus == NDIS_STATUS_PENDING ) + { + TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x] Not cleaning CID %s", + Request->RequestId, + MbbUtilGetCommandString( &Request->HandlerContext.Response.Command ) + ); + } + else + { + TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x] ResponseReceived cleanup for CID %s. Status=%!status! DataToFree=0x%p", + Request->RequestId, + MbbUtilGetCommandString( &Request->HandlerContext.Response.Command ), + NdisStatus, + Request->HandlerContext.DataToFreeOnResponse + ); + Request->HandlerContext.Response.NdisStatus = NdisStatus; + + if( Request->HandlerContext.DataToFreeOnResponse != NULL ) + FREE_POOL( Request->HandlerContext.DataToFreeOnResponse ); + + KeSetEvent( + &Request->WaitEvent, + IO_NO_INCREMENT, + FALSE + ); + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } +} + +VOID +MbbUtilInternalCIDResponse( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ) +/*++ + Description: + This routine is used by internal CID requestors. This is the deafult + handler for ResposenReceivethat handles common cleanup work. + + Internal routine requires that there is an OID handler Which means + that status indidcations are not supported on the internal path. +--*/ +{ + MbbUtilCommonCIDResponse( + Request, + NdisStatus, + MbbStatus, + InBuffer, + InBufferSize, + Request->OidHandler + ); +} + +NDIS_STATUS +MbbUtilQueryAttribute( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ) +{ + return MbbUtilQueryAttributeWithParameter( + Request, + NULL, + 0 + ); +} + +NDIS_STATUS +MbbUtilQueryAttributeWithParameter( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(GetRequestParametersSize) PUCHAR GetRequestParameters, + __in ULONG GetRequestParametersSize + ) +{ + NDIS_STATUS NdisStatus; + + do + { + // + // Call the wrapper routine to allocate + // and format the message buffers. + // + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Request->OidHandler->ResponseCommand, + MBB_COMMAND_TYPE_QUERY, + GetRequestParameters, + GetRequestParametersSize + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x] FAILED to setup command message for %s with status=%!status!", + Request->RequestId, MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x] FAILED to send message fragments for %s with status=%!status!", + Request->RequestId, MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), NdisStatus ); + } + + } while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilSetAttributeWithParameter( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(SetParametersSize) PUCHAR SetParameters, + __in ULONG SetParametersSize + ) +{ + NDIS_STATUS NdisStatus; + + do + { + // + // Call the wrapper routine to allocate + // and format the message buffers. + // + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &Request->OidHandler->ResponseCommand, + MBB_COMMAND_TYPE_SET, + SetParameters, + SetParametersSize + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x] FAILED to setup command message for %s with status=%!status!", + Request->RequestId, MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), NdisStatus ); + break; + } + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x] FAILED to send message fragments for %s with status=%!status!", + Request->RequestId, MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), NdisStatus ); + } + + } while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilDeviceServiceCommand( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + NDIS_STATUS NdisStatus; + MBB_COMMAND MbbCommand; + PNDIS_WWAN_DEVICE_SERVICE_COMMAND NdisDeviceServiceCommand; + + do + { + if( *InBufferSize < sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INSUFFICIENT InputBufferSize=%d Bytes for DEVICE_SERVICE_COMMAND, Expected=%d Bytes", + Request->RequestId, *InBufferSize, sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND) ); + + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + *InBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND); + break; + } + + NdisDeviceServiceCommand = (PNDIS_WWAN_DEVICE_SERVICE_COMMAND) InBuffer; + + + if( NdisDeviceServiceCommand->Header.Type != NDIS_OBJECT_TYPE_DEFAULT || + NdisDeviceServiceCommand->Header.Size < SIZEOF_NDIS_WWAN_DEVICE_SERVICE_COMMAND_1 || + NdisDeviceServiceCommand->Header.Revision < NDIS_WWAN_DEVICE_SERVICE_COMMAND_REVISION_1 ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INVALID ndis header for DEVICE_SERVICE_COMMAND, Type=0x%x Size=%d Revision=%d", + Request->RequestId, + NdisDeviceServiceCommand->Header.Type, + NdisDeviceServiceCommand->Header.Size, + NdisDeviceServiceCommand->Header.Revision + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + if (NdisDeviceServiceCommand->Command.uDataSize + RTL_SIZEOF_THROUGH_FIELD(NDIS_WWAN_DEVICE_SERVICE_COMMAND,Command.uDataSize) > *InBufferSize ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INSUFFICIENT InputBufferSize=%d Bytes for DEVICE_SERVICE_COMMAND, Expected=%d Bytes", + Request->RequestId, *InBufferSize, sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND) ); + + *InBufferSize = NdisDeviceServiceCommand->Command.uDataSize + RTL_SIZEOF_THROUGH_FIELD(NDIS_WWAN_DEVICE_SERVICE_COMMAND,Command.uDataSize); + + NdisStatus = NDIS_STATUS_INVALID_LENGTH; + break; + } + + RtlCopyMemory( + &MbbCommand.ServiceId, + &NdisDeviceServiceCommand->Command.DeviceServiceGuid, + sizeof(GUID) + ); + + MbbCommand.CommandId = NdisDeviceServiceCommand->Command.CommandID; + // + // Call the wrapper routine to allocate + // and format the message buffers. + // + if( (NdisStatus = MbbUtilSetupCommandMessage( + Request, + &MbbCommand, + MbbReqMgrIsSetOid( Request )? MBB_COMMAND_TYPE_SET: MBB_COMMAND_TYPE_QUERY, + (PUCHAR)(NdisDeviceServiceCommand + 1), + NdisDeviceServiceCommand->Command.uDataSize + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to setup command message for DEVICE_SERVICE_COMMAND with status=%!status!", + Request->RequestId, NdisStatus ); + break; + } + *InBufferSize += NdisDeviceServiceCommand->Command.uDataSize; + // + // Call the wrapper routine to send each fragment. + // The wrapper will cleanup fragments in case of + // success or failure. + // + NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); + if( NdisStatus != NDIS_STATUS_SUCCESS && + NdisStatus != NDIS_STATUS_PENDING ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to send message fragments for DEVICE_SERVICE_COMMAND with status=%!status!", + Request->RequestId, NdisStatus ); + } + + } while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilUiccAccessBinary( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PNDIS_WWAN_UICC_ACCESS_BINARY NdisUiccAccessBinary = (PNDIS_WWAN_UICC_ACCESS_BINARY)InBuffer; + PMBB_UICC_ACCESS_BINARY MbbUiccAccessBinary = NULL; + NDIS_STATUS NdisStatus; + ULONG BufferSize = 0; + + NdisStatus = MbbUtilWwanToMbbUiccAccessBinary( + &NdisUiccAccessBinary->UiccAccessBinary, + &MbbUiccAccessBinary, + &BufferSize + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbUiccAccessBinary; + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR) MbbUiccAccessBinary, + BufferSize + ); +} + +NDIS_STATUS +MbbUtilUiccAccessRecord( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ) +{ + PNDIS_WWAN_UICC_ACCESS_RECORD NdisUiccAccessRecord = (PNDIS_WWAN_UICC_ACCESS_RECORD)InBuffer; + PMBB_UICC_ACCESS_RECORD MbbUiccAccessRecord = NULL; + NDIS_STATUS NdisStatus; + ULONG BufferSize = 0; + + NdisStatus = MbbUtilWwanToMbbUiccAccessRecord( + &NdisUiccAccessRecord->UiccAccessRecord, + &MbbUiccAccessRecord, + &BufferSize + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + return NdisStatus; + } + + Request->HandlerContext.DataToFreeOnCompletion = MbbUiccAccessRecord; + + return MbbUtilQueryAttributeWithParameter( + Request, + (PUCHAR) MbbUiccAccessRecord, + BufferSize + ); +} + +// +// Wwan to Mbb +// + + +VOID +MbbUtilWwanToMbbRadioState( + __in WWAN_RADIO* WwanRadio, + __out MBB_RADIO_STATE* MbbRadioState + ) +{ + *MbbRadioState = (MBB_RADIO_STATE)*WwanRadio; +} + +NTSTATUS +MbbUtilWwanToMbbPinAction( + __in PWWAN_PIN_ACTION WwanPinAction, + __out PMBB_PIN_ACTION * MbbPinActionOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_PIN_ACTION MbbPinAction=NULL; + NTSTATUS Status; + SIZE_T PinLength; + SIZE_T NewPinLength; + + *ReturnedBufferSize=0; + + BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_PIN_ACTION,DataBuffer), ALIGN_DWORD); + + CurrentOffset=BufferSize; + + Status=RtlStringCbLengthW(WwanPinAction->Pin, sizeof(WwanPinAction->Pin), &PinLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status=RtlStringCbLengthW(WwanPinAction->NewPin, sizeof(WwanPinAction->NewPin), &NewPinLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + BufferSize+=(ULONG)ROUND_UP_COUNT(PinLength, ALIGN_DWORD); + BufferSize+=(ULONG)ROUND_UP_COUNT(NewPinLength, ALIGN_DWORD); + + if( (MbbPinAction = ALLOCATE_NONPAGED_POOL( BufferSize )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer=(PUCHAR)MbbPinAction; + + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + &MbbPinAction->Pin, + (PUCHAR)WwanPinAction->Pin, + (ULONG)PinLength + ); + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + &MbbPinAction->NewPin, + (PUCHAR)WwanPinAction->NewPin, + (ULONG)NewPinLength + ); + + + MbbPinAction->PinType = (MBB_PIN_TYPE)WwanPinAction->PinType; + MbbPinAction->PinOperation = (MBB_PIN_OPERATION)WwanPinAction->PinOperation; + + + *MbbPinActionOut=MbbPinAction; + + *ReturnedBufferSize=BufferSize; + + return STATUS_SUCCESS; +} + +NTSTATUS +MbbUtilWwanToMbbPinActionEx2( + __in PWWAN_PIN_ACTION_EX2 WwanPinAction, + __out PMBB_PIN_ACTION_EX2 *MbbPinActionOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_PIN_ACTION_EX2 MbbPinAction=NULL; + NTSTATUS Status; + SIZE_T PinLength; + SIZE_T NewPinLength; + + *ReturnedBufferSize=0; + + BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_PIN_ACTION_EX2,DataBuffer), ALIGN_DWORD); + + CurrentOffset=BufferSize; + + Status=RtlStringCbLengthW(WwanPinAction->Pin, sizeof(WwanPinAction->Pin), &PinLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status=RtlStringCbLengthW(WwanPinAction->NewPin, sizeof(WwanPinAction->NewPin), &NewPinLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + BufferSize+=(ULONG)ROUND_UP_COUNT(PinLength, ALIGN_DWORD); + BufferSize+=(ULONG)ROUND_UP_COUNT(NewPinLength, ALIGN_DWORD); + BufferSize+=(ULONG)ROUND_UP_COUNT(WwanPinAction->AppIdLength, ALIGN_DWORD); + + if( (MbbPinAction = ALLOCATE_NONPAGED_POOL( BufferSize )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer=(PUCHAR)MbbPinAction; + + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + &MbbPinAction->Pin, + (PUCHAR)WwanPinAction->Pin, + (ULONG)PinLength + ); + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + &MbbPinAction->NewPin, + (PUCHAR)WwanPinAction->NewPin, + (ULONG)NewPinLength + ); + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbPinAction->AppId, + (PUCHAR)WwanPinAction->AppId, + (ULONG)WwanPinAction->AppIdLength + ); + + MbbPinAction->PinType = (MBB_PIN_TYPE)WwanPinAction->PinType; + MbbPinAction->PinOperation = (MBB_PIN_OPERATION)WwanPinAction->PinOperation; + + *MbbPinActionOut=MbbPinAction; + + *ReturnedBufferSize=BufferSize; + + return STATUS_SUCCESS; +} + +ULONG +MbbUtilWwanToMbbProvider( + __in PWWAN_PROVIDER WwanProvider, + __in MBB_CELLULAR_CLASS MbbCellularClass, + __in ULONG Rssi, + __in ULONG ErrorRate, + __in ULONG MbbProviderSize, + __out_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider + ) +{ + ULONG MbbProviderOffset; + SIZE_T StringCbLength; + NDIS_STATUS NdisStatus; + + do + { + if( sizeof(MBB_PROVIDER) > MbbProviderSize ) + { + TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER, Size=%d Expected=%d", + MbbProviderSize, + sizeof(MBB_PROVIDER) + ); + MbbProviderOffset = 0; + break; + } + MbbProvider->ProviderState = (ULONG)WwanProvider->ProviderState; + MbbProvider->Rssi = Rssi; + MbbProvider->ErrorRate = ErrorRate; + MbbProvider->CellularClass = MbbCellularClass; + + MBB_INIT_MBB_STRING( &MbbProvider->ProviderId ); + MBB_INIT_MBB_STRING( &MbbProvider->ProviderName ); + + MbbProviderOffset = sizeof(MBB_PROVIDER); + + if( (NdisStatus = RtlStringCbLengthW( + WwanProvider->ProviderId, + sizeof(WwanProvider->ProviderId), + &StringCbLength + )) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util] FAILED to get string length for WWAN_PROVIDER.ProviderId, NdisStatus=%!STATUS!", + NdisStatus + ); + MbbProviderOffset = 0; + break; + } + + if( MbbProviderOffset + StringCbLength > MbbProviderSize ) + { + TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER.ProviderId, Size=%d Expected=%d", + MbbProviderSize, + (ULONG)(MbbProviderOffset + StringCbLength) + ); + MbbProviderOffset = 0; + break; + } + + MbbProviderOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbProvider, + MbbProviderSize, + MbbProviderOffset, + &MbbProvider->ProviderId, + (PCUCHAR)(WwanProvider->ProviderId), + (ULONG)StringCbLength + ); + + if( (NdisStatus = RtlStringCbLengthW( + WwanProvider->ProviderName, + sizeof(WwanProvider->ProviderName), + &StringCbLength + )) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util] FAILED to get string length for WWAN_PROVIDER.ProviderName, NdisStatus=%!STATUS!", NdisStatus ); + MbbProviderOffset = 0; + break; + } + + if( MbbProviderOffset + StringCbLength > MbbProviderSize ) + { + TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER.ProviderName, Size=%d Expected=%d", + MbbProviderSize, + (ULONG)(MbbProviderOffset + StringCbLength) + ); + MbbProviderOffset = 0; + break; + } + + MbbProviderOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbProvider, + MbbProviderSize, + MbbProviderOffset, + &MbbProvider->ProviderName, + (PCUCHAR)(WwanProvider->ProviderName), + (ULONG)StringCbLength + ); + } + while( FALSE ); + + return MbbProviderOffset; +} + +ULONG +MbbUtilWwanToMbbProvider2( + __in PWWAN_PROVIDER2 WwanProvider2, + __in ULONG MbbProviderSize, + __out_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider + ) +{ + // + // There is no MBB mapping for WwanCellularClassWiMAX. + // Assume that the service will behave correctly and not send bad data. + // + return MbbUtilWwanToMbbProvider( + &WwanProvider2->Provider, + (MBB_CELLULAR_CLASS)(WwanProvider2->WwanCellularClass), + WwanProvider2->Rssi, + WwanProvider2->ErrorRate, + MbbProviderSize, + MbbProvider + ); +} + +NDIS_STATUS +MbbUtilWwanToMbbProviderList( + __in PWWAN_LIST_HEADER WwanProviderList, + __in BOOLEAN IsMultiCarrierCapable, + __in_opt MBB_CELLULAR_CLASS MbbCellularClass, + __out_bcount(*MbbProviderListSize) PMBB_PROVIDER_LIST MbbProviderList, + __inout PULONG MbbProviderListSize + ) +{ + ULONG ElementIndex; + ULONG ElementCount = WwanProviderList->ElementCount; + ULONG MbbProviderSize; + ULONG MbbProviderListOffset; + NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE; + PMBB_PROVIDER MbbProvider; + PWWAN_PROVIDER2 WwanProviders2 = (PWWAN_PROVIDER2)(WwanProviderList + 1); + PMBB_ARRAY_ELEMENT MbbProviderElement = (PMBB_ARRAY_ELEMENT)(MbbProviderList->Providers); + + MbbProviderListOffset = FIELD_OFFSET(MBB_PROVIDER_LIST, Providers); + MbbProviderListOffset += ElementCount * sizeof(MBB_ARRAY_ELEMENT); + + if( MbbProviderListOffset > *MbbProviderListSize ) + { + TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER_LIST, BufferSize=%d Expected=%d", + *MbbProviderListSize, + MbbProviderListOffset + ); + return NDIS_STATUS_BUFFER_OVERFLOW; + } + + for( ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex ++ ) + { + MbbProviderListOffset = ROUND_UP_COUNT( MbbProviderListOffset, ALIGN_DWORD ); + MbbProviderElement[ElementIndex].Offset = MbbProviderListOffset; + MbbProvider = (PMBB_PROVIDER)(((PCHAR)MbbProviderList)+MbbProviderListOffset); + + if( MbbProviderListOffset > *MbbProviderListSize ) + { + TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER_LIST.Provider[%02d], BufferSize=%d Expected=%d", + *MbbProviderListSize, + MbbProviderListOffset, + ElementIndex + ); + NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; + break; + } + + if( (MbbProviderSize = MbbUtilWwanToMbbProvider2( + &WwanProviders2[ElementIndex], + *MbbProviderListSize - MbbProviderListOffset, + MbbProvider + )) == 0 ) + { + TraceError( WMBCLASS_OID, "[Util] FAILED to convert %02d# WWAN_PROVIDER2 to MBB_PROVIDER", ElementIndex ); + break; + } + + MbbProviderElement[ElementIndex].Size = MbbProviderSize; + MbbProviderListOffset += MbbProviderSize; + } + if( ElementIndex == ElementCount ) + { + MbbProviderList->ProviderCount = ElementCount; + NdisStatus = NDIS_STATUS_SUCCESS; + *MbbProviderListSize = MbbProviderListOffset; + } + return NdisStatus; +} + +NTSTATUS +MbbUtilWwanToMbbSetRegisterState( + __in PWWAN_SET_REGISTER_STATE WwanSetRegisterState, + __out PMBB_SET_REGISTER_STATE *MbbSetRegisterStateOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_SET_REGISTER_STATE MbbSetRegisterState=NULL; + NTSTATUS Status; + SIZE_T ProviderIdLength; + + *ReturnedBufferSize=0; + + BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_REGISTER_STATE,DataBuffer), ALIGN_DWORD); + + CurrentOffset=BufferSize; + + Status=RtlStringCbLengthW(WwanSetRegisterState->ProviderId, sizeof(WwanSetRegisterState->ProviderId), &ProviderIdLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + + BufferSize+=(ULONG)ROUND_UP_COUNT(ProviderIdLength, ALIGN_DWORD); + + if( (MbbSetRegisterState = ALLOCATE_NONPAGED_POOL( BufferSize )) == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer=(PUCHAR)MbbSetRegisterState; + + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + &MbbSetRegisterState->ProviderId, + (PUCHAR)WwanSetRegisterState->ProviderId, + (ULONG)ProviderIdLength + ); + + MbbSetRegisterState->DataClass = (MBB_DATA_CLASS_VALUE)WwanSetRegisterState->WwanDataClass; + MbbSetRegisterState->RegisterAction = (MBB_REGISTER_ACTION)WwanSetRegisterState->RegisterAction; + + + *MbbSetRegisterStateOut=MbbSetRegisterState; + + *ReturnedBufferSize=BufferSize; + + return STATUS_SUCCESS; + +} + +NDIS_STATUS +MbbUtilWwanToMbbSetPacketService( + __in WWAN_PACKET_SERVICE_ACTION PacketServiceAction, + __out PMBB_SET_PACKET_SERVICE MbbSetPacketService + ) +{ + switch( PacketServiceAction ) + { + case WwanPacketServiceActionAttach: + MbbSetPacketService->PacketServiceAction = MbbPacketServiceActionAttach; + return NDIS_STATUS_SUCCESS; + case WwanPacketServiceActionDetach: + MbbSetPacketService->PacketServiceAction = MbbPacketServiceActionDetach; + return NDIS_STATUS_SUCCESS; + default : + return NDIS_STATUS_INVALID_DATA; + } +} + +VOID +MbbUtilAdjustSignalStateConfigurationForDevice( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __inout PWWAN_SET_SIGNAL_INDICATION WwanSetSignalIndication + ) +/*++ +Description + The signal state interval and threshold values need to be adjusted + for Blue for efficient power management. This is done only for + devices that support MBIM 1.0 Errata and the configuration is adjusted + to (60, 1). The signal state configuration + for non-errata devices will continue to be the Win 8 WWAN values (30, -1). + The values are adjusted only if they were set to WWAN_RSSI_DEFAULT (-1). +--*/ +{ + // + // Check if device supports Errata + // + if ( Adapter->BusParams.IsErrataDevice ) + { + // + // Use new Blue values + // + if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiInterval ) + { + WwanSetSignalIndication->RssiInterval = WWAN_RSSI_INTERVAL_SECS_BLUE; + } + + if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiThreshold ) + { + WwanSetSignalIndication->RssiThreshold = WWAN_RSSI_THRESHOLD_CODED_UNIT_BLUE; + } + } + else + { + // + // Continue to use Win 8 values + // + if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiInterval ) + { + WwanSetSignalIndication->RssiInterval = WWAN_RSSI_INTERVAL_SECS_WIN8; + } + + if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiThreshold ) + { + WwanSetSignalIndication->RssiThreshold = WWAN_RSSI_THRESHOLD_CODED_UNIT_WIN8; + } + } +} + +VOID +MbbUtilWwanToMbbSetSignalStateIndication( + __in PWWAN_SET_SIGNAL_INDICATION WwanSetSignalIndication, + __out PMBB_SET_SIGNAL_INDICATION MbbSetSignalStateIndication + ) +/*++ +Description + MBB and WWAN default and disable values are inverted so + appropriate checks and translation is required. +--*/ +{ + if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiInterval ) + MbbSetSignalStateIndication->RssiInterval = MBB_RSSI_DEFAULT; + else if( WWAN_RSSI_DISABLE == WwanSetSignalIndication->RssiInterval ) + MbbSetSignalStateIndication->RssiInterval = MBB_RSSI_DISABLE; + else + MbbSetSignalStateIndication->RssiInterval = WwanSetSignalIndication->RssiInterval; + + if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiThreshold ) + MbbSetSignalStateIndication->RssiThreshold = MBB_RSSI_DEFAULT; + else if( WWAN_RSSI_DISABLE == WwanSetSignalIndication->RssiThreshold ) + MbbSetSignalStateIndication->RssiThreshold = MBB_RSSI_DISABLE; + else + MbbSetSignalStateIndication->RssiThreshold = WwanSetSignalIndication->RssiThreshold; + + MbbSetSignalStateIndication->ErrorRateThreshold = MBB_RSSI_DISABLE; +} + +VOID +MbbUtilWwanToMbbContextType( + __in WWAN_CONTEXT_TYPE WwanContextType, + __out PGUID MbbContextType + ) +{ + GUID SrcGuid; + + switch( WwanContextType ) + { + case WwanContextTypeInternet: + SrcGuid = MBB_UUID_CONTEXT_TYPE_INTERNET; + break; + + case WwanContextTypeVpn: + SrcGuid = MBB_UUID_CONTEXT_TYPE_VPN; + break; + + case WwanContextTypeVoice: + SrcGuid = MBB_UUID_CONTEXT_TYPE_VOICE; + break; + + case WwanContextTypeVideoShare: + SrcGuid = MBB_UUID_CONTEXT_TYPE_VIDEO_SHARE; + break; + + case WwanContextTypePurchase: + SrcGuid = MBB_UUID_CONTEXT_TYPE_PURCHASE; + break; + + case WwanContextTypeCustom: + SrcGuid = MBB_UUID_CONTEXT_TYPE_CUSTOM; + break; + + case WwanContextTypeIms: + SrcGuid = MBB_UUID_CONTEXT_TYPE_IMS; + break; + + case WwanContextTypeAdmin: + SrcGuid = MBB_UUID_CONTEXT_TYPE_MS_ADMIN; + break; + + case WwanContextTypeApp: + SrcGuid = MBB_UUID_CONTEXT_TYPE_MS_APP; + break; + + case WwanContextTypeLteAttach: + SrcGuid = MBB_UUID_BASIC_CONNECT_EXTENSIONS; + break; + + case WwanContextTypeNone: + default: + SrcGuid = MBB_UUID_CONTEXT_TYPE_NONE; + + break; + } + MBB_UUID_TO_NET( MbbContextType, &SrcGuid ); +} + +VOID +MbbUtilWwanToMbbSetContextState( + __in PWWAN_SET_CONTEXT_STATE WwanSetContextState, + __in ULONG AccessStringCchLength, + __in ULONG UserNameCchLength, + __in ULONG PasswordCchLength, + __in ULONG MbbSetContextStateSize, + __in ULONG SessionId, + __out PMBB_SET_CONTEXT_STATE MbbSetContextState + ) +{ + ULONG CurrentOffset; + + MbbSetContextState->SessionId = SessionId; + MbbSetContextState->ActivationCommand = (MBB_ACTIVATION_COMMAND)WwanSetContextState->ActivationCommand; + MbbSetContextState->Compression = (MBB_COMPRESSION)WwanSetContextState->Compression; + MbbSetContextState->AuthProtocol = (MBB_AUTH_PROTOCOL)WwanSetContextState->AuthType; + MbbSetContextState->IPType = (MBB_CONTEXT_IP_TYPE)WwanSetContextState->IPType; + if (MbbSetContextState->IPType > MbbContextIPTypeIPv4v6) + { + TraceWarn(WMBCLASS_UTIL, "Invalid IPType from the OS. Resetting it to MbbContextIPTypeDefault"); + MbbSetContextState->IPType = MbbContextIPTypeDefault; + } + + MbbUtilWwanToMbbContextType( + WwanContextTypeInternet, + &MbbSetContextState->ContextType + ); + + CurrentOffset = FIELD_OFFSET( MBB_SET_CONTEXT_STATE, DataBuffer ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContextState, + MbbSetContextStateSize, + CurrentOffset, + &MbbSetContextState->AccessString, + (PCUCHAR)(WwanSetContextState->AccessString), + AccessStringCchLength * sizeof(WCHAR) + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContextState, + MbbSetContextStateSize, + CurrentOffset, + &MbbSetContextState->UserName, + (PCUCHAR)(WwanSetContextState->UserName), + UserNameCchLength * sizeof(WCHAR) + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContextState, + MbbSetContextStateSize, + CurrentOffset, + &MbbSetContextState->Password, + (PCUCHAR)(WwanSetContextState->Password), + PasswordCchLength * sizeof(WCHAR) + ); +} + +VOID +MbbUtilMbbToWwanLteAttachConfigInfo( + __in MBB_MS_LTE_ATTACH_CONFIG_INFO* MbbLteAttachContextList, + __out PWWAN_LTE_ATTACH_CONFIG WwanLteAttachContext + ) +{ + PMBB_MS_LTE_ATTACH_CONTEXT MbbLteAttachContext; + + for( ULONG ContextIndex = 0; + ContextIndex < MbbLteAttachContextList->ElementCount; + ContextIndex ++ ) + { + MbbLteAttachContext = (PMBB_MS_LTE_ATTACH_CONTEXT)((PUCHAR)MbbLteAttachContextList + MbbLteAttachContextList->Contexts[ContextIndex].Offset); + + MbbUtilMbbToWwanLteAttachContext( + MbbLteAttachContext, + &(WwanLteAttachContext->LteContextArray[ContextIndex]) + ); + } +} + +NTSTATUS +MbbUtilWwanToMbbSetLteAttachContext( + __in PWWAN_SET_LTE_ATTACH WwanSetContextBuffer, + __out PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG *ReturnedMbbSetContext, + __out ULONG *ReturnedBufferSize + ) +{ + NTSTATUS Status = STATUS_SUCCESS; + + PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG MbbSetContext = NULL; + ULONG SetBufferSize = 0; + ULONG SetBufferOffset = 0; + + PMBB_MS_LTE_ATTACH_CONTEXT MbbLteAttachContext = NULL; + ULONG BufferSize[TotalRoamingConditions] = {0}; + ULONG MbbLteAttachOffset = 0; + SIZE_T AccessStringLength[TotalRoamingConditions] = {0}; + SIZE_T UserNameLength[TotalRoamingConditions] = {0}; + SIZE_T PasswordLength[TotalRoamingConditions] = {0}; + + PWWAN_SET_CONTEXT_V2 WwanSetLteAttachContext = NULL; + *ReturnedBufferSize=0; + *ReturnedMbbSetContext=NULL; + + SetBufferSize = ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG, Contexts), ALIGN_DWORD); + SetBufferSize += ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * TotalRoamingConditions, ALIGN_DWORD); + + SetBufferOffset = SetBufferSize; + + for (ULONG i = 0; i < TotalRoamingConditions; i ++) + { + WwanSetLteAttachContext = &(WwanSetContextBuffer->SetContextArray[i]); + + BufferSize[i] = ROUND_UP_COUNT(FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer), ALIGN_DWORD); + + Status=RtlStringCbLengthW(WwanSetLteAttachContext->basicInfo.AccessString, sizeof(WwanSetLteAttachContext->basicInfo.AccessString), &(AccessStringLength[i])); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status=RtlStringCbLengthW(WwanSetLteAttachContext->basicInfo.UserName, sizeof(WwanSetLteAttachContext->basicInfo.UserName), &(UserNameLength[i])); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status=RtlStringCbLengthW(WwanSetLteAttachContext->basicInfo.Password, sizeof(WwanSetLteAttachContext->basicInfo.Password), &(PasswordLength[i])); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + BufferSize[i] += (ULONG)ROUND_UP_COUNT(AccessStringLength[i], ALIGN_DWORD); + BufferSize[i] += (ULONG)ROUND_UP_COUNT(UserNameLength[i], ALIGN_DWORD); + BufferSize[i] += (ULONG)ROUND_UP_COUNT(PasswordLength[i], ALIGN_DWORD); + + SetBufferSize += BufferSize[i]; + } + + MbbSetContext = ALLOCATE_NONPAGED_POOL( SetBufferSize ); + + if ( MbbSetContext == NULL ) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory(MbbSetContext, SetBufferSize); + + MbbSetContext->Operation = WwanLteAttachOperationsMapTable[WwanSetContextBuffer->SetContextArray[0].Operation]; + MbbSetContext->ElementCount = TotalRoamingConditions; + + for (ULONG i = 0; i < TotalRoamingConditions; i ++) + { + MbbSetContext->Contexts[i].Offset = SetBufferOffset; + MbbSetContext->Contexts[i].Size = BufferSize[i]; + + MbbLteAttachOffset = FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer); + MbbLteAttachContext = (PMBB_MS_LTE_ATTACH_CONTEXT)((PBYTE)MbbSetContext + SetBufferOffset); + WwanSetLteAttachContext = &(WwanSetContextBuffer->SetContextArray[i]); + + if (WwanSetLteAttachContext->IPType >= WwanIPTypeDefault && + WwanSetLteAttachContext->IPType <= WwanIPTypeIpv4v6) + { + MbbLteAttachContext->IPType = WwanIpTypesMapTable[WwanSetLteAttachContext->IPType]; + } + else + { + MbbLteAttachContext->IPType = MbbContextIPTypeMaximum; + } + + MbbLteAttachContext->Roaming = (MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL)WwanSetLteAttachContext->Roaming; + + if (WwanSetLteAttachContext->Source >= WwanUserProvisioned && + WwanSetLteAttachContext->Source < WwanMaxProvisionSource) + { + MbbLteAttachContext->Source = WwanSourcsMapTable[WwanSetLteAttachContext->Source]; + } + else + { + MbbLteAttachContext->Source = MbbMsContextSourceMaximum; + } + + MbbLteAttachOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbLteAttachContext, + BufferSize[i], + MbbLteAttachOffset, + &MbbLteAttachContext->AccessString, + (PCUCHAR)(WwanSetLteAttachContext->basicInfo.AccessString), + (ULONG)AccessStringLength[i] + ); + + MbbLteAttachOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbLteAttachContext, + BufferSize[i], + MbbLteAttachOffset, + &MbbLteAttachContext->UserName, + (PCUCHAR)(WwanSetLteAttachContext->basicInfo.UserName), + (ULONG)UserNameLength[i] + ); + + MbbLteAttachOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbLteAttachContext, + BufferSize[i], + MbbLteAttachOffset, + &MbbLteAttachContext->Password, + (PCUCHAR)(WwanSetLteAttachContext->basicInfo.Password), + (ULONG)PasswordLength[i] + ); + + MbbLteAttachContext->Compression = (MBB_COMPRESSION)WwanSetLteAttachContext->basicInfo.Compression; + MbbLteAttachContext->AuthProtocol = (MBB_AUTH_PROTOCOL)WwanSetLteAttachContext->basicInfo.AuthType; + + SetBufferOffset += BufferSize[i]; + } + + *ReturnedBufferSize=SetBufferSize; + *ReturnedMbbSetContext=MbbSetContext; + + return STATUS_SUCCESS; +} + + +NTSTATUS +MbbUtilWwanToMbbSetContext( + __in PWWAN_SET_CONTEXT WwanSetContext, + __out PMBB_SET_CONTEXT *ReturnedMbbSetContext, + __out ULONG *ReturnedBufferSize + ) +{ + + + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_SET_CONTEXT MbbSetContext=NULL; + NTSTATUS Status; + SIZE_T AccessStringLength; + SIZE_T UserNameLength; + SIZE_T PasswordLength; + SIZE_T ProviderIdLength; + + *ReturnedBufferSize=0; + *ReturnedMbbSetContext=NULL; + + BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_CONTEXT,DataBuffer), ALIGN_DWORD); + + Status=RtlStringCbLengthW(WwanSetContext->AccessString, sizeof(WwanSetContext->AccessString), &AccessStringLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status=RtlStringCbLengthW(WwanSetContext->UserName, sizeof(WwanSetContext->UserName), &UserNameLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status=RtlStringCbLengthW(WwanSetContext->Password, sizeof(WwanSetContext->Password), &PasswordLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status=RtlStringCbLengthW(WwanSetContext->ProviderId, sizeof(WwanSetContext->ProviderId), &ProviderIdLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + + + BufferSize+=(ULONG)ROUND_UP_COUNT(AccessStringLength, ALIGN_DWORD); + BufferSize+=(ULONG)ROUND_UP_COUNT(UserNameLength, ALIGN_DWORD); + BufferSize+=(ULONG)ROUND_UP_COUNT(PasswordLength, ALIGN_DWORD); + BufferSize+=(ULONG)ROUND_UP_COUNT(ProviderIdLength, ALIGN_DWORD); + + MbbSetContext = ALLOCATE_NONPAGED_POOL( BufferSize ); + + if ( MbbSetContext == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + CurrentOffset = FIELD_OFFSET( MBB_SET_CONTEXT_STATE, DataBuffer ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContext, + BufferSize, + CurrentOffset, + &MbbSetContext->AccessString, + (PCUCHAR)(WwanSetContext->AccessString), + (ULONG)AccessStringLength + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContext, + BufferSize, + CurrentOffset, + &MbbSetContext->UserName, + (PCUCHAR)(WwanSetContext->UserName), + (ULONG)UserNameLength + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContext, + BufferSize, + CurrentOffset, + &MbbSetContext->Password, + (PCUCHAR)(WwanSetContext->Password), + (ULONG)PasswordLength + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContext, + BufferSize, + CurrentOffset, + &MbbSetContext->ProviderId, + (PCUCHAR)(WwanSetContext->ProviderId), + (ULONG)ProviderIdLength + ); + + + MbbSetContext->ContextId = WwanSetContext->ContextId; + MbbSetContext->Compression = (MBB_COMPRESSION)WwanSetContext->Compression; + MbbSetContext->AuthProtocol = (MBB_AUTH_PROTOCOL)WwanSetContext->AuthType; + + MbbUtilWwanToMbbContextType( + WwanSetContext->ContextType, + &MbbSetContext->ContextType + ); + + *ReturnedBufferSize=BufferSize; + *ReturnedMbbSetContext=MbbSetContext; + + return STATUS_SUCCESS; + +} + +NTSTATUS +MbbUtilWwanToMbbSetContextV2( + __in PWWAN_SET_PROVISIONED_CONTEXT_V2 WwanSetContext, + __out PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 *ReturnedMbbSetContext, + __out ULONG *ReturnedBufferSize +) +{ + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 MbbSetContext = NULL; + NTSTATUS Status; + SIZE_T AccessStringLength; + SIZE_T UserNameLength; + SIZE_T PasswordLength; + SIZE_T ProviderIdLength; + + *ReturnedBufferSize = 0; + *ReturnedMbbSetContext = NULL; + + BufferSize = ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2, DataBuffer), ALIGN_DWORD); + + Status = RtlStringCbLengthW(WwanSetContext->basicInfo.AccessString, sizeof(WwanSetContext->basicInfo.AccessString), &AccessStringLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status = RtlStringCbLengthW(WwanSetContext->basicInfo.UserName, sizeof(WwanSetContext->basicInfo.UserName), &UserNameLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status = RtlStringCbLengthW(WwanSetContext->basicInfo.Password, sizeof(WwanSetContext->basicInfo.Password), &PasswordLength); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + BufferSize += (ULONG)ROUND_UP_COUNT(AccessStringLength, ALIGN_DWORD); + BufferSize += (ULONG)ROUND_UP_COUNT(UserNameLength, ALIGN_DWORD); + BufferSize += (ULONG)ROUND_UP_COUNT(PasswordLength, ALIGN_DWORD); + + MbbSetContext = ALLOCATE_NONPAGED_POOL(BufferSize); + + if (MbbSetContext == NULL) + { + return NDIS_STATUS_RESOURCES; + } + + CurrentOffset = FIELD_OFFSET(MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2, DataBuffer); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContext, + BufferSize, + CurrentOffset, + &MbbSetContext->AccessString, + (PCUCHAR)(WwanSetContext->basicInfo.AccessString), + (ULONG)AccessStringLength + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContext, + BufferSize, + CurrentOffset, + &MbbSetContext->UserName, + (PCUCHAR)(WwanSetContext->basicInfo.UserName), + (ULONG)UserNameLength + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetContext, + BufferSize, + CurrentOffset, + &MbbSetContext->Password, + (PCUCHAR)(WwanSetContext->basicInfo.Password), + (ULONG)PasswordLength + ); + + + MbbSetContext->Compression = (MBB_COMPRESSION)WwanSetContext->basicInfo.Compression; + MbbSetContext->AuthProtocol = (MBB_AUTH_PROTOCOL)WwanSetContext->basicInfo.AuthType; + + MbbUtilWwanToMbbContextType( + WwanSetContext->basicInfo.ContextType, + &MbbSetContext->ContextType + ); + + MbbSetContext->Operation = (MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS)WwanSetContext->Operation; + MbbSetContext->IPType = WwanIpTypesMapTable[WwanSetContext->IPType]; + MbbSetContext->Enable = (MBB_BASICCONNECTEXT_CONTEXT_ENABLE)WwanSetContext->Enable; + MbbSetContext->Roaming = (MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL)WwanSetContext->Roaming; + MbbSetContext->MediaType = (MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE)WwanSetContext->MediaType; + MbbSetContext->Source = WwanSourcsMapTable[WwanSetContext->Source]; + + *ReturnedBufferSize = BufferSize; + *ReturnedMbbSetContext = MbbSetContext; + + return STATUS_SUCCESS; +} + +// SMS + +MBB_SMS_FORMAT +MbbUtilWwanToMbbSmsFormat( + __in WWAN_SMS_FORMAT WwanSmsFormat + ) +{ + switch( WwanSmsFormat ) + { + case WwanSmsFormatPdu: + return MbbSmsFormatPdu; + case WwanSmsFormatCdma: + return MbbSmsFormatCdma; + default: + return MbbSmsFormatMaximum; + } +} + +NTSTATUS +MbbUtilWwanToMbbSmsSetConfiguration( + __in PWWAN_SET_SMS_CONFIGURATION WwanSmsSetConfiguration, + __in ULONG ScAddressSize, + __out PMBB_SET_SMS_CONFIGURATION *MbbSmsSetConfigurationReturn, + __out PULONG ReturnedBufferSize + ) +{ + NTSTATUS NtStatus; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + WCHAR WideCharBuffer[WWAN_SMS_ADDRESS_MAX_LEN]; + PMBB_SET_SMS_CONFIGURATION MbbSmsSetConfiguration=NULL; + PBYTE Buffer=NULL; + ULONG BufferSize=0; + ULONG CurrentOffset=0; + + *MbbSmsSetConfigurationReturn=NULL; + *ReturnedBufferSize=0; + + + AnsiString.Buffer = WwanSmsSetConfiguration->ScAddress; + AnsiString.Length = (USHORT)ScAddressSize; + AnsiString.MaximumLength = WWAN_SMS_ADDRESS_MAX_LEN - 1; // No NULL + + UnicodeString.Buffer = &WideCharBuffer[0]; + UnicodeString.Length = 0; + UnicodeString.MaximumLength = sizeof(WideCharBuffer); + + + NtStatus = RtlAnsiStringToUnicodeString( + &UnicodeString, + &AnsiString, + FALSE // AllocateDestinationString + ); + + if ( NtStatus != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_UTIL, "[MbbNdis] FAILED to convert ScAddress Length=%dbytes, NtStatus=%!STATUS!", + AnsiString.Length, NtStatus + ); + ASSERT(0); + return NtStatus; + } + + BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_SMS_CONFIGURATION,DataBuffer), ALIGN_DWORD); + + CurrentOffset=BufferSize; + + + BufferSize+=(ULONG)ROUND_UP_COUNT(ScAddressSize * sizeof(WCHAR), ALIGN_DWORD); + + MbbSmsSetConfiguration = ALLOCATE_NONPAGED_POOL( BufferSize ); + + if (MbbSmsSetConfiguration == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer=(PUCHAR)MbbSmsSetConfiguration; + + MbbSmsSetConfiguration->SmsFormat = MbbUtilWwanToMbbSmsFormat( WwanSmsSetConfiguration->SmsFormat ); + + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + &MbbSmsSetConfiguration->ScAddress, + (PUCHAR)&WideCharBuffer[0], + (ULONG)ScAddressSize * sizeof(WCHAR) + ); + + *MbbSmsSetConfigurationReturn=MbbSmsSetConfiguration; + *ReturnedBufferSize=BufferSize; + + return STATUS_SUCCESS; + +} + +VOID +MbbUtilWwanToMbbSmsRead( + __in PWWAN_SMS_READ WwanSmsRead, + __out PMBB_SMS_READ MbbSmsRead + ) +{ + MbbSmsRead->SmsFormat = MbbUtilWwanToMbbSmsFormat( WwanSmsRead->SmsFormat ); + MbbSmsRead->SmsFlag = (MBB_SMS_FLAG)WwanSmsRead->ReadFilter.Flag; + MbbSmsRead->MessageIndex = WwanSmsRead->ReadFilter.MessageIndex; +} + +NDIS_STATUS +MbbUtilHexStringToUchar( + __in_ecount(2) PCHAR HexString, + __out PUCHAR Value + ) +/*++ + Description + On success Value is populated with the value of the hex string. + On failure, Value is undefined. +--*/ +{ + ULONG NibbleIndex; + UCHAR Nibbles[2]; + UCHAR NibbleAscii; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + for( NibbleIndex = 0; NibbleIndex < 2; NibbleIndex++ ) + { + NibbleAscii = HexString[NibbleIndex]; + + if( NibbleAscii >= 'a' && NibbleAscii <= 'f' ) + { + Nibbles[NibbleIndex] = 10 + NibbleAscii - 'a'; + } + else if( NibbleAscii >= 'A' && NibbleAscii <= 'F' ) + { + Nibbles[NibbleIndex] = 10 + NibbleAscii - 'A'; + } + else if( NibbleAscii >= '0' && NibbleAscii <= '9' ) + { + Nibbles[NibbleIndex] = NibbleAscii - '0'; + } + else + { + NdisStatus = NDIS_STATUS_FAILURE; + break; + } + } + + if( NdisStatus == NDIS_STATUS_SUCCESS ) + *Value = (Nibbles[0] * 16) + Nibbles[1]; + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilHexStringToByteStream( + __in_bcount_z(HexStringSize) PCHAR HexString, + __in ULONG HexStringSize, + __out_bcount(ByteStreamSize) PUCHAR ByteStream, + __in ULONG ByteStreamSize + ) +{ + ULONG i; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + for( i = 0; + i < ByteStreamSize && + ((i * 2) + 1) < HexStringSize; + i ++ ) + { + if( (NdisStatus = MbbUtilHexStringToUchar( + &HexString[i*2], + &ByteStream[i] + )) != NDIS_STATUS_SUCCESS ) + { + break; + } + } + return NdisStatus; +} + +VOID +MbbUtilByteStreamToHexString( + __in_bcount(ByteStreamSize) PUCHAR ByteStream, + __in ULONG ByteStreamSize, + __out_bcount_z(HexStringSize) PCHAR HexString, + __in ULONG HexStringSize + ) +{ + ULONG i; + UCHAR UpperNibble; + UCHAR LowerNibble; + CHAR AsciiTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + for( i = 0; + i < ByteStreamSize && + ((i * 2) + 1) < HexStringSize; + i ++ ) + { + UpperNibble = ( ByteStream[i] >> 4 ) & 0x0F; + LowerNibble = ByteStream[i] & 0x0F; + + HexString[i*2] = AsciiTable[UpperNibble]; + HexString[(i*2)+1] = AsciiTable[LowerNibble]; + } + HexString[MIN( (i*2), (HexStringSize-1) )] = 0; +} + +NDIS_STATUS +MbbUtilWwanToMbbSmsSendPdu( + __in PWWAN_SMS_SEND_PDU WwanSmsSendPdu, + __in MBB_CELLULAR_CLASS CellularClass, + __out PMBB_SMS_SEND *ReturnedMbbSmsSend, + __out PULONG MbbSmsSendSize + ) +{ + UCHAR SmscAddressLength = 0; + SIZE_T PduDataCbLength; + ULONG PduDataLength; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PMBB_SMS_SEND_PDU MbbSmsSendPdu=NULL; + ULONG CurrentOffset=0; + ULONG BufferSize = 0; + PUCHAR Buffer = NULL; + + ULONG OuterBufferSize = 0; + PUCHAR OuterBuffer = NULL; + ULONG InitialOffset=0; + + do + { + // + // add some space at the beginning, for the contain struct + // + InitialOffset = FIELD_OFFSET( MBB_SMS_SEND, u.Pdu ); + + if( CellularClass == MbbCellularClassGsm ) + { + // + // the first two bytes are the hex encoded length of smsc address. + // + NdisStatus=MbbUtilHexStringToUchar( + WwanSmsSendPdu->PduData, + &SmscAddressLength + ); + + + if( NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID hexstring for SMSC Address Length=%1c%1c", + WwanSmsSendPdu->PduData[0], + WwanSmsSendPdu->PduData[1] + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + // + // The encoded size is for the raw data. + // Add one byte for the SmscAddressLength itself. + // + SmscAddressLength++; + PduDataLength = WwanSmsSendPdu->Size; + + // + // Validate the buffer given by the service + // + if( (NdisStatus = RtlStringCbLengthA( + WwanSmsSendPdu->PduData, + sizeof(WwanSmsSendPdu->PduData), + &PduDataCbLength + )) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] FAILED to get string length for WwanSmsSendPdu->PduData, NtStatus=%!STATUS!", NdisStatus ); + break; + } + + // + // PduDataCbLength is the length of the null terminated string of hex digits from the service. + // PduDataLength is the declarded length of the PDU data from service not including the smsc address + // + if( ((PduDataCbLength/2) - SmscAddressLength) != PduDataLength ) + { + TraceError( WMBCLASS_UTIL, "[Util][Sms] INVALID WwanSmsSendPdu->Size=%d != PduDataStringLength=%d - SmscAddressLength=%d", + PduDataLength, + (ULONG)(PduDataCbLength/2), + SmscAddressLength + ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + + + BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SMS_SEND_PDU, DataBuffer), ALIGN_DWORD); + + CurrentOffset=BufferSize; + + BufferSize+=(ULONG)ROUND_UP_COUNT(PduDataLength + SmscAddressLength, ALIGN_DWORD); + + // + // Outer buffer has storage for the containing structure as well + // + OuterBufferSize = InitialOffset + BufferSize; + + OuterBuffer = ALLOCATE_NONPAGED_POOL(OuterBufferSize); + + if (OuterBuffer == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer=OuterBuffer + InitialOffset; + + MbbSmsSendPdu=(PMBB_SMS_SEND_PDU)Buffer; + + + // + // PduSize in the mbb message is the whole message len+smsc+pdudata + // + MbbSmsSendPdu->PduData.Size = PduDataLength + SmscAddressLength; + MbbSmsSendPdu->PduData.Offset = ROUND_UP_COUNT(FIELD_OFFSET(MBB_SMS_SEND_PDU, DataBuffer), ALIGN_DWORD); + + // + // convert the hex encoded data to binary data + // + NdisStatus = MbbUtilHexStringToByteStream( + WwanSmsSendPdu->PduData, + (PduDataLength + SmscAddressLength) * 2, + ((PUCHAR)MbbSmsSendPdu) + MbbSmsSendPdu->PduData.Offset, + MbbSmsSendPdu->PduData.Size + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_UTIL, "[Util][Sms] FAILED to convert hexstring to bytestream NdisStatus=%!STATUS!", NdisStatus ); + break; + } + } + else + { + BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SMS_SEND_PDU, DataBuffer), ALIGN_DWORD); + + CurrentOffset=BufferSize; + + BufferSize+=(ULONG)ROUND_UP_COUNT(WwanSmsSendPdu->Size, ALIGN_DWORD); + + // + // Outer buffer has storage for the containing structure as well + // + OuterBufferSize = InitialOffset + BufferSize; + + OuterBuffer = ALLOCATE_NONPAGED_POOL(OuterBufferSize); + + if (OuterBuffer == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer=OuterBuffer + InitialOffset; + + MbbSmsSendPdu=(PMBB_SMS_SEND_PDU)Buffer; + + MbbSmsSendPdu->PduData.Offset=CurrentOffset; + MbbSmsSendPdu->PduData.Size=WwanSmsSendPdu->Size; + + RtlCopyMemory( + ((PUCHAR)MbbSmsSendPdu) + MbbSmsSendPdu->PduData.Offset, + WwanSmsSendPdu->PduData, + WwanSmsSendPdu->Size + ); + + MbbSmsSendPdu->PduData.Size = WwanSmsSendPdu->Size; + } + + *MbbSmsSendSize = OuterBufferSize; + + *ReturnedMbbSmsSend = (PMBB_SMS_SEND)OuterBuffer; + + TraceInfo( WMBCLASS_UTIL, "[Util][Sms] Received PDU send record, CurrentCellularClass=%!MbbCellularClass! PduDataSize=0x%08x SmscAddressLength=0x%08x", + CellularClass, + WwanSmsSendPdu->Size, + SmscAddressLength + ); + TraceInfo( WMBCLASS_UTIL, "[Util][Sms] Converted to PDU record of size 0x%08x, PduDataSize=0x%08x", + *MbbSmsSendSize, + MbbSmsSendPdu->PduData.Size + ); + } + while( FALSE ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + if (OuterBuffer != NULL) + { + FREE_POOL(OuterBuffer); + *MbbSmsSendSize = 0; + *ReturnedMbbSmsSend = NULL; + } + } + return NdisStatus; +} + +NDIS_STATUS +MbbUtilWwanToMbbSmsSendCdma( + __in PWWAN_SMS_SEND_CDMA WwanSmsSendCdma, + __out PMBB_SMS_SEND *ReturnedMbbSmsSend, + __out PULONG MbbSmsSendSize + ) +{ + ULONG CurrentOffset; + SIZE_T StringCbLength; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + WCHAR TempWideString[WWAN_SMS_CDMA_ADDR_MAX_LEN]; + ULONG BufferSize = 0; + PUCHAR Buffer = NULL; + + ULONG OuterBufferSize = 0; + PUCHAR OuterBuffer = NULL; + ULONG InitialOffset=0; + + PMBB_SMS_SEND_CDMA MbbSmsSendCdma=NULL; + + *ReturnedMbbSmsSend=NULL; + *MbbSmsSendSize=0; + + do + { + // + // add some space at the beginning, for the contain struct + // + InitialOffset = FIELD_OFFSET( MBB_SMS_SEND, u.Cdma ); + + + BufferSize += ROUND_UP_COUNT( FIELD_OFFSET( MBB_SMS_SEND_CDMA, DataBuffer ), ALIGN_DWORD ); + + // + // Address + // + if( (NdisStatus = RtlStringCbLengthA( + WwanSmsSendCdma->Address, + WWAN_SMS_CDMA_ADDR_MAX_LEN, + &StringCbLength + )) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] FAILED to get string length for CDMA Address NtStatus=%!STATUS!", NdisStatus ); + return NdisStatus; + } + + BufferSize += ROUND_UP_COUNT( StringCbLength * sizeof(WCHAR), ALIGN_DWORD ); + + BufferSize += ROUND_UP_COUNT( WwanSmsSendCdma->SizeInBytes, ALIGN_DWORD ); + + // + // Outer buffer has storage for the containing structure as well + // + OuterBufferSize = InitialOffset + BufferSize; + +#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate to a outgoing reference ReturnedMbbSmsSend.") + OuterBuffer = ALLOCATE_NONPAGED_POOL(OuterBufferSize); + + if (OuterBuffer == NULL ) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer=OuterBuffer + InitialOffset; + + MbbSmsSendCdma=(PMBB_SMS_SEND_CDMA)Buffer; + + MbbSmsSendCdma->EncodingId = (MBB_SMS_CDMA_ENCODING)WwanSmsSendCdma->EncodingId; + MbbSmsSendCdma->LanguageId = (MBB_SMS_CDMA_LANGUAGE)WwanSmsSendCdma->LanguageId; + MbbSmsSendCdma->SizeInCharacters = WwanSmsSendCdma->SizeInCharacters; + + + + CurrentOffset = ROUND_UP_COUNT( FIELD_OFFSET( MBB_SMS_SEND_CDMA, DataBuffer ), ALIGN_DWORD ); + + TraceInfo( WMBCLASS_UTIL, "[Util][Sms] Received CDMA send record, EncodingId=0x%08x LanguageId=0x%08x Address[Sz=0x%08x] EncodedMessage[Sz=0x%08x SzCh=0x%08x]", + WwanSmsSendCdma->EncodingId, + WwanSmsSendCdma->LanguageId, + (ULONG)StringCbLength, + WwanSmsSendCdma->SizeInBytes, + WwanSmsSendCdma->SizeInCharacters + ); + + AnsiString.Buffer = WwanSmsSendCdma->Address; + AnsiString.Length = (USHORT)StringCbLength; + AnsiString.MaximumLength = WWAN_SMS_CDMA_ADDR_MAX_LEN; + + UnicodeString.Buffer = &TempWideString[0]; + UnicodeString.Length = 0; + UnicodeString.MaximumLength = sizeof(TempWideString); + + if( (NdisStatus = RtlAnsiStringToUnicodeString( + &UnicodeString, + &AnsiString, + FALSE // AllocateDestinationString + )) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_UTIL, "[Util][Sms] FAILED to convert WwanSmsSendCdma->Address Length=%dbytes, NtStatus=%!STATUS!", + AnsiString.Length, NdisStatus + ); + break; + } + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + &MbbSmsSendCdma->Address, + (PUCHAR)&TempWideString[0], + (ULONG)StringCbLength * sizeof(WCHAR) + ); + + CurrentOffset=MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbSmsSendCdma->EncodedMessage, + (PUCHAR)WwanSmsSendCdma->EncodedMsg, + WwanSmsSendCdma->SizeInBytes + ); + + // + // MessageSize + // + *MbbSmsSendSize = OuterBufferSize; + *ReturnedMbbSmsSend = (PMBB_SMS_SEND)OuterBuffer; + + TraceInfo( WMBCLASS_OID, "[Util][Sms] Converted to CDMA send record of size 0x%08x, Address[Off=0x%08x Sz=0x%08x] EncodedMessage[Off=0x%08x Sz=0x%08x SzCh=0x%08x]", + *MbbSmsSendSize, + MbbSmsSendCdma->Address.Offset, + MbbSmsSendCdma->Address.Size, + MbbSmsSendCdma->EncodedMessage.Offset, + MbbSmsSendCdma->EncodedMessage.Size, + MbbSmsSendCdma->SizeInCharacters + ); + } + while( FALSE ); + + return NdisStatus; +} + + +VOID +MbbUtilWwanToMbbSmsDelete( + __in PWWAN_SMS_FILTER WwanSmsFilter, + __out PMBB_SMS_DELETE MbbSmsDelete + ) +{ + MbbSmsDelete->SmsFlags = (MBB_SMS_FLAG)WwanSmsFilter->Flag; + MbbSmsDelete->MessageIndex = WwanSmsFilter->MessageIndex; +} + +NDIS_STATUS +MbbUtilWwanToMbbSubscribeEvents( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in_ecount(GuidCount) GUID* GuidList, + __in ULONG GuidCount, + __in BOOL ExternalRequest, + __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, + __in ULONG ExtSubscribeListSize, + __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, + __out PULONG OutputSubscribeBufferSize + ) +{ + ULONG i = 0; + PMBB_DS deviceServiceEntry = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG ResultSize = 0; + PMBB_SUBSCRIBE_EVENT_LIST MbbSubscribeList = NULL; + ULONG MbbSubscribeListSize = 0; + PMBB_SUBSCRIBE_EVENT_ENTRY EventEntry = NULL; + ULONG DeviceServiceCount = 0; + ULONG CurrentOffset; + + *OutputSubscribeList = NULL; + *OutputSubscribeBufferSize = 0; + + do + { + // + // Determine the size of the total list by going through all device services + // & combining that with the CID list length + // + MbbSubscribeListSize = FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement); + + for (i = 0; i < GuidCount; i++) + { + // If this is an external request, reject native services + // + if (ExternalRequest && MbbUtilIsNativeMbnService(&GuidList[i])) + { + // Native device services cannot be subscribed to using this path + TraceError( WMBCLASS_OID, "[Util] FAILED because of subscribe request for native device service %!GUID!", + &GuidList[i] + ); + + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + + // + // Find this device service so that we can get the CID list + // + deviceServiceEntry = MbbUtilFindDeviceService(Adapter, + &GuidList[i] + ); + if (deviceServiceEntry == NULL) + { + // Unsupported device service + if (ExternalRequest) + { + TraceError( WMBCLASS_OID, "[Util] FAILED because of subscribe request for unsupported device service %!GUID!", + &GuidList[i] + ); + + NdisStatus = NDIS_STATUS_INVALID_DATA; + break; + } + else + { + // Just move to the next for internal GUID lists + continue; + } + } + + MbbSubscribeListSize += sizeof(MBB_ARRAY_ELEMENT); + + // Space for this GUID & its CID list + MbbSubscribeListSize += (FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) + + deviceServiceEntry->CIDCount * sizeof(ULONG) + ); + + DeviceServiceCount++; + + } + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + // Failed due to bad device service in the list + break; + } + + if ((ExtSubscribeList != NULL) && (ExtSubscribeListSize > (ULONG)FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement))) + { + // + // we have another list to merge into this one + // + for (i=0; iCount; i++) + { + DeviceServiceCount++; + MbbSubscribeListSize += sizeof(MBB_ARRAY_ELEMENT); + MbbSubscribeListSize += ExtSubscribeList->ArrayElement[i].Size; + + } + } + + // + // Now allocate memory for the OID's device services subscription + // + MbbSubscribeList = ALLOCATE_NONPAGED_POOL( MbbSubscribeListSize); + + if ( MbbSubscribeList == NULL ) + { + TraceError( WMBCLASS_OID, "[Util] FAILED to allocate %d bytes for OID MBB_SUBSCRIBE_EVENT_LIST, ElementCount=%d", + MbbSubscribeListSize, + GuidCount + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + MbbSubscribeList->Count = DeviceServiceCount; + CurrentOffset=FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement) + (sizeof(MbbSubscribeList->ArrayElement[0]) * MbbSubscribeList->Count); + + // Start copying + + DeviceServiceCount=0; + + for (i = 0; i < GuidCount ; i++) + { + // Find the device service again (validation for the service is already done) + deviceServiceEntry = MbbUtilFindDeviceService(Adapter, + &GuidList[i] + ); + + if (deviceServiceEntry != NULL) + { + + EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)MbbSubscribeList+CurrentOffset); + + // OACR complains below that the size is small, but its really not because we + // checked before for the size + + // Copy the GUID (changing length) + MBB_UUID_TO_NET(&EventEntry->DeviceServiceId, + &GuidList[i] + ); + + // CID Count + EventEntry->CIDCount = deviceServiceEntry->CIDCount; + + // Copy the CIDs + RtlCopyMemory(EventEntry->CIDList, + deviceServiceEntry->CIDList, + sizeof(ULONG) * EventEntry->CIDCount + ); + + + MbbSubscribeList->ArrayElement[DeviceServiceCount].Offset=CurrentOffset; + MbbSubscribeList->ArrayElement[DeviceServiceCount].Size= FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) + deviceServiceEntry->CIDCount * sizeof(ULONG); + + CurrentOffset += FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) + deviceServiceEntry->CIDCount * sizeof(ULONG); + + DeviceServiceCount++; + + } + else + { + // Not supported by device, skip + } + + } + + if ((ExtSubscribeList != NULL) && (ExtSubscribeListSize > (ULONG)FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement))) + { + // + // we have another list to merge into this one + // + for (i=0; iCount; i++) + { + EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)MbbSubscribeList+CurrentOffset); + + MbbSubscribeList->ArrayElement[DeviceServiceCount].Offset=CurrentOffset; + MbbSubscribeList->ArrayElement[DeviceServiceCount].Size= ExtSubscribeList->ArrayElement[i].Size; + + RtlCopyMemory( + EventEntry, + ((PBYTE)ExtSubscribeList+ExtSubscribeList->ArrayElement[i].Offset), + ExtSubscribeList->ArrayElement[i].Size + ); + + CurrentOffset += ExtSubscribeList->ArrayElement[i].Size; + + DeviceServiceCount++; + } + } + + + *OutputSubscribeList = MbbSubscribeList; + *OutputSubscribeBufferSize = MbbSubscribeListSize; + + } while (FALSE); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + if (MbbSubscribeList) + { + FREE_POOL(MbbSubscribeList); + } + } + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilGenerateLowPowerSubscribeEventList( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in ULONG MediaSpecificWakeUpEvents, + __in ULONG WakeUpFlags, + __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, + __out PULONG OutputSubscribeListSize + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG NativeSubscribeCount=0; + ULONG NativeSubscribeListSize = 0; + PMBB_SUBSCRIBE_EVENT_LIST NativeSubscribeList = NULL; + PMBB_SUBSCRIBE_EVENT_ENTRY EventEntry = NULL; + ULONG i = 0; + ULONG CurrentOffset = 0; + ULONG CurrentEvent = 0; + ULONG BasicConnectCommands = 0; + + do + { + // Determine required size based on MediaSpecicWakeUpEvents and WakeUpFlags (grouped by service ID) + + // Count number of MBB_UUID_BASIC_CONNECT_CONSTANT wake ups + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_REGISTER_STATE_ENABLED) + { + BasicConnectCommands++; + } + + if (WakeUpFlags & NDIS_PM_WAKE_ON_MEDIA_DISCONNECT_ENABLED) + { + BasicConnectCommands++; + } + + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_PACKET_STATE_ENABLED) + { + BasicConnectCommands++; + } + + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_UICC_CHANGE_ENABLED) + { + BasicConnectCommands++; + } + + if (BasicConnectCommands > 0) + { + NativeSubscribeCount++; + NativeSubscribeListSize += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) ; + + NativeSubscribeListSize += sizeof(ULONG) * BasicConnectCommands-1; + } + + // Count number of MBB_UUID_SMS_CONSTANT wake ups + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_SMS_RECEIVE_ENABLED) + { + NativeSubscribeCount++; + NativeSubscribeListSize += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) ; + } + + // Count number of MBB_UUID_USSD_CONSTANT wake ups + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_USSD_RECEIVE_ENABLED) + { + NativeSubscribeCount++; + NativeSubscribeListSize += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) ; + } + + NativeSubscribeListSize += FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement); + NativeSubscribeListSize += sizeof(MBB_ARRAY_ELEMENT) * NativeSubscribeCount; + + if( (NativeSubscribeList = ALLOCATE_NONPAGED_POOL( NativeSubscribeListSize )) == NULL ) + { + TraceError( WMBCLASS_OID, "[Util] FAILED to allocate %d bytes for low power MBB_SUBSCRIBE_EVENT_LIST", + NativeSubscribeListSize + ); + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + + *OutputSubscribeListSize = NativeSubscribeListSize; + NativeSubscribeList->Count = NativeSubscribeCount; + + CurrentOffset=FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement) + (sizeof(NativeSubscribeList->ArrayElement[0]) * NativeSubscribeList->Count); + + // Populate the subsribe list with the MBB_UUID_BASIC_CONNECT_CONSTANT wake ups + if (BasicConnectCommands > 0) + { + GUID TempGuid=MBB_UUID_BASIC_CONNECT_CONSTANT; + + EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)NativeSubscribeList+CurrentOffset); + + MBB_UUID_TO_NET(&EventEntry->DeviceServiceId, &TempGuid); + EventEntry->CIDCount = BasicConnectCommands; + + i=0; + + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_REGISTER_STATE_ENABLED) + { + EventEntry->CIDList[i]=MBB_BASIC_CID_REGISTER_STATE; + i++; + } + if (WakeUpFlags & NDIS_PM_WAKE_ON_MEDIA_DISCONNECT_ENABLED) + { + EventEntry->CIDList[i]=MBB_BASIC_CID_CONNECT; + i++; + } + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_PACKET_STATE_ENABLED) + { + EventEntry->CIDList[i]=MBB_BASIC_CID_PACKET_SERVICE; + i++; + } + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_UICC_CHANGE_ENABLED) + { + EventEntry->CIDList[i]=MBB_BASIC_CID_SUBSCRIBER_READY_INFO; + i++; + } + + NativeSubscribeList->ArrayElement[CurrentEvent].Offset=CurrentOffset; + NativeSubscribeList->ArrayElement[CurrentEvent].Size= RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList[i-1]); + + CurrentEvent++; + // Next event entry + CurrentOffset += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList[i-1]); + } + + // Populate the subsribe list with the MBB_UUID_SMS_CONSTANT wake ups + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_SMS_RECEIVE_ENABLED) + { + GUID TempGuid=MBB_UUID_SMS_CONSTANT; + + EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)NativeSubscribeList+CurrentOffset); + + MBB_UUID_TO_NET(&EventEntry->DeviceServiceId, &TempGuid); + EventEntry->CIDCount = 1; + EventEntry->CIDList[0]=MBB_SMS_CID_STATUS; + + // Next event entry + NativeSubscribeList->ArrayElement[CurrentEvent].Offset=CurrentOffset; + NativeSubscribeList->ArrayElement[CurrentEvent].Size= RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList); + + CurrentEvent++; + + // Next event entry + CurrentOffset += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList); + } + + // Populate the subsribe list with the MBB_UUID_USSD_CONSTANT wake ups + if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_USSD_RECEIVE_ENABLED) + { + GUID TempGuid=MBB_UUID_USSD_CONSTANT; + + EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)NativeSubscribeList+CurrentOffset); + + MBB_UUID_TO_NET(&EventEntry->DeviceServiceId, &TempGuid); + EventEntry->CIDCount = 1; + EventEntry->CIDList[0]=MBB_USSD_CID_USSD; + + // Next event entry + NativeSubscribeList->ArrayElement[CurrentEvent].Offset=CurrentOffset; + NativeSubscribeList->ArrayElement[CurrentEvent].Size= RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList); + + CurrentEvent++; + + // Next event entry + CurrentOffset += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList); + } + + *OutputSubscribeList = NativeSubscribeList; + NativeSubscribeList = NULL; + } + while (FALSE); + + if (NativeSubscribeList != NULL) + FREE_POOL(NativeSubscribeList); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilGenerateFullPowerSubscribeEventList( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, + __in ULONG ExtSubscribeListSize, + __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, + __out PULONG OutputSubscribeListSize + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + PMBB_SUBSCRIBE_EVENT_LIST MergedSubscribeList = NULL; + ULONG MergedSubscribeBufferSize = 0; + + *OutputSubscribeList = NULL; + *OutputSubscribeListSize = 0; + do + { + // + // This function's job is to take the native device serices & create + // the subscribe list (with CIDs) for them. Also, take the extensibility device service subscribe list + // and merge it into the other list. It optimizes memory management by allocating memory + // for both lists when it creates the native device service's subscribe list + // + + // Fill the native one & leave space for the extensibility list + NdisStatus = MbbUtilWwanToMbbSubscribeEvents(Adapter, + NativeMbnServices, + ARRAYSIZE(NativeMbnServices), + FALSE, + ExtSubscribeList, + ExtSubscribeListSize, + &MergedSubscribeList, + &MergedSubscribeBufferSize + ); + + if( NdisStatus != NDIS_STATUS_SUCCESS) + { + TraceError( WMBCLASS_OID, "[Util] FAILED to allocate memory for merged MBB_SUBSCRIBE_EVENT_LIST"); + break; + } + + + *OutputSubscribeList = MergedSubscribeList; + *OutputSubscribeListSize = MergedSubscribeBufferSize; + MergedSubscribeList = NULL; + } + while (FALSE); + + if (MergedSubscribeList != NULL) + FREE_POOL(MergedSubscribeList); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilGenerateSubscribeEventList( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN FullPower, + __in ULONG MediaSpecificWakeUpEvents, + __in ULONG WakeUpFlags, + __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, + __in ULONG ExtSubscribeListSize, + __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, + __out PULONG OutputSubscribeListSize + ) +{ + if (FullPower) + { + // Will generate the full list + return MbbUtilGenerateFullPowerSubscribeEventList( + Adapter, + ExtSubscribeList, + ExtSubscribeListSize, + OutputSubscribeList, + OutputSubscribeListSize + ); + } + else + { + // Generate a limit list + return MbbUtilGenerateLowPowerSubscribeEventList( + Adapter, + MediaSpecificWakeUpEvents, + WakeUpFlags, + OutputSubscribeList, + OutputSubscribeListSize + ); + } + +} + +NDIS_STATUS +MbbUtilWwanToMbbAkapAuthChallenge( + __in PWWAN_AUTH_AKAP_CHALLENGE WwanAuthAkapChallenge, + __in ULONG UTF16ByteCount, + __in ULONG MbbSize, + __out_bcount(MbbSize) PMBB_AKAP_AUTH_CHALLENGE MbbAkapAuthChallenge + ) +{ + ULONG CurrentOffset; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + + if( MbbSize < sizeof(MBB_AKAP_AUTH_CHALLENGE) ) + { + return NDIS_STATUS_BUFFER_OVERFLOW; + } + RtlCopyMemory( + MbbAkapAuthChallenge->Rand, + WwanAuthAkapChallenge->Rand, + WWAN_AUTH_RAND_LEN + ); + RtlCopyMemory( + MbbAkapAuthChallenge->Autn, + WwanAuthAkapChallenge->Autn, + WWAN_AUTH_AUTN_LEN + ); + CurrentOffset = ROUND_UP_COUNT( FIELD_OFFSET( MBB_AKAP_AUTH_CHALLENGE, DataBuffer ), ALIGN_DWORD ); + // + // NetworkName + // + if( MbbSize < (CurrentOffset + UTF16ByteCount) ) + { + return NDIS_STATUS_BUFFER_OVERFLOW; + } + NdisStatus = RtlUTF8ToUnicodeN( + (PWCHAR)(((PCHAR)MbbAkapAuthChallenge) + CurrentOffset), + UTF16ByteCount, + NULL, + (PCCH)(WwanAuthAkapChallenge->NetworkName), + WwanAuthAkapChallenge->NetworkNameLength + ); + if( STATUS_SUCCESS != NdisStatus ) + { + TraceError( WMBCLASS_OID, "[Util] FAILED RtlUTF8ToUnicodeN(AuthAkap.NetworkName=%s)=%!STATUS!, ignoring=%!BOOLEAN!", + WwanAuthAkapChallenge->NetworkName, + NdisStatus, + (STATUS_SOME_NOT_MAPPED == NdisStatus) + ); + if( STATUS_SOME_NOT_MAPPED != NdisStatus ) + return NdisStatus; + else + NdisStatus = STATUS_SUCCESS; + } + + MbbAkapAuthChallenge->NetworkName.Size = UTF16ByteCount; + MbbAkapAuthChallenge->NetworkName.Offset = CurrentOffset; + return NdisStatus; +} + +NDIS_STATUS +MbbUtilWwanToMbbUiccFilePath( + __in PWWAN_UICC_FILE_PATH WwanUiccFilePath, + __deref_out PMBB_UICC_FILE_PATH *MbbUiccFilePathOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; + + *ReturnedBufferSize = 0; + + BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_UICC_FILE_PATH, DataBuffer), ALIGN_DWORD); + + CurrentOffset = BufferSize; + + BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccFilePath->AppIdLength, ALIGN_DWORD); + BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccFilePath->FilePathLength * sizeof(USHORT), ALIGN_DWORD); + + if ((MbbUiccFilePath = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer = (PUCHAR)MbbUiccFilePath; + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbUiccFilePath->AppId, + (PUCHAR)WwanUiccFilePath->AppId, + WwanUiccFilePath->AppIdLength + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbUiccFilePath->FilePath, + (PUCHAR)WwanUiccFilePath->FilePath, + WwanUiccFilePath->FilePathLength * sizeof(USHORT) + ); + + *MbbUiccFilePathOut = MbbUiccFilePath; + + *ReturnedBufferSize = BufferSize; + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbUtilWwanToMbbUiccAccessBinary( + __in PWWAN_UICC_ACCESS_BINARY WwanUiccAccessBinary, + __deref_out_opt PMBB_UICC_ACCESS_BINARY *MbbUiccAccessBinaryOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_UICC_ACCESS_BINARY MbbUiccAccessBinary = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG MbbUiccFilePathLength; + PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; + + *MbbUiccAccessBinaryOut = NULL; + *ReturnedBufferSize = 0; + + BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_UICC_ACCESS_BINARY, DataBuffer), ALIGN_DWORD); + + CurrentOffset = BufferSize; + + NdisStatus = MbbUtilWwanToMbbUiccFilePath( + &WwanUiccAccessBinary->UiccFilePath, + &MbbUiccFilePath, + &MbbUiccFilePathLength + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + goto Cleanup; + } + + BufferSize += (ULONG)ROUND_UP_COUNT(MbbUiccFilePathLength, ALIGN_DWORD); + BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccAccessBinary->LocalPinSize, ALIGN_DWORD); + BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccAccessBinary->BinaryDataSize, ALIGN_DWORD); + + if ((MbbUiccAccessBinary = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) + { + NdisStatus = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + Buffer = (PUCHAR)MbbUiccAccessBinary; + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbUiccAccessBinary->UiccFilePath, + (PUCHAR)MbbUiccFilePath, + MbbUiccFilePathLength + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbUiccAccessBinary->LocalPin, + (PUCHAR)WwanUiccAccessBinary->LocalPin, + WwanUiccAccessBinary->LocalPinSize + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbUiccAccessBinary->BinaryData, + (PUCHAR)WwanUiccAccessBinary->BinaryData, + WwanUiccAccessBinary->BinaryDataSize + ); + + MbbUiccAccessBinary->FileOffset = WwanUiccAccessBinary->FileOffset; + MbbUiccAccessBinary->NumberOfBytes = WwanUiccAccessBinary->NumberOfBytes; + + *MbbUiccAccessBinaryOut = MbbUiccAccessBinary; + *ReturnedBufferSize = BufferSize; + +Cleanup: + if (NULL != MbbUiccFilePath) + { + FREE_POOL(MbbUiccFilePath); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilWwanToMbbUiccAccessRecord( + __in PWWAN_UICC_ACCESS_RECORD WwanUiccAccessRecord, + __deref_out_opt PMBB_UICC_ACCESS_RECORD *MbbUiccAccessRecordOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_UICC_ACCESS_RECORD MbbUiccAccessRecord = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG MbbUiccFilePathLength; + PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; + + *MbbUiccAccessRecordOut = NULL; + *ReturnedBufferSize = 0; + + BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_UICC_ACCESS_RECORD, DataBuffer), ALIGN_DWORD); + + CurrentOffset = BufferSize; + + NdisStatus = MbbUtilWwanToMbbUiccFilePath( + &WwanUiccAccessRecord->UiccFilePath, + &MbbUiccFilePath, + &MbbUiccFilePathLength + ); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + goto Cleanup; + } + + BufferSize += (ULONG)ROUND_UP_COUNT(MbbUiccFilePathLength, ALIGN_DWORD); + BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccAccessRecord->LocalPinSize, ALIGN_DWORD); + BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccAccessRecord->RecordDataSize, ALIGN_DWORD); + + if ((MbbUiccAccessRecord = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) + { + NdisStatus = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + Buffer = (PUCHAR)MbbUiccAccessRecord; + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbUiccAccessRecord->UiccFilePath, + (PUCHAR)MbbUiccFilePath, + MbbUiccFilePathLength + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbUiccAccessRecord->LocalPin, + (PUCHAR)WwanUiccAccessRecord->LocalPin, + WwanUiccAccessRecord->LocalPinSize + ); + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbUiccAccessRecord->RecordData, + (PUCHAR)WwanUiccAccessRecord->RecordData, + WwanUiccAccessRecord->RecordDataSize + ); + + MbbUiccAccessRecord->RecordNumber = WwanUiccAccessRecord->RecordNumber; + + *MbbUiccAccessRecordOut = MbbUiccAccessRecord; + *ReturnedBufferSize = BufferSize; + +Cleanup: + if (NULL != MbbUiccFilePath) + { + FREE_POOL(MbbUiccFilePath); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilWwanToMbbPinApp( + __in PWWAN_PIN_APP WwanPinApp, + __deref_out PMBB_PIN_APP *MbbPinAppOut, + __out PULONG ReturnedBufferSize +) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_PIN_APP MbbPinApp = NULL; + + *ReturnedBufferSize = 0; + *MbbPinAppOut = NULL; + + BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_PIN_APP, DataBuffer), ALIGN_DWORD); + + CurrentOffset = BufferSize; + + BufferSize += (ULONG)ROUND_UP_COUNT(WwanPinApp->AppIdLength, ALIGN_DWORD); + + if ((MbbPinApp = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer = (PUCHAR)MbbPinApp; + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&MbbPinApp->AppId, + (PUCHAR)WwanPinApp->AppId, + WwanPinApp->AppIdLength + ); + + *MbbPinAppOut = MbbPinApp; + + *ReturnedBufferSize = BufferSize; + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetDeviceSlotMappingInfo( + __in PWWAN_DEVICE_SLOT_MAPPING_INFO WwanDeviceSlotMappingInfo, + __deref_out_opt PMBB_MS_DEVICE_SLOT_MAPPING_INFO *MbbDeviceSlotMappingInfoOut, + __out PULONG ReturnedBufferSize +) +{ + PUCHAR WwanBuffer = NULL; + ULONG CurrentOffsetInWwanBuffer = 0; + PUCHAR MbbBuffer = NULL; + ULONG CurrentOffsetInMbbBuffer = 0; + ULONG MbbBufferSize = 0; + PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbDeviceSlotMappingInfo = NULL; + ULONG MapCount = 0; + ULONG MapIndex = 0; + + WwanBuffer = (PUCHAR)WwanDeviceSlotMappingInfo; + CurrentOffsetInWwanBuffer = sizeof(WWAN_DEVICE_SLOT_MAPPING_INFO); + MapCount = WwanDeviceSlotMappingInfo->SlotMapListHeader.ElementCount; + *MbbDeviceSlotMappingInfoOut = NULL; + *ReturnedBufferSize = 0; + + // Calculate the buffer size for MbbDeviceSlotMappingInfo. + MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_MS_DEVICE_SLOT_MAPPING_INFO, SlotMapList), ALIGN_DWORD); + MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * MapCount, ALIGN_DWORD); + + CurrentOffsetInMbbBuffer = MbbBufferSize; + + MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(ULONG) * MapCount, ALIGN_DWORD); + + // Allocate the buffer for MbbDeviceSlotMappingInfo. + MbbDeviceSlotMappingInfo = ALLOCATE_NONPAGED_POOL(MbbBufferSize); + if (NULL == MbbDeviceSlotMappingInfo) + { + return NDIS_STATUS_RESOURCES; + } + + MbbBuffer = (PUCHAR)MbbDeviceSlotMappingInfo; + + // Set the values of MbbDeviceSlotMappingInfo + MbbDeviceSlotMappingInfo->MapCount = MapCount; + CurrentOffsetInMbbBuffer = MbbUtilWwanListToMbbList(&(WwanDeviceSlotMappingInfo->SlotMapListHeader), + sizeof(ULONG), + MbbBuffer, + CurrentOffsetInMbbBuffer, + &(MbbDeviceSlotMappingInfo->SlotMapList[0])); + + *MbbDeviceSlotMappingInfoOut = MbbDeviceSlotMappingInfo; + *ReturnedBufferSize = MbbBufferSize; + + return NDIS_STATUS_SUCCESS; +} + +ULONG +MbbUtilWwanListToMbbList( + __in PWWAN_LIST_HEADER WwanListHeader, + __in ULONG WwanListElementSize, + __inout PUCHAR MbbBuffer, + __in ULONG CurrentOffsetInMbbBuffer, + __inout PMBB_ARRAY_ELEMENT MbbArray + ) +{ + PUCHAR WwanBuffer = (PUCHAR)WwanListHeader; + ULONG CurrentOffsetInWwanBuffer = sizeof(WWAN_LIST_HEADER); + ULONG MapCount = WwanListHeader->ElementCount; + ULONG MapIndex = 0; + ULONG ReturnedOffsetInMbbBuffer = CurrentOffsetInMbbBuffer; + + for (MapIndex = 0; MapIndex < MapCount; MapIndex++) + { + // Set the offsets and sizes. + MbbArray[MapIndex].Offset = ReturnedOffsetInMbbBuffer; + MbbArray[MapIndex].Size = WwanListElementSize; + + // Set the DataBuffer. +#pragma warning(suppress: 26007) + RtlCopyMemory(MbbBuffer + ReturnedOffsetInMbbBuffer, + WwanBuffer + CurrentOffsetInWwanBuffer, + WwanListElementSize); + + ReturnedOffsetInMbbBuffer += WwanListElementSize; + CurrentOffsetInWwanBuffer += WwanListElementSize; + } + + return ReturnedOffsetInMbbBuffer; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetDeviceBindingsInfo( + __in PWWAN_DEVICE_BINDINGS_INFO WwanSetDeviceBindingsInfo, + __deref_out PMBB_DEVICE_BINDINGS_INFO *MbbSetDeviceBindingsInfoOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR WwanBuffer = NULL; + ULONG CurrentOffsetInWwanBuffer = 0; + PUCHAR MbbBuffer = NULL; + ULONG CurrentOffsetInMbbBuffer = 0; + ULONG MbbBufferSize = 0; + PMBB_DEVICE_BINDINGS_INFO MbbDeviceBindingsInfo = NULL; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + ULONG MbbUiccFilePathLength[MAX_CNT_UICC_APPS_BOUND_TO_DEVICE] = { 0 }; + PMBB_UICC_FILE_PATH MbbUiccFilePath[MAX_CNT_UICC_APPS_BOUND_TO_DEVICE] = { NULL }; + ULONG AppCount = 0; + ULONG AppIndex = 0; + + WwanBuffer = (PUCHAR)WwanSetDeviceBindingsInfo; + CurrentOffsetInWwanBuffer = sizeof(WWAN_DEVICE_BINDINGS_INFO); + AppCount = WwanSetDeviceBindingsInfo->ApplicationListHeader.ElementCount; + *ReturnedBufferSize = 0; + + // WWAN_DEVICE_BINDINGS_INFO can specify at most MAX_CNT_UICC_APPS_BOUND_TO_DEVICE (= 2) UICC applications. + if (AppCount > MAX_CNT_UICC_APPS_BOUND_TO_DEVICE) + { + return NDIS_STATUS_INVALID_PARAMETER; + } + + // Generate the MBB_UICC_FILE_PATH based on WWAN_UICC_FILE_PATH and calculate the MbbBufferSize. + MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_DEVICE_BINDINGS_INFO, ApplicationList), ALIGN_DWORD); + MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * AppCount, ALIGN_DWORD); + CurrentOffsetInMbbBuffer = MbbBufferSize; + + for (AppIndex = 0; AppIndex < AppCount; AppIndex++) + { + NdisStatus = MbbUtilWwanToMbbUiccFilePath( + (PWWAN_UICC_FILE_PATH)(WwanBuffer + CurrentOffsetInWwanBuffer), + &(MbbUiccFilePath[AppIndex]), + &(MbbUiccFilePathLength[AppIndex])); + + if (NdisStatus != NDIS_STATUS_SUCCESS) + { + goto Cleanup; + } + + CurrentOffsetInWwanBuffer += sizeof(WWAN_UICC_FILE_PATH); + MbbBufferSize += MbbUiccFilePathLength[AppIndex]; + } + + // Allocate the buffer for MbbDeviceSlotMappingInfo. + MbbDeviceBindingsInfo = ALLOCATE_NONPAGED_POOL(MbbBufferSize); + if (NULL == MbbDeviceBindingsInfo) + { + NdisStatus = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + MbbBuffer = (PUCHAR)MbbDeviceBindingsInfo; + + // Set the values of MbbDeviceBindingsInfo + MbbDeviceBindingsInfo->ApplicationCount = AppCount; + for (AppIndex = 0; AppIndex < AppCount; AppIndex++) + { + CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( + MbbBuffer, + MbbBufferSize, + CurrentOffsetInMbbBuffer, + (PMBB_STRING)(&(MbbDeviceBindingsInfo->ApplicationList[AppIndex])), + (PUCHAR)(MbbUiccFilePath[AppIndex]), + MbbUiccFilePathLength[AppIndex]); + } + + *MbbSetDeviceBindingsInfoOut = MbbDeviceBindingsInfo; + *ReturnedBufferSize = MbbBufferSize; + +Cleanup: + for (AppIndex = 0; AppIndex < AppCount; AppIndex++) + { + if (NULL != MbbUiccFilePath[AppIndex]) + { + FREE_POOL(MbbUiccFilePath[AppIndex]); + } + } + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetRegisterStateEx( + __in PWWAN_SET_REGISTER_STATE_EX WwanSetRegisterStateEx, + __deref_out PMBB_SET_REGISTER_STATE_V2 *MbbSetRegisterStateV2Out, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR WwanBuffer = NULL; + ULONG CurrentOffsetInWwanBuffer = 0; + PUCHAR MbbBuffer = NULL; + ULONG CurrentOffsetInMbbBuffer = 0; + ULONG MbbBufferSize = 0; + PMBB_SET_REGISTER_STATE_V2 MbbSetRegisterStateV2 = NULL; + SIZE_T ProviderIdSize = 0; + ULONG DataClassCount = 0; + + WwanBuffer = (PUCHAR)WwanSetRegisterStateEx; + CurrentOffsetInWwanBuffer = sizeof(WWAN_SET_REGISTER_STATE_EX); + DataClassCount = WwanSetRegisterStateEx->AcquisitionOrderListHeader.ElementCount; + *ReturnedBufferSize = 0; + + if (WwanStructRegisterAcquisitionOrder != WwanSetRegisterStateEx->AcquisitionOrderListHeader.ElementType) + { + return NDIS_STATUS_INVALID_PARAMETER; + } + + // Calculate the MbbBufferSize. + MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_REGISTER_STATE_V2, AcquisitionOrder), ALIGN_DWORD); + MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT), ALIGN_DWORD); + CurrentOffsetInMbbBuffer = MbbBufferSize; + + if (RtlStringCbLengthW(WwanSetRegisterStateEx->ProviderId, sizeof(WwanSetRegisterStateEx->ProviderId), &ProviderIdSize) + != STATUS_SUCCESS) + { + ProviderIdSize = sizeof(WwanSetRegisterStateEx->ProviderId); + } + MbbBufferSize += ROUND_UP_COUNT((ULONG)ProviderIdSize, ALIGN_DWORD); + + MbbBufferSize += ROUND_UP_COUNT(sizeof(ULONG) * DataClassCount, ALIGN_DWORD); + + // Allocate the buffer for MbbSetRegisterStateV2. + MbbSetRegisterStateV2 = ALLOCATE_NONPAGED_POOL(MbbBufferSize); + if (NULL == MbbSetRegisterStateV2) + { + return NDIS_STATUS_RESOURCES; + } + + MbbBuffer = (PUCHAR)MbbSetRegisterStateV2; + + // Set the values of MbbSetRegisterStateV2 + CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( + MbbBuffer, + MbbBufferSize, + CurrentOffsetInMbbBuffer, + &(MbbSetRegisterStateV2->ProviderId), + (PUCHAR)(WwanSetRegisterStateEx->ProviderId), + (ULONG)ProviderIdSize); + + MbbSetRegisterStateV2->RegisterAction = (MBB_REGISTER_ACTION)WwanSetRegisterStateEx->RegisterAction; + MbbSetRegisterStateV2->DataClass = WwanSetRegisterStateEx->WwanDataClass; + MbbSetRegisterStateV2->VoiceClass = (MBB_REGISTRATION_VOICE_CLASS)WwanSetRegisterStateEx->WwanVoiceClass; + MbbSetRegisterStateV2->VoiceDomain = (MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE)WwanSetRegisterStateEx->WwanVoiceDomain; + MbbSetRegisterStateV2->CdmaRoamMode = (MBB_REGISTRATION_CDMA_ROAM_MODE)WwanSetRegisterStateEx->WwanCdmaRoamMode; + + CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( + MbbBuffer, + MbbBufferSize, + CurrentOffsetInMbbBuffer, + (PMBB_STRING)(&(MbbSetRegisterStateV2->AcquisitionOrder)), + (PUCHAR)(WwanBuffer + CurrentOffsetInWwanBuffer), + sizeof(ULONG) * DataClassCount); + + *MbbSetRegisterStateV2Out = MbbSetRegisterStateV2; + *ReturnedBufferSize = MbbBufferSize; + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetUiccOpenChannel( + __in PWWAN_SET_UICC_OPEN_CHANNEL WwanSetUiccOpenChannel, + __deref_out PMBB_SET_UICC_OPEN_CHANNEL *MbbSetUiccOpenChannelOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_SET_UICC_OPEN_CHANNEL MbbSetUiccOpenChannel = NULL; + MBB_ARRAY_ELEMENT AppId = { 0 }; + + *MbbSetUiccOpenChannelOut = NULL; + *ReturnedBufferSize = 0; + + BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_UICC_OPEN_CHANNEL, DataBuffer), ALIGN_DWORD); + + CurrentOffset = BufferSize; + + BufferSize += (ULONG)ROUND_UP_COUNT(WwanSetUiccOpenChannel->AppIdLength, ALIGN_DWORD); + + if ((MbbSetUiccOpenChannel = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer = (PUCHAR)MbbSetUiccOpenChannel; + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&AppId, + (PUCHAR)WwanSetUiccOpenChannel->AppId, + WwanSetUiccOpenChannel->AppIdLength + ); + + // In the MBIM Extension for Low-Level UICC Access, (OFFSET, SIZE) type pairs are spec'ed in + // reverse order of the MBIM v1.0. Convert the pair that is filled by the utility function. + MbbSetUiccOpenChannel->AppId.Size = AppId.Size; + MbbSetUiccOpenChannel->AppId.Offset = AppId.Offset; + + MbbSetUiccOpenChannel->SelectP2Arg = WwanSetUiccOpenChannel->SelectP2Arg; + MbbSetUiccOpenChannel->ChannelGroup = WwanSetUiccOpenChannel->ChannelGroup; + + *MbbSetUiccOpenChannelOut = MbbSetUiccOpenChannel; + *ReturnedBufferSize = BufferSize; + + return NDIS_STATUS_SUCCESS; +} + +VOID +MbbUtilWwanToMbbSetUiccCloseChannel( + __in PWWAN_SET_UICC_CLOSE_CHANNEL WwanSetUiccCloseChannel, + __out PMBB_SET_UICC_CLOSE_CHANNEL MbbSetUiccCloseChannel + ) +{ + MbbSetUiccCloseChannel->Channel = WwanSetUiccCloseChannel->Channel; + MbbSetUiccCloseChannel->ChannelGroup = WwanSetUiccCloseChannel->ChannelGroup; + MbbSetUiccCloseChannel->SelectP2Arg = WwanSetUiccCloseChannel->SelectP2Arg; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetUiccApdu( + __in PWWAN_SET_UICC_APDU WwanSetUiccApdu, + __deref_out PMBB_SET_UICC_APDU *MbbSetUiccApduOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_SET_UICC_APDU MbbSetUiccApdu = NULL; + MBB_ARRAY_ELEMENT Command = { 0 }; + + *MbbSetUiccApduOut = NULL; + *ReturnedBufferSize = 0; + + BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_UICC_APDU, DataBuffer), ALIGN_DWORD); + + CurrentOffset = BufferSize; + + BufferSize += (ULONG)ROUND_UP_COUNT(WwanSetUiccApdu->CommandLength, ALIGN_DWORD); + + if ((MbbSetUiccApdu = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer = (PUCHAR)MbbSetUiccApdu; + + CurrentOffset = MbbUtilWriteStringToBuffer( + Buffer, + BufferSize, + CurrentOffset, + (PMBB_STRING)&Command, + (PUCHAR)WwanSetUiccApdu->Command, + WwanSetUiccApdu->CommandLength + ); + + // In the MBIM Extension for Low-Level UICC Access, (OFFSET, SIZE) type pairs are spec'ed in + // reverse order of the MBIM v1.0. Convert the pair that is filled by the utility function. + MbbSetUiccApdu->Command.Size = Command.Size; + MbbSetUiccApdu->Command.Offset = Command.Offset; + + MbbSetUiccApdu->Channel = WwanSetUiccApdu->Channel; + MbbSetUiccApdu->SecureMessaging = (MBB_UICC_SECURE_MESSAGING)WwanSetUiccApdu->SecureMessaging; + MbbSetUiccApdu->Type = (MBB_UICC_CLASS_BYTE_TYPE)WwanSetUiccApdu->Type; + + *MbbSetUiccApduOut = MbbSetUiccApdu; + *ReturnedBufferSize = BufferSize; + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetUiccTerminalCapability( + __in PWWAN_LIST_HEADER WwanCapabilityListHeader, + __deref_out PMBB_SET_UICC_TERMINAL_CAPABILITY *MbbSetUiccTerminalCapabilityOut, + __out PULONG ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG BufferSize; + PMBB_SET_UICC_TERMINAL_CAPABILITY MbbSetUiccTerminalCapability = NULL; + ULONG CapabilityCount = 0; + + *MbbSetUiccTerminalCapabilityOut = NULL; + *ReturnedBufferSize = 0; + + CapabilityCount = WwanCapabilityListHeader->ElementCount; + + BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_UICC_TERMINAL_CAPABILITY, CapabilityList), ALIGN_DWORD); + BufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * CapabilityCount, ALIGN_DWORD); + + CurrentOffset = BufferSize; + + BufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_UICC_TERMINAL_CAPABILITY_TLV) * CapabilityCount, ALIGN_DWORD); + + if ((MbbSetUiccTerminalCapability = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) + { + return NDIS_STATUS_RESOURCES; + } + + Buffer = (PUCHAR)MbbSetUiccTerminalCapability; + + MbbSetUiccTerminalCapability->ElementCount = CapabilityCount; + CurrentOffset = MbbUtilWwanListToMbbList(WwanCapabilityListHeader, + sizeof(MBB_UICC_TERMINAL_CAPABILITY_TLV), + Buffer, + CurrentOffset, + &(MbbSetUiccTerminalCapability->CapabilityList[0])); + + *MbbSetUiccTerminalCapabilityOut = MbbSetUiccTerminalCapability; + *ReturnedBufferSize = BufferSize; + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetSarConfig( + _In_ PWWAN_SET_SAR_CONFIG WwanSetSarConfig, + _Outptr_ PMBB_SET_SAR_CONFIG *MbbSetSarConfigOut, + _Out_ PULONG ReturnedBufferSize +) +{ + ULONG CurrentOffsetInWwanBuffer = 0; + ULONG CurrentOffsetInMbbBuffer = 0; + ULONG MbbBufferSize = 0; + PMBB_SET_SAR_CONFIG MbbSetSarConfig = NULL; + ULONG SarIndexCount = 0; + + CurrentOffsetInWwanBuffer = sizeof(WWAN_SET_SAR_CONFIG); + SarIndexCount = WwanSetSarConfig->SarConfigIndexListHeader.ElementCount; + *ReturnedBufferSize = 0; + + if (WwanStructSarConfig != WwanSetSarConfig->SarConfigIndexListHeader.ElementType) + { + return NDIS_STATUS_INVALID_PARAMETER; + } + + // Calculate the MbbBufferSize. + MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_SAR_CONFIG, Configurations), ALIGN_DWORD); + MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * SarIndexCount, ALIGN_DWORD); + CurrentOffsetInMbbBuffer = MbbBufferSize; + + MbbBufferSize += ROUND_UP_COUNT(sizeof(MBB_SAR_CONFIG_INDICES) * SarIndexCount, ALIGN_DWORD); + + // Allocate the buffer for MbbSetSarConfig. + MbbSetSarConfig = ALLOCATE_NONPAGED_POOL(MbbBufferSize); + if (NULL == MbbSetSarConfig) + { + return NDIS_STATUS_RESOURCES; + } + + // Set the values of MbbSetSarConfig + MbbSetSarConfig->SarMode = (MBB_SAR_CONTROL_MODE)WwanSetSarConfig->SarMode; + MbbSetSarConfig->SarBackoffStatus = (MBB_SAR_BACKOFF_STATE)WwanSetSarConfig->SarBackoffStatus; + MbbSetSarConfig->ElementCount = SarIndexCount; + + for (ULONG i = 0; i < SarIndexCount; i++) + { + CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbSetSarConfig, + MbbBufferSize, + CurrentOffsetInMbbBuffer, + (PMBB_STRING)(&(MbbSetSarConfig->Configurations[i])), + (PUCHAR)((PUCHAR)WwanSetSarConfig + CurrentOffsetInWwanBuffer), + sizeof(WWAN_SAR_CONFIG_INDICES)); + + CurrentOffsetInWwanBuffer += sizeof(WWAN_SAR_CONFIG_INDICES); + } + + *MbbSetSarConfigOut = MbbSetSarConfig; + *ReturnedBufferSize = MbbBufferSize; + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetNetworkBlacklist( + _In_ PWWAN_NETWORK_BLACKLIST_INFO SetNetworkBlacklist, + _Outptr_ PMBB_MS_NETWORK_BLACKLIST_INFO *MbbNetworkBlacklistOut, + _Out_ PULONG ReturnedBufferSize +) +{ + ULONG CurrentOffsetInWwanBuffer = 0; + ULONG CurrentOffsetInMbbBuffer = 0; + ULONG MbbBufferSize = 0; + PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist = NULL; + ULONG BlacklistedProviderCount = SetNetworkBlacklist->BlacklistProviderList.ElementCount; + + CurrentOffsetInWwanBuffer = sizeof(WWAN_NETWORK_BLACKLIST_INFO); + + *ReturnedBufferSize = 0; + + // Calculate the MbbBufferSize. + MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_MS_NETWORK_BLACKLIST_INFO, Contexts), ALIGN_DWORD); + MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * BlacklistedProviderCount, ALIGN_DWORD); + CurrentOffsetInMbbBuffer = MbbBufferSize; + + MbbBufferSize += ROUND_UP_COUNT(sizeof(MBB_MS_NETWORK_BLACKLIST_PROVIDER) * BlacklistedProviderCount, ALIGN_DWORD); + + // Allocate the buffer for MbbNetworkBlacklist. + MbbNetworkBlacklist = ALLOCATE_NONPAGED_POOL(MbbBufferSize); + if (NULL == MbbNetworkBlacklist) + { + return NDIS_STATUS_RESOURCES; + } + + // Set the values of MbbNetworkBlacklist + MbbNetworkBlacklist->BlacklistState = (MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE)SetNetworkBlacklist->BlacklistState; + MbbNetworkBlacklist->ElementCount = BlacklistedProviderCount; + + for (ULONG i = 0; i < BlacklistedProviderCount; i++) + { + CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( + (PUCHAR)MbbNetworkBlacklist, + MbbBufferSize, + CurrentOffsetInMbbBuffer, + (PMBB_STRING)(&(MbbNetworkBlacklist->Contexts[i])), + (PUCHAR)((PUCHAR)MbbNetworkBlacklist + CurrentOffsetInWwanBuffer), + sizeof(MBB_MS_NETWORK_BLACKLIST_PROVIDER)); + + CurrentOffsetInWwanBuffer += sizeof(MBB_MS_NETWORK_BLACKLIST_PROVIDER); + } + + *MbbNetworkBlacklistOut = MbbNetworkBlacklist; + *ReturnedBufferSize = MbbBufferSize; + + return NDIS_STATUS_SUCCESS; +} + + +// +// Mbb to Wwan +// + +WWAN_STATUS +MbbUtilMbbToWwanStatus( + __in MBB_STATUS MbbStatus + ) +{ + if( MBB_STATUS_IS_BASIC( MbbStatus ) ) + { + return MbbStatusMapTableBasic[MBB_STATUS_BASIC_INDEX(MbbStatus)]; + } + else if( MBB_STATUS_IS_SMS( MbbStatus ) ) + { + return MbbStatusMapTableSms[MBB_STATUS_SMS_INDEX(MbbStatus)]; + } + else if( MBB_STATUS_IS_UICC( MbbStatus ) ) + { + return MbbStatusMapTableUicc[MBB_STATUS_UICC_INDEX(MbbStatus)]; + } + else + { + TraceError( WMBCLASS_OID, "[Util][MBBStatus] INVALID MBB status code=%d", + MbbStatus + ); + + return WWAN_STATUS_FAILURE; + } +} + +VOID +MbbUtilMbbToWwanRadioState( + __in MBB_RADIO_STATE* MbbRadioState, + __out WWAN_RADIO* WwanRadio + ) +{ + *WwanRadio = (MBB_RADIO_STATE)*MbbRadioState ; +} + +NTSTATUS +MbbIsVariableFieldValid( + ULONG TotalMessageLength, + ULONG Offset, + ULONG Size, + ULONG MaxElements, + ULONG ElementSize + ) + +{ + ULONGLONG Temp; + + Temp = (ULONGLONG)Offset + Size; + + // + // does the field extend beyond the length of the whole message? + // + if (Temp > TotalMessageLength) + { + TraceError( WMBCLASS_OID, "Offset plus size exceeded total length, Offset=%d, Size=%d, Total=%d",Offset, Size, TotalMessageLength); + return STATUS_INVALID_PARAMETER; + } + + // + // Is the offset aligned on a dword boundary? + // + if (Offset != ROUND_UP_COUNT(Offset,ALIGN_DWORD)) + { + TraceError( WMBCLASS_OID, "Offset note dword aligned Offset=%d", Offset); + return STATUS_INVALID_PARAMETER; + } + + // + // Is the field bigger than the max we support? + // + if ((Size/ElementSize) > MaxElements) + { + TraceError( WMBCLASS_OID, "Size is larger than max elements Size=%d, Max=%d", Size/ElementSize , MaxElements); + return STATUS_INVALID_PARAMETER; + } + + // + // is the size an integral number of elements + // + if (Size % ElementSize != 0) + { + TraceError( WMBCLASS_OID, "Size is not a multiple of ElementSize Size=%d, element size=%d", Size, ElementSize); + return STATUS_INVALID_PARAMETER; + } + + return STATUS_SUCCESS; +} + + +NTSTATUS +MbbIsArrayFieldValid( + ULONG TotalMessageLength, + ULONG Offset, + ULONG ElementCount, + ULONG ElementSize + ) + +{ + ULONGLONG Temp; + ULONGLONG ArraySize; + + ArraySize= (ULONGLONG) ElementCount * ElementSize; + + if (ArraySize > ULONG_MAX) + { + TraceError( WMBCLASS_OID, "Array size is too big, Count=%d, Size=%d", ElementCount, ElementSize); + return STATUS_INVALID_PARAMETER; + } + + Temp = (ULONGLONG)Offset + ArraySize; + + // + // does the field extend beyond the length of the whole message? + // + if (Temp > TotalMessageLength) + { + TraceError( WMBCLASS_OID, "Offset plus size exceeded total length, Offset=%d, Size=%I64d, Total=%d",Offset, ArraySize, TotalMessageLength); + return STATUS_INVALID_PARAMETER; + } + + // + // Is the offset aligned on a dword boundary? + // + if (Offset != ROUND_UP_COUNT(Offset,ALIGN_DWORD)) + { + TraceError( WMBCLASS_OID, "Offset note dword aligned Offset=%d", Offset); + return STATUS_INVALID_PARAMETER; + } + + return STATUS_SUCCESS; +} + +VOID +MbbUtilMbbToWwanDeviceCaps( + __in PMBB_DEVICE_CAPS MbbDeviceCaps, + __in_ecount(ManufacturerStrLen) PWCHAR ManufacturerString, + __in ULONG ManufacturerStrLen, + __in_ecount(ModelStrLen) PWCHAR ModelString, + __in ULONG ModelStrLen, + __out PWWAN_DEVICE_CAPS WwanDeviceCaps, + __in BOOL fMultimode + ) +{ + WWAN_CELLULAR_CLASS* pCC = (WWAN_CELLULAR_CLASS*)(((PUCHAR)WwanDeviceCaps) + sizeof(*WwanDeviceCaps)); + + RtlZeroMemory(WwanDeviceCaps, sizeof(*WwanDeviceCaps)); + WwanDeviceCaps->CellularClassListHeader.ElementType = WwanStructCellularClass; + WwanDeviceCaps->CellularClassListHeader.ElementCount = 0; + + MbbDeviceCaps->CellularClass &= MbbCellularClassMaximum; + + WwanDeviceCaps->WwanDeviceType = (WWAN_DEVICE_TYPE)MbbDeviceCaps->DeviceType; + + if (MbbDeviceCaps->CellularClass & MbbCellularClassGsm) + { + + WwanDeviceCaps->WwanCellularClass = WwanCellularClassGsm; + } + else if (MbbDeviceCaps->CellularClass & MbbCellularClassCdma) + { + WwanDeviceCaps->WwanCellularClass = WwanCellularClassCdma; + } + + + WwanDeviceCaps->WwanVoiceClass = (WWAN_VOICE_CLASS)MbbDeviceCaps->VoiceClass; + WwanDeviceCaps->WwanSimClass = (WWAN_SIM_CLASS)MbbDeviceCaps->SimClass; + WwanDeviceCaps->WwanDataClass = (ULONG)MbbDeviceCaps->DataClass; + + WwanDeviceCaps->WwanGsmBandClass = (ULONG)WWAN_BAND_CLASS_UNKNOWN; + WwanDeviceCaps->WwanCdmaBandClass = (ULONG)WWAN_BAND_CLASS_UNKNOWN; + + WwanDeviceCaps->WwanSmsCaps = (ULONG)MbbDeviceCaps->SmsCaps; + WwanDeviceCaps->WwanControlCaps = (ULONG)MbbDeviceCaps->ControlCaps; + + + if(fMultimode) + { + WwanDeviceCaps->WwanControlCaps |= WWAN_CTRL_CAPS_MULTI_MODE; + WwanDeviceCaps->CellularClassListHeader.ElementCount = MbbCellularClassMaximum - 1 ; + + //for now we just have GSM and CDMA so hardcode, this is protected + //by a C_ASSERT + *pCC = WwanCellularClassGsm; + *(pCC+ 1) = WwanCellularClassCdma; + } + else + { + WwanDeviceCaps->WwanCellularClass = MbbDeviceCaps->CellularClass; + } + + // + // this bit is not in the mbim model + // + WwanDeviceCaps->WwanControlCaps &= ~WWAN_CTRL_CAPS_PROTECT_UNIQUEID; + + // + // translate this one to the right wwan bit + // + if (MbbDeviceCaps->ControlCaps & MbbControlCapsMultiCarrier) + { + WwanDeviceCaps->WwanControlCaps |= WWAN_CTRL_CAPS_MODEL_MULTI_CARRIER; + } + + WwanDeviceCaps->MaxActivatedContexts = MbbDeviceCaps->dwMaxSessions; + + MbbUtilPopulateStaticString(WwanDeviceCaps->CustomDataClass, MbbDeviceCaps, CustomDataClass); + + MbbUtilPopulateStaticString(WwanDeviceCaps->DeviceId, MbbDeviceCaps, DeviceIdString); + + MbbUtilPopulateStaticString(WwanDeviceCaps->FirmwareInfo, MbbDeviceCaps, FirmwareInfo); + + + RtlStringCchCopyNW( + WwanDeviceCaps->Manufacturer, + WWAN_MANUFACTURER_LEN, + ManufacturerString, + ManufacturerStrLen + ); + + RtlStringCchCopyNW( + WwanDeviceCaps->Model, + WWAN_MODEL_LEN, + ModelString, + ModelStrLen + ); + + return; +} + +VOID +MbbUtilMbbToWwanDeviceCapsV2( + __in PMBB_MS_DEVICE_CAPS_INFO_V2 MbbDeviceCaps, + __in_ecount(ManufacturerStrLen) PWCHAR ManufacturerString, + __in ULONG ManufacturerStrLen, + __in_ecount(ModelStrLen) PWCHAR ModelString, + __in ULONG ModelStrLen, + __out PWWAN_DEVICE_CAPS_EX WwanDeviceCaps, + __in BOOL fMultimode +) +{ + WWAN_CELLULAR_CLASS* pCC = (WWAN_CELLULAR_CLASS*)(((PUCHAR)WwanDeviceCaps) + sizeof(*WwanDeviceCaps)); + + RtlZeroMemory(WwanDeviceCaps, sizeof(*WwanDeviceCaps)); + WwanDeviceCaps->CellularClassListHeader.ElementType = WwanStructCellularClass; + WwanDeviceCaps->CellularClassListHeader.ElementCount = 0; + + MbbDeviceCaps->CellularClass &= MbbCellularClassMaximum; + + WwanDeviceCaps->WwanDeviceType = (WWAN_DEVICE_TYPE)MbbDeviceCaps->DeviceType; + + if (MbbDeviceCaps->CellularClass & MbbCellularClassGsm) + { + WwanDeviceCaps->WwanCellularClass = WwanCellularClassGsm; + } + else if (MbbDeviceCaps->CellularClass & MbbCellularClassCdma) + { + WwanDeviceCaps->WwanCellularClass = WwanCellularClassCdma; + } + + WwanDeviceCaps->WwanVoiceClass = (WWAN_VOICE_CLASS)MbbDeviceCaps->VoiceClass; + WwanDeviceCaps->WwanSimClass = (WWAN_SIM_CLASS)MbbDeviceCaps->SimClass; + WwanDeviceCaps->WwanDataClass = (ULONG)MbbDeviceCaps->DataClass; + + WwanDeviceCaps->WwanGsmBandClass = (ULONG)WWAN_BAND_CLASS_UNKNOWN; + WwanDeviceCaps->WwanCdmaBandClass = (ULONG)WWAN_BAND_CLASS_UNKNOWN; + + WwanDeviceCaps->WwanSmsCaps = (ULONG)MbbDeviceCaps->SmsCaps; + + WwanDeviceCaps->WwanControlCaps = (ULONG)MbbDeviceCaps->ControlCaps; + + if (fMultimode) + { + WwanDeviceCaps->WwanControlCaps |= WWAN_CTRL_CAPS_MULTI_MODE; + WwanDeviceCaps->CellularClassListHeader.ElementCount = MbbCellularClassMaximum - 1; + + //for now we just have GSM and CDMA so hardcode, this is protected + //by a C_ASSERT + *pCC = WwanCellularClassGsm; + *(pCC + 1) = WwanCellularClassCdma; + } + + // + // this bit is not in the mbim model + // + WwanDeviceCaps->WwanControlCaps &= ~WWAN_CTRL_CAPS_PROTECT_UNIQUEID; + + // + // translate this one to the right wwan bit + // + if (MbbDeviceCaps->ControlCaps & MbbControlCapsMultiCarrier) + { + WwanDeviceCaps->WwanControlCaps |= WWAN_CTRL_CAPS_MODEL_MULTI_CARRIER; + } + + WwanDeviceCaps->MaxActivatedContexts = MbbDeviceCaps->dwMaxSessions; + + MbbUtilPopulateStaticString(WwanDeviceCaps->CustomDataClass, MbbDeviceCaps, CustomDataClass); + + MbbUtilPopulateStaticString(WwanDeviceCaps->DeviceId, MbbDeviceCaps, DeviceIdString); + + MbbUtilPopulateStaticString(WwanDeviceCaps->FirmwareInfo, MbbDeviceCaps, FirmwareInfo); + + RtlStringCchCopyNW( + WwanDeviceCaps->Manufacturer, + WWAN_MANUFACTURER_LEN, + ManufacturerString, + ManufacturerStrLen + ); + + RtlStringCchCopyNW( + WwanDeviceCaps->Model, + WWAN_MODEL_LEN, + ModelString, + ModelStrLen + ); + + // + // new field added in WWAN_DEVICE_CAPS_EX + // + WwanDeviceCaps->ExecutorIndex = MbbDeviceCaps->ExecutorIndex; + + return; +} + +VOID +MbbUtilMbbToWwanReadyInfo( + __in PMBB_SUBSCRIBER_READY_INFO MbbReadyInfo, + __in PWWAN_READY_INFO WwanReadyInfo + ) +/*++ + Note: + Not all the information required to fill the WWAN_READY_INFO + structure is present in MBB_SUBSCRIBER_READY_INFO. Some of the + information will come from MBB_EMERGENCY_MODE and MBB_SMS_CONFIGURATION. +--*/ +{ + ULONG ElementCount = MbbReadyInfo->TelephoneNumberCount; + ULONG ElementIndex; + ULONG StringCb; + ULONG StringCch; + PWCHAR WwanTn; + PWCHAR MbbTn; + NTSTATUS NtStatus; + + WwanReadyInfo->ReadyState = (WWAN_READY_STATE)MbbReadyInfo->ReadyState; + + StringCb = MIN( MbbReadyInfo->SubscriberId.Size, (WWAN_SUBSCRIBERID_LEN-1) * sizeof(WCHAR) ); + RtlCopyMemory( + WwanReadyInfo->SubscriberId, + (((PCHAR)MbbReadyInfo) + MbbReadyInfo->SubscriberId.Offset), + StringCb + ); + StringCch = StringCb / sizeof(WCHAR); + WwanReadyInfo->SubscriberId[StringCch] = 0; + + StringCb = MIN( MbbReadyInfo->SimIccId.Size, (WWAN_SIMICCID_LEN-1) * sizeof(WCHAR) ); + RtlCopyMemory( + WwanReadyInfo->SimIccId, + (((PCHAR)MbbReadyInfo) + MbbReadyInfo->SimIccId.Offset), + StringCb + ); + StringCch = StringCb / sizeof(WCHAR); + WwanReadyInfo->SimIccId[StringCch] = 0; + + WwanReadyInfo->TNListHeader.ElementType = WwanStructTN; + WwanReadyInfo->TNListHeader.ElementCount = ElementCount; + + WwanTn = (PWCHAR)(WwanReadyInfo + 1); + + for( ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex ++ ) + { + MbbTn = (PWCHAR)((PCHAR)MbbReadyInfo + MbbReadyInfo->TelephoneNumbers[ElementIndex].Offset); + StringCb = MIN( MbbReadyInfo->TelephoneNumbers[ElementIndex].Size, (WWAN_TN_LEN-1) * sizeof(WCHAR) ); + RtlCopyMemory( + WwanTn, + MbbTn, + StringCb + ); + StringCch = StringCb / sizeof(WCHAR); + WwanTn[StringCch] = 0; + WwanTn += WWAN_TN_LEN; + } +} + +VOID +MbbUtilMbbToWwanPinInfo( + __in PMBB_PIN_INFO MbbPinInfo, + __out PWWAN_PIN_INFO WwanPinInfo + ) +{ + WwanPinInfo->PinType = (WWAN_PIN_TYPE)MbbPinInfo->PinType; + WwanPinInfo->PinState = (WWAN_PIN_STATE)MbbPinInfo->PinState; + WwanPinInfo->AttemptsRemaining = (ULONG)MbbPinInfo->AttemptsRemaining; +} + +VOID +MbbUtilMbbToWwanPinList( + __in PMBB_PIN_LIST MbbPinList, + __out PWWAN_PIN_LIST WwanPinList + ) +{ + ULONG PinIndex; + PWWAN_PIN_DESC WwanPinDesc; + PMBB_PIN_DESCRIPTION MbbPinDesc; + + WwanPinDesc = &WwanPinList->WwanPinDescPin1; + MbbPinDesc = &MbbPinList->PinDescPin1; + // + // A loop works because both the list are in the same order. + // + for( PinIndex = 0; + PinIndex < 10; + PinIndex ++ ) + { + WwanPinDesc[PinIndex].PinMode = (WWAN_PIN_MODE)MbbPinDesc[PinIndex].PinMode; + WwanPinDesc[PinIndex].PinFormat = (WWAN_PIN_FORMAT)MbbPinDesc[PinIndex].PinFormat; + WwanPinDesc[PinIndex].PinLengthMin = (ULONG)MbbPinDesc[PinIndex].PinLengthMin; + WwanPinDesc[PinIndex].PinLengthMax = (ULONG)MbbPinDesc[PinIndex].PinLengthMax; + } +} + +NDIS_STATUS +MbbUtilValidateMbbProvider( + __in ULONG MbbProviderSize, + __in_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; + + do + { + if( MbbProvider == NULL || + MbbProviderSize < sizeof(MBB_PROVIDER) ) + { + TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT BufferSize for MBB_PROVIDER, BufferSize[Received=%d Expected=%d]", + MbbProviderSize, + sizeof(MBB_PROVIDER) + ); + break; + } + if( MbbIsVariableFieldValid( + MbbProviderSize, + MbbProvider->ProviderId.Offset, + MbbProvider->ProviderId.Size, + MBB_MAXIMUM_PROVIDER_ID_LENGTH, + sizeof(WCHAR) + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util] INVALID MBB_PROVIDER.ProviderId Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + MbbProvider->ProviderId.Offset, + MbbProviderSize, + MbbProvider->ProviderId.Size, + MBB_MAXIMUM_PROVIDER_ID_LENGTH * sizeof(WCHAR) + ); + break; + } + if( MbbIsVariableFieldValid( + MbbProviderSize, + MbbProvider->ProviderName.Offset, + MbbProvider->ProviderName.Size, + MBB_MAXIMUM_PROVIDER_NAME_LENGTH, + sizeof(WCHAR) + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util] INVALID MBB_PROVIDER.ProviderName Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + MbbProvider->ProviderName.Offset, + MbbProviderSize, + MbbProvider->ProviderName.Size, + MBB_MAXIMUM_PROVIDER_NAME_LENGTH * sizeof(WCHAR) + ); + break; + } + if( MbbProvider->CellularClass >= MbbCellularClassMaximum ) + { + TraceError( WMBCLASS_OID, "[Util] INVALID MBB_PROVIDER.CellularClass=0x%x", MbbProvider->CellularClass ); + break; + } + NdisStatus = NDIS_STATUS_SUCCESS; + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilValidateMbbProviderList( + __in ULONG MbbProviderListSize, + __in_bcount(MbbProviderListSize) PMBB_PROVIDER_LIST MbbProviderList + ) +{ + ULONG ElementIndex; + ULONG ElementCount; + ULONG ExpectedSize; + NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; + NTSTATUS NtStatus = STATUS_SUCCESS; + + do + { + if( MbbProviderList == NULL || + MbbProviderListSize < RTL_SIZEOF_THROUGH_FIELD(MBB_PROVIDER_LIST, ProviderCount) ) + { + TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT BufferSize for MBB_PROVIDER_LIST, BufferSize[Received=%d Expected=%d]", + MbbProviderListSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_PROVIDER_LIST, ProviderCount) + ); + break; + } + + ElementCount = MbbProviderList->ProviderCount; + + NtStatus = RtlULongMult( + ElementCount, + sizeof(MBB_ARRAY_ELEMENT), + &ExpectedSize + ); + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[Util] Multiplication overflow occured, ElementCount=%d MBB_ARRAY_ELEMENT size=%d", + ElementCount, + sizeof(MBB_ARRAY_ELEMENT) + ); + break; + } + + NtStatus = RtlULongAdd( + ExpectedSize, + FIELD_OFFSET(MBB_PROVIDER_LIST, Providers), + &ExpectedSize + ); + if ( NT_ERROR(NtStatus) ) + { + TraceError( WMBCLASS_OID, "[Util] Addition overflow occured, ExpectedSize=%d FIELD_OFFSET=%d", + ExpectedSize, + FIELD_OFFSET(MBB_PROVIDER_LIST, Providers) + ); + break; + } + + if( ExpectedSize > MbbProviderListSize ) + { + TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT BufferSize for MBB_PROVIDER_LIST, BufferSize[Received=%d Expected=%d] ProviderCount=%d", + MbbProviderListSize, + ExpectedSize, + MbbProviderList->ProviderCount + ); + break; + } + + for( ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex ++ ) + { + if( MbbIsVariableFieldValid( + MbbProviderListSize, + MbbProviderList->Providers[ElementIndex].Offset, + MbbProviderList->Providers[ElementIndex].Size, + ULONG_MAX, // MaxElements + 1 // ElementSize + ) != NDIS_STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util] INVALID INVALID MBB_PROVIDER_LIST.Providers[%d] Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + ElementIndex, + MbbProviderList->Providers[ElementIndex].Offset, + MbbProviderListSize, + MbbProviderList->Providers[ElementIndex].Size, + ULONG_MAX + ); + break; + } + if( MbbUtilValidateMbbProvider( + MbbProviderList->Providers[ElementIndex].Size, + (PMBB_PROVIDER)(((PCHAR)MbbProviderList) + MbbProviderList->Providers[ElementIndex].Offset) + ) != NDIS_STATUS_SUCCESS ) + { + break; + } + } + if( ElementIndex != ElementCount ) + break; + + NdisStatus = NDIS_STATUS_SUCCESS; + } + while( FALSE ); + + return NdisStatus; +} + + +VOID +MbbUtilMbbToWwanProvider( + __in PMBB_PROVIDER MbbProvider, + __in ULONG MbbDataClass, + __out PWWAN_PROVIDER WwanProvider + ) +{ + ULONG StringCb; + ULONG StringCch; + + WwanProvider->ProviderState = (ULONG)MbbProvider->ProviderState; + WwanProvider->WwanDataClass = MbbDataClass; + + StringCb = MIN( MbbProvider->ProviderId.Size, (WWAN_PROVIDERID_LEN-1) * sizeof(WCHAR) ); + RtlCopyMemory( + WwanProvider->ProviderId, + (((PCHAR)MbbProvider) + MbbProvider->ProviderId.Offset), + StringCb + ); + StringCch = StringCb / sizeof(WCHAR); + WwanProvider->ProviderId[StringCch] = 0; + + StringCb = MIN( MbbProvider->ProviderName.Size, (WWAN_PROVIDERNAME_LEN-1) * sizeof(WCHAR) ); + RtlCopyMemory( + WwanProvider->ProviderName, + (((PCHAR)MbbProvider) + MbbProvider->ProviderName.Offset), + StringCb + ); + StringCch = StringCb / sizeof(WCHAR); + WwanProvider->ProviderName[StringCch] = 0; +} + +VOID +MbbUtilMbbToWwanProvider2( + __in PMBB_PROVIDER MbbProvider, + __in ULONG MbbDataClass, + __out PWWAN_PROVIDER2 WwanProvider2 + ) +{ + MbbUtilMbbToWwanProvider( + MbbProvider, + MbbDataClass, + &WwanProvider2->Provider + ); + WwanProvider2->Rssi = MbbProvider->Rssi; + WwanProvider2->ErrorRate = MbbProvider->ErrorRate; + WwanProvider2->WwanCellularClass= (WWAN_CELLULAR_CLASS)(MbbProvider->CellularClass); +} + +VOID +MbbUtilMbbToWwanProviderList( + __in PMBB_PROVIDER_LIST MbbProviderList, + __in ULONG MbbDataClass, + __in BOOLEAN IsMultiCarrier, + __out PWWAN_LIST_HEADER WwanProviderList + ) +/*++ +Description: + Assumption that the Offsets and Sizes are already verified. +--*/ +{ + ULONG ElementIndex; + ULONG ElementCount = MbbProviderList->ProviderCount; + PWWAN_PROVIDER2 WwanProviders2 = (PWWAN_PROVIDER2)(WwanProviderList + 1); + PMBB_PROVIDER MbbProvider; + + UNREFERENCED_PARAMETER( IsMultiCarrier ); + + for( ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex ++ ) + { + MbbProvider = (PMBB_PROVIDER)(((PCHAR)MbbProviderList) + MbbProviderList->Providers[ElementIndex].Offset); + + MbbUtilMbbToWwanProvider2( + MbbProvider, + MbbDataClass, + &WwanProviders2[ElementIndex] + ); + } + WwanProviderList->ElementType = WwanStructProvider2; + WwanProviderList->ElementCount = ElementIndex; +} + +VOID +MbbUtilMbbToWwanRegistrationState( + __in PMBB_REGISTRATION_STATE MbbRegistrationState, + __out PWWAN_REGISTRATION_STATE WwanRegistrationState + ) +{ + WwanRegistrationState->uNwError = MbbRegistrationState->NetworkError; + WwanRegistrationState->RegisterState = (WWAN_REGISTER_STATE)MbbRegistrationState->RegisterState; + WwanRegistrationState->RegisterMode = (WWAN_REGISTER_MODE)MbbRegistrationState->RegisterMode; + WwanRegistrationState->WwanRegFlags = (ULONG)MbbRegistrationState->RegFlags; + WwanRegistrationState->CurrentCellularClass = (WWAN_CELLULAR_CLASS)MbbRegistrationState->CurrentCellularClass; + + MbbUtilPopulateStaticString(WwanRegistrationState->ProviderId, MbbRegistrationState, ProviderId); + + MbbUtilPopulateStaticString(WwanRegistrationState->ProviderName, MbbRegistrationState, ProviderName); + + MbbUtilPopulateStaticString(WwanRegistrationState->RoamingText, MbbRegistrationState, RoamingText); + +} + +VOID +MbbUtilMbbToWwanPacketService( + __in PMBB_PACKET_SERVICE MbbPacketService, + __out PWWAN_PACKET_SERVICE WwanPacketService + ) +{ + WwanPacketService->uNwError = MbbPacketService->NetworkError; + WwanPacketService->PacketServiceState = (WWAN_PACKET_SERVICE_STATE)MbbPacketService->PacketServiceState; + WwanPacketService->CurrentDataClass = (ULONG)MbbPacketService->HighestAvailableDataClass; +} + +VOID +MbbUtilMbbToWwanSignalState( + __in PMBB_SIGNAL_STATE MbbSignalState, + __out PWWAN_SIGNAL_STATE WwanSignalState + ) +/*++ +Description + MBB and WWAN default and disable values are inverted so + appropriate checks and translation is required. +--*/ +{ + WwanSignalState->Rssi = MbbSignalState->Rssi; + WwanSignalState->ErrorRate = MbbSignalState->ErrorRate; + + if( MBB_RSSI_DEFAULT == MbbSignalState->RssiInterval ) + WwanSignalState->RssiInterval = WWAN_RSSI_DEFAULT; + else if( MBB_RSSI_DISABLE == MbbSignalState->RssiInterval ) + WwanSignalState->RssiInterval = WWAN_RSSI_DISABLE; + else + WwanSignalState->RssiInterval = MbbSignalState->RssiInterval; + + if( MBB_RSSI_DEFAULT == MbbSignalState->RssiThreshold ) + WwanSignalState->RssiThreshold = WWAN_RSSI_DEFAULT; + else if( MBB_RSSI_DISABLE == MbbSignalState->RssiThreshold ) + WwanSignalState->RssiThreshold = WWAN_RSSI_DISABLE; + else + WwanSignalState->RssiThreshold = MbbSignalState->RssiThreshold; +} + +VOID +MbbUtilMbbToWwanContextState( + __in PMBB_CONTEXT_STATE MbbContextState, + __in ULONG ConnectId, + __out PWWAN_CONTEXT_STATE WwanContextState + ) +{ + WwanContextState->uNwError = MbbContextState->NetworkError; + WwanContextState->ConnectionId = ConnectId; + WwanContextState->ActivationState = (WWAN_ACTIVATION_STATE)MbbContextState->ActivationState; + WwanContextState->VoiceCallState = (WWAN_VOICE_CALL_STATE)MbbContextState->VoiceCallState; + + if(MbbContextState->IPType >= MbbContextIPTypeDefault && + MbbContextState->IPType < MbbContextIPTypeMaximum) + { + WwanContextState->IPType = MbbIpTypesMapTable [MbbContextState->IPType]; + } + else + { + TraceWarn(WMBCLASS_UTIL, "Invalid IPType returned from the Modem. Resetting it to IPTypeDefault and setting Context State as Deactivated"); + // Just to be sure, we set the ActivationState as DeActivated if at all we see an IPType out of bounds + WwanContextState->IPType = WwanIPTypeDefault; + WwanContextState->ActivationState = WwanActivationStateDeactivated; + } +} + +VOID +MbbUtilConvertMbbIPConfigFlagsToWwanIPConfigFlags( + ULONG MbbIPConfigflags, + WWAN_IP_CONFIGURATION_FLAGS* WwanConfigFlags + ) +{ + WwanConfigFlags->Value = MbbIPConfigflags; + WwanConfigFlags->AddressAvailable = MbbIPConfigflags & MbbIpFlagsAddressAvailable ? 1 : 0; + WwanConfigFlags->GatewayAvailable = MbbIPConfigflags & MbbIpFlagsGatewayAvailable ? 1 : 0; + WwanConfigFlags->DnsServerAvailable = MbbIPConfigflags & MbbIpFlagsDnsServerAvailable ? 1 : 0; + WwanConfigFlags->MTUAvailable = MbbIPConfigflags & MbbIpFlagsMTUAvailable ? 1 : 0; +} + +NDIS_STATUS +MbbUtilPopulateWwanIPAddressState( + __in PMBB_IP_ADDRESS_INFO IpAddressInfo, + __in PMBB_IPADDRESS_ENTRY IpTable, + __in PMBB_IPADDRESS_ENTRY GatewayTable, + __in PMBB_IPADDRESS_ENTRY DnsTable, + __in ULONG IpCount, + __in ULONG GatewayCount, + __in ULONG DnsCount, + __out PWWAN_IP_ADDRESS_STATE pWwanIPAddressState + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + do + { + if(!IpAddressInfo) + { + Status = NDIS_STATUS_FAILURE; + TraceError( WMBCLASS_UTIL, "[MbbUtilPopulateWwanIPAddressState] Received NULL Ipaddress information to copy"); + break; + } + + MbbUtilConvertMbbIPConfigFlagsToWwanIPConfigFlags(IpAddressInfo->IPv4Flags,&(pWwanIPAddressState->IPv4Flags)); + MbbUtilConvertMbbIPConfigFlagsToWwanIPConfigFlags(IpAddressInfo->IPv6Flags,&(pWwanIPAddressState->IPv6Flags)); + pWwanIPAddressState->IPv4MTU = IpAddressInfo->IPv4MTU; + pWwanIPAddressState->IPv6MTU = IpAddressInfo->IPv6MTU; + + if(IpTable) + { + pWwanIPAddressState->IpTable= ALLOCATE_NONPAGED_POOL(sizeof(MBB_IPADDRESS_ENTRY) * IpCount); + + if(!pWwanIPAddressState->IpTable) + { + Status = NDIS_STATUS_RESOURCES; + TraceError( WMBCLASS_UTIL, "[MbbUtilPopulateWwanIPAddressState] FAILED to allocate memory for IpTable"); + } + else + { + NdisMoveMemory(pWwanIPAddressState->IpTable, IpTable, sizeof(MBB_IPADDRESS_ENTRY) * IpCount); + pWwanIPAddressState->IpCount = IpCount; + } + } + + if(GatewayTable) + { + pWwanIPAddressState->GatewayTable = ALLOCATE_NONPAGED_POOL(sizeof(MBB_IPADDRESS_ENTRY) * GatewayCount); + + if(!pWwanIPAddressState->GatewayTable) + { + Status = NDIS_STATUS_RESOURCES; + TraceError( WMBCLASS_UTIL, "[MbbUtilPopulateWwanIPAddressState] FAILED to allocate memory for GatewayTable"); + } + else + { + NdisMoveMemory(pWwanIPAddressState->GatewayTable, GatewayTable, sizeof(MBB_IPADDRESS_ENTRY) * GatewayCount); + pWwanIPAddressState->GatewayCount = GatewayCount; + } + } + + if(DnsTable) + { + pWwanIPAddressState->DnsTable = ALLOCATE_NONPAGED_POOL(sizeof(MBB_IPADDRESS_ENTRY) * DnsCount); + + if(!pWwanIPAddressState->DnsTable) + { + Status = NDIS_STATUS_RESOURCES; + TraceError( WMBCLASS_UTIL, "[MbbUtilPopulateWwanIPAddressState] FAILED to allocate memory for DnsTable"); + } + else + { + NdisMoveMemory(pWwanIPAddressState->DnsTable, DnsTable, sizeof(MBB_IPADDRESS_ENTRY) * DnsCount); + pWwanIPAddressState->DnsCount = DnsCount; + } + } + }while(FALSE); + + return Status; +} + +WWAN_CONTEXT_TYPE +MbbUtilMbbToWwanContextType( + __in PGUID MbbContextTypeNetworkByteOrder + ) +{ + GUID MbbContextType; + WWAN_CONTEXT_TYPE WwanContextType; + + MBB_UUID_TO_HOST( &MbbContextType, MbbContextTypeNetworkByteOrder ); + + if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_NONE , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeNone; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_INTERNET , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeInternet; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_VPN , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeVpn; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_VOICE , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeVoice; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_VIDEO_SHARE , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeVideoShare; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_PURCHASE , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypePurchase; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_MMS , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeCustom; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_LOCAL , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeCustom; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_CUSTOM , sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeCustom; + else if (RtlCompareMemory(&MbbContextType, &MBB_UUID_CONTEXT_TYPE_IMS, sizeof(GUID)) == sizeof(GUID)) + WwanContextType = WwanContextTypeIms; + else if (RtlCompareMemory(&MbbContextType, &MBB_UUID_CONTEXT_TYPE_MS_ADMIN, sizeof(GUID)) == sizeof(GUID)) + WwanContextType = WwanContextTypeAdmin; + else if (RtlCompareMemory(&MbbContextType, &MBB_UUID_CONTEXT_TYPE_MS_APP, sizeof(GUID)) == sizeof(GUID)) + WwanContextType = WwanContextTypeApp; + else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_BASIC_CONNECT_EXTENSIONS, sizeof(GUID) ) == sizeof(GUID) ) + WwanContextType = WwanContextTypeLteAttach; + else + WwanContextType = WwanContextTypeCustom; + + return WwanContextType; +} + +VOID +MbbUtilMbbToWwanContext( + __in PMBB_CONTEXT MbbContext, + __out PWWAN_CONTEXT WwanContext + ) +{ + WwanContext->ContextId = MbbContext->ContextId; + WwanContext->ContextType = MbbUtilMbbToWwanContextType( &MbbContext->ContextType ); + WwanContext->Compression = (WWAN_COMPRESSION)MbbContext->Compression; + WwanContext->AuthType = (WWAN_AUTH_PROTOCOL)MbbContext->AuthProtocol; + + MbbUtilPopulateStaticString(WwanContext->AccessString, MbbContext, AccessString ); + + MbbUtilPopulateStaticString(WwanContext->UserName, MbbContext, UserName ); + + MbbUtilPopulateStaticString(WwanContext->Password, MbbContext, Password ); + +} + +VOID +MbbUtilMbbToWwanLteAttachContext( + __in PMBB_MS_LTE_ATTACH_CONTEXT MbbLteAttachContext, + __out WWAN_CONTEXT_V2* WwanLteAttachContext + ) +{ + WwanLteAttachContext->basicInfo.ContextId = 0; + WwanLteAttachContext->basicInfo.ContextType = WwanContextTypeLteAttach; + WwanLteAttachContext->basicInfo.Compression = (WWAN_COMPRESSION)MbbLteAttachContext->Compression; + WwanLteAttachContext->basicInfo.AuthType = (WWAN_AUTH_PROTOCOL)MbbLteAttachContext->AuthProtocol; + + MbbUtilPopulateStaticString(WwanLteAttachContext->basicInfo.AccessString, MbbLteAttachContext, AccessString ); + + MbbUtilPopulateStaticString(WwanLteAttachContext->basicInfo.UserName, MbbLteAttachContext, UserName ); + + MbbUtilPopulateStaticString(WwanLteAttachContext->basicInfo.Password, MbbLteAttachContext, Password ); + + if(MbbLteAttachContext->IPType >= MbbContextIPTypeDefault && + MbbLteAttachContext->IPType < MbbContextIPTypeMaximum) + { + WwanLteAttachContext->IPType = MbbIpTypesMapTable [MbbLteAttachContext->IPType]; + } + else + { + TraceWarn(WMBCLASS_UTIL, "Invalid IPType returned from the Modem. Resetting it to IPTypeDefault"); + WwanLteAttachContext->IPType = WwanIPTypeDefault; + } + + WwanLteAttachContext->Roaming = (WWAN_CONTEXT_ROAMING_CONTROL)MbbLteAttachContext->Roaming; + + if (MbbLteAttachContext->Source >= MbbMsContextSourceAdmin && + MbbLteAttachContext->Source < MbbMsContextSourceMaximum) + { + WwanLteAttachContext->Source = MbbSourcesMapTable[MbbLteAttachContext->Source]; + } + else + { + TraceWarn(WMBCLASS_UTIL, "Invalid source returned from the Modem. Resetting it to WwanMaxProvisionSource"); + WwanLteAttachContext->Source = WwanMaxProvisionSource; + } +} + +VOID +MbbUtilMbbToWwanLteAttachStatus( +__in MBB_MS_LTE_ATTACH_STATUS* MbbLteAttachStatus, +__out PWWAN_LTE_ATTACH_STATUS WwanLteAttachStatus +) +{ + WwanLteAttachStatus->LteAttachState = MbbLteAttachStatus->LteAttachState; + if(MbbLteAttachStatus->IPType >= MbbContextIPTypeDefault && + MbbLteAttachStatus->IPType < MbbContextIPTypeMaximum) + { + WwanLteAttachStatus->IPType = MbbIpTypesMapTable [MbbLteAttachStatus->IPType]; + } + else + { + TraceWarn(WMBCLASS_UTIL, "Invalid IPType returned from the Modem. Resetting it to IPTypeDefault"); + WwanLteAttachStatus->IPType = WwanIPTypeDefault; + } + + WwanLteAttachStatus->basicInfo.ContextId = 0; + WwanLteAttachStatus->basicInfo.ContextType = WwanContextTypeLteAttach; + WwanLteAttachStatus->basicInfo.Compression = (WWAN_COMPRESSION)MbbLteAttachStatus->Compression; + WwanLteAttachStatus->basicInfo.AuthType = (WWAN_AUTH_PROTOCOL)MbbLteAttachStatus->AuthProtocol; + + MbbUtilPopulateStaticString(WwanLteAttachStatus->basicInfo.AccessString, MbbLteAttachStatus, AccessString ); + + MbbUtilPopulateStaticString(WwanLteAttachStatus->basicInfo.UserName, MbbLteAttachStatus, UserName ); + + MbbUtilPopulateStaticString(WwanLteAttachStatus->basicInfo.Password, MbbLteAttachStatus, Password ); +} + + +VOID +MbbUtilMbbToWwanContextList( + __in PMBB_CONTEXT_LIST MbbContextList, + __out PWWAN_LIST_HEADER WwanContextList + ) +{ + ULONG ContextIndex; + ULONG ContextCount = MbbContextList->ContextCount; + PMBB_CONTEXT MbbContext; + PWWAN_CONTEXT WwanContext; + + + WwanContext = (PWWAN_CONTEXT)(WwanContextList + 1); + + for( ContextIndex = 0; + ContextIndex < ContextCount; + ContextIndex ++ ) + { + MbbContext = (PMBB_CONTEXT)((PUCHAR)MbbContextList + MbbContextList->Contexts[ContextIndex].Offset); + + MbbUtilMbbToWwanContext( + MbbContext, + &WwanContext[ContextIndex] + ); + } + + WwanContextList->ElementType = WwanStructContext; + WwanContextList->ElementCount = ContextCount; +} + +VOID +MbbUtilMbbToWwanContextV2( + __in PMBB_MS_CONTEXT_V2 MbbContext, + __out PWWAN_CONTEXT_V2 WwanContext +) +{ + WwanContext->basicInfo.ContextId = MbbContext->ContextId; + WwanContext->basicInfo.ContextType = MbbUtilMbbToWwanContextType(&MbbContext->ContextType); + WwanContext->basicInfo.Compression = (WWAN_COMPRESSION)MbbContext->Compression; + WwanContext->basicInfo.AuthType = (WWAN_AUTH_PROTOCOL)MbbContext->AuthProtocol; + + MbbUtilPopulateStaticString(WwanContext->basicInfo.AccessString, MbbContext, AccessString); + + MbbUtilPopulateStaticString(WwanContext->basicInfo.UserName, MbbContext, UserName); + + MbbUtilPopulateStaticString(WwanContext->basicInfo.Password, MbbContext, Password); + + WwanContext->IPType = MbbIpTypesMapTable[MbbContext->IPType]; + WwanContext->Enable = (WWAN_CONTEXT_ENABLE)MbbContext->Enable; + WwanContext->Roaming = (WWAN_CONTEXT_ROAMING_CONTROL)MbbContext->Roaming; + WwanContext->MediaType = (WWAN_CONTEXT_MEDIA_TYPE)MbbContext->MediaType; + WwanContext->Source = MbbSourcesMapTable[MbbContext->Source]; +} + +VOID +MbbUtilMbbToWwanContextV2List( + __in PMBB_CONTEXT_LIST MbbContextList, + __out PWWAN_LIST_HEADER WwanContextList +) +{ + ULONG ContextIndex; + ULONG ContextCount = MbbContextList->ContextCount; + PMBB_MS_CONTEXT_V2 MbbContext; + PWWAN_CONTEXT_V2 WwanContext; + + + WwanContext = (PWWAN_CONTEXT_V2)(WwanContextList + 1); + + for (ContextIndex = 0; + ContextIndex < ContextCount; + ContextIndex++) + { + MbbContext = (PMBB_MS_CONTEXT_V2)((PUCHAR)MbbContextList + MbbContextList->Contexts[ContextIndex].Offset); + + MbbUtilMbbToWwanContextV2( + MbbContext, + &WwanContext[ContextIndex] + ); + } + + WwanContextList->ElementType = WwanStructContextV2; + WwanContextList->ElementCount = ContextCount; +} + +VOID +MbbUtilMbbToWwanServiceActivationStatus( + __in PMBB_SERVICE_ACTIVATION_STATUS MbbServiceActivationStatus, + __in ULONG VendorSpecificBufferSize, + __out PWWAN_SERVICE_ACTIVATION_STATUS WwanServiceActivationStatus + ) +{ + WwanServiceActivationStatus->uNwError = MbbServiceActivationStatus->NetworkError; + WwanServiceActivationStatus->uVendorSpecificBufferSize = VendorSpecificBufferSize; + + RtlCopyMemory( + WwanServiceActivationStatus + 1, + MbbServiceActivationStatus->VendorSpecificBuffer, + VendorSpecificBufferSize + ); +} + + +// SMS + +WWAN_SMS_FORMAT +MbbUtilMbbToWwanSmsFormat( + __in MBB_SMS_FORMAT MbbSmsFormat + ) +{ + switch( MbbSmsFormat ) + { + case MbbSmsFormatPdu: + return WwanSmsFormatPdu; + case MbbSmsFormatCdma: + return WwanSmsFormatCdma; + default: + return WwanSmsFormatMax; + } +} + +VOID +MbbUtilMbbToWwanSmsConfiguration( + __in PMBB_SMS_CONFIGURATION MbbSmsConfiguration, + __out PWWAN_SMS_CONFIGURATION WwanSmsConfiguration + ) +{ + NTSTATUS NtStatus; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + + + AnsiString.Buffer = WwanSmsConfiguration->ScAddress; + AnsiString.MaximumLength = WWAN_SMS_ADDRESS_MAX_LEN - 1; + + UnicodeString.Buffer = (PWCHAR)(((PUCHAR)MbbSmsConfiguration) + MbbSmsConfiguration->ScAddress.Offset); + UnicodeString.Length = (USHORT)MbbSmsConfiguration->ScAddress.Size; + UnicodeString.MaximumLength = (USHORT)MbbSmsConfiguration->ScAddress.Size; + + if( (NtStatus = RtlUnicodeStringToAnsiString( + &AnsiString, + &UnicodeString, + FALSE // AllocateDestinationString + )) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_UTIL, "[MbbNdis] FAILED to convert ScAddress Length=%dbytes", MbbSmsConfiguration->ScAddress.Size ); + WwanSmsConfiguration->ScAddress[0] = 0; + } + else + { + WwanSmsConfiguration->ScAddress[AnsiString.Length] = 0; + } + + ASSERT( NtStatus == STATUS_SUCCESS ); + + WwanSmsConfiguration->SmsFormat = MbbUtilMbbToWwanSmsFormat( MbbSmsConfiguration->SmsFormat ); + WwanSmsConfiguration->ulMaxMessageIndex = MbbSmsConfiguration->MaxMessages; +} + +NDIS_STATUS +MbbUtilValidateMbbSmsPduRecord( + __in MBB_CELLULAR_CLASS CellularClass, + __in ULONG MbbSmsPduRecordSize, + __in_bcount(MbbSmsPduRecordSize) PMBB_SMS_PDU_RECORD MbbSmsPduRecord + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; + + do + { + if( MbbSmsPduRecordSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_PDU_RECORD, PduData) ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INSUFFICIENT Buffer size for MBB_SMS_PDU_RECORD, Received=%d Expected=%d", + MbbSmsPduRecordSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_PDU_RECORD, PduData) + ); + break; + } + + if( MbbIsVariableFieldValid( + MbbSmsPduRecordSize, + MbbSmsPduRecord->PduData.Offset, + MbbSmsPduRecord->PduData.Size, + (CellularClass == MbbCellularClassGsm) ? MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH : MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH, + sizeof(UCHAR) + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_PDU_RECORD.Address Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + MbbSmsPduRecord->PduData.Offset, + MbbSmsPduRecordSize, + MbbSmsPduRecord->PduData.Size, + ((CellularClass == MbbCellularClassGsm) ? MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH : MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH) * sizeof(UCHAR) + ); + break; + } + + NdisStatus = NDIS_STATUS_SUCCESS; + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilValidateMbbSmsCdmaRecord( + __in ULONG MbbSmsCdmaRecordSize, + __in_bcount(MbbSmsCdmaRecordSize) PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; + + do + { + if( MbbSmsCdmaRecordSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_CDMA_RECORD, SizeInCharacters) ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INSUFFICIENT Buffer size for MBB_SMS_CDMA_RECORD, Received=%d Expected=%d", + MbbSmsCdmaRecordSize, + RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_CDMA_RECORD, SizeInCharacters) + ); + break; + } + + if( MbbIsVariableFieldValid( + MbbSmsCdmaRecordSize, + MbbSmsCdmaRecord->Address.Offset, + MbbSmsCdmaRecord->Address.Size, + MBB_MAXIMUM_SMS_ADDRESS_LENGTH, + sizeof(WCHAR) + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_CDMA_RECORD.Address Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + MbbSmsCdmaRecord->Address.Offset, + MbbSmsCdmaRecordSize, + MbbSmsCdmaRecord->Address.Size, + MBB_MAXIMUM_SMS_ADDRESS_LENGTH * sizeof(WCHAR) + ); + break; + } + + if( MbbIsVariableFieldValid( + MbbSmsCdmaRecordSize, + MbbSmsCdmaRecord->TimeStamp.Offset, + MbbSmsCdmaRecord->TimeStamp.Size, + MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH, + 1 + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_CDMA_RECORD.TimeStamp Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + MbbSmsCdmaRecord->TimeStamp.Offset, + MbbSmsCdmaRecordSize, + MbbSmsCdmaRecord->TimeStamp.Size, + MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH + ); + break; + } + + if( MbbIsVariableFieldValid( + MbbSmsCdmaRecordSize, + MbbSmsCdmaRecord->EncodedMessage.Offset, + MbbSmsCdmaRecord->EncodedMessage.Size, + MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH, + 1 + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_CDMA_RECORD.EncodedMessage Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + MbbSmsCdmaRecord->EncodedMessage.Offset, + MbbSmsCdmaRecordSize, + MbbSmsCdmaRecord->EncodedMessage.Size, + MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH + ); + break; + } + NdisStatus = NDIS_STATUS_SUCCESS; + } + while( FALSE ); + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilValidateMbbSmsReceive( + __in MBB_CELLULAR_CLASS CellularClass, + __in ULONG MbbSmsReceiveSize, + __in_bcount(MbbSmsReceiveSize) PMBB_SMS_RECEIVE MbbSmsReceive + ) +{ + ULONG ElementIndex; + ULONG ElementCount; + ULONG MbbMaxMessageSize; + NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; + ULONGLONG ExpectedSize; + + do + { + ExpectedSize = RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_RECEIVE, MessageCount); + + if( MbbSmsReceive == NULL || + MbbSmsReceiveSize < ExpectedSize ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INSUFFICIENT BufferSize for MBB_SMS_RECEIVE, BufferSize[Received=%d Expected=%d]", + MbbSmsReceiveSize, + (ULONG)ExpectedSize + ); + break; + } + + ElementCount = MbbSmsReceive->MessageCount; + ExpectedSize += (ULONGLONG)ElementCount * sizeof(MBB_ARRAY_ELEMENT); + if( MbbSmsReceiveSize < ExpectedSize ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INSUFFICIENT BufferSize for MBB_SMS_RECEIVE.MessageElement[%d], BufferSize[Received=%d Expected=%I64u]", + ElementCount, + MbbSmsReceiveSize, + ExpectedSize + ); + break; + } + + if( MbbSmsReceive->SmsFormat == MbbSmsFormatPdu ) + { + + if ( CellularClass == MbbCellularClassGsm ) + { + MbbMaxMessageSize = ROUND_UP_COUNT( FIELD_OFFSET(MBB_SMS_PDU_RECORD,DataBuffer), ALIGN_DWORD ) \ + + ROUND_UP_COUNT( MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH, ALIGN_DWORD ); + } + else + { + + MbbMaxMessageSize = ROUND_UP_COUNT( FIELD_OFFSET(MBB_SMS_PDU_RECORD,DataBuffer), ALIGN_DWORD ) \ + + ROUND_UP_COUNT( MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH, ALIGN_DWORD ); + } + } + else + { + MbbMaxMessageSize = ROUND_UP_COUNT( FIELD_OFFSET(MBB_SMS_CDMA_RECORD,DataBuffer), ALIGN_DWORD ) \ + + ROUND_UP_COUNT( (MBB_MAXIMUM_SMS_ADDRESS_LENGTH * sizeof(WCHAR)), ALIGN_DWORD ) \ + + ROUND_UP_COUNT( MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH, ALIGN_DWORD ) \ + + ROUND_UP_COUNT( MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH, ALIGN_DWORD ); + } + + for( ElementIndex = 0; + ElementIndex < ElementCount; + ElementIndex ++ ) + { + if( MbbIsVariableFieldValid( + MbbSmsReceiveSize, + MbbSmsReceive->MessageElement[ElementIndex].Offset, + MbbSmsReceive->MessageElement[ElementIndex].Size, + MbbMaxMessageSize, + 1 + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID Offset/Size for MBB_SMS_RECEIVE.MessageElement[%d], Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", + ElementIndex, + MbbSmsReceive->MessageElement[ElementIndex].Offset, + MbbSmsReceiveSize, + MbbSmsReceive->MessageElement[ElementIndex].Size, + MbbMaxMessageSize + ); + break; + } + + if( MbbSmsReceive->SmsFormat == MbbSmsFormatPdu ) + { + if( MbbUtilValidateMbbSmsPduRecord( + CellularClass, + MbbSmsReceive->MessageElement[ElementIndex].Size, + (PMBB_SMS_PDU_RECORD)(((PUCHAR)MbbSmsReceive)+MbbSmsReceive->MessageElement[ElementIndex].Offset) + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_PDU_RECORD at MBB_SMS_RECEIVE.MessageElement[%d]", ElementIndex ); + break; + } + } + else + { + if( MbbUtilValidateMbbSmsCdmaRecord( + MbbSmsReceive->MessageElement[ElementIndex].Size, + (PMBB_SMS_CDMA_RECORD)(((PUCHAR)MbbSmsReceive)+MbbSmsReceive->MessageElement[ElementIndex].Offset) + ) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_CDMA_RECORD at MBB_SMS_RECEIVE.MessageElement[%d]", ElementIndex ); + break; + } + } + } + + if( ElementIndex == ElementCount ) + NdisStatus = NDIS_STATUS_SUCCESS; + } + while( FALSE ); + + return NdisStatus; +} + +VOID +MbbUtilMbbToWwanSmsPduRecord( + __in PMBB_SMS_PDU_RECORD MbbSmsPduRecord, + __in MBB_CELLULAR_CLASS CellularClass, + __out PWWAN_SMS_PDU_RECORD WwanSmsPduRecord + ) +/*++ +Description: + For GSM-based devices, messages are hexadecimal strings that + represent messages in PDU format as defined in the + 3GPP TS 27.005 and 3GPP TS 23.040 specifications. + + For CDMA-based devices messages are byte arrays that represent + messages as defined in section 3.4.2.1 SMS Point-to-Point Message + in 3GPP2 specification C.S0015-A "Short Message Service (SMS) + for Wideband Spread Spectrum Systems". + +Assumption: + Buffer and length validation is already performed. +--*/ +{ + WwanSmsPduRecord->MessageIndex = MbbSmsPduRecord->MessageIndex; + WwanSmsPduRecord->MsgStatus = (WWAN_MSG_STATUS)MbbSmsPduRecord->MessageStatus; + // + // Although the MSDN document says that Pdu.Size should excluded the SMSC address length + // no test code or logo code handles it that way. Pdu.Size is the size of the complete PduData. + // + WwanSmsPduRecord->Size = (UCHAR)MbbSmsPduRecord->PduData.Size; + + if( CellularClass == MbbCellularClassGsm ) + { + MbbUtilByteStreamToHexString( + ((PUCHAR)MbbSmsPduRecord) + MbbSmsPduRecord->PduData.Offset, + MbbSmsPduRecord->PduData.Size, + WwanSmsPduRecord->PduData, + WWAN_SMS_PDU_HEX_BUF_LEN + ); + } + else if( CellularClass == MbbCellularClassCdma ) + { + RtlCopyMemory( + WwanSmsPduRecord->PduData, + ((PUCHAR)MbbSmsPduRecord) + MbbSmsPduRecord->PduData.Offset, + MbbSmsPduRecord->PduData.Size + ); + } +} + +VOID +MbbUtilMbbToWwanSmsCdmaRecord( + __in PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord, + __out PWWAN_SMS_CDMA_RECORD WwanSmsCdmaRecord + ) +/*++ +Assumption: + Buffer and length validation is already performed. +--*/ +{ + ULONG MinSize; + NTSTATUS NtStatus; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + + RtlZeroMemory(WwanSmsCdmaRecord, sizeof(WWAN_SMS_CDMA_RECORD)); + + WwanSmsCdmaRecord->MessageIndex = MbbSmsCdmaRecord->MessageIndex; + WwanSmsCdmaRecord->MsgStatus = (WWAN_MSG_STATUS)MbbSmsCdmaRecord->MessageStatus; + WwanSmsCdmaRecord->EncodingId = (WWAN_SMS_CDMA_ENCODING)MbbSmsCdmaRecord->EncodingId; + WwanSmsCdmaRecord->LanguageId = (WWAN_SMS_CDMA_LANG)MbbSmsCdmaRecord->LanguageId; + // + // Address + // + AnsiString.Buffer = WwanSmsCdmaRecord->Address; + AnsiString.MaximumLength = WWAN_SMS_CDMA_ADDR_MAX_LEN - 1; + + UnicodeString.Buffer = (PWCHAR)(((PCHAR)MbbSmsCdmaRecord) + MbbSmsCdmaRecord->Address.Offset); + UnicodeString.Length = (USHORT)MbbSmsCdmaRecord->Address.Size; + UnicodeString.MaximumLength = (USHORT)MbbSmsCdmaRecord->Address.Size; + + if( (NtStatus = RtlUnicodeStringToAnsiString( + &AnsiString, + &UnicodeString, + FALSE // AllocateDestinationString + )) != STATUS_SUCCESS ) + { + TraceError( WMBCLASS_UTIL, "[Util][Sms] FAILED to convert MBB_SMS_CDMA_RECORD.Address Length=%dbytes", MbbSmsCdmaRecord->Address.Size ); + WwanSmsCdmaRecord->Address[0] = 0; + } + else + { + WwanSmsCdmaRecord->Address[AnsiString.Length] = 0; + } + ASSERT( NtStatus == STATUS_SUCCESS ); + // + // Timestamp + // + RtlZeroMemory( + WwanSmsCdmaRecord->ScTimeStamp, + WWAN_SMS_CDMA_TIMESTAMP_MAX_LEN + ); + RtlCopyMemory( + WwanSmsCdmaRecord->ScTimeStamp, + (((PCHAR)MbbSmsCdmaRecord) + MbbSmsCdmaRecord->TimeStamp.Offset), + MIN( MbbSmsCdmaRecord->TimeStamp.Size, WWAN_SMS_CDMA_TIMESTAMP_MAX_LEN ) + ); + // + // EncodedMessage + // + RtlCopyMemory( + WwanSmsCdmaRecord->EncodedMsg, + (((PCHAR)MbbSmsCdmaRecord) + MbbSmsCdmaRecord->EncodedMessage.Offset), + MIN( MbbSmsCdmaRecord->EncodedMessage.Size, WWAN_SMS_CDMA_MAX_BUF_LEN ) + ); + // + // If there is truncation SizeInBytes and SizeInCharacters will go out of sync + // since we dont know how to calculate SizeInCharacters. + // + WwanSmsCdmaRecord->SizeInBytes = (USHORT)MIN( MbbSmsCdmaRecord->EncodedMessage.Size, WWAN_SMS_CDMA_MAX_BUF_LEN ); + WwanSmsCdmaRecord->SizeInCharacters = (UCHAR)MbbSmsCdmaRecord->SizeInCharacters; +} + +NDIS_STATUS +MbbUtilMbbToWwanSmsReceive( + __in_bcount(MbbSmsReceiveSize) PMBB_SMS_RECEIVE MbbSmsReceive, + __in ULONG MbbSmsReceiveSize, + __in MBB_CELLULAR_CLASS CellularClass, + __out PWWAN_LIST_HEADER SmsListHeader + ) +{ + ULONG SmsIndex; + + if( MbbSmsReceive->SmsFormat == MbbSmsFormatPdu ) + { + PWWAN_SMS_PDU_RECORD WwanSmsPduRecord; + PMBB_SMS_PDU_RECORD MbbSmsPduRecord; + + if( CellularClass != MbbCellularClassGsm && + CellularClass != MbbCellularClassCdma ) + { + TraceError( WMBCLASS_UTIL, "[Util][Sms] FAILED to convert PDU record due to invalid CurrentCellularClass=%!MbbCellularClass!", + CellularClass + ); + return NDIS_STATUS_INVALID_STATE; + } + + SmsListHeader->ElementType = WwanStructSmsPdu; + + for(SmsIndex = 0; + SmsIndex < MbbSmsReceive->MessageCount; + SmsIndex ++ ) + { + MbbSmsPduRecord = (PMBB_SMS_PDU_RECORD)(((PCHAR)MbbSmsReceive) + MbbSmsReceive->MessageElement[SmsIndex].Offset); + WwanSmsPduRecord = &((PWWAN_SMS_PDU_RECORD)(SmsListHeader+1))[SmsIndex]; + + MbbUtilMbbToWwanSmsPduRecord( + MbbSmsPduRecord, + CellularClass, + WwanSmsPduRecord + ); + } + } + else if( MbbSmsReceive->SmsFormat == MbbSmsFormatCdma ) + { + PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord; + PWWAN_SMS_CDMA_RECORD WwanSmsCdmaRecord; + + SmsListHeader->ElementType = WwanStructSmsCdma; + + for(SmsIndex = 0; + SmsIndex < MbbSmsReceive->MessageCount; + SmsIndex ++ ) + { + MbbSmsCdmaRecord = (PMBB_SMS_CDMA_RECORD)(((PCHAR)MbbSmsReceive) + MbbSmsReceive->MessageElement[SmsIndex].Offset); + WwanSmsCdmaRecord = &((PWWAN_SMS_CDMA_RECORD)(SmsListHeader+1))[SmsIndex]; + + MbbUtilMbbToWwanSmsCdmaRecord( + MbbSmsCdmaRecord, + WwanSmsCdmaRecord + ); + } + } + else + { + TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB SmsFormat=%d", MbbSmsReceive->SmsFormat ); + return NDIS_STATUS_INVALID_DATA; + } + SmsListHeader->ElementCount = MbbSmsReceive->MessageCount; + + return NDIS_STATUS_SUCCESS; +} + +VOID +MbbUtilMbbToWwanSmsStatus( + __in PMBB_SMS_STATUS MbbSmsStatus, + __out PWWAN_SMS_STATUS WwanSmsStatus + ) +{ + WwanSmsStatus->MessageIndex = MbbSmsStatus->MessageIndex; + WwanSmsStatus->uFlag = WWAN_SMS_FLAG_NONE; + + if( MbbSmsStatus->StatusFlags & MbbSmsFlagMessageStoreFull ) + WwanSmsStatus->uFlag |= WWAN_SMS_FLAG_MESSAGE_STORE_FULL; + + if( MbbSmsStatus->StatusFlags & MbbSmsFlagNewMessage ) + WwanSmsStatus->uFlag |= WWAN_SMS_FLAG_NEW_MESSAGE; +} + +VOID +MbbUtilMbbToWwanUiccFileStatus( + __in PMBB_UICC_FILE_STATUS MbbUiccFileStatus, + __out PWWAN_UICC_FILE_STATUS WwanUiccFileStatus + ) +{ + WwanUiccFileStatus->StatusWord1 = MbbUiccFileStatus->StatusWord1; + WwanUiccFileStatus->StatusWord2 = MbbUiccFileStatus->StatusWord2; + WwanUiccFileStatus->FileAccessibility = (WWAN_UICC_FILE_ACCESSIBILITY)MbbUiccFileStatus->FileAccessibility; + WwanUiccFileStatus->FileType = (WWAN_UICC_FILE_TYPE)MbbUiccFileStatus->FileType; + WwanUiccFileStatus->FileStructure = (WWAN_UICC_FILE_STRUCTURE)MbbUiccFileStatus->FileStructure; + WwanUiccFileStatus->ItemCount = MbbUiccFileStatus->ItemCount; + WwanUiccFileStatus->ItemSize = MbbUiccFileStatus->ItemSize; + + RtlCopyMemory( + WwanUiccFileStatus->FileLockStatus, + MbbUiccFileStatus->FileLockStatus, + sizeof(MbbUiccFileStatus->FileLockStatus) + ); +} + +VOID +MbbUtilMbbToWwanUiccResponse( + __in PMBB_UICC_RESPONSE MbbUiccResponse, + __out PWWAN_UICC_RESPONSE WwanUiccResponse + ) +{ + WwanUiccResponse->StatusWord1 = MbbUiccResponse->StatusWord1; + WwanUiccResponse->StatusWord2 = MbbUiccResponse->StatusWord2; + WwanUiccResponse->ResponseDataSize = (USHORT)MbbUiccResponse->ResponseData.Size; + + RtlCopyMemory( + WwanUiccResponse->ResponseData, + ((PUCHAR)MbbUiccResponse) + MbbUiccResponse->ResponseData.Offset, + MbbUiccResponse->ResponseData.Size + ); +} + +VOID +MbbUtilMbbToWwanUiccAppList( + __in PMBB_UICC_APP_LIST MbbUiccAppList, + __out PWWAN_UICC_APP_LIST WwanUiccAppList +) +{ + ULONG AppCount = MbbUiccAppList->AppCount; + ULONG AppIndex = 0; + PWWAN_UICC_APP_INFO WwanUiccAppInfo = NULL; + PMBB_UICC_APP_INFO MbbUiccAppInfo = NULL; + + WwanUiccAppList->Version = MbbUiccAppList->Version; + WwanUiccAppList->AppCount = MbbUiccAppList->AppCount; + WwanUiccAppList->ActiveAppIndex = MbbUiccAppList->ActiveAppIndex; + WwanUiccAppList->AppListSize = MbbUiccAppList->AppListSize; + + for (AppIndex = 0; AppIndex < AppCount; AppIndex++) + { + WwanUiccAppInfo = (PWWAN_UICC_APP_INFO)((PUCHAR)WwanUiccAppList + + sizeof(WWAN_UICC_APP_LIST) + sizeof(WWAN_UICC_APP_INFO) * AppIndex); + MbbUiccAppInfo = (PMBB_UICC_APP_INFO)((PUCHAR)MbbUiccAppList + + MbbUiccAppList->DataBuffer[AppIndex].Offset); + + WwanUiccAppInfo->AppType = (WWAN_UICC_APP_TYPE)MbbUiccAppInfo->AppType; + WwanUiccAppInfo->AppIdSize = (BYTE)(MbbUiccAppInfo->AppId.Size); + WwanUiccAppInfo->AppNameLength = (BYTE)(MbbUiccAppInfo->AppName.Size); + WwanUiccAppInfo->NumPins = MbbUiccAppInfo->NumPins; + RtlCopyMemory(WwanUiccAppInfo->AppId, + (PUCHAR)WwanUiccAppInfo + MbbUiccAppInfo->AppId.Offset, + MbbUiccAppInfo->AppId.Size); + RtlCopyMemory(WwanUiccAppInfo->AppName, + (PUCHAR)WwanUiccAppInfo + MbbUiccAppInfo->AppName.Offset, + MbbUiccAppInfo->AppName.Size); + RtlCopyMemory(WwanUiccAppInfo->PinRef, + (PUCHAR)WwanUiccAppInfo + MbbUiccAppInfo->PinRef.Offset, + MbbUiccAppInfo->PinRef.Size); + } +} + +VOID +MbbUtilMbbToWwanSysCapsInfo( + __in PMBB_MS_SYS_CAPS_INFO MbbSysCapsInfo, + __out PWWAN_SYS_CAPS_INFO WwanSysCapsInfo + ) +{ + WwanSysCapsInfo->NumberOfExecutors = MbbSysCapsInfo->NumberOfExecutors; + WwanSysCapsInfo->NumberOfSlots = MbbSysCapsInfo->NumberOfSlots; + WwanSysCapsInfo->Concurrency = MbbSysCapsInfo->Concurrency; + WwanSysCapsInfo->ModemID = MbbSysCapsInfo->ModemId; +} + +VOID +MbbUtilMbbToWwanDeviceSlotMappingInfo( + __in PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbDeviceSlotMappingInfo, + __out PWWAN_DEVICE_SLOT_MAPPING_INFO WwanDeviceSlotMappingInfo + ) +{ + WwanDeviceSlotMappingInfo->SlotMapListHeader.ElementType = WwanStructDeviceSlotMap; + WwanDeviceSlotMappingInfo->SlotMapListHeader.ElementCount = MbbDeviceSlotMappingInfo->MapCount; + + RtlCopyMemory((PUCHAR)WwanDeviceSlotMappingInfo + sizeof(WWAN_DEVICE_SLOT_MAPPING_INFO), + (PUCHAR)MbbDeviceSlotMappingInfo + MbbDeviceSlotMappingInfo->SlotMapList[0].Offset, + sizeof(ULONG) * MbbDeviceSlotMappingInfo->MapCount); +} + +VOID +MbbUtilMbbToWwanSlotInfo( + __in PMBB_MS_SLOT_INFO MbbSlotInfo, + __out PWWAN_SLOT_INFO WwanSlotInfo + ) +{ + WwanSlotInfo->SlotIndex = MbbSlotInfo->SlotIndex; + WwanSlotInfo->State = (WWAN_UICCSLOT_STATE)(MbbSlotInfo->State); +} + +VOID +MbbUtilMbbToWwanDeviceBindingsInfo( + __in PMBB_DEVICE_BINDINGS_INFO MbbDeviceBindingsInfo, + __out PWWAN_DEVICE_BINDINGS_INFO WwanDeviceBindingsInfo + ) +{ + ULONG AppCount = MbbDeviceBindingsInfo->ApplicationCount; + ULONG AppIndex = 0; + PWWAN_UICC_FILE_PATH WwanUiccFilePath = NULL; + PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; + + WwanDeviceBindingsInfo->ApplicationListHeader.ElementType = WwanStructUiccApplication; + WwanDeviceBindingsInfo->ApplicationListHeader.ElementCount = AppCount; + + for (AppIndex = 0; AppIndex < AppCount; AppIndex++) + { + WwanUiccFilePath = (PWWAN_UICC_FILE_PATH)((PUCHAR)WwanDeviceBindingsInfo + + sizeof(WWAN_DEVICE_BINDINGS_INFO) + sizeof(WWAN_UICC_FILE_PATH) * AppIndex); + MbbUiccFilePath = (PMBB_UICC_FILE_PATH)((PUCHAR)MbbDeviceBindingsInfo + + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Offset); + + RtlZeroMemory(WwanUiccFilePath, sizeof(WWAN_UICC_FILE_PATH)); + + WwanUiccFilePath->AppIdLength = (BYTE)(MbbUiccFilePath->AppId.Size); + RtlCopyMemory(WwanUiccFilePath->AppId, + (PUCHAR)MbbUiccFilePath + MbbUiccFilePath->AppId.Offset, + MbbUiccFilePath->AppId.Size); + + // FilePath in MBB_UICC_FILE_PATH is not used for this OID/CID. + } +} + +VOID +MbbUtilMbbToWwanRegistrationStateInfoV2( + __in PMBB_REGISTRATION_STATE_INFOS_V2 MbbRegistrationStateInfosV2, + __out PWWAN_REGISTRATION_STATE_INFOS WwanRegistrationStateInfos + ) +{ + ULONG RegistrationStateCount = MbbRegistrationStateInfosV2->ElementCount; + ULONG RegistrationStateIndex = 0; + PWWAN_REGISTRATION_STATE_EX WwanRegistrationStateEx = NULL; + PMBB_REGISTRATION_STATE_V2 MbbRegistrationStateV2 = NULL; + + WwanRegistrationStateInfos->RegistrationStateListHeader.ElementType = WwanStructRegistrationState; + WwanRegistrationStateInfos->RegistrationStateListHeader.ElementCount = RegistrationStateCount; + + for (RegistrationStateIndex = 0; RegistrationStateIndex < RegistrationStateCount; RegistrationStateIndex++) + { + WwanRegistrationStateEx = (PWWAN_REGISTRATION_STATE_EX)((PUCHAR)WwanRegistrationStateInfos + + sizeof(WWAN_REGISTRATION_STATE_INFOS) + sizeof(WWAN_REGISTRATION_STATE_EX) * RegistrationStateIndex); + MbbRegistrationStateV2 = (PMBB_REGISTRATION_STATE_V2)((PUCHAR)MbbRegistrationStateInfosV2 + + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Offset); + + RtlZeroMemory(WwanRegistrationStateEx, sizeof(WWAN_REGISTRATION_STATE_EX)); + + WwanRegistrationStateEx->uNwError = MbbRegistrationStateV2->NetworkError; + WwanRegistrationStateEx->RegisterState = (WWAN_REGISTER_STATE)(MbbRegistrationStateV2->RegisterState); + WwanRegistrationStateEx->RegisterMode = (WWAN_REGISTER_MODE)(MbbRegistrationStateV2->RegisterMode); + + MbbUtilPopulateStaticString(WwanRegistrationStateEx->ProviderId, MbbRegistrationStateV2, ProviderId); + MbbUtilPopulateStaticString(WwanRegistrationStateEx->ProviderName, MbbRegistrationStateV2, ProviderName); + MbbUtilPopulateStaticString(WwanRegistrationStateEx->RoamingText, MbbRegistrationStateV2, RoamingText); + + WwanRegistrationStateEx->WwanRegFlags = (DWORD)(MbbRegistrationStateV2->RegFlags); + WwanRegistrationStateEx->CurrentCellularClass = (WWAN_CELLULAR_CLASS)(MbbRegistrationStateV2->CurrentCellularClass); + WwanRegistrationStateEx->AvailableDataClasses = MbbRegistrationStateV2->AvailableDataClasses; + WwanRegistrationStateEx->VoiceSupport = MbbRegistrationStateV2->VoiceSupport; + WwanRegistrationStateEx->CurrentRATClass = MbbRegistrationStateV2->CurrentRATClass; + } +} + +VOID +MbbUtilMbbToWwanSignalStateInfoV2( + __in PMBB_SIGNAL_STATE_INFOS_V2 MbbSignalStateInfosV2, + __out PWWAN_SIGNAL_STATE_INFOS WwanSignalStateInfos + ) +{ + ULONG SignalStateCount = MbbSignalStateInfosV2->ElementCount; + ULONG SignalStateIndex = 0; + PWWAN_SIGNAL_STATE_EX WwanSignalStateEx = NULL; + PMBB_SIGNAL_STATE_V2 MbbSignalStateV2 = NULL; + + WwanSignalStateInfos->SignalStateListHeader.ElementType = WwanStructSignalState; + WwanSignalStateInfos->SignalStateListHeader.ElementCount = SignalStateCount; + + + for (SignalStateIndex = 0; SignalStateIndex < SignalStateCount; SignalStateIndex++) + { + WwanSignalStateEx = (PWWAN_SIGNAL_STATE_EX)((PUCHAR)WwanSignalStateInfos + + sizeof(WWAN_SIGNAL_STATE_INFOS) + sizeof(WWAN_SIGNAL_STATE_EX) * SignalStateIndex); + MbbSignalStateV2 = (PMBB_SIGNAL_STATE_V2)((PUCHAR)MbbSignalStateInfosV2 + + MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Offset); + + WwanSignalStateEx->Rssi = MbbSignalStateV2->Rssi; + WwanSignalStateEx->ErrorRate = MbbSignalStateV2->ErrorRate; + WwanSignalStateEx->RssiInterval = MbbSignalStateV2->RssiInterval; + WwanSignalStateEx->RssiThreshold = MbbSignalStateV2->RssiThreshold; + WwanSignalStateEx->ErrorRateThreshold = MbbSignalStateV2->ErrorRateThreshold; + WwanSignalStateEx->Snr = MbbSignalStateV2->Snr; + WwanSignalStateEx->SnrThreshold = MbbSignalStateV2->SnrThreshold; + WwanSignalStateEx->DataClass = MbbSignalStateV2->DataClass; + } +} + +VOID +MbbUtilMbbToWwanAtrInfo( + __in PMBB_ATR_INFO MbbAtrInfo, + __out PWWAN_ATR_INFO WwanAtrInfo + ) +{ + WwanAtrInfo->AtrLength = MbbAtrInfo->Atr.Size; + + RtlCopyMemory( + WwanAtrInfo->Atr, + (PUCHAR)MbbAtrInfo + MbbAtrInfo->Atr.Offset, + MbbAtrInfo->Atr.Size + ); +} + +VOID +MbbUtilMbbToWwanUiccOpenChannelInfo( + __in PMBB_UICC_OPEN_CHANNEL_INFO MbbUiccOpenChannelInfo, + __out PWWAN_UICC_OPEN_CHANNEL_INFO WwanUiccOpenChannelInfo + ) +{ + RtlCopyMemory( + WwanUiccOpenChannelInfo->Status, + MbbUiccOpenChannelInfo->Status, + WWAN_UICC_STATUS_LEN + ); + + WwanUiccOpenChannelInfo->Channel = MbbUiccOpenChannelInfo->Channel; + WwanUiccOpenChannelInfo->ResponseLength = MbbUiccOpenChannelInfo->Response.Size; + + RtlCopyMemory( + WwanUiccOpenChannelInfo->Response, + (PUCHAR)MbbUiccOpenChannelInfo + MbbUiccOpenChannelInfo->Response.Offset, + MbbUiccOpenChannelInfo->Response.Size + ); +} + +VOID +MbbUtilMbbToWwanUiccCloseChannelInfo( + __in PMBB_UICC_CLOSE_CHANNEL_INFO MbbUiccCloseChannelInfo, + __out PWWAN_UICC_CLOSE_CHANNEL_INFO WwanUiccCloseChannelInfo + ) +{ + RtlCopyMemory( + WwanUiccCloseChannelInfo->Status, + MbbUiccCloseChannelInfo->Status, + WWAN_UICC_STATUS_LEN + ); +} + +VOID +MbbUtilMbbToWwanUiccApduInfo( + __in PMBB_UICC_APDU_INFO MbbUiccApduInfo, + __out PWWAN_UICC_APDU_INFO WwanUiccApduInfo + ) +{ + RtlCopyMemory( + WwanUiccApduInfo->Status, + MbbUiccApduInfo->Status, + WWAN_UICC_STATUS_LEN + ); + + WwanUiccApduInfo->ResponseLength = MbbUiccApduInfo->Response.Size; + + RtlCopyMemory( + WwanUiccApduInfo->Response, + (PUCHAR)MbbUiccApduInfo + MbbUiccApduInfo->Response.Offset, + MbbUiccApduInfo->Response.Size + ); +} + +VOID +MbbUtilMbbToWwanUiccTerminalCapabilityInfo( + __in PMBB_UICC_TERMINAL_CAPABILITY_INFO MbbUiccTerminalCapabilityInfo, + __out PWWAN_LIST_HEADER WwanCapabilityListHeader + ) +{ + ULONG CapabilityCount = MbbUiccTerminalCapabilityInfo->ElementCount; + ULONG CapabilityIndex = 0; + + WwanCapabilityListHeader->ElementType = WwanStructUiccTerminalCapability; + WwanCapabilityListHeader->ElementCount = CapabilityCount; + + for (CapabilityIndex = 0; CapabilityIndex < CapabilityCount; CapabilityIndex++) + { + RtlCopyMemory( + (PUCHAR)WwanCapabilityListHeader + sizeof(WWAN_LIST_HEADER) + sizeof(WWAN_UICC_TERMINAL_CAPABILITY_TLV) * CapabilityIndex, + (PUCHAR)MbbUiccTerminalCapabilityInfo + MbbUiccTerminalCapabilityInfo->CapabilityList[CapabilityIndex].Offset, + sizeof(MBB_UICC_TERMINAL_CAPABILITY_TLV) + ); + } +} + +VOID +MbbUtilMbbToWwanSarConfigInfo( + _In_ PMBB_SAR_CONFIG_INFO MbbSarConfigInfo, + _Out_ PWWAN_SAR_CONFIG_INFO WwanSarConfigInfo +) +{ + ULONG count = MbbSarConfigInfo->ElementCount; + + WwanSarConfigInfo->SarMode = (WWAN_SAR_CONTROL_MODE)MbbSarConfigInfo->SarMode; + WwanSarConfigInfo->SarBackoffStatus = (WWAN_SAR_BACKOFF_STATE)MbbSarConfigInfo->SarBackoffStatus; + WwanSarConfigInfo->SarWifiIntegration = (WWAN_SAR_WIFI_HARDWARE_INTEGRATION)MbbSarConfigInfo->SarWifiIntegration; + WwanSarConfigInfo->SarConfigIndexListHeader.ElementType = WwanStructSarConfig; + WwanSarConfigInfo->SarConfigIndexListHeader.ElementCount = count; + + RtlCopyMemory( + (PBYTE)WwanSarConfigInfo + sizeof(WWAN_SAR_CONFIG_INFO), + (PBYTE)MbbSarConfigInfo + MbbSarConfigInfo->Configurations[0].Offset, + sizeof(WWAN_SAR_CONFIG_INDICES) * count + ); +} + +VOID +MbbUtilMbbToWwanTransmissionStatusInfo( + _In_ PMBB_SAR_TRANSMISSION_STATUS_INFO MbbTransmissionStatusInfo, + _Out_ PWWAN_SAR_TRANSMISSION_STATUS_INFO WwanTransmissionStatusInfo +) +{ + WwanTransmissionStatusInfo->ChannelNotification = (WWAN_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE)MbbTransmissionStatusInfo->ChannelNotification; + WwanTransmissionStatusInfo->TransmissionStatus = (WWAN_SAR_TRANSMISSION_STATUS)MbbTransmissionStatusInfo->TransmissionStatus; + WwanTransmissionStatusInfo->HysteresisTimer = MbbTransmissionStatusInfo->HysteresisTimer; +} + + +VOID +MbbUtilMbbToWwanNetworkBlackList( + __in PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist, + __out PWWAN_LIST_HEADER WwanBlacklistProviderList +) +{ + ULONG ProviderIndex; + ULONG ProviderCount = MbbNetworkBlacklist->ElementCount; + PMBB_MS_NETWORK_BLACKLIST_PROVIDER MbbProvider; + PWWAN_NETWORK_BLACKLIST_PROVIDER WwanProvider; + + WwanProvider = (PWWAN_NETWORK_BLACKLIST_PROVIDER)(WwanBlacklistProviderList + 1); + + for (ProviderIndex = 0; + ProviderIndex < ProviderCount; + ProviderIndex++) + { + MbbProvider = (PMBB_MS_NETWORK_BLACKLIST_PROVIDER)((PUCHAR)MbbNetworkBlacklist + MbbNetworkBlacklist->Contexts[ProviderIndex].Offset); + + WwanProvider[ProviderIndex].MCC = MbbProvider->MCC; + WwanProvider[ProviderIndex].MNC = MbbProvider->MNC; + WwanProvider[ProviderIndex].NetworkBlacklistType = MbbProvider->NetworkBlacklistType; + } + + WwanBlacklistProviderList->ElementType = WwanStructNetworkBlacklistProvider; + WwanBlacklistProviderList->ElementCount = ProviderCount; +} + +// +// Drain Object +// + +VOID +InitDrainObject( + PDRAIN_OBJECT DrainObject, + MBB_DRAIN_COMPLETE DrainCompleteCallback, + PVOID Context + ) +/*++ + The drain object is initialized as draining because + the first thing that will happen on miniport initialization + is the Restart handler will get called which will call + DrainComplete. DrainComplete requires that Draining is + set to TRUE and it will set Draining to FALSE starting the + queue. +--*/ +{ + RtlZeroMemory(DrainObject, sizeof(*DrainObject)); + + NdisAllocateSpinLock(&DrainObject->Lock); + DrainObject->Draining=TRUE; + DrainObject->DrainComplete=TRUE; + DrainObject->Count=0; + DrainObject->DrainCompleteCallback=DrainCompleteCallback; + DrainObject->Context=Context; +} + +VOID +StartDrain( + PDRAIN_OBJECT DrainObject + ) + +{ + BOOLEAN CallComplete=FALSE; + + NdisAcquireSpinLock(&DrainObject->Lock); + + ASSERT(!DrainObject->Draining); + + DrainObject->Draining=TRUE; + DrainObject->DrainComplete=FALSE; + + if (DrainObject->Count == 0) + { + CallComplete=TRUE; + DrainObject->DrainComplete=TRUE; + } + + NdisReleaseSpinLock(&DrainObject->Lock); + + if (CallComplete) + { + DrainObject->DrainCompleteCallback(DrainObject->Context); + } + + return; +} + +VOID +DrainComplete( + PDRAIN_OBJECT DrainObject + ) + +{ + NdisAcquireSpinLock(&DrainObject->Lock); + + ASSERT(DrainObject->Draining); + ASSERT(DrainObject->DrainComplete); + + DrainObject->Draining=FALSE; + + NdisReleaseSpinLock(&DrainObject->Lock); + +} + +BOOLEAN +DrainAddRef( + PDRAIN_OBJECT DrainObject + ) + +{ + BOOLEAN Ready=FALSE; + + NdisAcquireSpinLock(&DrainObject->Lock); + + if ( (Ready = !DrainObject->Draining) ) + { + DrainObject->Count++; + } + + NdisReleaseSpinLock(&DrainObject->Lock); + + return Ready; +} + +VOID +DrainRelease( + PDRAIN_OBJECT DrainObject + ) + +{ + BOOLEAN CallComplete=FALSE; + + NdisAcquireSpinLock(&DrainObject->Lock); + DrainObject->Count--; + if ((DrainObject->Count == 0) && DrainObject->Draining) + { + CallComplete=TRUE; + DrainObject->DrainComplete=TRUE; + } + NdisReleaseSpinLock(&DrainObject->Lock); + + if (CallComplete) + { + DrainObject->DrainCompleteCallback(DrainObject->Context); + } + + return; + + +} + +NTSTATUS +MbbEventActivityIdCtl ( + _Inout_ LPGUID ActivityId + ) +/* ++ +Routine Description: + + Creates an activity identifier + +Arguments: + + +ActivityId [in, out] - The identifier that indicates the activity associated with the event. The ActivityId + parameter provides a way to group related events and is used in end-to-end tracing. + +Return Value: + + STATUS_SUCCESS or an appropriate NTSTATUS value. + */ +{ + + if(ActivityId == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + return EtwActivityIdControl(EVENT_ACTIVITY_CTRL_CREATE_ID, ActivityId); +} + +VOID +MbbWriteEvent ( + IN PCEVENT_DESCRIPTOR EventDescriptor, + IN LPGUID ActivityId OPTIONAL, + IN LPGUID RelatedActivityId OPTIONAL, + IN USHORT ArgCount, + ... + ) + +/*++ + +Routine Description: + + Writes an ETW event. + +Arguments: + + EventDescriptor - Supplies the event descriptor. + + ActivityId - Supplies the activity GUID to be associated with this event. + + ArgCount - Supplies the number of elements in the variable list. + + ... - Supplies the variable list of event data to write. + +Return Value: + + None. + +--*/ + +{ + va_list Arguments; + + va_start(Arguments, ArgCount); + + MbbWriteEventCommon( + GlobalControl.TraceHandle, + EventDescriptor, + ActivityId, + RelatedActivityId, + ArgCount, + Arguments + ); + + va_end(Arguments); + + return; +} + +VOID +MbbWriteEventOpn ( + IN PCEVENT_DESCRIPTOR EventDescriptor, + IN LPGUID ActivityId OPTIONAL, + IN LPGUID RelatedActivityId OPTIONAL, + IN USHORT ArgCount, + ... + ) + +/*++ + +Routine Description: + + Writes an ETW event for OPN. + +Arguments: + + EventDescriptor - Supplies the event descriptor. + + ActivityId - Supplies the activity GUID to be associated with this event. + + ArgCount - Supplies the number of elements in the variable list. + + ... - Supplies the variable list of event data to write. + +Return Value: + + None. + +--*/ + +{ + va_list Arguments; + + va_start(Arguments, ArgCount); + + MbbWriteEventCommon( + GlobalControl.TraceHandleOpn, + EventDescriptor, + ActivityId, + RelatedActivityId, + ArgCount, + Arguments + ); + + va_end(Arguments); + + return; +} + +VOID +MbbWriteEventCommon ( + IN REGHANDLE TraceHandle, + IN PCEVENT_DESCRIPTOR EventDescriptor, + IN LPGUID ActivityId OPTIONAL, + IN LPGUID RelatedActivityId OPTIONAL, + IN USHORT ArgCount, + IN va_list Arguments + ) + +/*++ + +Routine Description: + + Writes an ETW event. + +Arguments: + + TraceHandle - Supplies the trace handle. + + EventDescriptor - Supplies the event descriptor. + + ActivityId - Supplies the activity GUID to be associated with this event. + + ArgCount - Supplies the number of elements in the variable list. + + Arguments - Supplies the variable list of event data to write. + +Return Value: + + None. + +--*/ + +{ + + EVENT_DATA_DESCRIPTOR EventData[WMBCLASS_MAX_EVENT_DATA_DESCRIPTORS]; + PEVENT_DATA_DESCRIPTOR DataDescriptors; + ULONG EventDataCount = 0; + ULONG Length; + PVOID Source; + + if (TraceHandle == 0) + { + return; + } + + if (ArgCount > MAX_EVENT_DATA_DESCRIPTORS) { + return; + } + + if (ArgCount <= WMBCLASS_MAX_EVENT_DATA_DESCRIPTORS) { + DataDescriptors = &EventData[0]; + + } else { +#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate new data descriptors, release when ETW write finishes.") + DataDescriptors = ALLOCATE_NONPAGED_POOL(sizeof(EVENT_DATA_DESCRIPTOR) * ArgCount); + + if (!DataDescriptors) { + return; + } + } + + // + // Build up the event data descriptors. + // + + while (EventDataCount < ArgCount) { + Source = va_arg(Arguments, PVOID); + Length = va_arg(Arguments, ULONG); + + // + // EtwWrite expects that if Size > 0 then Ptr != NULL. + // Passing a null pointer with Size > 0 causes it to enter a critical + // region and then throw an exception without exiting the critical + // region. This makes driver verifier bugcheck because of a mismatched + // APC Disable count on the thread (even if the exception has been + // catched). + // + NT_ASSERT(Length == 0 || Source != NULL); + + DataDescriptors[EventDataCount].Ptr = (ULONGLONG)Source; + DataDescriptors[EventDataCount].Size = Length; + + EventDataCount++; + } + + // + // Write all the event data. + // + + if (RelatedActivityId == NULL) { + + EtwWrite(TraceHandle, + EventDescriptor, + ActivityId, + EventDataCount, + DataDescriptors); + } else { + + EtwWriteTransfer(TraceHandle, + EventDescriptor, + ActivityId, + RelatedActivityId, + EventDataCount, + DataDescriptors); + } + + if (DataDescriptors != &EventData[0]) { + + NT_ASSERT(DataDescriptors != NULL); + FREE_POOL(DataDescriptors); + } + + return; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetUSSD( + __out PMBB_SET_USSD MbbSetUSSD, + __in PWWAN_USSD_REQUEST WWanUSSDRequest +) +{ + NTSTATUS ntStatus; + // + // Convert WWAN -> MBB + // + if(WWanUSSDRequest->RequestType == WwanUssdRequestInitiate){ + MbbSetUSSD->USSDAction = MbbUSSDInitiate; + } + else if (WWanUSSDRequest->RequestType == WwanUssdRequestContinue){ + MbbSetUSSD->USSDAction = MbbUSSDContinue; + } + else if(WWanUSSDRequest->RequestType == WwanUssdRequestCancel) { + MbbSetUSSD->USSDAction = MbbUSSDCancel; + } + else { + TraceError( WMBCLASS_OID, "[Util][USSD] INVALID USSD Requestt Type from client =%d", WWanUSSDRequest->RequestType ); + return NDIS_STATUS_INVALID_PARAMETER; + } + + MbbSetUSSD->USSDDataCodingScheme = WWanUSSDRequest->UssdString.DataCodingScheme; + MbbSetUSSD->USSDPayload.Size = WWanUSSDRequest->UssdString.StringLength;//bytes + MbbSetUSSD->USSDPayload.Offset = FIELD_OFFSET(MBB_SET_USSD, DataBuffer); + + RtlCopyMemory(MbbSetUSSD->DataBuffer, + WWanUSSDRequest->UssdString.String, + MbbSetUSSD->USSDPayload.Size); + + return NDIS_STATUS_SUCCESS; + +} + +NDIS_STATUS +MbbUtilMbbToWwanUSSDEvent( + __in PMBB_USSD MbbUSSD, + __out PWWAN_USSD_EVENT WWanUSSDEvt + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + if ( MbbUSSD->USSDResponse == MbbUSSDNoActionRequired){ + WWanUSSDEvt->EventType= WwanUssdEventNoActionRequired; + } + else if (MbbUSSD->USSDResponse == MbbUSSDActionRequired){ + WWanUSSDEvt->EventType = WwanUssdEventActionRequired; + } + else if (MbbUSSD->USSDResponse == MbbUSSDTerminated){ + WWanUSSDEvt->EventType = WwanUssdEventTerminated; + } + else if (MbbUSSD->USSDResponse == MbbUSSDOtherLocalClient){ + WWanUSSDEvt->EventType = WwanUssdEventOtherLocalClient; + } + else if (MbbUSSD->USSDResponse == MbbUSSDOperationNotSupported){ + WWanUSSDEvt->EventType = WwanUssdEventOperationNotSupported; + } + else if (MbbUSSD->USSDResponse == MbbUSSDNetworkTimeOut){ + WWanUSSDEvt->EventType = WwanUssdEventNetworkTimeOut; + } + else{ + // + // Todo: no invalid status code in WWAN_USSD_RESPONSE, should probably define one. + // + // + // Device/network is returning invalid data. + // + TraceError( WMBCLASS_OID, "[Util][USSD] INVALID USSD Response from device =%d", MbbUSSD->USSDResponse ); + return NDIS_STATUS_INVALID_DATA; + } + + WWanUSSDEvt->UssdString.DataCodingScheme = (BYTE)MbbUSSD->USSDDataCodingScheme; + + if (MbbUSSD->USSDSessionState == MbbUSSDNewSession){ + WWanUSSDEvt->SessionState = WwanUssdSessionStateNew; + } + else if (MbbUSSD->USSDSessionState == MbbUSSDExistingSession){ + WWanUSSDEvt->SessionState = WwanUssdSessionStateExisting; + } + else + { + // + // Todo: no invalid status code in WWAN_USSD_RESPONSE, should probably define one. + // + // + // Device/network is returning invalid data. + // + TraceError( WMBCLASS_OID, "[Util][USSD] INVALID USSD Response.SessionState from device =%d", MbbUSSD->USSDSessionState ); + return NDIS_STATUS_INVALID_DATA; + } + + WWanUSSDEvt->UssdString.StringLength = 0; + + if (MbbUSSD->USSDPayload.Size > MBB_USSD_STRING_LEN_MAX) + { + // + // Device/network is returning invalid data. + // + TraceError( WMBCLASS_OID, "[Util][USSD] INVALID USSD Response from device =%d", MbbUSSD->USSDPayload.Size ); + NdisStatus = NDIS_STATUS_INVALID_DATA; + + } + else + { + WWanUSSDEvt->UssdString.StringLength = (BYTE)MbbUSSD->USSDPayload.Size; + + RtlCopyMemory(WWanUSSDEvt->UssdString.String, + MbbUSSD->DataBuffer, + MbbUSSD->USSDPayload.Size + ); + } + + return NdisStatus; + +} + + +ULONG +MbbUtilWriteStringToBuffer( + __in_ecount(BufferSize) PUCHAR Start, + __in ULONG BufferSize, + __in ULONG CurrentOffset, + __in PMBB_STRING StringDesc, + __in_ecount(SourceLength) PCUCHAR SourceString, + __in ULONG SourceLength + ) + +{ + + CurrentOffset= ROUND_UP_COUNT(CurrentOffset, ALIGN_DWORD); + + // + // Only copy if the buffer is not overflown. + // + if( ((ULONGLONG)CurrentOffset) + SourceLength <= BufferSize ) + { + StringDesc->Offset=0; + StringDesc->Size=SourceLength; + + if (StringDesc->Size > 0) + { + // + // only set this if the size is non zero. otherwise offset and size are both zero. + StringDesc->Offset=CurrentOffset; + + RtlCopyMemory(&Start[CurrentOffset], SourceString, SourceLength); + + CurrentOffset= ROUND_UP_COUNT(CurrentOffset+SourceLength, ALIGN_DWORD); + + } + } + else + { + ASSERT(((ULONGLONG)CurrentOffset) + SourceLength <= BufferSize); + DbgBreakPoint(); + } + return CurrentOffset; + +} + +BOOLEAN +MbbUtilIsNativeMbnService( + __in GUID* DeviceServiceGuid + ) +{ + ULONG i = 0; + + for (i = 0; i < ARRAYSIZE(NativeMbnServices); i++) + { + if (RtlCompareMemory(&NativeMbnServices[i], DeviceServiceGuid, sizeof(GUID)) + == sizeof(GUID)) + { + // Matching ID + return TRUE; + } + } + + return FALSE; +} + +PMBB_DS +MbbUtilFindDeviceService( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in GUID* DeviceServiceGuid + ) +{ + ULONG i = 0; + + for (i = 0; i < Adapter->DeviceServiceState.ServicesCount; i++) + { + if (RtlCompareMemory(&(Adapter->DeviceServiceState.ServicesList[i].DeviceServiceId), DeviceServiceGuid, sizeof(GUID)) + == sizeof(GUID)) + { + // Matching ID + return &(Adapter->DeviceServiceState.ServicesList[i]); + } + } + + return NULL; +} + +_Requires_lock_not_held_(&Port->Lock) +NDIS_STATUS +MbbUtilAddNoMatchFilter( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_PORT Port + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PUCHAR PatternBuffer = NULL; + ULONG PatternSize = MBB_NO_MATCH_WOL_PATTERN_SIZE; + ULONG TotalPatternLength = 0; + ULONG MaskSize = 0; + ULONG PatternNameSize = 0; + RTL_BITMAP BitMap; + PNDIS_PM_WOL_PATTERN NoMatchWolPattern = NULL; + NDIS_PM_COUNTED_STRING PatternFriendlyName = {0}; + NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; + + struct _WOL_BITMAP_PATTERN *WoLBitMapPattern = NULL; + + if(!Port ) + { + return NDIS_STATUS_INVALID_PARAMETER; + } + + // + // First, round up to an integral multiple of the number of bits in ULONG. + // Then, determine the number of bytes required to store the bit-mask. + // + + MaskSize = (((PatternSize + RTL_BITS_OF(ULONG) - 1) & ~(RTL_BITS_OF(ULONG) - 1))/ RTL_BITS_OF(UCHAR)); + + TotalPatternLength = sizeof(NDIS_PM_WOL_PATTERN) + PatternSize + MaskSize; + + PatternBuffer = ALLOCATE_NONPAGED_POOL(TotalPatternLength); + + if(PatternBuffer == NULL) + { + Status = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + NdisZeroMemory(PatternBuffer, TotalPatternLength); + + NoMatchWolPattern = (PNDIS_PM_WOL_PATTERN) PatternBuffer; + WoLBitMapPattern = &NoMatchWolPattern->WoLPattern.WoLBitMapPattern; + + NoMatchWolPattern->Header.Revision = NDIS_PM_WOL_PATTERN_REVISION_2; + NoMatchWolPattern->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + NoMatchWolPattern->Header.Size = NDIS_SIZEOF_NDIS_PM_WOL_PATTERN_REVISION_2; + NoMatchWolPattern->WoLPacketType = NdisPMWoLPacketBitmapPattern; + NoMatchWolPattern->Priority = NDIS_PM_WOL_PRIORITY_NORMAL; + NoMatchWolPattern->PatternId = MBB_NO_MATCH_WOL_PATTERN_ID; // invalid pattern Id + + WoLBitMapPattern->MaskOffset = sizeof(NDIS_PM_WOL_PATTERN); + WoLBitMapPattern->MaskSize = MaskSize; + WoLBitMapPattern->PatternOffset = sizeof(NDIS_PM_WOL_PATTERN) + MaskSize; + WoLBitMapPattern->PatternSize = PatternSize; + + RtlInitializeBitMap( + &BitMap, + (PULONG) (PatternBuffer + sizeof(NDIS_PM_WOL_PATTERN)), + MaskSize * RTL_BITS_OF(UCHAR)); + + //set the first bit of the mask + RtlSetBits(&BitMap, 0, 1); + + MBB_ACQUIRE_PORT_LOCK(Port); + PortNumber = Port->PortNumber; + MBB_RELEASE_PORT_LOCK(Port); + + // Add the no-match filter + + Status = MbbUtilSetPowerFilterPattern( + Adapter, + PortNumber, + NoMatchWolPattern->PatternId, + PatternBuffer + NoMatchWolPattern->WoLPattern.WoLBitMapPattern.MaskOffset, + NoMatchWolPattern->WoLPattern.WoLBitMapPattern.MaskSize, + PatternBuffer + NoMatchWolPattern->WoLPattern.WoLBitMapPattern.PatternOffset, + NoMatchWolPattern->WoLPattern.WoLBitMapPattern.PatternSize + ); + + if(Status == NDIS_STATUS_SUCCESS) + { + MBB_ACQUIRE_PORT_LOCK(Port); + Port->HasNoMatchWolPattern = TRUE; + MBB_RELEASE_PORT_LOCK(Port); + } + + +Cleanup: + + if(PatternBuffer) + { + FREE_POOL(PatternBuffer); + PatternBuffer = NULL; + } + + if(Status == NDIS_STATUS_SUCCESS) + { + TraceInfo( WMBCLASS_OID, "[Util] Successfully added a no-match filter to adapter powerfilter table for connected port %lu", PortNumber); + } + else + { + TraceError( WMBCLASS_OID, "[Util] Failed to add no-match filter to adapter powerfilter table for connected port %lu. Status = %!status!", PortNumber, Status); + } + + return Status; +} + + +_Requires_lock_not_held_(&Port->Lock) +NTSTATUS +MbbUtilRemoveNoMatchFilter( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_PORT Port + ) +{ + // Clear all the no-match patterns for this port number, if any if this is a valid + // pattern. Doing this will free up the slots in the adapter filter table + // as it doesnt make sense to have a No-match WOL pattern and + // a valid WOL pattern set for a session Id. + + NTSTATUS Status = STATUS_SUCCESS; + BOOLEAN fHasNoMatchWolPattern = FALSE; + NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; + + if(!Port ) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + MBB_ACQUIRE_PORT_LOCK(Port); + PortNumber = Port->PortNumber; + fHasNoMatchWolPattern = Port->HasNoMatchWolPattern; + MBB_RELEASE_PORT_LOCK(Port); + + if(fHasNoMatchWolPattern) + { + Status = MbbUtilSetPowerFilterPattern( + Adapter, + PortNumber, + MBB_NO_MATCH_WOL_PATTERN_ID, + NULL, + 0, + NULL, + 0 + ); + + if(NT_SUCCESS(Status)) + { + MBB_ACQUIRE_PORT_LOCK(Port); + Port->HasNoMatchWolPattern = FALSE; + MBB_RELEASE_PORT_LOCK(Port); + + TraceInfo( WMBCLASS_OID, "[Util] Successfully cleared the no-match WOL pattern for connected port %lu from the adapter power filter table", PortNumber); + } + } + + Cleanup: + + if(!NT_SUCCESS(Status)) + { + TraceError( WMBCLASS_OID, "[Util] Failed to clear the no-match WOL pattern for connected port %lu from the adapter power filter table. Status = %!status!", PortNumber, Status); + } + + return Status; +} + +VOID +MbbUtilClearPowerFilterAtIndex( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in ULONG Index + ) +{ + Adapter->PowerFilterTable[Index].InUse=FALSE; + Adapter->PowerFilterTable[Index].PortNumber = MBB_INVALID_PORT_NUMBER; + Adapter->PowerFilterTable[Index].PatternId=0; + + if(Adapter->PowerFilterTable[Index].Mask != NULL) + { + FREE_POOL(Adapter->PowerFilterTable[Index].Mask); + Adapter->PowerFilterTable[Index].Mask=NULL; + } + + if(Adapter->PowerFilterTable[Index].Pattern !=NULL) + { + FREE_POOL(Adapter->PowerFilterTable[Index].Pattern); + Adapter->PowerFilterTable[Index].Pattern=NULL; + } +} + + +NTSTATUS +MbbUtilSetPowerFilterPattern( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in NDIS_PORT_NUMBER PortNumber, + __in ULONG PatternId, + __in_bcount_opt(MaskSize) PCUCHAR Mask, + __in ULONG MaskSize, + __in_bcount_opt(PatternSize) PCUCHAR Pattern, + __in ULONG PatternSize + ) +{ + ULONG i=0; + ULONG Index=0; + ULONG j=0; + ULONG k=0; + ULONG NcmPatternSize=0; + NTSTATUS Status=STATUS_SUCCESS; + PUCHAR NcmPattern=NULL; + PUCHAR NcmMask=NULL; + UCHAR LastMaskByte; + + if (MaskSize > 0xffff) + { + // + // NCM only has a ushort for mask count + // + Status= STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + if (MaskSize == 0) + { + // + // this means the caller wants to clear and existing mask + // + + for (i=0; iBusParams.PowerFiltersSupported; i++) + { + if (Adapter->PowerFilterTable[i].InUse + && (Adapter->PowerFilterTable[i].PatternId == PatternId) + && Adapter->PowerFilterTable[i].PortNumber == PortNumber) // same pattern may be plumbed for multiple port numbers + { + break; + } + } + + if (i < Adapter->BusParams.PowerFiltersSupported) + { + MbbUtilClearPowerFilterAtIndex(Adapter, i); + } + else + { + // + // mask not found + // + TraceError( WMBCLASS_OID, "[Util] power filter id not found =%d", PatternId ); + + Status= STATUS_INVALID_PARAMETER; + + ASSERT(0); + + goto Cleanup; + } + } + else + { + // Get the next available slot in adapter power filter table + for (i = 0; i < Adapter->BusParams.PowerFiltersSupported; i++) + { + if (!Adapter->PowerFilterTable[i].InUse) + { + break; + } + } + + if (i == Adapter->BusParams.PowerFiltersSupported) + { + // this means all the slots in the adapter power filter table + // are used and we cannot plumb any more wake patterns + + TraceError( WMBCLASS_OID, "[Util] max wake patterns already plumbed. Returning"); + + Status= STATUS_INVALID_PARAMETER; + + goto Cleanup; + } + + + NcmMask=ALLOCATE_NONPAGED_POOL(PatternSize); + + if (NcmMask == NULL) + { + TraceError( WMBCLASS_OID, "[Util] MbbUtilSetPowerFilterPattern failed to allocate memory for NcmMask"); + + Status=STATUS_NO_MEMORY; + + goto Cleanup; + } + + RtlZeroMemory(NcmMask, PatternSize); + + + NcmPattern=ALLOCATE_NONPAGED_POOL(PatternSize); + + if (NcmPattern == NULL) + { + TraceError( WMBCLASS_OID, "[Util] MbbUtilSetPowerFilterPattern failed to allocate memory for NcmPattern"); + + Status=STATUS_NO_MEMORY; + + goto Cleanup; + } + + // + // translate the mask bit to mask bytes + // + for (k=0; kPowerFilterTable[i].InUse = TRUE; + Adapter->PowerFilterTable[i].PortNumber = PortNumber; + Adapter->PowerFilterTable[i].PatternId = PatternId; + Adapter->PowerFilterTable[i].MaskSize = PatternSize; + + Adapter->PowerFilterTable[i].Mask=NcmMask; + NcmMask=NULL; + + Adapter->PowerFilterTable[i].Pattern=NcmPattern; + NcmPattern=NULL; + } + +Cleanup: + + if (NcmMask != NULL) + { + FREE_POOL(NcmMask); + NcmMask=NULL; + } + + if (NcmPattern != NULL) + { + FREE_POOL(NcmPattern); + NcmPattern=NULL; + } + + return Status; +} + +NDIS_STATUS +MbbUtilWwanToMbbSetPacketFilter( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN Set, + __in NDIS_PORT_NUMBER PortNumber, + __out PMBB_PACKET_FILTERS *ReturnedMbbPacketFilters, + __out ULONG *ReturnedBufferSize + ) +{ + PUCHAR Buffer; + ULONG CurrentOffset; + ULONG LocalOffset; + ULONG BufferSize; + PMBB_PACKET_FILTERS MbbPacketFilters=NULL; + PMBB_SINGLE_PACKET_FILTER MbbSinglePacketFilter=NULL; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + ULONG FiltersInUse=0; + ULONG i=0; + ULONG CurrentFilter=0; + PMBB_PORT Port = NULL; + ULONG SessionId = MBB_INVALID_SESSION_ID; + + *ReturnedBufferSize=0; + *ReturnedMbbPacketFilters=NULL; + + BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_PACKET_FILTERS, ArrayElement), ALIGN_DWORD); + + do + { + // Check if the port number corresponds to an active session + // Find the port corresponding to the port number + Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); + + if(!Port) + { + TraceError( WMBCLASS_POWER, "MbbUtilWwanToMbbSetPacketFilter: Invalid port number %lu", PortNumber); + Status = NDIS_STATUS_INVALID_PORT; + break; + } + + MBB_ACQUIRE_PORT_LOCK(Port); + + if( Port->ConnectionState.ConnectionUp) + { + SessionId = Port->SessionId; + TraceInfo( WMBCLASS_POWER, "MbbUtilWwanToMbbSetPacketFilter: Read the port session id as %d",SessionId); + } + else + { + Status = NDIS_STATUS_INVALID_PARAMETER; + TraceError( WMBCLASS_POWER, "MbbUtilWwanToMbbSetPacketFilter: Port %lu is not connected", PortNumber); + MBB_RELEASE_PORT_LOCK(Port); + break; + } + + MBB_RELEASE_PORT_LOCK(Port); + + if(SessionId == MBB_INVALID_SESSION_ID) + { + Status = NDIS_STATUS_INVALID_PARAMETER; + TraceError( WMBCLASS_POWER, "MbbUtilWwanToMbbSetPacketFilter: Invalid session Id %d", SessionId); + break; + } + + if (Set) + { + for (i=0; iBusParams.PowerFiltersSupported; i++) + { + if (Adapter->PowerFilterTable[i].InUse + && PortNumber == Adapter->PowerFilterTable[i].PortNumber) + { + FiltersInUse++; + + // + // array elemet header + // + BufferSize += ROUND_UP_COUNT(sizeof(MBB_SINGLE_PACKET_FILTER), ALIGN_DWORD); + + BufferSize += ROUND_UP_COUNT(FIELD_OFFSET(MBB_SINGLE_PACKET_FILTER,DataBuffer), ALIGN_DWORD); + + BufferSize += ROUND_UP_COUNT(Adapter->PowerFilterTable[i].MaskSize, ALIGN_DWORD); + BufferSize += ROUND_UP_COUNT(Adapter->PowerFilterTable[i].MaskSize, ALIGN_DWORD); + } + } + } + + + MbbPacketFilters = ALLOCATE_NONPAGED_POOL( BufferSize ); + + if ( MbbPacketFilters == NULL ) + { + Status = NDIS_STATUS_RESOURCES; + break; + } + + Buffer=(PUCHAR)MbbPacketFilters; + + MbbPacketFilters->SessionId = SessionId; + MbbPacketFilters->PacketFiltersCount=FiltersInUse; + + // + // start the current offset after the array elements + // + CurrentOffset = FIELD_OFFSET( MBB_PACKET_FILTERS, ArrayElement ) + (sizeof(MbbPacketFilters->ArrayElement[0]) * FiltersInUse); + + if (FiltersInUse > 0) + { + for (i=0; iBusParams.PowerFiltersSupported; i++) + { + if (Adapter->PowerFilterTable[i].InUse + && PortNumber == Adapter->PowerFilterTable[i].PortNumber) + { + MbbPacketFilters->ArrayElement[CurrentFilter].Offset=CurrentOffset; + + MbbSinglePacketFilter=(PMBB_SINGLE_PACKET_FILTER)&Buffer[CurrentOffset]; + + LocalOffset=FIELD_OFFSET( MBB_SINGLE_PACKET_FILTER, DataBuffer ); + + + MbbSinglePacketFilter->FilterSize=Adapter->PowerFilterTable[i].MaskSize; + MbbSinglePacketFilter->PacketFilterOffset=LocalOffset; + + RtlCopyMemory(&Buffer[CurrentOffset+LocalOffset],Adapter->PowerFilterTable[i].Pattern, Adapter->PowerFilterTable[i].MaskSize); + + LocalOffset += ROUND_UP_COUNT(Adapter->PowerFilterTable[i].MaskSize, ALIGN_DWORD); + + MbbSinglePacketFilter->PacketMaskOffset=LocalOffset; + + RtlCopyMemory(&Buffer[CurrentOffset+LocalOffset],Adapter->PowerFilterTable[i].Mask, Adapter->PowerFilterTable[i].MaskSize); + + LocalOffset += ROUND_UP_COUNT(Adapter->PowerFilterTable[i].MaskSize, ALIGN_DWORD); + + CurrentOffset+=LocalOffset; + + MbbPacketFilters->ArrayElement[CurrentFilter].Size=LocalOffset; + + CurrentFilter++; + + } + } + } + + *ReturnedBufferSize=BufferSize; + *ReturnedMbbPacketFilters=MbbPacketFilters; + }while(FALSE); + + if(Status != NDIS_STATUS_SUCCESS) + { + if(MbbPacketFilters != NULL) + { + FREE_POOL(MbbPacketFilters); + MbbPacketFilters = NULL; + } + } + + if(Port) + { + // Remove the reference added during find + Dereference(Port); + } + + return Status; +} + +WWAN_STATUS +MbbUtilNdisToWwanStatus( + __in NDIS_STATUS NdisStatus + ) +{ + switch( NdisStatus ) + { + case NDIS_STATUS_SUCCESS: + return WWAN_STATUS_SUCCESS; + case NDIS_STATUS_PENDING: + return WWAN_STATUS_SUCCESS; + default: + return WWAN_STATUS_FAILURE; + } +} + +VOID +MbbUtilNdisMiniportIndicateStatusEx( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PNDIS_STATUS_INDICATION StatusIndication + ) +{ + MbbWriteEvent( + &NDIS_STATUS_INDICATION_EVENT, + NULL, + NULL, + 5, + &Adapter->TraceInstance, + sizeof(Adapter->TraceInstance), + &StatusIndication->StatusCode, + sizeof(StatusIndication->StatusCode), + &StatusIndication->RequestId, + sizeof(StatusIndication->RequestId), + &StatusIndication->DestinationHandle, + sizeof(StatusIndication->DestinationHandle), + &StatusIndication->StatusBufferSize, + sizeof(StatusIndication->StatusBufferSize) + ); + + NdisMIndicateStatusEx( + Adapter->MiniportAdapterHandle, + StatusIndication + ); + + return; +} + + +NDIS_STATUS +MbbUtilWwanToMbbGetVisible( + __in PWWAN_GET_VISIBLE_PROVIDERS WwanVisibleProviders, + __out PMBB_GET_VISIBLE_PROVIDERS MbbVisibleProviders + ) +{ + MbbVisibleProviders->Action = WwanVisibleProviders->Action; + + if( MbbVisibleProviders->Action >= MbbVisibleProvidersActionMax ) + return NDIS_STATUS_INVALID_DATA; + else + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +MbbUtilWwanAssignMacAddress( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ NDIS_WWAN_MAC_ADDRESS macAddress + ) +{ + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + BOOLEAN found = FALSE; + ULONG addressId = 1; + ULONG i = 0; + UCHAR macAddress0; + ULONG maxActivatedContexts = 0; + + /* + * Define the scheme that we select MAC address. + * The very first MAC will just use the MAC address from the EEPROM. + * For the rest we set the U/L bit (bit 1) in MAC address and iterate till + * we find a unique MAC address. + */ + MbbAdapterPortsLock(Adapter); + maxActivatedContexts = Adapter->MaxActivatedContexts; + MbbAdapterPortsUnlock(Adapter); + + for(addressId = 1; addressId < maxActivatedContexts; addressId++) + { + found = FALSE; + + macAddress0 = (UCHAR)(((addressId)<<2)|0x02); + + // check if this unique. Since we only altering the first byte of the + // mac address we need to compare with only first byte of the mac + // address of the ports + + MbbAdapterPortsLock(Adapter); + + for(i = 0; i < Adapter->NumberOfPorts; i++) + { + if(NdisEqualMemory(&(Adapter->PortList[i]->MACAddress[0]),&macAddress0,sizeof(UCHAR))) + { + found = TRUE; + break; + } + } + + MbbAdapterPortsUnlock(Adapter); + + if(!found) + { + macAddress[0] = macAddress0; + Status = NDIS_STATUS_SUCCESS; + break; + } + } + + + return Status; +} + +NDIS_STATUS +MbbUtilProcessSetConnectState( + __in PMBB_REQUEST_CONTEXT Request, + __in PWWAN_SET_CONTEXT_STATE SetContextState, + __in ULONG SessionId + ) +{ + ULONG MbbSetContextStateSize; + ULONG AccessStringCchLength; + ULONG UserNameCchLength; + ULONG PasswordCchLength; + SIZE_T StringCchLength; + NDIS_STATUS NdisStatus; + PMBB_CONTEXT_STATE MbbContextState; + PMBB_SET_CONTEXT_STATE MbbSetContextState; + + do + { + if(!SetContextState) + { + NdisStatus = NDIS_STATUS_FAILURE; + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbUtilProcessSetConnectState: SetContextState is NULL parameter",Request->RequestId); + break; + } + + // + // Determine the length of the strings + // + NdisStatus = RtlStringCchLengthW( + SetContextState->AccessString, + WWAN_ACCESSSTRING_LEN, + &StringCchLength + ); + if( NT_ERROR( NdisStatus ) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to get strlen for AccessString, Status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + AccessStringCchLength = (ULONG)StringCchLength; + + NdisStatus = RtlStringCchLengthW( + SetContextState->UserName, + WWAN_USERNAME_LEN, + &StringCchLength + ); + if( NT_ERROR( NdisStatus ) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to get strlen for UserName, Status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + UserNameCchLength = (ULONG)StringCchLength; + + NdisStatus = RtlStringCchLengthW( + SetContextState->Password, + WWAN_PASSWORD_LEN, + &StringCchLength + ); + if( NT_ERROR( NdisStatus ) ) + { + TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to get strlen for Password, Status=%!STATUS!", + Request->RequestId, + NdisStatus + ); + break; + } + PasswordCchLength = (ULONG)StringCchLength; + + MbbSetContextStateSize = FIELD_OFFSET(MBB_SET_CONTEXT_STATE, DataBuffer); + MbbSetContextStateSize = ROUND_UP_COUNT( MbbSetContextStateSize, ALIGN_DWORD ); + MbbSetContextStateSize += MIN(AccessStringCchLength,MBB_MAXIMUM_ACCESS_STRING_LENGTH) * sizeof(WCHAR); + MbbSetContextStateSize = ROUND_UP_COUNT( MbbSetContextStateSize, ALIGN_DWORD ); + MbbSetContextStateSize += MIN(UserNameCchLength,MBB_MAXIMUM_USERNAME_LENGTH) * sizeof(WCHAR); + MbbSetContextStateSize = ROUND_UP_COUNT( MbbSetContextStateSize, ALIGN_DWORD ); + MbbSetContextStateSize += MIN(PasswordCchLength,MBB_MAXIMUM_PASSWORD_LENGTH) * sizeof(WCHAR); + + if( (MbbSetContextState = (PMBB_SET_CONTEXT_STATE) ALLOCATE_NONPAGED_POOL( MbbSetContextStateSize )) == NULL ) + { + NdisStatus = NDIS_STATUS_RESOURCES; + break; + } + Request->HandlerContext.DataToFreeOnCompletion = MbbSetContextState; + + MbbUtilWwanToMbbSetContextState( + SetContextState, + AccessStringCchLength, + UserNameCchLength, + PasswordCchLength, + MbbSetContextStateSize, + SessionId, + MbbSetContextState + ); + + NdisStatus = MbbUtilSetAttributeWithParameter( + Request, + (PCHAR) MbbSetContextState, + MbbSetContextStateSize + ); + }while(FALSE); + + return NdisStatus; +} + + +NDIS_STATUS +MbbUtilWwanCreateMac( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PMINIPORT_ADAPTER_CONTEXT Adapter= (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); + PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; + PMBB_PORT NewPort = NULL; + PNDIS_WWAN_MAC_INFO NdisWwanMacInfo = NULL; + + do + { + OidRequest->DATA.METHOD_INFORMATION.BytesWritten = 0; + OidRequest->DATA.METHOD_INFORMATION.BytesRead = 0; + OidRequest->DATA.METHOD_INFORMATION.BytesNeeded = 0; + + Status = MbbWwanAllocatePort(Adapter, TRUE, &NewPort); + + if (Status != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID,"Failed to allocate a new port\n"); + break; + } + + // Add it to the adapter list + MbbWwanAddPortToAdapterList(Adapter,&NewPort); + + // Done creating the new virtual adapter + + NdisWwanMacInfo = (PNDIS_WWAN_MAC_INFO)OidRequest->DATA.METHOD_INFORMATION.InformationBuffer; + NdisWwanMacInfo->uNdisPortNumber = NewPort->PortNumber; + + NdisMoveMemory(NdisWwanMacInfo->MacAddr, Adapter->MACAddress, sizeof(NDIS_WWAN_MAC_ADDRESS)); + + // Adjust the mac address + Status = MbbUtilWwanAssignMacAddress(Adapter, NdisWwanMacInfo->MacAddr); + + if(Status != NDIS_STATUS_SUCCESS) + { + TraceError(WMBCLASS_OID,"Failed to assign a MAC address to the port with port number %lu\n",NewPort->PortNumber); + break; + } + + //Copy the adjusted MAC address to the port + NdisMoveMemory(NewPort->MACAddress, NdisWwanMacInfo->MacAddr, sizeof(NDIS_WWAN_MAC_ADDRESS)); + + OidRequest->DATA.METHOD_INFORMATION.BytesWritten = sizeof(NDIS_WWAN_MAC_INFO); + + // Save the port context in the Request handlercontext so that we can access it + // in the completion routine + + // Add a reference to the port which will be removed in the completion routine + Reference(NewPort); + Request->HandlerContext.Parameters.NdisPortContext.Port = NewPort; + + TraceInfo(WMBCLASS_OID,"Created a new Port \n"); + } while (FALSE); + + return Status; +} + +NDIS_STATUS +MbbUtilWwanCreateMacComplete( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port, + _In_ NDIS_STATUS NdisStatus + ) +{ + NDIS_STATUS Status = NdisStatus; + NDIS_PORT_NUMBER PortNumber; + + if(Port != NULL) + { + if (Status == NDIS_STATUS_SUCCESS) + { + // + // We can now activate the port. We cannot do this while + // we are processing the OID as the OS would deadlock. + // + + + // If this port has been allocated with NDIS, activate it. This notification + // goes upto the OS and it would handle the request + Status = MbbWwanActivatePort(Adapter, Port); + ASSERT(Status == NDIS_STATUS_SUCCESS); + } + else + { + MBB_ACQUIRE_PORT_LOCK(Port); + PortNumber = Port->PortNumber; + MBB_RELEASE_PORT_LOCK(Port); + + if (IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + // If port is not getting activated, remove it from the adapter port list + // and deallocate it so that it can get freed + + if (MbbWwanRemovePortFromAdapterList(Adapter, Port)) + { + MbbWwanDeallocatePort(Port); + } + else + { + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Port(0x%p) with port number %lu was already removed", Port, Port->PortNumber); + } + } + } + } + + return Status; +} + +NDIS_STATUS +MbbUtilWwanDeleteMac( + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PMINIPORT_ADAPTER_CONTEXT Adapter= (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); + PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; + PNDIS_WWAN_MAC_INFO NdisWwanMacInfo = NULL; + PMBB_PORT DestinationPort = NULL; + NDIS_PORT_NUMBER PortNumber; + + do + { + NdisWwanMacInfo = (PNDIS_WWAN_MAC_INFO)OidRequest->DATA.SET_INFORMATION.InformationBuffer; + PortNumber = NdisWwanMacInfo->uNdisPortNumber; + + // + // First we would need to translate from the NDIS_PORT_NUMBER + // to our port structure. This is done by walking the PortList + // Since OID calls are serialized, we do not expect the Portlist to change + // while we are trying to find the port or for the port to get deleted + // until this OID is completed. So we do not need to protect the Port/PortList + // in any way + // + + DestinationPort = MbbWwanTranslatePortNumberToPort( + Adapter, + PortNumber + ); + + if (DestinationPort == NULL) + { + TraceError(WMBCLASS_OID, "Unable to find Port corresponding to PortNumber %d\n", NdisWwanMacInfo->uNdisPortNumber); + Status = NDIS_STATUS_INVALID_PORT; + break; + } + + if (!IS_ALLOCATED_PORT_NUMBER(PortNumber)) + { + // This port has been allocate with NDIS. When we are done, delete the + // port + TraceError(WMBCLASS_OID, "Invalid port number specified %lu\n", NdisWwanMacInfo->uNdisPortNumber); + Status = NDIS_STATUS_INVALID_PORT; + break; + } + + // remove it from the adapter list + if (MbbWwanRemovePortFromAdapterList(Adapter, DestinationPort)) + { + + //Done deleting the mac state + OidRequest->DATA.SET_INFORMATION.BytesRead = sizeof(NDIS_WWAN_MAC_INFO); + + // Save the port number in the Request handlercontext so that we can access it + // in the completion routine + + // Add a reference to the port which will be removed in the completion routine + Reference(DestinationPort); + Request->HandlerContext.Parameters.NdisPortContext.Port = DestinationPort; + + TraceInfo(WMBCLASS_OID, "Removed the port %lu from adapter", NdisWwanMacInfo->uNdisPortNumber); + } + else + { + Status = NDIS_STATUS_INVALID_PORT_STATE; + TraceInfo(WMBCLASS_INIT, "%!FUNC!: Port(0x%p) was already removed", DestinationPort); + } + } while (FALSE); + + + // Remove the reference which got added in converting port number to port + if(DestinationPort != NULL) + { + Dereference(DestinationPort); + } + + return Status; +} + +NDIS_STATUS +MbbUtilWwanDeleteMacComplete( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port, + _In_ NDIS_STATUS NdisStatus + ) +{ + NDIS_STATUS Status = NdisStatus; + NDIS_PORT_NUMBER PortNumber; + + if(Port != NULL) + { + if (Status == NDIS_STATUS_SUCCESS) + { + // Check if the port has an activated context associated with it. + Status = MbbUtilDisconnectPortOnDeleteMac(Adapter,Port); + if(Status != NDIS_STATUS_SUCCESS) + { + + TraceError( WMBCLASS_OID, "[MbbAdapter]MbbUtilDisconnectPortOnDeleteMac FAILED to deactivate context. Status=%!status!",Status); + } + + // + // We can now deactivate the port. We cannot do this while we are processing + // the OID, else the OS would deadlock. + // + Status = MbbWwanDeactivatePort(Adapter, Port); + ASSERT(Status == NDIS_STATUS_SUCCESS); + + // Deallocate the port that the NDIS port can be freed + // and the port can be cleaned up. + + MbbWwanDeallocatePort(Port); + } + } + + return Status; +} + +NDIS_STATUS +MbbUtilDisconnectPortOnDeleteMac( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port + ) +{ + ULONG SessionId = MBB_INVALID_SESSION_ID; + ULONG MaxActivatedContexts = 0; + BOOLEAN DeactivateContext = FALSE; + PMBB_REQUEST_CONTEXT Request = NULL; + PMBB_REQUEST_MANAGER RequestManager = NULL; + LARGE_INTEGER Timeout; + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + + SessionId = MbbWwanGetPortSessionId(Port); + + MbbAdapterPortsLock(Adapter); + MaxActivatedContexts = Adapter->MaxActivatedContexts; + MbbAdapterPortsUnlock(Adapter); + + // No need of taking port lock as port is already + // removed from adapter port list + + if(SessionId <= MBB_DEFAULT_SESSION_ID + || SessionId >= MaxActivatedContexts) + { + // Return success here as this will be the case when + // deactivate context is done before port is torn down + return NDIS_STATUS_SUCCESS; + } + + MbbAdapterSessionIdPortTableLock(Adapter); + + if(Adapter->SessionIdPortTable[SessionId].InUse + && Adapter->SessionIdPortTable[SessionId].PortNumber == Port->PortNumber) + { + //means port has an active context associated with it + DeactivateContext = TRUE; + } + + MbbAdapterSessionIdPortTableUnlock(Adapter); + + if(DeactivateContext) + { + MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_CONNECT }; + + do + { + if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbAdapter] FAILED to reference RequestManager for deactivate context" ); + NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; + break; + } + + if( (Request = MbbReqMgrCreateRequest( + RequestManager, + NULL, + 0, + &NdisStatus)) == NULL ) + { + TraceError( WMBCLASS_OID, "[MbbAdapter] FAILED to allocate RequestContext for deactivate context" ); + break; + } + + Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); + + Request->HandlerContext.Parameters.ContextSessionId.SessionId = SessionId; + + NdisStatus = MbbReqMgrDispatchRequest( + Request, + TRUE, // Serialized + MbbUtilDeactivateContext, + MbbUtilInternalCIDCompletion, + MbbUtilInternalCIDResponse + ); + + if( NdisStatus != NDIS_STATUS_PENDING ) + { + MbbReqMgrDestroyRequest( + Request->RequestManager, + Request + ); + } + }while(FALSE); + } + + if( RequestManager != NULL ) + { + MbbReqMgrDeref( RequestManager ); + } + + return NdisStatus; +} + +NDIS_STATUS +MbbUtilDeactivateContext( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ) +{ + NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; + MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_CONNECT }; + PWWAN_SET_CONTEXT_STATE WwanSetContextState = ALLOCATE_NONPAGED_POOL(sizeof(WWAN_SET_CONTEXT_STATE)); + + if(!WwanSetContextState) + { + TraceError( WMBCLASS_OID, "[MbbAdapter] MbbUtilDeactivateContext: FAILED to allocate WWAN_SET_CONTEXT_STATE" ); + return NDIS_STATUS_RESOURCES; + } + + NdisZeroMemory(WwanSetContextState, sizeof(*WwanSetContextState)); + + WwanSetContextState->ActivationCommand = WwanActivationCommandDeactivate; + + NdisStatus = MbbUtilProcessSetConnectState( + Request, + WwanSetContextState, + Request->HandlerContext.Parameters.ContextSessionId.SessionId); + + if(WwanSetContextState) + { + FREE_POOL(WwanSetContextState); + WwanSetContextState = NULL; + } + + return NdisStatus; +} + diff --git a/network/wwan/cxwmbclass/util.h b/network/wwan/cxwmbclass/util.h new file mode 100644 index 000000000..9c9cb7afc --- /dev/null +++ b/network/wwan/cxwmbclass/util.h @@ -0,0 +1,1263 @@ +/*************************************************************************** + +Copyright (c) 2010 Microsoft Corporation + +Module Name: + + Util.h + +Abstract: + + This file contains the message definitions for helper functions. + All data conversion from MBB structures to WWAN structures and + vice versa is present in Util.c. + + Note the MbbUtilXxx routines do not perform length validation + as they require the caller to perform validation and allocate + sufficient memory. + +Environment: + + kernel mode only + +Notes: + + +Revision History: + + 3/2/2010 : TriRoy : Added MbbUtilXxx routines + +Authors: + + BrianL + TriRoy + +****************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Infrastructure for testability. +// Flags can be added to conditionally simulate test situations. +// MbbGlobalTestFlags can be set from the debugger to trigger conditions. +// +//typedef enum +//{ +// MbbTestFlagNone = 0x00000000, +// MbbTestFlagSimulateQueryDeviceServiceDispatchFailure = 0x00000001, +// MbbTestFlagSimulateQueryDeviceServiceTimeout = 0x00000002, +// MbbTestFlagSimulateInvalidResponseBufferSize = 0x00000004 +// +//} MBB_TEST_FLAG; +// +//extern volatile ULONG MbbGlobalTestFlags; + +typedef union +{ + ULONG Value; + struct + { + ULONG NoPostAllocation:1; + }; + +} MBB_ALLOC_FLAGS; + +typedef __callback +VOID +(*MBB_WORKITEM_ROUTINE)( + __in PVOID Context1, + __in PVOID Context2, + __in PVOID Context3, + __in PVOID Context4 + ); + +typedef enum +{ + MbbPoolTagDefault = '0CBM', + MbbPoolTagNtbSend = '1CBM', + MbbPoolTagNblSend = '2CBM', + MbbPoolTagNbSend = '3CBM', + MbbPoolTagNtbReceive = '4CBM', + MbbPoolTagNblReceive = '5CBM', + MbbPoolTagMdlReceive = '6CBM', + MbbPoolTagNbPool = '7CBM', + MbbPoolTagNblPool = '8CBM', + MbbPoolTagTimer = '9CBM', + MbbPoolTagRequest = 'rCBM', + MbbPoolTagPort = 'pCBM', + MbbPoolTagNblFastIOContext = 'cOIF' +} MBB_POOL_TAG; + +#define ALLOCATE_PAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_PAGED, _y, MbbPoolTagDefault) +#define ALLOCATE_NONPAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_NON_PAGED, _y, MbbPoolTagDefault) +#define ALLOCATE_NONPAGED_POOL_WITH_TAG(_x, _y) ExAllocatePool2(POOL_FLAG_NON_PAGED, _x, _y) + +#define FREE_POOL(_x) {ExFreePool(_x);_x=NULL;}; + +#define ALLOCATE_LOOKASIDE(LOOKASIDELIST) NdisAllocateFromNPagedLookasideList( LOOKASIDELIST ) +#define FREE_LOOKASIDE(MEMORY,LOOKASIDELIST) { NdisFreeToNPagedLookasideList( (LOOKASIDELIST), (MEMORY) ); (MEMORY) = NULL; }; + +#define MIN( _X_, _Y_ ) (((_X_) < (_Y_))? (_X_): (_Y_)) +#define MAX( _X_, _Y_ ) (((_X_) > (_Y_))? (_X_): (_Y_)) + +#define ALIGN_FLOOR( _VALUE_, _ALIGN_ ) ((SIZE_T)(_VALUE_) - (((SIZE_T)(_VALUE_))%((SIZE_T)(_ALIGN_)))) +#define ALIGN_CIELING( _VALUE_, _ALIGN_ ) ALIGN_FLOOR( _VALUE_, _ALIGN_ ) + ((SIZE_T)(_ALIGN_)) +#define ALIGN( _VALUE_, _ALIGN_ ) ALIGN_CIELING( _VALUE_, _ALIGN_ ) +#define ALIGN_AT_OFFSET( _VALUE_, _ALIGN_, _OFFSET_ ) (((SIZE_T)(_VALUE_) <= (ALIGN_FLOOR(_VALUE_,_ALIGN_)+(_OFFSET_)))? (ALIGN_FLOOR(_VALUE_,_ALIGN_)+(_OFFSET_)): (ALIGN(_VALUE_,_ALIGN_)+(_OFFSET_))) + +#define MBB_BAD_POINTER ((PVOID)0x5A5A5A5A) + +#define MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION( NSI, MINIPORTADAPTERHANDLE, STATUS ) \ +{ \ + (NSI)->Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; \ + (NSI)->Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; \ + (NSI)->Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; \ + (NSI)->SourceHandle = (MINIPORTADAPTERHANDLE); \ + (NSI)->PortNumber = 0; \ + (NSI)->StatusCode = (STATUS); \ + (NSI)->Flags = 0; \ + (NSI)->DestinationHandle = NULL; \ + (NSI)->RequestId = 0; \ + RtlZeroMemory( &(NSI)->Guid, sizeof((NSI)->Guid) ); \ +} + +#define MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( NSI, REQ, STATUS ) \ +{ \ + MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION(NSI, (REQ)->RequestManager->AdapterContext->MiniportAdapterHandle, STATUS) \ + (NSI)->DestinationHandle = (REQ)->OidContext.OidRequestHandle; \ + (NSI)->RequestId = (REQ)->OidContext.OidRequestId; \ +} + +#define MbbUtilPopulateStaticString(_StaticString, _ContainingStruct, _MbbString) \ +{ \ + ASSERT(sizeof(_StaticString) > _ContainingStruct->_MbbString.Size); \ + \ + RtlZeroMemory( \ + &_StaticString[0], \ + sizeof(_StaticString) \ + ); \ + \ + RtlCopyMemory( \ + &_StaticString[0], \ + ((PUCHAR)_ContainingStruct) + _ContainingStruct->_MbbString.Offset, \ + _ContainingStruct->_MbbString.Size \ + ); \ +} + +#define MBB_INIT_MBB_STRING(_X_) \ +{ \ + (_X_)->Size = 0; \ + (_X_)->Offset = 0; \ +} + + +#define MBB_INVALID_SESSION_ID -1 +#define MBB_INVALID_PORT_NUMBER -1 + +#define MBB_NO_MATCH_WOL_PATTERN_ID 0 +#define MBB_NO_MATCH_WOL_PATTERN_SIZE 8 // 8 bytes - 0x00000000 + + +//////////////////////////////////////////////////////////////////////////////// +// +// DECLARATIONS +// +//////////////////////////////////////////////////////////////////////////////// +PCSTR +GetOidName( + __in NDIS_OID Oid + ); + +BOOLEAN +IsSameGuid(GUID * pgGuid1, GUID *pgGuid2); + +BOOLEAN +IsZeroGuid( + __in GUID* pGuid + ); + +NDIS_STATUS +GetDeviceFriendlyName( + __in NDIS_HANDLE MiniportAdapterHandle, + __out PANSI_STRING AnsiName + ); + +VOID +FreeAdapterBlock( + _In_ __drv_freesMem(Mem) PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +PCHAR +MbbUtilGetCommandString( + __in PMBB_COMMAND Command + ); + +BOOLEAN +MbbUtilIsBasicCommand( + __in PMBB_COMMAND Command + ); + +BOOLEAN +MbbUtilIsValidDeviceService( + __in GUID* DeviceServiceGuid + ); + +NDIS_STATUS +MbbUtilSendMessageFragmentsAndLog( + __in PMBB_REQUEST_CONTEXT Request + ); + +NDIS_STATUS +MbbUtilSendMessageFragments( + __in PMBB_REQUEST_CONTEXT Request + ); + +NDIS_STATUS +MbbUtilSetupCommandMessage( + __in PMBB_REQUEST_CONTEXT Request, + __in PMBB_COMMAND Command, + __in MBB_COMMAND_TYPE CommandType, + __in_bcount_opt(InputBufferLength) PUCHAR InputBuffer, + __in ULONG InputBufferLength + ); + +NDIS_STATUS +MbbUtilInternalCIDQuery( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ); + +VOID +MbbUtilInternalCIDCompletion( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); + +VOID +MbbUtilInternalCIDResponse( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +VOID +MbbUtilCommonCIDResponse( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize, + __in_opt PMBB_OID_HANDLER_ENTRY OidHandler + ); + +NDIS_STATUS +MbbUtilQueryAttribute( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +NDIS_STATUS +MbbUtilQueryAttributeWithParameter( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(GetRequestParametersSize) PUCHAR GetRequestParameters, + __in ULONG GetRequestParametersSize + ); + +NDIS_STATUS +MbbUtilSetAttributeWithParameter( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(SetParametersSize) PUCHAR SetParameters, + __in ULONG SetParametersSize + ); + +NDIS_STATUS +MbbUtilDeviceServiceCommand( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbUtilUiccAccessBinary( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +NDIS_STATUS +MbbUtilUiccAccessRecord( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +PCSTR +MbbUtilGetWwanIndicationString( + __in NDIS_STATUS Indication + ); + +// +// Allocator +// + +__drv_allocatesMem(Mem) +__drv_aliasesMem +PVOID +MbbAllocMgrInitialize( + __in ULONG AllocationSize, + __in ULONG AllocationCount, + __in ULONG PoolTag, + __in MBB_ALLOC_FLAGS Flags + ); + +VOID +MbbAllocMgrCleanup( + __in __drv_freesMem(Mem) PVOID AllocMgrHandle + ); + +PVOID +MbbAllocMgrAllocate( + __in PVOID AllocMgrHandle + ); + +VOID +MbbAllocMgrFree( + __in PVOID AllocHandle + ); + +// +// Buffer Manager +// + +__drv_allocatesMem(Mem) +__drv_aliasesMem +PVOID +MbbBufMgrInitialize( + __in ULONG BufferCount, + __in ULONG BufferLength + ); + +VOID +MbbBufMgrCleanup( + __in __drv_freesMem(Mem) PVOID ManagerHandle + ); + +// +// Work Item +// + +__drv_allocatesMem(Mem) +__drv_aliasesMem +PVOID +MbbWorkMgrInitialize( + __in ULONG InitialWorkItemCount + ); + +VOID +MbbWorkMgrCleanup( + __in __drv_freesMem(Mem) PVOID WorkItemManagerHandle + ); + +NDIS_STATUS +MbbWorkMgrQueueWorkItem( + __in PVOID WorkItemManagerHandle, + __in_opt PVOID Context1, + __in_opt PVOID Context2, + __in_opt PVOID Context3, + __in_opt PVOID Context4, + __in MBB_WORKITEM_ROUTINE Routine + ); + +// +// Wwan to Mbb +// + + +VOID +MbbUtilWwanToMbbRadioState( + __in WWAN_RADIO* WwanRadio, + __out MBB_RADIO_STATE* MbbRadioState + ); + +NTSTATUS +MbbUtilWwanToMbbPinAction( + __in PWWAN_PIN_ACTION WwanPinAction, + __out PMBB_PIN_ACTION * MbbPinActionOut, + __out PULONG ReturnedBufferSize + ); + +NTSTATUS +MbbUtilWwanToMbbPinActionEx2( + __in PWWAN_PIN_ACTION_EX2 WwanPinAction, + __out PMBB_PIN_ACTION_EX2 *MbbPinActionOut, + __out PULONG ReturnedBufferSize + ); + +ULONG +MbbUtilWwanToMbbProvider( + __in PWWAN_PROVIDER WwanProvider, + __in MBB_CELLULAR_CLASS MbbCellularClass, + __in ULONG Rssi, + __in ULONG ErrorRate, + __in ULONG MbbProviderSize, + __out_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider + ); + +ULONG +MbbUtilWwanToMbbProvider2( + __in PWWAN_PROVIDER2 WwanProvider2, + __in ULONG MbbProviderSize, + __out_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider + ); + +NDIS_STATUS +MbbUtilWwanToMbbProviderList( + __in PWWAN_LIST_HEADER WwanProviderList, + __in BOOLEAN IsMultiCarrierCapable, + __in_opt MBB_CELLULAR_CLASS MbbCellularClass, + __out_bcount(*MbbProviderListSize) PMBB_PROVIDER_LIST MbbProviderList, + __inout PULONG MbbProviderListSize + ); + +NTSTATUS +MbbUtilWwanToMbbSetRegisterState( + __in PWWAN_SET_REGISTER_STATE WwanSetRegisterState, + __out PMBB_SET_REGISTER_STATE *MbbSetRegisterStateOut, + __out PULONG ReturnedBufferSize + ); + + +NDIS_STATUS +MbbUtilWwanToMbbSetPacketService( + __in WWAN_PACKET_SERVICE_ACTION PacketServiceAction, + __out PMBB_SET_PACKET_SERVICE MbbSetPacketService + ); + +VOID +MbbUtilAdjustSignalStateConfigurationForDevice( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __inout PWWAN_SET_SIGNAL_INDICATION WwanSetSignalIndication + ); + +VOID +MbbUtilWwanToMbbSetSignalStateIndication( + __in PWWAN_SET_SIGNAL_INDICATION WwanSetSignalIndication, + __out PMBB_SET_SIGNAL_INDICATION MbbSetSignalStateIndication + ); + +VOID +MbbUtilWwanToMbbSetContextState( + __in PWWAN_SET_CONTEXT_STATE WwanSetContextState, + __in ULONG AccessStringCchLength, + __in ULONG UserNameCchLength, + __in ULONG PasswordCchLength, + __in ULONG MbbSetContextStateSize, + __in ULONG SessionId, + __out PMBB_SET_CONTEXT_STATE MbbSetContextState + ); + +NTSTATUS +MbbUtilWwanToMbbSetLteAttachContext( + __in PWWAN_SET_LTE_ATTACH WwanSetContextBuffer, + __out PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG *ReturnedMbbSetContext, + __out ULONG *ReturnedBufferSize + ); + +VOID +MbbUtilMbbToWwanLteAttachConfigInfo( + __in MBB_MS_LTE_ATTACH_CONFIG_INFO* MbbLteAttachContextList, + __out PWWAN_LTE_ATTACH_CONFIG WwanLteAttachContext + ); + +VOID +MbbUtilMbbToWwanLteAttachContext( + __in PMBB_MS_LTE_ATTACH_CONTEXT MbbLteAttachContext, + __out WWAN_CONTEXT_V2* WwanLteAttachContext + ); + +VOID +MbbUtilMbbToWwanLteAttachStatus( + __in MBB_MS_LTE_ATTACH_STATUS* MbbLteAttachStatus, + __out PWWAN_LTE_ATTACH_STATUS WwanLteAttachStatus + ); + +NTSTATUS +MbbUtilWwanToMbbSetContext( + __in PWWAN_SET_CONTEXT WwanSetContext, + __out PMBB_SET_CONTEXT *ReturnedMbbSetContext, + __out ULONG *ReturnedBufferSize + ); + +NTSTATUS +MbbUtilWwanToMbbSetContextV2( + __in PWWAN_SET_PROVISIONED_CONTEXT_V2 WwanSetContext, + __out PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 *ReturnedMbbSetContext, + __out ULONG *ReturnedBufferSize +); + +NTSTATUS +MbbUtilWwanToMbbSmsSetConfiguration( + __in PWWAN_SET_SMS_CONFIGURATION WwanSmsSetConfiguration, + __in ULONG ScAddressSize, + __out PMBB_SET_SMS_CONFIGURATION *MbbSmsSetConfigurationReturn, + __out PULONG ReturnedBufferSize + ); + + +VOID +MbbUtilWwanToMbbSmsRead( + __in PWWAN_SMS_READ WwanSmsRead, + __out PMBB_SMS_READ MbbSmsRead + ); +#if 0 +NDIS_STATUS +MbbUtilWwanToMbbSmsSend( + __in PWWAN_SMS_SEND WwanSmsSend, + __in MBB_CELLULAR_CLASS CellularClass, + __out_bcount(MbbSmsSendSize) PMBB_SMS_SEND MbbSmsSend, + __in ULONG MbbSmsSendSize + ); +#endif + +MBB_SMS_FORMAT +MbbUtilWwanToMbbSmsFormat( + __in WWAN_SMS_FORMAT WwanSmsFormat + ); + + +NDIS_STATUS +MbbUtilWwanToMbbSmsSendPdu( + __in PWWAN_SMS_SEND_PDU WwanSmsSendPdu, + __in MBB_CELLULAR_CLASS CellularClass, + __out PMBB_SMS_SEND *ReturnedMbbSmsSend, + __out PULONG MbbSmsSendSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbSmsSendCdma( + __in PWWAN_SMS_SEND_CDMA WwanSmsSendCdma, + __out PMBB_SMS_SEND *ReturnedMbbSmsSend, + __out PULONG MbbSmsSendSize + ); + + + +VOID +MbbUtilWwanToMbbSmsDelete( + __in PWWAN_SMS_FILTER WwanSmsFilter, + __out PMBB_SMS_DELETE MbbSmsDelete + ); + +NDIS_STATUS +MbbUtilWwanToMbbSubscribeEvents( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in_ecount(GuidCount) GUID* GuidList, + __in ULONG GuidCount, + __in BOOL ExternalRequest, + __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, + __in ULONG ExtSubscribeListSize, + __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, + __out PULONG OutputSubscribeBufferSize + ); + +NDIS_STATUS +MbbUtilGenerateSubscribeEventList( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN FullPower, + __in ULONG MediaSpecificWakeUpEvents, + __in ULONG WakeUpFlags, + __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, + __in ULONG ExtSubscribeListSize, + __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, + __out PULONG OutputSubscribeListSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbAkapAuthChallenge( + __in PWWAN_AUTH_AKAP_CHALLENGE WwanAuthAkapChallenge, + __in ULONG UTF16ByteCount, + __in ULONG MbbSize, + __out_bcount(MbbSize) PMBB_AKAP_AUTH_CHALLENGE MbbAkapAuthChallenge + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetPacketFilter( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in BOOLEAN Set, + __in NDIS_PORT_NUMBER PortNumber, + __out PMBB_PACKET_FILTERS *ReturnedMbbPacketFilters, + __out ULONG *ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbUiccFilePath( + __in PWWAN_UICC_FILE_PATH WwanUiccFilePath, + __deref_out PMBB_UICC_FILE_PATH *MbbUiccFilePathOut, + __out PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbUiccAccessBinary( + __in PWWAN_UICC_ACCESS_BINARY WwanUiccAccessBinary, + __deref_out_opt PMBB_UICC_ACCESS_BINARY *MbbUiccAccessBinaryOut, + __out PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbUiccAccessRecord( + __in PWWAN_UICC_ACCESS_RECORD WwanUiccAccessRecord, + __deref_out_opt PMBB_UICC_ACCESS_RECORD *MbbUiccAccessRecordOut, + __out PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbPinApp( + __in PWWAN_PIN_APP WwanPinApp, + __deref_out PMBB_PIN_APP *MbbPinAppOut, + __out PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetDeviceSlotMappingInfo( + __in PWWAN_DEVICE_SLOT_MAPPING_INFO WwanDeviceSlotMappingInfo, + __deref_out_opt PMBB_MS_DEVICE_SLOT_MAPPING_INFO *MbbDeviceSlotMappingInfoOut, + __out PULONG ReturnedBufferSize + ); + +ULONG +MbbUtilWwanListToMbbList( + __in PWWAN_LIST_HEADER WwanListHeader, + __in ULONG WwanListElementSize, + __inout PUCHAR MbbBuffer, + __in ULONG CurrentOffsetInMbbBuffer, + __inout PMBB_ARRAY_ELEMENT MbbArray + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetDeviceBindingsInfo( + __in PWWAN_DEVICE_BINDINGS_INFO WwanSetDeviceBindingsInfo, + __deref_out PMBB_DEVICE_BINDINGS_INFO *MbbSetDeviceBindingsInfoOut, + __out PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetRegisterStateEx( + __in PWWAN_SET_REGISTER_STATE_EX WwanSetRegisterStateEx, + __deref_out PMBB_SET_REGISTER_STATE_V2 *MbbSetRegisterStateV2Out, + __out PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetUiccOpenChannel( + __in PWWAN_SET_UICC_OPEN_CHANNEL WwanSetUiccOpenChannel, + __deref_out PMBB_SET_UICC_OPEN_CHANNEL *MbbSetUiccOpenChannelOut, + __out PULONG ReturnedBufferSize + ); + +VOID +MbbUtilWwanToMbbSetUiccCloseChannel( + __in PWWAN_SET_UICC_CLOSE_CHANNEL WwanSetUiccCloseChannel, + __out PMBB_SET_UICC_CLOSE_CHANNEL MbbSetUiccCloseChannel + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetUiccApdu( + __in PWWAN_SET_UICC_APDU WwanSetUiccApdu, + __deref_out PMBB_SET_UICC_APDU *MbbSetUiccApduOut, + __out PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetUiccTerminalCapability( + __in PWWAN_LIST_HEADER WwanCapabilityListHeader, + __deref_out PMBB_SET_UICC_TERMINAL_CAPABILITY *MbbSetUiccTerminalCapabilityOut, + __out PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetSarConfig( + _In_ PWWAN_SET_SAR_CONFIG WwanSetSarConfig, + _Outptr_ PMBB_SET_SAR_CONFIG *MbbSetSarConfigOut, + _Out_ PULONG ReturnedBufferSize + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetNetworkBlacklist( + _In_ PWWAN_NETWORK_BLACKLIST_INFO SetNetworkBlacklist, + _Outptr_ PMBB_MS_NETWORK_BLACKLIST_INFO *MbbNetworkBlacklistOut, + _Out_ PULONG ReturnedBufferSize + ); + +// +// Mbb to Wwan +// + +WWAN_STATUS +MbbUtilMbbToWwanStatus( + __in MBB_STATUS MbbStatus + ); + +VOID +MbbUtilMbbToWwanDeviceCaps( + __in PMBB_DEVICE_CAPS MbbDeviceCaps, + __in_ecount(ManufacturerStrLen) PWCHAR ManufacturerString, + __in ULONG ManufacturerStrLen, + __in_ecount(ModelStrLen) PWCHAR ModelString, + __in ULONG ModelStrLen, + __out PWWAN_DEVICE_CAPS WwanDeviceCaps, + __in BOOL fMultimode + ); + +VOID +MbbUtilMbbToWwanDeviceCapsV2( + __in PMBB_MS_DEVICE_CAPS_INFO_V2 MbbDeviceCaps, + __in_ecount(ManufacturerStrLen) PWCHAR ManufacturerString, + __in ULONG ManufacturerStrLen, + __in_ecount(ModelStrLen) PWCHAR ModelString, + __in ULONG ModelStrLen, + __out PWWAN_DEVICE_CAPS_EX WwanDeviceCaps, + __in BOOL fMultimode +); + +VOID +MbbUtilMbbToWwanRadioState( + __in MBB_RADIO_STATE* MbbRadioState, + __out WWAN_RADIO* WwanRadio + ); + +VOID +MbbUtilMbbToWwanReadyInfo( + __in PMBB_SUBSCRIBER_READY_INFO MbbReadyInfo, + __in PWWAN_READY_INFO WwanReadyInfo + ); + +VOID +MbbUtilMbbToWwanPinInfo( + __in PMBB_PIN_INFO MbbPinInfo, + __out PWWAN_PIN_INFO WwanPinInfo + ); + +VOID +MbbUtilMbbToWwanPinList( + __in PMBB_PIN_LIST MbbPinList, + __out PWWAN_PIN_LIST WwanPinList + ); + +VOID +MbbUtilMbbToWwanProvider( + __in PMBB_PROVIDER MbbProvider, + __in ULONG MbbDataClass, + __out PWWAN_PROVIDER WwanProvider + ); + +VOID +MbbUtilMbbToWwanProvider2( + __in PMBB_PROVIDER MbbProvider, + __in ULONG MbbDataClass, + __out PWWAN_PROVIDER2 WwanProvider2 + ); + +VOID +MbbUtilMbbToWwanProviderList( + __in PMBB_PROVIDER_LIST MbbProviderList, + __in ULONG MbbDataClass, + __in BOOLEAN IsMultiCarrier, + __out PWWAN_LIST_HEADER WwanProviderList + ); + +VOID +MbbUtilMbbToWwanRegistrationState( + __in PMBB_REGISTRATION_STATE MbbRegistrationState, + __out PWWAN_REGISTRATION_STATE WwanRegistrationState + ); + +VOID +MbbUtilMbbToWwanPacketService( + __in PMBB_PACKET_SERVICE MbbPacketService, + __out PWWAN_PACKET_SERVICE WwanPacketService + ); + +VOID +MbbUtilMbbToWwanSignalState( + __in PMBB_SIGNAL_STATE MbbSignalState, + __out PWWAN_SIGNAL_STATE WwanSignalState + ); + +VOID +MbbUtilMbbToWwanContextState( + __in PMBB_CONTEXT_STATE MbbContextState, + __in ULONG ConnectId, + __out PWWAN_CONTEXT_STATE WwanContextState + ); + +NDIS_STATUS +MbbUtilPopulateWwanIPAddressState( + __in PMBB_IP_ADDRESS_INFO IPAddressInfo, + __in PMBB_IPADDRESS_ENTRY IpTable, + __in PMBB_IPADDRESS_ENTRY GatewayTable, + __in PMBB_IPADDRESS_ENTRY DnsTable, + __in ULONG IpCount, + __in ULONG GatewayCount, + __in ULONG DnsCount, + __out PWWAN_IP_ADDRESS_STATE pWwanIPAddressState + ); + +VOID +MbbUtilMbbToWwanContext( + __in PMBB_CONTEXT MbbContext, + __out PWWAN_CONTEXT WwanContext + ); + +VOID +MbbUtilMbbToWwanContextList( + __in PMBB_CONTEXT_LIST MbbContextList, + __out PWWAN_LIST_HEADER WwanContextList + ); + +VOID +MbbUtilMbbToWwanContextV2( + __in PMBB_MS_CONTEXT_V2 MbbContext, + __out PWWAN_CONTEXT_V2 WwanContext + ); + +VOID +MbbUtilMbbToWwanContextV2List( + __in PMBB_CONTEXT_LIST MbbContextList, + __out PWWAN_LIST_HEADER WwanContextList + ); + +VOID +MbbUtilMbbToWwanServiceActivationStatus( + __in PMBB_SERVICE_ACTIVATION_STATUS MbbServiceActivationStatus, + __in ULONG VendorSpecificBufferSize, + __out PWWAN_SERVICE_ACTIVATION_STATUS WwanServiceActivationStatus + ); + +VOID +MbbUtilMbbToWwanSmsConfiguration( + __in PMBB_SMS_CONFIGURATION MbbSmsConfiguration, + __out PWWAN_SMS_CONFIGURATION WwanSmsConfiguration + ); + +NDIS_STATUS +MbbUtilValidateMbbSmsPduRecord( + __in MBB_CELLULAR_CLASS CellularClass, + __in ULONG MbbSmsPduRecordSize, + __in_bcount(MbbSmsPduRecordSize) PMBB_SMS_PDU_RECORD MbbSmsPduRecord + ); + +NDIS_STATUS +MbbUtilValidateMbbSmsCdmaRecord( + __in ULONG MbbSmsCdmaRecordSize, + __in_bcount(MbbSmsCdmaRecordSize) PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord + ); + +NDIS_STATUS +MbbUtilValidateMbbSmsReceive( + __in MBB_CELLULAR_CLASS CellularClass, + __in ULONG MbbSmsReceiveSize, + __in_bcount(MbbSmsReceiveSize) PMBB_SMS_RECEIVE MbbSmsReceive + ); + +VOID +MbbUtilMbbToWwanSmsPduRecord( + __in PMBB_SMS_PDU_RECORD MbbSmsPduRecord, + __in MBB_CELLULAR_CLASS CellularClass, + __out PWWAN_SMS_PDU_RECORD WwanSmsPduRecord + ); + +VOID +MbbUtilMbbToWwanSmsCdmaRecord( + __in PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord, + __out PWWAN_SMS_CDMA_RECORD WwanSmsCdmaRecord + ); + +NDIS_STATUS +MbbUtilMbbToWwanSmsReceive( + __in_bcount(MbbSmsReceiveSize) PMBB_SMS_RECEIVE MbbSmsReceive, + __in ULONG MbbSmsReceiveSize, + __in MBB_CELLULAR_CLASS CellularClass, + __out PWWAN_LIST_HEADER SmsListHeader + ); + +VOID +MbbUtilMbbToWwanSmsStatus( + __in PMBB_SMS_STATUS MbbSmsStatus, + __out PWWAN_SMS_STATUS WwanSmsStatus + ); + +VOID +MbbUtilMbbToWwanUiccAppList( + __in PMBB_UICC_APP_LIST MbbUiccAppList, + __out PWWAN_UICC_APP_LIST WwanUiccAppList + ); + +VOID +MbbUtilMbbToWwanUiccFileStatus( + __in PMBB_UICC_FILE_STATUS MbbUiccFileStatus, + __out PWWAN_UICC_FILE_STATUS WwanUiccFileStatus + ); + +VOID +MbbUtilMbbToWwanUiccResponse( + __in PMBB_UICC_RESPONSE MbbUiccResponse, + __out PWWAN_UICC_RESPONSE WwanUiccResponse + ); + +VOID +MbbUtilMbbToWwanSysCapsInfo( + __in PMBB_MS_SYS_CAPS_INFO MbbSysCapsInfo, + __out PWWAN_SYS_CAPS_INFO WwanSysCapsInfo + ); + +VOID +MbbUtilMbbToWwanDeviceSlotMappingInfo( + __in PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbDeviceSlotMappingInfo, + __out PWWAN_DEVICE_SLOT_MAPPING_INFO WwanDeviceSlotMappingInfo + ); + +VOID +MbbUtilMbbToWwanSlotInfo( + __in PMBB_MS_SLOT_INFO MbbSlotInfo, + __out PWWAN_SLOT_INFO WwanSlotInfo + ); + +VOID +MbbUtilMbbToWwanDeviceBindingsInfo( + __in PMBB_DEVICE_BINDINGS_INFO MbbDeviceBindingsInfo, + __out PWWAN_DEVICE_BINDINGS_INFO WwanDeviceBindingsInfo + ); + +VOID +MbbUtilMbbToWwanRegistrationStateInfoV2( + __in PMBB_REGISTRATION_STATE_INFOS_V2 MbbRegistrationStateInfosV2, + __out PWWAN_REGISTRATION_STATE_INFOS WwanRegistrationStateInfos + ); + +VOID +MbbUtilMbbToWwanSignalStateInfoV2( + __in PMBB_SIGNAL_STATE_INFOS_V2 MbbSignalStateInfosV2, + __out PWWAN_SIGNAL_STATE_INFOS WwanSignalStateInfos + ); + +VOID +MbbUtilMbbToWwanAtrInfo( + __in PMBB_ATR_INFO MbbAtrInfo, + __out PWWAN_ATR_INFO WwanAtrInfo + ); + +VOID +MbbUtilMbbToWwanUiccOpenChannelInfo( + __in PMBB_UICC_OPEN_CHANNEL_INFO MbbUiccOpenChannelInfo, + __out PWWAN_UICC_OPEN_CHANNEL_INFO WwanUiccOpenChannelInfo + ); + +VOID +MbbUtilMbbToWwanUiccCloseChannelInfo( + __in PMBB_UICC_CLOSE_CHANNEL_INFO MbbUiccCloseChannelInfo, + __out PWWAN_UICC_CLOSE_CHANNEL_INFO WwanUiccCloseChannelInfo + ); + +VOID +MbbUtilMbbToWwanUiccApduInfo( + __in PMBB_UICC_APDU_INFO MbbUiccApduInfo, + __out PWWAN_UICC_APDU_INFO WwanUiccApduInfo + ); + +VOID +MbbUtilMbbToWwanUiccTerminalCapabilityInfo( + __in PMBB_UICC_TERMINAL_CAPABILITY_INFO MbbUiccTerminalCapabilityInfo, + __out PWWAN_LIST_HEADER WwanCapabilityListHeader + ); + +VOID +MbbUtilMbbToWwanSarConfigInfo( + _In_ PMBB_SAR_CONFIG_INFO MbbSarConfigInfo, + _Out_ PWWAN_SAR_CONFIG_INFO WwanSarConfigInfo + ); + +VOID +MbbUtilMbbToWwanTransmissionStatusInfo( + _In_ PMBB_SAR_TRANSMISSION_STATUS_INFO MbbTransmissionStatusInfo, + _Out_ PWWAN_SAR_TRANSMISSION_STATUS_INFO WwanTransmissionStatusInfo + ); + +// +// Drain Object +// +VOID +InitDrainObject( + PDRAIN_OBJECT DrainObject, + MBB_DRAIN_COMPLETE DrainCompleteCallback, + PVOID Context + ); + +VOID +StartDrain( + PDRAIN_OBJECT DrainObject + ); + +VOID +DrainComplete( + PDRAIN_OBJECT DrainObject + ); + +BOOLEAN +DrainAddRef( + PDRAIN_OBJECT DrainObject + ); + +VOID +DrainRelease( + PDRAIN_OBJECT DrainObject + ); + +NTSTATUS +MbbEventActivityIdCtl ( + _Inout_ LPGUID ActivityId + ); + + +VOID +MbbWriteEvent ( + IN PCEVENT_DESCRIPTOR EventDescriptor, + IN LPGUID ActivityId OPTIONAL, + IN LPGUID RelatedActivityId OPTIONAL, + IN USHORT ArgCount, + ... + ); + +VOID +MbbWriteEventOpn ( + IN PCEVENT_DESCRIPTOR EventDescriptor, + IN LPGUID ActivityId OPTIONAL, + IN LPGUID RelatedActivityId OPTIONAL, + IN USHORT ArgCount, + ... + ); + +VOID +MbbWriteEventCommon ( + IN REGHANDLE TraceHandle, + IN PCEVENT_DESCRIPTOR EventDescriptor, + IN LPGUID ActivityId OPTIONAL, + IN LPGUID RelatedActivityId OPTIONAL, + IN USHORT ArgCount, + IN va_list Arguments + ); + +NDIS_STATUS +MbbUtilWwanToMbbSetUSSD( + __out PMBB_SET_USSD MbbSetUSSD, + __in PWWAN_USSD_REQUEST WWanUSSDRequest + ); + +NDIS_STATUS +MbbUtilMbbToWwanUSSDEvent( + __in PMBB_USSD MbbUSSD, + __out PWWAN_USSD_EVENT WWanUSSDEvt + ); + +VOID +MbbUtilMbbToWwanNetworkBlackList( + __in PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist, + __out PWWAN_LIST_HEADER BlacklistProviderList + ); + +// +// Validation routines +// + +NTSTATUS +MbbIsVariableFieldValid( + ULONG TotalLength, + ULONG Offset, + ULONG Size, + ULONG MaxLength, + ULONG ElementSize + ); + +NTSTATUS +MbbIsArrayFieldValid( + ULONG TotalMessageLength, + ULONG Offset, + ULONG ElementCount, + ULONG ElementSize + ); + + +NDIS_STATUS +MbbUtilValidateMbbProvider( + __in ULONG MbbProviderSize, + __in_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider + ); + +NDIS_STATUS +MbbUtilValidateMbbProviderList( + __in ULONG MbbProviderListSize, + __in_bcount(MbbProviderListSize) PMBB_PROVIDER_LIST MbbProviderList + ); + +ULONG +MbbUtilWriteStringToBuffer( + __in_ecount(BufferSize) PUCHAR Start, + __in ULONG BufferSize, + __in ULONG CurrentOffset, + __in PMBB_STRING StringDesc, + __in_ecount(SourceLength) PCUCHAR SourceString, + __in ULONG SourceLength + ); + +BOOLEAN +MbbUtilIsNativeMbnService( + __in GUID* DeviceServiceGuid + ); + +PMBB_DS +MbbUtilFindDeviceService( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in GUID* DeviceServiceGuid + ); + +// +// Hex string routines +// +NDIS_STATUS +MbbUtilHexStringToUchar( + __in_ecount(2) PCHAR HexString, + __out PUCHAR Value + ); + +NDIS_STATUS +MbbUtilHexStringToByteStream( + __in_bcount_z(HexStringSize) PCHAR HexString, + __in ULONG HexStringSize, + __out_bcount(ByteStreamSize) PUCHAR ByteStream, + __in ULONG ByteStreamSize + ); + +VOID +MbbUtilByteStreamToHexString( + __in_bcount(ByteStreamSize) PUCHAR ByteStream, + __in ULONG ByteStreamSize, + __out_bcount_z(HexStringSize) PCHAR HexString, + __in ULONG HexStringSize + ); + +_Requires_lock_not_held_(&Port->Lock) +NDIS_STATUS +MbbUtilAddNoMatchFilter( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_PORT Port + ); + +_Requires_lock_not_held_(&Port->Lock) +NTSTATUS +MbbUtilRemoveNoMatchFilter( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PMBB_PORT Port + ); + + +VOID +MbbUtilClearPowerFilterAtIndex( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in ULONG Index + ); + +NTSTATUS +MbbUtilSetPowerFilterPattern( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in NDIS_PORT_NUMBER PortNumber, + __in ULONG PatternId, + __in_bcount_opt(MaskSize) PCUCHAR Mask, + __in ULONG MaskSize, + __in_bcount_opt(PatternSize) PCUCHAR Pattern, + __in ULONG PatternSize + ); + +WWAN_STATUS +MbbUtilNdisToWwanStatus( + __in NDIS_STATUS NdisStatus + ); + +VOID +MbbUtilNdisMiniportIndicateStatusEx( + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in PNDIS_STATUS_INDICATION StatusIndication + ); + +VOID +MbbUtilSendMbimError( + __in ULONG TransactionId, + __in MBB_ERROR ErrorCode, + __in PMINIPORT_ADAPTER_CONTEXT Adapter, + __in GUID ActivityId, + __in PMBB_COMMAND Command + ); + +NDIS_STATUS +MbbUtilWwanToMbbGetVisible( + __in PWWAN_GET_VISIBLE_PROVIDERS WwanVisibleProviders, + __out PMBB_GET_VISIBLE_PROVIDERS MbbVisibleProviders + ); + +NDIS_STATUS +MbbUtilWwanCreateMac( + __in PMBB_REQUEST_CONTEXT Request + ); + +NDIS_STATUS +MbbUtilWwanDeleteMac( + __in PMBB_REQUEST_CONTEXT Request + ); + +NDIS_STATUS +MbbUtilWwanAssignMacAddress( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ NDIS_WWAN_MAC_ADDRESS macAddress + + ); + +NDIS_STATUS +MbbUtilProcessSetConnectState( + __in PMBB_REQUEST_CONTEXT Request, + __in PWWAN_SET_CONTEXT_STATE SetContextState, + __in ULONG SessionId + ); + +NDIS_STATUS +MbbUtilWwanCreateMacComplete( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port, + _In_ NDIS_STATUS NdisStatus + ); + +NDIS_STATUS +MbbUtilWwanDeleteMacComplete( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port, + _In_ NDIS_STATUS NdisStatus + ); + +NDIS_STATUS +MbbUtilDisconnectPortOnDeleteMac( + _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, + _In_ PMBB_PORT Port + ); + +NDIS_STATUS +MbbUtilDeactivateContext( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ); diff --git a/network/wwan/cxwmbclass/wmbclass.h b/network/wwan/cxwmbclass/wmbclass.h new file mode 100644 index 000000000..343ee8f53 --- /dev/null +++ b/network/wwan/cxwmbclass/wmbclass.h @@ -0,0 +1,1096 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#define WMBCLASS_INTERFACE_TYPE NdisInterfaceInternal; +#define WMBCLASS_CHECK_FOR_HANG_INTERVAL 3; +#define WMBCLASS_MAX_WOL_PATTERN (256) +#define WMBCLASS_MAX_MBIM_WOL_PATTERN (192) + + +#define MBB_DEFAULT_SESSION_ID 0 + +#define MBB_REGVAL_NETCFGID L"NetCfgInstanceId" +#define MBB_REGVAL_OVERRIDE_NAME L"AllowDriverToOverrideDeviceName" +#define MBB_REGVAL_RADIO_OFF L"RadioOff" +#define MBB_REGVAL_LAST_IPv4 L"LastIPv4" +#define MBB_REGVAL_LAST_IPv6 L"LastIPv6" +#define MBB_REGVAL_LAST_GWv4 L"LastGWv4" +#define MBB_REGVAL_LAST_GWv6 L"LastGWv6" +#define MBB_REGVAL_LAST_DNSv4 L"LastDNSv4" +#define MBB_REGVAL_LAST_DNSv6 L"LastDNSv6" + +#define MBB_LOCK_TAKEN TRUE +#define MBB_LOCK_NOT_TAKEN FALSE + +#define MBB_PSEUDO_IMEI L"002099001761481" +#define MBB_PSEUDO_ESN L"12816777215" + +#define MBB_MAC_ADDRESS_LENGTH 6 + + +#define MBB_MAX_SERVICE_ACTIVATION_BUFFER 0x10000 +#define MBB_MAX_READY_INFO_PHONE_NUMBERS 100 +#define MBB_MAX_PROVIDER_LIST_SIZE 1024 +#define MBB_MAX_PROVISIONED_CONTEXTS 1024 + +#define MBB_STATUS_INDICATION_ALREADY_SENT NDIS_STATUS_NOT_RECOGNIZED + +#define MBB_MAX_NUMBER_OF_PORTS 11 // including the default port + + +//////////////////////////////////////////////////////////////////////////////// +// +// TYPEDEFS +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Forward declaration +// + +typedef struct _MBB_PORT MBB_PORT, *PMBB_PORT; + +typedef struct _MINIPORT_DRIVER_CONTEXT +{ + WDFDRIVER hDriver; + NDIS_HANDLE NdisDriverHandle; + HANDLE IpInterfaceNotificationHandle; + HANDLE IpRouteNotificationHandle; + HANDLE IpUnicastAddressNotificationHandle; + PVOID IpWorkItemManagerHandle; + NDIS_SPIN_LOCK AdapterListLock; + LIST_ENTRY AdapterList; + REGHANDLE TraceHandle; + ULONG CurrentTraceInstance; + REGHANDLE TraceHandleOpn; +} MINIPORT_DRIVER_CONTEXT, +*PMINIPORT_DRIVER_CONTEXT; + +typedef struct _MBB_OID_HANDLER_ENTRY MBB_OID_HANDLER_ENTRY; +typedef struct _MBB_OID_HANDLER_ENTRY* PMBB_OID_HANDLER_ENTRY; + +typedef struct _MBB_REQUEST_CONTEXT MBB_REQUEST_CONTEXT; +typedef struct _MBB_REQUEST_CONTEXT* PMBB_REQUEST_CONTEXT; + +typedef struct _MBB_REQUEST_MANAGER MBB_REQUEST_MANAGER; +typedef struct _MBB_REQUEST_MANAGER* PMBB_REQUEST_MANAGER; + +typedef struct _MINIPORT_ADAPTER_CONTEXT MINIPORT_ADAPTER_CONTEXT; +typedef struct _MINIPORT_ADAPTER_CONTEXT *PMINIPORT_ADAPTER_CONTEXT; + +typedef +__callback VOID +(*MBB_REQUEST_COMPLETION_CALLBACK)( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); + +typedef +__callback NDIS_STATUS +(*MBB_REQUEST_DISPATCH_ROUTINE)( + __in MBB_PROTOCOL_HANDLE AdapterHandle, + __in PMBB_REQUEST_CONTEXT Request + ); + +typedef +__callback VOID +(*MBB_REQUEST_RESPONSE_HANDLER)( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); +/*++ + Description + Callback invoked when the response is ready or was failed to retrieve. + + Parameters + __in PMBB_REQUEST_CONTEXT Request + In case of command response the request context used to send the encapsulated command. + In case of status indication arbitrary request context used to retrieve the status indication. + + __in NDIS_STATUS NdisStatus + Whether retrieving the response was successful. + This is used to distinguish whether the host was unsuccessful in retrieving a reponse or + whether the device completed the response with failure status. + + __in MBB_STATUS MbbStatus + If the host was successful in retrieving the response i.e. NdisStatus is NDIS_STATUS_SUCCESS + then the status that the device returned. + + __in_bcount_opt(InBufferSize) PUCHAR InBuffer + If the host was successful in retrieving the response i.e. NdisStatus is NDIS_STATUS_SUCCESS + and the device responded successfully i.e. MBB_STATUS_SUCCESS( ) then the response buffer. + + __in ULONG InBufferSize + If the host was successful in retrieving the response i.e. NdisStatus is NDIS_STATUS_SUCCESS + and the device responded successfully i.e. MBB_STATUS_SUCCESS( ) then the response buffer length. + + Return Value + None +--*/ + +typedef NDIS_STATUS +(*MBB_OID_SET_HANDLER)( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize + ); + +typedef NDIS_STATUS +(*MBB_OID_QUERY_HANDLER)( + __in PMBB_REQUEST_CONTEXT Request, + __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, + __in PULONG InBufferSize, + __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, + __inout PULONG OutBufferSize + ); + +typedef VOID +(*MBB_OID_COMPLETION_HANDLER)( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus + ); + +typedef NDIS_STATUS +(*MBB_OID_RESPONSE_HANDLER)( + __in PMBB_REQUEST_CONTEXT Request, + __in NDIS_STATUS NdisStatus, + __in MBB_STATUS MbbStatus, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); + +struct _MBB_OID_HANDLER_ENTRY +{ + NDIS_OID Oid; + ULONG IsSettable:1; + ULONG IsQueryable:1; + ULONG IsSerialized:1; + ULONG IsIndicationRequired:1; + ULONG CompleteRequestOnSendComplete:1; + // + // Valid for InBuffers i.e. Sets and Methods + // + UCHAR NdisObjectHeaderType; + UCHAR NdisObjectHeaderRevision; + USHORT NdisObjectHeaderSize; + + MBB_OID_SET_HANDLER SetHandler; + ULONG MinSetInBufferSize; + + MBB_OID_QUERY_HANDLER QueryHandler; + ULONG MinQueryInBufferSize; + ULONG MinQueryOutBufferSize; + // + // Valid, if a Response CID is associated with this OID + // + MBB_COMMAND ResponseCommand; + ULONG ResponseBufferLength; + MBB_OID_RESPONSE_HANDLER ResponseHandler; + // + // Optional completion handler for cleanup on send failure. + // + MBB_OID_COMPLETION_HANDLER CompletionHandler; +}; + +typedef enum +{ + // + // Dispatch the request. Request may be queued behind others. + // + MbbRequestEventDispatch = 0, + // + // Request is current, start processing the request. + // + MbbRequestEventStart, + // + // Request was cancelled + // + MbbRequestEventCancel, + // + // Bus layer indicated (un)succesful sending of all fragments + // + MbbRequestEventSendComplete, + // + // A response matching the TransactionId of the request was received. + // + MbbRequestEventResponseReceived, + // + // Same as MbbRequestStateResponseReceived but with MBB_STATUS_MORE_DATA. + // + MbbRequestEventResponseReceivedMoreData, + // + // + // + MbbRequestEventMaximum + +} MBB_REQUEST_EVENT; + +typedef enum +{ + // + // Initial state, request is created and ready to be dispatched. + // If the request is cancelled in this state the request owner + // is not notified about the cancellation since the request + // is not dispatched yet and does not have a completion routine. + // + MbbRequestStateReady = 0, + // + // Request is queued for dispatch as requests are serialized. + // The request may be started immediately if its the current request + // or may have to wait for other requests to complete. When the request + // is cancelled in this state the completion callback is called with failure. + // + MbbRequestStateDispatching, + // + // Initial state, when not queued. + // Dispatch routine has sent all the fragments to the bus layer + // which is still sending them to the device. + // + MbbRequestStateSendPending, + // + // Bus layer completed sending all fragments to the device. + // The FSM notifies the CompletionCallback. + // + MbbRequestStateSendComplete, + // + // The host received response from the device matching the TransactionId + // of this request. The rquest will be completed to higher layers. + // The FSM notifies the ResponseAvailable callback. + // + MbbRequestStateResponseReceived, + // + // Same as MbbRequestStateResponseReceived but with MBB_STATUS_MORE_DATA. + // More MbbRequestEventResponseReceived or MbbRequestEventResponseReceivedMoreData + // are expected. + // + MbbRequestStateResponseReceivedMoreData, + // + // The request is cancelled. + // The device didnt respond within a defined amount of time. + // The request will complete with failure status. + // The FSM notifies the CompletionCallback / ResponseAvailable callback. + // + MbbRequestStateCancelled, + // + // Catch invalid state transitions. + // + MbbRequestStateInvalid, + // + // + // + MbbRequestStateMaximum + +} MBB_REQUEST_STATE; + +typedef struct +{ + ULONG InUse:1; + ULONG Allocated:1; + +} MBB_EVENT_FLAGS; + +typedef struct _MBB_EVENT_ENTRY +{ + LIST_ENTRY EventLink; + MBB_EVENT_FLAGS EventFlags; + MBB_REQUEST_EVENT Event; + PMBB_REQUEST_CONTEXT Request; + PVOID EventData; + ULONG EventDataLength; + +} MBB_EVENT_ENTRY, +*PMBB_EVENT_ENTRY; + +typedef struct _MBB_REASSEMBLE_CONTEXT +{ + PUCHAR FragmentBuffer; + ULONG FragmentBufferLength; + ULONG FragmentLength; + PUCHAR Buffer; + ULONG BufferLength; + ULONG BufferOffset; + ULONG DataLength; + ULONG TransactionId; + ULONG FragmentCount; + ULONG NextFragment; + NDIS_STATUS NdisStatus; + MBB_STATUS MbbStatus; + MBB_COMMAND Command; + +} MBB_REASSEMBLE_CONTEXT, +*PMBB_REASSEMBLE_CONTEXT; + +typedef +__callback VOID +(*MBB_DRAIN_COMPLETE)( + __in PVOID Context + ); + + +typedef struct _DRAIN_OBJECT { + + NDIS_SPIN_LOCK Lock; + ULONG Count; + BOOL Draining; + BOOL DrainComplete; + + MBB_DRAIN_COMPLETE DrainCompleteCallback; + PVOID Context; + +} DRAIN_OBJECT, *PDRAIN_OBJECT; + +VOID +InitDrainObject( + PDRAIN_OBJECT DrainObject, + MBB_DRAIN_COMPLETE DrainCompleteCallback, + PVOID Context + ); + +VOID +StartDrain( + PDRAIN_OBJECT DrainObject + ); + +VOID +DrainComplete( + PDRAIN_OBJECT DrainObject + ); + +BOOLEAN +DrainAddRef( + PDRAIN_OBJECT DrainObject + ); + +VOID +DrainRelease( + PDRAIN_OBJECT DrainObject + ); + +// +// MBB_NDIS_OID_STATE +// +// Oids have multi-states to correctly complete them +// without race condition between the dispatch thread +// and the completion thread. Note that request manager +// can call a completion routine if the request was +// cancelled or dispatch failed. Thus the oids completion +// handler may be called without the dispatch handler +// ever being called. All the different possibilities or +// states are tracked through the oid state. +// +typedef enum +{ + MbbNdisOidStateNone = 0, + // + // The oid is pending with request manager + // to be dispatched. The oid can get cancelled + // without the Oid Dispatch routine ever being + // called. If the Oid Completion routine runs + // at this state then it should + // + MbbNdisOidStatePending, + // + // Oid Dispatch routine is currently running. + // If the Oid completion routine runs during + // this state then it will defer the oid + // completion to the dispatch handler. + // + MbbNdisOidStateDispatching, + // + // Oid dispatch routine has completed. If the + // Oid completion routine runs after this point + // then it will complete the Oid. + // + MbbNdisOidStateDispatched, + // + // Oid completion routine has run. If the Dispatch + // routine finds this state then it means that the + // Oid completion routine has deferred the Oid + // competion. The Dispatch routine will complete Oid. + // + MbbNdisOidStateComplete, + MbbNdisOidStateMax + +} MBB_NDIS_OID_STATE; + +struct _MBB_REQUEST_CONTEXT +{ + // + // Request Management + // + + LIST_ENTRY ManagerLink; + ULONG RequestId; + ULONG TransactionId; + GUID ActivityId; + + // Controls the lifetime of the request. + // On creation the RefCount is set to 1. + // Destroy drops this initial RefCount. + // When the RefCount drops to zero request is freed. + ULONG ReferenceCount; + // Tracks the request. + // RequestManager->Lock is used to synchronize + // access to the fields of the request. + PMBB_REQUEST_MANAGER RequestManager; + // Event to wait for request to get into desired state - Send Complete, + // Response received + KEVENT WaitEvent; + + PMBB_OID_HANDLER_ENTRY OidHandler; + + // + // State Machine + // + + ULONGLONG DispatchTime; + MBB_REQUEST_STATE State; + MBB_REQUEST_STATE LastState; + MBB_REQUEST_EVENT LastEvent; + + // + // Pre-allocated resources for forward progress. + // + + MBB_EVENT_ENTRY EventEntries[MbbRequestEventMaximum]; + + // + // Per sub-component contexts + // + + // Valid if request was created for ndis oid. + struct + { + PNDIS_OID_REQUEST OidRequest; + PVOID OidRequestId; + NDIS_HANDLE OidRequestHandle; + NDIS_STATUS OidStatus; + BOOLEAN IsSetOid; + // synchronized with interlock + MBB_NDIS_OID_STATE OidState; + + } OidContext; + + struct + { + BOOLEAN IsSerialized; + BOOLEAN IsQueued; + LIST_ENTRY QueueLink; + LIST_ENTRY CancelLink; + LIST_ENTRY TimeoutLink; + MBB_REQUEST_DISPATCH_ROUTINE DispatchRoutine; + MBB_REQUEST_COMPLETION_CALLBACK CompletionCallback; + MBB_REQUEST_RESPONSE_HANDLER ResponseHandler; + + } ReqMgrContext; + + struct + { + PVOID DataToFreeOnCompletion; + PVOID DataToFreeOnResponse; + BOOLEAN IsIndication; + // + // Send Command + // + struct + { + // Static fields + ULONG FragmentLength; + ULONG FragmentCount; + PUCHAR Data; + ULONG DataLength; + MBB_COMMAND Command; + MBB_COMMAND_TYPE CommandType; + // Dynamic fields + BOOLEAN IsProcessing; + ULONG NextFragmentIndex; + ULONG FragmentSentCount; + NDIS_STATUS SendStatus; + + } Command; + // + // Get Response + // + MBB_REASSEMBLE_CONTEXT Response; + // + // Parameters + // + union { + struct { + WCHAR DeviceId[WWAN_DEVICEID_LEN]; + GUID CurrentQueriedDeviceService; + ULONG IsUssdCapsValid:1; + ULONG IsAuthCapsValid:1; + ULONG NdisDeviceCapsSize; + PNDIS_WWAN_DEVICE_CAPS NdisDeviceCaps; + } DeviceCaps; + + struct { + ULONG IsWwanEmergencyModeValid:1; + ULONG IsCdmaShortMsgSizeValid:1; + ULONG IsQueryReadyInfo:1; + ULONG IsFirstCid:1; + ULONG NdisReadyInfoSize; + PNDIS_WWAN_READY_INFO NdisReadyInfo; + WWAN_EMERGENCY_MODE WwanEmergencyMode; + UCHAR CdmaShortMsgSize; + } SubscriberReadyInfo; + + struct { + ULONG IsWwanAvailableDataClassValid:1; + ULONG IsQuery:1; + ULONG IsFirstCid:1; + ULONG NdisPacketServiceStateSize; + PNDIS_WWAN_PACKET_SERVICE_STATE NdisPacketServiceState; + ULONG AvailableDataClass; + } PacketServiceState; + + struct { + BOOLEAN Activate; + ULONG ConnectionId; + ULONG SessionId; + } Connect; + + struct { + MBB_CONNECTION_STATE ConnectionState; + ULONG SessionId; + } IpAddress; + struct { + // The radio state set that was requested + WWAN_RADIO SetAction; + } RadioState; + struct { + // Info about the external request + PMBB_SUBSCRIBE_EVENT_LIST ExtList; // Memory managed via DataToFreeOnResponse + ULONG ExtSize; + } EventSubscribe; + struct { + GUID DeviceServiceGuid; + ULONG SessionId; + MBB_DSS_LINK_STATE LinkState; + } DssSession; + + struct { + // used for sync device services subscription changes + BOOLEAN FullPower; + ULONG MediaSpecificWakeUpEvents; + ULONG WakeUpFlags; + } SyncDeviceServiceSubription; + struct { + BOOLEAN Set; + NDIS_PORT_NUMBER PortNumber; + } SetPacketFilter; + struct { + PMBB_PORT Port; + } NdisPortContext; + struct { + ULONG SessionId; + } ContextSessionId; + } Parameters; + + } HandlerContext; +}; + +typedef enum +{ + MbbTimerTypeRequest = 0, + MbbTimerTypeFragment, + MbbTimerTypeMaximum + +} MBB_TIMER_TYPE; + +typedef struct _MBB_TIMER_CONTEXT +{ + MBB_TIMER_TYPE TimerType; + ULONGLONG TimerArmTime; + NDIS_HANDLE TimerHandle; + ULONG TimerDelayInMS; + ULONG TimerPeriodInMS; + ULONG TimerToleranceInMS; + PNDIS_TIMER_FUNCTION TimerFunction; + PMBB_REQUEST_MANAGER RequestManager; + +} MBB_TIMER_CONTEXT, +*PMBB_TIMER_CONTEXT; + +typedef struct _MBB_REQUEST_MANAGER +{ + PMINIPORT_ADAPTER_CONTEXT AdapterContext; + LIST_ENTRY AllocatedRequestList; + LIST_ENTRY PendingRequestQueue; + MBB_TIMER_CONTEXT TimerContexts[MbbTimerTypeMaximum]; + PMBB_REQUEST_CONTEXT CurrentRequest; + NDIS_SPIN_LOCK Spinlock; + KEVENT NoAllocatedRequestEvent; + ULONG RequestIdCounter; + DRAIN_OBJECT DrainObject; + KEVENT DrainCompleteEvent; + // + // Pre-allocated resources for fragmentation & reassembly + // + struct + { + ULONG ControlFragmentLength; + ULONG BulkFragmentLength; + PVOID BufferManager; + BOOLEAN ReassembleInUse; + MBB_REASSEMBLE_CONTEXT Reassemble; + + } Fragmentation; + // + // Work Item + // + PVOID WorkItemManagerHandle; + // + // Request allocator + // + PVOID RequestAllocatorHandle; + // BOOLEAN to indicate whether the Request Manager is currently closed and Draining all the + // outstanding requests in the Queue. Used in the Surprise Removal Path + BOOLEAN IsClosed; + +} MBB_REQUEST_MANAGER, +*PMBB_REQUEST_MANAGER; + +typedef enum +{ + MbbDataPathTelmetryStatusNotReport = 0, + MbbDataPathTelmetryStatusReportSuccess, + MbbDataPathTelmetryStatusReportHang +} MBB_DATA_PATH_TELMETRY_STATUS; + +typedef struct _MBB_SEND_QUEUE +{ + // + // Queue state + // + NDIS_SPIN_LOCK Lock; + BOOLEAN ProcessingQueue; + DRAIN_OBJECT QueueDrainObject; + // + // Lookaside lists + // + NPAGED_LOOKASIDE_LIST NblLookasideList; + NPAGED_LOOKASIDE_LIST NtbLookasideList; + NPAGED_LOOKASIDE_LIST NbLookasideList; + // + // Track NTBs + // + ULONG ConcurrentSends; + ULONG MaxConcurrentSends; + LIST_ENTRY NtbQueue; + ULONG NtbSequence; + // + // Track NBLs + // + LIST_ENTRY NblTrackList; + LIST_ENTRY NblDispatchQueue; + KEVENT NblQueueEmptyEvent; + // + // Handles + // + PMINIPORT_ADAPTER_CONTEXT AdapterContext; + MBB_BUS_HANDLE BusHandle; + PCHAR PaddingBuffer; + +#if DBG + // + // Testing + // + PCHAR ScratchBuffer; + ULONG ScratchLength; +#endif + + // + // NBL pool for DSS + // + NDIS_HANDLE NblPool; + MBB_DATA_PATH_TELMETRY_STATUS LastDataPathTelemetryStatus; + +} MBB_SEND_QUEUE, +*PMBB_SEND_QUEUE; + +typedef struct _MBB_RECEIVE_QUEUE +{ + // + // Queue State + // + BOOLEAN LookasideList; + NDIS_SPIN_LOCK Lock; + KEVENT QueueEmptyEvent; + DRAIN_OBJECT QueueDrainObject; + // + // Track Receives + // + LIST_ENTRY ReceivedQueue; + // + // Resources + // + NDIS_HANDLE NblPool; + NPAGED_LOOKASIDE_LIST ReceiveLookasideList; + +} MBB_RECEIVE_QUEUE, +*PMBB_RECEIVE_QUEUE; + +typedef enum _STATE_CHANGE_TYPE { + + STATE_CHANGE_TYPE_PAUSE = 0, + STATE_CHANGE_TYPE_RESTART = 1, + STATE_CHANGE_TYPE_POWER = 2, + STATE_CHANGE_TYPE_RESET = 3, + STATE_CHANGE_TYPE_STALL_CLEAR = 4, + STATE_CHANGE_MAX =5 + +} STATE_CHANGE_TYPE, *PSTATE_CHANGE_TYPE; + +#define STATE_CHANGE_EVENT_RESERVE_COUNT (10) + +typedef struct _STATE_CHANGE_EVENT { + + LIST_ENTRY ListEntry; + STATE_CHANGE_TYPE EventType; + PVOID Context1; + PVOID Context2; + + union { + struct { + PMBB_REQUEST_CONTEXT Request; + NET_DEVICE_POWER_STATE NewPower; + } Power; + struct { + NTSTATUS PipeStartStatus; + } Reset; + }; + +} STATE_CHANGE_EVENT, *PSTATE_CHANGE_EVENT; + +typedef +__callback VOID +(*MBB_STATE_CHANGE_HANDLER)( + PSTATE_CHANGE_EVENT StateChange + ); + + + +typedef struct _ADAPTER_STATE { + + BOOLEAN ShuttingDown; + + BOOLEAN Started; + + NET_DEVICE_POWER_STATE CurrentPowerState; + + BOOLEAN Hung; + + PSTATE_CHANGE_EVENT RunningEvent; + + ULONG PendingActions; + + NDIS_SPIN_LOCK Lock; + NDIS_HANDLE WorkItem; + LIST_ENTRY ListEntry; + PSTATE_CHANGE_EVENT CurrentEvent; + + LIST_ENTRY FreeList; + + MBB_STATE_CHANGE_HANDLER Handlers[STATE_CHANGE_MAX]; + + KEVENT StallClearCompleteEvent; + +} ADAPTER_STATE, *PADAPTER_STATE; + +// Per-device service state +typedef struct _MBB_DS +{ + // Device service ID (from device) + GUID DeviceServiceId; + + // DSS state (from device) + WWAN_DEVICE_SERVICE_SESSION_CAPABILITY DSSCapability; + ULONG MaxDSSInstances; + + // Number of CIDs supported (from device) + ULONG CIDCount; + + // Pointer to the CID list (from device) + PULONG CIDList; + + +} MBB_DS, *PMBB_DS; + +// The state for all device services +typedef struct _MBB_DS_STATE +{ + // Number of supported services (from device) + ULONG ServicesCount; + + // Pointer to list of device services (from device) + PMBB_DS ServicesList; + + // Maximum number of DSS sessions (from device) + ULONG MaxDSSSessions; + + // Subscribe OID settings + ULONG ExtSubscribeListBufferSize; + PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList; + +} MBB_DS_STATE, *PMBB_DS_STATE; + +typedef union +{ + ULONG Value; + struct + { + ULONG IsMultiCarrier:1; + ULONG IsUssdCapable:1; + ULONG IsSimAuthCapable:1; + ULONG IsAkaAuthCapable:1; + ULONG IsAkapAuthCapable:1; + ULONG IsShowIMSI:1; + ULONG ShutdownNotificationCapable:1; + ULONG IsPreshutdownCapable:1; + ULONG IsProvisionedContextV2Capable : 1; + ULONG IsNetworkBlacklistCapable : 1; + ULONG IsSARCapable : 1; + ULONG IsLTEAttachConfigCapable : 1; + ULONG IsMultiSIMCapable : 1; + ULONG IsUiccLowLevelCapable : 1; + ULONG IsDeviceCapsV2Capable : 1; + ULONG IsPcoCapable : 1; + ULONG IsDeviceResetCapable : 1; + ULONG IsBaseStationsInfoCapable : 1; + }; +} ADAPTER_FLAGS; + +typedef struct _POWER_FILTER_LOOKUP { + + ULONG PatternId; + BOOLEAN InUse; + ULONG MaskSize; + PUCHAR Mask; + PUCHAR Pattern; + NDIS_PORT_NUMBER PortNumber; +} POWER_FILTER_LOOKUP, *PPOWER_FILTER_LOOKUP; + +typedef struct _SESSIONID_PORTNUMBER_ENTRY +{ + // Indicates whether the session Id is in use or not + BOOLEAN InUse; + + // Valid only when InUse is set. Corresponds + // to the NDIS PORT number for this session + NDIS_PORT_NUMBER PortNumber; + +} SESSIONID_PORTNUMBER_ENTRY, *PSESSIONID_PORTNUMBER_ENTRY; + + +typedef struct _MINIPORT_ADAPTER_CONTEXT +{ + // + // NDIS information + // + NDIS_SPIN_LOCK Lock; + ULONG Reference; + NDIS_HANDLE MiniportAdapterHandle; + ULONG TraceInstance; + + NET_IFINDEX IfIndex; + NET_LUID NetLuid; + BOOLEAN OverrideDeviceName; + GUID NetCfgId; + LIST_ENTRY DriverLink; + UCHAR MACAddress[MBB_MAC_ADDRESS_LENGTH]; + // + // Bus information + // + PDEVICE_OBJECT Pdo; + PDEVICE_OBJECT Fdo; + PDEVICE_OBJECT NextDeviceObject; + ANSI_STRING FriendlyName; + MBB_BUS_HANDLE BusHandle; + MBB_BUS_PARAMETERS BusParams; + // + // Adapter State + // + ADAPTER_STATE AdapterState; + // + // Request processing + // + MBB_SEND_QUEUE SendQueue; + MBB_RECEIVE_QUEUE ReceiveQueue; + MBB_REQUEST_MANAGER RequestManagerAllocation; + PMBB_REQUEST_MANAGER RequestManager; + // + // Stats + // + ULONG64 MaxLinkSpeed; + ULONG64 CurrentLinkSpeed; + + ULONGLONG UplinkSpeed; + ULONGLONG DownlinkSpeed; + + ULONGLONG GenXmitFramesOk; + ULONGLONG GenRcvFramesOk; + NDIS_STATISTICS_INFO Stats; + + // Radio state: TRUE = OFF, FALSE = ON + BOOLEAN RadioOff; + + BOOLEAN AvailableDataClassValid; + ULONG AvailableDataClass; + ULONG AdapterDataClass; + ADAPTER_FLAGS AdapterFlags; + // Used for multi-mode adapters + MBB_CELLULAR_CLASS AdapterSupportedCellularClass; + MBB_CELLULAR_CLASS AdapterCurrentCellularClass; + + PPOWER_FILTER_LOOKUP PowerFilterTable; + + NDIS_MINIPORT_SYSPOWER_NOTIFY LastLowSystemPowerState; + + // + // Device services related state + // + MBB_DS_STATE DeviceServiceState; + + // + // Protects Port specific information i.e + // 1) NumberofPorts + // 2) PortList. + // 3) MaxActivatedContexts + // Separate lock is required to protect Port specific + // information to avoid contention for Adapter lock. + // + + NDIS_SPIN_LOCK PortsLock; + + /** + * List to hold the ports created on this adapter + */ + MBB_PORT* PortList[MBB_MAX_NUMBER_OF_PORTS]; + ULONG NumberOfPorts; + + // Indicates how many PDP contexts can this adapter(device) hold. + // This should come from OID_WWAN_DEVICE_CAPS + ULONG MaxActivatedContexts; + + NDIS_SPIN_LOCK SessionIdPortTableLock; + + SESSIONID_PORTNUMBER_ENTRY SessionIdPortTable[MBB_MAX_NUMBER_OF_PORTS]; + + BOOLEAN SurpriseRemoved; +} MINIPORT_ADAPTER_CONTEXT, +*PMINIPORT_ADAPTER_CONTEXT; + +extern MINIPORT_DRIVER_CONTEXT GlobalControl; + +// MBB services natively supported by Windows via OIDs +static GUID NativeMbnServices[] = +{ + MBB_UUID_BASIC_CONNECT_CONSTANT, + MBB_UUID_SMS_CONSTANT, + MBB_UUID_USSD_CONSTANT, + MBB_UUID_AUTH_CONSTANT, + MBB_UUID_DSS_CONSTANT, + MBB_UUID_BASIC_CONNECT_EXT_CONSTANT +}; + + +//////////////////////////////////////////////////////////////////////////////// +// +// PROTOTYPES +// +//////////////////////////////////////////////////////////////////////////////// +// +// Driver routines +// +_Acquires_lock_( Driver->AdapterListLock ) +__drv_raisesIRQL(DISPATCH_LEVEL) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_savesIRQLGlobal( NdisSpinLock, Driver ) +VOID +MbbDriverLockAdapterList( + __in PMINIPORT_DRIVER_CONTEXT Driver + ); + +_Releases_lock_( Driver->AdapterListLock ) +__drv_maxIRQL(DISPATCH_LEVEL) +__drv_minIRQL(DISPATCH_LEVEL) +__drv_restoresIRQLGlobal( NdisSpinLock, Driver ) +VOID +MbbDriverUnlockAdapterList( + __in PMINIPORT_DRIVER_CONTEXT Driver + ); + +VOID +MbbDriverAddAdapter( + __in PMINIPORT_DRIVER_CONTEXT Driver, + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +VOID +MbbDriverRemoveAdapter( + __in PMINIPORT_DRIVER_CONTEXT Driver, + __in PMINIPORT_ADAPTER_CONTEXT Adapter + ); + +PMINIPORT_ADAPTER_CONTEXT +MbbDriverFindAdapterByNetLuid( + __in PMINIPORT_DRIVER_CONTEXT Driver, + __in PNET_LUID NetLuid + ); +// +// NDIS Miniport routines +// +MINIPORT_OID_REQUEST MbbNdisMiniportOidRequest; +MINIPORT_CANCEL_OID_REQUEST MbbNdisMiniportCancelOidRequest; +MINIPORT_SEND_NET_BUFFER_LISTS MbbNdisMiniportSendNetBufferLists; +MINIPORT_CANCEL_SEND MbbNdisMiniportCancelSend; +MINIPORT_RETURN_NET_BUFFER_LISTS MbbNdisMiniportReturnNetBufferLists; + +MBB_BUS_HANDLE +MbbNdisGetBusHandle( + __in MBB_PROTOCOL_HANDLE AdapterHandle + ); + +VOID +MbbNdisReceiveCallback( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, + __in MBB_RECEIVE_CONTEXT ReceiveContext, + __in PMDL Mdl + ); + +VOID +DrainCompleteCallback( + PVOID Context + ); + +PMBB_OID_HANDLER_ENTRY +MbbNdisGetOidHandlerByCommand( + __in PMBB_COMMAND Command + ); + +// Dss Send complete handler +VOID +MbbNdisDeviceServiceSessionSendComplete( + __in MBB_REQUEST_HANDLE RequestHandle, + __in NDIS_STATUS NdisStatus + ); + +// Dss Receive handler +NDIS_STATUS +MbbNdisDeviceServiceSessionReceive( + __in PMINIPORT_ADAPTER_CONTEXT AdapterContext, + __in ULONG SessionId, + __in_bcount_opt(InBufferSize) PUCHAR InBuffer, + __in ULONG InBufferSize + ); diff --git a/network/wwan/cxwmbclass/wmbclass.rc b/network/wwan/cxwmbclass/wmbclass.rc new file mode 100644 index 000000000..e42268c29 --- /dev/null +++ b/network/wwan/cxwmbclass/wmbclass.rc @@ -0,0 +1,21 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +#include +#include +#include "wmbclassEvents.rc" + +/*-----------------------------------------------*/ +/* the following lines are specific to this file */ +/*-----------------------------------------------*/ + +#define VER_FILETYPE VFT_DRV + +#define VER_FILESUBTYPE VFT2_DRV_NETWORK + +#define VER_FILEDESCRIPTION_STR "Windows Mobile Broadband Class NDIS Miniport" + +#define VER_INTERNALNAME_STR "wmbclass.sys" +#define VER_ORIGINALFILENAME_STR "wmbclass.sys" + +#include "common.ver" From 1b1a2099619c30d8ef9bb6dd87b44df76f22bed3 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Thu, 27 Oct 2022 10:09:53 -0700 Subject: [PATCH 03/15] udpate readme --- network/wwan/cxwmbclass/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 network/wwan/cxwmbclass/README.md diff --git a/network/wwan/cxwmbclass/README.md b/network/wwan/cxwmbclass/README.md new file mode 100644 index 000000000..e69de29bb From 9f8f982fb94f641ce78dd6ec6dbe9cb43b7d29c9 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Thu, 27 Oct 2022 10:27:20 -0700 Subject: [PATCH 04/15] update setup --- network/wwan/cxwmbclass.sln | 35 ++++ network/wwan/cxwmbclass/README.md | 14 ++ network/wwan/cxwmbclass/cxwmbclass.vcxproj | 167 ++++++++++++++++++ .../cxwmbclass/cxwmbclass.vcxproj.filters | 107 +++++++++++ 4 files changed, 323 insertions(+) create mode 100644 network/wwan/cxwmbclass.sln create mode 100644 network/wwan/cxwmbclass/cxwmbclass.vcxproj create mode 100644 network/wwan/cxwmbclass/cxwmbclass.vcxproj.filters diff --git a/network/wwan/cxwmbclass.sln b/network/wwan/cxwmbclass.sln new file mode 100644 index 000000000..6fe6c3c30 --- /dev/null +++ b/network/wwan/cxwmbclass.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KMDF Driver1", "KMDF Driver1\KMDF Driver1.vcxproj", "{C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|ARM64.Build.0 = Debug|ARM64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|x64.ActiveCfg = Debug|x64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|x64.Build.0 = Debug|x64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|x64.Deploy.0 = Debug|x64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|ARM64.ActiveCfg = Release|ARM64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|ARM64.Build.0 = Release|ARM64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|ARM64.Deploy.0 = Release|ARM64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|x64.ActiveCfg = Release|x64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|x64.Build.0 = Release|x64 + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|x64.Deploy.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7321185E-A30B-41CC-831E-42E6865DFF39} + EndGlobalSection +EndGlobal diff --git a/network/wwan/cxwmbclass/README.md b/network/wwan/cxwmbclass/README.md index e69de29bb..d0b049782 100644 --- a/network/wwan/cxwmbclass/README.md +++ b/network/wwan/cxwmbclass/README.md @@ -0,0 +1,14 @@ +--- +page_type: sample +description: "Demonstrates use of the cxwmbclass driver." +languages: +- c +products: +- windows +- windows-wdk +--- + +# cxwmbclass samples + +This sample demonstrates use of the cxwmbclass. + diff --git a/network/wwan/cxwmbclass/cxwmbclass.vcxproj b/network/wwan/cxwmbclass/cxwmbclass.vcxproj new file mode 100644 index 000000000..494c6b548 --- /dev/null +++ b/network/wwan/cxwmbclass/cxwmbclass.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + + + + {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683} + {497e31cb-056b-4f31-abb8-447fd55ee5a5} + v4.5 + 12.0 + Debug + x64 + KMDF_Driver1 + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + true + true + trace.h + true + + + sha256 + + + + + true + true + trace.h + true + + + sha256 + + + + + true + true + trace.h + true + + + sha256 + + + + + true + true + trace.h + true + + + sha256 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/network/wwan/cxwmbclass/cxwmbclass.vcxproj.filters b/network/wwan/cxwmbclass/cxwmbclass.vcxproj.filters new file mode 100644 index 000000000..3ba14d984 --- /dev/null +++ b/network/wwan/cxwmbclass/cxwmbclass.vcxproj.filters @@ -0,0 +1,107 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Driver Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file From ec53c7a7ca6a602e9cf2fdefd6dc4ebf756aaa00 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Fri, 28 Oct 2022 00:14:51 -0700 Subject: [PATCH 05/15] update build --- network/wwan/cxwmbclass.sln | 35 - network/wwan/cxwmbclass/BusFastIO.cpp | 85 + network/wwan/cxwmbclass/IpAddress.c | 1192 - network/wwan/cxwmbclass/IpAddress.h | 74 - network/wwan/cxwmbclass/LocalWPP.ini | 21 - .../wwan/cxwmbclass/MbbFastIOControlPlane.c | 116 - .../wwan/cxwmbclass/MbbFastIOControlPlane.h | 5 - network/wwan/cxwmbclass/MbbFastIODataPlane.c | 263 - network/wwan/cxwmbclass/MbbFastIODataPlane.h | 12 - network/wwan/cxwmbclass/MbbLibrary.c | 505 - network/wwan/cxwmbclass/RequestManager.c | 2176 -- network/wwan/cxwmbclass/RequestManager.h | 230 - network/wwan/cxwmbclass/adapter.c | 3398 --- network/wwan/cxwmbclass/adapter.cpp | 197 + network/wwan/cxwmbclass/adapter.h | 337 - network/wwan/cxwmbclass/businit.cpp | 2043 ++ network/wwan/cxwmbclass/cxwmbclass.rc | 20 + network/wwan/cxwmbclass/cxwmbclass.vcxproj | 167 - .../cxwmbclass/cxwmbclass.vcxproj.filters | 107 - network/wwan/cxwmbclass/datapipe.cpp | 1001 + network/wwan/cxwmbclass/device.cpp | 391 + network/wwan/cxwmbclass/driver.cpp | 121 + network/wwan/cxwmbclass/inc/BusFastIO.h | 35 + network/wwan/cxwmbclass/inc/BusInterface.h | 573 + network/wwan/cxwmbclass/inc/MapWwanMbb.h | 217 + network/wwan/cxwmbclass/inc/MbbLibrary.h | 175 + network/wwan/cxwmbclass/inc/WwanDrvCmn.h | 33 + network/wwan/cxwmbclass/inc/adapter.h | 49 + network/wwan/cxwmbclass/inc/align.h | 168 + network/wwan/cxwmbclass/inc/data.h | 185 + network/wwan/cxwmbclass/inc/device.h | 51 + network/wwan/cxwmbclass/inc/mbbfastio.h | 102 + network/wwan/cxwmbclass/inc/mbbmessages.h | 3274 +++ network/wwan/cxwmbclass/inc/mbbncm.h | 431 + network/wwan/cxwmbclass/inc/power.h | 7 + network/wwan/cxwmbclass/inc/precomp.h | 52 + network/wwan/cxwmbclass/inc/rxqueue.h | 22 + network/wwan/cxwmbclass/inc/txqueue.h | 19 + network/wwan/cxwmbclass/inc/usbbus.h | 250 + network/wwan/cxwmbclass/inc/util.h | 41 + network/wwan/cxwmbclass/inc/utils.h | 61 + network/wwan/cxwmbclass/init.c | 2269 -- network/wwan/cxwmbclass/port.c | 825 - network/wwan/cxwmbclass/port.h | 252 - network/wwan/cxwmbclass/power.cpp | 117 + network/wwan/cxwmbclass/precomp.h | 44 - network/wwan/cxwmbclass/product.pbxproj | 13 - network/wwan/cxwmbclass/receive.c | 1961 -- network/wwan/cxwmbclass/receive.h | 22 - network/wwan/cxwmbclass/request.c | 19728 ---------------- network/wwan/cxwmbclass/rxqueue.cpp | 609 + network/wwan/cxwmbclass/selsuspend.cpp | 79 + network/wwan/cxwmbclass/send.c | 2744 --- network/wwan/cxwmbclass/send.h | 42 - network/wwan/cxwmbclass/sources.inc | 12 + network/wwan/cxwmbclass/tmpMbbMessages.h | 3306 --- network/wwan/cxwmbclass/txqueue.cpp | 989 + network/wwan/cxwmbclass/util.c | 9090 ------- network/wwan/cxwmbclass/util.cpp | 326 + network/wwan/cxwmbclass/util.h | 1263 - network/wwan/cxwmbclass/utils.cpp | 589 + network/wwan/cxwmbclass/wmbclass.h | 1096 - network/wwan/cxwmbclass/wmbclass.rc | 21 - 63 files changed, 12324 insertions(+), 51314 deletions(-) delete mode 100644 network/wwan/cxwmbclass.sln create mode 100644 network/wwan/cxwmbclass/BusFastIO.cpp delete mode 100644 network/wwan/cxwmbclass/IpAddress.c delete mode 100644 network/wwan/cxwmbclass/IpAddress.h delete mode 100644 network/wwan/cxwmbclass/LocalWPP.ini delete mode 100644 network/wwan/cxwmbclass/MbbFastIOControlPlane.c delete mode 100644 network/wwan/cxwmbclass/MbbFastIOControlPlane.h delete mode 100644 network/wwan/cxwmbclass/MbbFastIODataPlane.c delete mode 100644 network/wwan/cxwmbclass/MbbFastIODataPlane.h delete mode 100644 network/wwan/cxwmbclass/MbbLibrary.c delete mode 100644 network/wwan/cxwmbclass/RequestManager.c delete mode 100644 network/wwan/cxwmbclass/RequestManager.h delete mode 100644 network/wwan/cxwmbclass/adapter.c create mode 100644 network/wwan/cxwmbclass/adapter.cpp delete mode 100644 network/wwan/cxwmbclass/adapter.h create mode 100644 network/wwan/cxwmbclass/businit.cpp create mode 100644 network/wwan/cxwmbclass/cxwmbclass.rc delete mode 100644 network/wwan/cxwmbclass/cxwmbclass.vcxproj delete mode 100644 network/wwan/cxwmbclass/cxwmbclass.vcxproj.filters create mode 100644 network/wwan/cxwmbclass/datapipe.cpp create mode 100644 network/wwan/cxwmbclass/device.cpp create mode 100644 network/wwan/cxwmbclass/driver.cpp create mode 100644 network/wwan/cxwmbclass/inc/BusFastIO.h create mode 100644 network/wwan/cxwmbclass/inc/BusInterface.h create mode 100644 network/wwan/cxwmbclass/inc/MapWwanMbb.h create mode 100644 network/wwan/cxwmbclass/inc/MbbLibrary.h create mode 100644 network/wwan/cxwmbclass/inc/WwanDrvCmn.h create mode 100644 network/wwan/cxwmbclass/inc/adapter.h create mode 100644 network/wwan/cxwmbclass/inc/align.h create mode 100644 network/wwan/cxwmbclass/inc/data.h create mode 100644 network/wwan/cxwmbclass/inc/device.h create mode 100644 network/wwan/cxwmbclass/inc/mbbfastio.h create mode 100644 network/wwan/cxwmbclass/inc/mbbmessages.h create mode 100644 network/wwan/cxwmbclass/inc/mbbncm.h create mode 100644 network/wwan/cxwmbclass/inc/power.h create mode 100644 network/wwan/cxwmbclass/inc/precomp.h create mode 100644 network/wwan/cxwmbclass/inc/rxqueue.h create mode 100644 network/wwan/cxwmbclass/inc/txqueue.h create mode 100644 network/wwan/cxwmbclass/inc/usbbus.h create mode 100644 network/wwan/cxwmbclass/inc/util.h create mode 100644 network/wwan/cxwmbclass/inc/utils.h delete mode 100644 network/wwan/cxwmbclass/init.c delete mode 100644 network/wwan/cxwmbclass/port.c delete mode 100644 network/wwan/cxwmbclass/port.h create mode 100644 network/wwan/cxwmbclass/power.cpp delete mode 100644 network/wwan/cxwmbclass/precomp.h delete mode 100644 network/wwan/cxwmbclass/product.pbxproj delete mode 100644 network/wwan/cxwmbclass/receive.c delete mode 100644 network/wwan/cxwmbclass/receive.h delete mode 100644 network/wwan/cxwmbclass/request.c create mode 100644 network/wwan/cxwmbclass/rxqueue.cpp create mode 100644 network/wwan/cxwmbclass/selsuspend.cpp delete mode 100644 network/wwan/cxwmbclass/send.c delete mode 100644 network/wwan/cxwmbclass/send.h create mode 100644 network/wwan/cxwmbclass/sources.inc delete mode 100644 network/wwan/cxwmbclass/tmpMbbMessages.h create mode 100644 network/wwan/cxwmbclass/txqueue.cpp delete mode 100644 network/wwan/cxwmbclass/util.c create mode 100644 network/wwan/cxwmbclass/util.cpp delete mode 100644 network/wwan/cxwmbclass/util.h create mode 100644 network/wwan/cxwmbclass/utils.cpp delete mode 100644 network/wwan/cxwmbclass/wmbclass.h delete mode 100644 network/wwan/cxwmbclass/wmbclass.rc diff --git a/network/wwan/cxwmbclass.sln b/network/wwan/cxwmbclass.sln deleted file mode 100644 index 6fe6c3c30..000000000 --- a/network/wwan/cxwmbclass.sln +++ /dev/null @@ -1,35 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.3.32929.385 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KMDF Driver1", "KMDF Driver1\KMDF Driver1.vcxproj", "{C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM64 = Debug|ARM64 - Debug|x64 = Debug|x64 - Release|ARM64 = Release|ARM64 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|ARM64.Build.0 = Debug|ARM64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|x64.ActiveCfg = Debug|x64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|x64.Build.0 = Debug|x64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Debug|x64.Deploy.0 = Debug|x64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|ARM64.ActiveCfg = Release|ARM64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|ARM64.Build.0 = Release|ARM64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|ARM64.Deploy.0 = Release|ARM64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|x64.ActiveCfg = Release|x64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|x64.Build.0 = Release|x64 - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683}.Release|x64.Deploy.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7321185E-A30B-41CC-831E-42E6865DFF39} - EndGlobalSection -EndGlobal diff --git a/network/wwan/cxwmbclass/BusFastIO.cpp b/network/wwan/cxwmbclass/BusFastIO.cpp new file mode 100644 index 000000000..ad125d355 --- /dev/null +++ b/network/wwan/cxwmbclass/BusFastIO.cpp @@ -0,0 +1,85 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +#include + +VOID MbbBusSendNetBufferLists(_In_ MBB_BUS_HANDLE BusHandle, _In_ PNET_BUFFER_LIST NetBufferList, _In_ ULONG SessionId, _In_ ULONG SendFlags) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + BusObject->SendNetBufferListsHandler(BusObject->ModemContext, NetBufferList, SessionId, SendFlags); +} + +VOID MbbBusReturnNetBufferLists(_In_ MBB_BUS_HANDLE BusHandle, _In_ PNET_BUFFER_LIST NetBufferList, _In_ ULONG ReturnFlags) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + BusObject->ReturnNetBufferListsHandler(BusObject->ModemContext, NetBufferList, ReturnFlags); +} + +VOID MbbBusCancelSendHandler(_In_ MBB_BUS_HANDLE BusHandle, _In_ PVOID CancelId) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + BusObject->CancelSendHandler(BusObject->ModemContext, CancelId); +} + +VOID MbbBusHalt(_In_ MBB_BUS_HANDLE BusHandle, _In_ NDIS_HALT_ACTION HaltAction) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + if (BusObject->State == BUS_STATE_OPENED) + { + BusObject->HaltHandler(BusObject->ModemContext, HaltAction); + } +} + +_IRQL_requires_(PASSIVE_LEVEL) +NDIS_STATUS +MbbBusPause(_In_ MBB_BUS_HANDLE BusHandle) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + if (BusObject->State == BUS_STATE_OPENED) + { + Status = BusObject->PauseHandler(BusObject->ModemContext); + } + return Status; +} + +_When_(ShutdownAction == NdisShutdownPowerOff, _IRQL_requires_(PASSIVE_LEVEL)) + _When_(ShutdownAction == NdisShutdownBugCheck, _IRQL_requires_(HIGH_LEVEL)) VOID + MbbBusShutdown(_In_ MBB_BUS_HANDLE BusHandle, _In_ NDIS_SHUTDOWN_ACTION ShutdownAction) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + if (BusObject->ShutdownHandler && BusObject->State == BUS_STATE_OPENED) + { + BusObject->ShutdownHandler(BusObject->ModemContext, ShutdownAction); + } +} + +_IRQL_requires_max_(DISPATCH_LEVEL) NDIS_STATUS MbbBusReset(_In_ MBB_BUS_HANDLE BusHandle) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + if (BusObject->ResetHandler && BusObject->State == BUS_STATE_OPENED) + { + Status = BusObject->ResetHandler(BusObject->ModemContext); + } + return Status; +} + +_IRQL_requires_max_(DISPATCH_LEVEL) NDIS_STATUS MbbBusRestart(_In_ MBB_BUS_HANDLE BusHandle) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + if (BusObject->State == BUS_STATE_OPENED) + { + Status = BusObject->RestartHandler(BusObject->ModemContext); + } + return Status; +} + +BOOLEAN +MbbBusIsFastIO(_In_ MBB_BUS_HANDLE BusHandle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + return (BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceType == USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO); +} diff --git a/network/wwan/cxwmbclass/IpAddress.c b/network/wwan/cxwmbclass/IpAddress.c deleted file mode 100644 index 29f9d0697..000000000 --- a/network/wwan/cxwmbclass/IpAddress.c +++ /dev/null @@ -1,1192 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -//////////////////////////////////////////////////////////////////////////////// -// -// INCLUDES -// -//////////////////////////////////////////////////////////////////////////////// -#include "precomp.h" -#include "IpAddress.tmh" - - -#define MBB_PREALLOC_IP_WORKITEM_COUNT 1 - - -//////////////////////////////////////////////////////////////////////////////// -// -// PROTOTYPES -// -//////////////////////////////////////////////////////////////////////////////// - -_Requires_lock_held_( Port->Lock ) -VOID -MbbIpSnapPortAddressTable( - __in PMBB_PORT Port, - __in MBB_ADDRESS_TABLE_ID TableId, - __deref_out_ecount(*AddressCount) PMBB_IPADDRESS_ENTRY* AddressTable, - __out PULONG AddressCount - ); - -_Requires_lock_held_( Port->Lock ) -VOID -MbbIpSnapPortIpTable( - __in PMBB_PORT Port, - __deref_out_ecount(*AddressCount) PMBB_IPADDRESS_ENTRY* AddressTable, - __out PULONG AddressCount - ); - -__callback -VOID -MbbIpProcessChange( - __in PVOID Context1, - __in PVOID Context2, - __in PVOID Context3, - __in PVOID Context4 - ); - -NDIS_STATUS -MbbIpQueueIPChange( - __in PMINIPORT_DRIVER_CONTEXT Driver, - __in PNET_LUID NetLuid, - __in MBB_IP_CHANGE_TYPE IPChangeType, - __in NDIS_PORT_NUMBER PortNumber - ); - -__callback -VOID -MbbIpInterfaceChangeCallback( - __in PVOID CallerContext, - __in_opt PMIB_IPINTERFACE_ROW Row, - __in MIB_NOTIFICATION_TYPE NotificationType - ); - -__callback -VOID -MbbIpRouteChangeCallback( - _In_ PVOID CallerContext, - _In_opt_ PMIB_IPFORWARD_ROW2 Row, - _In_ MIB_NOTIFICATION_TYPE NotificationType - ); - -__callback -VOID -MbbIpUnicastAddressChangeCallback( - _In_ PVOID CallerContext, - _In_opt_ PMIB_UNICASTIPADDRESS_ROW Row, - _In_ MIB_NOTIFICATION_TYPE NotificationType - ); - - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// IMPLEMENTATION -// -//////////////////////////////////////////////////////////////////////////////// -_Requires_lock_held_( Port->Lock ) -VOID -MbbIpSnapPortAddressTable( - __in PMBB_PORT Port, - __in MBB_ADDRESS_TABLE_ID TableId, - __deref_out_ecount(*AddressCount) PMBB_IPADDRESS_ENTRY* AddressTable, - __out PULONG AddressCount - ) -{ - ULONG AddressIndex; - ULONG V4Index; - ULONG V6Index; - ULONG V4Count = 0; - ULONG V6Count = 0; - #pragma prefast (suppress:__WARNING_IPV6_ADDRESS_STRUCTURE_IPV4_SPECIFIC) - IN_ADDR* V4Table = NULL; - IN6_ADDR* V6Table = NULL; - ULONG LocalAddressCount = 0; - PMBB_IPADDRESS_ENTRY LocalAddressTable = NULL; - - do - { - if( Port->IpAddressInfo == NULL ) - { - // - // We are not connected yet. - // - break; - } - - switch( TableId ) - { - case MbbAddressTableGateway: - { - V4Count = MBB_IP_GET_GWV4COUNT( Port->IpAddressInfo ); - V4Table = MBB_IP_GET_GWV4TABLE( Port->IpAddressInfo ); - V6Count = MBB_IP_GET_GWV6COUNT( Port->IpAddressInfo ); - V6Table = MBB_IP_GET_GWV6TABLE( Port->IpAddressInfo ); - } - break; - - case MbbAddressTableDns: - { - V4Count = MBB_IP_GET_DSV4COUNT( Port->IpAddressInfo ); - V4Table = MBB_IP_GET_DSV4TABLE( Port->IpAddressInfo ); - V6Count = MBB_IP_GET_DSV6COUNT( Port->IpAddressInfo ); - V6Table = MBB_IP_GET_DSV6TABLE( Port->IpAddressInfo ); - } - break; - - default: - { - ASSERT( TableId == MbbAddressTableGateway || TableId == MbbAddressTableDns ); - } - break; - } - - if( (LocalAddressCount = V4Count + V6Count) == 0 ) - { - break; - } - - if( (LocalAddressTable = ALLOCATE_NONPAGED_POOL( sizeof(MBB_IPADDRESS_ENTRY) * LocalAddressCount )) == NULL ) - { - LocalAddressCount = 0; - break; - } - - for( V4Index = 0, AddressIndex = 0; - V4Index < V4Count; - V4Index ++, AddressIndex ++ ) - { - LocalAddressTable[AddressIndex].IsIpv6 = FALSE; - LocalAddressTable[AddressIndex].IsReported = FALSE; - - #pragma prefast (suppress:__WARNING_IPV6_ADDRESS_STRUCTURE_IPV4_SPECIFIC) - RtlCopyMemory( - &LocalAddressTable[AddressIndex].Ipv4.IPV4Address, - &V4Table[V4Index], - sizeof(IN_ADDR) - ); - } - - for( V6Index = 0; - V6Index < V6Count; - V6Index ++, AddressIndex ++ ) - { - LocalAddressTable[AddressIndex].IsIpv6 = TRUE; - LocalAddressTable[AddressIndex].IsReported = FALSE; - - RtlCopyMemory( - &LocalAddressTable[AddressIndex].Ipv6.IPV6Address, - &V6Table[V6Index], - sizeof(IN6_ADDR) - ); - } - } while( FALSE ); - - *AddressCount = LocalAddressCount; - *AddressTable = LocalAddressTable; -} - -_Requires_lock_held_( Port->Lock ) -VOID -MbbIpSnapPortIpTable( - __in PMBB_PORT Port, - __deref_out_ecount(*AddressCount) PMBB_IPADDRESS_ENTRY* AddressTable, - __out PULONG AddressCount - ) -{ - ULONG AddressIndex; - ULONG V4Index; - ULONG V6Index; - ULONG V4Count = 0; - ULONG V6Count = 0; - PMBB_IPV4_ADDRESS V4Table = NULL; - PMBB_IPV6_ADDRESS V6Table = NULL; - ULONG LocalAddressCount = 0; - PMBB_IPADDRESS_ENTRY LocalAddressTable = NULL; - - do - { - if( Port->IpAddressInfo == NULL ) - { - // - // We are not connected yet. - // - break; - } - - V4Count = MBB_IP_GET_IPV4COUNT( Port->IpAddressInfo ); - V4Table = MBB_IP_GET_IPV4TABLE( Port->IpAddressInfo ); - V6Count = MBB_IP_GET_IPV6COUNT( Port->IpAddressInfo ); - V6Table = MBB_IP_GET_IPV6TABLE( Port->IpAddressInfo ); - - if( (LocalAddressCount = V4Count + V6Count) == 0 ) - { - break; - } - - if( (LocalAddressTable = ALLOCATE_NONPAGED_POOL( sizeof(MBB_IPADDRESS_ENTRY) * LocalAddressCount )) == NULL ) - { - LocalAddressCount = 0; - break; - } - - for( V4Index = 0, AddressIndex = 0; - V4Index < V4Count; - V4Index ++, AddressIndex ++ ) - { - LocalAddressTable[AddressIndex].IsIpv6 = FALSE; - LocalAddressTable[AddressIndex].IsReported = FALSE; - - RtlCopyMemory( - &LocalAddressTable[AddressIndex].Ipv4, - &V4Table[V4Index], - sizeof(MBB_IPV4_ADDRESS) - ); - } - - for( V6Index = 0; - V6Index < V6Count; - V6Index ++, AddressIndex ++ ) - { - LocalAddressTable[AddressIndex].IsIpv6 = TRUE; - LocalAddressTable[AddressIndex].IsReported = FALSE; - - RtlCopyMemory( - &LocalAddressTable[AddressIndex].Ipv6, - &V6Table[V6Index], - sizeof(MBB_IPV6_ADDRESS) - ); - } - } while( FALSE ); - - *AddressCount = LocalAddressCount; - *AddressTable = LocalAddressTable; -} - -// -// Ip Address CID -// - -NDIS_STATUS -MbbIpAddressStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -/*++ -Description: - - The IP Status Handler processes responses to requested IP Info as well as - unsolicited change indications from the device. Only one instance of this routine - runs at any time due to the CID Serializer (RequestManager) so there is no race in - reporting two IP indications from the device on two threads. - - It does the following - - - 1. Verify that IP information received is valid. - - 2. Copy & cache the information in the adapter object. - a. Required for validating the IP configured on the adpater in IpChangeCallback. - - 3. Enable \ Disable DHCPv4 depending on whether IP Address is available via Layer2. - DHCPv6 or NDP behavior is not changed. - The network is required to be configured correctly i.e. not give IPv6 over Layer2 and Layer3. - - 4. Report the new DNS, IP, Gateway to IP stack. - The order in which the information is reported is important. - a. MTU (Supported starting in Blue) - b. DNS Servers - c. IP Address - d. Routes - - 5. Indicate LinkUP to NDIS under the following condition - - a. DNS Server setting changed. LinkDOWN followed by a LinkUP is required for the stack to pick up the changes. - b. IP Information was retrieved as a result of a connect (not unsolicited indication). ---*/ -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; - PMBB_IP_ADDRESS_INFO IpAddressInfo = (PMBB_IP_ADDRESS_INFO)InBuffer; - MBB_CONNECTION_STATE ConnectionState; - PMBB_PORT Port = NULL; - NDIS_PORT_NUMBER PortNumber = DEFAULT_NDIS_PORT_NUMBER; - USHORT EffectiveMaxMtu = MBIM_MAX_MTU_SIZE; - - do - { - // - // Only parse the result on sucess - // - if( NdisStatus != STATUS_SUCCESS || - (MbbStatus != MBB_STATUS_SUCCESS) || - IpAddressInfo == NULL ) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: FAILED to get IP Address info, NdisStatus=%!STATUS! MbbStatus=%!MbbStatus!", - Adapter->NetLuid.Value, - NdisStatus, - MbbStatus - ); - break; - } - - //Get the port corresponding to the session id - - Port = MbbWwanTranslateSessionIdToPort(Adapter, IpAddressInfo->SessionId); - - if(!Port) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid session id. No port corresponding to the session id %lu", - Adapter->NetLuid.Value, IpAddressInfo->SessionId - ); - break; - } - - MBB_ACQUIRE_PORT_LOCK(Port); - PortNumber = Port->PortNumber; - MBB_RELEASE_PORT_LOCK(Port); - - // - // Device should only send unsolicited indications after successful connection. - // - if( MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE && - MbbPortIsConnected(Port) == FALSE ) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: IGNORING unsolicited notification when port is disconnected", - Adapter->NetLuid.Value - ); - break; - } - - // - // Minimum buffer size check - // - if( InBufferSize < sizeof(MBB_IP_ADDRESS_INFO) ) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: INSUFFICIENT IP Address info length, expected=%d received=%d", - Adapter->NetLuid.Value, - sizeof(MBB_IP_ADDRESS_INFO), - InBufferSize - ); - break; - } - - // - // Max MTU is different from initialized value if the device has the Extended descriptor (per Errata). - // - if ( Adapter->BusParams.IsErrataDevice ) - { - EffectiveMaxMtu = Adapter->BusParams.MTU; - } - - // - // Minimum and Maximum IPv4 MTU size check, but only require correct - // value if MTU being set. If not correct, just ignore. - // - if( MBB_IP_IS_MTUV4_AVAILABLE( IpAddressInfo ) ) - { - - if( ( - IpAddressInfo->IPv4MTU < MBIM_MIN_MTU_SIZE - ) || - ( - (USHORT) IpAddressInfo->IPv4MTU > EffectiveMaxMtu - ) ) - - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: IGNORING Invalid IPv4 MTU value, received=%d min=%d max=%d", - Adapter->NetLuid.Value, - IpAddressInfo->IPv4MTU, - MBIM_MIN_MTU_SIZE, - EffectiveMaxMtu - ); - // Do *NOT* break so other settings continue to work even if MTU setting is off. - // Simply set to be ignored when effecting the actual change in MbbIpProcessChange() later on. - IpAddressInfo->IPv4Flags &= ~MbbIpFlagsMTUAvailable; - } - } - - // - // Minimum and Maximum IPv6 MTU size check, but only require correct - // value if MTU being set, otherwise ignore. - // - if( MBB_IP_IS_MTUV6_AVAILABLE( IpAddressInfo ) ) - { - - if( ( - IpAddressInfo->IPv6MTU < MBIM_MIN_MTU_SIZE - ) || - ( - (USHORT) IpAddressInfo->IPv6MTU > EffectiveMaxMtu - ) ) - - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: IGNORING Invalid IPv6 MTU value, received=%d min=%d max=%d", - Adapter->NetLuid.Value, - IpAddressInfo->IPv6MTU, - MBIM_MIN_MTU_SIZE, - EffectiveMaxMtu - ); - // Do *NOT* break so other settings continue to work even if MTU setting is off. - // Simply set to be ignored when effecting the actual change in MbbIpProcessChange() later on. - IpAddressInfo->IPv6Flags &= ~MbbIpFlagsMTUAvailable; - } - } - - // - // Variable fields check - // - #pragma prefast (suppress:__WARNING_IPV6_ADDRESS_STRUCTURE_IPV4_SPECIFIC) - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - IpAddressInfo->IPv4GatewayOffset, - sizeof(IN_ADDR), - 1, - sizeof(IN_ADDR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv4 gateway, offset=%d received=%d", - Adapter->NetLuid.Value, - IpAddressInfo->IPv4GatewayOffset, - InBufferSize - ); - - break; - - } - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - IpAddressInfo->IPv6GatewayOffset, - sizeof(IN6_ADDR), - 1, - sizeof(IN6_ADDR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv6 gateway, offset=%d received=%d", - Adapter->NetLuid.Value, - IpAddressInfo->IPv6GatewayOffset, - InBufferSize - ); - - break; - - } - - - NdisStatus=MbbIsArrayFieldValid( - InBufferSize, - IpAddressInfo->IPv4AddressOffset, - IpAddressInfo->IPv4AddressCount, - sizeof(MBB_IPV4_ADDRESS) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv4 address array, offset=%d, count=%d, received=%d", - Adapter->NetLuid.Value, - IpAddressInfo->IPv4AddressOffset, - IpAddressInfo->IPv4AddressCount, - InBufferSize - ); - - break; - - } - - NdisStatus=MbbIsArrayFieldValid( - InBufferSize, - IpAddressInfo->IPv6AddressOffset, - IpAddressInfo->IPv6AddressCount, - sizeof(MBB_IPV6_ADDRESS) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv6 address array, offset=%d, count=%d, received=%d", - Adapter->NetLuid.Value, - IpAddressInfo->IPv6AddressOffset, - IpAddressInfo->IPv6AddressCount, - InBufferSize - ); - - break; - - } - - #pragma prefast (suppress:__WARNING_IPV6_ADDRESS_STRUCTURE_IPV4_SPECIFIC) - NdisStatus=MbbIsArrayFieldValid( - InBufferSize, - IpAddressInfo->IPv4DnsServerOffset, - IpAddressInfo->IPv4DnsServerCount, - sizeof(IN_ADDR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv4 DNS address array, offset=%d, count=%d, received=%d", - Adapter->NetLuid.Value, - IpAddressInfo->IPv4DnsServerOffset, - IpAddressInfo->IPv4DnsServerCount, - InBufferSize - ); - - break; - - } - - NdisStatus=MbbIsArrayFieldValid( - InBufferSize, - IpAddressInfo->IPv6DnsServerOffset, - IpAddressInfo->IPv6DnsServerCount, - sizeof(IN6_ADDR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: Invalid IPv6 DNS address array, offset=%d, count=%d, received=%d", - Adapter->NetLuid.Value, - IpAddressInfo->IPv6DnsServerOffset, - IpAddressInfo->IPv6DnsServerCount, - InBufferSize - ); - - break; - - } - - - // - // IP and Gateway should be reported using the same mechanism - // - if( MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ) != MBB_IP_IS_GWV4_AVAILABLE( IpAddressInfo ) && - MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo ) != MBB_IP_IS_GWV6_AVAILABLE( IpAddressInfo ) ) - { - ASSERT( FALSE ); - - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: IP and Gateway should be configured using same Layer mechanisms. v4[IP=%!bool! GW=%!bool!] v6[IP=%!bool! GW=%!bool!]", - Adapter->NetLuid.Value, - MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ), - MBB_IP_IS_GWV4_AVAILABLE( IpAddressInfo ), - MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo ), - MBB_IP_IS_GWV6_AVAILABLE( IpAddressInfo ) - ); - break; - } - // - // Log a warning when IP is derived from Layer2 mechanisms and DNS is derived from Layer3 - // - if( ( - MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ) && - !MBB_IP_IS_DSV4_AVAILABLE( IpAddressInfo ) - ) || - ( - MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo ) && - !MBB_IP_IS_DSV6_AVAILABLE( IpAddressInfo ) - ) ) - { - TraceWarn( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: DNS configured using Layer3 when IP is derived from Layer2. v4[IP=%!bool! DNS=%!bool!] v6[IP=%!bool! DNS=%!bool!]", - Adapter->NetLuid.Value, - MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ), - MBB_IP_IS_DSV4_AVAILABLE( IpAddressInfo ), - MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo ), - MBB_IP_IS_DSV6_AVAILABLE( IpAddressInfo ) - ); - } - - if(!IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - // Enable/Disable DHCP for default port connection. For non-default - // port connection the virtual miniport will do it when we send - // NDIS_WWAN_IP_ADDRESS_STATE indication - WwanAdjustDhcpSettings( - Adapter->NetLuid, - Adapter->NetCfgId, - (! MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo ))); - } - - TraceInfo( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x][Port=%lu] CID_IP_CONFIGURATION: %02d IPv4 %02d IPv6 %02d DNv4 %02d DNv6 %02d GWv4 %02d GWv6 (IPv4MTU %d IPv6MTU %d)", - Adapter->NetLuid.Value, - PortNumber, - MBB_IP_IS_IPV4_AVAILABLE( IpAddressInfo )? IpAddressInfo->IPv4AddressCount: 0, - MBB_IP_IS_IPV6_AVAILABLE( IpAddressInfo )? IpAddressInfo->IPv6AddressCount: 0, - MBB_IP_IS_DSV4_AVAILABLE( IpAddressInfo )? IpAddressInfo->IPv4DnsServerCount: 0, - MBB_IP_IS_DSV6_AVAILABLE( IpAddressInfo )? IpAddressInfo->IPv6DnsServerCount: 0, - MBB_IP_IS_GWV4_AVAILABLE( IpAddressInfo )? 1: 0, - MBB_IP_IS_GWV6_AVAILABLE( IpAddressInfo )? 1: 0, - MBB_IP_IS_MTUV4_AVAILABLE( IpAddressInfo ) ? IpAddressInfo->IPv4MTU : 0, - MBB_IP_IS_MTUV6_AVAILABLE( IpAddressInfo ) ? IpAddressInfo->IPv6MTU : 0 - ); - - if (MBB_IP_IS_IPV4_AVAILABLE(IpAddressInfo)) - { - PMBB_IPV4_ADDRESS pIPV4Elem = (PMBB_IPV4_ADDRESS)(InBuffer + IpAddressInfo->IPv4AddressOffset); - for (unsigned int i = 0; i < IpAddressInfo->IPv4AddressCount; i++, pIPV4Elem++) - { - TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: IPv4 #%d (subnetAddrLen %d) : %!IPV4ADDR!", - i+1, pIPV4Elem->OnLinkPrefixLength, pIPV4Elem->IPV4Address); - } - } - - if (MBB_IP_IS_GWV4_AVAILABLE(IpAddressInfo)) - { - PIN_ADDR pInAddr = (PIN_ADDR)(InBuffer + IpAddressInfo->IPv4GatewayOffset); - TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: GWv4: %d.%d.%d.%d", - pInAddr->S_un.S_un_b.s_b1, pInAddr->S_un.S_un_b.s_b2, pInAddr->S_un.S_un_b.s_b3, pInAddr->S_un.S_un_b.s_b4); - } - - if (MBB_IP_IS_DSV4_AVAILABLE(IpAddressInfo)) - { - PIN_ADDR pInAddr = (PIN_ADDR)(InBuffer + IpAddressInfo->IPv4DnsServerOffset); - for (unsigned int i = 0; i < IpAddressInfo->IPv4DnsServerCount; i++, pInAddr++) - { - TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: DNSv4 #%d: %d.%d.%d.%d", - i+1, pInAddr->S_un.S_un_b.s_b1, pInAddr->S_un.S_un_b.s_b2, pInAddr->S_un.S_un_b.s_b3, pInAddr->S_un.S_un_b.s_b4); - } - } - - if (MBB_IP_IS_IPV6_AVAILABLE(IpAddressInfo)) - { - PMBB_IPV6_ADDRESS pIPV6Elem = (PMBB_IPV6_ADDRESS)(InBuffer + IpAddressInfo->IPv6AddressOffset); - for (unsigned int i = 0; i < IpAddressInfo->IPv6AddressCount; i++, pIPV6Elem++) - { - TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: IPv6 #%d (prefixLen %d): %!IPV6ADDR!", - i + 1, pIPV6Elem->OnLinkPrefixLength, pIPV6Elem->IPV6Address); - } - } - - if (MBB_IP_IS_GWV6_AVAILABLE(IpAddressInfo)) - { - PIN6_ADDR pIn6Addr = (PIN6_ADDR)(InBuffer + IpAddressInfo->IPv6GatewayOffset); - TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: GWv6: %!IPV6ADDR!", pIn6Addr->u.Byte); - } - - if (MBB_IP_IS_DSV6_AVAILABLE(IpAddressInfo)) - { - PIN6_ADDR pIn6Addr = (PIN6_ADDR)(InBuffer + IpAddressInfo->IPv6DnsServerOffset); - for (unsigned int i = 0; i < IpAddressInfo->IPv6DnsServerCount; i++, pIn6Addr++) - { - TraceInfo( WMBCLASS_IP, "CID_IP_CONFIGURATION: DNSv6 #%d: %!IPV6ADDR!", i+1, pIn6Addr->u.Byte); - } - } - - // - // Copy the received info. - // -#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate IP address info, only one instance exists, released if new IP info comes.") - if( (IpAddressInfo = ALLOCATE_NONPAGED_POOL( InBufferSize )) == NULL ) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] CID_IP_CONFIGURATION: FAILED to allocate IP Address Info", Adapter->NetLuid.Value ); - break; - } - RtlCopyMemory( IpAddressInfo, InBuffer, InBufferSize ); - - MBB_ACQUIRE_PORT_LOCK(Port); - - if( Port->IpAddressInfo != NULL ) - { - FREE_POOL( Port->IpAddressInfo ); - } - Port->IpAddressInfo = IpAddressInfo; - - MBB_RELEASE_PORT_LOCK(Port); - - MbbIpQueueIPChange( - &GlobalControl, - &Adapter->NetLuid, - MbbReqMgrIsUnsolicitedIndication( Request )? - MbbIPChangeTypeDeviceConfigurationChange: - MbbIPChangeTypeDeviceConfiguration, - PortNumber - ); - - - } - while( FALSE ); - - if(Port != NULL) - { - // Remove the reference added in find - Dereference(Port); - } - - return NDIS_STATUS_SUCCESS; -} - -__callback -VOID -MbbIpProcessChange( - __in PVOID Context1, - __in PVOID Context2, - __in PVOID Context3, - __in PVOID Context4 - ) -{ - PMBB_REQUEST_CONTEXT NextRequest; -// PMINIPORT_DRIVER_CONTEXT Driver = (PMINIPORT_DRIVER_CONTEXT)Context1; - PMINIPORT_ADAPTER_CONTEXT Adapter= (PMINIPORT_ADAPTER_CONTEXT)Context2; - MBB_IP_CHANGE_TYPE IPChangeType = (MBB_IP_CHANGE_TYPE)Context3; - PMBB_PORT Port = (PMBB_PORT)Context4; - NDIS_PORT_NUMBER PortNumber = DEFAULT_NDIS_PORT_NUMBER; - PMBB_IPADDRESS_ENTRY IpTable = NULL; - ULONG IpCount; - PMBB_IPADDRESS_ENTRY GatewayTable = NULL; - ULONG GatewayCount; - PMBB_IPADDRESS_ENTRY DnsTable = NULL; - ULONG DnsCount = 0; - PMBB_IPADDRESS_ENTRY LastIpTable; - ULONG LastIpCount; - PMBB_IPADDRESS_ENTRY LastGatewayTable; - ULONG LastGatewayCount; - PMBB_IPADDRESS_ENTRY LastDnsTable; - ULONG LastDnsCount; - BOOLEAN IsUserConfiguredIP = FALSE; - MBB_CONNECTION_STATE ConnectionState; - NDIS_STATUS NdisStatus; - WWAN_IP_ADDRESS_STATE IpAddressState = {0}; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - TraceInfo( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] Processing %!MbbIPChangeType!", Adapter->NetLuid.Value, IPChangeType ); - - do - { - if(Port == NULL) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] IP change queued on invalid ndis port", Adapter->NetLuid.Value); - break; - } - - // - // Get current IP information - // - - MBB_ACQUIRE_PORT_LOCK(Port); - - PortNumber = Port->PortNumber; - - MbbIpSnapPortIpTable( - Port, - &IpTable, - &IpCount - ); - - MbbIpSnapPortAddressTable( - Port, - MbbAddressTableGateway, - &GatewayTable, - &GatewayCount - ); - // - // Only evaluate DNS changes when the device reports a change. - // - if( IPChangeType == MbbIPChangeTypeDeviceConfiguration || - IPChangeType == MbbIPChangeTypeDeviceConfigurationChange ) - { - MbbIpSnapPortAddressTable( - Port, - MbbAddressTableDns, - &DnsTable, - &DnsCount - ); - } - - Status = MbbUtilPopulateWwanIPAddressState( - Port->IpAddressInfo, - IpTable, - GatewayTable, - DnsTable, - IpCount, - GatewayCount, - DnsCount, - &IpAddressState); - - MBB_RELEASE_PORT_LOCK(Port); - - if(Status != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] IP change queued for disconnected port", Adapter->NetLuid.Value); - break; - } - - // For DEFAULT_NDIS_PORT ( i.e Port 0 ) update the IP address information - // For non default ports we send the indication upto the virtual miniport. - // The virtual miniport then updates its IP address information in the registry - - if(IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - MbbPortSetIpAddressState( - Adapter, - &IpAddressState, - PortNumber); - } - else - { - // Report the information in order to the IP stack for default port - WwanUpdateIPStack( - Adapter->MiniportAdapterHandle, - &IpAddressState, - Adapter->NetLuid, - Adapter->NetCfgId, - Adapter->IfIndex, - (IPChangeType == MbbIPChangeTypeDeviceConfiguration - || IPChangeType == MbbIPChangeTypeDeviceConfigurationChange) - ); - } - - // - // Indicate LinkUP to NDIS. - // In case of successful connect request this is done even when IP info was not reported to IP successfully - // since the CONNECT OID is already completed with success. Worst case is that the adapter will not - // have an IP info. - // - if( IPChangeType == MbbIPChangeTypeDeviceConfiguration ) - { - ConnectionState.ConnectionUp = MediaConnectStateConnected; - - ConnectionState.UpStreamBitRate = Adapter->UplinkSpeed; - ConnectionState.DownStreamBitRate = Adapter->DownlinkSpeed; - - MbbAdapterSetConnectionState( - Adapter, - &ConnectionState, - PortNumber - ); - } - } - while( FALSE ); - - if(DnsTable!= NULL) - { - FREE_POOL( DnsTable ); - DnsTable = NULL; - } - - if(IpTable!= NULL) - { - FREE_POOL( IpTable ); - IpTable = NULL; - } - - if(GatewayTable!= NULL) - { - FREE_POOL( GatewayTable ); - GatewayTable = NULL; - } - - if(IpAddressState.IpTable) - { - FREE_POOL(IpAddressState.IpTable); - IpAddressState.IpTable = NULL; - } - - if(IpAddressState.GatewayTable) - { - FREE_POOL(IpAddressState.GatewayTable); - IpAddressState.GatewayTable = NULL; - } - - if(IpAddressState.DnsTable) - { - FREE_POOL(IpAddressState.DnsTable); - IpAddressState.DnsTable = NULL; - } - - if(Port != NULL) - { - Dereference(Port); - } - - MbbAdapterDeref( Adapter ); -} - - -__callback -VOID -MbbIpInterfaceChangeCallback( - __in PVOID CallerContext, - __in_opt PMIB_IPINTERFACE_ROW Row, - __in MIB_NOTIFICATION_TYPE NotificationType - ) -{ - NET_LUID NetLuid; - PMINIPORT_DRIVER_CONTEXT Driver = (PMINIPORT_DRIVER_CONTEXT)CallerContext; - - switch( NotificationType ) - { - case MibInitialNotification : - { - TraceInfo( WMBCLASS_IP, "[MbbIP] Successfully regsitered for interface change notification" ); - } - break; - - case MibAddInstance : __fallthrough; - case MibDeleteInstance : __fallthrough; - case MibParameterNotification : __fallthrough; - { - ASSERT(Row != NULL); - - __analysis_assume(Row != NULL); - MbbIpQueueIPChange( - Driver, - &Row->InterfaceLuid, - MbbIPChangeTypeHostInterfaceChange, - DEFAULT_NDIS_PORT_NUMBER // indicate on default NDIS port, the adapter may indicate it to the miniport if needed - ); - } - break; - } -} - -__callback -VOID -MbbIpUnicastAddressChangeCallback( - _In_ PVOID CallerContext, - _In_opt_ PMIB_UNICASTIPADDRESS_ROW Row, - _In_ MIB_NOTIFICATION_TYPE NotificationType - ) -{ - PMINIPORT_DRIVER_CONTEXT Driver = (PMINIPORT_DRIVER_CONTEXT)CallerContext; - - if (Row != NULL) - { - MbbIpQueueIPChange( - Driver, - &Row->InterfaceLuid, - MbbIPChangeTypeHostIPChange, - DEFAULT_NDIS_PORT_NUMBER // indicate on default NDIS port, the adapter may indicate it to the miniport if needed - ); - } - else - { - ASSERT(NotificationType == MibInitialNotification); - } -} - -__callback -VOID -MbbIpRouteChangeCallback( - _In_ PVOID CallerContext, - _In_opt_ PMIB_IPFORWARD_ROW2 Row, - _In_ MIB_NOTIFICATION_TYPE NotificationType - ) -{ - PMINIPORT_DRIVER_CONTEXT Driver = (PMINIPORT_DRIVER_CONTEXT)CallerContext; - - if (Row != NULL) - { - if (NotificationType != MibDeleteInstance) - { - MbbIpQueueIPChange( - Driver, - &Row->InterfaceLuid, - MbbIPChangeTypeHostRouteChange, - DEFAULT_NDIS_PORT_NUMBER // indicate on default NDIS port, the adapter may indicate it to the miniport if needed - ); - } - } - else - { - ASSERT(NotificationType == MibInitialNotification); - } -} - -NDIS_STATUS -MbbIpQueueIPChange( - __in PMINIPORT_DRIVER_CONTEXT Driver, - __in PNET_LUID NetLuid, - __in MBB_IP_CHANGE_TYPE IPChangeType, - __in NDIS_PORT_NUMBER PortNumber - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - PMBB_PORT Port = NULL; - - if( (Adapter = MbbDriverFindAdapterByNetLuid( - Driver, - NetLuid - )) != NULL ) - { - Port = MbbWwanTranslatePortNumberToPort( - Adapter, - PortNumber); - - if(Port) - { - MBB_ACQUIRE_PORT_LOCK(Port); - - if( IPChangeType == MbbIPChangeTypeDeviceConfiguration || - Port->ConnectionState.ConnectionUp == TRUE ) - { - // Add reference to the port before queuing it up in the workitem. - // The workitem routine will cleanup the reference - - // Adapter find reference is reused and cleared insider the worker thread - Reference(Port); - if( (NdisStatus = MbbWorkMgrQueueWorkItem( - Driver->IpWorkItemManagerHandle, - Driver, - Adapter, - (PVOID)IPChangeType, - (PVOID)Port, - MbbIpProcessChange - )) != NDIS_STATUS_SUCCESS ) - { - // Remove the reference added for queuing - Dereference(Port); - TraceError( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] FAILED to queue work item to process %!MbbIPChangeType! with status=%!status!.", NetLuid->Value, IPChangeType, NdisStatus ); - } - else - { - TraceInfo( WMBCLASS_IP, "[MbbIP][Luid=0x%I64x] Queuing %!MbbIPChangeType!", NetLuid->Value, IPChangeType ); - } - } - else - { - NdisStatus = NDIS_STATUS_MEDIA_DISCONNECT; - } - - MBB_RELEASE_PORT_LOCK(Port); - } - else - { - NdisStatus = NDIS_STATUS_INVALID_PORT; - } - } - else - { - NdisStatus = NDIS_STATUS_ADAPTER_NOT_FOUND; - } - - if(Port!= NULL) - { - //Remove the reference on the port due to find - Dereference(Port); - } - - // - // If successful, adapter and port would be derefed in MbbIpProcessChange - // - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - if( Adapter != NULL ) - { - MbbAdapterDeref( Adapter ); - } - } - return NdisStatus; -} - -NDIS_STATUS -MbbIpInitialize( - __in PMINIPORT_DRIVER_CONTEXT Driver - ) -{ - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - // - // Work item manager - // - if( (Driver->IpWorkItemManagerHandle = MbbWorkMgrInitialize( MBB_PREALLOC_IP_WORKITEM_COUNT )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbIP] FAILED to initialize work item manager" ); - NtStatus = NDIS_STATUS_FAILURE; - break; - } - // - // Register with IP Helper for IP change notifications. - // - if( (NtStatus = NotifyIpInterfaceChange( - AF_UNSPEC, - MbbIpInterfaceChangeCallback, - Driver, - TRUE, - &Driver->IpInterfaceNotificationHandle - ))!= STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbIP] FAILED to register for Interface change notifications, status=%!STATUS!", NtStatus ); - NtStatus = NDIS_STATUS_FAILURE; - break; - } - - if( (NtStatus = NotifyRouteChange2( - AF_UNSPEC, - MbbIpRouteChangeCallback, - Driver, - TRUE, - &Driver->IpRouteNotificationHandle - )) != NO_ERROR ) - { - TraceError( WMBCLASS_INIT, "[MbbIP] FAILED to register for Route change notifications, status=%!STATUS!", NtStatus ); - NtStatus = NDIS_STATUS_FAILURE; - break; - } - - if( (NtStatus = NotifyUnicastIpAddressChange( - AF_UNSPEC, - MbbIpUnicastAddressChangeCallback, - Driver, - TRUE, - &Driver->IpUnicastAddressNotificationHandle - )) != NO_ERROR ) - { - TraceError( WMBCLASS_INIT, "[MbbIP] FAILED to register for Unicast address change notifications, status=%!STATUS!", NtStatus ); - NtStatus = NDIS_STATUS_FAILURE; - break; - } - } - while( FALSE ); - // - // Cleanup on error - // - if( NtStatus != NDIS_STATUS_SUCCESS ) - { - MbbIpCleanup( Driver ); - } - else - { - TraceInfo( WMBCLASS_INIT, "[MbbIP] IP subsystem initialized" ); - } - - return (NDIS_STATUS)NtStatus; -} - -VOID -MbbIpCleanup( - __in PMINIPORT_DRIVER_CONTEXT Driver - ) -{ - TraceInfo( WMBCLASS_INIT, "[MbbIP] IP subsystem clean up" ); - - if( Driver->IpUnicastAddressNotificationHandle != NULL ) - { - CancelMibChangeNotify2( Driver->IpUnicastAddressNotificationHandle ); - Driver->IpUnicastAddressNotificationHandle = NULL; - } - - if( Driver->IpRouteNotificationHandle != NULL ) - { - CancelMibChangeNotify2( Driver->IpRouteNotificationHandle ); - Driver->IpRouteNotificationHandle = NULL; - } - - if( Driver->IpInterfaceNotificationHandle != NULL ) - { - CancelMibChangeNotify2( Driver->IpInterfaceNotificationHandle ); - Driver->IpInterfaceNotificationHandle = NULL; - } - - if( Driver->IpWorkItemManagerHandle != NULL ) - { - MbbWorkMgrCleanup( Driver->IpWorkItemManagerHandle ); - Driver->IpWorkItemManagerHandle = NULL; - } -} diff --git a/network/wwan/cxwmbclass/IpAddress.h b/network/wwan/cxwmbclass/IpAddress.h deleted file mode 100644 index 2d64e68b1..000000000 --- a/network/wwan/cxwmbclass/IpAddress.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// - -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// -#define MBB_IP_IS_IPV4_AVAILABLE(_X_) (((_X_)->IPv4Flags & MbbIpFlagsAddressAvailable) == MbbIpFlagsAddressAvailable) -#define MBB_IP_IS_IPV6_AVAILABLE(_X_) (((_X_)->IPv6Flags & MbbIpFlagsAddressAvailable) == MbbIpFlagsAddressAvailable) -#define MBB_IP_IS_GWV4_AVAILABLE(_X_) (((_X_)->IPv4Flags & MbbIpFlagsGatewayAvailable) == MbbIpFlagsGatewayAvailable) -#define MBB_IP_IS_GWV6_AVAILABLE(_X_) (((_X_)->IPv6Flags & MbbIpFlagsGatewayAvailable) == MbbIpFlagsGatewayAvailable) -#define MBB_IP_IS_MTUV4_AVAILABLE(_X_) (((_X_)->IPv4Flags & MbbIpFlagsMTUAvailable) == MbbIpFlagsMTUAvailable) -#define MBB_IP_IS_MTUV6_AVAILABLE(_X_) (((_X_)->IPv6Flags & MbbIpFlagsMTUAvailable) == MbbIpFlagsMTUAvailable) -#define MBB_IP_IS_DSV4_AVAILABLE(_X_) (((_X_)->IPv4Flags & MbbIpFlagsDnsServerAvailable) == MbbIpFlagsDnsServerAvailable) -#define MBB_IP_IS_DSV6_AVAILABLE(_X_) (((_X_)->IPv6Flags & MbbIpFlagsDnsServerAvailable) == MbbIpFlagsDnsServerAvailable) - -#define MBB_IP_GET_IPV4TABLE(_X_) (PMBB_IPV4_ADDRESS)(MBB_IP_IS_IPV4_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv4AddressOffset): NULL) -#define MBB_IP_GET_IPV6TABLE(_X_) (PMBB_IPV6_ADDRESS)(MBB_IP_IS_IPV6_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv6AddressOffset): NULL) -#define MBB_IP_GET_GWV4TABLE(_X_) (IN_ADDR*) (MBB_IP_IS_GWV4_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv4GatewayOffset): NULL) -#define MBB_IP_GET_GWV6TABLE(_X_) (IN6_ADDR*)(MBB_IP_IS_GWV6_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv6GatewayOffset): NULL) -#define MBB_IP_GET_DSV4TABLE(_X_) (IN_ADDR*) (MBB_IP_IS_DSV4_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv4DnsServerOffset): NULL) -#define MBB_IP_GET_DSV6TABLE(_X_) (IN6_ADDR*)(MBB_IP_IS_DSV6_AVAILABLE(_X_)? (((PCHAR)(_X_)) + (_X_)->IPv6DnsServerOffset): NULL) - -#define MBB_IP_GET_IPV4COUNT(_X_) (MBB_IP_IS_IPV4_AVAILABLE(_X_)? (_X_)->IPv4AddressCount: 0) -#define MBB_IP_GET_IPV6COUNT(_X_) (MBB_IP_IS_IPV6_AVAILABLE(_X_)? (_X_)->IPv6AddressCount: 0) -#define MBB_IP_GET_DSV4COUNT(_X_) (MBB_IP_IS_DSV4_AVAILABLE(_X_)? (_X_)->IPv4DnsServerCount: 0) -#define MBB_IP_GET_DSV6COUNT(_X_) (MBB_IP_IS_DSV6_AVAILABLE(_X_)? (_X_)->IPv6DnsServerCount: 0) -#define MBB_IP_GET_GWV4COUNT(_X_) (MBB_IP_IS_GWV4_AVAILABLE(_X_)? 1: 0) -#define MBB_IP_GET_GWV6COUNT(_X_) (MBB_IP_IS_GWV6_AVAILABLE(_X_)? 1: 0) - - - -//////////////////////////////////////////////////////////////////////////////// -// -// TYPEDEFS -// -//////////////////////////////////////////////////////////////////////////////// - -typedef enum -{ - MbbIPChangeTypeNone = 0, - MbbIPChangeTypeDeviceConfiguration, - MbbIPChangeTypeDeviceConfigurationChange, - MbbIPChangeTypeHostInterfaceChange, - MbbIPChangeTypeHostIPChange, - MbbIPChangeTypeHostRouteChange, - -} MBB_IP_CHANGE_TYPE; - -//////////////////////////////////////////////////////////////////////////////// -// -// PROTOTYPES -// -//////////////////////////////////////////////////////////////////////////////// -NDIS_STATUS -MbbIpInitialize( - __in PMINIPORT_DRIVER_CONTEXT Driver - ); - -VOID -MbbIpCleanup( - __in PMINIPORT_DRIVER_CONTEXT Driver - ); - -NDIS_STATUS -MbbIpAddressStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); diff --git a/network/wwan/cxwmbclass/LocalWPP.ini b/network/wwan/cxwmbclass/LocalWPP.ini deleted file mode 100644 index eb04ac298..000000000 --- a/network/wwan/cxwmbclass/LocalWPP.ini +++ /dev/null @@ -1,21 +0,0 @@ -CUSTOM_TYPE( MbbStatus, ItemEnum(MBB_STATUS) ); -CUSTOM_TYPE( MbbError, ItemEnum(MBB_ERROR) ); -CUSTOM_TYPE( MbbTimer, ItemEnum(MBB_TIMER_TYPE) ); -CUSTOM_TYPE( MbbMsgType, ItemEnum(MBB_MESSAGE_TYPE) ); -CUSTOM_TYPE( MbbCmdType, ItemEnum(MBB_COMMAND_TYPE) ); -CUSTOM_TYPE( MbbOidState, ItemEnum(MBB_NDIS_OID_STATE) ); -CUSTOM_TYPE( MbbRequestState, ItemEnum(MBB_REQUEST_STATE) ); -CUSTOM_TYPE( MbbRequestEvent, ItemEnum(MBB_REQUEST_EVENT) ); -CUSTOM_TYPE( MbbCellularClass, ItemEnum(MBB_CELLULAR_CLASS) ); -CUSTOM_TYPE( MibNotificationType, ItemEnum(MIB_NOTIFICATION_TYPE) ); -CUSTOM_TYPE( MbbAddressType, ItemEnum(MBB_ADDRESS_TABLE_ID) ); -CUSTOM_TYPE( MbbIPChangeType, ItemEnum(MBB_IP_CHANGE_TYPE) ); -CUSTOM_TYPE( WwanStatus, ItemEnum(wwan_status) ); -CUSTOM_TYPE( UsbCapDeviceType, ItemEnum(USB_CAP_DEVICE_TYPE) ); -CUSTOM_TYPE( MbbNblType, ItemEnum(MBB_NBL_TYPE) ); - -DEFINE_CPLX_TYPE(IPV4ADDR,WPP_LOGIPV4, CONST UCHAR*,ItemIPAddr,"s", _IPV4_, 0); -WPP_FLAGS(-DWPP_LOGIPV4(x) WPP_LOGPAIR( 4, (x))); - -DEFINE_CPLX_TYPE(IPV6ADDR,WPP_LOGIPV6, CONST UCHAR*,ItemIPV6Addr,"s", _IPV6_, 0); -WPP_FLAGS(-DWPP_LOGIPV6(x) WPP_LOGPAIR( 16, (x))); diff --git a/network/wwan/cxwmbclass/MbbFastIOControlPlane.c b/network/wwan/cxwmbclass/MbbFastIOControlPlane.c deleted file mode 100644 index b96abe167..000000000 --- a/network/wwan/cxwmbclass/MbbFastIOControlPlane.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "precomp.h" -#include "MbbFastIOControlPlane.tmh" - -BOOL FastIOPause(_In_ PSTATE_CHANGE_EVENT StateChange) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - if (MbbBusIsFastIO(Adapter->BusHandle)) - { - NdisAcquireSpinLock(&Adapter->Lock); - ASSERT(Adapter->AdapterState.Started); - Adapter->AdapterState.Started = FALSE; - NdisReleaseSpinLock(&Adapter->Lock); - - //MbbBusPause must return NDIS_STATUS_SUCCESS since we only support synchronous FastIOPause now - Status = MbbBusPause(Adapter->BusHandle); - ASSERT(Status == NDIS_STATUS_SUCCESS); - TraceInfo(WMBCLASS_INIT, "FastIO Completing Pause"); - - MbbWriteEvent( - &PAUSE_COMPLETE_EVENT, - NULL, - NULL, - 2, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &Status, - sizeof(Status) - ); - - NdisMPauseComplete(Adapter->MiniportAdapterHandle); - CompleteStateChange( - &Adapter->AdapterState, - StateChange - ); - return TRUE; - } - - return FALSE; -} - -BOOL FastIOReset(_In_ PSTATE_CHANGE_EVENT StateChange) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - if (MbbBusIsFastIO(Adapter->BusHandle)) - { - //FastIOReset must return NDIS_STATUS_SUCCESS since we only support synchronous FastIOReset now - Status = MbbBusReset(Adapter->BusHandle); - ASSERT(Status == NDIS_STATUS_SUCCESS); - TraceInfo(WMBCLASS_INIT, "FastIO Completing Reset"); - - MbbWriteEvent( - &RESET_COMPLETE_EVENT, - NULL, - NULL, - 2, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &Status, - sizeof(Status) - ); - NdisMResetComplete( - Adapter->MiniportAdapterHandle, - StateChange->Reset.PipeStartStatus, - FALSE - ); - CompleteStateChange( - &Adapter->AdapterState, - StateChange - ); - return TRUE; - } - - return FALSE; -} - -BOOL FastIORestart(_In_ PSTATE_CHANGE_EVENT StateChange) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - if (MbbBusIsFastIO(Adapter->BusHandle)) - { - NdisAcquireSpinLock(&Adapter->Lock); - Adapter->AdapterState.Started = TRUE; - NdisReleaseSpinLock(&Adapter->Lock); - - //FastIORestart must return NDIS_STATUS_SUCCESS since we only support synchronous FastIORestart now - Status = MbbBusRestart(Adapter->BusHandle); - ASSERT(Status == NDIS_STATUS_SUCCESS); - TraceInfo(WMBCLASS_INIT, "FastIO Completing Restart"); - - MbbWriteEvent( - &RESTART_COMPLETE_EVENT, - NULL, - NULL, - 2, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &Status, - sizeof(Status) - ); - - NdisMRestartComplete(Adapter->MiniportAdapterHandle, Status); - CompleteStateChange( - &Adapter->AdapterState, - StateChange - ); - return TRUE; - } - - return FALSE; -} \ No newline at end of file diff --git a/network/wwan/cxwmbclass/MbbFastIOControlPlane.h b/network/wwan/cxwmbclass/MbbFastIOControlPlane.h deleted file mode 100644 index 447063491..000000000 --- a/network/wwan/cxwmbclass/MbbFastIOControlPlane.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -BOOL FastIOPause(_In_ PSTATE_CHANGE_EVENT StateChange); -BOOL FastIOReset(_In_ PSTATE_CHANGE_EVENT StateChange); -BOOL FastIORestart(_In_ PSTATE_CHANGE_EVENT StateChange); \ No newline at end of file diff --git a/network/wwan/cxwmbclass/MbbFastIODataPlane.c b/network/wwan/cxwmbclass/MbbFastIODataPlane.c deleted file mode 100644 index d63e1fffb..000000000 --- a/network/wwan/cxwmbclass/MbbFastIODataPlane.c +++ /dev/null @@ -1,263 +0,0 @@ -#include "precomp.h" -#include "MbbFastIODataPlane.tmh" - -VOID -FastIOSendNetBufferListsComplete( - _In_ PVOID MiniportAdapterContext, - _In_ PNET_BUFFER_LIST NetBufferLists, - _In_ ULONG SendCompleteFlags -) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - MBB_NBL_TYPE NblType = MBB_NBL_TYPE_MAXIMUM, LastNblType = MBB_NBL_TYPE_MAXIMUM; - PVOID NblContext; - USHORT NblContextSize; - MBB_REQUEST_HANDLE RequestHandle = NULL; - PNET_BUFFER_LIST NetBufferList = NetBufferLists, NextNetBufferList = NULL; - PNET_BUFFER NetBuffer = NULL; - - ASSERT(Adapter != NULL); - for (NetBufferList = NetBufferList; - NetBufferList != NULL; - NetBufferList = NextNetBufferList) - { - NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NblContext = NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); - NblContextSize = ALIGN(sizeof(MBB_NBL_TYPE), MEMORY_ALLOCATION_ALIGNMENT); - - ASSERT(NblContext != NULL); - - NblType = *((MBB_NBL_TYPE*)NblContext); - NdisFreeNetBufferListContext(NetBufferList, NblContextSize); - - if (LastNblType != MBB_NBL_TYPE_MAXIMUM && LastNblType != NblType) - { - TraceError(WMBCLASS_SEND, "[FastIOSend] Doesn't allow mixed NBL data type in the list, OS will crash. [NblType=%!MbbNblType!] [LastNblType=%!MbbNblType!] [NBL=0x%p]", - NblType, LastNblType, NetBufferList); - ASSERT(FALSE); - return; - } - - LastNblType = NblType; - - switch (NblType) - { - case MBB_NBL_TYPE_IP: - for (NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); - NetBuffer != NULL; - NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer)) - { - InterlockedAdd64(&Adapter->Stats.ifHCOutOctets, NET_BUFFER_DATA_LENGTH(NetBuffer)); - InterlockedIncrement64(&Adapter->GenXmitFramesOk); - InterlockedIncrement64(&Adapter->Stats.ifHCOutUcastPkts); - } - break; - case MBB_NBL_TYPE_DSS: - RequestHandle = (MBB_REQUEST_HANDLE)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList)[0]; - MbbNdisDeviceServiceSessionSendComplete( - RequestHandle, - NetBufferList->Status - ); - - // Free the Nbl & stuff associated with the request - MbbCleanupDssNbl(&Adapter->SendQueue, NetBufferList); - break; - default: - TraceError(WMBCLASS_SEND, "[FastIOSend] Unknown MBB_NBL_TYPE [%!MbbNblType!], OS will crash. [NBL=0x%p]", NblType, NetBufferList); - ASSERT(FALSE); - return; - } - } - - if (NblType == MBB_NBL_TYPE_IP) - { - NdisMSendNetBufferListsComplete(Adapter->MiniportAdapterHandle, NetBufferLists, SendCompleteFlags); - } -} - - -VOID -FastIONdisDeviceServiceSessionReceive( - _In_ PMINIPORT_ADAPTER_CONTEXT AdapterContext, - _In_ PNET_BUFFER_LIST NetBufferList, - _In_ ULONG SessionId, - _In_ ULONG ReceiveFlags -) -{ - PNET_BUFFER NetBuffer; - PMDL Mdl; - PCHAR MdlDataBuffer = NULL; - ULONG MdlDataOffset; - ULONG MdlDataLength; - ULONG datagramLength; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ NdisWwanDssRead = NULL; - PCHAR NdisWwanDssReadBuffer = NULL; - ULONG TotalNdisWwanSize = 0; - ULONG ReturnFlags = (ReceiveFlags & NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL) ? NDIS_RETURN_FLAGS_DISPATCH_LEVEL : 0; - - for (NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); - NetBuffer != NULL; - NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer)) - { - - datagramLength = NET_BUFFER_DATA_LENGTH(NetBuffer); - TotalNdisWwanSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_READ) + datagramLength; - // Allocate memory for the output buffer - if ((NdisWwanDssRead = (PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ)ALLOCATE_NONPAGED_POOL(TotalNdisWwanSize)) == NULL) - { - TraceError(WMBCLASS_RECEIVE, "[Receive][DSS Read] FAILED to allocate for PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ %d bytes", - TotalNdisWwanSize - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - NdisWwanDssRead->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisWwanDssRead->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_READ_1; - NdisWwanDssRead->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SESSION_READ_REVISION_1; - - NdisWwanDssRead->ReadData.uDataSize = datagramLength; - NdisWwanDssRead->ReadData.uSessionID = SessionId; - - // Copy the data. We cannot use the original buffer because it doesnt - // have space for the session Id, etc - Mdl = NET_BUFFER_CURRENT_MDL(NetBuffer); - MdlDataOffset = NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer); - NdisWwanDssReadBuffer = (PCHAR)(NdisWwanDssRead + 1); - - for (; - datagramLength > 0; - datagramLength -= MdlDataLength) - { - MdlDataLength = MmGetMdlByteCount(Mdl) - MdlDataOffset; - if ((MdlDataBuffer = (PCHAR)MmGetSystemAddressForMdlSafe( - Mdl, - NormalPagePriority | MdlMappingNoExecute - )) == NULL) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - MdlDataBuffer = MdlDataBuffer + MdlDataOffset; - MdlDataLength = MIN(datagramLength, MdlDataLength); - - RtlCopyMemory( - NdisWwanDssReadBuffer, - MdlDataBuffer, - MdlDataLength - ); - - NdisWwanDssReadBuffer = NdisWwanDssReadBuffer + MdlDataLength; - Mdl = Mdl->Next; - MdlDataOffset = 0; - } - - // Create the status indication - MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION( - &StatusIndication, - AdapterContext->MiniportAdapterHandle, - NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ - ); - - StatusIndication.StatusBuffer = NdisWwanDssRead; - StatusIndication.StatusBufferSize = TotalNdisWwanSize; - - TraceInfo(WMBCLASS_RECEIVE, "[Receive][DSS Read] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ"); - - MbbUtilNdisMiniportIndicateStatusEx( - AdapterContext, - &StatusIndication - ); - if (NdisWwanDssRead) - { - FREE_POOL(NdisWwanDssRead); - } - } - - NET_BUFFER_LIST_STATUS(NetBufferList) = NdisStatus; - if ((ReceiveFlags & NDIS_RECEIVE_FLAGS_RESOURCES) == 0) - MbbBusReturnNetBufferLists(AdapterContext->BusHandle, NetBufferList, ReturnFlags); -} - -VOID -FastIOIndicateReceiveNetBufferLists( - _In_ PVOID MiniportAdapterContext, - _In_ PNET_BUFFER_LIST NetBufferLists, - _In_ ULONG SessionId, - _In_ ULONG NumberOfNetBufferLists, - _In_ ULONG ReceiveFlags -) -{ - PVOID NblContext = NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter; - SESSIONID_PORTNUMBER_ENTRY SessionIdPortNumberEntry = { 0 }; - MBB_NBL_TYPE NblType; - ULONG ReturnFlags = (ReceiveFlags & NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL) ? NDIS_RETURN_FLAGS_DISPATCH_LEVEL : 0; - PNET_BUFFER_LIST NetBufferList = NetBufferLists, NextNetBufferList = NULL; - PNET_BUFFER NetBuffer = NULL; - - if (NetBufferList == NULL) - { - return; - } - - NblContext = NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - - ASSERT(NblContext != NULL); - ASSERT(Adapter != NULL); - - NblType = *((MBB_NBL_TYPE*)NblContext); - SessionIdPortNumberEntry = Adapter->SessionIdPortTable[SessionId]; - - switch (NblType) - { - case MBB_NBL_TYPE_IP: - if (!SessionIdPortNumberEntry.InUse) - { - //discard - TraceError(WMBCLASS_RECEIVE, "[FastIORecv][NBL=0x%p] FAILED to receive NBL as session id is not in use. [Session Id = %lu]", - NetBufferList, - SessionId - ); - NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_INVALID_PARAMETER; - InterlockedIncrement64(&Adapter->Stats.ifInDiscards); - MbbBusReturnNetBufferLists(Adapter->BusHandle, NetBufferList, ReturnFlags); - return; - } - for (; - NetBufferList != NULL; - NetBufferList = NextNetBufferList) - { - NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NetBufferList->SourceHandle = Adapter->MiniportAdapterHandle; - for (NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList); - NetBuffer != NULL; - NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer)) - { - InterlockedAdd64(&Adapter->Stats.ifHCInOctets, NET_BUFFER_DATA_LENGTH(NetBuffer)); - InterlockedIncrement64(&Adapter->GenRcvFramesOk); - InterlockedIncrement64(&Adapter->Stats.ifHCInUcastPkts); - } - } - NdisMIndicateReceiveNetBufferLists(Adapter->MiniportAdapterHandle, NetBufferLists, SessionIdPortNumberEntry.PortNumber, NumberOfNetBufferLists, ReceiveFlags); - break; - case MBB_NBL_TYPE_DSS: - - for (; - NetBufferList != NULL; - NetBufferList = NextNetBufferList) - { - NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; - FastIONdisDeviceServiceSessionReceive(Adapter, NetBufferList, SessionId, ReceiveFlags); - } - break; - default: - TraceError(WMBCLASS_RECEIVE, "[FastIOReceive] Unknown MBB_NBL_TYPE [%!MbbNblType!], OS will crash. [NBL=0x%p]", NblType, NetBufferLists); - ASSERT(FALSE); - break; - } -} diff --git a/network/wwan/cxwmbclass/MbbFastIODataPlane.h b/network/wwan/cxwmbclass/MbbFastIODataPlane.h deleted file mode 100644 index ae40944a4..000000000 --- a/network/wwan/cxwmbclass/MbbFastIODataPlane.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -_IRQL_requires_max_(DISPATCH_LEVEL) -VOID -FastIONdisDeviceServiceSessionReceive( - _In_ PMINIPORT_ADAPTER_CONTEXT AdapterContext, - _In_ PNET_BUFFER_LIST NetBufferList, - _In_ ULONG SessionId, - _In_ ULONG ReceiveFlags -); - -FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE FastIOSendNetBufferListsComplete; -FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS FastIOIndicateReceiveNetBufferLists; \ No newline at end of file diff --git a/network/wwan/cxwmbclass/MbbLibrary.c b/network/wwan/cxwmbclass/MbbLibrary.c deleted file mode 100644 index 1b575c8de..000000000 --- a/network/wwan/cxwmbclass/MbbLibrary.c +++ /dev/null @@ -1,505 +0,0 @@ -/*************************************************************************** - -Copyright (c) 2010 Microsoft Corporation - -Module Name: - - MbbLibrary.c - -Abstract: - - This files contains the implementation of the pack / unpack and - fragment / reassembly functions provided by the Mbb library. - The class driver Protocol layer calls the libary to convert payloads - to messages as defined in the MBB Class Driver Hardware Interface - document before sending it to the Bus Layer. - -Environment: - - User and kernel mode only - -Notes: - - This library can be used both in user and kernel mode because it does not - to make any memory allocations. - -Revision History: - - 2/7/2010 : created - -Authors: - - TriRoy - -****************************************************************************/ - -//////////////////////////////////////////////////////////////////////////////// -// -// INCLUDES -// -//////////////////////////////////////////////////////////////////////////////// -#include -#include "tmpMbbMessages.h" -#include "MbbLibrary.h" -//#include "MbbLibrary.tmh" - -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// -#define MIN( _X_, _Y_ ) (((_X_) < (_Y_))? (_X_): (_Y_)) - -//////////////////////////////////////////////////////////////////////////////// -// -// FUNCTION PROTOTYPES -// -//////////////////////////////////////////////////////////////////////////////// -ULONG -MbbLibraryGetNextTransactionId( ); - - -//////////////////////////////////////////////////////////////////////////////// -// -// GLOBALS -// -//////////////////////////////////////////////////////////////////////////////// -static ULONG GlobalMbbLibraryTransactionId; - - -//////////////////////////////////////////////////////////////////////////////// -// -// EXPORTED ROUTINES -// -//////////////////////////////////////////////////////////////////////////////// -NTSTATUS -MbbLibForamtBufferAsOpenMessage( - __out_bcount_opt(*BufferLength) PVOID MessageBuffer, - __inout PULONG BufferLength, - __in ULONG MaximumControlTransfer - ) -/* - Description - Formats an input buffer as a MBB Open Message. - - Parameters - __out_opt_bcount(*BufferLength) PVOID MessageBuffer - The input message buffer. This parameter may be NULL - if BufferLength is 0. This parameter should not be NULL - when BufferLength is non-zero. - - __inout PULONG BufferLength - This provides the length of the memory location described by MessageBuffer. - If BufferLength is 0 then the function will return the required buffer length - in this parameter with STATUS_BUFFER_OVERFLOW. On success, the amount of - buffer space used by the routine is returned to the caller in BufferLength. - - __in ULONG MaximumControlTransfer - MaximumControlTransfer field of the Open Message. - - Return Value - STATUS_BUFFER_OVERFLOW - The buffer passed in is not sufficient for formatting the message. - - STATUS_INVALID_PARAMETER - One of the required parameters is missing. - - STATUS_SUCCESS - The input buffer was formatted successfully and the amount of buffer - used is returned in BufferLength. -*/ -{ - NTSTATUS Status = STATUS_SUCCESS; - PMBB_OPEN_MESSAGE Open = (PMBB_OPEN_MESSAGE)(MessageBuffer); - - do - { - if( BufferLength == NULL ) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - else if( *BufferLength != 0 && Open == NULL ) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - // - // If the caller is querying for the size or - // there isnt enough space in the buffer, - // return the size with the correct status. - // - if( *BufferLength < sizeof( MBB_OPEN_MESSAGE ) ) - { - *BufferLength = sizeof( MBB_OPEN_MESSAGE ); - Status = STATUS_BUFFER_OVERFLOW; - break; - } - // - // Sufficient space available. Format the input - // buffer as an open message. - // - Open->MessageHeader.MessageType = MBB_MESSAGE_TYPE_OPEN; - Open->MessageHeader.MessageLength = sizeof( MBB_OPEN_MESSAGE ); - Open->MessageHeader.MessageTransactionId = MbbLibraryGetNextTransactionId( ); - Open->MaximumControlTransfer = MaximumControlTransfer; - // - // Update how much buffer is written. - // - *BufferLength = sizeof( MBB_OPEN_MESSAGE ); - - } while( FALSE ); - - return Status; -} - -NTSTATUS -MbbLibForamtBufferAsCloseMessage( - __out_bcount_opt(*BufferLength) PVOID MessageBuffer, - __inout PULONG BufferLength - ) -/* - Description - Formats an input buffer as a MBB Close Message. - - Parameters - __out_opt_bcount(*BufferLength) PVOID MessageBuffer - The input message buffer. This parameter may be NULL - if BufferLength is 0. This parameter should not be NULL - when BufferLength is non-zero. - - __inout PULONG BufferLength - This provides the length of the memory location described by MessageBuffer. - If BufferLength is 0 then the function will return the required buffer length - in this parameter with STATUS_BUFFER_OVERFLOW. On success, the amount of - buffer space used by the routine is returned to the caller in BufferLength. - - Return Value - STATUS_BUFFER_OVERFLOW - The buffer passed in is not sufficient for formatting the message. - - STATUS_INVALID_PARAMETER - One of the required parameters is missing. - - STATUS_SUCCESS - The input buffer was formatted successfully and the amount of buffer - used is returned in BufferLength. -*/ -{ - NTSTATUS Status = STATUS_SUCCESS; - PMBB_CLOSE_MESSAGE Close = (PMBB_CLOSE_MESSAGE)(MessageBuffer); - - do - { - if( BufferLength == NULL ) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - else if( *BufferLength != 0 && Close == NULL ) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - // - // If the caller is querying for the size or - // there isnt enough space in the buffer, - // return the size with the correct status. - // - if( *BufferLength < sizeof( MBB_CLOSE_MESSAGE ) ) - { - *BufferLength = sizeof( MBB_CLOSE_MESSAGE ); - Status = STATUS_BUFFER_OVERFLOW; - break; - } - // - // Sufficient space available. Format the input - // buffer as an open message. - // - Close->MessageHeader.MessageType = MBB_MESSAGE_TYPE_CLOSE; - Close->MessageHeader.MessageLength = sizeof( MBB_CLOSE_MESSAGE ); - Close->MessageHeader.MessageTransactionId = MbbLibraryGetNextTransactionId( ); - // - // Update how much buffer is written. - // - *BufferLength = sizeof( MBB_CLOSE_MESSAGE ); - - } while( FALSE ); - - return Status; -} - -NTSTATUS -MbbLibFragmentBufferToCommandMessages( - __in PMBB_COMMAND Command, - __in MBB_COMMAND_TYPE CommandType, - __in_bcount_opt(PayloadLength) PCHAR Payload, - __in ULONG PayloadLength, - __inout_opt PULONG TransactionId, - __in ULONG CurrentFragment, - __inout PULONG FragmentBufferCount, - __inout PULONG FragmentLength, - __out_ecount_opt(*FragmentBufferCount) PCHAR* FragmentBuffers - ) -/* - Description - Given the Payload the routine fragments the payload - in to the FragmentBuffers. - - Parameters - __in MBB_COMMAND Command - Command contains the GUID and Cid. - The GUID identifying the service for this message. - The command identifier for the given service. - - __in MBB_COMMAND_TYPE CommandType - Identifies whether the command is a Set or Query. - - __in_bcount(PayloadLength) PCHAR Payload - The Payload is a byte array that needs to be fragmented. - If Payload length is not 0 Payload should be provided. - - __in ULONG PayloadLength - Length of the payload. If there is no Payload for this command - Payload is set to 0. - - __inout PULONG TransactionId - If non-zero then this is the transaction id used for the fragments. - If zero then a new transcation id is generated and returned to the caller. - - __in ULONG CurrentFragment - If non-zero then Fragments are constructed starting this Fragment. - If zero then Fragments are constructed from the beginning. - - __inout ULONG FragmentBufferCount - Number of input fragments i.e. numberof buffers described by - FragmentBuffers array. If the caller is querying for the - number of fragments required then this should be set to 0. - The function will return the number of fragment required - with STATUS_BUFFER_OVERFLOW. - - __in ULONG FragmentLength - Length of each output fragment buffers. All fragment - buffers needs to be of the same size. - The length of the last fragment is returned on STATUS_SUCCESS. - All but the last fragment are of FragmentLength size. - The last fragment can be lesser than the FragmentLength size. - - __out_ecount_opt(*FragmentBufferCount) PCHAR* FragmentBuffers - Array of input fragment buffers. If FragmentCount is 0 - FragmentBuffers can be NULL. If FragmentCount is non 0 - FragmentBuffers should be provided. - - Return Value - STATUS_INVALID_PARAMETER - One of the required parameters is missing. - - STATUS_SUCCESS - The Payload was fragmented successfully in to - FragmentBuffers and the number of fragments used is - returned in FragmentCount. - - STATUS_MORE_PROCESSING_REQUIRED - The complete Payload is not fragmented yet. - This is not a failure code but an indication to the caller that - more calls are needed with more fragment buffers. -*/ -{ - NTSTATUS Status = STATUS_SUCCESS; - PCHAR FragmentPayload; - ULONG BufferIndex; - ULONG FirstFragmentPayloadSize; - ULONG OtherFragmentPayloadSize; - ULONG FragmentPayloadLength; - ULONG TotalFragments; - ULONG PayloadOffset; - PMBB_COMMAND_HEADER CommandHeader; - PMBB_COMMAND_FRAGMENT_HEADER CommandFragmentHeader = NULL; - - do - { - // - // Parameter Validation. - // Check for required parameters. - // - if( (Command == NULL) || (FragmentBufferCount == NULL) || (FragmentLength == 0) || - (PayloadLength != 0 && Payload == NULL) || - (*FragmentBufferCount != 0 && FragmentBuffers == NULL) ) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - // - // The fragments must be atleast the header size. - // - if( *FragmentLength < sizeof(MBB_COMMAND_HEADER) ) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - // - // The size of the payload each fragment can carry. - // - FirstFragmentPayloadSize = *FragmentLength - sizeof(MBB_COMMAND_HEADER); - OtherFragmentPayloadSize = *FragmentLength - sizeof(MBB_COMMAND_FRAGMENT_HEADER); - // - // Calculate the number of fragments required. - // Equation to calculate the fragment count. - // Key : - // CH = CommandHeader = sizeof(MBB_COMMAND_HEADER) - // FH = FragmentHeader = sizeof(MBB_COMMAND_FRAGMENT_HEADER) - // PL = PayloadLength - // FL = FragmentLength - // n = FragmentBufferCount - // - // 1. There is 1 CH and (n-1) FH in n Fragments. - // 2. So the total length of all fragments would be (CH + (n-1)FH + PL). - // 3. To round off the result add (FL-FH-1). - // - // CH + (n-1)FH + PL + (FL-FH-1) / FL = n - // n = ( (CH+PL-1) + (FL-2FH) ) / (FL-FH) - // - TotalFragments = (sizeof(MBB_COMMAND_HEADER) + PayloadLength - 1); - TotalFragments += (*FragmentLength - (2* sizeof(MBB_COMMAND_FRAGMENT_HEADER))); - TotalFragments /= (*FragmentLength - sizeof(MBB_COMMAND_FRAGMENT_HEADER)); - // - // Starting fragment cannot be larger than the total fragments. - // - if( CurrentFragment >= TotalFragments ) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - // - // If the caller is querying for the size - // return the required fragment count to the caller. - // - if( *FragmentBufferCount == 0 ) - { - *FragmentBufferCount = (TotalFragments-CurrentFragment); - Status = STATUS_SUCCESS; - break; - } - // - // Get a transaction Id if not provided. - // Only get a new TransactionId if we are starting fragmentation. - // Do not get a new transaction id while in the middle of fragmentation. - // - if( TransactionId == NULL ) - { - Status = STATUS_INVALID_PARAMETER; - break; - } - if( *TransactionId == 0 ) - { - *TransactionId = MbbLibraryGetNextTransactionId( ); - } - // - // PayloadOffset for Fragment #m is equal to amount of data - // in (m-1) fragments. - // - if( CurrentFragment > 0 ) - { - PayloadOffset = FirstFragmentPayloadSize; - PayloadOffset += (CurrentFragment-1) * OtherFragmentPayloadSize; - } - else - { - PayloadOffset = 0; - } - // - // Format the fragment buffers. - // - for( BufferIndex = 0; - BufferIndex < *FragmentBufferCount; - BufferIndex++ ) - { - // - // If all the data is filled dont create anymore fragments. - // This check is for the case where there are more fragments - // than are required. - // - if( PayloadLength != 0 && - PayloadOffset >= PayloadLength ) - { - break; - } - // - // Common header for all fragments - // - CommandFragmentHeader = (PMBB_COMMAND_FRAGMENT_HEADER)FragmentBuffers[BufferIndex]; - - CommandFragmentHeader->MessageHeader.MessageType = MBB_MESSAGE_TYPE_COMMAND; - CommandFragmentHeader->MessageHeader.MessageTransactionId = *TransactionId; - CommandFragmentHeader->FragmentHeader.CurrentFragment = (USHORT)CurrentFragment; - CommandFragmentHeader->FragmentHeader.TotalFragments = (USHORT)TotalFragments; - // - // Special handling for the first fragment. - // - if( CurrentFragment == 0 ) - { - CommandHeader = (PMBB_COMMAND_HEADER)FragmentBuffers[BufferIndex]; - - MBB_UUID_TO_NET( - &CommandHeader->Command.ServiceId, - &Command->ServiceId - ); - - CommandHeader->Command.CommandId = Command->CommandId; - CommandHeader->CommandType = CommandType; - CommandHeader->InformationBufferLength = PayloadLength; - - FragmentPayload = FragmentBuffers[BufferIndex] + sizeof(MBB_COMMAND_HEADER); - FragmentPayloadLength = MIN( ( PayloadLength - PayloadOffset ), FirstFragmentPayloadSize ); - CommandFragmentHeader->MessageHeader.MessageLength = FragmentPayloadLength + sizeof(MBB_COMMAND_HEADER); - } - else - { - FragmentPayload = FragmentBuffers[BufferIndex] + sizeof(MBB_COMMAND_FRAGMENT_HEADER); - FragmentPayloadLength = MIN( ( PayloadLength - PayloadOffset ), OtherFragmentPayloadSize ); - CommandFragmentHeader->MessageHeader.MessageLength = FragmentPayloadLength + sizeof(MBB_COMMAND_FRAGMENT_HEADER); - } - // - // Copy the actual payload. - // - memcpy( - FragmentPayload, - Payload + PayloadOffset, - FragmentPayloadLength - ); - CurrentFragment++; - PayloadOffset += FragmentPayloadLength; - } - // - // Update how much data is written. - // FragmentLength is the length of ONLY the last fragment. - // - *FragmentBufferCount = BufferIndex; - if (CommandFragmentHeader) - { - *FragmentLength = CommandFragmentHeader->MessageHeader.MessageLength; - } - // - // If the complete Payload is not fragmented indicate it to the caller. - // - if( CurrentFragment < TotalFragments ) - Status = STATUS_MORE_PROCESSING_REQUIRED; - else - Status = STATUS_SUCCESS; - - } while( FALSE ); - - return Status; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// INTERNAL ROUTINES -// -//////////////////////////////////////////////////////////////////////////////// - -ULONG -MbbLibraryGetNextTransactionId( ) -{ - return InterlockedIncrement( &GlobalMbbLibraryTransactionId ); -} diff --git a/network/wwan/cxwmbclass/RequestManager.c b/network/wwan/cxwmbclass/RequestManager.c deleted file mode 100644 index 9f639ecb2..000000000 --- a/network/wwan/cxwmbclass/RequestManager.c +++ /dev/null @@ -1,2176 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -//////////////////////////////////////////////////////////////////////////////// -// -// INCLUDES -// -//////////////////////////////////////////////////////////////////////////////// -#include "precomp.h" -#include "RequestManager.tmh" -#include "WMBClassTelemetry.h" - -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// -#define MBB_REQUEST_TIMEOUT_TOLERANCE_MS 5000 // 5 sec in milliseconds -#define MBB_REQUEST_TIMEOUT_MS 210000 // 210secs in milliseconds -#define MBB_REQUEST_TIMEOUT_100NS ((LONGLONG)MBB_REQUEST_TIMEOUT_MS * 10000) -#define MBB_FRAGMENT_TIMEOUT_TOLERANCE_MS 100 -#define MBB_FRAGMENT_TIMEOUT_MS 1250 // based on MBIM spec -#define MBB_FRAGMENT_TIMEOUT_100NS ((LONGLONG)MBB_FRAGMENT_TIMEOUT_MS * 10000) - - -//////////////////////////////////////////////////////////////////////////////// -// -// TYPEDEFS -// -//////////////////////////////////////////////////////////////////////////////// -typedef -VOID -(*MBB_REQUEST_STATE_TRANSITION)( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ); - - -//////////////////////////////////////////////////////////////////////////////// -// -// DECLARATIONS -// -//////////////////////////////////////////////////////////////////////////////// - -__callback -VOID -MbbReqMgrDrainCompleteCallback( - __in PVOID Context - ); - -// -// ASYNC CONTEXT MANAGEMENT -// - -VOID -MbbReqMgrTimerCallback( - __in PVOID SystemSpecific1, - __in PVOID FunctionContext, - __in PVOID SystemSpecific2, - __in PVOID SystemSpecific3 - ); - -VOID -MbbReqMgrTimerRequestTimeoutCallback( - __in PVOID SystemSpecific1, - __in PVOID FunctionContext, - __in PVOID SystemSpecific2, - __in PVOID SystemSpecific3 - ); - -VOID -MbbReqMgrTimerFragmentTimeoutCallback( - __in PVOID SystemSpecific1, - __in PVOID FunctionContext, - __in PVOID SystemSpecific2, - __in PVOID SystemSpecific3 - ); - -VOID -MbbReqMgrCleanupRequest( - __in __drv_freesMem(Mem) PMBB_REQUEST_CONTEXT Request - ); - -VOID -MbbReqMgrReleaseRequestEvent( - __in PMBB_EVENT_ENTRY EventEntry - ); - -NDIS_OID -MbbNdisGetOid( - __in PNDIS_OID_REQUEST OidRequest - ); - -PMBB_REQUEST_CONTEXT -MbbReqMgrGetRequestByKey( - __in PMBB_REQUEST_MANAGER RequestManager, - __in ULONG ValidKeys, - __in_opt ULONG RequestId, - __in_opt ULONG TransactionId, - __in_opt PNDIS_OID_REQUEST OidRequest - ); - -// -// REQUEST FSM -// - -VOID -MbbReqMgrInitializeFsmTransitionTable( ); - -VOID -MbbReqFsmReady( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ); - -VOID -MbbReqFsmDispatching( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ); - -VOID -MbbReqFsmSendPending( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ); - -VOID -MbbReqFsmSendComplete( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ); - -VOID -MbbReqFsmResponseReceived( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ); - -VOID -MbbReqFsmCancelled( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ); - -VOID -MbbReqFsmInvalid( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ); - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// GLOBALS -// -//////////////////////////////////////////////////////////////////////////////// -MBB_REQUEST_STATE MbbReqFsmTransitionTable[MbbRequestStateMaximum][MbbRequestEventMaximum]; - -MBB_REQUEST_STATE_TRANSITION MbbReqFsmStateHandlerTable[MbbRequestStateMaximum] = -{ - MbbReqFsmReady, - MbbReqFsmDispatching, - MbbReqFsmSendPending, - MbbReqFsmSendComplete, - MbbReqFsmResponseReceived, - MbbReqFsmResponseReceived, - MbbReqFsmCancelled, - MbbReqFsmInvalid -}; - -MBB_TIMER_CONTEXT GlobalTimerContexts[MbbTimerTypeMaximum] = -{ - { - MbbTimerTypeRequest, - 0, - NULL, - MBB_REQUEST_TIMEOUT_MS, - 0, - MBB_REQUEST_TIMEOUT_TOLERANCE_MS, - MbbReqMgrTimerRequestTimeoutCallback, - NULL - }, - { - MbbTimerTypeFragment, - 0, - NULL, - MBB_FRAGMENT_TIMEOUT_MS, - 0, - MBB_FRAGMENT_TIMEOUT_TOLERANCE_MS, - MbbReqMgrTimerFragmentTimeoutCallback, - NULL - } -}; - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// ASYNC REQUEST MANAGER -// -//////////////////////////////////////////////////////////////////////////////// -#define KEY_REQUESTID 1 -#define KEY_TRANSACTIONID 2 -#define KEY_OIDID 4 - -PMBB_REQUEST_CONTEXT -MbbReqMgrGetRequestByKey( - __in PMBB_REQUEST_MANAGER RequestManager, - __in ULONG ValidKeys, - __in_opt ULONG RequestId, - __in_opt ULONG TransactionId, - __in_opt PNDIS_OID_REQUEST OidRequest - ) -{ - PLIST_ENTRY ListEntry; - PMBB_REQUEST_CONTEXT Request = NULL; - - MbbReqMgrLockManager( RequestManager ); - for( ListEntry = RequestManager->AllocatedRequestList.Flink; - ListEntry != &RequestManager->AllocatedRequestList; - ListEntry = ListEntry->Flink ) - { - Request = CONTAINING_RECORD( - ListEntry, - MBB_REQUEST_CONTEXT, - ManagerLink - ); - if( ((ValidKeys & KEY_REQUESTID) && (Request->RequestId == RequestId)) || - ((ValidKeys & KEY_OIDID) && (OidRequest != NULL) && (Request->OidContext.OidRequest == OidRequest)) || - ((ValidKeys & KEY_TRANSACTIONID) && (Request->TransactionId == TransactionId)) ) - { - MbbReqMgrRefRequest( Request ); - break; - } - else - { - Request = NULL; - } - } - MbbReqMgrUnlockManager( RequestManager ); - - return Request; -} - -PMBB_REQUEST_CONTEXT -MbbReqMgrGetRequestById( - __in PMBB_REQUEST_MANAGER RequestManager, - __in ULONG RequestId - ) -{ - return MbbReqMgrGetRequestByKey( - RequestManager, - KEY_REQUESTID, - RequestId, - 0, - NULL - ); -} - -PMBB_REQUEST_CONTEXT -MbbReqMgrGetRequestByTransactionId( - __in PMBB_REQUEST_MANAGER RequestManager, - __in ULONG TransactionId - ) -{ - return MbbReqMgrGetRequestByKey( - RequestManager, - KEY_TRANSACTIONID, - 0, - TransactionId, - NULL - ); -} - -PMBB_REQUEST_CONTEXT -MbbReqMgrGetRequestByOidRequestId( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PNDIS_OID_REQUEST OidRequestId - ) -{ - return MbbReqMgrGetRequestByKey( - RequestManager, - KEY_OIDID, - 0, - 0, - OidRequestId - ); -} - -MBB_PROTOCOL_HANDLE -MbbReqMgrGetAdapterHandle( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - return (MBB_PROTOCOL_HANDLE)(Request->RequestManager->AdapterContext); -} - -BOOLEAN -MbbReqMgrIsInternalRequest( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - if( Request->OidContext.OidRequest == NULL && - MbbReqMgrIsUnsolicitedIndication( Request ) == FALSE ) - return TRUE; - else - return FALSE; -} - -VOID -MbbReqMgrSetUnsolicitedIndication( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - Request->HandlerContext.IsIndication = TRUE; -} - -BOOLEAN -MbbReqMgrIsUnsolicitedIndication( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - return Request->HandlerContext.IsIndication; -} - -_Requires_lock_not_held_(&(Request->RequestManager->Spinlock)) -VOID -MbbReqMgrGetState( - __in PMBB_REQUEST_CONTEXT Request, - __inout MBB_REQUEST_STATE *pCurrentState, - __inout MBB_REQUEST_STATE *pLastState - ) -{ - - PMBB_REQUEST_MANAGER RequestManager = NULL; - - RequestManager = Request->RequestManager; - - if(RequestManager) - { - MbbReqMgrLockManager( RequestManager ); - - if(pCurrentState) - { - *pCurrentState = Request->State; - } - - if(pLastState) - { - *pLastState = Request->LastState; - } - - MbbReqMgrUnlockManager( RequestManager ); - } -} - -BOOLEAN -MbbReqMgrIsSetOid( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - BOOLEAN IsOidRequest = ! MbbReqMgrIsInternalRequest( Request ); - - return ( IsOidRequest && Request->OidContext.IsSetOid ); -} - -MBB_NDIS_OID_STATE -MbbReqMgrGetSetOidState( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_NDIS_OID_STATE OidState - ) -/*++ -Description - Sets the new oid state and returns the old state. - Oid state is a enum so a interlocked exchange as a long is fine. - -Return - Old Oid state. ---*/ -{ - LONG Long; - - Long = InterlockedExchange( - (volatile LONG*)(&Request->OidContext.OidState), - OidState - ); - - return (MBB_NDIS_OID_STATE)Long; -} - -_Acquires_lock_( RequestManager->Spinlock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, RequestManager ) -VOID -MbbReqMgrLockManager( - __in PMBB_REQUEST_MANAGER RequestManager - ) -{ - NdisAcquireSpinLock( &RequestManager->Spinlock ); -} - -_Releases_lock_( RequestManager->Spinlock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, RequestManager ) -VOID -MbbReqMgrUnlockManager( - __in PMBB_REQUEST_MANAGER RequestManager - ) -{ - NdisReleaseSpinLock( &RequestManager->Spinlock ); -} - -VOID -MbbReqMgrIntProcessNextRequestWorker( - __in PVOID Context1, - __in PVOID Context2, - __in PVOID Context3, - __in PVOID Context4 - ) -{ - PMBB_REQUEST_CONTEXT NextRequest = NULL; - PMBB_REQUEST_MANAGER RequestManager = (PMBB_REQUEST_MANAGER)Context1; - - MbbReqMgrLockManager( RequestManager ); - if( ! IsListEmpty( &(RequestManager->PendingRequestQueue) ) ) - { - NextRequest = CONTAINING_RECORD( - RemoveHeadList( &(RequestManager->PendingRequestQueue) ), - MBB_REQUEST_CONTEXT, - ReqMgrContext.QueueLink - ); - InitializeListHead( &NextRequest->ReqMgrContext.QueueLink ); - NextRequest->ReqMgrContext.IsQueued = FALSE; - } - RequestManager->CurrentRequest = NextRequest; - MbbReqMgrUnlockManager( RequestManager ); - - if( NextRequest != NULL ) - { - MbbReqMgrQueueEvent( - RequestManager, - NextRequest, - MbbRequestEventStart, - NULL, - 0 - ); - // - // Ref taken when queuing the request in the PendingRequestQueue - // - MbbReqMgrDerefRequest( NextRequest ); - } -} - -VOID -MbbReqMgrIntProcessNextRequest( - __in PMBB_REQUEST_MANAGER RequestManager - ) -/*++ -Description - If a request is pending to be dispatched - this routine will queue a work item to start - the request on another thread. If there are - no more requests it returns enabling the - request manager serializer to process the - next request. ---*/ -{ - NDIS_STATUS NdisStatus; - - MbbReqMgrLockManager( RequestManager ); - if( IsListEmpty( &(RequestManager->PendingRequestQueue) ) ) - { - RequestManager->CurrentRequest = NULL; - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] No more requests, idling queue. QueueStatus[Current=0x%p %s]", - RequestManager->CurrentRequest, - IsListEmpty( &RequestManager->PendingRequestQueue )? "EMPTY": "NON-EMPTY" - ); - } - else - { - if( (NdisStatus = MbbWorkMgrQueueWorkItem( - RequestManager->WorkItemManagerHandle, - RequestManager, - NULL, - NULL, - NULL, - MbbReqMgrIntProcessNextRequestWorker - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to queue work item to process request with status=%!status!. Requests may hang", NdisStatus ); - } - } - MbbReqMgrUnlockManager( RequestManager ); -} - -VOID -MbbReqMgrTransition( - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - PMBB_REQUEST_CONTEXT Request; - PMBB_REQUEST_MANAGER RequestManager; - MBB_REQUEST_STATE OldState = {0}; - MBB_REQUEST_STATE NewState = MbbRequestStateMaximum; - - Request = EventEntry->Request; - RequestManager = Request->RequestManager; - - MbbReqMgrLockManager( RequestManager ); - if( (Request->State < MbbRequestStateMaximum && Request->State >= 0) && - (EventEntry->Event < MbbRequestEventMaximum && EventEntry->Event >= 0) ) - { - NewState = MbbReqFsmTransitionTable[Request->State][EventEntry->Event]; - TraceInfo( WMBCLASS_REQUEST_FSM, "[ReqFsm][ReqId=0x%04x] Transition: %!MbbRequestState! -> %!MbbRequestState! event=%!MbbRequestEvent!", - Request->RequestId, Request->State, NewState, EventEntry->Event - ); - OldState = Request->State; - Request->State = NewState; - Request->LastState = OldState; - Request->LastEvent = EventEntry->Event; - } - MbbReqMgrUnlockManager( RequestManager ); - - if( NewState < MbbRequestStateMaximum ) - { - MbbReqFsmStateHandlerTable[NewState]( - Request, - OldState, - EventEntry - ); - } -} - -FORCEINLINE -BOOLEAN -MbbReqMgrRef( - __in PMBB_REQUEST_MANAGER RequestManager - ) -{ - return DrainAddRef( &RequestManager->DrainObject ); -} - -FORCEINLINE -VOID -MbbReqMgrDeref( - __in PMBB_REQUEST_MANAGER RequestManager - ) -{ - DrainRelease( &RequestManager->DrainObject ); -} - -NDIS_STATUS -MbbReqMgrInitialize( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - ULONG BufferLength; - NTSTATUS NtStatus; - NDIS_STATUS NdisStatus = NDIS_STATUS_RESOURCES; - MBB_ALLOC_FLAGS Flags = { 0 }; - NDIS_TIMER_CHARACTERISTICS TimerCharacteristics; - - do - { - InitializeListHead( &(RequestManager->AllocatedRequestList) ); - - InitializeListHead( &(RequestManager->PendingRequestQueue) ); - - NdisAllocateSpinLock( &(RequestManager->Spinlock) ); - - KeInitializeEvent( - &RequestManager->DrainCompleteEvent, - NotificationEvent, - FALSE - ); - - InitDrainObject( - &RequestManager->DrainObject, - MbbReqMgrDrainCompleteCallback, - &RequestManager->DrainCompleteEvent - ); - - DrainComplete( &RequestManager->DrainObject ); - - MbbReqMgrInitializeFsmTransitionTable( ); - - KeInitializeEvent( - &(RequestManager->NoAllocatedRequestEvent), - NotificationEvent, - TRUE - ); - RequestManager->AdapterContext = Adapter; - // - // Work item manager - // - if( (RequestManager->WorkItemManagerHandle = MbbWorkMgrInitialize( MBB_PREALLOC_WORKITEM_COUNT )) == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to initialize work item manager" ); - break; - } - // - // Allocation manager for requests. - // - if( (RequestManager->RequestAllocatorHandle = MbbAllocMgrInitialize( - sizeof(MBB_REQUEST_CONTEXT), - MBB_PREALLOC_REQUEST_COUNT, - MbbPoolTagRequest, - Flags - )) == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to initialize request allocator" ); - break; - } - // - // Allocate fragment buffers - // - RequestManager->Fragmentation.ControlFragmentLength = Adapter->BusParams.FragmentSize; - RequestManager->Fragmentation.BulkFragmentLength = MBB_FRAGMENATION_BULK_BUFFER_LENGTH; - - BufferLength = MAX( - RequestManager->Fragmentation.ControlFragmentLength, - RequestManager->Fragmentation.BulkFragmentLength - ); - if( (RequestManager->Fragmentation.BufferManager = MbbBufMgrInitialize( - MBB_PREALLOC_FRAGMENATION_BUFFER_COUNT, - BufferLength - )) == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate %d fragment buffers of size=%dBytes", - MBB_PREALLOC_FRAGMENATION_BUFFER_COUNT, - BufferLength - ); - break; - } - // - // Allocate default response buffer. - // - RequestManager->Fragmentation.Reassemble.FragmentBufferLength = Adapter->BusParams.FragmentSize; - if( (RequestManager->Fragmentation.Reassemble.FragmentBuffer = ALLOCATE_NONPAGED_POOL( RequestManager->Fragmentation.Reassemble.FragmentBufferLength )) == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate default fragment buffer of size=%dBytes", RequestManager->Fragmentation.Reassemble.FragmentBufferLength ); - break; - } - // - // Allocate default reassemble buffer. - // - RequestManager->Fragmentation.Reassemble.BufferLength = MBB_REASSEMBLE_BUFFER_LENGTH; - if( (RequestManager->Fragmentation.Reassemble.Buffer = ALLOCATE_NONPAGED_POOL( RequestManager->Fragmentation.Reassemble.BufferLength )) == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate default fragment buffer of size=%dBytes", RequestManager->Fragmentation.Reassemble.BufferLength ); - break; - } - // - // Allocate default timer. - // - if( (NdisStatus = MbbReqMgrTimerInitialize( - RequestManager, - MbbTimerTypeRequest - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate %!MbbTimer! with status=%!status!", MbbTimerTypeRequest, NdisStatus ); - break; - } - - if( (NdisStatus = MbbReqMgrTimerInitialize( - RequestManager, - MbbTimerTypeFragment - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate %!MbbTimer! with status=%!status!", MbbTimerTypeFragment, NdisStatus ); - break; - } - - RequestManager->IsClosed = FALSE; - - NdisStatus = NDIS_STATUS_SUCCESS; - - } while( FALSE ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - MbbReqMgrTimerCleanup( RequestManager, MbbTimerTypeFragment ); - MbbReqMgrTimerCleanup( RequestManager, MbbTimerTypeRequest ); - - if( RequestManager->Fragmentation.Reassemble.Buffer != NULL ) - { - FREE_POOL( RequestManager->Fragmentation.Reassemble.Buffer ); - } - if( RequestManager->Fragmentation.Reassemble.FragmentBuffer != NULL ) - { - FREE_POOL( RequestManager->Fragmentation.Reassemble.FragmentBuffer ); - } - if( RequestManager->Fragmentation.BufferManager != NULL ) - { - MbbBufMgrCleanup( RequestManager->Fragmentation.BufferManager ); - RequestManager->Fragmentation.BufferManager = NULL; - } - if( RequestManager->RequestAllocatorHandle != NULL ) - { - MbbAllocMgrCleanup( RequestManager->RequestAllocatorHandle ); - RequestManager->RequestAllocatorHandle = NULL; - } - if( RequestManager->WorkItemManagerHandle != NULL ) - { - MbbWorkMgrCleanup( RequestManager->WorkItemManagerHandle ); - RequestManager->WorkItemManagerHandle = NULL; - } - } - else - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] Initialization complete" ); - } - return NdisStatus; -} - -__callback -VOID -MbbReqMgrDrainCompleteCallback( - __in PVOID Context - ) -{ - PKEVENT DrainCompleteEvent = (PKEVENT)Context; - - KeSetEvent( DrainCompleteEvent, IO_NO_INCREMENT, FALSE ); -} - -VOID -MbbReqMgrCleanup( - __in PMBB_REQUEST_MANAGER RequestManager - ) -{ - NTSTATUS NtStatus; - BOOLEAN SignalThread = FALSE; - BOOLEAN WaitForTimers = FALSE; - PVOID EventThreadObject; - - // - // Synchronize draining with new request creation. - // Once draining is started inside the lock - // it is guaranteed that no more requests would be created. - // - MbbReqMgrLockManager( RequestManager ); - KeResetEvent( &RequestManager->DrainCompleteEvent ); - StartDrain( &RequestManager->DrainObject ); - MbbReqMgrUnlockManager( RequestManager ); - // - // Cancel all pending requests by queuing cancel event. - // - MbbReqMgrCancelRequests( RequestManager, FALSE); - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Cleanup] Waiting for pending requests to complete" ); - // - // Wait for pending operations to complete. - // - KeWaitForSingleObject( - &(RequestManager->NoAllocatedRequestEvent), - Executive, - KernelMode, - FALSE, - NULL - ); - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Cleanup] Waiting for references to go down" ); - // - // Drop the reference that was taken to pass in the request manager. - // - MbbReqMgrDeref( RequestManager ); - // - // Wait for all references on request manager to go down. - // This guarantees that no thread is accessign the request - // manager while its wiped out here. - // - KeWaitForSingleObject( - &(RequestManager->DrainCompleteEvent), - Executive, - KernelMode, - FALSE, - NULL - ); - // - // Wait for the lock before cleaning up so that the - // thread that set the event has a change to release the lock. - // - MbbReqMgrLockManager( RequestManager ); - // - // Ensure all lists are empty - // - ASSERT( IsListEmpty( &(RequestManager->AllocatedRequestList) ) ); - ASSERT( IsListEmpty( &(RequestManager->PendingRequestQueue) ) ); - - MbbReqMgrUnlockManager( RequestManager ); - // - // Cancel timers - // - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Cleanup] Cancelling timers" ); - MbbReqMgrTimerCleanup( RequestManager, MbbTimerTypeFragment ); - MbbReqMgrTimerCleanup( RequestManager, MbbTimerTypeRequest ); - // - // Free resources, if allocated. - // - if( RequestManager->Fragmentation.Reassemble.Buffer != NULL ) - { - FREE_POOL( RequestManager->Fragmentation.Reassemble.Buffer ); - } - if( RequestManager->Fragmentation.Reassemble.FragmentBuffer != NULL ) - { - FREE_POOL( RequestManager->Fragmentation.Reassemble.FragmentBuffer ); - } - if( RequestManager->Fragmentation.BufferManager != NULL ) - { - MbbBufMgrCleanup( RequestManager->Fragmentation.BufferManager ); - RequestManager->Fragmentation.BufferManager = NULL; - } - if( RequestManager->RequestAllocatorHandle != NULL ) - { - MbbAllocMgrCleanup( RequestManager->RequestAllocatorHandle ); - RequestManager->RequestAllocatorHandle = NULL; - } - if( RequestManager->WorkItemManagerHandle != NULL ) - { - MbbWorkMgrCleanup( RequestManager->WorkItemManagerHandle ); - RequestManager->WorkItemManagerHandle = NULL; - } - // - // Always allocated - // - NdisFreeSpinLock( &(RequestManager->Spinlock) ); - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Cleanup] Cleanup complete" ); -} - -/// -/// Function to Cancel all the Requests in the Request Manager -/// -/// Pointer to the Request Manager -/// Flag to indicate that the Request Manager is Closed. Set only in the Surprise Removal Path -VOID -MbbReqMgrCancelRequests( - __in PMBB_REQUEST_MANAGER RequestManager, - __in BOOLEAN IsClosed - ) -{ - LIST_ENTRY TempList; - PLIST_ENTRY ListEntry; - PMBB_REQUEST_CONTEXT Request; - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] Cancelling pending requests" ); - - InitializeListHead( &TempList ); - - MbbReqMgrLockManager( RequestManager ); - RequestManager->IsClosed = IsClosed; - for( ListEntry = RequestManager->AllocatedRequestList.Flink; - ListEntry != &RequestManager->AllocatedRequestList; - ListEntry = ListEntry->Flink ) - { - Request = CONTAINING_RECORD( ListEntry, MBB_REQUEST_CONTEXT, ManagerLink ); - MbbReqMgrRefRequest( Request ); - InsertTailList( &TempList, &Request->ReqMgrContext.CancelLink ); - } - MbbReqMgrUnlockManager( RequestManager ); - - while (!IsListEmpty(&TempList)) - { - // Get the Entry of the list - ListEntry = RemoveHeadList(&TempList); - Request = CONTAINING_RECORD(ListEntry, MBB_REQUEST_CONTEXT, ReqMgrContext.CancelLink); - - MbbReqMgrQueueEvent( - RequestManager, - Request, - MbbRequestEventCancel, - (PVOID)(NDIS_STATUS_REQUEST_ABORTED), - 0 - ); - MbbReqMgrDerefRequest(Request); - } -} - -/// -/// Function to Create the Request for the Request Manager off the OID Request that came through -/// -/// Request Manager -/// The oid request. -/// Length of the response buffer. -/// out parameter that has the NDIS status filled in -/// newly created request otherwise null -__checkReturn -__drv_aliasesMem -__drv_allocatesMem(Mem) -PMBB_REQUEST_CONTEXT -MbbReqMgrCreateRequest( - __in PMBB_REQUEST_MANAGER RequestManager, - __in_opt PNDIS_OID_REQUEST OidRequest, - __in ULONG ResponseBufferLength, - __out PNDIS_STATUS NdisStatus - ) -{ - PMBB_REQUEST_CONTEXT Request = NULL; - NDIS_TIMER_CHARACTERISTICS TimerCharacteristics; - - do - { - *NdisStatus = NDIS_STATUS_RESOURCES; - - if( (Request = (PMBB_REQUEST_CONTEXT) MbbAllocMgrAllocate( RequestManager->RequestAllocatorHandle )) == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to allocate request context" ); - break; - } - RtlZeroMemory( Request, sizeof(MBB_REQUEST_CONTEXT) ); - Request->OidContext.OidRequest = OidRequest; - if (OidRequest != NULL) - { - Request->OidContext.OidRequestId = OidRequest->RequestId; - Request->OidContext.OidRequestHandle = OidRequest->RequestHandle; - } - InitializeListHead( &(Request->ManagerLink) ); - InitializeListHead( &(Request->ReqMgrContext.QueueLink) ); - InitializeListHead( &(Request->ReqMgrContext.CancelLink) ); - InitializeListHead( &(Request->ReqMgrContext.TimeoutLink) ); - // - // Insert the request in allocated list for tracking. - // Take the reference on the request manager since a pointer - // is stored in the request. A successful reference also - // guarantees that the request manager is not draining. - // - MbbReqMgrLockManager( RequestManager ); - - // If the Request Manager is Closed, then no point in inserting the requests in to the Queue - // Currently this code path will get hit for Surprise Removal - if (RequestManager->IsClosed) - { - TraceError(WMBCLASS_REQUEST_MANAGER, "[ReqMgr] Not Queuing up the Requests as the Request Manager is Closed"); - *NdisStatus = NDIS_STATUS_NOT_ACCEPTED; - MbbReqMgrUnlockManager(RequestManager); - break; - } - - if( MbbReqMgrRef( RequestManager ) ) - { - Request->RequestId = (RequestManager->RequestIdCounter)++; - Request->RequestManager = RequestManager; - KeResetEvent( &(RequestManager->NoAllocatedRequestEvent) ); - InsertTailList( - &RequestManager->AllocatedRequestList, - &Request->ManagerLink - ); - } - - else - { - TraceError(WMBCLASS_REQUEST_MANAGER, "[ReqMgr] FAILED to reference the RequestManager for creating a RequestContext"); - *NdisStatus = NDIS_STATUS_RESOURCES; - MbbReqMgrUnlockManager(RequestManager); - break; - } - - KeInitializeEvent( - &Request->WaitEvent, - NotificationEvent, - FALSE - ); - - if (OidRequest != NULL) - { - if (OidRequest->RequestType == NdisRequestSetInformation) - { - Request->OidContext.IsSetOid = TRUE; - } - TraceInfo(WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Request created for %s [RequestContext=0x%p OidRequest=0x%p] SET=%!BOOLEAN!", - Request->RequestId, GetOidName(MbbNdisGetOid(OidRequest)), Request, OidRequest, MbbReqMgrIsSetOid(Request) - ); - } - else - { - TraceInfo(WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Internal Request created [RequestContext=0x%p]", - Request->RequestId, Request - ); - } - Request->ReferenceCount = 1; - - MbbReqMgrUnlockManager( RequestManager ); - - *NdisStatus = NDIS_STATUS_SUCCESS; - - } while( FALSE ); - - if( Request != NULL ) - { - if( *NdisStatus != NDIS_STATUS_SUCCESS) - { - if(Request->RequestManager) - { - MbbReqMgrDeref(Request->RequestManager); - } - MbbAllocMgrFree( Request ); - - Request = NULL; - } - } - - return Request; -} - -#pragma warning(push) -#pragma warning(disable:__WARNING_MEMORY_LEAK) -VOID -MbbReqMgrCleanupRequest( - __in __drv_freesMem(Mem) PMBB_REQUEST_CONTEXT Request - ) -{ - PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; - - if(!RequestManager) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] MbbReqMgrCleanupRequest: RequestManager is NULL.", Request->RequestId ); - ASSERT(FALSE); - return; - } - - ASSERT( Request->ReferenceCount == 0 ); - - // - // If the request allocation failed directly free the request memory. - // - - MbbReqMgrLockManager( RequestManager ); - - if( IsListEmpty( &(Request->ManagerLink) ) ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Request double free attempt.", Request->RequestId ); - ASSERT(FALSE); - MbbReqMgrUnlockManager( RequestManager ); - return; - } - else - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Destroying request.", Request->RequestId ); - - RemoveEntryList( &(Request->ManagerLink) ); - - // Clear the manager link flink and blink so that if IsListEmpty - // check is called again on the same link, it returns empty. - InitializeListHead( &(Request->ManagerLink) ); - - if( IsListEmpty( &(RequestManager->AllocatedRequestList) ) ) - { - // - // The event can trigger the cleanup code which - // could cleanup the lock making it invalid. But - // the cleanup code waits for the lock before cleaning - // the request manager. So the lock is guaranteed to - // be valid until we release it. - // - KeSetEvent( - &(RequestManager->NoAllocatedRequestEvent), - IO_NO_INCREMENT, - FALSE - ); - // - // Disarm the request timeout timer if its still active. - // - MbbReqMgrTimerDisarm( - RequestManager, - MbbTimerTypeRequest, - MBB_LOCK_TAKEN - ); - } - - MbbReqMgrUnlockManager( RequestManager ); - MbbAllocMgrFree( Request ); - - // - // Do not touch the request manager beyond this point. - // - - if( RequestManager ) - MbbReqMgrDeref( RequestManager ); - } -} -#pragma warning(pop) - -VOID -MbbNdisIndicateStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -VOID -MbbReqMgrDestroyRequest( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - // - // Drop the initial reference taken during initialization. - // - MbbReqMgrDerefRequest( Request ); -} - -VOID -MbbReqMgrRefRequest( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - LONG ref = InterlockedIncrement( &Request->ReferenceCount ); - - // When the request is created its initial ref count is 1. Hence whenever - // the request is going to be ref'd the ref count should be > 1. - // This assert will catch the ref count to be going from 0 to 1, meaning - // that some thread is trying to use a freed request. - - ASSERT(ref > 1); -} - -VOID -MbbReqMgrDerefRequest( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - LONG ref = InterlockedDecrement( &Request->ReferenceCount ); - - // Catches negative dereferences - ASSERT(ref >= 0); - - if( ref == 0 ) - { - MbbReqMgrCleanupRequest( Request ); - } -} - -NDIS_STATUS -MbbReqMgrDispatchRequest( - __in PMBB_REQUEST_CONTEXT Request, - __in BOOLEAN IsSerialized, - __in MBB_REQUEST_DISPATCH_ROUTINE DispatchRoutine, - __in MBB_REQUEST_COMPLETION_CALLBACK CompletionCallback, - __in_opt MBB_REQUEST_RESPONSE_HANDLER ResponseHandler - ) -/*++ - Return Value - NDIS_STATUS_PENDING - Request was queued for later dispatch. - NDIS_STATUS_SUCCESS - Request was dispatched synchronously and successfully complete. - Ndis failure codes - Request was either not dispatched or completed with failure. ---*/ -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - LARGE_INTEGER DueTime; - - do - { - if( Request == NULL || DispatchRoutine == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] Invalid parameters, Request=0x%p DispatchRoutine=0x%p", Request, DispatchRoutine ); - NdisStatus = NDIS_STATUS_INVALID_PARAMETER; - break; - } - - Request->ReqMgrContext.IsSerialized = IsSerialized; - Request->ReqMgrContext.DispatchRoutine = DispatchRoutine; - Request->ReqMgrContext.CompletionCallback = CompletionCallback; - Request->ReqMgrContext.ResponseHandler = ResponseHandler; - Request->ReqMgrContext.IsQueued = FALSE; - - NdisGetSystemUpTimeEx( (PLARGE_INTEGER)(&Request->DispatchTime) ); - - MbbReqMgrQueueEvent( - Request->RequestManager, - Request, - MbbRequestEventDispatch, - NULL, - 0 - ); - NdisStatus = NDIS_STATUS_PENDING; - - } while( FALSE ); - - return NdisStatus; -} - -VOID -MbbReqMgrInitializeFsmTransitionTable( ) -{ - ULONG StateIndex; - ULONG EventIndex; - - for( StateIndex = 0; StateIndex < MbbRequestStateMaximum; StateIndex++ ) - { - for( EventIndex = 0; EventIndex < MbbRequestEventMaximum; EventIndex++ ) - { - MbbReqFsmTransitionTable[StateIndex][EventIndex] = MbbRequestStateInvalid; - } - } - // - // Valid State transitions. - // - MbbReqFsmTransitionTable[MbbRequestStateReady][MbbRequestEventDispatch] = MbbRequestStateDispatching; - MbbReqFsmTransitionTable[MbbRequestStateReady][MbbRequestEventCancel] = MbbRequestStateCancelled; - - MbbReqFsmTransitionTable[MbbRequestStateDispatching][MbbRequestEventStart] = MbbRequestStateSendPending; - MbbReqFsmTransitionTable[MbbRequestStateDispatching][MbbRequestEventCancel] = MbbRequestStateCancelled; - - MbbReqFsmTransitionTable[MbbRequestStateSendPending][MbbRequestEventCancel] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateSendPending][MbbRequestEventSendComplete] = MbbRequestStateSendComplete; - MbbReqFsmTransitionTable[MbbRequestStateSendPending][MbbRequestEventResponseReceived] = MbbRequestStateResponseReceived; - MbbReqFsmTransitionTable[MbbRequestStateSendPending][MbbRequestEventResponseReceivedMoreData] = MbbRequestStateResponseReceivedMoreData; - - MbbReqFsmTransitionTable[MbbRequestStateSendComplete][MbbRequestEventCancel] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateSendComplete][MbbRequestEventResponseReceived] = MbbRequestStateResponseReceived; - MbbReqFsmTransitionTable[MbbRequestStateSendComplete][MbbRequestEventResponseReceivedMoreData] = MbbRequestStateResponseReceivedMoreData; - - MbbReqFsmTransitionTable[MbbRequestStateResponseReceived][MbbRequestEventCancel] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateResponseReceived][MbbRequestEventSendComplete] = MbbRequestStateResponseReceived; - - MbbReqFsmTransitionTable[MbbRequestStateResponseReceivedMoreData][MbbRequestEventCancel] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateResponseReceivedMoreData][MbbRequestEventSendComplete] = MbbRequestStateResponseReceivedMoreData; - MbbReqFsmTransitionTable[MbbRequestStateResponseReceivedMoreData][MbbRequestEventResponseReceived] = MbbRequestStateResponseReceived; - MbbReqFsmTransitionTable[MbbRequestStateResponseReceivedMoreData][MbbRequestEventResponseReceivedMoreData] = MbbRequestStateResponseReceivedMoreData; - - MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventDispatch] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventStart] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventCancel] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventSendComplete] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventResponseReceived] = MbbRequestStateCancelled; - MbbReqFsmTransitionTable[MbbRequestStateCancelled][MbbRequestEventResponseReceivedMoreData] = MbbRequestStateCancelled; -} - -VOID -MbbReqMgrReleaseRequestEvent( - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - PMBB_REQUEST_CONTEXT Request = EventEntry->Request; - PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; - - // - // If this is a pre-allocated event hold the manager - // lock to synchronize access. If allocated from pool - // no one else can access it. - // - if( EventEntry->EventFlags.Allocated == TRUE ) - { - FREE_POOL( EventEntry ); - } - else - { - MbbReqMgrLockManager( RequestManager ); - EventEntry->EventFlags.InUse = FALSE; - MbbReqMgrUnlockManager( RequestManager ); - } - MbbReqMgrDerefRequest( Request ); -} - -_Requires_lock_not_held_( RequestManager->Spinlock ) -VOID -MbbReqMgrQueueEvent( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_EVENT Event, - __in_opt PVOID EventData, - __in ULONG EventDataLength - ) -{ - BOOLEAN AllocateEvent = FALSE; - PMBB_EVENT_ENTRY EventEntry; - - // - // Try to use the pre-allocated events for forward progress. - // Some events can occur multiple times at the same instance like ResponseReceived. - // For these events try to allocate a new entry. - // - MbbReqMgrLockManager( RequestManager ); - EventEntry = &(Request->EventEntries[Event]); - if( EventEntry->EventFlags.InUse == TRUE ) - AllocateEvent = TRUE; - else - EventEntry->EventFlags.InUse = TRUE; - MbbReqMgrUnlockManager( RequestManager ); - - if( AllocateEvent ) - { -#pragma prefast(suppress: __WARNING_MEMORY_LEAK, "Released by MbbReqMgrReleaseRequestEvent") - if( (EventEntry = ALLOCATE_NONPAGED_POOL( sizeof(MBB_EVENT_ENTRY) )) == NULL ) - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqID=0x%04x] FAILED to queue event=%!MbbRequestEvent!, unable to allocate entry", Request->RequestId, Event ); - else - EventEntry->EventFlags.Allocated = TRUE; - } - - if( EventEntry != NULL ) - { - EventEntry->Event = Event; - EventEntry->EventData = EventData; - EventEntry->EventDataLength = EventDataLength; - EventEntry->Request = Request; - // - // Reference the request since the event stores a pointer to it. - // - MbbReqMgrRefRequest( Request ); - } - - MbbReqMgrTransition( EventEntry ); - - MbbReqMgrReleaseRequestEvent( EventEntry ); -} - -// Reassemble context - -_Requires_lock_not_held_( RequestManager->Spinlock ) -PMBB_REASSEMBLE_CONTEXT -MbbReqMgrAcquireSharedReassembleContext( - __in PMBB_REQUEST_MANAGER RequestManager, - __in_bcount(MessageLength) PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader, - __in ULONG MessageLength, - __in GUID ActivityId - ) -{ - MBB_COMMAND Command = { 0 }; - PMBB_COMMAND_DONE_HEADER CommandDone; - PMBB_INDICATE_STATUS_HEADER IndicationStatus; - PMBB_REASSEMBLE_CONTEXT ReassembleContext = &RequestManager->Fragmentation.Reassemble; - - // - // Get the command for debugging purposes - // - if( MessageFragmentHeader->FragmentHeader.CurrentFragment == 0 ) - { - if( MessageFragmentHeader->MessageHeader.MessageType == MBB_MESSAGE_TYPE_COMMAND_DONE && - MessageFragmentHeader->MessageHeader.MessageLength >= sizeof(MBB_COMMAND_DONE_HEADER) && - MessageLength >= sizeof(MBB_COMMAND_DONE_HEADER) ) - { - CommandDone = (PMBB_COMMAND_DONE_HEADER)MessageFragmentHeader; - Command.CommandId = CommandDone->Command.CommandId; - MBB_UUID_TO_HOST( - &Command.ServiceId, - &CommandDone->Command.ServiceId - ); - } - else - if( MessageFragmentHeader->MessageHeader.MessageType == MBB_MESSAGE_TYPE_INDICATE_STATUS && - MessageFragmentHeader->MessageHeader.MessageLength >= sizeof(MBB_INDICATE_STATUS_HEADER) && - MessageLength >= sizeof(MBB_INDICATE_STATUS_HEADER) ) - { - IndicationStatus = (PMBB_INDICATE_STATUS_HEADER)MessageFragmentHeader; - Command.CommandId = IndicationStatus->Command.CommandId; - MBB_UUID_TO_HOST( - &Command.ServiceId, - &IndicationStatus->Command.ServiceId - ); - } - } - - MbbReqMgrLockManager( RequestManager ); - - if( RequestManager->Fragmentation.ReassembleInUse == TRUE ) - { - if( ReassembleContext->TransactionId == MessageFragmentHeader->MessageHeader.MessageTransactionId && - ReassembleContext->FragmentCount == MessageFragmentHeader->FragmentHeader.TotalFragments && - ReassembleContext->NextFragment == MessageFragmentHeader->FragmentHeader.CurrentFragment ) - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] Using owned reassemble context", MessageFragmentHeader->MessageHeader.MessageTransactionId ); - } - else - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] FAILED to acquire reassemble context, owned by TID=0x%08x, Command=%s", - MessageFragmentHeader->MessageHeader.MessageTransactionId, - ReassembleContext->TransactionId, - MbbUtilGetCommandString( &Command ) - ); - ReassembleContext = NULL; - } - } - else - { - if( MessageFragmentHeader->FragmentHeader.CurrentFragment == 0 ) - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] Acquired reassemble context", MessageFragmentHeader->MessageHeader.MessageTransactionId ); - - ReassembleContext->Command = Command; - ReassembleContext->TransactionId = MessageFragmentHeader->MessageHeader.MessageTransactionId; - ReassembleContext->FragmentCount = MessageFragmentHeader->FragmentHeader.TotalFragments; - - RequestManager->Fragmentation.ReassembleInUse = TRUE; - } - else - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] FAILED to acquire reassemble context for out of order fragment, Fragement=%d/%d", - MessageFragmentHeader->MessageHeader.MessageTransactionId, - MessageFragmentHeader->FragmentHeader.CurrentFragment, - MessageFragmentHeader->FragmentHeader.TotalFragments - ); - ReassembleContext = NULL; - } - } - // - // If the context was acquired disable the fragment timer. - // If the timer cannot be disabled then do not proceed. - // - // Else send an error message to the device. - // - if( ReassembleContext != NULL ) - { - ReassembleContext->NextFragment = MessageFragmentHeader->FragmentHeader.CurrentFragment + 1; - - if( MessageFragmentHeader->FragmentHeader.CurrentFragment != 0 ) - { - if( MbbReqMgrTimerDisarm( - RequestManager, - MbbTimerTypeFragment, - MBB_LOCK_TAKEN - ) == FALSE ) - { - ReassembleContext = NULL; - } - } - } - else - { - MbbUtilSendMbimError( - MessageFragmentHeader->MessageHeader.MessageTransactionId, - MBB_ERROR_FRAGMENT_OUT_OF_SEQUENCE, - RequestManager->AdapterContext, - ActivityId, - &Command - ); - } - - MbbReqMgrUnlockManager( RequestManager ); - - return ReassembleContext; -} - -_Requires_lock_not_held_( RequestManager->Spinlock ) -VOID -MbbReqMgrReleaseSharedReassembleContext( - __in PMBB_REQUEST_MANAGER RequestManager - ) -{ - PMBB_REASSEMBLE_CONTEXT ReassembleContext = &RequestManager->Fragmentation.Reassemble; - - MbbReqMgrLockManager( RequestManager ); - - if( RequestManager->Fragmentation.ReassembleInUse == TRUE ) - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][TID=0x%08x] Released reassemble context. Command=%s", - ReassembleContext->TransactionId, - MbbUtilGetCommandString( &ReassembleContext->Command ) - ); - - ReassembleContext->FragmentLength = 0; - ReassembleContext->BufferOffset = 0; - ReassembleContext->DataLength = 0; - ReassembleContext->TransactionId = 0; - ReassembleContext->FragmentCount = 0; - ReassembleContext->NextFragment = 0; - ReassembleContext->NdisStatus = 0; - ReassembleContext->MbbStatus = 0; - - RtlZeroMemory( &ReassembleContext->Command, sizeof(MBB_COMMAND) ); - - RequestManager->Fragmentation.ReassembleInUse = FALSE; - } - else - { - ReassembleContext = NULL; - } - - MbbReqMgrUnlockManager( RequestManager ); - - if( ReassembleContext == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[ReqMgr] INVALID release of reassemble context." ); - ASSERT( FALSE ); - } -} - -// Timer - -NDIS_STATUS -MbbReqMgrTimerInitialize( - __in PMBB_REQUEST_MANAGER RequestManager, - __in MBB_TIMER_TYPE TimerType - ) -{ - NDIS_STATUS NdisStatus; - NDIS_TIMER_CHARACTERISTICS TimerCharacteristics; - - RtlCopyMemory( - &RequestManager->TimerContexts[TimerType], - &GlobalTimerContexts[TimerType], - sizeof(MBB_TIMER_CONTEXT) - ); - RequestManager->TimerContexts[TimerType].RequestManager = RequestManager; - - TimerCharacteristics.Header.Type = NDIS_OBJECT_TYPE_TIMER_CHARACTERISTICS; - TimerCharacteristics.Header.Revision = NDIS_TIMER_CHARACTERISTICS_REVISION_1; - TimerCharacteristics.Header.Size = NDIS_SIZEOF_TIMER_CHARACTERISTICS_REVISION_1; - TimerCharacteristics.AllocationTag = MbbPoolTagTimer; - TimerCharacteristics.TimerFunction = MbbReqMgrTimerCallback; - TimerCharacteristics.FunctionContext = &RequestManager->TimerContexts[TimerType]; - - NdisStatus = NdisAllocateTimerObject( - RequestManager->AdapterContext->MiniportAdapterHandle, - &TimerCharacteristics, - &RequestManager->TimerContexts[TimerType].TimerHandle - ); - return NdisStatus; -} - -BOOLEAN -MbbReqMgrTimerCleanup( - __in PMBB_REQUEST_MANAGER RequestManager, - __in MBB_TIMER_TYPE TimerType - ) -/*++ - Return Value - TRUE - Timer is successfully cancelled. - FALSE - Timer is running, caller needs to wait. ---*/ -{ - BOOLEAN WaitForTimer = FALSE; - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] Cleaning %!MbbTimer!", TimerType ); - - if( RequestManager->TimerContexts[TimerType].TimerHandle != NULL ) - { - MbbReqMgrLockManager( RequestManager ); - if( RequestManager->TimerContexts[TimerType].TimerArmTime != 0 ) - { - if( NdisCancelTimerObject( RequestManager->TimerContexts[TimerType].TimerHandle ) == FALSE ) - { - WaitForTimer = TRUE; - } - RequestManager->TimerContexts[TimerType].TimerArmTime = 0; - } - MbbReqMgrUnlockManager( RequestManager ); - - if( WaitForTimer ) - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] Waiting for %!MbbTimer! thread to exit", TimerType ); - KeFlushQueuedDpcs( ); - } - NdisFreeTimerObject( RequestManager->TimerContexts[TimerType].TimerHandle ); - RequestManager->TimerContexts[TimerType].TimerHandle = NULL; - } - - return (!WaitForTimer); -} - -_When_( Locked==FALSE, _Requires_lock_not_held_( RequestManager->Spinlock ) ) -VOID -MbbReqMgrTimerArm( - __in PMBB_REQUEST_MANAGER RequestManager, - __in MBB_TIMER_TYPE TimerType, - __in_opt ULONG DelayInMS, - __in_opt ULONG PeriodInMS, - __in_opt ULONG ToleranceInMS, - __in BOOLEAN Locked - ) -{ - LARGE_INTEGER DueTime; - - if( ! Locked ) - MbbReqMgrLockManager( RequestManager ); - - if( RequestManager->TimerContexts[TimerType].TimerArmTime == 0 ) - { - NdisGetSystemUpTimeEx( (PLARGE_INTEGER)(&RequestManager->TimerContexts[TimerType].TimerArmTime) ); - - if( DelayInMS == 0 ) - DelayInMS = RequestManager->TimerContexts[TimerType].TimerDelayInMS; - - if( PeriodInMS == 0 ) - PeriodInMS = RequestManager->TimerContexts[TimerType].TimerPeriodInMS; - - if( ToleranceInMS == 0 ) - ToleranceInMS = RequestManager->TimerContexts[TimerType].TimerToleranceInMS; - - DueTime.QuadPart = DelayInMS; - DueTime.QuadPart *= 10000 * -1; - - NdisSetCoalescableTimerObject( - RequestManager->TimerContexts[TimerType].TimerHandle, - DueTime, - PeriodInMS, - NULL, - ToleranceInMS - ); - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! armed at %I64x for %I64x ms", - TimerType, - RequestManager->TimerContexts[TimerType].TimerArmTime, - DelayInMS - ); - } - else - { - TraceWarn( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! already armed at %I64x, not re-arming", - TimerType, - RequestManager->TimerContexts[TimerType].TimerArmTime - ); - } - - if( ! Locked ) - MbbReqMgrUnlockManager( RequestManager ); -} - -_When_( Locked==FALSE, _Requires_lock_not_held_( RequestManager->Spinlock ) ) -BOOLEAN -MbbReqMgrTimerDisarm( - __in PMBB_REQUEST_MANAGER RequestManager, - __in MBB_TIMER_TYPE TimerType, - __in BOOLEAN Locked - ) -/*++ - Return Value - TRUE - Timer is successfully cancelled. - FALSE - Timer could not be cancelled. ---*/ -{ - BOOLEAN IsTimerCancelled = TRUE; - - if( ! Locked ) - MbbReqMgrLockManager( RequestManager ); - - if( RequestManager->TimerContexts[TimerType].TimerArmTime != 0 ) - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! disarmed", TimerType ); - IsTimerCancelled = NdisCancelTimerObject( RequestManager->TimerContexts[TimerType].TimerHandle ); - RequestManager->TimerContexts[TimerType].TimerArmTime = 0; - } - else - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! not armed, cant disarmed", TimerType ); - } - - if( ! Locked ) - MbbReqMgrUnlockManager( RequestManager ); - - return IsTimerCancelled; -} - -VOID -MbbReqMgrTimerCallback( - __in PVOID SystemSpecific1, - __in PVOID FunctionContext, - __in PVOID SystemSpecific2, - __in PVOID SystemSpecific3 - ) -{ - PMBB_TIMER_CONTEXT TimerContext = (PMBB_TIMER_CONTEXT)FunctionContext; - PMBB_REQUEST_MANAGER RequestManager = TimerContext->RequestManager; - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer] %!MbbTimer! fired", TimerContext->TimerType ); - - MbbReqMgrLockManager( RequestManager ); - TimerContext->TimerArmTime = 0; - MbbReqMgrUnlockManager( RequestManager ); - - TimerContext->TimerFunction( - SystemSpecific1, - RequestManager, - SystemSpecific2, - SystemSpecific3 - ); -} - -// Inter-Fragment timer - -VOID -MbbReqMgrTimerFragmentTimeoutCallback( - __in PVOID SystemSpecific1, - __in PVOID FunctionContext, - __in PVOID SystemSpecific2, - __in PVOID SystemSpecific3 - ) -{ - PMBB_REQUEST_MANAGER RequestManager = (PMBB_REQUEST_MANAGER)FunctionContext; - PMBB_REASSEMBLE_CONTEXT ReassembleContext = &RequestManager->Fragmentation.Reassemble; - PMBB_REQUEST_CONTEXT Request; - GUID ActivityId = {0}; - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][Timer][TID=0x%08x] Fragment timeout", ReassembleContext->TransactionId ); - - Request = MbbReqMgrGetRequestByTransactionId( RequestManager, ReassembleContext->TransactionId ); - - if(Request) - { - ActivityId = Request->ActivityId; - } - - MbbUtilSendMbimError( - ReassembleContext->TransactionId, - MBB_ERROR_TIMEOUT_FRAGMENT, - RequestManager->AdapterContext, - ActivityId, - &ReassembleContext->Command - ); - - MbbReqMgrReleaseSharedReassembleContext( RequestManager ); - - if( Request ) - { - MbbReqMgrQueueEvent( - RequestManager, - Request, - MbbRequestEventCancel, - (PVOID)(STATUS_TIMEOUT), - 0 - ); - MbbReqMgrDerefRequest( Request ); - } -} - -// Request timeout timer - -VOID -MbbReqMgrTimerRequestTimeoutCallback( - __in PVOID SystemSpecific1, - __in PVOID FunctionContext, - __in PVOID SystemSpecific2, - __in PVOID SystemSpecific3 - ) -{ - PMBB_REQUEST_MANAGER RequestManager = (PMBB_REQUEST_MANAGER)FunctionContext; - PMBB_REQUEST_CONTEXT Request; - PLIST_ENTRY ListEntry; - LIST_ENTRY TempList; - ULONGLONG TimeoutDelta; - ULONGLONG NextTimeout = ULLONG_MAX; - ULONGLONG CurrentTime; - - InitializeListHead( &TempList ); - - MbbReqMgrLockManager( RequestManager ); - NdisGetSystemUpTimeEx( (PLARGE_INTEGER)(&CurrentTime) ); - for( ListEntry = RequestManager->AllocatedRequestList.Flink; - ListEntry != &RequestManager->AllocatedRequestList; - ListEntry = ListEntry->Flink ) - { - Request = CONTAINING_RECORD( ListEntry, MBB_REQUEST_CONTEXT, ManagerLink ); - - TimeoutDelta = CurrentTime - Request->DispatchTime; - if( TimeoutDelta > (MBB_REQUEST_TIMEOUT_MS-MBB_REQUEST_TIMEOUT_TOLERANCE_MS) ) - { - MbbReqMgrRefRequest( Request ); - InsertTailList( &TempList, &Request->ReqMgrContext.TimeoutLink ); - } - else - if( TimeoutDelta < NextTimeout ) - { - NextTimeout = TimeoutDelta; - } - } - // - // Re-arm the timer if required. - // Note that the tolerance is smaller than MBB_REQUEST_TIMEOUT_TOLERANCE_MS. - // This is because its not known how large NextTimeout is. - // - if( NextTimeout != ULLONG_MAX ) - { - MbbReqMgrTimerArm( - RequestManager, - MbbTimerTypeRequest, - (ULONG)NextTimeout, - 0, - 100, - MBB_LOCK_TAKEN - ); - } - - MbbReqMgrUnlockManager( RequestManager ); - - while (!IsListEmpty(&TempList)) - { - // Get the Entry of the list - ListEntry = RemoveHeadList(&TempList); - Request = CONTAINING_RECORD(ListEntry, MBB_REQUEST_CONTEXT, ReqMgrContext.TimeoutLink); - - MbbReqMgrQueueEvent( - RequestManager, - Request, - MbbRequestEventCancel, - (PVOID)(NDIS_STATUS_REQUEST_ABORTED), - 0 - ); - - PMBB_SEND_QUEUE SendQueue = &((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request))->SendQueue; - if (Request->OidHandler != NULL) - { - switch (Request->OidHandler->Oid) - { - case OID_WWAN_CONNECT: - TraceLoggingWrite( - g_hLoggingProvider, - "ConnectResponseTimeout", - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); - //case OID_WWAN_PIN_EX: - TryQueueStallState(SendQueue); - break; - } - } - MbbReqMgrDerefRequest(Request); - } -} - -// -// FSM State Handlers -// - -VOID -MbbReqFsmReady( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - // - // No-op - // -} - -VOID -MbbReqFsmDispatching( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - BOOLEAN DispatchRequest; - PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; - - MbbReqMgrLockManager( RequestManager ); - - if( Request->ReqMgrContext.IsSerialized == TRUE ) - { - if( RequestManager->CurrentRequest == NULL ) - { - RequestManager->CurrentRequest = Request; - DispatchRequest = TRUE; - } - else - { - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[ReqMgr][ReqId=0x%04x] Queuing request, QueueStatus[Current=0x%p %s]", - Request->RequestId, - RequestManager->CurrentRequest, - IsListEmpty( &RequestManager->PendingRequestQueue )? "EMPTY": "NON-EMPTY" - ); - // - // Reference request while it is queued - // - MbbReqMgrRefRequest( Request ); - - InsertTailList( - &(RequestManager->PendingRequestQueue), - &(Request->ReqMgrContext.QueueLink) - ); - DispatchRequest = FALSE; - Request->ReqMgrContext.IsQueued = TRUE; - } - } - else - { - DispatchRequest = TRUE; - } - // - // Schedule the timeout timer, if not already scheduled. - // - MbbReqMgrTimerArm( - RequestManager, - MbbTimerTypeRequest, - 0, - 0, - 0, - MBB_LOCK_TAKEN - ); - - MbbReqMgrUnlockManager( RequestManager ); - - if( DispatchRequest ) - { - MbbReqMgrQueueEvent( - RequestManager, - Request, - MbbRequestEventStart, - NULL, - 0 - ); - } -} - -VOID -MbbReqFsmSendPending( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - NDIS_STATUS NdisStatus; - PMBB_EVENT_ENTRY NewEventEntry; - - // - // Reference request while it is pending - // - MbbReqMgrRefRequest( Request ); - - NdisStatus = Request->ReqMgrContext.DispatchRoutine( - MbbReqMgrGetAdapterHandle( Request ), - Request - ); - if( NdisStatus != NDIS_STATUS_PENDING ) - { - MbbReqMgrQueueEvent( - Request->RequestManager, - Request, - MbbRequestEventSendComplete, - (PVOID)NdisStatus, - 0 - ); - } -} - -VOID -MbbReqFsmSendComplete( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - BOOLEAN IsSerialized = Request->ReqMgrContext.IsSerialized; - - if ((NDIS_STATUS)(EventEntry->EventData) != STATUS_SUCCESS) - { - // - // the send failed. copy the command id from the send to the response area since - // no response will be received and this can cause some handlers to not complete in indication - // - Request->HandlerContext.Response.Command= Request->HandlerContext.Command.Command; - } - - if( Request->ReqMgrContext.CompletionCallback != NULL ) - { - Request->ReqMgrContext.CompletionCallback( - MbbReqMgrGetAdapterHandle( Request ), - Request, - (NDIS_STATUS)(EventEntry->EventData) - ); - } - - if( IsSerialized == TRUE ) - { - MbbReqMgrIntProcessNextRequest( Request->RequestManager ); - } - // - // Request no longer pending - // - MbbReqMgrDerefRequest( Request ); -} - -VOID -MbbReqFsmResponseReceived( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - switch( EventEntry->Event ) - { - case MbbRequestEventResponseReceived: - { - if( Request->ReqMgrContext.ResponseHandler != NULL ) - { - Request->ReqMgrContext.ResponseHandler( - Request, - Request->HandlerContext.Response.NdisStatus, - Request->HandlerContext.Response.MbbStatus, - (PUCHAR) EventEntry->EventData, - EventEntry->EventDataLength - ); - } - } - break; - - case MbbRequestEventResponseReceivedMoreData: - { - if( Request->ReqMgrContext.ResponseHandler != NULL ) - { - Request->ReqMgrContext.ResponseHandler( - Request, - Request->HandlerContext.Response.NdisStatus, - MBB_STATUS_SMS_MORE_DATA, - (PUCHAR) EventEntry->EventData, - EventEntry->EventDataLength - ); - } - } - break; - - case MbbRequestEventSendComplete: - { - MbbReqFsmSendComplete( - Request, - OldState, - EventEntry - ); - } - break; - } -} - -VOID -MbbReqFsmCancelled( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - switch( EventEntry->Event ) - { - case MbbRequestEventDispatch: - { - // - // Request was cancelled after being created - // but before being dispatched. The request - // is not yet queued for dispatching. Fail the - // request instead of dispatching it. - // - ASSERT( Request->ReqMgrContext.CompletionCallback != NULL ); - - if( Request->ReqMgrContext.CompletionCallback != NULL ) - { - Request->ReqMgrContext.CompletionCallback( - MbbReqMgrGetAdapterHandle( Request ), - Request, - (NDIS_STATUS)(NDIS_STATUS_REQUEST_ABORTED) - ); - } - } - break; - - case MbbRequestEventSendComplete: - { - - EventEntry->EventData=(PVOID)NDIS_STATUS_REQUEST_ABORTED; - - MbbReqFsmSendComplete( - Request, - OldState, - EventEntry - ); - } - break; - - case MbbRequestEventCancel: - { - switch( OldState ) - { - case MbbRequestStateDispatching: - { - // - // Request was dispatched and serialized. - // Dequeue the request and fail it. - // - MbbReqMgrLockManager( Request->RequestManager ); - - RemoveEntryList( &Request->ReqMgrContext.QueueLink ); - - if(Request->ReqMgrContext.IsQueued) - { - // this means that the request was actually queued during - // dispatching and not processed directly. When the request - // was queued a reference was taken on the request which - // needs to be removed now. - - Request->ReqMgrContext.IsQueued = FALSE; - - MbbReqMgrUnlockManager( Request->RequestManager ); - - TraceInfo( WMBCLASS_REQUEST_FSM, "[ReqFsm][ReqId=0x%04x] Dequeuing queued request due to cancellation", Request->RequestId ); - - MbbReqMgrDerefRequest( Request ); - } - else - { - MbbReqMgrUnlockManager( Request->RequestManager ); - } - - if( Request->ReqMgrContext.CompletionCallback != NULL ) - { - Request->ReqMgrContext.CompletionCallback( - MbbReqMgrGetAdapterHandle( Request ), - Request, - (NDIS_STATUS)(EventEntry->EventData) - ); - } - } - break; - - case MbbRequestStateSendComplete: - case MbbRequestStateResponseReceivedMoreData: - { - if( Request->ReqMgrContext.ResponseHandler != NULL ) - { - Request->ReqMgrContext.ResponseHandler( - Request, - (NDIS_STATUS)(EventEntry->EventData), - MBB_STATUS_FAILURE, - NULL, - 0 - ); - } - } - break; - - case MbbRequestStateReady: - case MbbRequestStateCancelled: - case MbbRequestStateSendPending: - case MbbRequestStateResponseReceived: - default: - { - // - // No-op - // - } - break; - } - } - break; - - case MbbRequestEventStart: - case MbbRequestEventResponseReceived: - case MbbRequestEventResponseReceivedMoreData: - default: - { - // - // No-op - // - } - break; - } -} - -VOID -MbbReqFsmInvalid( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_STATE OldState, - __in PMBB_EVENT_ENTRY EventEntry - ) -{ - TraceInfo( WMBCLASS_REQUEST_FSM, "[ReqFsm][ReqId=0x%04x] INVALID Transition!!", Request->RequestId ); - ASSERT( FALSE ); -} diff --git a/network/wwan/cxwmbclass/RequestManager.h b/network/wwan/cxwmbclass/RequestManager.h deleted file mode 100644 index 790119dac..000000000 --- a/network/wwan/cxwmbclass/RequestManager.h +++ /dev/null @@ -1,230 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// -#define MBB_PREALLOC_REQUEST_COUNT 10 -#define MBB_PREALLOC_WORKITEM_COUNT 4 -#define MBB_PREALLOC_FRAGMENATION_BUFFER_COUNT 3 -#define MBB_FRAGMENATION_BULK_BUFFER_LENGTH (64*1024) -#define MBB_REASSEMBLE_BUFFER_LENGTH (64*1024) - - -//////////////////////////////////////////////////////////////////////////////// -// -// DECLARATIONS -// -//////////////////////////////////////////////////////////////////////////////// -FORCEINLINE -BOOLEAN -MbbReqMgrRef( - __in PMBB_REQUEST_MANAGER RequestManager - ); - -FORCEINLINE -VOID -MbbReqMgrDeref( - __in PMBB_REQUEST_MANAGER RequestManager - ); - -NDIS_STATUS -MbbReqMgrInitialize( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PMINIPORT_ADAPTER_CONTEXT AdapterContext - ); - -VOID -MbbReqMgrCleanup( - __in PMBB_REQUEST_MANAGER RequestManager - ); - -VOID -MbbReqMgrCancelRequests( - __in PMBB_REQUEST_MANAGER RequestManager, - __in BOOLEAN IsClosed - ); - -MBB_PROTOCOL_HANDLE -MbbReqMgrGetAdapterHandle( - __in PMBB_REQUEST_CONTEXT Request - ); - -BOOLEAN -MbbReqMgrIsInternalRequest( - __in PMBB_REQUEST_CONTEXT Request - ); - -VOID -MbbReqMgrSetUnsolicitedIndication( - __in PMBB_REQUEST_CONTEXT Request - ); - -BOOLEAN -MbbReqMgrIsUnsolicitedIndication( - __in PMBB_REQUEST_CONTEXT Request - ); - -_Requires_lock_not_held_(&(Request->RequestManager->Spinlock)) -VOID -MbbReqMgrGetState( - __in PMBB_REQUEST_CONTEXT Request, - __inout MBB_REQUEST_STATE *pCurrentState, - __inout MBB_REQUEST_STATE *pLastState - ); - -BOOLEAN -MbbReqMgrIsSetOid( - __in PMBB_REQUEST_CONTEXT Request - ); - -MBB_NDIS_OID_STATE -MbbReqMgrGetSetOidState( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_NDIS_OID_STATE OidState - ); - -__checkReturn -__drv_aliasesMem -__drv_allocatesMem(Mem) -PMBB_REQUEST_CONTEXT -MbbReqMgrCreateRequest( - __in PMBB_REQUEST_MANAGER RequestManager, - __in_opt PNDIS_OID_REQUEST OidRequest, - __in ULONG ResponseBufferLength, - __out PNDIS_STATUS NdisStatus - ); - -VOID -MbbReqMgrDestroyRequest( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PMBB_REQUEST_CONTEXT Request - ); - -NDIS_STATUS -MbbReqMgrDispatchRequest( - __in PMBB_REQUEST_CONTEXT Request, - __in BOOLEAN IsSerialized, - __in MBB_REQUEST_DISPATCH_ROUTINE DispatchRoutine, - __in MBB_REQUEST_COMPLETION_CALLBACK CompletionCallback, - __in_opt MBB_REQUEST_RESPONSE_HANDLER ResponseHandler - ); - -_Acquires_lock_( RequestManager->Spinlock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, RequestManager ) -VOID -MbbReqMgrLockManager( - __in PMBB_REQUEST_MANAGER RequestManager - ); - -_Releases_lock_( RequestManager->Spinlock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, RequestManager ) -VOID -MbbReqMgrUnlockManager( - __in PMBB_REQUEST_MANAGER RequestManager - ); - -PMBB_REQUEST_CONTEXT -MbbReqMgrGetRequestByOidRequestId( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PNDIS_OID_REQUEST RequestId - ); - -PMBB_REQUEST_CONTEXT -MbbReqMgrGetRequestById( - __in PMBB_REQUEST_MANAGER RequestManager, - __in ULONG RequestId - ); - -PMBB_REQUEST_CONTEXT -MbbReqMgrGetRequestByTransactionId( - __in PMBB_REQUEST_MANAGER RequestManager, - __in ULONG TransactionId - ); - -_Requires_lock_held_( RequestManager->Spinlock ) -VOID -MbbReqMgrQueueEventLocked( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_EVENT Event, - __in_opt PVOID EventData, - __in ULONG EventDataLength, - __in BOOLEAN SignalThread - ); - -_Requires_lock_not_held_( RequestManager->Spinlock ) -VOID -MbbReqMgrQueueEvent( - __in PMBB_REQUEST_MANAGER RequestManager, - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_EVENT Event, - __in_opt PVOID EventData, - __in ULONG EventDataLength - ); - -VOID -MbbReqMgrRefRequest( - __in PMBB_REQUEST_CONTEXT Request - ); - -VOID -MbbReqMgrDerefRequest( - __in PMBB_REQUEST_CONTEXT Request - ); - -// Reassemble context - -_Requires_lock_not_held_( RequestManager->Spinlock ) -PMBB_REASSEMBLE_CONTEXT -MbbReqMgrAcquireSharedReassembleContext( - __in PMBB_REQUEST_MANAGER RequestManager, - __in_bcount(MessageLength) PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader, - __in ULONG MessageLength, - __in GUID ActivityId - ); - -_Requires_lock_not_held_( RequestManager->Spinlock ) -VOID -MbbReqMgrReleaseSharedReassembleContext( - __in PMBB_REQUEST_MANAGER RequestManager - ); - -// Timer - -NDIS_STATUS -MbbReqMgrTimerInitialize( - __in PMBB_REQUEST_MANAGER RequestManager, - __in MBB_TIMER_TYPE TimerType - ); - -BOOLEAN -MbbReqMgrTimerCleanup( - __in PMBB_REQUEST_MANAGER RequestManager, - __in MBB_TIMER_TYPE TimerType - ); - -_When_( Locked==FALSE, _Requires_lock_not_held_( RequestManager->Spinlock ) ) -VOID -MbbReqMgrTimerArm( - __in PMBB_REQUEST_MANAGER RequestManager, - __in MBB_TIMER_TYPE TimerType, - __in_opt ULONG DelayInMS, - __in_opt ULONG PeriodInMS, - __in_opt ULONG ToleranceInMS, - __in BOOLEAN Locked - ); - -_When_( Locked==FALSE, _Requires_lock_not_held_( RequestManager->Spinlock ) ) -BOOLEAN -MbbReqMgrTimerDisarm( - __in PMBB_REQUEST_MANAGER RequestManager, - __in MBB_TIMER_TYPE TimerType, - __in BOOLEAN Locked - ); diff --git a/network/wwan/cxwmbclass/adapter.c b/network/wwan/cxwmbclass/adapter.c deleted file mode 100644 index 5e637838d..000000000 --- a/network/wwan/cxwmbclass/adapter.c +++ /dev/null @@ -1,3398 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -#include "precomp.h" -#include "adapter.tmh" -#include "WMBClassTelemetry.h" - -#define MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS (10 * 1000 * 1000) // 10 seconds -#define MBB_ADAPTER_PRESHUTDOWN_REQUEST_TIMEOUT_MS (6 * 1000 * 1000) // 6 seconds - -// -// Adapter routines -// -_Acquires_lock_( Adapter->Lock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterLock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NdisAcquireSpinLock( &Adapter->Lock ); -} - -_Releases_lock_( Adapter->Lock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterUnlock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NdisReleaseSpinLock( &Adapter->Lock ); -} - -_Acquires_lock_( Adapter->PortsLock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterPortsLock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NdisAcquireSpinLock( &Adapter->PortsLock ); -} - -_Releases_lock_( Adapter->PortsLock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterPortsUnlock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NdisReleaseSpinLock( &Adapter->PortsLock ); -} - -_Acquires_lock_( Adapter->SessionIdPortTableLock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterSessionIdPortTableLock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NdisAcquireSpinLock( &Adapter->SessionIdPortTableLock ); -} - -_Releases_lock_( Adapter->SessionIdPortTableLock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterSessionIdPortTableUnlock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NdisReleaseSpinLock( &Adapter->SessionIdPortTableLock ); -} - - -VOID -MbbAdapterRef( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - InterlockedIncrement( &Adapter->Reference ); -} - -VOID -MbbAdapterDeref( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - if( InterlockedDecrement( &Adapter->Reference ) == 0 ) - { - FreeAdapterBlock( Adapter ); - } -} - -VOID -MbbAdapterConnectionChange( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in PMBB_CONNECTION_STATE ConnectionState, - __in NDIS_PORT_NUMBER PortNumber - ) -{ - NDIS_STATUS NdisStatus; - MBB_COMMAND IpCommand; - PMBB_REQUEST_CONTEXT IpRequest; - PMBB_REQUEST_MANAGER RequestManager = NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; - PMBB_PORT Port = NULL; - - do - { - // Get the port - Port = MbbWwanTranslatePortNumberToPort(Adapter,PortNumber); - - if(!Port) - { - break; - } - - if( ConnectionState->ConnectionUp == TRUE ) - { - // - // Get the IP Address if connection was successful. - // When IP is retrieved link state would be indicated to NDIS. - // - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][Luid=0x%I64x] FAILED to reference RequestManager to get IP Address", Adapter->NetLuid.Value ); - break; - } - if( (IpRequest = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][Luid=0x%I64x] FAILED to allocate RequestContext to get IP Address", Adapter->NetLuid.Value ); - break; - } - IpCommand.ServiceId = MBB_UUID_BASIC_CONNECT; - IpCommand.CommandId = MBB_BASIC_CID_IP_ADDRESS_INFO; - IpRequest->OidHandler = MbbNdisGetOidHandlerByCommand( &IpCommand ); - // - // Save the connection state for indication to NDIS when IP is retrieved. - // - IpRequest->HandlerContext.Parameters.IpAddress.ConnectionState = *ConnectionState; - IpRequest->HandlerContext.Parameters.IpAddress.SessionId = MbbWwanGetPortSessionId(Port); - - NdisStatus = MbbReqMgrDispatchRequest( - IpRequest, - TRUE, - MbbUtilInternalCIDQuery, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - if( NdisStatus != NDIS_STATUS_PENDING ) - { - MbbReqMgrDestroyRequest( - IpRequest->RequestManager, - IpRequest - ); - } - } - else - { - MbbAdapterSetConnectionState( - Adapter, - ConnectionState, - PortNumber - ); - } - } - while( FALSE ); - - if(Port!=NULL) - Dereference(Port); - - if( RequestManager != NULL ) - MbbReqMgrDeref( RequestManager ); -} - -VOID -MbbAdapterSetConnectionState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_CONNECTION_STATE ConnectionState, - __in NDIS_PORT_NUMBER PortNumber - ) -{ - - PMBB_PORT Port = NULL; - BOOLEAN fIndicateLinkState = FALSE; - - Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); - - if(Port != NULL) - { - MBB_ACQUIRE_PORT_LOCK(Port); - - Port->ConnectionState = *ConnectionState; - - MBB_RELEASE_PORT_LOCK(Port); - } - - if(ConnectionState->ConnectionUp) - { - // Always indicate Link state when on a successful connection - fIndicateLinkState = TRUE; - } - else - { - // Connection is disconnected. - // Look at all the ports in the adapter and indicate the link state - // down only if all the ports are disconnected - - ULONG NumPortsConnected = 0; - fIndicateLinkState = ((NumPortsConnected = MbbWwanGetNumPortsConnected(Adapter))== 0); - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] %S status LINK_STATE disconnected for Port =%lu since %d ports are connected", - fIndicateLinkState ? L"Indicating" : L"Not indicating", - PortNumber, - NumPortsConnected); - } - - if(fIndicateLinkState) - { - // Indicate link down - MbbAdapterSetLinkState( - Adapter, - ConnectionState, - PortNumber); - } - - // Always indicate the port state - MbbAdapterSetPortState( - Adapter, - ConnectionState, - PortNumber); - - if(Port != NULL) - { - Dereference(Port); - } -} - -VOID -MbbAdapterSetLinkState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_CONNECTION_STATE ConnectionState, - __in NDIS_PORT_NUMBER PortNumber - ) -{ - NDIS_LINK_STATE LinkState; - NDIS_STATUS_INDICATION StatusIndication; - - LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1; - LinkState.Header.Size = NDIS_SIZEOF_LINK_STATE_REVISION_1; - LinkState.MediaConnectState = ConnectionState->ConnectionUp ? MediaConnectStateConnected : MediaConnectStateDisconnected; - LinkState.MediaDuplexState = MediaDuplexStateUnknown; - LinkState.XmitLinkSpeed = ConnectionState->UpStreamBitRate; - LinkState.RcvLinkSpeed = ConnectionState->DownStreamBitRate; - LinkState.PauseFunctions = NdisPauseFunctionsUnsupported; - LinkState.AutoNegotiationFlags = 0; - - StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; - StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; - StatusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; - StatusIndication.SourceHandle = Adapter->MiniportAdapterHandle; - StatusIndication.PortNumber = PortNumber; - StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE; - StatusIndication.Flags = 0; - StatusIndication.DestinationHandle = NULL; - StatusIndication.RequestId = 0; - StatusIndication.StatusBuffer = &LinkState; - StatusIndication.StatusBufferSize = sizeof(NDIS_LINK_STATE); - - RtlZeroMemory( &StatusIndication.Guid, sizeof(StatusIndication.Guid) ); - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] Indicating status LINK_STATE Connected=%!BOOLEAN! to NDIS, Uplink=%I64d, downlink=%I64d for Port =%lu", - ConnectionState->ConnectionUp, - ConnectionState->DownStreamBitRate, - ConnectionState->UpStreamBitRate, - PortNumber - ); - - MbbUtilNdisMiniportIndicateStatusEx( - Adapter, - &StatusIndication - ); -} - - -VOID -MbbAdapterSetPortState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_CONNECTION_STATE ConnectionState, - __in NDIS_PORT_NUMBER PortNumber - ) -{ - NDIS_PORT_STATE PortState; - NDIS_STATUS_INDICATION StatusIndication; - PMBB_PORT Port = NULL; - - Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); - - if(Port != NULL) - { - MBB_ACQUIRE_PORT_LOCK(Port); - - Port->ConnectionState = *ConnectionState; - - MBB_RELEASE_PORT_LOCK(Port); - - Dereference(Port); - } - - PortState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - PortState.Header.Revision = NDIS_PORT_STATE_REVISION_1; - PortState.Header.Size = NDIS_SIZEOF_PORT_STATE_REVISION_1; - PortState.MediaConnectState = ConnectionState->ConnectionUp ? MediaConnectStateConnected : MediaConnectStateDisconnected; - PortState.XmitLinkSpeed = ConnectionState->UpStreamBitRate; - PortState.RcvLinkSpeed = ConnectionState->DownStreamBitRate; - PortState.Direction = NET_IF_DIRECTION_SENDRECEIVE; - PortState.SendControlState = NdisPortControlStateUncontrolled; - PortState.RcvControlState = NdisPortControlStateUncontrolled; - PortState.SendAuthorizationState = NdisPortAuthorizationUnknown; - PortState.RcvAuthorizationState = NdisPortAuthorizationUnknown; - PortState.Flags = 0; - - StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; - StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; - StatusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; - StatusIndication.SourceHandle = Adapter->MiniportAdapterHandle; - StatusIndication.PortNumber = PortNumber; - StatusIndication.StatusCode = NDIS_STATUS_PORT_STATE; - StatusIndication.Flags = 0; - StatusIndication.DestinationHandle = NULL; - StatusIndication.RequestId = 0; - StatusIndication.StatusBuffer = &PortState; - StatusIndication.StatusBufferSize = sizeof(NDIS_PORT_STATE); - - RtlZeroMemory( &StatusIndication.Guid, sizeof(StatusIndication.Guid) ); - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] Indicating status PORT_STATE Connected=%!BOOLEAN! to NDIS, Uplink=%I64d, downlink=%I64d for Port =%lu", - ConnectionState->ConnectionUp, - ConnectionState->DownStreamBitRate, - ConnectionState->UpStreamBitRate, - PortNumber - ); - - MbbUtilNdisMiniportIndicateStatusEx( - Adapter, - &StatusIndication - ); -} - -VOID -MbbPortSetIpAddressState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PWWAN_IP_ADDRESS_STATE WwanIpAddressState, - __in NDIS_PORT_NUMBER PortNumber - ) -{ - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_IP_ADDRESS_STATE IpAddressState = {0}; - - if(!WwanIpAddressState) - { - return; - } - - IpAddressState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - IpAddressState.Header.Size = SIZEOF_NDIS_WWAN_IP_ADDRESS_STATE_1; - IpAddressState.Header.Revision = NDIS_WWAN_IP_ADDRESS_STATE_REVISION_1; - IpAddressState.WwanIpAddressState = *WwanIpAddressState; - - StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; - StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; - StatusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; - StatusIndication.SourceHandle = Adapter->MiniportAdapterHandle; - StatusIndication.PortNumber = PortNumber; - StatusIndication.Flags = 0; - StatusIndication.DestinationHandle = NULL; - StatusIndication.RequestId = 0; - StatusIndication.StatusCode = NDIS_STATUS_WWAN_IP_ADDRESS_STATE; - StatusIndication.StatusBuffer = &IpAddressState; - StatusIndication.StatusBufferSize = SIZEOF_NDIS_WWAN_IP_ADDRESS_STATE_1; - - RtlZeroMemory( &StatusIndication.Guid, sizeof(StatusIndication.Guid) ); - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] Indicating status NDIS_STATUS_WWAN_IPADDRESS_STATE on NDIS port number %lu",PortNumber); - - NdisMIndicateStatusEx( - Adapter->MiniportAdapterHandle, - &StatusIndication - ); -} - -BOOLEAN -MbbPortIsConnected( - __in PMBB_PORT Port - ) -{ - BOOLEAN IsConnected; - - MBB_ACQUIRE_PORT_LOCK(Port); - IsConnected = Port->ConnectionState.ConnectionUp; - MBB_RELEASE_PORT_LOCK(Port); - - return IsConnected; -} - -VOID -MbbAdapterIndicateD3Exit( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in NDIS_PORT_NUMBER PortNumber - ) -{ - NDIS_STATUS_INDICATION StatusIndication; - - StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; - StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; - StatusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; - StatusIndication.SourceHandle = Adapter->MiniportAdapterHandle; - StatusIndication.PortNumber = PortNumber; - StatusIndication.StatusCode = NDIS_STATUS_WWAN_RESERVED_3; //NDIS_STATUS_WWAN_DEVICE_POWER_STATE_D3_EXIT - StatusIndication.Flags = 0; - StatusIndication.DestinationHandle = NULL; - StatusIndication.RequestId = 0; - StatusIndication.StatusBuffer = NULL; - StatusIndication.StatusBufferSize = 0; - - RtlZeroMemory( &StatusIndication.Guid, sizeof(StatusIndication.Guid) ); - - TraceInfo( WMBCLASS_REQUEST_MANAGER, "[MbbAdapter] Indicating status NDIS_STATUS_WWAN_DEVICE_POWER_STATE_D3_EXIT to NDIS for adapter with guid %!GUID! on Port number %lu", - &(Adapter->NetCfgId), - PortNumber - ); - - MbbUtilNdisMiniportIndicateStatusEx( - Adapter, - &StatusIndication - ); -} - - -NDIS_STATUS -MbbAdapterDispatchQueryDeviceServicesRequest( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - MBB_COMMAND Command; - - do - { - RtlCopyMemory( - &(Command.ServiceId), - &MBB_UUID_BASIC_CONNECT, - sizeof(GUID) - ); - Command.CommandId = MBB_BASIC_CID_DEVICE_SERVICES; - - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Command, - MBB_COMMAND_TYPE_QUERY, - NULL, - 0 - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for QueryDeviceServices with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for QueryDeviceServices with status=%!status!", - Request->RequestId, NdisStatus ); - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterQueryDeviceServices( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_DEVICE_SERVICES }; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for QueryDeviceService" ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for QueryDeviceService" ); - break; - } - Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - // - // Ref the request so that the response handler does not free it - // - MbbReqMgrRefRequest( Request ); - - TraceInfo( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] Internal query dispatch for BASIC_CID_DEVICE_SERVICES", - Request->RequestId - ); - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbAdapterDispatchQueryDeviceServicesRequest, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If the request is pending wait for it to complete. - // If the request didnt complete within the timeout period drop our ref count and fail to the caller. - // Something is wrong with a device that does not complete a non-network request within the timeout - // If dispatching the request failed then our completion callback will not be invoked, - // in this case destroy the request. - // - if( NdisStatus == NDIS_STATUS_PENDING ) - { - Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; - NdisStatus = KeWaitForSingleObject( - &Request->WaitEvent, - Executive, - KernelMode, - TRUE, // Alertable - &Timeout // Timeout - ); - if( NdisStatus != STATUS_WAIT_0 ) - { - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - // - // Only if Send was successful then get the response status. - // - if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) - NdisStatus = Request->HandlerContext.Response.NdisStatus; - } - } - else - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - // - // It is ok to destroy the request here and deref it later. - // Destroy will not free the request while there is a pending ref. - // - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - if( Request != NULL ) - { - MbbReqMgrDerefRequest( Request ); - } - return NdisStatus; -} - - -NDIS_STATUS -MbbAdapterDispatchConfigureRadioStateRequest( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - MBB_COMMAND Command; - MBB_RADIO_STATE* MbbRadioState; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - - do - { - RtlCopyMemory( - &(Command.ServiceId), - &MBB_UUID_BASIC_CONNECT, - sizeof(GUID) - ); - Command.CommandId = MBB_BASIC_CID_RADIO_STATE; - - if( (MbbRadioState = (MBB_RADIO_STATE*) ALLOCATE_NONPAGED_POOL( sizeof(MBB_RADIO_STATE) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbRadioState; - - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - *MbbRadioState = Adapter->RadioOff ? MbbRadioStateOff : MbbRadioStateOn; - - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Command, - MBB_COMMAND_TYPE_SET, - (PUCHAR) MbbRadioState, - sizeof(MBB_RADIO_STATE) - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for ConfigureRadioState with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for ConfigureRadioState with status=%!status!", - Request->RequestId, NdisStatus ); - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterConfigureRadioState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_RADIO_STATE }; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for ConfigureRadioState" ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for ConfigureRadioState" ); - break; - } - Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - // - // Ref the request so that the response handler does not free it - // - MbbReqMgrRefRequest( Request ); - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbAdapterDispatchConfigureRadioStateRequest, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If the request is pending wait for it to complete. - // If the request didnt complete within the timeout period drop our ref count and fail to the caller. - // Something is wrong with a device that does not send response for a non-network request - // If dispatching the request failed then our completion callback will not be invoked, - // in this case destroy the request. - // - if( NdisStatus == NDIS_STATUS_PENDING ) - { - Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; - NdisStatus = KeWaitForSingleObject( - &Request->WaitEvent, - Executive, - KernelMode, - TRUE, // Alertable - &Timeout // Timeout - ); - if( NdisStatus != STATUS_WAIT_0 ) - { - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - // - // Only if Send was successful then get the response status. - // - if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) - NdisStatus = Request->HandlerContext.Response.NdisStatus; - } - } - else if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - // - // It is ok to destroy the request here and deref it later. - // Destroy will not free the request while there is a pending ref. - // - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - if( Request != NULL ) - { - MbbReqMgrDerefRequest( Request ); - } - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterPerformInitialRequests( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - // - // We are going to wait for these requests to finish. This will block the - // MiniportInitialize call. For NDIS 6.30 drivers, NDIS would not be blocking - // the PnP IRP until MiniportInitialize finishes. So we are OK with the taking - // a while for MiniportInitialize - // - - // Query device services - if( (Status = MbbAdapterQueryDeviceServices( Adapter )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to QueryDeviceService, status=%!STATUS!", Status ); - goto Cleanup; - } - - // Set default subscribe list - if( (Status = MbbAdapterConfigureDeviceServiceSubscription( Adapter, TRUE, 0, 0 )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to Set initial subscribe events list, status=%!STATUS!", Status ); - goto Cleanup; - } - - // Set the radio state that has been persisted in registry - if( (Status = MbbAdapterConfigureRadioState( Adapter )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to ConfigureRadioState, status=%!STATUS!", Status ); - goto Cleanup; - } - -Cleanup: - - return Status; -} - - - - -NDIS_STATUS -MbbAdapterDispatchConfigurePacketFiltersRequest( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - MBB_COMMAND Command; - MBB_PACKET_FILTERS* MbbPacketFilters=NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - ULONG BufferSize=0; - - do - { - RtlCopyMemory( - &(Command.ServiceId), - &MBB_UUID_BASIC_CONNECT, - sizeof(GUID) - ); - Command.CommandId = MBB_BASIC_CID_PACKET_FILTERS; - - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - NdisStatus=MbbUtilWwanToMbbSetPacketFilter( - Adapter, - Request->HandlerContext.Parameters.SetPacketFilter.Set, - Request->HandlerContext.Parameters.SetPacketFilter.PortNumber, - &MbbPacketFilters, - &BufferSize - ); - - if (!NT_SUCCESS(NdisStatus)) - { - break; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbPacketFilters; - - - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Command, - MBB_COMMAND_TYPE_SET, - (PUCHAR) MbbPacketFilters, - BufferSize - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for ConfigurePacketFilters with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for ConfigurePacketFilters with status=%!status!", - Request->RequestId, NdisStatus ); - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterConfigurePacketFilters( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN Set - ) - // Algorithm: - // 1) Iterate through the adapter powerfilter table and check if - // there are any empty slots. - // - // 2) Iterate over all the connected sessions and check if they are having - // any WOL patterns associated with them. - // - // 3) If no WOL patterns are found - // { - // create a no-match WOL pattern and add it to the power filter table for that session ID - // goto step4 - // } - // - //4) Plumb the WOL patterns for connected sessions - // - - // Assumptions: - // Since this routine is called under the context of an OID, there will not be - // any other routines trying to alter the Adapter->PowerFilterTable - // - // In case there are no WOL patterns corresponding to the session, the code will - // try to set no-match pattern for them, if any wake slots are available according to - // Adapter->PowerFilterTable. We will return on first failure. -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - ULONG NumEmptySlots = 0; - ULONG ConnectedPorts[MBB_MAX_NUMBER_OF_PORTS] = {0}; - ULONG NumConnectedPorts = 0; - ULONG i = 0, j = 0; - - - // Only if this is a set request for wake filters, get the number of - // empty slots - - if(Set) - { - for (i = 0; i < Adapter->BusParams.PowerFiltersSupported; i++) - { - if(!Adapter->PowerFilterTable[i].InUse) - { - NumEmptySlots++; - } - } - } - - - // We will create a transient array of connected ports and send the request to - // configure packet filters for them iteratively. No new ports are expected to be added - // since this routine is called in context of an OID request and until this OID request completes - // OID to create a new context can not come. There can however be unsolicited context - // deactivations. In that case we will still send the request to the device which should fail it. - - MbbAdapterPortsLock(Adapter); - - for(i = 0; i < Adapter->NumberOfPorts && NumConnectedPorts < MBB_MAX_NUMBER_OF_PORTS; i++) - { - NDIS_PORT_NUMBER PortNumber = MBB_INVALID_PORT_NUMBER; - PMBB_PORT Port = Adapter->PortList[i]; - - MBB_ACQUIRE_PORT_LOCK(Port); - - if(Port->ConnectionState.ConnectionUp) - { - ASSERT(Port->SessionId != MBB_INVALID_SESSION_ID && (ULONG)Port->SessionId < Adapter->MaxActivatedContexts); - - PortNumber = Port->PortNumber; - - MBB_RELEASE_PORT_LOCK(Port); - - ConnectedPorts[NumConnectedPorts++] = PortNumber; - - if(Set) - { - // add a no-match WOL pattern if there are empty slots - if(NumEmptySlots > 0) - { - // Evaluate and add no-match patterns for this - // port if it has no wake filter configured. - - BOOL fHasWOLPattern = FALSE; - - for(j = 0; j < Adapter->BusParams.PowerFiltersSupported; j++) - { - if(Adapter->PowerFilterTable[j].InUse - && Adapter->PowerFilterTable[j].PortNumber == PortNumber) - { - fHasWOLPattern = TRUE; - break; - } - } - - if(!fHasWOLPattern) - { - if((Status = MbbUtilAddNoMatchFilter(Adapter, Port)) == NDIS_STATUS_SUCCESS) - { - NumEmptySlots--; - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Remaining slots in adapter power filter table after addition of no-match filter = %d", NumEmptySlots); - } - else - { - // absorb the error - Status = NDIS_STATUS_SUCCESS; - } - } - } - else - { - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Not evaluating no-match filters for port number %lu since there are no empty slots", PortNumber); - } - } - else - { - // Remove the no-match filter for this port, if any - MbbUtilRemoveNoMatchFilter(Adapter, Port); - } - } - else - { - MBB_RELEASE_PORT_LOCK(Port); - } - } - - MbbAdapterPortsUnlock(Adapter); - - if(NumConnectedPorts > 0) - { - for(i = 0; i < NumConnectedPorts; i++) - { - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Attempting to %s packet filters or no-match filters for connected port %lu", Set ? "set":"reset", ConnectedPorts[i]); - - if( (Status = MbbAdapterConfigurePacketFiltersOnSession(Adapter, Set, ConnectedPorts[i])) != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] Failed to %s packet filters or no-match filters for port %lu. Status=%!status!", Set ? "set":"reset", ConnectedPorts[i], Status); - // continue plumbing as many packet filters as possible - } - else - { - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Successfully %s packet filters or no-match filters for connected port %lu", Set ? "set":"reset", ConnectedPorts[i]); - } - } - } - else - { - TraceWarn( WMBCLASS_INIT, "[MbbAdapter] Not attempting to %s packet filters or no-match filters as there are no connected ports", Set ? "set":"reset"); - } - - return Status ; -} - - -NDIS_STATUS -MbbAdapterConfigurePacketFiltersOnSession( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN Set, - __in NDIS_PORT_NUMBER PortNumber - ) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_FILTERS }; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for ConfigurePacketFilters" ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for ConfigurePacketFilters" ); - break; - } - Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - - Request->HandlerContext.Parameters.SetPacketFilter.Set=Set; - Request->HandlerContext.Parameters.SetPacketFilter.PortNumber = PortNumber; - - // - // Ref the request so that the response handler does not free it - // - MbbReqMgrRefRequest( Request ); - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbAdapterDispatchConfigurePacketFiltersRequest, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If the request is pending wait for it to complete. - // If the request didnt complete within the timeout period drop our ref count and fail to the caller. - // Something is wrong with a device that does not send response for a non-network request - // If dispatching the request failed then our completion callback will not be invoked, - // in this case destroy the request. - // - if( NdisStatus == NDIS_STATUS_PENDING ) - { - Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; - NdisStatus = KeWaitForSingleObject( - &Request->WaitEvent, - Executive, - KernelMode, - TRUE, // Alertable - &Timeout // Timeout - ); - if( NdisStatus != STATUS_WAIT_0 ) - { - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - // - // Only if Send was successful then get the response status. - // - if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) - NdisStatus = Request->HandlerContext.Response.NdisStatus; - } - } - else if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - // - // It is ok to destroy the request here and deref it later. - // Destroy will not free the request while there is a pending ref. - // - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - if( Request != NULL ) - { - MbbReqMgrDerefRequest( Request ); - } - return NdisStatus; -} - - -NDIS_STATUS -MbbAdapterDispatchConfigureDeviceServiceSubscriptionRequest( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - MBB_COMMAND Command; - MBB_SUBSCRIBE_EVENT_LIST* MbbDeviceServiceSubscription=NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - ULONG BufferSize=0; - - do - { - RtlCopyMemory( - &(Command.ServiceId), - &MBB_UUID_BASIC_CONNECT, - sizeof(GUID) - ); - Command.CommandId = MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES; - - - - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - NdisStatus=MbbUtilGenerateSubscribeEventList( - Adapter, - Request->HandlerContext.Parameters.SyncDeviceServiceSubription.FullPower, - Request->HandlerContext.Parameters.SyncDeviceServiceSubription.MediaSpecificWakeUpEvents, - Request->HandlerContext.Parameters.SyncDeviceServiceSubription.WakeUpFlags, - Adapter->DeviceServiceState.ExtSubscribeList, - Adapter->DeviceServiceState.ExtSubscribeListBufferSize, - &MbbDeviceServiceSubscription, - &BufferSize - ); - - - - if (!NT_SUCCESS(NdisStatus)) - { - break; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbDeviceServiceSubscription; - - - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Command, - MBB_COMMAND_TYPE_SET, - (PUCHAR) MbbDeviceServiceSubscription, - BufferSize - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for ConfigureDeviceServiceSubscription with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for ConfigureDeviceServiceSubscription with status=%!status!", - Request->RequestId, NdisStatus ); - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterConfigureDeviceServiceSubscription( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN FullPower, - __in ULONG MediaSpecificWakeUpEvents, - __in ULONG WakeUpFlags - ) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES }; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for ConfigureDeviceServiceSubscription" ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for ConfigureDeviceServiceSubscription" ); - break; - } - Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - - Request->HandlerContext.Parameters.SyncDeviceServiceSubription.FullPower=FullPower; - Request->HandlerContext.Parameters.SyncDeviceServiceSubription.MediaSpecificWakeUpEvents=MediaSpecificWakeUpEvents; - Request->HandlerContext.Parameters.SyncDeviceServiceSubription.WakeUpFlags=WakeUpFlags; - // - // Ref the request so that the response handler does not free it - // - MbbReqMgrRefRequest( Request ); - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbAdapterDispatchConfigureDeviceServiceSubscriptionRequest, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If the request is pending wait for it to complete. - // If the request didnt complete within the timeout period drop our ref count and fail to the caller. - // Something is wrong with a device that does not send response for a non-network request - // If dispatching the request failed then our completion callback will not be invoked, - // in this case destroy the request. - // - if( NdisStatus == NDIS_STATUS_PENDING ) - { - Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; - NdisStatus = KeWaitForSingleObject( - &Request->WaitEvent, - Executive, - KernelMode, - TRUE, // Alertable - &Timeout // Timeout - ); - if( NdisStatus != STATUS_WAIT_0 ) - { - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - // - // Only if Send was successful then get the response status. - // - if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) - NdisStatus = Request->HandlerContext.Response.NdisStatus; - } - } - else if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - // - // It is ok to destroy the request here and deref it later. - // Destroy will not free the request while there is a pending ref. - // - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - if( Request != NULL ) - { - MbbReqMgrDerefRequest( Request ); - } - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterDispatchSendNetworkIdleHintRequest( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - MBB_COMMAND Command; - MBB_SUBSCRIBE_EVENT_LIST* MbbDeviceServiceSubscription=NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - ULONG BufferSize=0; - PMBB_NETWORK_IDLE_HINT IdleHint=NULL; - - do - { - RtlCopyMemory( - &(Command.ServiceId), - &MBB_UUID_BASIC_CONNECT, - sizeof(GUID) - ); - Command.CommandId = MBB_BASIC_CID_NETWORK_IDLE_HINT; - - IdleHint=ALLOCATE_NONPAGED_POOL(sizeof(*IdleHint)); - - if (IdleHint == NULL) - { - NdisStatus=NDIS_STATUS_RESOURCES; - break; - } - - IdleHint->NetworkIdleHintState=MbbNetworkIdleHintEnabled; - - Request->HandlerContext.DataToFreeOnCompletion = IdleHint; - - - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Command, - MBB_COMMAND_TYPE_SET, - (PUCHAR) IdleHint, - sizeof(*IdleHint) - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for SendNetworkIdleHint with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for SendNetworkIdleHint with status=%!status!", - Request->RequestId, NdisStatus ); - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterSendNetworkIdleHint( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_NETWORK_IDLE_HINT }; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for SendNetworkIdleHint" ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for SendNetworkIdleHint" ); - break; - } - Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - - // - // Ref the request so that the response handler does not free it - // - MbbReqMgrRefRequest( Request ); - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbAdapterDispatchSendNetworkIdleHintRequest, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If the request is pending wait for it to complete. - // If the request didnt complete within the timeout period drop our ref count and fail to the caller. - // Something is wrong with a device that does not send response for a non-network request - // If dispatching the request failed then our completion callback will not be invoked, - // in this case destroy the request. - // - if( NdisStatus == NDIS_STATUS_PENDING ) - { - Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; - NdisStatus = KeWaitForSingleObject( - &Request->WaitEvent, - Executive, - KernelMode, - TRUE, // Alertable - &Timeout // Timeout - ); - if( NdisStatus != STATUS_WAIT_0 ) - { - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - // - // Only if Send was successful then get the response status. - // - if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) - NdisStatus = Request->HandlerContext.Response.NdisStatus; - } - } - else if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - // - // It is ok to destroy the request here and deref it later. - // Destroy will not free the request while there is a pending ref. - // - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - if( Request != NULL ) - { - MbbReqMgrDerefRequest( Request ); - } - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterDispatchSendNetworkShutdownHintRequest( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - MBB_COMMAND Command; - MBB_SUBSCRIBE_EVENT_LIST* MbbDeviceServiceSubscription=NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - ULONG BufferSize=0; - - do - { - RtlCopyMemory( - &(Command.ServiceId), - &MBB_UUID_HOSTSHUTDOWN, - sizeof(GUID) - ); - Command.CommandId = MBB_HOSTSHUTDOWN_CID_ONE; - - - - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Command, - MBB_COMMAND_TYPE_SET, - NULL, - 0 - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to setup command message for SendNetworkShutdownHint with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter][ReqId=0x%04x] FAILED to send message fragments for SendNetworkShutdownHint with status=%!status!", - Request->RequestId, NdisStatus ); - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterSendNetworkShutdownHint( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - MBB_COMMAND Command = { MBB_UUID_HOSTSHUTDOWN_CONSTANT, MBB_HOSTSHUTDOWN_CID_ONE }; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - BOOLEAN HintSupport=FALSE; - - do - { - MbbAdapterLock( Adapter ); - HintSupport = Adapter->AdapterFlags.ShutdownNotificationCapable == 1; - MbbAdapterUnlock( Adapter ); - - if (!HintSupport) - { - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] device does not support NetworkShutdownHint" ); - NdisStatus=STATUS_SUCCESS; - break; - } - - - - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for SendNetworkShutdownHint" ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for SendNetworkShutdownHint" ); - break; - } - Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - - // - // Ref the request so that the response handler does not free it - // - MbbReqMgrRefRequest( Request ); - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbAdapterDispatchSendNetworkShutdownHintRequest, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If the request is pending wait for it to complete. - // If the request didnt complete within the timeout period drop our ref count and fail to the caller. - // Something is wrong with a device that does not send response for a non-network request - // If dispatching the request failed then our completion callback will not be invoked, - // in this case destroy the request. - // - if( NdisStatus == NDIS_STATUS_PENDING ) - { - Timeout.QuadPart = -1 * 10 * 500000; - NdisStatus = KeWaitForSingleObject( - &Request->WaitEvent, - Executive, - KernelMode, - TRUE, // Alertable - &Timeout // Timeout - ); - if( NdisStatus != STATUS_WAIT_0 ) - { - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - // - // Only if Send was successful then get the response status. - // - if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) - NdisStatus = Request->HandlerContext.Response.NdisStatus; - } - } - else if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - // - // It is ok to destroy the request here and deref it later. - // Destroy will not free the request while there is a pending ref. - // - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - if( Request != NULL ) - { - MbbReqMgrDerefRequest( Request ); - } - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterDispatchSendPreShutdownRequest( - _In_ MBB_PROTOCOL_HANDLE AdapterHandle, - _In_ PMBB_REQUEST_CONTEXT Request -) -{ - NDIS_STATUS NdisStatus = MbbUtilSetAttributeWithParameter( - Request, - NULL, - 0); - - if ((NdisStatus != NDIS_STATUS_SUCCESS) && - (NdisStatus != NDIS_STATUS_PENDING)) - { - TraceError(WMBCLASS_INIT, "[MbbNdis][ReqID=0x%04x] SendPreShutdownRequest Set failed with status=%!status!", - Request->RequestId, NdisStatus); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterSendPreShutdown( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter -) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - MBB_COMMAND Command = { MBB_UUID_HOSTSHUTDOWN_CONSTANT, MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN }; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - BOOLEAN IsPreshutdownSupport = FALSE; - - MbbAdapterLock(Adapter); - IsPreshutdownSupport = (TRUE == Adapter->AdapterFlags.IsPreshutdownCapable); - MbbAdapterUnlock(Adapter); - - do { - if (!IsPreshutdownSupport) - { - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support PreShutdown"); - NdisStatus = STATUS_SUCCESS; - break; - } - - if ((RequestManager = MbbAdapterGetRequestManager(Adapter)) == NULL) - { - TraceError(WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for SendPreShutdown"); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - - if ((Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL) - { - TraceError(WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for SendPreShutdown"); - break; - } - Request->OidHandler = MbbNdisGetOidHandlerByCommand(&Command); - - // - // Ref the request so that the response handler does not free it - // - MbbReqMgrRefRequest(Request); - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbAdapterDispatchSendPreShutdownRequest, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // The request is dispatched and queued. We expect to get NDIS_STATUS_PENDING and wait for it to complete. - // - if (NdisStatus == NDIS_STATUS_PENDING) - { - // A positive value specifies an absolute time, relative to January 1, 1601. - // Here we use a NEGATIVE value to specify an interval relative to the current time. - Timeout.QuadPart = -10 * MBB_ADAPTER_PRESHUTDOWN_REQUEST_TIMEOUT_MS; // 100-nanosecond unit; - NdisStatus = KeWaitForSingleObject( - &Request->WaitEvent, - Executive, - KernelMode, - TRUE, // Alertable - &Timeout - ); - if (NdisStatus != STATUS_WAIT_0) - { - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - // get the response status only when Send was successful - if ((NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS) - { - NdisStatus = Request->HandlerContext.Response.NdisStatus; - } - } - } - else if (NdisStatus != NDIS_STATUS_SUCCESS) - { - // Something wrong when dispatching request, destroy it and deref later - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - } while (FALSE); - - if (RequestManager != NULL) - { - MbbReqMgrDeref(RequestManager); - } - if (Request != NULL) - { - MbbReqMgrDerefRequest(Request); - } - return NdisStatus; -} - -VOID -AdapterPauseHandler( - PSTATE_CHANGE_EVENT StateChange - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; - BOOLEAN StopSendQueue=FALSE; - BOOLEAN NoOustandingNBLs=FALSE; - - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - if (FastIOPause(StateChange)) - { - return; - } - - NdisAcquireSpinLock(&Adapter->Lock); - - ASSERT(Adapter->AdapterState.Started); - - Adapter->AdapterState.Started=FALSE; - - - // - // add one for this routine running now - // - Adapter->AdapterState.PendingActions++; - - // - // power changes don't effect the receive control, so we stop it now - // - NoOustandingNBLs=TRUE; - Adapter->AdapterState.PendingActions++; - - - if (Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) - { - // - // if the device is powered, - // stop everything - // - StopSendQueue=TRUE; - Adapter->AdapterState.PendingActions++; - } - else - { - // - // not powered, The send queue is already stopped - // - - } - - Adapter->AdapterState.RunningEvent=StateChange; - - NdisReleaseSpinLock(&Adapter->Lock); - - if (StopSendQueue) - { - MbbSendQCancel( - &Adapter->SendQueue, - NDIS_STATUS_PAUSED, - TRUE - ); - - // - // stop the pipes and cancel the io - // - MbbBusStopDataPipes(Adapter->BusHandle); - - } - - if (NoOustandingNBLs) - { - MbbRecvQCancel( - &Adapter->ReceiveQueue, - NDIS_STATUS_PAUSED, - TRUE - ); - } - - - - // - // call this to remove the pending action count added above - // - DrainCompleteCallback(Adapter); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; -} - - -VOID -AdapterRestartHandler( - PSTATE_CHANGE_EVENT StateChange - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; - NTSTATUS Status=STATUS_SUCCESS; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - if (FastIORestart(StateChange)) - { - return; - } - - if (Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) - { - Status=MbbBusStartDataPipes(Adapter->BusHandle); - - if (NT_SUCCESS(Status)) - { - - // - // powered up, start send queue - // - DrainComplete( &(Adapter->SendQueue.QueueDrainObject) ); - } - } - - // - // always enable receive control because power does not touch it - // - DrainComplete( &(Adapter->ReceiveQueue.QueueDrainObject) ); - - Adapter->AdapterState.Started=TRUE; - - CompleteStateChange( - &Adapter->AdapterState, - StateChange - ); - - StateChange=NULL; - - TraceInfo(WMBCLASS_INIT, "Calling NdisMRestartComplete()"); - - MbbWriteEvent( - &RESTART_COMPLETE_EVENT, - NULL, - NULL, - 2, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &Status, - sizeof(Status) - ); - - - NdisMRestartComplete(Adapter->MiniportAdapterHandle, Status); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); -} - - -VOID -AdapterPowerHandler( - PSTATE_CHANGE_EVENT StateChange - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; - BOOLEAN StartSendQueue=FALSE; - BOOLEAN StopSendQueue=FALSE; - NET_DEVICE_POWER_STATE PreviousPowerState; - BOOLEAN FullPower=FALSE; - NTSTATUS Status=STATUS_SUCCESS; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - NdisAcquireSpinLock(&Adapter->Lock); - - - PreviousPowerState=Adapter->AdapterState.CurrentPowerState; - Adapter->AdapterState.CurrentPowerState = StateChange->Power.NewPower; - - if (StateChange->Power.NewPower == NetDeviceStateD0) - { - // - // full power - // - if (Adapter->AdapterState.Started) - { - StartSendQueue=TRUE; - } - FullPower=TRUE; - - } - else - { - // - // reduced power - // - ASSERT(Adapter->AdapterState.PendingActions == 0); - - FullPower=FALSE; - - if (Adapter->AdapterState.Started && MbbBusIsFastIO(Adapter->BusHandle) == FALSE) - { - // - // started, stop the send queue - // - StopSendQueue=TRUE; - Adapter->AdapterState.PendingActions++; - - } - - Adapter->AdapterState.PendingActions++; - - } - - NdisReleaseSpinLock(&Adapter->Lock); - - - if (FullPower) - { - // - // D0 - // - - if (PreviousPowerState == NetDeviceStateD3) - { - do - { - // - // device was in d3, open it again - // - Status = MbbBusOpen(Adapter->BusHandle, MbbLibraryGetNextTransactionId(), FastIOSendNetBufferListsComplete, FastIOIndicateReceiveNetBufferLists); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] MbbBusOpen() with %!STATUS!", Status); - break; - } - - // - // opened, make sure the radio is in the right state - // - Status = MbbAdapterConfigureRadioState( Adapter ); - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "D0 power up FAILED to ConfigureRadioState, status=%!STATUS!. Reset data pipe as workaround for surface in order to reset modem", Status); - MbbBusResetBulkPipe(Adapter->BusHandle, TRUE); - - TraceLoggingWrite( - g_hLoggingProvider, - "MbbPipeReset", - TraceLoggingString("PowerHandler", "ResetType"), - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); - - break; - } - - // send an indication to service indicating we are out of D3 - MbbAdapterIndicateD3Exit(Adapter, NDIS_DEFAULT_PORT_NUMBER); //always indicate on port 0 - }while(FALSE); - - if(NT_ERROR(Status)) - { - NdisMRemoveMiniport( - Adapter->MiniportAdapterHandle - ); - } - } - - if (StartSendQueue && MbbBusIsFastIO(Adapter->BusHandle) == FALSE) - { - // - // re-enable the send queue - // - - DrainComplete( &(Adapter->SendQueue.QueueDrainObject) ); - - if NT_SUCCESS(Status) - { - - MbbBusStartDataPipes(Adapter->BusHandle); - } - } - - - Adapter->LastLowSystemPowerState.TargetSystemState = PowerSystemWorking; - Adapter->LastLowSystemPowerState.EffectiveSystemState = PowerSystemWorking; - - MbbBusSetNotificationState(Adapter->BusHandle, TRUE); - - MbbAdapterConfigurePacketFilters(Adapter, FALSE); - - MbbAdapterConfigureDeviceServiceSubscription(Adapter, TRUE, 0, 0); - - TraceInfo(WMBCLASS_INIT, "Completing set power request"); - - // - // done - // - MbbReqMgrQueueEvent( - StateChange->Power.Request->RequestManager, - StateChange->Power.Request, - MbbRequestEventSendComplete, - (PVOID)(NDIS_STATUS_SUCCESS), - 0 - ); - - - CompleteStateChange( - &Adapter->AdapterState, - StateChange - ); - - StateChange=NULL; - } - else - { - // - // low power - // - Adapter->AdapterState.RunningEvent=StateChange; - - if (StopSendQueue) - { - - MbbSendQCancel( - &Adapter->SendQueue, - NDIS_STATUS_PAUSED, - TRUE - ); - - MbbBusStopDataPipes(Adapter->BusHandle); - } - - if ((PreviousPowerState == NetDeviceStateD0) && (Adapter->AdapterState.CurrentPowerState == NetDeviceStateD3)) - { - if (Adapter->LastLowSystemPowerState.TargetSystemState > PowerSystemSleeping3) - { - // when the system supports hibernate and user requests shutdown, the system will try - // hibernate first rather than full shutdown. - // That is, (TargetSysState: PowerSystemShutdown, EffectiveSysState: PowerSystemHibernate) - if (Adapter->LastLowSystemPowerState.EffectiveSystemState == PowerSystemHibernate) - { - // If the suspend event is S4, the network device would power off - // send preshutdown to make it cleanup in case the device is flashless. - // We don't send it for S5 here because S5 is handled by OID request from wwansvc - MbbAdapterSendPreShutdown(Adapter); - } - // - // only send in the case the sleep is greater than S3 - // - MbbAdapterSendNetworkShutdownHint(Adapter); - } - - MbbBusSetNotificationState(Adapter->BusHandle, FALSE); - - MbbBusClose(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FALSE); - } - else - { - MbbBusSetNotificationState(Adapter->BusHandle, FALSE); - } - - // - // the request will be completed when the drain has completed - // - DrainCompleteCallback(Adapter); - - - } - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; - - -} - -VOID -AdapterResetHandler( - PSTATE_CHANGE_EVENT StateChange - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; - BOOLEAN StopSendQueue=FALSE; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - if (FastIOReset(StateChange)) - { - return; - } - // - // add one for this routing running now - // - Adapter->AdapterState.PendingActions++; - - - if ((Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) && Adapter->AdapterState.Started) - { - // - // if the device is powered and started - // stop everything - // - StopSendQueue=TRUE; - Adapter->AdapterState.PendingActions++; - } - else - { - // - // not powered, The send queue is already stopped - // - - } - - StateChange->Reset.PipeStartStatus=STATUS_SUCCESS; - - if (StopSendQueue) - { - MbbSendQCancel( - &Adapter->SendQueue, - NDIS_STATUS_PAUSED, - TRUE - ); - - // - // stop and start the pipes to cancel any io - // - MbbBusStopDataPipes(Adapter->BusHandle); - - StateChange->Reset.PipeStartStatus = MbbBusResetBulkPipe(Adapter->BusHandle, TRUE); - - TraceLoggingWrite( - g_hLoggingProvider, - "MbbPipeReset", - TraceLoggingString("ResetHandler", "ResetType"), - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); - - MbbBusStartDataPipes(Adapter->BusHandle); - - } - - Adapter->AdapterState.RunningEvent=StateChange; - - // - // call this to remove the pending action count add above - // - DrainCompleteCallback(Adapter); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; - - -} - -VOID -AdapterStallClearHandler( - PSTATE_CHANGE_EVENT StateChange - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)StateChange->Context1; - BOOLEAN StartSendQueue=FALSE; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - NdisAcquireSpinLock(&Adapter->Lock); - // - // add one for this routine running now - // - Adapter->AdapterState.PendingActions++; - - - if ((Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) && Adapter->AdapterState.Started) - { - // - // if the device is powered and started - // stop everything - // - StartSendQueue=TRUE; - Adapter->AdapterState.PendingActions++; - } - else - { - // - // not powered, The send queue is already stopped - // - - } - NdisReleaseSpinLock(&Adapter->Lock); - - if(StartSendQueue) - { - MbbSendQCancel( - &Adapter->SendQueue, - NDIS_STATUS_PAUSED, - TRUE - ); - } - - // - // stop and start the pipes to cancel any io - // - MbbBusStopDataPipes(Adapter->BusHandle); - - MbbBusResetBulkPipe(Adapter->BusHandle, TRUE); - - TraceLoggingWrite( - g_hLoggingProvider, - "MbbPipeReset", - TraceLoggingString("StallClearHandler", "ResetType"), - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); - - if (StartSendQueue) - { - MbbBusStartDataPipes(Adapter->BusHandle); - DrainComplete(&(Adapter->SendQueue.QueueDrainObject)); - } - - Adapter->AdapterState.RunningEvent=StateChange; - // - // call this to remove the pending action count add above - // - DrainCompleteCallback(Adapter); - - return; - - -} - - - - -NTSTATUS -InitAdapterStateObject( - __out PADAPTER_STATE AdapterState, - __in NDIS_HANDLE MiniportAdapterContext, - MBB_STATE_CHANGE_HANDLER PauseHandler, - MBB_STATE_CHANGE_HANDLER RestartHandler, - MBB_STATE_CHANGE_HANDLER PowerHandler, - MBB_STATE_CHANGE_HANDLER ResetHandler, - MBB_STATE_CHANGE_HANDLER StallClearHandler - ) - -{ - ULONG i; - - RtlZeroMemory(AdapterState, sizeof(*AdapterState)); - - // - // device is power to start with - // - AdapterState->CurrentPowerState=NetDeviceStateD0; - - AdapterState->Handlers[STATE_CHANGE_TYPE_PAUSE] = PauseHandler; - AdapterState->Handlers[STATE_CHANGE_TYPE_RESTART] = RestartHandler; - AdapterState->Handlers[STATE_CHANGE_TYPE_POWER] = PowerHandler; - AdapterState->Handlers[STATE_CHANGE_TYPE_RESET] = ResetHandler; - AdapterState->Handlers[STATE_CHANGE_TYPE_STALL_CLEAR] = StallClearHandler; - - InitializeListHead(&AdapterState->FreeList); - - - - InitializeListHead(&AdapterState->ListEntry); - AdapterState->CurrentEvent=NULL; - - KeInitializeEvent( - &AdapterState->StallClearCompleteEvent, - NotificationEvent, - TRUE - ); - - NdisAllocateSpinLock(&AdapterState->Lock); - - for (i=0; i< STATE_CHANGE_EVENT_RESERVE_COUNT; i++) - { - - PSTATE_CHANGE_EVENT StateChange=NULL; - - StateChange=ALLOCATE_NONPAGED_POOL(sizeof(*StateChange)); - - if (StateChange != NULL) - { - - NdisAcquireSpinLock(&AdapterState->Lock); - - InsertHeadList(&AdapterState->FreeList, &StateChange->ListEntry); - StateChange=NULL; - - NdisReleaseSpinLock(&AdapterState->Lock); - - } - else - { - return STATUS_INSUFFICIENT_RESOURCES; - } - } - - - AdapterState->WorkItem=NdisAllocateIoWorkItem(MiniportAdapterContext); - - if (AdapterState->WorkItem == NULL) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - return STATUS_SUCCESS; - -} - -VOID -ShutdownAdapterStateObject( - PADAPTER_STATE AdapterState - ) - -{ - PSTATE_CHANGE_EVENT StateChange=NULL; - - ASSERT(AdapterState->CurrentEvent == NULL); - ASSERT(IsListEmpty(&AdapterState->ListEntry)); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - AdapterState->ShuttingDown=TRUE; - - StateChange=AllocateStateChangeEvent(AdapterState); - - while (StateChange != NULL) - { - FREE_POOL(StateChange); - StateChange=NULL; - - StateChange=AllocateStateChangeEvent(AdapterState); - } - - if (AdapterState->WorkItem != NULL) - { - NdisFreeIoWorkItem(AdapterState->WorkItem); - AdapterState->WorkItem=NULL; - } - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; - -} - - - -VOID -AdapterStateWorkitemRoutine( - PVOID WorkItemContext, - NDIS_HANDLE WorkItemHandle - ) - -{ - PADAPTER_STATE AdapterState=(PADAPTER_STATE)WorkItemContext; - PSTATE_CHANGE_EVENT StateChange=AdapterState->CurrentEvent; - - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - if (StateChange->EventType < STATE_CHANGE_MAX && StateChange->EventType >= 0) - { - (*AdapterState->Handlers[StateChange->EventType])(StateChange); - } - else - { - ASSERT(0); - } - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; - -} - - -VOID -ProcessStateChangeQueue( - PADAPTER_STATE AdapterState - ) - -{ - PLIST_ENTRY ListEntry=NULL; - PSTATE_CHANGE_EVENT StateChangeEvent=NULL; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!:Entered"); - - NdisAcquireSpinLock(&AdapterState->Lock); - - if (AdapterState->CurrentEvent == NULL) - { - // - // queue is idle - // - if (!IsListEmpty(&AdapterState->ListEntry)) - { - // - // more item to run - // - ListEntry=RemoveTailList(&AdapterState->ListEntry); - - StateChangeEvent=CONTAINING_RECORD(ListEntry, STATE_CHANGE_EVENT, ListEntry); - - AdapterState->CurrentEvent=StateChangeEvent; - - TraceInfo(WMBCLASS_INIT, "Queuing work item"); - - NdisQueueIoWorkItem(AdapterState->WorkItem, AdapterStateWorkitemRoutine, AdapterState); - - } - } - - - NdisReleaseSpinLock(&AdapterState->Lock); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; - - - -} - -VOID -QueueStateChangeEvent( - PADAPTER_STATE AdapterState, - PSTATE_CHANGE_EVENT StateChange - ) - -{ - - TraceInfo(WMBCLASS_INIT, "%!FUNC!:Entered"); - - NdisAcquireSpinLock(&AdapterState->Lock); - - InsertHeadList(&AdapterState->ListEntry, &StateChange->ListEntry); - - - NdisReleaseSpinLock(&AdapterState->Lock); - - ProcessStateChangeQueue(AdapterState); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; -} - - - -VOID -CompleteStateChange( - PADAPTER_STATE AdapterState, - PSTATE_CHANGE_EVENT StateChange - ) - - -{ - TraceInfo(WMBCLASS_INIT, "%!FUNC!:Entered"); - - NdisAcquireSpinLock(&AdapterState->Lock); - - ASSERT(AdapterState->CurrentEvent == StateChange); - - AdapterState->CurrentEvent=NULL; - - NdisReleaseSpinLock(&AdapterState->Lock); - - FreeStateChangeEvent(AdapterState, StateChange); - - ProcessStateChangeQueue(AdapterState); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - -} - -PSTATE_CHANGE_EVENT -AllocateStateChangeEvent( - PADAPTER_STATE AdapterState - ) - -{ - PLIST_ENTRY ListEntry=NULL; - PSTATE_CHANGE_EVENT StateChangeEvent=NULL; - - NdisAcquireSpinLock(&AdapterState->Lock); - - if (!IsListEmpty(&AdapterState->FreeList)) - { - // - // more item to run - // - ListEntry=RemoveTailList(&AdapterState->FreeList); - - StateChangeEvent=CONTAINING_RECORD(ListEntry, STATE_CHANGE_EVENT, ListEntry); - - RtlZeroMemory(StateChangeEvent, sizeof(*StateChangeEvent)); - } - else - { - if (!AdapterState->ShuttingDown) - { - ASSERT(0); - } - } - - NdisReleaseSpinLock(&AdapterState->Lock); - - - return StateChangeEvent; - -} - - -VOID -FreeStateChangeEvent( - PADAPTER_STATE AdapterState, - PSTATE_CHANGE_EVENT StateChange - ) - -{ - NdisAcquireSpinLock(&AdapterState->Lock); - - InsertHeadList(&AdapterState->FreeList, &StateChange->ListEntry); - StateChange=NULL; - - NdisReleaseSpinLock(&AdapterState->Lock); - - return; - -} - -VOID -FreeDeviceServiceState( - __in PMBB_DS_STATE DeviceServiceState - ) -{ - PMBB_DS DeviceService; - ULONG* CIDList; - ULONG i; - - if (DeviceServiceState->ExtSubscribeList != NULL) - FREE_POOL(DeviceServiceState->ExtSubscribeList); - - if (DeviceServiceState->ServicesList != NULL) - { - // Free each device service entry - for (i = 0; i < DeviceServiceState->ServicesCount; i++) - { - DeviceService = &(DeviceServiceState->ServicesList[i]); - - // Free the CID list - if (DeviceService->CIDList != NULL) - FREE_POOL(DeviceService->CIDList); - } - - // Free the device services list structure - FREE_POOL(DeviceServiceState->ServicesList); - } - - return; -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetMultiCarrierCapable( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN IsMultiCarrierSupported - ) -{ - MbbAdapterLock( Adapter ); - Adapter->AdapterFlags.IsMultiCarrier = IsMultiCarrierSupported; - MbbAdapterUnlock( Adapter ); -} - - _Requires_lock_not_held_(&Adapter->Lock) -BOOLEAN -MbbAdapterIsMultiCarrierCapable( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - BOOLEAN IsMultiCarrierSupported; - - MbbAdapterLock( Adapter ); - IsMultiCarrierSupported = (Adapter->AdapterFlags.IsMultiCarrier == 1); - MbbAdapterUnlock( Adapter ); - - return IsMultiCarrierSupported; -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetDataClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in ULONG DataClass - ) -{ - MbbAdapterLock( Adapter ); - Adapter->AdapterDataClass = DataClass; - MbbAdapterUnlock( Adapter ); -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterGetDataClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __out ULONG* DataClass - ) -{ - MbbAdapterLock( Adapter ); - *DataClass = Adapter->AdapterDataClass; - MbbAdapterUnlock( Adapter ); -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetSupportedCellularClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_CELLULAR_CLASS CellularClass - ) -{ - MbbAdapterLock( Adapter ); - Adapter->AdapterSupportedCellularClass = CellularClass; - MbbAdapterUnlock( Adapter ); -} - -_Requires_lock_not_held_(&Adapter->Lock) -MBB_CELLULAR_CLASS -MbbAdapterGetSupportedCellularClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - MBB_CELLULAR_CLASS CellularClass; - - MbbAdapterLock( Adapter ); - CellularClass = Adapter->AdapterSupportedCellularClass; - MbbAdapterUnlock( Adapter ); - return CellularClass; -} - -_Requires_lock_not_held_(&Adapter->Lock) -BOOLEAN -MbbAdapterIsMultimodeCapable( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - ULONG BitValue; - - MbbAdapterLock( Adapter ); - BitValue = (ULONG)(Adapter->AdapterSupportedCellularClass); - MbbAdapterUnlock( Adapter ); - // - // If only a single bit is set then the following expression - // should be zero. Otherwise this will be set to the "other" bits. - // - if( (BitValue & (BitValue - 1)) != 0 ) - return TRUE; - else - return FALSE; -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetCurrentCellularClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_CELLULAR_CLASS CellularClass - ) -{ - MbbAdapterLock( Adapter ); - Adapter->AdapterCurrentCellularClass = CellularClass; - MbbAdapterUnlock( Adapter ); -} - -_Requires_lock_not_held_(&Adapter->PortsLock) -VOID -MbbAdapterSetMaxActivatedContexts( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in ULONG dwMaxActivatedContexts - ) -{ - ASSERT(dwMaxActivatedContexts >= 1); - MbbAdapterPortsLock(Adapter); - Adapter->MaxActivatedContexts = (dwMaxActivatedContexts < MBB_MAX_NUMBER_OF_PORTS) ? dwMaxActivatedContexts: MBB_MAX_NUMBER_OF_PORTS; - MbbAdapterPortsUnlock(Adapter); -} - - -_Requires_lock_not_held_(&Adapter->Lock) -MBB_CELLULAR_CLASS -MbbAdapterGetCurrentCellularClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - MBB_CELLULAR_CLASS CellularClass; - - MbbAdapterLock( Adapter ); - CellularClass = Adapter->AdapterCurrentCellularClass; - MbbAdapterUnlock( Adapter ); - return CellularClass; -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetRequestManager( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_REQUEST_MANAGER RequestManager - ) -{ - MbbAdapterLock( Adapter ); - Adapter->RequestManager = RequestManager; - MbbAdapterUnlock( Adapter ); -} - -_Requires_lock_not_held_(&Adapter->Lock) -PMBB_REQUEST_MANAGER -MbbAdapterGetRequestManager( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -/*++ -Description - Synchronizes access to request manager with its lifetime. - Try to return a valid request manager reference. - Caller is required to derefernce the request manager. - -Return Value - non-NULL - Request Manager is successfully returned. - NULL - Request Manager is not initialized or could not be referenced. ---*/ -{ - PMBB_REQUEST_MANAGER RequestManager = NULL; - - MbbAdapterLock( Adapter ); - if( Adapter->RequestManager && - MbbReqMgrRef( Adapter->RequestManager ) ) - { - RequestManager = Adapter->RequestManager; - } - MbbAdapterUnlock( Adapter ); - - return RequestManager; -} - -_Requires_lock_not_held_(&Adapter->Lock) -NDIS_STATUS -MbbAdapterQueryDeviceId( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_DEVICE_CAPS }; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager for QueryDeviceCaps" ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to allocate RequestContext for QueryDeviceCaps" ); - break; - } - Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - - // - // Ref the request so that the response handler does not free it - // - MbbReqMgrRefRequest( Request ); - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbUtilInternalCIDQuery, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If the request is pending wait for it to complete. - // If the request didnt complete within the timeout period drop our ref count and fail to the caller. - // Something is wrong with a device that does not send response for a non-network request - // If dispatching the request failed then our completion callback will not be invoked, - // in this case destroy the request. - // - if( NdisStatus == NDIS_STATUS_PENDING ) - { - Timeout.QuadPart = -1 * 10 * MBB_ADAPTER_INITIAL_REQUEST_TIMEOUT_MS; - NdisStatus = KeWaitForSingleObject( - &Request->WaitEvent, - Executive, - KernelMode, - TRUE, // Alertable - &Timeout // Timeout - ); - if( NdisStatus != STATUS_WAIT_0 ) - { - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - // - // Only if Send was successful then get the response status. - // - if( (NdisStatus = Request->HandlerContext.Command.SendStatus) == NDIS_STATUS_SUCCESS ) - NdisStatus = Request->HandlerContext.Response.NdisStatus; - } - } - else if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - // - // It is ok to destroy the request here and deref it later. - // Destroy will not free the request while there is a pending ref. - // - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - - if( NdisStatus == NDIS_STATUS_SUCCESS ) - { - PCHAR pDeviceId = (PCHAR)(Request->HandlerContext.Parameters.DeviceCaps.DeviceId); - CHAR cOctet[MBB_MAC_ADDRESS_LENGTH]; - ULONG ulOctetIndex; - - RtlZeroMemory( - cOctet, - MBB_MAC_ADDRESS_LENGTH - ); - - // - // XOR the bytes to get a 6-byte MAC - // Left shift is done for more randomization. - // - for(ulOctetIndex = 0; - pDeviceId[ulOctetIndex*2]; - ulOctetIndex++ ) - { - cOctet[ulOctetIndex % MBB_MAC_ADDRESS_LENGTH] ^= ( pDeviceId[ulOctetIndex*2] << (ulOctetIndex / MBB_MAC_ADDRESS_LENGTH) ); - } - - // - // Mask of the multicast and locally administered bit - // - cOctet[0] &= ~0x03; - - RtlCopyMemory( - Adapter->MACAddress, - cOctet, - MBB_MAC_ADDRESS_LENGTH - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - if( Request != NULL ) - { - MbbReqMgrDerefRequest( Request ); - } - return NdisStatus; -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterResetCapabilities( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - MbbAdapterLock( Adapter ); - Adapter->AdapterFlags.IsUssdCapable = FALSE; - Adapter->AdapterFlags.IsSimAuthCapable = FALSE; - Adapter->AdapterFlags.IsAkaAuthCapable = FALSE; - Adapter->AdapterFlags.IsAkapAuthCapable = FALSE; - MbbAdapterUnlock( Adapter ); -} - -NDIS_STATUS -MbbAdapterQueryMultiCarrierDsCidList( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in const GUID* Guid, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus; - LARGE_INTEGER Timeout; - PMBB_REQUEST_CONTEXT NewRequest = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - PMBB_DS MbbDs; - MBB_COMMAND Command = { - MBB_UUID_MULTICARRIER_CONSTANT, - MBB_MULTICARRIER_CID_CURRENT_CID_LIST - }; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED to reference RequestManager", Request->RequestId ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - if( (NewRequest = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED to allocate RequestContext", Request->RequestId ); - break; - } - NewRequest->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - // - // Cache the context from the previous request since it will be destroyed - // - NewRequest->OidContext.OidRequestId = Request->OidContext.OidRequestId; - NewRequest->OidContext.OidRequestHandle = Request->OidContext.OidRequestHandle; - NewRequest->HandlerContext.Parameters.DeviceCaps= Request->HandlerContext.Parameters.DeviceCaps; - - TraceInfo( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x][ReqId=0x%04x] Request created to query CID list for DS=%!GUID!", Request->RequestId, NewRequest->RequestId, Guid ); - - MBB_UUID_TO_NET( - &NewRequest->HandlerContext.Parameters.DeviceCaps.CurrentQueriedDeviceService, - Guid - ); - - NdisStatus = MbbReqMgrDispatchRequest( - NewRequest, - (TRUE == Request->OidHandler->IsSerialized), - MbbUtilInternalCIDQuery, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - if( NdisStatus != NDIS_STATUS_PENDING && - NdisStatus != NDIS_STATUS_INDICATION_REQUIRED ) - { - // - // It is ok to destroy the request here and deref it later. - // Destroy will not free the request while there is a pending ref. - // - MbbReqMgrDestroyRequest( - NewRequest->RequestManager, - NewRequest - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - RequestManager = NULL; - } - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterMultiCarrierDeviceServicesToCapabilities( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - do - { - if( Request->HandlerContext.Parameters.DeviceCaps.IsUssdCapsValid == 0 ) - { - NdisStatus = MbbAdapterQueryMultiCarrierDsCidList( - Adapter, - &MBB_UUID_USSD, - Request - ); - if( NDIS_STATUS_SUCCESS != NdisStatus && - NDIS_STATUS_PENDING != NdisStatus ) - { - TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED MbbAdapterQueryMultiCarrierDsCidList(USSD)=%!STATUS!", Request->RequestId, NdisStatus ); - break; - } - } - else if( Request->HandlerContext.Parameters.DeviceCaps.IsAuthCapsValid == 0 ) - { - NdisStatus = MbbAdapterQueryMultiCarrierDsCidList( - Adapter, - &MBB_UUID_AUTH, - Request - ); - if( NDIS_STATUS_SUCCESS != NdisStatus && - NDIS_STATUS_PENDING != NdisStatus ) - { - TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED MbbAdapterQueryMultiCarrierDsCidList(AUTH)=%!STATUS!", Request->RequestId, NdisStatus ); - break; - } - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbAdapterSingleCarrierDeviceServicesToCapabilities( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - ULONG CidIndex; - PMBB_DS MbbDs; - - MbbDs = MbbUtilFindDeviceService( - Adapter, - (GUID*)&MBB_UUID_USSD - ); - if( MbbDs != NULL ) - { - MbbAdapterLock( Adapter ); - Adapter->AdapterFlags.IsUssdCapable = TRUE; - MbbAdapterUnlock( Adapter ); - } - - MbbDs = MbbUtilFindDeviceService( - Adapter, - (GUID*)&MBB_UUID_AUTH - ); - if( MbbDs != NULL ) - { - MbbAdapterLock( Adapter ); - for(CidIndex = 0; - CidIndex < MbbDs->CIDCount; - CidIndex++ ) - { - switch( MbbDs->CIDList[CidIndex] ) - { - case MBB_AUTH_CID_AKA: - { - Adapter->AdapterFlags.IsAkaAuthCapable = TRUE; - } - break; - - case MBB_AUTH_CID_AKAP: - { - Adapter->AdapterFlags.IsAkapAuthCapable = TRUE; - } - break; - - case MBB_AUTH_CID_SIM: - { - Adapter->AdapterFlags.IsSimAuthCapable = TRUE; - } - break; - } - } - MbbAdapterUnlock( Adapter ); - } - Request->HandlerContext.Parameters.DeviceCaps.IsUssdCapsValid = 1; - Request->HandlerContext.Parameters.DeviceCaps.IsAuthCapsValid = 1; - return NDIS_STATUS_SUCCESS; -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetShutdownNotificationCapabilities( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - ULONG CidIndex; - PMBB_DS MbbDs; - - MbbDs = MbbUtilFindDeviceService( - Adapter, - (GUID*)&MBB_UUID_HOSTSHUTDOWN - ); - if (MbbDs != NULL) - { - MbbAdapterLock(Adapter); - for (CidIndex = 0; - CidIndex < MbbDs->CIDCount; - CidIndex++) - { - switch (MbbDs->CIDList[CidIndex]) - { - case MBB_HOSTSHUTDOWN_CID_ONE: - { - Adapter->AdapterFlags.ShutdownNotificationCapable = TRUE; - } - break; - - case MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN: - { - Adapter->AdapterFlags.IsPreshutdownCapable = TRUE; - } - break; - } - } - MbbAdapterUnlock(Adapter); - } - - return; -} - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetOptionalServiceSupport( - __in PMINIPORT_ADAPTER_CONTEXT Adapter -) -{ - ULONG CidIndex; - PMBB_DS MbbDs; - - MbbDs = MbbUtilFindDeviceService( - Adapter, - (GUID*)&MBB_UUID_BASIC_CONNECT_EXTENSIONS - ); - if (MbbDs != NULL) - { - MbbAdapterLock(Adapter); - for (CidIndex = 0; - CidIndex < MbbDs->CIDCount; - CidIndex++) - { - switch (MbbDs->CIDList[CidIndex]) - { - case MBB_BASICCONNECTEXT_CID_PROVISIONED_CONTEXT_V2: - { - Adapter->AdapterFlags.IsProvisionedContextV2Capable = TRUE; - } - break; - - case MBB_BASICCONNECTEXT_CID_NETWORK_BLACKLIST: - { - Adapter->AdapterFlags.IsNetworkBlacklistCapable = TRUE; - } - break; - - case MBB_BASICCONNECTEXT_CID_LTE_ATTACH_CONFIG: - { - Adapter->AdapterFlags.IsLTEAttachConfigCapable = TRUE; - } - break; - - case MBB_BASICCONNECTEXT_CID_DEVICE_SLOT_MAPPINGS: - { - Adapter->AdapterFlags.IsMultiSIMCapable = TRUE; - } - break; - - case MBB_BASICCONNECTEXT_CID_DEVICE_CAPS_V2: - { - Adapter->AdapterFlags.IsDeviceCapsV2Capable = TRUE; - } - break; - - case MBB_BASICCONNECTEXT_CID_PCO: - { - Adapter->AdapterFlags.IsPcoCapable = TRUE; - } - break; - - case MBB_BASICCONNECTEXT_CID_DEVICE_RESET: - { - Adapter->AdapterFlags.IsDeviceResetCapable = TRUE; - } - break; - - case MBB_BASICCONNECTEXT_CID_BASE_STATIONS_INFO: - { - Adapter->AdapterFlags.IsBaseStationsInfoCapable = TRUE; - } - break; - - } - } - MbbAdapterUnlock(Adapter); - } - - MbbDs = MbbUtilFindDeviceService( - Adapter, - (GUID*)&MBB_UUID_SARCONTROL - ); - if (MbbDs != NULL) - { - MbbAdapterLock(Adapter); - for (CidIndex = 0; - CidIndex < MbbDs->CIDCount; - CidIndex++) - { - switch (MbbDs->CIDList[CidIndex]) - { - case MBB_SAR_CID_CONFIG: - { - Adapter->AdapterFlags.IsSARCapable = TRUE; - } - break; - } - } - MbbAdapterUnlock(Adapter); - } - - MbbDs = MbbUtilFindDeviceService( - Adapter, - (GUID*)&MBB_UUID_UICC_LOW_LEVEL - ); - if (MbbDs != NULL) - { - MbbAdapterLock(Adapter); - for (CidIndex = 0; - CidIndex < MbbDs->CIDCount; - CidIndex++) - { - switch (MbbDs->CIDList[CidIndex]) - { - case MBB_UICC_CID_ATR: - { - // if this CID is supported, the entire group of MBB_UUID_UICC_LOW_LEVEL CIDs must be supported. - Adapter->AdapterFlags.IsUiccLowLevelCapable = TRUE; - } - break; - } - } - MbbAdapterUnlock(Adapter); - } - - return; -} - -_Requires_lock_not_held_(&Adapter->Lock) -NDIS_STATUS -MbbAdapterFWDeviceServicesToCapabilities( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_REQUEST_CONTEXT Request - ) -/*++ -Description: - Check whether the optional multi-carrier - device service is implemented by the device. The presence - of the multi-carrier device service indicates that this - is a multi-carrier device. This method is called from - device caps query path. ---*/ -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PNDIS_WWAN_DEVICE_CAPS NdisDeviceCaps = Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCaps; - - do - { - // - //If this is not a multi-carrier device then get - //get the supported native device services from the - //device services. If this is a multi-carrier device - //find the support for USSD and AUTH. - // - if( NdisDeviceCaps->DeviceCaps.WwanControlCaps & WWAN_CTRL_CAPS_MODEL_MULTI_CARRIER ) - { - NdisStatus = MbbAdapterMultiCarrierDeviceServicesToCapabilities( Adapter, Request ); - if( NDIS_STATUS_SUCCESS != NdisStatus && - NDIS_STATUS_PENDING != NdisStatus ) - { - TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED MbbAdapterMultiCarrierDeviceServicesToCapabilities()=%!STATUS!", Request->RequestId, NdisStatus ); - break; - } - } - else - { - NdisStatus = MbbAdapterSingleCarrierDeviceServicesToCapabilities( Adapter, Request ); - if( NDIS_STATUS_SUCCESS != NdisStatus && - NDIS_STATUS_PENDING != NdisStatus ) - { - TraceError( WMBCLASS_OID, "[MbbAdapter][ReqId=0x%04x] FAILED MbbAdapterSingleCarrierDeviceServicesToCapabilities()=%!STATUS!", Request->RequestId, NdisStatus ); - break; - } - } - } - while( FALSE ); - - return NdisStatus; -} - -_Requires_lock_not_held_(&SendQueue->AdapterContext->Lock) -VOID TryQueueStallState(_In_ PMBB_SEND_QUEUE SendQueue) -{ - PSTATE_CHANGE_EVENT StateChange = NULL; - - MbbAdapterLock(SendQueue->AdapterContext); - - if (!SendQueue->AdapterContext->AdapterState.Hung) - { - StateChange = AllocateStateChangeEvent(&SendQueue->AdapterContext->AdapterState); - - if (StateChange != NULL) - { - SendQueue->AdapterContext->AdapterState.Hung = TRUE; - - StateChange->EventType = STATE_CHANGE_TYPE_STALL_CLEAR; - StateChange->Context1 = SendQueue->AdapterContext; - - TraceInfo(WMBCLASS_OID, "%!FUNC!: Reset data pipe has been scheduled"); - KeResetEvent(&SendQueue->AdapterContext->AdapterState.StallClearCompleteEvent); - QueueStateChangeEvent(&SendQueue->AdapterContext->AdapterState, StateChange); - - } - else - { - TraceError(WMBCLASS_OID, "%!FUNC!: Reset data pipe isn't scheduled since AllocateStateChangeEvent failed"); - } - } - else - { - TraceError(WMBCLASS_OID, "%!FUNC!: Skip reset data pipe since it has already been scheduled, "); - } - - MbbAdapterUnlock(SendQueue->AdapterContext); -} - -VOID WaitStallClearComplete( - _In_ PADAPTER_STATE AdapterState -) -{ - if (AdapterState->WorkItem != NULL) - { - KeWaitForSingleObject( - &AdapterState->StallClearCompleteEvent, - Executive, - KernelMode, - FALSE, // Alertable - NULL // Timeout - ); - } -} \ No newline at end of file diff --git a/network/wwan/cxwmbclass/adapter.cpp b/network/wwan/cxwmbclass/adapter.cpp new file mode 100644 index 000000000..17d7e941a --- /dev/null +++ b/network/wwan/cxwmbclass/adapter.cpp @@ -0,0 +1,197 @@ +//------------------------------------------------------------------------------- +// Net Adapter source file +// +// Copyright (c) Microsoft Corporation. All rights reserved. +#include "precomp.h" + +#include "device.h" +#include "txqueue.h" +#include "rxqueue.h" + +_Use_decl_annotations_ NTSTATUS WmbClassAdapterStart(NETADAPTER netAdapter) +{ + NTSTATUS status = STATUS_SUCCESS; + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = WmbClassGetNetAdapterContext(netAdapter); + PWMBCLASS_DEVICE_CONTEXT deviceContext = netAdapterContext->WmbDeviceContext; + + ULONG64 maxXmitLinkSpeed = MBB_MEDIA_MAX_SPEED; + ULONG64 maxRcvLinkSpeed = MBB_MEDIA_MAX_SPEED; + DWORD maxPowerFilterSize = 0; + + NET_ADAPTER_LINK_LAYER_CAPABILITIES linkLayerCapabilities; + NET_ADAPTER_LINK_LAYER_CAPABILITIES_INIT(&linkLayerCapabilities, maxXmitLinkSpeed, maxRcvLinkSpeed); + + NetAdapterSetLinkLayerCapabilities(netAdapter, &linkLayerCapabilities); + + if (deviceContext->BusParams.IsErrataDevice) + { + NetAdapterSetLinkLayerMtuSize(netAdapter, deviceContext->BusParams.MTU); + } + else + { + NetAdapterSetLinkLayerMtuSize(netAdapter, deviceContext->BusParams.MaxSegmentSize); + } + + if (deviceContext->BusParams.PowerFiltersSupported > 0) + { + NET_ADAPTER_WAKE_BITMAP_CAPABILITIES bitmapCapabilities; + NET_ADAPTER_WAKE_BITMAP_CAPABILITIES_INIT(&bitmapCapabilities); + + bitmapCapabilities.BitmapPattern = TRUE; + bitmapCapabilities.MaximumPatternCount = deviceContext->BusParams.PowerFiltersSupported; + + if (deviceContext->BusParams.IsErrataDevice) + { + // For errata devices we will report the device specific max pattern size. + // 192 bytes is the maximum power filter size as per the MBIM spec. + // If a device reports more than 192 bytes as the power filter size, we + // normalize it here to 192 bytes. This will prevent erroneous devices + // from indicating arbitrary pattern size. This needs to change with any + // MBIM spec revision. + + if (deviceContext->BusParams.MaxPowerFilterSize > WMBCLASS_MAX_MBIM_WOL_PATTERN) + { + maxPowerFilterSize = WMBCLASS_MAX_MBIM_WOL_PATTERN; + } + else + { + maxPowerFilterSize = deviceContext->BusParams.MaxPowerFilterSize; + } + } + else + { + // To maintain backward compatibility with Win8 devices, we continue + // reporting 256 bytes as the wake pattern size. + maxPowerFilterSize = WMBCLASS_MAX_WOL_PATTERN; + } + + bitmapCapabilities.MaximumPatternSize = maxPowerFilterSize; + + NetAdapterWakeSetBitmapCapabilities(netAdapter, &bitmapCapabilities); + } + + NET_ADAPTER_WAKE_MEDIA_CHANGE_CAPABILITIES wakeMediaChangeCapabilities; + NET_ADAPTER_WAKE_MEDIA_CHANGE_CAPABILITIES_INIT(&wakeMediaChangeCapabilities); + + wakeMediaChangeCapabilities.MediaConnect = TRUE; + wakeMediaChangeCapabilities.MediaDisconnect = TRUE; + + NetAdapterWakeSetMediaChangeCapabilities(netAdapter, &wakeMediaChangeCapabilities); + + if (deviceContext->BusParams.SelectiveSuspendSupported) + { + NET_ADAPTER_WAKE_PACKET_FILTER_CAPABILITIES wakePacketFilterCapabilities; + NET_ADAPTER_WAKE_PACKET_FILTER_CAPABILITIES_INIT(&wakePacketFilterCapabilities); + wakePacketFilterCapabilities.PacketFilterMatch = TRUE; + + NetAdapterWakeSetPacketFilterCapabilities(netAdapter, &wakePacketFilterCapabilities); + } + + NET_ADAPTER_TX_CAPABILITIES txCapabilities; + NET_ADAPTER_TX_CAPABILITIES_INIT(&txCapabilities, 1); + NET_ADAPTER_RX_CAPABILITIES rxCapabilities; + NET_ADAPTER_RX_CAPABILITIES_INIT_DRIVER_MANAGED(&rxCapabilities, EvtAdapterReturnRxBuffer, MBB_MAX_PACKET_SIZE, 1); + + NetAdapterSetDataPathCapabilities(netAdapter, &txCapabilities, &rxCapabilities); + + status = NetAdapterStart(netAdapter); + + return status; +} + +NTSTATUS +EvtAdapterCreateTxQueue(_In_ NETADAPTER netAdapter, _Inout_ NETTXQUEUE_INIT* txQueueInit) +{ + NTSTATUS status = STATUS_SUCCESS; + PMBB_TXQUEUE_CONTEXT txQueueContext = NULL; + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = WmbClassGetNetAdapterContext(netAdapter); + PWMBCLASS_DEVICE_CONTEXT deviceContext = netAdapterContext->WmbDeviceContext; + WDF_OBJECT_ATTRIBUTES txAttributes; + NET_EXTENSION_QUERY extension; + + WDF_OBJECT_ATTRIBUTES_INIT(&txAttributes); + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&txAttributes, MBB_TXQUEUE_CONTEXT); + + txAttributes.EvtDestroyCallback = EvtTxQueueDestroy; + + NET_PACKET_QUEUE_CONFIG queueConfig; + NET_PACKET_QUEUE_CONFIG_INIT(&queueConfig, EvtTxQueueAdvance, EvtTxQueueSetNotificationEnabled, EvtTxQueueCancel); + + NETPACKETQUEUE txQueue; + status = NetTxQueueCreate(txQueueInit, &txAttributes, &queueConfig, &txQueue); + + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + txQueueContext = MbbGetTxQueueContext(txQueue); + + + txQueueContext->NetAdapterContext = netAdapterContext; + txQueueContext->DatapathDescriptor = NetTxQueueGetRingCollection(txQueue); + + // Try to use MaxOutDatagrams parameter as the tx completion batch size, but limit to half of the packet ring buffer + auto maxBatchSize = NetRingCollectionGetPacketRing(txQueueContext->DatapathDescriptor)->NumberOfElements / 2; + txQueueContext->CompletionBatchSize = min(deviceContext->BusParams.MaxOutDatagrams, maxBatchSize); + + NET_EXTENSION_QUERY_INIT(&extension, NET_FRAGMENT_EXTENSION_MDL_NAME, NET_FRAGMENT_EXTENSION_MDL_VERSION_1, NetExtensionTypeFragment); + + NetTxQueueGetExtension(txQueue, &extension, &txQueueContext->MdlExtension); + + netAdapterContext->TxQueue = txQueue; +Exit: + return status; +} + +void EvtRxQueueStart(_In_ NETPACKETQUEUE rxQueue) +{ + MbbGetRxQueueContext(rxQueue)->NetAdapterContext->AllowRxTraffic = TRUE; +} + +NTSTATUS +EvtAdapterCreateRxQueue(_In_ NETADAPTER netAdapter, _Inout_ NETRXQUEUE_INIT* rxQueueInit) +{ + NTSTATUS status = STATUS_SUCCESS; + + PMBB_RXQUEUE_CONTEXT rxQueueContext = NULL; + WDF_OBJECT_ATTRIBUTES rxAttributes; + NET_EXTENSION_QUERY extension; + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = WmbClassGetNetAdapterContext(netAdapter); + + NET_PACKET_QUEUE_CONFIG rxConfig; + NET_PACKET_QUEUE_CONFIG_INIT(&rxConfig, EvtRxQueueAdvance, EvtRxQueueSetNotificationEnabled, EvtRxQueueCancel); + rxConfig.EvtStart = EvtRxQueueStart; + + WDF_OBJECT_ATTRIBUTES_INIT(&rxAttributes); + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&rxAttributes, MBB_RXQUEUE_CONTEXT); + rxAttributes.EvtDestroyCallback = EvtRxQueueDestroy; + + NETPACKETQUEUE rxQueue; + status = NetRxQueueCreate(rxQueueInit, &rxAttributes, &rxConfig, &rxQueue); + + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + rxQueueContext = MbbGetRxQueueContext(rxQueue); + + NET_EXTENSION_QUERY_INIT(&extension, NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME, NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_VERSION_1, NetExtensionTypeFragment); + + NetRxQueueGetExtension(rxQueue, &extension, &rxQueueContext->VirtualAddressExtension); + + rxQueueContext->NetAdapterContext = netAdapterContext; + rxQueueContext->DatapathDescriptor = NetRxQueueGetRingCollection(rxQueue); + + NET_EXTENSION_QUERY_INIT(&extension, NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME, NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1, NetExtensionTypeFragment); + + NetRxQueueGetExtension(rxQueue, &extension, &rxQueueContext->ReturnContextExtension); + + // Set netAdapterContext->RxQueue to mean EvtAdapterCreateRxQueue completed successfully + netAdapterContext->RxQueue = rxQueue; + +Exit: + + return status; +} diff --git a/network/wwan/cxwmbclass/adapter.h b/network/wwan/cxwmbclass/adapter.h deleted file mode 100644 index 0e9b7cf38..000000000 --- a/network/wwan/cxwmbclass/adapter.h +++ /dev/null @@ -1,337 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// - -typedef struct _WWAN_IP_ADDRESS_STATE WWAN_IP_ADDRESS_STATE; -// -// Adapter routines -// -_Acquires_lock_( Adapter->Lock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterLock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Releases_lock_( Adapter->Lock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterUnlock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Acquires_lock_( Adapter->PortsLock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterPortsLock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Releases_lock_( Adapter->PortsLock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterPortsUnlock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Acquires_lock_( Adapter->SessionIdPortTableLock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterSessionIdPortTableLock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Releases_lock_( Adapter->SessionIdPortTableLock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, Adapter ) -VOID -MbbAdapterSessionIdPortTableUnlock( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - - -BOOLEAN -MbbAdapterIsReady( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -VOID -MbbAdapterConnectionChange( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in PMBB_CONNECTION_STATE ConnectionState, - __in NDIS_PORT_NUMBER PortNumber - ); - -VOID -MbbAdapterSetConnectionState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_CONNECTION_STATE ConnectionState, - __in NDIS_PORT_NUMBER PortNumber - ); - -VOID -MbbAdapterSetLinkState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_CONNECTION_STATE ConnectionState, - __in NDIS_PORT_NUMBER PortNumber - ); - -VOID -MbbAdapterSetPortState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_CONNECTION_STATE ConnectionState, - __in NDIS_PORT_NUMBER PortNumber - ); - -VOID -MbbPortSetIpAddressState( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PWWAN_IP_ADDRESS_STATE WwanIpAddressState, - __in NDIS_PORT_NUMBER PortNumber - ); - -BOOLEAN -MbbPortIsConnected( - __in PMBB_PORT Port - ); - -VOID -MbbAdapterRef( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -VOID -MbbAdapterDeref( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -NDIS_STATUS -MbbAdapterPerformInitialRequests( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -NTSTATUS -InitAdapterStateObject( - __out PADAPTER_STATE AdapterState, - __in NDIS_HANDLE MiniportAdapterContext, - MBB_STATE_CHANGE_HANDLER PauseHandler, - MBB_STATE_CHANGE_HANDLER RestartHandler, - MBB_STATE_CHANGE_HANDLER PowerHandler, - MBB_STATE_CHANGE_HANDLER ResetHandler, - MBB_STATE_CHANGE_HANDLER StallClearHandler - ); - -VOID -ShutdownAdapterStateObject( - PADAPTER_STATE AdapterState - ); - -VOID -QueueStateChangeEvent( - PADAPTER_STATE AdapterState, - PSTATE_CHANGE_EVENT StateChange - ); - -VOID -CompleteStateChange( - PADAPTER_STATE AdapterState, - PSTATE_CHANGE_EVENT StateChange - ); - - -PSTATE_CHANGE_EVENT -AllocateStateChangeEvent( - PADAPTER_STATE AdapterState - ); - -VOID -FreeStateChangeEvent( - PADAPTER_STATE AdapterState, - PSTATE_CHANGE_EVENT StateChange - ); - -VOID -FreeDeviceServiceState( - __in PMBB_DS_STATE DeviceServiceState - ); - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetMultiCarrierCapable( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN IsMultiCarrierSupported - ); - -_Requires_lock_not_held_(&Adapter->Lock) -BOOLEAN -MbbAdapterIsMultiCarrierCapable( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetDataClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in ULONG DataClass - ); - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterGetDataClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __out ULONG* DataClass - ); - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetSupportedCellularClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_CELLULAR_CLASS CellularClass - ); - -_Requires_lock_not_held_(&Adapter->Lock) -MBB_CELLULAR_CLASS -MbbAdapterGetSupportedCellularClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Requires_lock_not_held_(&Adapter->Lock) -BOOLEAN -MbbAdapterIsMultimodeCapable( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetCurrentCellularClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_CELLULAR_CLASS CellularClass - ); - -_Requires_lock_not_held_(&Adapter->Lock) -MBB_CELLULAR_CLASS -MbbAdapterGetCurrentCellularClass( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Requires_lock_not_held_(&Adapter->PortsLock) -VOID -MbbAdapterSetMaxActivatedContexts( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in DWORD dwMaxActivatedContexts - ); - - -NDIS_STATUS -MbbAdapterConfigurePacketFilters( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN Set - ); - -NDIS_STATUS -MbbAdapterConfigurePacketFiltersOnSession( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN Set, - __in NDIS_PORT_NUMBER PortNumber - ); - -NDIS_STATUS -MbbAdapterConfigureDeviceServiceSubscription( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN FullPower, - __in ULONG MediaSpecificWakeUpEvents, - __in ULONG WakeUpEvents - ); - -NDIS_STATUS -MbbAdapterSendNetworkIdleHint( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetRequestManager( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_REQUEST_MANAGER RequestManager - ); - -_Requires_lock_not_held_(&Adapter->Lock) -PMBB_REQUEST_MANAGER -MbbAdapterGetRequestManager( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Requires_lock_not_held_(&Adapter->Lock) -NDIS_STATUS -MbbAdapterQueryDeviceId( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Requires_lock_not_held_(&Adapter->Lock) -NDIS_STATUS -MbbAdapterFWDeviceServicesToCapabilities( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_REQUEST_CONTEXT Request - ); - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterResetCapabilities( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - - -VOID -AdapterStallClearHandler( - PSTATE_CHANGE_EVENT StateChange - ); - - -NDIS_STATUS -MbbAdapterSendNetworkShutdownHint( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -NDIS_STATUS -MbbAdapterSendPreShutdown( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter -); - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetShutdownNotificationCapabilities( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -VOID -MbbAdapterIndicateD3Exit( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in NDIS_PORT_NUMBER PortNumber - ); - - -_Requires_lock_not_held_(&Adapter->Lock) -VOID -MbbAdapterSetOptionalServiceSupport( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -_Requires_lock_not_held_(&SendQueue->AdapterContext->Lock) -VOID TryQueueStallState( - _In_ PMBB_SEND_QUEUE SendQueue -); - -VOID WaitStallClearComplete( - _In_ PADAPTER_STATE AdapterState -); diff --git a/network/wwan/cxwmbclass/businit.cpp b/network/wwan/cxwmbclass/businit.cpp new file mode 100644 index 000000000..063415c02 --- /dev/null +++ b/network/wwan/cxwmbclass/businit.cpp @@ -0,0 +1,2043 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +#include + +#pragma pack(push, 1) + +typedef struct _USB_DESCRIPTOR_HEADER +{ + + BYTE bLength; + BYTE bDescriptorType; + +} USB_DESCRIPTOR_HEADER, *PUSB_DESCRIPTOR_HEADER; + +#pragma pack(pop) + +NTSTATUS +MbbParseConfigDescriptor( + WDFUSBDEVICE WdfUsbDevice, + PUSHORT MaxSegmentSize, + PUCHAR NcmCaps, + PUCHAR PowerFiltersSupported, + PUCHAR MaxPowerFilterSize, + PUCHAR CommunicationClassInterface, + PUCHAR DataClassInterface, + PUSHORT MaxControlMessage, + PUCHAR AltCommunicationClassSetting, + PUCHAR AltDataClassSetting, + PUSHORT BulkInDataClassPacketSize, + PUSHORT MTU, + PUSHORT MbimVersion, + PUSHORT MbimExtendedVersion); + +NTSTATUS +GetNtbParameters(WDFUSBDEVICE WdfUsbDevice, PNCM_NTB_PARAMETER NcmNtb); + +NTSTATUS +GetDeviceString(__in WDFUSBDEVICE UsbDevice, __in UCHAR Index, __out PWSTR* String); + +VOID FreeBusObject(_In_ __drv_freesMem(Mem) PBUS_OBJECT BusObject); + +NTSTATUS +SetActivityIdForRequest(__in WDFREQUEST Request, __in LPGUID ActivityId); + +void ResetDataPipeWorkItem(_In_ WDFWORKITEM WorkItem); + +EVT_WDF_USB_READER_COMPLETION_ROUTINE InterruptPipeReadComplete; +EVT_WDF_USB_READERS_FAILED InterruptPipeReadError; + +NTSTATUS +MbbBusInitializeByWdf( + _In_ WDFDEVICE WdfDevice, + _In_ MBB_BUS_RESPONSE_AVAILABLE_CALLBACK ResponseAvailableCallback, + _In_ MBB_BUS_DATA_RECEIVE_CALLBACK ReceiveDataCallback, + _In_ MBB_BUS_SS_IDLE_CONFIRM_CALLBACK IdleConfirmCallback, + _In_ MBB_BUS_SS_IDLE_NOTIFICATION_COMPLETE_CALLBACK IdleNotificationComplete, + _In_ MBB_PROTOCOL_HANDLE ProtocolHandle, + _Outptr_ MBB_BUS_HANDLE* BusHandle, + _Inout_opt_ MBB_BUS_HANDLE preAllocatedBusObject) +{ + NTSTATUS Status = STATUS_SUCCESS; + WDF_OBJECT_ATTRIBUTES attributes; + + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; + PWDF_USB_INTERFACE_SETTING_PAIR settingPairs = NULL; + WDF_USB_INTERFACE_SELECT_SETTING_PARAMS SettingParams; + WDFUSBPIPE pipe; + WDF_USB_PIPE_INFORMATION pipeInfo; + WDFUSBINTERFACE UsbInterface = NULL; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + USB_DEVICE_DESCRIPTOR DeviceDescriptor; + USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + WDF_USB_DEVICE_CREATE_CONFIG Config; + + WDF_WORKITEM_CONFIG workitemConfig; + WDF_OBJECT_ATTRIBUTES workitemAttributes; + + UCHAR numInterfaces; + UCHAR interfaceIndex; + UCHAR i; + UCHAR index; + USHORT DescriptorSize = 0; + UCHAR DummyBuffer; + UCHAR CurrentSetting; + USHORT BulkInPacketSize = 0; + WDF_USB_CONTINUOUS_READER_CONFIG ReaderConfig; + + PIRP UsbSsIrp = NULL; + USB_IDLE_CALLBACK_INFO UsbSsCallback; + + PBUS_OBJECT BusObject = NULL; + + USB_CAP_DEVICE_INFO usbCapDeviceInfo = {USB_CAP_DEVICE_TYPE_MAXIMUM, 0, 0, 0}; + ULONG capResultLength = 0; + + WDF_USB_DEVICE_INFORMATION deviceInformation; + + *BusHandle = NULL; + + if (preAllocatedBusObject == NULL) + { + + BusObject = (PBUS_OBJECT)ALLOCATE_NONPAGED_POOL(sizeof(BUS_OBJECT)); + + if (BusObject == NULL) + { + Status = STATUS_NO_MEMORY; + goto Cleanup; + } + + RtlZeroMemory(BusObject, sizeof(*BusObject)); + + BusObject->Fdo = WdfDeviceWdmGetDeviceObject(WdfDevice); + + INITIALIZE_PASSIVE_LOCK(&BusObject->Lock); + BusObject->State = BUS_STATE_CLOSED; + + BusObject->ProtocolHandle = ProtocolHandle; + BusObject->ResponseAvailableCallback = ResponseAvailableCallback; + BusObject->ReceiveDataCallback = ReceiveDataCallback; + BusObject->IdleConfirmCallback = IdleConfirmCallback; + BusObject->IdleNotificationComplete = IdleNotificationComplete; + + } + else + { + BusObject = (PBUS_OBJECT)preAllocatedBusObject; + } + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, USB_DEVICE_CONTEXT); + + WDF_USB_DEVICE_CREATE_CONFIG_INIT(&Config, USBD_CLIENT_CONTRACT_VERSION_602); + + Status = WdfUsbTargetDeviceCreateWithParameters(WdfDevice, &Config, &attributes, &BusObject->WdfUsbDevice); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + usbDeviceContext->BulkPipeResetFlag = FALSE; + usbDeviceContext->BulkPipeResetWorkitem = NULL; + + // + // create a work item to reset data pipe + // + ExInitializeRundownProtection(&usbDeviceContext->BulkPipeResetRundown); + + WDF_OBJECT_ATTRIBUTES_INIT(&workitemAttributes); + workitemAttributes.ParentObject = BusObject->WdfUsbDevice; + WDF_WORKITEM_CONFIG_INIT(&workitemConfig, ResetDataPipeWorkItem); + + Status = WdfWorkItemCreate(&workitemConfig, &workitemAttributes, &usbDeviceContext->BulkPipeResetWorkitem); + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + // + // create a lock + // + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = BusObject->WdfUsbDevice; + + Status = WdfWaitLockCreate(&attributes, &usbDeviceContext->PipeStateLock); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = BusObject->WdfUsbDevice; + + Status = WdfCollectionCreate(&attributes, &usbDeviceContext->WriteRequestCollection); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + // + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = BusObject->WdfUsbDevice; + + Status = WdfSpinLockCreate(&attributes, &usbDeviceContext->WriteCollectionLock); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + // + // see if the bus driver supports chained mdl's + // + Status = WdfUsbTargetDeviceQueryUsbCapability(BusObject->WdfUsbDevice, (PGUID)&GUID_USB_CAPABILITY_CHAINED_MDLS, 0, NULL, NULL); + + if (NT_SUCCESS(Status)) + { + // + // request work, the stack supports chained mdl's + // + BusObject->ChainedMdlsSupported = TRUE; + } + else + { + } + + // see what USB device type the bus driver is supporting + // + Status = WdfUsbTargetDeviceQueryUsbCapability( + BusObject->WdfUsbDevice, (PGUID)&GUID_USB_CAPABILITY_DEVICE_TYPE, sizeof(USB_CAP_DEVICE_INFO), (PVOID)&usbCapDeviceInfo, &capResultLength); + + if (NT_SUCCESS(Status)) + { + // + // request work, the stack returns USB device type + // + if (IsUsbCapDeviceInfoValid(usbCapDeviceInfo, capResultLength)) + { + BusObject->UsbCapDeviceInfo = usbCapDeviceInfo; + } + } + + WdfUsbTargetDeviceGetDeviceDescriptor(BusObject->WdfUsbDevice, &DeviceDescriptor); + + Status = GetDeviceString(BusObject->WdfUsbDevice, DeviceDescriptor.iManufacturer, &BusObject->Manufacturer); + + Status = GetDeviceString(BusObject->WdfUsbDevice, DeviceDescriptor.iProduct, &BusObject->Model); + + WDF_USB_DEVICE_INFORMATION_INIT(&deviceInformation); + Status = WdfUsbTargetDeviceRetrieveInformation(BusObject->WdfUsbDevice, &deviceInformation); + if (NT_SUCCESS(Status)) + { + BusObject->RemoteWakeCapable = IS_USB_DEVICE_REMOTE_WAKE_CAPABLE(deviceInformation); + } + + Status = MbbParseConfigDescriptor( + BusObject->WdfUsbDevice, + &BusObject->MaxSegmentSize, + &BusObject->NcmParams, + &BusObject->PowerFiltersSupported, + &BusObject->MaxPowerFilterSize, + &usbDeviceContext->UsbCommunicationInterfaceIndex, + &usbDeviceContext->UsbDataInterfaceIndex, + &BusObject->MaxControlChannelSize, + &usbDeviceContext->UsbCommunicationInterfaceSetting, + &usbDeviceContext->UsbDataInterfaceSetting, + &BulkInPacketSize, + &BusObject->MTU, + &BusObject->MbimVersion, + &BusObject->MbimExtendedVersion); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + if (BusObject->MaxControlChannelSize < MIN_CONTROL_MESSAGE_SIZE) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + + if (BulkInPacketSize == 0) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + + numInterfaces = WdfUsbTargetDeviceGetNumInterfaces(BusObject->WdfUsbDevice); + + settingPairs = (PWDF_USB_INTERFACE_SETTING_PAIR)ALLOCATE_NONPAGED_POOL(sizeof(WDF_USB_INTERFACE_SETTING_PAIR) * numInterfaces); + + if (settingPairs == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Cleanup; + } + + for (interfaceIndex = 0; interfaceIndex < numInterfaces; interfaceIndex++) + { + settingPairs[interfaceIndex].UsbInterface = WdfUsbTargetDeviceGetInterface(BusObject->WdfUsbDevice, interfaceIndex); + + // + // Select alternate setting zero on all interfaces. + // + settingPairs[interfaceIndex].SettingIndex = 0; + } + + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(&configParams, numInterfaces, settingPairs); + + Status = WdfUsbTargetDeviceSelectConfig(BusObject->WdfUsbDevice, NULL, &configParams); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + if (configParams.Types.MultiInterface.NumberOfConfiguredInterfaces < 2) + { + Status = STATUS_NO_SUCH_DEVICE; + goto Cleanup; + } + + + usbDeviceContext->WdfCommunicationInterfaceIndex = 0xff; + usbDeviceContext->WdfDataInterfaceIndex = 0xff; + + for (i = 0; i < configParams.Types.MultiInterface.NumberOfConfiguredInterfaces; i++) + { + UsbInterface = WdfUsbTargetDeviceGetInterface(BusObject->WdfUsbDevice, i); + CurrentSetting = WdfUsbInterfaceGetConfiguredSettingIndex(UsbInterface); + WdfUsbInterfaceGetDescriptor(UsbInterface, CurrentSetting, &InterfaceDescriptor); + if ((InterfaceDescriptor.bInterfaceNumber == usbDeviceContext->UsbCommunicationInterfaceIndex)) + { + if (usbDeviceContext->WdfCommunicationInterfaceIndex == 0xff) + { + usbDeviceContext->WdfCommunicationInterfaceIndex = i; + } + } + + if ((InterfaceDescriptor.bInterfaceNumber == usbDeviceContext->UsbDataInterfaceIndex)) + { + if (usbDeviceContext->WdfDataInterfaceIndex == 0xff) + { + usbDeviceContext->WdfDataInterfaceIndex = i; + } + } + } + + if ((usbDeviceContext->WdfCommunicationInterfaceIndex == 0xff) || (usbDeviceContext->WdfDataInterfaceIndex == 0xff)) + { + Status = STATUS_NO_SUCH_DEVICE; + goto Cleanup; + } + + // + // get interrupt pipe handles + // + { + BYTE ConfiguredPipes = 0; + UsbInterface = WdfUsbTargetDeviceGetInterface(BusObject->WdfUsbDevice, usbDeviceContext->WdfCommunicationInterfaceIndex); + + WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING(&SettingParams, usbDeviceContext->UsbCommunicationInterfaceSetting); + + Status = WdfUsbInterfaceSelectSetting(UsbInterface, WDF_NO_OBJECT_ATTRIBUTES, &SettingParams); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + ConfiguredPipes = WdfUsbInterfaceGetNumConfiguredPipes(UsbInterface); + + if (ConfiguredPipes != 1) + { + Status = STATUS_NO_SUCH_DEVICE; + goto Cleanup; + } + + WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo); + + pipe = WdfUsbInterfaceGetConfiguredPipe( + UsbInterface, + 0, // index 0 + &pipeInfo); + + if (WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) + { + usbDeviceContext->InterruptPipe = pipe; + usbDeviceContext->InterruptPipeIoTarget = WdfUsbTargetPipeGetIoTarget(pipe); + + usbDeviceContext->InterruptPipeMaxPacket = pipeInfo.MaximumPacketSize; + } + else + { + Status = STATUS_NO_SUCH_DEVICE; + goto Cleanup; + } + } + + BusObject->SyncInterruptReadBuffer = (PUCHAR)ALLOCATE_NONPAGED_POOL(usbDeviceContext->InterruptPipeMaxPacket); + + if (BusObject->SyncInterruptReadBuffer == NULL) + { + Status = STATUS_NO_MEMORY; + goto Cleanup; + } + + // + // Configure the continous reader now + // + + WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&ReaderConfig, InterruptPipeReadComplete, BusObject, usbDeviceContext->InterruptPipeMaxPacket); + + ReaderConfig.NumPendingReads = 1; + ReaderConfig.EvtUsbTargetPipeReadersFailed = InterruptPipeReadError; + + Status = WdfUsbTargetPipeConfigContinuousReader(usbDeviceContext->InterruptPipe, &ReaderConfig); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + Status = GetNtbParameters(BusObject->WdfUsbDevice, &BusObject->NtbParam); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + if (!BusObject->ChainedMdlsSupported) + { + // + // chained mdl's not supported, create a lookaside list to hold the buffers + // + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = BusObject->WdfUsbDevice; + // + // TODO : For testing + // + // BusObject->NtbParam.dwNtbOutMaxSize = 512; + + Status = WdfLookasideListCreate( + &attributes, BusObject->NtbParam.dwNtbOutMaxSize, NonPagedPoolNx, WDF_NO_OBJECT_ATTRIBUTES, 'CBMW', &usbDeviceContext->LookasideList); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + } + + if (BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceType == USB_CAP_DEVICE_TYPE_UDE_MBIM) + { + BusObject->MaxBulkInTransfer = BusObject->NtbParam.dwNtbInMaxSize < MAX_HOST_NTB_SIZE_FOR_UDE_MBIM + ? BusObject->NtbParam.dwNtbInMaxSize + : MAX_HOST_NTB_SIZE_FOR_UDE_MBIM; + } + else + { + BusObject->MaxBulkInTransfer = + BusObject->NtbParam.dwNtbInMaxSize < MAX_HOST_NTB_SIZE ? BusObject->NtbParam.dwNtbInMaxSize : MAX_HOST_NTB_SIZE; + } + + // + // round down the transfer size so it is a multiple of maxpacket size for the builk in pipe + // + BusObject->MaxBulkInTransfer = (BusObject->MaxBulkInTransfer / BulkInPacketSize) * BulkInPacketSize; + + BusObject->BulkInHeaderSize = + ROUND_UP_COUNT((ULONG)MmSizeOfMdl(NULL, ROUND_UP_COUNT(BusObject->MaxBulkInTransfer + PAGE_SIZE, ALIGN_QUAD)), ALIGN_QUAD); + + if ((BusObject->NtbParam.bmNtbFormatSupported & NCM_NTB_FORMAT_32_BIT) == NCM_NTB_FORMAT_32_BIT) + { + // + // device supports 32 bit mode + // + if ((BusObject->NtbParam.dwNtbInMaxSize > 0xffff) || (BusObject->NtbParam.dwNtbOutMaxSize > 0xffff)) + { + // + // the device can actually handle a transfer larger than 16bit, change to 32 bit + // + BusObject->NtbFormat32Bit = TRUE; + } + } + + // + // put the device back into a known state + // + Status = MbbBusResetDeviceAndSetParms(BusObject); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + *BusHandle = BusObject; + usbDeviceContext->BusObject = BusObject; + BusObject = NULL; + +Cleanup: + + if (settingPairs != NULL) + { + FREE_POOL(settingPairs); + settingPairs = NULL; + } + + if (BusObject != NULL && preAllocatedBusObject == NULL) + { + FreeBusObject(BusObject); + BusObject = NULL; + } + + return Status; +} + +VOID FreeBusObject(_In_ __drv_freesMem(Mem) PBUS_OBJECT BusObject) + +{ + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + + if (BusObject->WdfUsbDevice != NULL) + { + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + if (usbDeviceContext->InterruptPipeIoTarget != NULL) + { + WdfIoTargetStop(usbDeviceContext->InterruptPipeIoTarget, WdfIoTargetCancelSentIo); + } + + usbDeviceContext->BusObject = NULL; + } + + if (BusObject->Manufacturer != NULL) + { + FREE_POOL(BusObject->Manufacturer); + BusObject->Manufacturer = NULL; + } + + if (BusObject->Model != NULL) + { + FREE_POOL(BusObject->Model); + BusObject->Model = NULL; + } + + if (BusObject->WdfDevice != NULL) + { + WdfObjectDelete(BusObject->WdfDevice); + } + + if (BusObject->UsbSsIrp != NULL) + { + IoCancelIrp(BusObject->UsbSsIrp); + + + KeWaitForSingleObject(&BusObject->UsbSsIrpComplete, Executive, KernelMode, FALSE, NULL); + + + IoFreeIrp(BusObject->UsbSsIrp); + BusObject->UsbSsIrp = NULL; + } + + if (BusObject->SyncInterruptReadBuffer != NULL) + { + FREE_POOL(BusObject->SyncInterruptReadBuffer); + BusObject->SyncInterruptReadBuffer = NULL; + } + + FREE_POOL(BusObject); + BusObject = NULL; + + return; +} + +VOID MbbBusCleanup(__in MBB_BUS_HANDLE BusHandle) + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + + FreeBusObject(BusObject); + BusObject = NULL; + + return; +} + +NTSTATUS +MbbParseConfigDescriptor( + WDFUSBDEVICE WdfUsbDevice, + PUSHORT MaxSegmentSize, + PUCHAR NcmCaps, + PUCHAR PowerFiltersSupported, + PUCHAR MaxPowerFilterSize, + PUCHAR CommunicationClassInterface, + PUCHAR DataClassInterface, + PUSHORT MaxControlMessage, + PUCHAR AltCommunicationClassSetting, + PUCHAR AltDataClassSetting, + PUSHORT BulkInDataClassPacketSize, + PUSHORT MTU, + PUSHORT MbimVersion, + PUSHORT MbimExtendedVersion) + +{ + + NTSTATUS Status; + + BYTE* ConfigDescriptorBuffer = NULL; + PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor = NULL; + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor = NULL; + PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor = NULL; + PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR IadDescriptor = NULL; + PUSB_CS_DESCRIPTOR CsDescriptor = NULL; + PUSB_CS_ECM_DESCRIPTOR EcmDescriptor = NULL; + PUSB_CS_NCM_DESCRIPTOR NcmDescriptor = NULL; + PUSB_CS_MBB_DESCRIPTOR MbbDescriptor = NULL; + PUSB_CS_MBB_DESCRIPTOR_EXTENDED MbbDescriptorExtended = NULL; + PUSB_CS_CDC_DESCRIPTOR CdcDescriptor = NULL; + + BYTE* Current = NULL; + USHORT DescriptorSize = 0; + + BOOLEAN GotEcmDesc = FALSE; + BOOLEAN GotNcmDesc = FALSE; + BOOLEAN GotMbbDesc = FALSE; + BYTE CurrentInterface = 0; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + + *CommunicationClassInterface = 0xff; + *DataClassInterface = 0xff; + *AltCommunicationClassSetting = 0; + *AltDataClassSetting = 0; + *BulkInDataClassPacketSize = 0; + *MTU = 0; + *MbimVersion = 0x0100; // Default to MBIM 1.0 Version + *MbimExtendedVersion = 0x0100; + + usbDeviceContext = GetUsbDeviceContext(WdfUsbDevice); + + Status = WdfUsbTargetDeviceRetrieveConfigDescriptor(WdfUsbDevice, NULL, &DescriptorSize); + + if (Status != STATUS_BUFFER_TOO_SMALL) + { + + goto Cleanup; + } + + ConfigDescriptorBuffer = (BYTE*)ALLOCATE_NONPAGED_POOL(DescriptorSize); + + if (ConfigDescriptorBuffer == NULL) + { + Status = STATUS_NO_MEMORY; + goto Cleanup; + } + + Status = WdfUsbTargetDeviceRetrieveConfigDescriptor(WdfUsbDevice, ConfigDescriptorBuffer, &DescriptorSize); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + Current = ConfigDescriptorBuffer; + + while (Current + sizeof(USB_DESCRIPTOR_HEADER) <= ConfigDescriptorBuffer + DescriptorSize) + { + PUSB_DESCRIPTOR_HEADER Header = (PUSB_DESCRIPTOR_HEADER)Current; + + if (Current + Header->bLength > ConfigDescriptorBuffer + DescriptorSize) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + + goto Cleanup; + } + + switch (Header->bDescriptorType) + { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + + ConfigDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Current; + + break; + + case USB_INTERFACE_DESCRIPTOR_TYPE: + + InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Current; + + CurrentInterface = InterfaceDescriptor->bInterfaceNumber; + + if ((InterfaceDescriptor->bInterfaceClass == MBIM_CC_INTERFACE_CLASS) && + ((InterfaceDescriptor->bInterfaceSubClass == MBIM_CC_INTERFACE_SUBCLASS)) && + (InterfaceDescriptor->bInterfaceProtocol == MBIM_CC_INTERFACE_PROTOCOL || + InterfaceDescriptor->bInterfaceProtocol == MBIM_CC_INTERFACE_NBL_PROTOCOL || + InterfaceDescriptor->bInterfaceProtocol == MBIM_CC_INTERFACE_NETPACKET_PROTOCOL)) + { + + *CommunicationClassInterface = InterfaceDescriptor->bInterfaceNumber; + *AltCommunicationClassSetting = InterfaceDescriptor->bAlternateSetting; + } + + if ((InterfaceDescriptor->bInterfaceClass == MBIM_DC_INTERFACE_CLASS) && + (InterfaceDescriptor->bInterfaceSubClass == MBIM_DC_INTERFACE_SUBCLASS) && + (InterfaceDescriptor->bInterfaceProtocol == MBIM_DC_INTERFACE_PROTOCOL)) + { + *DataClassInterface = InterfaceDescriptor->bInterfaceNumber; + *AltDataClassSetting = InterfaceDescriptor->bAlternateSetting; + } + + break; + + case USB_ENDPOINT_DESCRIPTOR_TYPE: + + if ((Header->bLength != sizeof(*EndpointDescriptor))) + { + + Status = STATUS_INFO_LENGTH_MISMATCH; + + goto Cleanup; + } + + EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Current; + + + if (CurrentInterface == *DataClassInterface) + { + // + // this endpoint is for the data interface + // + if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress) && (EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_BULK)) + { + // + // bulk in endpoint + // + *BulkInDataClassPacketSize = EndpointDescriptor->wMaxPacketSize & 0x7ff; + + } + } + + break; + + case USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE: + + + break; + + case USB_CDC_CS_DESCRIPTOR_TYPE: + + CsDescriptor = (PUSB_CS_DESCRIPTOR)Current; + + switch (CsDescriptor->bSubType) + { + case USB_CDC_CS_ECM_DESCRIPTOR_SUBTYPE: + + EcmDescriptor = (PUSB_CS_ECM_DESCRIPTOR)Current; + + + break; + + case USB_CDC_CS_NCM_DESCRIPTOR_SUBTYPE: + + NcmDescriptor = (PUSB_CS_NCM_DESCRIPTOR)Current; + + break; + + case USB_CDC_CS_DESCRIPTOR_SUBTYPE: + + if ((CsDescriptor->bLength != sizeof(*CdcDescriptor))) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + + goto Cleanup; + } + + CdcDescriptor = (PUSB_CS_CDC_DESCRIPTOR)Current; + + break; + + case USB_CDC_CS_MBB_DESCRIPTOR_SUBTYPE: + + if ((CsDescriptor->bLength != sizeof(*MbbDescriptor))) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + + goto Cleanup; + } + + MbbDescriptor = (PUSB_CS_MBB_DESCRIPTOR)Current; + + if (MbbDescriptor->wMbbVersion < MBIM_MBB_FUNCDESC_MIN_VERSION) + { + + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + + if (MbbDescriptor->wMaxSegmentSize < MBIM_MIN_SEGMENT_SIZE) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + + if (MbbDescriptor->bMaxFilterSize > MBIM_MAX_PACKET_FILTER_SIZE) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + + goto Cleanup; + } + + if (MbbDescriptor->bNumberPowerFilters < MBIM_MIN_NUMBER_OF_PACKET_FILTERS) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + + goto Cleanup; + } + + *MaxSegmentSize = MbbDescriptor->wMaxSegmentSize; + *PowerFiltersSupported = MbbDescriptor->bNumberPowerFilters; + *MaxPowerFilterSize = MbbDescriptor->bMaxFilterSize; + *NcmCaps = MbbDescriptor->bmNetworkCapabilities; + *MaxControlMessage = MbbDescriptor->wMaxControlMessage; + GotMbbDesc = TRUE; + *MbimVersion = MbbDescriptor->wMbbVersion; + + break; + + case USB_CDC_CS_MBB_DESCRIPTOR_EXTENDED_SUBTYPE: + + // MBIM 1.0 - 6.5: If MBIM Extended Functional Descriptor is provided, it must appear after MBIM Functional Descriptor. + if (!GotMbbDesc) + { + Status = STATUS_UNRECOGNIZED_MEDIA; + + goto Cleanup; + } + + if ((CsDescriptor->bLength != sizeof(*MbbDescriptorExtended))) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + + goto Cleanup; + } + + MbbDescriptorExtended = (PUSB_CS_MBB_DESCRIPTOR_EXTENDED)Current; + + if (MbbDescriptorExtended->wMbbVersion < MBIM_MBB_FUNCDESC_EXTENDED_MIN_VERSION) + { + + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + + if (MbbDescriptorExtended->wMTU < MBIM_MIN_MTU_SIZE) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + + // If the Extended MTU comes in as larger than the MaxSegmentSize, we set the MTU to MaxSegmentSize + if (MbbDescriptorExtended->wMTU > *MaxSegmentSize) + { + // Check if the MaxSegmentSize is not less than the Minimum MTU size, if it is then bail + if (*MaxSegmentSize < MBIM_MIN_MTU_SIZE) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + else + { + MbbDescriptorExtended->wMTU = *MaxSegmentSize; + } + } + + *MTU = MbbDescriptorExtended->wMTU; + *MbimExtendedVersion = MbbDescriptorExtended->wMbbVersion; + + break; + + default: + + + break; + } + + break; + + default: + + + break; + } + + Current += Header->bLength; + } + + Status = STATUS_SUCCESS; + +Cleanup: + + if (ConfigDescriptorBuffer != NULL) + { + FREE_POOL(ConfigDescriptorBuffer); + ConfigDescriptorBuffer = NULL; + } + + if (!(GotMbbDesc)) + { + + Status = STATUS_UNRECOGNIZED_MEDIA; + } + + if ((*CommunicationClassInterface == 0xff) || (*DataClassInterface == 0xff)) + { + + Status = STATUS_UNRECOGNIZED_MEDIA; + } + + return Status; +} + +NTSTATUS +GetNtbParameters(WDFUSBDEVICE WdfUsbDevice, PNCM_NTB_PARAMETER NcmNtb) + +{ + + NTSTATUS Status; + ULONG BytesTransfered = 0; + + Status = SendSyncControlCommand( + WdfUsbDevice, BmRequestDeviceToHost, BmRequestToInterface, GET_NTB_PARAMETERS, 0, (PUCHAR)NcmNtb, sizeof(*NcmNtb), &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + if (BytesTransfered < sizeof(*NcmNtb)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + } + else + { + goto Cleanup; + } + + if ((NcmNtb->bmNtbFormatSupported & NCM_NTB_FORMAT_16_BIT) != NCM_NTB_FORMAT_16_BIT) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + + if (NcmNtb->wNdpInPayloadRemainder >= NcmNtb->wNdpInDivisor) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + if ((NcmNtb->wNdpInPayloadRemainder > NcmNtb->dwNtbInMaxSize) || (NcmNtb->wNdpInDivisor > NcmNtb->dwNtbInMaxSize)) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + if ((NcmNtb->wNdpInAlignment < 4) || (NcmNtb->wNdpInAlignment > NcmNtb->dwNtbInMaxSize) || + ((NcmNtb->wNdpInAlignment - 1) & NcmNtb->wNdpInAlignment) != 0) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + if (NcmNtb->wNdpOutPayloadRemainder >= NcmNtb->wNdpOutDivisor) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + if ((NcmNtb->wNdpOutPayloadRemainder > NcmNtb->dwNtbOutMaxSize) || (NcmNtb->wNdpOutDivisor > NcmNtb->dwNtbOutMaxSize)) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + if ((NcmNtb->wNdpOutAlignment < 4) || (NcmNtb->wNdpOutAlignment > NcmNtb->dwNtbOutMaxSize) || + ((NcmNtb->wNdpOutAlignment - 1) & NcmNtb->wNdpOutAlignment) != 0) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + +Cleanup: + + return Status; +} + +NTSTATUS +SetActivityIdForRequest(__in WDFREQUEST Request, __in LPGUID ActivityId) +{ + NTSTATUS Status = STATUS_SUCCESS; + PIRP Irp = NULL; + + do + { + GUID zeroGuid = {0}; + + if (ActivityId == NULL || IsEqualGUID(*ActivityId, zeroGuid)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + Irp = WdfRequestWdmGetIrp(Request); + + if (Irp == NULL) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + // set the activity id of the IRP + Status = IoSetActivityIdIrp(Irp, ActivityId); + } while (FALSE); + + return Status; +} + +EVT_WDF_REQUEST_COMPLETION_ROUTINE SendCompletionRoutine; + +VOID SendCompletionRoutine(__in WDFREQUEST Request, __in WDFIOTARGET Target, __in PWDF_REQUEST_COMPLETION_PARAMS Params, __in WDFCONTEXT Context) + +{ + PREQUEST_CONTEXT ReqContext = NULL; + + ReqContext = GetRequestContext(Request); + + (ReqContext->Callback.Send)(ReqContext->ProtocolHandle, ReqContext->CallbackContext, Params->IoStatus.Status); + + WdfObjectDelete(Request); +} + +NTSTATUS +MbbBusSendMessageFragment( + __in MBB_BUS_HANDLE BusHandle, + __in MBB_REQUEST_HANDLE RequestHandle, + __in PVOID MessageFragment, + __in ULONG FragmentLength, + __in LPGUID ActivityId, + __in MBB_BUS_SEND_COMPLETION_CALLBACK SendCompletionCallback) + +/* + Description + The protocol layer call this routine to request the bus layer to + send a message fragment. Fragmentation / Reassembly is handled by + the protocol layer and it will only handle fragments that are within + the maximum transfer size of the bus. + + This routine is asynchronous and returns immediately after queueing + the transfer. The caller is notified of the completion through the + callback. + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + __in MBB_REQUEST_HANDLE RequestHandle, + Identifies the request. + + __in PVOID MessageFragment, + The data payload that needs to be sent. + + __in ULONG FragmentLength, + Length of the data payload. This will not be greater than the + maximum transfer size supported by the bus. + + __in LPGUID ActivityId, + The activity Id to be associated with this fragment transfer. + This activity Id will also be used by USB for logging USB events. + + __in MBB_BUS_SEND_COMPLETION_CALLBACK SendCompletionCallback + The completion callback routine that will be called by the bus + when the transfer is complete. + + Return Value + + NTSTATUS_SUCCESS + The transfer has completed successfully. SendCompletionCallback will NOT be called. + + NTSTATUS_PENDING + The transfer was queued. SendCompletionCallback will be called on completion. + + Other failure code + The transfer could not be queued. SendCompletionCallback will NOT be called. +*/ + +{ + + WDF_USB_CONTROL_SETUP_PACKET packet; + NTSTATUS status; + WDF_OBJECT_ATTRIBUTES attributes; + WDFMEMORY memHandle = NULL; + WDFREQUEST request = NULL; + BOOLEAN SentToDevice = FALSE; + PREQUEST_CONTEXT Context = NULL; + WDF_REQUEST_SEND_OPTIONS SendOptions; + + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, REQUEST_CONTEXT); + attributes.ParentObject = BusObject->WdfUsbDevice; + + status = WdfRequestCreate(&attributes, WdfUsbTargetDeviceGetIoTarget(BusObject->WdfUsbDevice), &request); + + if (!NT_SUCCESS(status)) + { + + goto Cleanup; + } + + Context = GetRequestContext(request); + + Context->CallbackContext = RequestHandle; + Context->Callback.Send = SendCompletionCallback; + Context->ProtocolHandle = BusObject->ProtocolHandle; + Context->UsbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = request; + + status = WdfMemoryCreatePreallocated(&attributes, MessageFragment, FragmentLength, &memHandle); + + if (!NT_SUCCESS(status)) + { + + goto Cleanup; + } + + WDF_USB_CONTROL_SETUP_PACKET_INIT_CLASS( + &packet, BmRequestHostToDevice, BmRequestToInterface, SEND_ENCAPSULATE_COMMAND, 0, Context->UsbDeviceContext->UsbCommunicationInterfaceIndex); + + status = WdfUsbTargetDeviceFormatRequestForControlTransfer(BusObject->WdfUsbDevice, request, &packet, memHandle, NULL); + + if (!NT_SUCCESS(status)) + { + + goto Cleanup; + } + + WdfRequestSetCompletionRoutine(request, SendCompletionRoutine, NULL); + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, 0); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(10)); + + // Set the activity Id of the IRP associated with the request. + // Ignore any failures + SetActivityIdForRequest(request, ActivityId); + + if (FragmentLength >= sizeof(MBB_COMMAND_HEADER)) + { + PMBB_COMMAND_HEADER CommandHeader = (PMBB_COMMAND_HEADER)MessageFragment; + } + + SentToDevice = WdfRequestSend(request, WdfUsbTargetDeviceGetIoTarget(BusObject->WdfUsbDevice), &SendOptions); + + status = STATUS_PENDING; + + if (!SentToDevice) + { + + status = WdfRequestGetStatus(request); + + } + +Cleanup: + + if (!NT_SUCCESS(status)) + { + if (request != NULL) + { + WdfObjectDelete(request); + request = NULL; + } + } + + return status; +} + +EVT_WDF_REQUEST_COMPLETION_ROUTINE ReceiveCompletionRoutine; + +VOID ReceiveCompletionRoutine(__in WDFREQUEST Request, __in WDFIOTARGET Target, __in PWDF_REQUEST_COMPLETION_PARAMS Params, __in WDFCONTEXT Context) + +{ + PREQUEST_CONTEXT ReqContext = NULL; + GUID ActivityId = {0}; + PIRP Irp = NULL; + NTSTATUS Status = STATUS_INVALID_PARAMETER; + + ReqContext = GetRequestContext(Request); + + // Get the IRP + Irp = WdfRequestWdmGetIrp(Request); + + if (Irp != NULL) + { + // Get the activity Id + Status = IoGetActivityIdIrp(Irp, &ActivityId); + } + + if (NT_SUCCESS(Params->IoStatus.Status) && (Params->IoStatus.Information >= sizeof(MBB_COMMAND_DONE_HEADER))) + { + + PMBB_COMMAND_DONE_HEADER CommandHeader = (PMBB_COMMAND_DONE_HEADER)ReqContext->Buffer; + } + + (*ReqContext->Callback.Receive)( + ReqContext->ProtocolHandle, ReqContext->CallbackContext, Params->IoStatus.Status, (ULONG)Params->IoStatus.Information); + + WdfObjectDelete(Request); +} + +NTSTATUS +MbbBusReceiveMessageFragment( + _In_ MBB_BUS_HANDLE BusHandle, + _In_ MBB_REQUEST_HANDLE RequestHandle, + _In_ __drv_aliasesMem PVOID MessageFragment, + _In_ ULONG FragmentLength, + _In_ LPGUID ActivityId, + _In_ MBB_BUS_RECEIVE_COMPLETION_CALLBACK ReceiveCompletionCallback) +/* + Description + + Parameters + + + Return Value + + NTSTATUS_SUCCESS + Initialization was successful. + + Other failure code +*/ +/* + Description + The protocol layer call this routine to request the bus layer to + receive data from the device. Reassembly is handled by the protocol layer. + + This routine is asynchronous and returns immediately after queueing + the transfer. The caller is notified of the completion through the + callback. + + Parameters + _In_ MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + _In_ MBB_REQUEST_HANDLE RequestHandle, + Identifies the request. + + _In_ __drv_aliasesMem PVOID MessageFragment, + The data buffer that would be filled with the received data. + + _In_ ULONG FragmentLength, + Length of the data requested from the device. This will not be + greater than the maximum transfer size supported by the bus. + + _In_ LPGUID ActivityId, + The activity Id to be associated with this fragment transfer. + This activity Id will also be used by USB for logging USB events. + + _In_ MBB_BUS_RECEIVE_COMPLETION_CALLBACK ReceiveCompletionCallback + The completion callback routine that will be called by the bus + when the transfer is complete. + + Return Value + + NTSTATUS_SUCCESS + The transfer has completed successfully. ReceiveCompletionCallback will NOT be called. + + NTSTATUS_PENDING + The transfer was queued. ReceiveCompletionCallback will be called on completion. + + Other failure code + The transfer could not be queued. ReceiveCompletionCallback will NOT be called. +*/ + +{ + WDF_USB_CONTROL_SETUP_PACKET packet; + NTSTATUS status; + WDF_OBJECT_ATTRIBUTES attributes; + WDFMEMORY memHandle = NULL; + WDFREQUEST request = NULL; + BOOLEAN SentToDevice = FALSE; + PREQUEST_CONTEXT Context = NULL; + WDF_REQUEST_SEND_OPTIONS SendOptions; + PIRP Irp = NULL; + + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, REQUEST_CONTEXT); + + attributes.ParentObject = BusObject->WdfUsbDevice; + + status = WdfRequestCreate(&attributes, WdfUsbTargetDeviceGetIoTarget(BusObject->WdfUsbDevice), &request); + + if (!NT_SUCCESS(status)) + { + + goto Cleanup; + } + + Context = GetRequestContext(request); + + Context->CallbackContext = RequestHandle; + Context->Callback.Receive = ReceiveCompletionCallback; + Context->ProtocolHandle = BusObject->ProtocolHandle; + Context->UsbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + Context->Buffer = MessageFragment; + Context->BufferLength = FragmentLength; + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = request; + + status = WdfMemoryCreatePreallocated(&attributes, MessageFragment, FragmentLength, &memHandle); + + if (!NT_SUCCESS(status)) + { + + goto Cleanup; + } + + WDF_USB_CONTROL_SETUP_PACKET_INIT_CLASS( + &packet, BmRequestDeviceToHost, BmRequestToInterface, GET_ENCAPSULATE_RESPONSE, 0, Context->UsbDeviceContext->UsbCommunicationInterfaceIndex); + + status = WdfUsbTargetDeviceFormatRequestForControlTransfer(BusObject->WdfUsbDevice, request, &packet, memHandle, NULL); + + if (!NT_SUCCESS(status)) + { + + goto Cleanup; + } + + WdfRequestSetCompletionRoutine(request, ReceiveCompletionRoutine, NULL); + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, 0); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(10)); + + // Set the activity Id of the IRP associated with the request. + // Ignore any failures + SetActivityIdForRequest(request, ActivityId); + + SentToDevice = WdfRequestSend(request, WdfUsbTargetDeviceGetIoTarget(BusObject->WdfUsbDevice), &SendOptions); + + status = STATUS_PENDING; + + if (!SentToDevice) + { + + status = WdfRequestGetStatus(request); + + } + +Cleanup: + + if (!NT_SUCCESS(status)) + { + if (request != NULL) + { + WdfObjectDelete(request); + request = NULL; + } + } + + return status; +} + +VOID InterruptPipeReadComplete(__in WDFUSBPIPE Pipe, __in WDFMEMORY Memory, __in size_t NumBytesTransfered, __in WDFCONTEXT Context) + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)Context; + PVOID Buffer = NULL; + PUSB_CDC_NOTIFICATION CdcNotification = NULL; + PUSB_CDC_NOTIFICATION_SPEED_CHANGE CdcSpeedChangeNotification = NULL; + MBB_CONNECTION_STATE ConnectStateChange; + ULONG TempBytesTransfered = (ULONG)NumBytesTransfered; + UCHAR IndicateBuffer[INTERRUPT_REASSEMBLY_BUFFER_SIZE]; + ULONG BufferLength = 0; + + + Buffer = WdfMemoryGetBuffer(Memory, NULL); + + // + // process this fragment, the function will return a non-zero value if a complete message is returned. + // + BufferLength = ProcessInterruptPipeRead(BusObject, (PCUCHAR)Buffer, NumBytesTransfered, IndicateBuffer, sizeof(IndicateBuffer)); + + if (BufferLength >= sizeof(*CdcNotification)) + { + CdcNotification = (PUSB_CDC_NOTIFICATION)&IndicateBuffer[0]; + + switch (CdcNotification->bNotificationCode) + { + case USB_CDC_NOTIFICATION_RESPONSE_AVAILABLE: (BusObject->ResponseAvailableCallback)(BusObject->ProtocolHandle); break; + + case USB_CDC_NOTIFICATION_NETWORK_CONNECTION: + case USB_CDC_NOTIFICATION_CONNECTION_SPEED_CHANGE: + default: break; + } + } + + return; +} + +BOOLEAN +InterruptPipeReadError(__in WDFUSBPIPE Pipe, __in NTSTATUS Status, __in USBD_STATUS UsbdStatus) + +{ + return TRUE; +} + +NTSTATUS +MbbBusQueryBusParameters(__in MBB_BUS_HANDLE BusHandle, __out PMBB_BUS_PARAMETERS BusParameters) + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + + RtlZeroMemory(BusParameters, sizeof(*BusParameters)); + + BusParameters->FragmentSize = BusObject->MaxControlChannelSize; + + BusParameters->MaxSegmentSize = BusObject->MaxSegmentSize; + + BusParameters->Ntb32BitSupported = (BusObject->NtbParam.bmNtbFormatSupported & NCM_NTB_FORMAT_32_BIT) == NCM_NTB_FORMAT_32_BIT; + BusParameters->MaxOutNtb = BusObject->NtbParam.dwNtbOutMaxSize; + + if ((BusObject->NtbParam.wNtbOutMaxDatagrams == 0) || (BusObject->NtbParam.wNtbOutMaxDatagrams > MAX_OUT_DATAGRAMS)) + { + // + // Zero means unlimited, impose a limit so the driver can preallocated the contexts it needs + // + BusParameters->MaxOutDatagrams = MAX_OUT_DATAGRAMS; + } + else + { + BusParameters->MaxOutDatagrams = BusObject->NtbParam.wNtbOutMaxDatagrams; + } + + BusParameters->NdpOutDivisor = BusObject->NtbParam.wNdpOutDivisor; + BusParameters->NdpOutRemainder = BusObject->NtbParam.wNdpOutPayloadRemainder; + BusParameters->NdpOutAlignment = BusObject->NtbParam.wNdpOutAlignment; + // + // TODO: Read the current value from the bus object when SetNtb is implemented + // + BusParameters->CurrentMode32Bit = BusObject->NtbFormat32Bit; + BusParameters->SelectiveSuspendSupported = TRUE; + + BusParameters->PowerFiltersSupported = BusObject->PowerFiltersSupported; + BusParameters->MaxPowerFilterSize = BusObject->MaxPowerFilterSize; + BusParameters->RemoteWakeCapable = BusObject->RemoteWakeCapable; + + if (BusObject->Manufacturer != NULL) + { + RtlStringCbCopyW(BusParameters->Manufacturer, sizeof(BusParameters->Manufacturer), BusObject->Manufacturer); + } + + if (BusObject->Model != NULL) + { + RtlStringCbCopyW(BusParameters->Model, sizeof(BusParameters->Model), BusObject->Model); + } + + BusParameters->MTU = BusObject->MTU; + if (BusObject->MTU != 0) + { + BusParameters->IsErrataDevice = TRUE; + } + else + { + BusParameters->IsErrataDevice = FALSE; + } + + BusParameters->MbimVersion = BusObject->MbimVersion; + BusParameters->MbimExtendedVersion = BusObject->MbimExtendedVersion; + + return STATUS_SUCCESS; +} + +NTSTATUS MbbBusHandshake(_In_ PBUS_OBJECT BusObject, _In_ ULONG TransactionId, _In_opt_ PVOID FastIOSendNetBufferListsComplete, _In_opt_ PVOID FastIOIndicateReceiveNetBufferLists) +{ + NTSTATUS Status; + ULONG BytesTransferred = 0; + UCHAR ReadBuffer[256]; + ULONG RetryCount = 0; + MBB_OPEN_MESSAGE OpenMessage; + PMBB_OPEN_DONE OpenDoneMessage = NULL; + MBB_OPEN_MESSAGE_FASTIO OpenMessageFastIO; + PMBB_OPEN_DONE_FASTIO OpenDoneMessageFastIO = NULL; + + if (MbbBusIsFastIO(BusObject)) + { + if (FastIOSendNetBufferListsComplete == NULL || FastIOIndicateReceiveNetBufferLists == NULL) + { + Status = STATUS_NOT_SUPPORTED; + goto Cleanup; + } + RtlZeroMemory(&OpenMessageFastIO, sizeof(OpenMessageFastIO)); + + OpenMessageFastIO.MessageHeader.MessageType = MBB_MESSAGE_TYPE_OPEN; + OpenMessageFastIO.MessageHeader.MessageLength = sizeof(OpenMessageFastIO); + OpenMessageFastIO.MessageHeader.MessageTransactionId = TransactionId; + OpenMessageFastIO.MaximumControlTransfer = + BusObject->MaxControlChannelSize < MAX_CONTROL_MESSAGE_SIZE ? BusObject->MaxControlChannelSize : MAX_CONTROL_MESSAGE_SIZE; + OpenMessageFastIO.AdapterContext = BusObject->ProtocolHandle; + OpenMessageFastIO.SendNetBufferListsCompleteHandler = FastIOSendNetBufferListsComplete; + OpenMessageFastIO.ReceiveNetBufferListsHandler = FastIOIndicateReceiveNetBufferLists; + + do + { + + RetryCount++; + + Status = TransactControlChannel( + BusObject, + RetryCount * INITIAL_OPEN_TIMEOUT, + (PUCHAR)&OpenMessageFastIO, + sizeof(OpenMessageFastIO), + (PUCHAR)&ReadBuffer[0], + sizeof(ReadBuffer), + &BytesTransferred); + } while ((Status == STATUS_IO_TIMEOUT) && (RetryCount < MAX_OPEN_RETRY_ATTEMPTS)); + + if (NT_SUCCESS(Status)) + { + if (BytesTransferred < sizeof(*OpenDoneMessageFastIO)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + OpenDoneMessageFastIO = (PMBB_OPEN_DONE_FASTIO)&ReadBuffer[0]; + + if ((OpenDoneMessageFastIO->MessageHeader.MessageType != MBB_MESSAGE_TYPE_OPEN_DONE) || + (OpenDoneMessageFastIO->MessageHeader.MessageLength < sizeof(MBB_OPEN_DONE_FASTIO)) || + (OpenDoneMessageFastIO->MessageHeader.MessageTransactionId != OpenMessageFastIO.MessageHeader.MessageTransactionId)) + { + Status = STATUS_NDIS_INVALID_DATA; + + goto Cleanup; + } + + if (OpenDoneMessageFastIO->MbbStatus != STATUS_SUCCESS) + { + Status = STATUS_OPEN_FAILED; + + goto Cleanup; + } + + if (BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceMajorVersion == 0x1 && + BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceMinorVersion == 0x0) + { + BusObject->ModemContext = OpenDoneMessageFastIO->ModemContext; + BusObject->SendNetBufferListsHandler = (FastIOSendNetBufferListsHandler)OpenDoneMessageFastIO->SendNetBufferListsHandler; + if (BusObject->SendNetBufferListsHandler == NULL) + { + Status = STATUS_OPEN_FAILED; + goto Cleanup; + } + BusObject->ReturnNetBufferListsHandler = (FastIOReturnNetBufferListsHandler)OpenDoneMessageFastIO->ReturnNetBufferListsHandler; + if (BusObject->ReturnNetBufferListsHandler == NULL) + { + Status = STATUS_OPEN_FAILED; + goto Cleanup; + } + BusObject->CancelSendHandler = (FastIOCancelSendHandler)OpenDoneMessageFastIO->CancelSendHandler; + if (BusObject->CancelSendHandler == NULL) + { + Status = STATUS_OPEN_FAILED; + goto Cleanup; + } + BusObject->HaltHandler = (FastIOHaltHandler)OpenDoneMessageFastIO->HaltHandler; + if (BusObject->HaltHandler == NULL) + { + Status = STATUS_OPEN_FAILED; + goto Cleanup; + } + BusObject->PauseHandler = (FastIOPauseHandler)OpenDoneMessageFastIO->PauseHandler; + if (BusObject->PauseHandler == NULL) + { + Status = STATUS_OPEN_FAILED; + goto Cleanup; + } + BusObject->ShutdownHandler = (FastIOShutdownHandler)OpenDoneMessageFastIO->ShutdownHandler; + BusObject->ResetHandler = (FastIOResetHandler)OpenDoneMessageFastIO->ResetHandler; + BusObject->RestartHandler = (FastIORestartHandler)OpenDoneMessageFastIO->RestartHandler; + if (BusObject->RestartHandler == NULL) + { + Status = STATUS_OPEN_FAILED; + goto Cleanup; + } + } + } + else + { + RtlZeroMemory(&OpenMessage, sizeof(OpenMessage)); + + OpenMessage.MessageHeader.MessageType = MBB_MESSAGE_TYPE_OPEN; + OpenMessage.MessageHeader.MessageLength = sizeof(OpenMessage); + OpenMessage.MessageHeader.MessageTransactionId = TransactionId; + OpenMessage.MaximumControlTransfer = + BusObject->MaxControlChannelSize < MAX_CONTROL_MESSAGE_SIZE ? BusObject->MaxControlChannelSize : MAX_CONTROL_MESSAGE_SIZE; + + do + { + + RetryCount++; + + Status = TransactControlChannel( + BusObject, RetryCount * INITIAL_OPEN_TIMEOUT, (PUCHAR)&OpenMessage, sizeof(OpenMessage), (PUCHAR)&ReadBuffer[0], sizeof(ReadBuffer), &BytesTransferred); + } while ((Status == STATUS_IO_TIMEOUT) && (RetryCount < MAX_OPEN_RETRY_ATTEMPTS)); + + if (NT_SUCCESS(Status)) + { + if (BytesTransferred < sizeof(*OpenDoneMessage)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + OpenDoneMessage = (PMBB_OPEN_DONE)&ReadBuffer[0]; + + if ((OpenDoneMessage->MessageHeader.MessageType != MBB_MESSAGE_TYPE_OPEN_DONE) || + (OpenDoneMessage->MessageHeader.MessageLength < sizeof(*OpenDoneMessage)) || + (OpenDoneMessage->MessageHeader.MessageTransactionId != OpenMessage.MessageHeader.MessageTransactionId)) + { + Status = STATUS_NDIS_INVALID_DATA; + + goto Cleanup; + } + + if (OpenDoneMessage->MbbStatus != STATUS_SUCCESS) + { + Status = STATUS_OPEN_FAILED; + + goto Cleanup; + } + } +Cleanup: + if (!NT_SUCCESS(Status)) + { + BusObject->SendNetBufferListsHandler = NULL; + BusObject->ReturnNetBufferListsHandler = NULL; + BusObject->CancelSendHandler = NULL; + BusObject->HaltHandler = NULL; + BusObject->PauseHandler = NULL; + BusObject->ShutdownHandler = NULL; + BusObject->ResetHandler = NULL; + BusObject->RestartHandler = NULL; + } + return Status; +} + +NTSTATUS +MbbBusStart(_In_ MBB_BUS_HANDLE BusHandle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + BOOLEAN FailOpen = FALSE; + + BOOLEAN AltSettingSet = FALSE; + + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + if (BusObject->State != BUS_STATE_CLOSED) + { + FailOpen = TRUE; + } + else + { + BusObject->State = BUS_STATE_OPENING; + } + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + + if (FailOpen) + { + Status = STATUS_UNSUCCESSFUL; + + goto Cleanup; + } + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + Status = MbbBusResetDeviceAndSetParms(BusObject); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + Status = MbbBusSelectDataAltSetting(BusObject, ALT_DATA_SETTING_1); + + if (NT_ERROR(Status)) + { + goto Cleanup; + } + + AltSettingSet = TRUE; + + // + // start the continouse reader now + // + Status = WdfIoTargetStart(usbDeviceContext->InterruptPipeIoTarget); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + Status = STATUS_SUCCESS; + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + BusObject->State = BUS_STATE_OPENED; + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + +Cleanup: + + if (!NT_SUCCESS(Status)) + { + // + // stop the pipe reader + // + WdfIoTargetStop(usbDeviceContext->InterruptPipeIoTarget, WdfIoTargetCancelSentIo); + + // + // set the data pipes back to alt seeting 0 + // + if (AltSettingSet) + { + MbbBusSelectDataAltSetting(BusObject, ALT_DATA_SETTING_0); + } + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + BusObject->State = BUS_STATE_CLOSED; + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + } + + return Status; +} + +NTSTATUS +MbbBusStop(__in MBB_BUS_HANDLE BusHandle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + // + // stop the interrupt pipe so the continuous reader will stop and we can do sync reads + // + WdfIoTargetStop(usbDeviceContext->InterruptPipeIoTarget, WdfIoTargetCancelSentIo); + + Status = STATUS_SUCCESS; + + MbbBusSelectDataAltSetting(BusObject, ALT_DATA_SETTING_0); + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + BusObject->State = BUS_STATE_CLOSED; + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + + + return Status; +} + +BOOLEAN +MbbBusIsStoped(_In_ MBB_BUS_HANDLE BusHandle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + return BusObject->State == BUS_STATE_CLOSED; +} + +NTSTATUS +MbbBusOpen(_In_ MBB_BUS_HANDLE BusHandle, _In_ ULONG TransactionId, _In_opt_ PVOID FastIOSendNetBufferListsComplete, _In_opt_ PVOID FastIOIndicateReceiveNetBufferLists) +/* + Description + + Opens the session with the device + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + BOOLEAN FailOpen = FALSE; + + PUSB_CDC_NOTIFICATION Notification = NULL; + BOOLEAN AltSettingSet = FALSE; + + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + if (BusObject->State != BUS_STATE_CLOSED) + { + FailOpen = TRUE; + } + else + { + BusObject->State = BUS_STATE_OPENING; + } + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + + if (FailOpen) + { + Status = STATUS_UNSUCCESSFUL; + + + goto Cleanup; + } + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + + Status = MbbBusResetDeviceAndSetParms(BusObject); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + Status = MbbBusSelectDataAltSetting(BusObject, ALT_DATA_SETTING_1); + + if (NT_ERROR(Status)) + { + goto Cleanup; + } + + AltSettingSet = TRUE; + + Status = MbbBusHandshake(BusObject, TransactionId, FastIOSendNetBufferListsComplete, FastIOIndicateReceiveNetBufferLists); + if (NT_ERROR(Status)) + { + goto Cleanup; + } + + // + // start the continouse reader now + // + Status = WdfIoTargetStart(usbDeviceContext->InterruptPipeIoTarget); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + Status = STATUS_SUCCESS; + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + BusObject->State = BUS_STATE_OPENED; + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + +Cleanup: + + if (!NT_SUCCESS(Status)) + { + // + // stop the pipe reader + // + WdfIoTargetStop(usbDeviceContext->InterruptPipeIoTarget, WdfIoTargetCancelSentIo); + + // + // set the data pipes back to alt seeting 0 + // + if (AltSettingSet) + { + MbbBusSelectDataAltSetting(BusObject, ALT_DATA_SETTING_0); + } + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + BusObject->State = BUS_STATE_CLOSED; + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + } + + return Status; +} + +NTSTATUS +MbbBusClose(__in MBB_BUS_HANDLE BusHandle, __in ULONG TransactionId, __in BOOLEAN ForceClose) +/* + Description + + Opens the session with the device + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + BOOLEAN FailClose = FALSE; + + ULONG BytesTransfered = 0; + PUSB_CDC_NOTIFICATION Notification = NULL; + MBB_CLOSE_MESSAGE CloseMessage; + PMBB_CLOSE_DONE CloseDoneMessage = NULL; + UCHAR ReadBuffer[256]; + WDF_USB_CONTINUOUS_READER_CONFIG ReaderConfig; + + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + if (!ForceClose) + { + if (BusObject->State != BUS_STATE_OPENED) + { + FailClose = TRUE; + } + } + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + + if (FailClose) + { + Status = STATUS_UNSUCCESSFUL; + + goto Cleanup; + } + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + // + // stop the interrupt pipe so the continuous reader will stop and we can do sync reads + // + WdfIoTargetStop(usbDeviceContext->InterruptPipeIoTarget, WdfIoTargetCancelSentIo); + + RtlZeroMemory(&CloseMessage, sizeof(CloseMessage)); + + CloseMessage.MessageHeader.MessageType = MBB_MESSAGE_TYPE_CLOSE; + CloseMessage.MessageHeader.MessageLength = sizeof(CloseMessage); + CloseMessage.MessageHeader.MessageTransactionId = TransactionId; + + Status = TransactControlChannel( + BusObject, DEFAULT_IO_TIMEOUT, (PUCHAR)&CloseMessage, sizeof(CloseMessage), (PUCHAR)&ReadBuffer[0], sizeof(ReadBuffer), &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + if (BytesTransfered < sizeof(*CloseDoneMessage)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + CloseDoneMessage = (PMBB_CLOSE_DONE)&ReadBuffer[0]; + + if ((CloseDoneMessage->MessageHeader.MessageType != MBB_MESSAGE_TYPE_CLOSE_DONE) || + (CloseDoneMessage->MessageHeader.MessageLength < sizeof(*CloseDoneMessage)) || + (CloseDoneMessage->MessageHeader.MessageTransactionId != CloseMessage.MessageHeader.MessageTransactionId)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + + goto Cleanup; + } + +Cleanup: + + Status = STATUS_SUCCESS; + + MbbBusSelectDataAltSetting(BusObject, ALT_DATA_SETTING_0); + + ACQUIRE_PASSIVE_LOCK(&BusObject->Lock); + + BusObject->State = BUS_STATE_CLOSED; + + RELEASE_PASSIVE_LOCK(&BusObject->Lock); + + return Status; +} + +VOID MbbBusSetNotificationState(__in MBB_BUS_HANDLE BusHandle, __in BOOLEAN Enabled) + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + if (!Enabled) + { + WdfIoTargetStop(usbDeviceContext->InterruptPipeIoTarget, WdfIoTargetCancelSentIo); + } + else + { + (void)WdfIoTargetStart(usbDeviceContext->InterruptPipeIoTarget); + } + + return; +} diff --git a/network/wwan/cxwmbclass/cxwmbclass.rc b/network/wwan/cxwmbclass/cxwmbclass.rc new file mode 100644 index 000000000..6df53fd8a --- /dev/null +++ b/network/wwan/cxwmbclass/cxwmbclass.rc @@ -0,0 +1,20 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +#include "windows.h" +#include "ntverp.h" + +/*-----------------------------------------------*/ +/* the following lines are specific to this file */ +/*-----------------------------------------------*/ + +#define VER_FILETYPE VFT_DRV + +#define VER_FILESUBTYPE VFT2_DRV_NETWORK + +#define VER_FILEDESCRIPTION_STR "Windows Mobile Broadband Class Driver" + +#define VER_INTERNALNAME_STR "cxwmbclass.sys" +#define VER_ORIGINALFILENAME_STR "cxwmbclass.sys" + +#include "common.ver" diff --git a/network/wwan/cxwmbclass/cxwmbclass.vcxproj b/network/wwan/cxwmbclass/cxwmbclass.vcxproj deleted file mode 100644 index 494c6b548..000000000 --- a/network/wwan/cxwmbclass/cxwmbclass.vcxproj +++ /dev/null @@ -1,167 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - Debug - ARM64 - - - Release - ARM64 - - - - - - - {C8DBB8AC-0437-4D94-BD6C-F24BA5DB9683} - {497e31cb-056b-4f31-abb8-447fd55ee5a5} - v4.5 - 12.0 - Debug - x64 - KMDF_Driver1 - - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - KMDF - Universal - - - Windows10 - false - WindowsKernelModeDriver10.0 - Driver - KMDF - Universal - - - Windows10 - true - WindowsKernelModeDriver10.0 - Driver - KMDF - Universal - - - Windows10 - false - WindowsKernelModeDriver10.0 - Driver - KMDF - Universal - - - - - - - - - - - DbgengKernelDebugger - - - DbgengKernelDebugger - - - DbgengKernelDebugger - - - DbgengKernelDebugger - - - - true - true - trace.h - true - - - sha256 - - - - - true - true - trace.h - true - - - sha256 - - - - - true - true - trace.h - true - - - sha256 - - - - - true - true - trace.h - true - - - sha256 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/network/wwan/cxwmbclass/cxwmbclass.vcxproj.filters b/network/wwan/cxwmbclass/cxwmbclass.vcxproj.filters deleted file mode 100644 index 3ba14d984..000000000 --- a/network/wwan/cxwmbclass/cxwmbclass.vcxproj.filters +++ /dev/null @@ -1,107 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {8E41214B-6785-4CFE-B992-037D68949A14} - inf;inv;inx;mof;mc; - - - - - Driver Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Resource Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/network/wwan/cxwmbclass/datapipe.cpp b/network/wwan/cxwmbclass/datapipe.cpp new file mode 100644 index 000000000..aaa607ced --- /dev/null +++ b/network/wwan/cxwmbclass/datapipe.cpp @@ -0,0 +1,1001 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +#include "precomp.h" + +typedef struct _USB_WRITE_REQ_CONTEXT +{ + WDFMEMORY UrbMemory; + PURB Urb; + PMDL Mdl; + WDFMEMORY LookasideBuffer; + PBUS_OBJECT BusObject; + MBB_BUS_SEND_DATA_COMPLETION_CALLBACK Callback; + MBB_REQUEST_HANDLE RequestHandle; + +} USB_WRITE_REQ_CONTEXT, *PUSB_WRITE_REQ_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(USB_WRITE_REQ_CONTEXT, GetWriteRequestContext) + +EVT_WDF_USB_READER_COMPLETION_ROUTINE BulkInReadComplete; + +EVT_WDF_USB_READERS_FAILED BulkInReadError; + +NTSTATUS +GetWriteRequests(WDFUSBDEVICE UsbDevice, WDFREQUEST* ReturnedWriteRequest); + +VOID FreeWriteRequest(WDFUSBDEVICE UsbDevice, WDFREQUEST WriteRequest); + +NTSTATUS +MbbBusSelectDataAltSetting(__in MBB_BUS_HANDLE BusHandle, __in UCHAR AltSetting) + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + WDF_USB_INTERFACE_SELECT_SETTING_PARAMS SettingParams; + WDFUSBINTERFACE UsbInterface = NULL; + WDF_USB_PIPE_INFORMATION pipeInfo; + WDFUSBPIPE pipe; + UCHAR ConfiguredPipes = 0; + UCHAR index = 0; + NTSTATUS Status; + NTSTATUS TempStatus; + WDF_USB_CONTINUOUS_READER_CONFIG ReaderConfig; + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + WdfWaitLockAcquire(usbDeviceContext->PipeStateLock, NULL); + + UsbInterface = WdfUsbTargetDeviceGetInterface(BusObject->WdfUsbDevice, usbDeviceContext->WdfDataInterfaceIndex); + + WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING(&SettingParams, AltSetting == 0 ? 0 : usbDeviceContext->UsbDataInterfaceSetting); + + Status = WdfUsbInterfaceSelectSetting(UsbInterface, NULL, &SettingParams); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + ConfiguredPipes = WdfUsbInterfaceGetNumConfiguredPipes(UsbInterface); + + if (((AltSetting == ALT_DATA_SETTING_0) && (ConfiguredPipes != ALT_DATA_SETTING_0_PIPES)) || + ((AltSetting == ALT_DATA_SETTING_1) && (ConfiguredPipes != ALT_DATA_SETTING_1_PIPES))) + { + Status = STATUS_UNSUCCESSFUL; + + goto Cleanup; + } + + if (AltSetting == ALT_DATA_SETTING_1) + { + for (index = 0; index < ConfiguredPipes; index++) + { + + WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo); + + pipe = WdfUsbInterfaceGetConfiguredPipe( + UsbInterface, + index, // PipeIndex, + &pipeInfo); + + if (WdfUsbPipeTypeBulk == pipeInfo.PipeType) + { + + if (WdfUsbTargetPipeIsInEndpoint(pipe)) + { + usbDeviceContext->BulkInputPipeConfigured = TRUE; + usbDeviceContext->BulkInputPipe = pipe; + usbDeviceContext->BulkInputPipeMaxPacket = pipeInfo.MaximumPacketSize; + } + else + { + usbDeviceContext->BulkOutputPipeConfigured = TRUE; + usbDeviceContext->BulkOutputPipe = pipe; + usbDeviceContext->BulkOutputPipeMaxPacket = pipeInfo.MaximumPacketSize; + } + } + else + { + + Status = STATUS_UNSUCCESSFUL; + + goto Cleanup; + } + } + + if (!(usbDeviceContext->BulkInputPipeConfigured && usbDeviceContext->BulkOutputPipeConfigured)) + { + Status = STATUS_UNSUCCESSFUL; + + goto Cleanup; + } + + // + // configure the continous reader on the bulk pipe now, since this can only be done once on a given pipe + // unless it is unselected + // + WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&ReaderConfig, BulkInReadComplete, BusObject, BusObject->MaxBulkInTransfer); + + if (BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceType == USB_CAP_DEVICE_TYPE_UDE_MBIM) + { + ReaderConfig.NumPendingReads = PENDING_BULK_IN_READS_FOR_UDE_MBIM; + } + else + { + ReaderConfig.NumPendingReads = PENDING_BULK_IN_READS; + } + ReaderConfig.HeaderLength = BusObject->BulkInHeaderSize; + ReaderConfig.EvtUsbTargetPipeReadersFailed = BulkInReadError; + + Status = WdfUsbTargetPipeConfigContinuousReader(usbDeviceContext->BulkInputPipe, &ReaderConfig); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + // + // call this now that the pipe is configured + // + PreAllocateWriteRequests(BusObject->WdfUsbDevice); + } + else + { + // + // selecting the setting causes the frame work to delete the pipe + // + WDFREQUEST WriteRequest = NULL; + + usbDeviceContext->BulkInputPipeConfigured = FALSE; + usbDeviceContext->BulkInputPipe = NULL; + + usbDeviceContext->BulkOutputPipeConfigured = FALSE; + usbDeviceContext->BulkOutputPipe = NULL; + + WdfSpinLockAcquire(usbDeviceContext->WriteCollectionLock); + + WriteRequest = (WDFREQUEST)WdfCollectionGetLastItem(usbDeviceContext->WriteRequestCollection); + + // + // delete the write request because they are associated with a pipe object + // + while (WriteRequest != NULL) + { + WdfCollectionRemove(usbDeviceContext->WriteRequestCollection, WriteRequest); + + WdfObjectDelete(WriteRequest); + WriteRequest = (WDFREQUEST)WdfCollectionGetLastItem(usbDeviceContext->WriteRequestCollection); + } + + WdfSpinLockRelease(usbDeviceContext->WriteCollectionLock); + } + +Cleanup: + + if (!NT_SUCCESS(Status)) + { + // + // failed to configure the pipes, set back to alt setting 0 + // + WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING(&SettingParams, 0); + + TempStatus = WdfUsbInterfaceSelectSetting(UsbInterface, NULL, &SettingParams); + + usbDeviceContext->BulkInputPipeConfigured = FALSE; + usbDeviceContext->BulkInputPipe = NULL; + + usbDeviceContext->BulkOutputPipeConfigured = FALSE; + usbDeviceContext->BulkOutputPipe = NULL; + } + + WdfWaitLockRelease(usbDeviceContext->PipeStateLock); + + return Status; +} + +NTSTATUS +MbbUsbDeviceStartDataPipes(__in PUSB_DEVICE_CONTEXT usbDeviceContext) +{ + NTSTATUS Status; + NTSTATUS TempStatus; + + WdfWaitLockAcquire(usbDeviceContext->PipeStateLock, NULL); + + if (!(usbDeviceContext->BulkInputPipeConfigured && usbDeviceContext->BulkOutputPipeConfigured)) + { + Status = STATUS_UNSUCCESSFUL; + + goto Cleanup; + } + + Status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkInputPipe)); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + usbDeviceContext->BulkInputPipeStarted = TRUE; + + Status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkOutputPipe)); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + usbDeviceContext->BulkOutputPipeStarted = TRUE; + +Cleanup: + + if (!NT_SUCCESS(Status)) + { + // + // failed to configure the pipes, set back to alt setting 0 + // + if (usbDeviceContext->BulkInputPipeStarted) + { + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkInputPipe), WdfIoTargetCancelSentIo); + } + + if (usbDeviceContext->BulkOutputPipeStarted) + { + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkOutputPipe), WdfIoTargetCancelSentIo); + } + + usbDeviceContext->BulkInputPipeStarted = FALSE; + usbDeviceContext->BulkOutputPipeStarted = FALSE; + } + + WdfWaitLockRelease(usbDeviceContext->PipeStateLock); + + return Status; +} + +NTSTATUS +MbbBusStartDataPipes(__in MBB_BUS_HANDLE BusHandle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + return MbbUsbDeviceStartDataPipes(GetUsbDeviceContext(BusObject->WdfUsbDevice)); +} + +VOID MbbUsbDeviceStopDataPipes(__in PUSB_DEVICE_CONTEXT usbDeviceContext) +{ + WDF_USB_INTERFACE_SELECT_SETTING_PARAMS SettingParams; + WDFUSBINTERFACE UsbInterface = NULL; + NTSTATUS Status; + + WdfWaitLockAcquire(usbDeviceContext->PipeStateLock, NULL); + + if (usbDeviceContext->BulkInputPipeConfigured) + { + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkInputPipe), WdfIoTargetCancelSentIo); + } + if (usbDeviceContext->BulkOutputPipeConfigured) + { + WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkOutputPipe), WdfIoTargetCancelSentIo); + } + + usbDeviceContext->BulkInputPipeStarted = FALSE; + + usbDeviceContext->BulkOutputPipeStarted = FALSE; + + WdfWaitLockRelease(usbDeviceContext->PipeStateLock); + + return; +} + +VOID MbbBusStopDataPipes(__in MBB_BUS_HANDLE BusHandle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + PUSB_DEVICE_CONTEXT usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + WdfWorkItemFlush(usbDeviceContext->BulkPipeResetWorkitem); + + MbbUsbDeviceStopDataPipes(GetUsbDeviceContext(BusObject->WdfUsbDevice)); +} + +NTSTATUS +MbbUsbDeviceResetBulkPipe(__in PUSB_DEVICE_CONTEXT usbDeviceContext, __in BOOLEAN Out) + +{ + WDFUSBPIPE Pipe = NULL; + WDF_REQUEST_SEND_OPTIONS SendOptions; + NTSTATUS StatusToReturn = STATUS_SUCCESS; + NTSTATUS Status; + + WdfWaitLockAcquire(usbDeviceContext->PipeStateLock, NULL); + + if (Out ? usbDeviceContext->BulkOutputPipeConfigured : usbDeviceContext->BulkInputPipeConfigured) + { + + Pipe = Out ? usbDeviceContext->BulkOutputPipe : usbDeviceContext->BulkInputPipe; + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(30)); + + Status = WdfUsbTargetPipeAbortSynchronously(Pipe, NULL, &SendOptions); + + if (!NT_SUCCESS(Status)) + { + if (StatusToReturn == STATUS_SUCCESS) + { + StatusToReturn = Status; + } + } + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(30)); + + Status = WdfUsbTargetPipeResetSynchronously(Pipe, NULL, &SendOptions); + + if (!NT_SUCCESS(Status)) + { + if (StatusToReturn == STATUS_SUCCESS) + { + StatusToReturn = Status; + } + } + } + WdfWaitLockRelease(usbDeviceContext->PipeStateLock); + + return StatusToReturn; +} + +NTSTATUS +MbbBusResetBulkPipe(__in MBB_BUS_HANDLE BusHandle, __in BOOLEAN Out) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + return MbbUsbDeviceResetBulkPipe(GetUsbDeviceContext(BusObject->WdfUsbDevice), Out); +} + +EVT_WDF_REQUEST_COMPLETION_ROUTINE WriteCompletionRoutine; + +void WriteCompletionRoutine(__in WDFREQUEST Request, __in WDFIOTARGET Target, __in PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, __in WDFCONTEXT Context) +/*++ + +Routine Description + + Request - Handle to the WDFREQUEST which was used to send data to the USB target. + Target - Handle to the Iotarget to which teh Request was sent. COnceptually this + is the BULK USB __out pipe(on of Data or beacon) + CompletionParams - In case of USB this contains the USB status and amount of bytes transferred + + + Context - This is the COntext we set in WdfRequestSend + + +Arguments: + + + +Return Value: + + + +--*/ + +{ + PUSB_WRITE_REQ_CONTEXT WriteContext; + NTSTATUS Status; + + UNREFERENCED_PARAMETER(Target); + WriteContext = (PUSB_WRITE_REQ_CONTEXT)Context; + + Status = CompletionParams->IoStatus.Status; + + // + // For usb devices, we should look at the Usb.Completion param. + // + + if (WriteContext->Callback != NULL) + { + (*WriteContext->Callback)(WriteContext->BusObject->ProtocolHandle, WriteContext->RequestHandle, Status, WriteContext->Mdl); + } + + if (WriteContext->LookasideBuffer != NULL) + { + + WdfObjectDelete(WriteContext->LookasideBuffer); + } + + if (WriteContext->UrbMemory != NULL) + { + WdfObjectDelete(WriteContext->UrbMemory); + } + + FreeWriteRequest(WriteContext->BusObject->WdfUsbDevice, Request); +} + +NTSTATUS +MbbBusWriteData(__in MBB_BUS_HANDLE BusHandle, __in MBB_REQUEST_HANDLE RequestHandle, __in PMDL Mdl, __in MBB_BUS_SEND_DATA_COMPLETION_CALLBACK Callback) + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + PMDL TempMdl = NULL; + ULONGLONG TotalTransferLength = 0; + NTSTATUS Status; + WDFMEMORY urbMemory = NULL; + WDF_OBJECT_ATTRIBUTES objectAttribs; + PURB urbBuffer = NULL; + WDF_REQUEST_SEND_OPTIONS SendOptions; + WDFREQUEST WriteRequest = NULL; + USBD_PIPE_HANDLE usbdPipeHandle = NULL; + PUSB_WRITE_REQ_CONTEXT writeContext = NULL; + BOOLEAN SentToDevice = FALSE; + WDFMEMORY BufferMemoryObject = NULL; + WDFREQUEST WriteRequestZLP = NULL; + PUSB_WRITE_REQ_CONTEXT writeContextZLP = NULL; + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + if (!ExAcquireRundownProtection(&usbDeviceContext->BulkPipeResetRundown)) + { + return STATUS_NDIS_ADAPTER_NOT_READY; + } + + // + // make sure the length is not too big + // + TempMdl = Mdl; + + while (TempMdl != NULL) + { + TotalTransferLength += MmGetMdlByteCount(TempMdl); + + TempMdl = TempMdl->Next; + } + + if (TotalTransferLength > BusObject->NtbParam.dwNtbOutMaxSize) + { + // + // too big + // + Status = STATUS_UNSUCCESSFUL; + + goto Cleanup; + } + + if ((TotalTransferLength < BusObject->NtbParam.dwNtbOutMaxSize) && (TotalTransferLength % usbDeviceContext->BulkOutputPipeMaxPacket == 0)) + { + // + // The transfer length is less than the max out transfer size, and transfer length is a multiple of MaxPacket size. + // Need to send a ZLP to the device stack to terminated the transfer. + + Status = GetWriteRequests(BusObject->WdfUsbDevice, &WriteRequestZLP); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + writeContextZLP = GetWriteRequestContext(WriteRequestZLP); + + writeContextZLP->BusObject = BusObject; + writeContextZLP->Callback = NULL; + } + + Status = GetWriteRequests(BusObject->WdfUsbDevice, &WriteRequest); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + writeContext = GetWriteRequestContext(WriteRequest); + + if (usbDeviceContext->LookasideList == NULL) + { + + // + // allocate the URB, request is the parent + // + WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs); + objectAttribs.ParentObject = WriteRequest; + + Status = WdfUsbTargetDeviceCreateUrb(BusObject->WdfUsbDevice, &objectAttribs, &urbMemory, &urbBuffer); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + // + // get the USBD pipe handle, to build the URB + // + usbdPipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(usbDeviceContext->BulkOutputPipe); + + // + // NOTE : call UsbBuildInterruptOrBulkTransferRequest otherwise + // WdfUsbTargetPipeFormatRequestForUrb will assert + // with *** Assertion failed: Urb->UrbHeader.Length >= sizeof(_URB_HEADER) + // + UsbBuildInterruptOrBulkTransferRequest( + urbBuffer, + sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), + usbdPipeHandle, + NULL, + Mdl, + (ULONG)TotalTransferLength, + USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK, + NULL); + + // + // By calling WdfUsbTargetPipeFormatRequestForUrb the frameworks allocate a lot of resources + // like the underlying IRP for the request and hence it is better to do it at initilization + // to prevent an avoidable failure later. + // + Status = WdfUsbTargetPipeFormatRequestForUrb(usbDeviceContext->BulkOutputPipe, WriteRequest, urbMemory, NULL); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + writeContext->UrbMemory = urbMemory; + writeContext->Urb = (PURB)urbBuffer; + } + else + { + // + // usb stack does not support chained mdl's, double buffer the transfer + // + PUCHAR DestBuffer = NULL; + PUCHAR SourceAddress = NULL; + size_t BufferSize = 0; + ULONG SourceLength = 0; + WDFMEMORY_OFFSET MemoryOffset; + + Status = WdfMemoryCreateFromLookaside(usbDeviceContext->LookasideList, &BufferMemoryObject); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + DestBuffer = (PUCHAR)WdfMemoryGetBuffer(BufferMemoryObject, &BufferSize); + + TempMdl = Mdl; + TotalTransferLength = 0; + while (TempMdl != NULL) + { + SourceLength = MmGetMdlByteCount(TempMdl); + + SourceAddress = (PUCHAR)MmGetSystemAddressForMdlSafe(TempMdl, NormalPagePriority | MdlMappingNoExecute); + + if (SourceAddress == NULL) + { + + Status = STATUS_INSUFFICIENT_RESOURCES; + + goto Cleanup; + } + + RtlCopyMemory(DestBuffer, SourceAddress, SourceLength); + + DestBuffer += SourceLength; + + TotalTransferLength += SourceLength; + + ASSERT(TotalTransferLength <= BufferSize); + + TempMdl = TempMdl->Next; + } + + MemoryOffset.BufferOffset = 0; + MemoryOffset.BufferLength = (ULONG)TotalTransferLength; + + Status = WdfUsbTargetPipeFormatRequestForWrite(usbDeviceContext->BulkOutputPipe, WriteRequest, BufferMemoryObject, &MemoryOffset); + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + writeContext->LookasideBuffer = BufferMemoryObject; + BufferMemoryObject = NULL; + } + + // + // set REQUEST_CONTEXT parameters. + // + + writeContext->Mdl = Mdl; + writeContext->BusObject = BusObject; + writeContext->Callback = Callback; + writeContext->RequestHandle = RequestHandle; + + WdfRequestSetCompletionRoutine(WriteRequest, WriteCompletionRoutine, writeContext); + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, 0); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(30)); + + SentToDevice = WdfRequestSend(WriteRequest, WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkOutputPipe), &SendOptions); + + Status = STATUS_PENDING; + + if (!SentToDevice) + { + Status = WdfRequestGetStatus(WriteRequest); + } + else + { + WriteRequest = NULL; + } + + if (NT_SUCCESS(Status)) + { + + // + // actual data write worked, see if we need to send the zlp + // + + if (WriteRequestZLP != NULL) + { + + NTSTATUS ZlpStatus; + + Status = WdfUsbTargetPipeFormatRequestForWrite(usbDeviceContext->BulkOutputPipe, WriteRequestZLP, NULL, NULL); + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + WdfRequestSetCompletionRoutine(WriteRequestZLP, WriteCompletionRoutine, writeContextZLP); + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, 0); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(30)); + + SentToDevice = WdfRequestSend(WriteRequestZLP, WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkOutputPipe), &SendOptions); + + ZlpStatus = STATUS_PENDING; + + if (!SentToDevice) + { + + ZlpStatus = WdfRequestGetStatus(WriteRequestZLP); + } + else + { + WriteRequestZLP = NULL; + } + } + } + +Cleanup: + + ExReleaseRundownProtection(&usbDeviceContext->BulkPipeResetRundown); + + if (WriteRequest != NULL) + { + if (NULL != writeContext) + { + if (NULL != writeContext->LookasideBuffer) + { + WdfObjectDelete(writeContext->LookasideBuffer); + } + if (NULL != writeContext->UrbMemory) + { + WdfObjectDelete(writeContext->UrbMemory); + } + } + + FreeWriteRequest(BusObject->WdfUsbDevice, WriteRequest); + WriteRequest = NULL; + } + + if (WriteRequestZLP != NULL) + { + FreeWriteRequest(BusObject->WdfUsbDevice, WriteRequestZLP); + WriteRequestZLP = NULL; + } + + return Status; +} + +VOID BulkInReadComplete(__in WDFUSBPIPE Pipe, __in WDFMEMORY Memory, __in size_t NumBytesTransferred, __in WDFCONTEXT Context) + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)Context; + PUCHAR Buffer = NULL; + PMDL Mdl = NULL; + PUCHAR DataBuffer = NULL; + + if (NumBytesTransferred > 0) + { + // + // actaully got some data + // + Buffer = (PUCHAR)WdfMemoryGetBuffer(Memory, NULL); + + // + // the header at the front is where we will put the MDL + // + Mdl = (PMDL)Buffer; + + // + // the actual payload starts after the header/mdl + // + DataBuffer = Buffer + BusObject->BulkInHeaderSize; + + ASSERT(((ULONG_PTR)DataBuffer & 0x7) == 0); + + // + // bytes transfered does not include the header + // + MmInitializeMdl(Mdl, DataBuffer, NumBytesTransferred); + + MmBuildMdlForNonPagedPool(Mdl); + + ASSERT(BusObject->BulkInHeaderSize >= MmSizeOfMdl(Mdl, NumBytesTransferred)); + + WdfObjectReference(Memory); + + (*BusObject->ReceiveDataCallback)(BusObject->ProtocolHandle, Memory, Mdl); + } + + return; +} + +BOOLEAN +BulkInReadError(__in WDFUSBPIPE Pipe, __in NTSTATUS Status, __in USBD_STATUS UsbdStatus) + +{ + return TRUE; +} + +VOID MbbBusReturnReceiveBuffer(__in MBB_BUS_HANDLE BusHandle, __in MBB_RECEIVE_CONTEXT ReceiveContext, __in PMDL Mdl) + +{ + WDFMEMORY Memory = (WDFMEMORY)ReceiveContext; + + WdfObjectDereference(Memory); + + return; +} + +NTSTATUS +CreateWriteRequest(WDFUSBDEVICE UsbDevice, WDFREQUEST* ReturnedWriteRequest) + +{ + + WDFREQUEST WriteRequest = NULL; + PUSB_WRITE_REQ_CONTEXT writeContext = NULL; + WDF_OBJECT_ATTRIBUTES objectAttribs; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + NTSTATUS Status = STATUS_INVALID_PARAMETER; + + *ReturnedWriteRequest = NULL; + + usbDeviceContext = GetUsbDeviceContext(UsbDevice); + + if (usbDeviceContext->BulkOutputPipe == NULL) + { + goto Cleanup; + } + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&objectAttribs, USB_WRITE_REQ_CONTEXT); + objectAttribs.ParentObject = UsbDevice; + + // + // create the request + // + Status = WdfRequestCreate(&objectAttribs, WdfUsbTargetPipeGetIoTarget(usbDeviceContext->BulkOutputPipe), &WriteRequest); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + writeContext = GetWriteRequestContext(WriteRequest); + RtlZeroMemory(writeContext, sizeof(*writeContext)); + + // + // Preallocate the request timer to prevent the request from failing while trying to send it. + // + Status = WdfRequestAllocateTimer(WriteRequest); + + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + Status = WdfUsbTargetPipeFormatRequestForWrite(usbDeviceContext->BulkOutputPipe, WriteRequest, NULL, NULL); + if (!NT_SUCCESS(Status)) + { + + goto Cleanup; + } + + *ReturnedWriteRequest = WriteRequest; + WriteRequest = NULL; + +Cleanup: + + if (WriteRequest != NULL) + { + WdfObjectDelete(WriteRequest); + WriteRequest = NULL; + } + + return Status; +} + +NTSTATUS +PreAllocateWriteRequests(WDFUSBDEVICE UsbDevice) + +{ + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + WDFREQUEST WriteRequest = NULL; + NTSTATUS Status; + ULONG i = 0; + + usbDeviceContext = GetUsbDeviceContext(UsbDevice); + + for (i = 0; i < MAX_PREALLOCATED_WRITE_REQUESTS; i++) + { + Status = CreateWriteRequest(UsbDevice, &WriteRequest); + + if (!NT_SUCCESS(Status)) + { + break; + } + + Status = WdfCollectionAdd(usbDeviceContext->WriteRequestCollection, WriteRequest); + + if (!NT_SUCCESS(Status)) + { + WdfObjectDelete(WriteRequest); + WriteRequest = NULL; + break; + } + } + + return Status; +} + +NTSTATUS +GetWriteRequests(WDFUSBDEVICE UsbDevice, WDFREQUEST* ReturnedWriteRequest) +{ + + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + NTSTATUS Status = STATUS_SUCCESS; + WDF_REQUEST_REUSE_PARAMS ReuseParams; + PUSB_WRITE_REQ_CONTEXT writeContext = NULL; + + usbDeviceContext = GetUsbDeviceContext(UsbDevice); + + *ReturnedWriteRequest = NULL; + + if (usbDeviceContext->BulkOutputPipe == NULL) + { + return STATUS_UNSUCCESSFUL; + } + + WdfSpinLockAcquire(usbDeviceContext->WriteCollectionLock); + + *ReturnedWriteRequest = (WDFREQUEST)WdfCollectionGetLastItem(usbDeviceContext->WriteRequestCollection); + + if (*ReturnedWriteRequest == NULL) + { + // + // the collection is empty, try creating a new one + // + WdfSpinLockRelease(usbDeviceContext->WriteCollectionLock); + + Status = CreateWriteRequest(UsbDevice, ReturnedWriteRequest); + } + else + { + + WdfCollectionRemove(usbDeviceContext->WriteRequestCollection, *ReturnedWriteRequest); + + WdfSpinLockRelease(usbDeviceContext->WriteCollectionLock); + + WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, 0, STATUS_SUCCESS); + + WdfRequestReuse(*ReturnedWriteRequest, &ReuseParams); + } + + if (NT_SUCCESS(Status)) + { + writeContext = GetWriteRequestContext(*ReturnedWriteRequest); + RtlZeroMemory(writeContext, sizeof(*writeContext)); + } + + return Status; +} + +VOID FreeWriteRequest(WDFUSBDEVICE UsbDevice, WDFREQUEST WriteRequest) + +{ + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + NTSTATUS Status = STATUS_SUCCESS; + ULONG RequestCount = 0; + + usbDeviceContext = GetUsbDeviceContext(UsbDevice); + + WdfSpinLockAcquire(usbDeviceContext->WriteCollectionLock); + + RequestCount = WdfCollectionGetCount(usbDeviceContext->WriteRequestCollection); + + if (RequestCount < MAX_PREALLOCATED_WRITE_REQUESTS * 2) + { + // + // put it back in the collection + // + Status = WdfCollectionAdd(usbDeviceContext->WriteRequestCollection, WriteRequest); + + if (NT_SUCCESS(Status)) + { + WriteRequest = NULL; + } + } + + WdfSpinLockRelease(usbDeviceContext->WriteCollectionLock); + + if (WriteRequest != NULL) + { + WdfObjectDelete(WriteRequest); + WriteRequest = NULL; + } + + return; +} + +VOID MbbBusResetDataPipes(_In_ MBB_BUS_HANDLE BusHandle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + PUSB_DEVICE_CONTEXT usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + if (!InterlockedCompareExchange(&usbDeviceContext->BulkPipeResetFlag, TRUE, FALSE)) + { + WdfWorkItemEnqueue(usbDeviceContext->BulkPipeResetWorkitem); + } + else + { + } +} + +VOID MbbUsbDeviceCyclePort(_In_ PUSB_DEVICE_CONTEXT usbDeviceContext) +{ + NTSTATUS Status = WdfUsbTargetDeviceCyclePortSynchronously(usbDeviceContext->BusObject->WdfUsbDevice); + if (!NT_SUCCESS(Status)) + { + } +} + +void ResetDataPipeWorkItem(_In_ WDFWORKITEM WorkItem) +{ + PUSB_DEVICE_CONTEXT usbDeviceContext = GetUsbDeviceContext(WdfWorkItemGetParentObject(WorkItem)); + + ExWaitForRundownProtectionRelease(&usbDeviceContext->BulkPipeResetRundown); + ExRundownCompleted(&usbDeviceContext->BulkPipeResetRundown); + + MbbUsbDeviceStopDataPipes(usbDeviceContext); + + MbbUsbDeviceResetBulkPipe(usbDeviceContext, TRUE); + + MbbUsbDeviceCyclePort(usbDeviceContext); + + MbbUsbDeviceStartDataPipes(usbDeviceContext); + + ExReInitializeRundownProtection(&usbDeviceContext->BulkPipeResetRundown); + + InterlockedExchange(&usbDeviceContext->BulkPipeResetFlag, FALSE); +} diff --git a/network/wwan/cxwmbclass/device.cpp b/network/wwan/cxwmbclass/device.cpp new file mode 100644 index 000000000..1a7dfc958 --- /dev/null +++ b/network/wwan/cxwmbclass/device.cpp @@ -0,0 +1,391 @@ +//------------------------------------------------------------------------------- +// Net Adapter source file +// +// Copyright (c) Microsoft Corporation. All rights reserved. + +#include "precomp.h" + +#include "device.h" +#include "rxqueue.h" + +const ULONG MBB_DEFAULT_IDLE_TIMEOUT_HINT_MS = 2u * 1000u; // 2 seconds + +_Use_decl_annotations_ VOID EvtMbbDeviceSendMbimFragment(WDFDEVICE Device, MBBREQUEST Fragment) +{ + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(Device); + + size_t bufferSize = 0; + PVOID buffer = MbbRequestGetBuffer(Fragment, &bufferSize); + + auto completionRoutine = [](MBB_PROTOCOL_HANDLE, MBB_REQUEST_HANDLE RequestHandle, NTSTATUS NtStatus) { + MbbRequestComplete((MBBREQUEST)RequestHandle, NtStatus); + }; + + NTSTATUS sendStatus = MbbBusSendMessageFragment( + deviceContext->BusHandle, Fragment, buffer, (ULONG)bufferSize, (LPGUID)MbbRequestGetCorrelationId(Fragment), completionRoutine); + + // Accoding to the documentation of MbbBusSendMessageFragment the completion routine + // will be called only when ntStatus is STATUS_PENDING, so we need to call it ourselves + // for the other cases + if (sendStatus != STATUS_PENDING) + { + completionRoutine(deviceContext, Fragment, sendStatus); + } +} + +VOID MbbNdisResponseFragmentAvailable(__in MBB_PROTOCOL_HANDLE ProtocolHandle) +{ + PWMBCLASS_DEVICE_CONTEXT deviceContext = (PWMBCLASS_DEVICE_CONTEXT)ProtocolHandle; + MbbDeviceResponseAvailable(deviceContext->WdfDevice); +} + +_Use_decl_annotations_ VOID EvtMbbDeviceReceiveMbimFragment(WDFDEVICE Device, MBBREQUEST Fragment) +{ + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(Device); + + size_t bufferSize = 0; + PVOID buffer = MbbRequestGetBuffer(Fragment, &bufferSize); + + auto completionRoutine = [](MBB_PROTOCOL_HANDLE, MBB_REQUEST_HANDLE RequestHandle, NTSTATUS Status, ULONG_PTR ReceivedLength) { + MbbRequestCompleteWithInformation((MBBREQUEST)RequestHandle, Status, ReceivedLength); + }; + + // Accoding to the documentation of MbbBusReceiveMessageFragment the completion routine + // will be called only when ntStatus is STATUS_PENDING, so we need to call it ourselves + // for the other cases + NTSTATUS receiveStatus = MbbBusReceiveMessageFragment( + deviceContext->BusHandle, Fragment, buffer, (ULONG)bufferSize, (LPGUID)MbbRequestGetCorrelationId(Fragment), completionRoutine); + + if (receiveStatus != STATUS_PENDING) + { + // Note: There isn't a case where receiveStatus is STATUS_SUCCESS, it is either pending + // or an error code. The API signature itself is incomplete since it does not return how + // many bytes were read if the request was completed synchronously. Leaving a telemetry + // assert here in case someone changes MbbBusReceiveMessageFragment + //MICROSOFT_TELEMETRY_ASSERT_KM(NT_ERROR(receiveStatus)); + + completionRoutine(deviceContext, Fragment, receiveStatus, 0); + } +} + +static NTSTATUS SetupAdapterSpecificPowerSettings(_In_ PWMBCLASS_DEVICE_CONTEXT DeviceContext) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (DeviceContext->BusParams.RemoteWakeCapable) + { + // + // Configure USB selective suspend with default timeout + // + WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings; + WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleUsbSelectiveSuspend); + + idleSettings.IdleTimeout = MBB_DEFAULT_IDLE_TIMEOUT_HINT_MS; + idleSettings.IdleTimeoutType = SystemManagedIdleTimeoutWithHint; + + status = WdfDeviceAssignS0IdleSettings(DeviceContext->WdfDevice, &idleSettings); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + } +Exit: + return status; +} + +NTSTATUS +MbbInitializeHardware(_In_ PWMBCLASS_DEVICE_CONTEXT DeviceContext) +{ + NTSTATUS status = STATUS_SUCCESS; + WDF_OBJECT_ATTRIBUTES attributes; + UNICODE_STRING manufacturer; + UNICODE_STRING model; + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = DeviceContext->WdfDevice; + status = WdfLookasideListCreate( + &attributes, + sizeof(MBB_NDIS_RECEIVE_CONTEXT), + NonPagedPoolNx, + WDF_NO_OBJECT_ATTRIBUTES, + MbbPoolTagMdlReceive, + &DeviceContext->ReceiveLookasideList); + if (!NT_SUCCESS(status)) + { + goto Cleanup; + } + + for (int i = 0; i < MBB_MAX_NUMBER_OF_SESSIONS; i++) + { + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = DeviceContext->WdfDevice; + + status = WdfSpinLockCreate(&attributes, &DeviceContext->Sessions[i].WdfRecvSpinLock); + if (!NT_SUCCESS(status)) + { + goto Cleanup; + } + } + + status = MbbBusInitializeByWdf( + DeviceContext->WdfDevice, + MbbNdisResponseFragmentAvailable, + MbbNdisReceiveCallback, + nullptr, + nullptr, + DeviceContext, + &DeviceContext->BusHandle, + nullptr); + + if (status != STATUS_SUCCESS) + { + goto Cleanup; + } + + // + // Initialize the OID/CID handlers before the device is OPENED. + // Once the device is opened and the interrupt pipe is connected. + // This driver will start receiving unsolicited interrupt message + // from the device. + // + status = MbbBusQueryBusParameters(DeviceContext->BusHandle, &DeviceContext->BusParams); + + if (status != STATUS_SUCCESS) + { + goto Cleanup; + } + + WDFMEMORY sharedPaddingMemory; + ULONG sharedPaddingLength = max(DeviceContext->BusParams.NdpOutAlignment, DeviceContext->BusParams.NdpOutDivisor); + status = CreateNonPagedWdfMemory( + sharedPaddingLength, &sharedPaddingMemory, (PVOID*)&DeviceContext->sharedPaddingBuffer, DeviceContext->WdfDevice, MbbPoolTagNtbSend); + if (!NT_SUCCESS(status)) + { + goto Cleanup; + } + + RtlInitUnicodeString(&manufacturer, DeviceContext->BusParams.Manufacturer); + RtlInitUnicodeString(&model, DeviceContext->BusParams.Model); + MBB_DEVICE_MBIM_PARAMETERS mbimParams; + + // 2.0 by default + MBB_MBIM_EXTENDED_VERSION mbimExVer = MbbMbimExtendedVersion2Dot0; + switch(DeviceContext->BusParams.MbimExtendedVersion) + { + case 0x0100: + mbimExVer = MbbMbimExtendedVersion1Dot0; + break; + case 0x0200: + mbimExVer = MbbMbimExtendedVersion2Dot0; + break; + case 0x0300: + mbimExVer = MbbMbimExtendedVersion3Dot0; + break; + case 0x0400: + mbimExVer = MbbMbimExtendedVersion4Dot0; + break; + default: + status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + MBB_DEVICE_MBIM_PARAMETERS_INIT( + &mbimParams, + DeviceContext->BusParams.IsErrataDevice ? MbbMbimVersion1Dot0Errata : MbbMbimVersion1Dot0, + DeviceContext->BusParams.FragmentSize, + mbimExVer); + + MbbDeviceSetMbimParameters(DeviceContext->WdfDevice, &mbimParams); + //MBB_DEVICE_OPTIONAL_PARAMETERS optionalParameters; + //MBB_DEVICE_OPTIONAL_PARAMETERS_INIT(&optionalParameters, manufacturer, model, MbbBusIsUde(DeviceContext->BusHandle)); + //MbbDeviceSetOptionalParameters(DeviceContext->WdfDevice, &optionalParameters); + + MBB_DEVICE_WAKE_CAPABILITIES mbbWakeCapabilities; + MBB_DEVICE_WAKE_CAPABILITIES_INIT(&mbbWakeCapabilities); + + mbbWakeCapabilities.PacketState = TRUE; + mbbWakeCapabilities.RegisterState = TRUE; + mbbWakeCapabilities.SmsReceive = TRUE; + mbbWakeCapabilities.UiccChange = TRUE; + mbbWakeCapabilities.UssdReceive = TRUE; + + MbbDeviceSetWakeCapabilities(DeviceContext->WdfDevice, &mbbWakeCapabilities); + + status = SetupAdapterSpecificPowerSettings(DeviceContext); + if (NT_ERROR(status)) + { + goto Cleanup; + } + +Cleanup: + + if (status != STATUS_SUCCESS) + { + if (DeviceContext != NULL) + { + if (DeviceContext->BusHandle != NULL) + { + MbbBusStop(DeviceContext->BusHandle); + MbbBusCleanup(DeviceContext->BusHandle); + DeviceContext->BusHandle = NULL; + } + } + + } + + return status; +} + +void MbbReleaseHardware(_In_ PWMBCLASS_DEVICE_CONTEXT DeviceContext) +{ + + if (DeviceContext->BusHandle != NULL) + { + MbbBusCleanup(DeviceContext->BusHandle); + DeviceContext->BusHandle = NULL; + } + + return; +} + +NTSTATUS +EvtDevicePrepareHardware(_In_ WDFDEVICE device, _In_ WDFCMRESLIST resourcesRaw, _In_ WDFCMRESLIST resourcesTranslated) +{ + UNREFERENCED_PARAMETER(resourcesRaw); + UNREFERENCED_PARAMETER(resourcesTranslated); + + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(device); + + NTSTATUS status = MbbInitializeHardware(deviceContext); + + return status; +} + +NTSTATUS +EvtDeviceReleaseHardware(_In_ WDFDEVICE device, _In_ WDFCMRESLIST resourcesTranslated) +{ + UNREFERENCED_PARAMETER(resourcesTranslated); + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(device); + + MbbReleaseHardware(deviceContext); + + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ void EvtDeviceSurpriseRemoval(WDFDEVICE device) +{ + UNREFERENCED_PARAMETER(device); +} + +NTSTATUS MbbInitAdapterContext(_In_ WDFDEVICE Device, _In_ NETADAPTER NetAdapter) +{ + WDF_OBJECT_ATTRIBUTES adapterAttributes; + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(Device); + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = WmbClassGetNetAdapterContext(NetAdapter); + + ULONG ntbSize; + ntbSize = FIELD_OFFSET(MBB_NTB_BUILD_CONTEXT, NdpDatagramEntries); + ntbSize += (deviceContext->BusParams.MaxOutDatagrams * sizeof(MBB_NDP_HEADER_ENTRY)); + + WDF_OBJECT_ATTRIBUTES_INIT(&adapterAttributes); + adapterAttributes.ParentObject = NetAdapter; + + NTSTATUS ntStatus = WdfLookasideListCreate( + &adapterAttributes, ntbSize, NonPagedPoolNx, WDF_NO_OBJECT_ATTRIBUTES, MbbPoolTagNtbSend, &netAdapterContext->NtbLookasideList); + if (!NT_SUCCESS(ntStatus)) + { + return ntStatus; + } + + WDF_OBJECT_ATTRIBUTES_INIT(&adapterAttributes); + adapterAttributes.ParentObject = NetAdapter; + ntStatus = WdfLookasideListCreate( + &adapterAttributes, + sizeof(MBB_RECEIVE_NDP_CONTEXT), + NonPagedPoolNx, + WDF_NO_OBJECT_ATTRIBUTES, + MbbPoolTagMdlReceive, + &netAdapterContext->ReceiveNdpLookasideList); + if (!NT_SUCCESS(ntStatus)) + { + return ntStatus; + } + netAdapterContext->SessionId = MbbAdapterGetSessionId(NetAdapter); + WdfSpinLockAcquire(deviceContext->Sessions[netAdapterContext->SessionId].WdfRecvSpinLock); + deviceContext->Sessions[netAdapterContext->SessionId].NetAdapterContext = netAdapterContext; + // Allow to receive data from this point since connection may happen before RxQueueCreate, if it happens, we allow to cache the recieved NDP + netAdapterContext->AllowRxTraffic = TRUE; + InitializeListHead(&netAdapterContext->ReceiveNdpList); + netAdapterContext->WmbDeviceContext = deviceContext; + netAdapterContext->NetAdapter = NetAdapter; + WdfSpinLockRelease(deviceContext->Sessions[netAdapterContext->SessionId].WdfRecvSpinLock); + return ntStatus; +} + +_Use_decl_annotations_ NTSTATUS EvtMbbDeviceCreateAdapter(WDFDEVICE Device, NETADAPTER_INIT* AdapterInit) +{ + + NET_ADAPTER_DATAPATH_CALLBACKS datapathCallbacks; + NET_ADAPTER_DATAPATH_CALLBACKS_INIT(&datapathCallbacks, EvtAdapterCreateTxQueue, EvtAdapterCreateRxQueue); + + NetAdapterInitSetDatapathCallbacks(AdapterInit, &datapathCallbacks); + + WDF_OBJECT_ATTRIBUTES adapterAttributes; + WDF_OBJECT_ATTRIBUTES_INIT(&adapterAttributes); + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&adapterAttributes, WMBCLASS_NETADAPTER_CONTEXT); + adapterAttributes.EvtCleanupCallback = EvtAdapterCleanup; + + NETADAPTER netAdapter; + NTSTATUS ntStatus = NetAdapterCreate(AdapterInit, &adapterAttributes, &netAdapter); + if (!NT_SUCCESS(ntStatus)) + { + return ntStatus; + } + + ntStatus = MbbAdapterInitialize(netAdapter); + + if (!NT_SUCCESS(ntStatus)) + { + return ntStatus; + } + + ntStatus = MbbInitAdapterContext(Device, netAdapter); + if (!NT_SUCCESS(ntStatus)) + { + return ntStatus; + } + + ntStatus = WmbClassAdapterStart(netAdapter); + + if (!NT_SUCCESS(ntStatus)) + { + return ntStatus; + } + + return ntStatus; +} + +_Use_decl_annotations_ VOID EvtAdapterCleanup(_In_ WDFOBJECT NetAdapter) +{ + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = WmbClassGetNetAdapterContext(NetAdapter); + PWMBCLASS_DEVICE_CONTEXT deviceContext = netAdapterContext->WmbDeviceContext; + if (deviceContext == NULL || deviceContext->Sessions[netAdapterContext->SessionId].NetAdapterContext == NULL) + { + return; + } + + // Cancel these Ndps which are cached before RxQueueCreate but not cleaned in case RxQueueCreate failed. + // NetAdapter should be destoryed immediately if RxQueueCreate failed, or these cached Ndps will stay in memory until release device or delete additional PDP + MbbRecvCancelNdps(deviceContext, netAdapterContext->SessionId); + + WdfSpinLockAcquire(deviceContext->Sessions[netAdapterContext->SessionId].WdfRecvSpinLock); + deviceContext->Sessions[netAdapterContext->SessionId].NetAdapterContext = NULL; + WdfSpinLockRelease(deviceContext->Sessions[netAdapterContext->SessionId].WdfRecvSpinLock); + +} + +_Use_decl_annotations_ VOID EvtMbbDeviceReset(WDFDEVICE WdfDevice) +{ + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(WdfDevice); + MbbBusResetDataPipes(deviceContext->BusHandle); +} diff --git a/network/wwan/cxwmbclass/driver.cpp b/network/wwan/cxwmbclass/driver.cpp new file mode 100644 index 000000000..490472df2 --- /dev/null +++ b/network/wwan/cxwmbclass/driver.cpp @@ -0,0 +1,121 @@ +//------------------------------------------------------------------------------- +// Net Adapter source file +// +// Copyright (c) Microsoft Corporation. All rights reserved. + +#include "precomp.h" + +#include "device.h" +#include "power.h" + +MINIPORT_DRIVER_CONTEXT GlobalControl = {0}; + +EXTERN_C __declspec(code_seg("INIT")) DRIVER_INITIALIZE DriverEntry; +EVT_WDF_DRIVER_UNLOAD EvtDriverUnload; +EVT_WDF_DRIVER_DEVICE_ADD EvtDriverDeviceAdd; + +#define MBB_DRIVER_DEFAULT_POOL_TAG 'DBMW' + +__declspec(code_seg("INIT")) NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) +{ + NTSTATUS status = STATUS_SUCCESS; + + WDF_DRIVER_CONFIG driverConfig; + WDF_DRIVER_CONFIG_INIT(&driverConfig, EvtDriverDeviceAdd); + driverConfig.DriverPoolTag = MBB_DRIVER_DEFAULT_POOL_TAG; + + driverConfig.EvtDriverUnload = EvtDriverUnload; + + WDFDRIVER driver; + status = WdfDriverCreate(driverObject, registryPath, WDF_NO_OBJECT_ATTRIBUTES, &driverConfig, &driver); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + return status; +} + +NTSTATUS +EvtDriverDeviceAdd(_In_ WDFDRIVER driver, _Inout_ PWDFDEVICE_INIT deviceInit) +{ + UNREFERENCED_PARAMETER((driver)); + + NTSTATUS status = STATUS_SUCCESS; + + status = NetDeviceInitConfig(deviceInit); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + status = MbbDeviceInitConfig(deviceInit); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + // Register with the NetAdapter framework that we want to do the Device Reset + //NET_DEVICE_RESET_CONFIG resetConfig; + //NET_DEVICE_RESET_CONFIG_INIT(&resetConfig, EvtMbbDeviceReset); + //NetDeviceInitSetResetConfig(deviceInit, &resetConfig); + + NET_DEVICE_POWER_POLICY_EVENT_CALLBACKS netPowerPolicyCallbacks; + NET_DEVICE_POWER_POLICY_EVENT_CALLBACKS_INIT(&netPowerPolicyCallbacks); + netPowerPolicyCallbacks.EvtDevicePreviewBitmapPattern = EvtDevicePreviewBitmapPattern; + + NetDeviceInitSetPowerPolicyEventCallbacks(deviceInit, &netPowerPolicyCallbacks); + + WDF_OBJECT_ATTRIBUTES deviceAttributes; + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, WMBCLASS_DEVICE_CONTEXT); + + WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; + WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); + pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware; + pnpPowerCallbacks.EvtDeviceReleaseHardware = EvtDeviceReleaseHardware; + pnpPowerCallbacks.EvtDeviceSurpriseRemoval = EvtDeviceSurpriseRemoval; + pnpPowerCallbacks.EvtDeviceD0Entry = EvtDeviceD0Entry; + pnpPowerCallbacks.EvtDeviceD0Exit = EvtDeviceD0Exit; + WdfDeviceInitSetPnpPowerEventCallbacks(deviceInit, &pnpPowerCallbacks); + + WDF_POWER_POLICY_EVENT_CALLBACKS powerPolicyCallbacks; + WDF_POWER_POLICY_EVENT_CALLBACKS_INIT(&powerPolicyCallbacks); + powerPolicyCallbacks.EvtDeviceArmWakeFromS0 = EvtDeviceArmWakeFromS0; + powerPolicyCallbacks.EvtDeviceDisarmWakeFromS0 = EvtDeviceDisarmWakeFromS0; + WdfDeviceInitSetPowerPolicyEventCallbacks(deviceInit, &powerPolicyCallbacks); + + WDFDEVICE wdfDevice; + status = WdfDeviceCreate(&deviceInit, &deviceAttributes, &wdfDevice); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + // Set the device to be not ejectable + WDF_DEVICE_PNP_CAPABILITIES pnpCapabilities; + WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCapabilities); + pnpCapabilities.SurpriseRemovalOK = WdfTrue; + WdfDeviceSetPnpCapabilities(wdfDevice, &pnpCapabilities); + + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(wdfDevice); + deviceContext->WdfDevice = wdfDevice; + + MBB_DEVICE_CONFIG mbbDeviceConfig; + MBB_DEVICE_CONFIG_INIT( + &mbbDeviceConfig, EvtMbbDeviceSendMbimFragment, EvtMbbDeviceReceiveMbimFragment, EvtMbbDeviceSendDeviceServiceSessionData, EvtMbbDeviceCreateAdapter); + + status = MbbDeviceInitialize(wdfDevice, &mbbDeviceConfig); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + return status; +} + +VOID EvtDriverUnload(_In_ WDFDRIVER driver) +{ + UNREFERENCED_PARAMETER(driver); +} diff --git a/network/wwan/cxwmbclass/inc/BusFastIO.h b/network/wwan/cxwmbclass/inc/BusFastIO.h new file mode 100644 index 000000000..fd396f2e3 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/BusFastIO.h @@ -0,0 +1,35 @@ +#pragma once + +// FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE FastIOSendNetBufferListsComplete; +// FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS FastIOIndicateReceiveNetBufferLists; + +_IRQL_requires_max_(DISPATCH_LEVEL) +EXTERN_C VOID MbbBusSendNetBufferLists(_In_ MBB_BUS_HANDLE BusHandle, _In_ PNET_BUFFER_LIST NetBufferList, _In_ ULONG SessionId, _In_ ULONG SendFlags); + +_IRQL_requires_max_(DISPATCH_LEVEL) +EXTERN_C VOID MbbBusReturnNetBufferLists(_In_ MBB_BUS_HANDLE BusHandle, _In_ PNET_BUFFER_LIST NetBufferList, _In_ ULONG ReturnFlags); + +_IRQL_requires_max_(DISPATCH_LEVEL) +EXTERN_C VOID MbbBusCancelSendHandler(_In_ MBB_BUS_HANDLE BusHandle, _In_ PVOID CancelId); + +_IRQL_requires_(PASSIVE_LEVEL) +EXTERN_C +VOID MbbBusHalt(_In_ MBB_BUS_HANDLE BusHandle, _In_ NDIS_HALT_ACTION HaltAction); + +_IRQL_requires_(PASSIVE_LEVEL) +EXTERN_C +NDIS_STATUS +MbbBusPause(_In_ MBB_BUS_HANDLE BusHandle); + +_When_(ShutdownAction == NdisShutdownPowerOff, _IRQL_requires_(PASSIVE_LEVEL)) + _When_(ShutdownAction == NdisShutdownBugCheck, _IRQL_requires_(HIGH_LEVEL)) + EXTERN_C VOID MbbBusShutdown(_In_ MBB_BUS_HANDLE BusHandle, _In_ NDIS_SHUTDOWN_ACTION ShutdownAction); + + _IRQL_requires_max_(DISPATCH_LEVEL) + EXTERN_C NDIS_STATUS MbbBusReset(_In_ MBB_BUS_HANDLE BusHandle); + + _IRQL_requires_max_(DISPATCH_LEVEL) + EXTERN_C NDIS_STATUS MbbBusRestart(_In_ MBB_BUS_HANDLE BusHandle); + + _IRQL_requires_max_(DISPATCH_LEVEL) + EXTERN_C BOOLEAN MbbBusIsFastIO(_In_ MBB_BUS_HANDLE BusHandle); \ No newline at end of file diff --git a/network/wwan/cxwmbclass/inc/BusInterface.h b/network/wwan/cxwmbclass/inc/BusInterface.h new file mode 100644 index 000000000..d72c663a3 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/BusInterface.h @@ -0,0 +1,573 @@ +/*************************************************************************** + +Copyright (c) 2010 Microsoft Corporation + +Module Name: + + BusInterface.h + +Abstract: + + This module defines the interface between the upper NDIS layer and lower + bus layer of the MBB (Mobile BroadBand) Class driver. + +Environment: + + kernel mode only + +Notes: + + The upper ndis layer may only communicate with the lower bus layer through + these interfaces. + +Revision History: + + 2/7/2010 : created + +Authors: + + TriRoy + +****************************************************************************/ + +#ifndef _BusInterface_H_ +#define _BusInterface_H_ + +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#if 0 +#include "MbbDebug.h" +#endif +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// + +#define MAX_PARAMETER_STRING (128) + +#define ALT_DATA_SETTING_0 (0) +#define ALT_DATA_SETTING_1 (1) + +#define MAX_PENDING_SENDS (3) + +//////////////////////////////////////////////////////////////////////////////// +// +// TYPEDEFS +// +//////////////////////////////////////////////////////////////////////////////// +typedef PVOID MBB_BUS_HANDLE; +typedef PVOID MBB_PROTOCOL_HANDLE; +typedef PVOID MBB_REQUEST_HANDLE; +typedef PVOID MBB_RECEIVE_CONTEXT; + +typedef struct _MBB_BUS_PARAMETERS +{ + ULONG FragmentSize; + + ULONG MaxSegmentSize; + + BOOLEAN ChainedMdlsSupported; + BOOLEAN Ntb32BitSupported; + BOOLEAN CurrentMode32Bit; + BOOLEAN SelectiveSuspendSupported; + + ULONG MaxOutNtb; + USHORT MaxOutDatagrams; + USHORT NdpOutDivisor; + USHORT NdpOutRemainder; + USHORT NdpOutAlignment; + + BYTE PowerFiltersSupported; + BYTE MaxPowerFilterSize; + + WCHAR Manufacturer[MAX_PARAMETER_STRING]; + WCHAR Model[MAX_PARAMETER_STRING]; + + BYTE MaxOutstandingCommandMessages; + USHORT MTU; + BOOLEAN IsErrataDevice; + USHORT MbimVersion; + BOOLEAN RemoteWakeCapable; + USHORT MbimExtendedVersion; + +} MBB_BUS_PARAMETERS, *PMBB_BUS_PARAMETERS; + +typedef struct _MBB_CONNECTION_STATE +{ + + BOOLEAN ConnectionUp; + ULONGLONG UpStreamBitRate; + ULONGLONG DownStreamBitRate; + +} MBB_CONNECTION_STATE, *PMBB_CONNECTION_STATE; + +typedef __callback VOID (*MBB_BUS_SEND_COMPLETION_CALLBACK)(__in MBB_PROTOCOL_HANDLE ProtocolHandle, __in MBB_REQUEST_HANDLE RequestHandle, __in NTSTATUS Status); + +typedef __callback VOID (*MBB_BUS_RECEIVE_COMPLETION_CALLBACK)( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, __in MBB_REQUEST_HANDLE RequestHandle, __in NTSTATUS Status, __in ULONG_PTR ReceivedLength); + +typedef __callback VOID (*MBB_BUS_RESPONSE_AVAILABLE_CALLBACK)(__in MBB_PROTOCOL_HANDLE ProtocolHandle); + +typedef __callback VOID (*MBB_BUS_SEND_DATA_COMPLETION_CALLBACK)( + __in MBB_PROTOCOL_HANDLE ProtocolHandle, __in MBB_REQUEST_HANDLE RequestHandle, __in NTSTATUS Status, __in PMDL Mdl); + +typedef __callback VOID (*MBB_BUS_DATA_RECEIVE_CALLBACK)(__in MBB_PROTOCOL_HANDLE ProtocolHandle, __in MBB_RECEIVE_CONTEXT ReceiveContext, __in PMDL Mdl); + +typedef __callback VOID (*MBB_BUS_SS_IDLE_CONFIRM_CALLBACK)(__in MBB_PROTOCOL_HANDLE ProtocolHandle, __in DEVICE_POWER_STATE PowerState); + +typedef __callback VOID (*MBB_BUS_SS_IDLE_NOTIFICATION_COMPLETE_CALLBACK)(__in MBB_PROTOCOL_HANDLE ProtocolHandle, __in NTSTATUS Status); + +//////////////////////////////////////////////////////////////////////////////// +// +// INTERFACE +// +//////////////////////////////////////////////////////////////////////////////// +EXTERN_C +NTSTATUS +MbbBusInitialize( + _In_ PDEVICE_OBJECT Pdo, + _In_ PDEVICE_OBJECT Fdo, + _In_ PDEVICE_OBJECT NextDeviceObject, + _In_ MBB_BUS_RESPONSE_AVAILABLE_CALLBACK ResponseAvailableCallback, + _In_ MBB_BUS_DATA_RECEIVE_CALLBACK ReceiveDataCallback, + _In_ MBB_BUS_SS_IDLE_CONFIRM_CALLBACK IdleConfirmCallback, + _In_ MBB_BUS_SS_IDLE_NOTIFICATION_COMPLETE_CALLBACK IdleNotificationComplete, + _In_ MBB_PROTOCOL_HANDLE ProtocolHandle, + _Outptr_ MBB_BUS_HANDLE* BusHandle); +/* + Description + This routine initializes the bus layer i.e. the lower layer in the + MBB Class Driver. All bus layer implementations need to have this + function. The Protocol Layer i.e. the upper layer in the MBB Class + Driver will call this function before calling any other function in + the Bus Layer. + + Parameters + _In_ PDEVICE_OBJECT DeviceObject, + The WDM device representation of the device. + + _In_ MBB_BUS_NOTIFICATION_CALLBACK NotificationCallback, + The routine the bus layer calls when it needs to notify + the upper protocol layer. + + _In_ MBB_PROTOCOL_HANDLE ProtocolHandle, + The handle the bus layer passes back to the protocol layer + when it calls any callback. The protocol layer uses this handle + to identify the instance of the MBB device the callback is meant for. + + _Outptr_ MBB_BUS_HANDLE BusHandle + The handle returned by the bus layer on successful initialization. + The protocol layer passes this handle to the bus layer on subsequent + calls to the bus layer. The bus layer uses this handle to indetify + the instance of the MBB device. + + Return Value + NTSTATUS_SUCCESS + Initialization was successful. + + Other failure code +*/ + +EXTERN_C +NTSTATUS +MbbBusInitializeByWdf( + _In_ WDFDEVICE WdfDevice, + _In_ MBB_BUS_RESPONSE_AVAILABLE_CALLBACK ResponseAvailableCallback, + _In_ MBB_BUS_DATA_RECEIVE_CALLBACK ReceiveDataCallback, + _In_ MBB_BUS_SS_IDLE_CONFIRM_CALLBACK IdleConfirmCallback, + _In_ MBB_BUS_SS_IDLE_NOTIFICATION_COMPLETE_CALLBACK IdleNotificationComplete, + _In_ MBB_PROTOCOL_HANDLE ProtocolHandle, + _Outptr_ MBB_BUS_HANDLE* BusHandle, + _Inout_opt_ MBB_BUS_HANDLE preAllocatedBusObject); + +EXTERN_C +VOID MbbBusCleanup(__in MBB_BUS_HANDLE BusHandle); +/* + Description + This will be last call from Protocol layer in to Bus Layer + to cleanup the bus layer. The bus layer should free all + resources. The BusHandle will not be used for subsequent calls. + If there are pending requests the Bus Layer should not return + from this call unless all operations are complete. + + Parameters + __in MBB_BUS_HANDLE BusHandle + BusHandle identifies the instance of the bus layer. + + Return Value + None +*/ + +EXTERN_C +NTSTATUS +MbbBusQueryBusParameters(__in MBB_BUS_HANDLE BusHandle, __out PMBB_BUS_PARAMETERS BusParameters); +/* + Description + This routine queries the bus specific parameters like transfer size, + DMA support etc... This is called when the bus is initialized to format + requests correctly before sending to the bus. + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + __out PMBB_BUS_PARAMETERS BusParameters + The buffer where the bus layer returns the information to the caller. + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ +EXTERN_C +NTSTATUS +MbbBusSendMessageFragment( + __in MBB_BUS_HANDLE BusHandle, + __in MBB_REQUEST_HANDLE RequestHandle, + __in PVOID MessageFragment, + __in ULONG FragmentLength, + __in LPGUID ActivityId, + __in MBB_BUS_SEND_COMPLETION_CALLBACK SendCompletionCallback); +/* + Description + The protocol layer call this routine to request the bus layer to + send a message fragment. Fragmentation / Reassembly is handled by + the protocol layer and it will only handle fragments that are within + the maximum transfer size of the bus. + + This routine is asynchronous and returns immediately after queueing + the transfer. The caller is notified of the completion through the + callback. + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + __in MBB_REQUEST_HANDLE RequestHandle, + Identifies the request. + + __in PVOID MessageFragment, + The data payload that needs to be sent. + + __in ULONG FragmentLength, + Length of the data payload. This will not be greater than the + maximum transfer size supported by the bus. + + __in MBB_BUS_SEND_COMPLETION_CALLBACK SendCompletionCallback + The completion callback routine that will be called by the bus + when the transfer is complete. + + Return Value + + NTSTATUS_SUCCESS + The transfer has completed successfully. SendCompletionCallback will NOT be called. + + NTSTATUS_PENDING + The transfer was queued. SendCompletionCallback will be called on completion. + + Other failure code + The transfer could not be queued. SendCompletionCallback will NOT be called. +*/ + +EXTERN_C +NTSTATUS +MbbBusReceiveMessageFragment( + _In_ MBB_BUS_HANDLE BusHandle, + _In_ MBB_REQUEST_HANDLE RequestHandle, + _In_ __drv_aliasesMem PVOID MessageFragment, + _In_ ULONG FragmentLength, + _In_ LPGUID ActivityId, + _In_ MBB_BUS_RECEIVE_COMPLETION_CALLBACK ReceiveCompletionCallback); +/* + Description + + Parameters + + + Return Value + + NTSTATUS_SUCCESS + Initialization was successful. + + Other failure code +*/ +/* + Description + The protocol layer call this routine to request the bus layer to + receive data from the device. Reassembly is handled by the protocol layer. + + This routine is asynchronous and returns immediately after queueing + the transfer. The caller is notified of the completion through the + callback. + + Parameters + _In_ MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + _In_ MBB_REQUEST_HANDLE RequestHandle, + Identifies the request. + + _InOut_ PVOID MessageFragment, + The data buffer that would be filled with the received data. + + _In_ ULONG FragmentLength, + Length of the data requested from the device. This will not be + greater than the maximum transfer size supported by the bus. + + _In_ MBB_BUS_RECEIVE_COMPLETION_CALLBACK ReceiveCompletionCallback + The completion callback routine that will be called by the bus + when the transfer is complete. + + Return Value + + NTSTATUS_SUCCESS + The transfer has completed successfully. ReceiveCompletionCallback will NOT be called. + + NTSTATUS_PENDING + The transfer was queued. ReceiveCompletionCallback will be called on completion. + + Other failure code + The transfer could not be queued. ReceiveCompletionCallback will NOT be called. +*/ + +EXTERN_C +NTSTATUS +MbbBusSetPacketFilter(__in MBB_BUS_HANDLE BusHandle, __in ULONG PacketFilter); +/* + Description + Sets the packet filter on the device. + For MBB only directed is supported + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + __in ULONG PacketFilter + the filter to apply + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ + +EXTERN_C +NTSTATUS +MbbBusGetStat(__in MBB_BUS_HANDLE BusHandle, __in USHORT StatIndex, __out ULONGLONG* Value); +/* + Description + Retrieves a status from the device + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + __in ULONG PacketFilter + the filter to apply + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ + +EXTERN_C +NTSTATUS +MbbBusStart(_In_ MBB_BUS_HANDLE BusHandle); + +EXTERN_C +NTSTATUS +MbbBusStop(__in MBB_BUS_HANDLE BusHandle); + +EXTERN_C +BOOLEAN +MbbBusIsStoped(_In_ MBB_BUS_HANDLE BusHandle); + +EXTERN_C +NTSTATUS +MbbBusOpen(_In_ MBB_BUS_HANDLE BusHandle, _In_ ULONG TransactionId, _In_opt_ PVOID FastIOSendNetBufferListsComplete, _In_opt_ PVOID FastIOIndicateReceiveNetBufferLists); +/* + Description + + Opens the session with the device + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ + +EXTERN_C +NTSTATUS +MbbBusClose(__in MBB_BUS_HANDLE BusHandle, __in ULONG TransactionId, __in BOOLEAN ForceClose); +/* + Description + + Opens the session with the device + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ + +EXTERN_C +NTSTATUS +MbbBusStartDataPipes(__in MBB_BUS_HANDLE BusHandle); +/* + Description + + Selects alt data interface 1 and starts the IoTargets + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ + +EXTERN_C +VOID MbbBusStopDataPipes(__in MBB_BUS_HANDLE BusHandle); +/* + Description + + Resets the IoTargets canceling all and waiting for io to compelte + Selects alt data interface 0 disabling the pipes + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ + +EXTERN_C +void MbbBusResetDataPipes(_In_ MBB_BUS_HANDLE BusHandle); + +EXTERN_C +NTSTATUS +MbbBusWriteData(__in MBB_BUS_HANDLE BusHandle, __in MBB_REQUEST_HANDLE RequestHandle, __in PMDL Mdl, __in MBB_BUS_SEND_DATA_COMPLETION_CALLBACK Callback); +/* + Description + + Writes data to device bulk out pipe + + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. + + __in MBB_REQUEST_HANDLE RequestHandle, + Identifies the request. + + __in PMDL Mdl + pointer to an MDL identifying the data to send. The bus layer will own this until the completion callback is called. + + __in MBB_BUS_SEND_DATA_COMPLETION_CALLBACK Callback + Callback that will be called when write is complete. + + Return Value + + NTSTATUS_SUCCESS + Information was successfully returned in the BusParameters structure. + + NTSTATUS_INVALID_PARAMETER + One of the required parameters is missing or bad. + + Other failure code +*/ +EXTERN_C +VOID MbbBusReturnReceiveBuffer(__in MBB_BUS_HANDLE BusHandle, __in MBB_RECEIVE_CONTEXT ReceiveContext, __in PMDL Mdl); + +EXTERN_C +NTSTATUS +MbbBusSelectDataAltSetting(__in MBB_BUS_HANDLE BusHandle, __in UCHAR AltSetting); + +EXTERN_C +NTSTATUS +MbbBusIdleNotification(__in MBB_BUS_HANDLE BusHandle, __in BOOLEAN ForceIdle); + +EXTERN_C +VOID MbbBusCancelIdleNotification(__in MBB_BUS_HANDLE BusHandle); + +EXTERN_C +NTSTATUS +MbbBusSetPowerFilterPattern( + __in MBB_BUS_HANDLE BusHandle, + __in ULONG PatternId, + __in_bcount_opt(MaskSize) PCUCHAR Mask, + __in ULONG MaskSize, + __in_bcount_opt(PatternSize) PCUCHAR Pattern, + __in ULONG PatternSize); + +EXTERN_C +NTSTATUS +MbbBusResetBulkPipe(__in MBB_BUS_HANDLE BusHandle, __in BOOLEAN Out); + +EXTERN_C +VOID MbbBusSetNotificationState(__in MBB_BUS_HANDLE BusHandle, __in BOOLEAN Enabled); + +EXTERN_C +BOOLEAN +MbbBusIsUde(_In_ MBB_BUS_HANDLE BusHandle); + +#endif diff --git a/network/wwan/cxwmbclass/inc/MapWwanMbb.h b/network/wwan/cxwmbclass/inc/MapWwanMbb.h new file mode 100644 index 000000000..8d695f273 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/MapWwanMbb.h @@ -0,0 +1,217 @@ +#include +#include + +#pragma once +//////////////////////////////////////////////////////////////////////////////// +// +// Table mapping between WWAN type enum to its corresponding MBB type enum +// payload or other way around. When update the table, please double +// check wwan.h and MbbMessages.h +// +//////////////////////////////////////////////////////////////////////////////// + +#pragma region To_WWAN_ENUM +WWAN_STATUS MbbStatusMapTableBasic[MBB_STATUS_BASIC_COUNT()] = { + // MBB_STATUS_SUCCESS = 0, + WWAN_STATUS_SUCCESS, + // MBB_STATUS_BUSY = 1, + WWAN_STATUS_BUSY, + // MBB_STATUS_FAILURE = 2, + WWAN_STATUS_FAILURE, + // MBB_STATUS_SIM_NOT_INSERTED = 3, + WWAN_STATUS_SIM_NOT_INSERTED, + // MBB_STATUS_BAD_SIM = 4, + WWAN_STATUS_BAD_SIM, + // MBB_STATUS_PIN_REQUIRED = 5, + WWAN_STATUS_PIN_REQUIRED, + // MBB_STATUS_PIN_DISABLED = 6, + WWAN_STATUS_PIN_DISABLED, + // MBB_STATUS_NOT_REGISTERED = 7, + WWAN_STATUS_NOT_REGISTERED, + // MBB_STATUS_PROVIDERS_NOT_FOUND = 8, + WWAN_STATUS_PROVIDERS_NOT_FOUND, + // MBB_STATUS_NO_DEVICE_SUPPORT = 9, + WWAN_STATUS_NO_DEVICE_SUPPORT, + // MBB_STATUS_PROVIDER_NOT_VISIBLE = 10, + WWAN_STATUS_PROVIDER_NOT_VISIBLE, + // MBB_STATUS_DATA_CLASS_NOT_AVAILABLE = 11, + WWAN_STATUS_DATA_CLASS_NOT_AVAILABLE, + // MBB_STATUS_PACKET_SVC_DETACHED = 12, + WWAN_STATUS_PACKET_SVC_DETACHED, + // MBB_STATUS_MAX_ACTIVATED_CONTEXTS = 13, + WWAN_STATUS_MAX_ACTIVATED_CONTEXTS, + // MBB_STATUS_NOT_INITIALIZED = 14, + WWAN_STATUS_NOT_INITIALIZED, + // MBB_STATUS_VOICE_CALL_IN_PROGRESS = 15, + WWAN_STATUS_VOICE_CALL_IN_PROGRESS, + // MBB_STATUS_CONTEXT_NOT_ACTIVATED = 16, + WWAN_STATUS_CONTEXT_NOT_ACTIVATED, + // MBB_STATUS_SERVICE_NOT_ACTIVATED = 17, + WWAN_STATUS_SERVICE_NOT_ACTIVATED, + // MBB_STATUS_INVALID_ACCESS_STRING = 18, + WWAN_STATUS_INVALID_ACCESS_STRING, + // MBB_STATUS_INVALID_USER_NAME_PWD = 19, + WWAN_STATUS_INVALID_USER_NAME_PWD, + // MBB_STATUS_RADIO_POWER_OFF = 20, + WWAN_STATUS_RADIO_POWER_OFF, + // MBB_STATUS_INVALID_PARAMETERS = 21, + WWAN_STATUS_INVALID_PARAMETERS, + // MBB_STATUS_READ_FAILURE = 22, + WWAN_STATUS_READ_FAILURE, + // MBB_STATUS_WRITE_FAILURE = 23, + WWAN_STATUS_WRITE_FAILURE, + // MBB_STATUS_DENIED_POLICY = 24, + WWAN_STATUS_DENIED_POLICY, + // MBIM_STATUS_NO_PHONEBOOK 25, + WWAN_STATUS_FAILURE, + // MBIM_STATUS_PARAMETER_TOO_LONG 26, + WWAN_STATUS_FAILURE, + // MBIM_STATUS_STK_BUSY 27, + WWAN_STATUS_FAILURE, + // MBIM_STATUS_OPERATION_NOT_ALLOWED 28, + WWAN_STATUS_NO_DEVICE_SUPPORT, + // MBIM_STATUS _MEMORY_FAILURE 29, + WWAN_STATUS_SMS_MEMORY_FAILURE, + // MBIM_STATUS_INVALID_MEMORY_INDEX 30, + WWAN_STATUS_SMS_INVALID_MEMORY_INDEX, + // MBIM_STATUS_MEMORY_FULL 31, + WWAN_STATUS_SMS_MEMORY_FULL, + // MBIM_STATUS _FILTER_NOT_SUPPORTED 32, + WWAN_STATUS_SMS_FILTER_NOT_SUPPORTED, + // MBIM_STATUS_DSS_INSTANCE_LIMIT 33, + WWAN_STATUS_FAILURE, + // MBIM_STATUS_INVALID_DEVICE_SERVICE_OPERATION 34, + WWAN_STATUS_FAILURE, + // MBIM_STATUS_AUTH_INCORRECT_AUTN 35, + WWAN_STATUS_AUTH_INCORRECT_AUTN, + // MBIM_STATUS_AUTH_SYNC_FAILURE 36, + WWAN_STATUS_AUTH_SYNC_FAILURE, + // MBIM_STATUS_AUTH_AMF_NOT_SET 37, + WWAN_STATUS_AUTH_AMF_NOT_SET, + // MBIM_STATUS_CONTEXT_NOT_SUPPORTED 38, + WWAN_STATUS_MORE_DATA, + // MBB_STATUS_SHAREABILITY_CONDITION_ERROR 39, + WWAN_STATUS_SHAREABILITY_CONDITION_ERROR, + // MBB_STATUS_PIN_FAILURE 40, + WWAN_STATUS_PIN_FAILURE, + // MBB_STATUS_NO_LTE_ATTACH_CONFIG 41, + WWAN_STATUS_NO_LTE_ATTACH_CONFIG + +}; + +WWAN_STATUS MbbStatusMapTableSms[MBB_STATUS_SMS_COUNT()] = { + + // MBB_STATUS_SMS_UNKNOWN_SMSC_ADDRESS = 100, + WWAN_STATUS_SMS_UNKNOWN_SMSC_ADDRESS, + // MBB_STATUS_SMS_NETWORK_TIMEOUT = 101, + WWAN_STATUS_SMS_NETWORK_TIMEOUT, + // MBB_STATUS_SMS_LANG_NOT_SUPPORTED = 102, + WWAN_STATUS_SMS_LANG_NOT_SUPPORTED, + // MBB_STATUS_SMS_ENCODING_NOT_SUPPORTED = 103, + WWAN_STATUS_SMS_ENCODING_NOT_SUPPORTED, + // MBB_STATUS_SMS_FORMAT_NOT_SUPPORTED = 104, + WWAN_STATUS_SMS_FORMAT_NOT_SUPPORTED, + // MBB_STATUS_SMS_MORE_DATA = 105, + WWAN_STATUS_SMS_MORE_DATA + +}; + +WWAN_STATUS MbbStatusMapTableUicc[MBB_STATUS_UICC_COUNT()] = { + + // MBB_STATUS_UICC_NO_LOGICAL_CHANNELS = 0x87430001, + WWAN_STATUS_UICC_NO_LOGICAL_CHANNELS, + // MBB_STATUS_UICC_SELECT_FAILED = 0x87430002, + WWAN_STATUS_UICC_SELECT_FAILED, + // MBB_STATUS_UICC_INVALID_LOGICAL_CHANNEL = 0x87430003, + WWAN_STATUS_UICC_INVALID_LOGICAL_CHANNEL + +}; + +WWAN_STATUS MbbStatusMapTable4_0[MBB_STATUS_4_0_COUNT()] = { + // MBB_STATUS_MATCHING_PDU_SESSION_FOUND = 200, + WWAN_STATUS_SESSION_ALREADY_EXISTS, + // MBB_STATUS_DISSOCIATION_NEEDED_FOR_APPLICATION = 201, + WWAN_STATUS_DISSOCIATION_NEEDED_FOR_APPLICATION, + // MBB_STATUS_ERROR_INVALID_SLOT = 202, + WWAN_STATUS_ERROR_INVALID_SLOT, + // MBB_STATUS_NO_MATCHING_URSP_RULE = 203, + WWAN_STATUS_NO_MATCHING_URSP_RULE, + // MBB_STATUS_NO_DEFAULT_URSP_RULE = 204, + WWAN_STATUS_NO_DEFAULT_URSP_RULE +}; + +// defining the maping table for IpTypes +// this implementation assume that the MBB_CONTEXT_IP_TYPE +// does not have gaps and will end with MbbContextIPTypeMaximum +WWAN_IP_TYPE MbbIpTypesMapTable[MbbContextIPTypeMaximum] = { + // MbbContextIPTypeDefault = 0, + WwanIPTypeDefault, + // MbbContextIPTypeIPv4 = 1, + WwanIPTypeIPv4, + // MbbContextIPTypeIPv6 = 2, + WwanIPTypeIPv6, + // MbbContextIPTypeIPv4v6 = 3, + WwanIPTypeIpv4v6, + // MbbContextIPTypeIPv4AndIPv6 = 4, + // IPv4AndIPv6 is reported as IPv4v6 + // SHOULD NOT be mapped to WwanIPTypeXlat!!!! + WwanIPTypeIpv4v6}; + +WWAN_CONFIGURATION_SOURCE MbbSourcesMapTable[MbbMsContextSourceMaximum] = { + // MbbMsContextSourceAdmin = 0, + WwanAdminProvisioned, + // MbbMsContextSourceUser = 1, + WwanUserProvisioned, + // MbbMsContextSourceOperator = 2, + WwanOperatorProvisioned, + // MbbMsContextSourceModem = 3, + WwanModemProvisioned, + // MbbMsContextSourceDevice = 4, + WwanDeviceProvisioned, +}; + +WWAN_CONTEXT_OPERATIONS MbbLteAttachOperationsMapTable[MbbMsLteAttachContextOperationMaximum] = { + // MbbMsLteAttachContextOperationDefault = 0, + WwanContextOperationDefault, + // MbbMsLteAttachContextOperationRestoreFactory = 1, + WwanContextOperationRestoreFactory, + // MbbMsLteAttachContextOperationMaximum = 2, +}; +#pragma endregion To_WWAN_ENUM + +#pragma region To_MBB_ENUM +MBB_CONTEXT_IP_TYPE WwanIpTypesMapTable[] = { + // WwanIPTypeDefault = 0, + MbbContextIPTypeDefault, + // WwanIPTypeIPv4, + MbbContextIPTypeIPv4, + // WwanIPTypeIPv6, + MbbContextIPTypeIPv6, + // WwanIPTypeIpv4v6, + MbbContextIPTypeIPv4v6, +}; + +MBB_BASICCONNECTEXT_CONTEXT_SOURCE WwanSourcsMapTable[WwanMaxProvisionSource] = { + // WwanUserProvisioned = 0, // the source is user(s) + MbbMsContextSourceUser, + // WwanAdminProvisioned, // the source is administrator + MbbMsContextSourceAdmin, + // WwanOperatorProvisioned, // the source is mobile operator + MbbMsContextSourceOperator, + // WwanDeviceProvisioned, // the source is device (such as MultiVariant), but not from modem + MbbMsContextSourceDevice, + // WwanModemProvisioned, // the source is modem (such as pre-configured in modem) + MbbMsContextSourceModem, +}; + +MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS +WwanLteAttachOperationsMapTable[WwanContextOperationMaximum] = { + // WwanContextOperationDefault = 0, + MbbMsLteAttachContextOperationDefault, + // WwanContextOperationDelete = 1, + MbbMsLteAttachContextOperationMaximum, // no deletion operation for LTE Attach + // WwanContextOperationRestoreFactory = 2, + MbbMsLteAttachContextOperationRestoreFactory, + // WwanContextOperationMaximum = 3 +}; +#pragma endregion To_MBB_ENUM \ No newline at end of file diff --git a/network/wwan/cxwmbclass/inc/MbbLibrary.h b/network/wwan/cxwmbclass/inc/MbbLibrary.h new file mode 100644 index 000000000..03f64d8ae --- /dev/null +++ b/network/wwan/cxwmbclass/inc/MbbLibrary.h @@ -0,0 +1,175 @@ +/*************************************************************************** + +Copyright (c) 2010 Microsoft Corporation + +Module Name: + + MbbLibrary.h + +Abstract: + + This header files contains the interfaces to the pack / unpack and + fragment / reassembly functions provided by the Mbb library. + The class driver Protocol layer calls the libary to convert payloads + to messages as defined in the MBB Class Driver Hardware Interface + document before sending it to the Bus Layer. + +Environment: + + User and kernel mode only + +Notes: + + This library can be used both in user and kernel mode because it does not + to make any memory allocations. + +Revision History: + + 2/7/2010 : created + +Authors: + + TriRoy + +****************************************************************************/ +EXTERN_C +NTSTATUS +MbbLibForamtBufferAsOpenMessage(__out_bcount_opt(*BufferLength) PVOID MessageBuffer, __inout PULONG BufferLength, __in ULONG MaximumControlTransfer); +/* + Description + Formats an input buffer as a MBB Open Message. + + Parameters + __out_opt_bcount(*BufferLength) PVOID MessageBuffer + The input message buffer. This parameter may be NULL + if BufferLength is 0. This parameter should not be NULL + when BufferLength is non-zero. + + __inout PULONG BufferLength + This provides the length of the memory location described by MessageBuffer. + If BufferLength is 0 then the function will return the required buffer length + in this parameter with STATUS_BUFFER_OVERFLOW. On success, the amount of + buffer space used by the routine is returned to the caller in BufferLength. + + __in ULONG MaximumControlTransfer + MaximumControlTransfer field of the Open Message. + + Return Value + STATUS_BUFFER_OVERFLOW + The buffer passed in is not sufficient for formatting the message. + + STATUS_INVALID_PARAMETER + One of the required parameters is missing. + + STATUS_SUCCESS + The input buffer was formatted successfully and the amount of buffer + used is returned in BufferLength. +*/ +EXTERN_C +NTSTATUS +MbbLibForamtBufferAsCloseMessage(__out_bcount_opt(*BufferLength) PVOID MessageBuffer, __inout PULONG BufferLength); +/* + Description + Formats an input buffer as a MBB Close Message. + + Parameters + __out_opt_bcount(*BufferLength) PVOID MessageBuffer + The input message buffer. This parameter may be NULL + if BufferLength is 0. This parameter should not be NULL + when BufferLength is non-zero. + + __inout PULONG BufferLength + This provides the length of the memory location described by MessageBuffer. + If BufferLength is 0 then the function will return the required buffer length + in this parameter with STATUS_BUFFER_OVERFLOW. On success, the amount of + buffer space used by the routine is returned to the caller in BufferLength. + + Return Value + STATUS_BUFFER_OVERFLOW + The buffer passed in is not sufficient for formatting the message. + + STATUS_INVALID_PARAMETER + One of the required parameters is missing. + + STATUS_SUCCESS + The input buffer was formatted successfully and the amount of buffer + used is returned in BufferLength. +*/ +EXTERN_C +NTSTATUS +MbbLibFragmentBufferToCommandMessages( + __in PMBB_COMMAND Command, + __in MBB_COMMAND_TYPE CommandType, + __in_bcount_opt(PayloadLength) PCHAR Payload, + __in ULONG PayloadLength, + __inout_opt PULONG TransactionId, + __in ULONG CurrentFragment, + __inout PULONG FragmentBufferCount, + __inout PULONG FragmentLength, + __out_ecount_opt(*FragmentBufferCount) PCHAR* FragmentBuffers); +/* + Description + Given the Payload the routine fragments the payload + in to the FragmentBuffers. + + Parameters + __in MBB_COMMAND Command + Command contains the GUID and Cid. + The GUID identifying the service for this message. + The command identifier for the given service. + + __in MBB_COMMAND_TYPE CommandType + Identifies whether the command is a Set or Query. + + __in_bcount(PayloadLength) PCHAR Payload + The Payload is a byte array that needs to be fragmented. + If Payload length is not 0 Payload should be provided. + + __in ULONG PayloadLength + Length of the payload. If there is no Payload for this command + Payload is set to 0. + + __inout PULONG TransactionId + If non-zero then this is the transaction id used for the fragments. + If zero then a new transcation id is generated and returned to the caller. + + __in ULONG CurrentFragment + If non-zero then Fragments are constructed starting this Fragment. + If zero then Fragments are constructed from the beginning. + + __inout ULONG FragmentBufferCount + Number of input fragments i.e. numberof buffers described by + FragmentBuffers array. If the caller is querying for the + number of fragments required then this should be set to 0. + The function will return the number of fragment required + with STATUS_BUFFER_OVERFLOW. + + __in ULONG FragmentLength + Length of each output fragment buffers. All fragment + buffers needs to be of the same size. + The length of the last fragment is returned on STATUS_SUCCESS. + All but the last fragment are of FragmentLength size. + The last fragment can be lesser than the FragmentLength size. + + __out_ecount_opt(*FragmentBufferCount) PCHAR* FragmentBuffers + Array of input fragment buffers. If FragmentCount is 0 + FragmentBuffers can be NULL. If FragmentCount is non 0 + FragmentBuffers should be provided. + + Return Value + STATUS_INVALID_PARAMETER + One of the required parameters is missing. + + STATUS_SUCCESS + The Payload was fragmented successfully in to + FragmentBuffers and the number of fragments used is + returned in FragmentCount. + + STATUS_MORE_PROCESSING_REQUIRED + The complete Payload is not fragmented yet. + This is not a failure code but an indication to the caller that + more calls are needed with more fragment buffers. +*/ + +ULONG +MbbLibraryGetNextTransactionId(); diff --git a/network/wwan/cxwmbclass/inc/WwanDrvCmn.h b/network/wwan/cxwmbclass/inc/WwanDrvCmn.h new file mode 100644 index 000000000..6c9a76f46 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/WwanDrvCmn.h @@ -0,0 +1,33 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + WwanDrvCmn.h + +Abstract: + Contains common functions declarations used by WWAN + class driver and WWAN virtual miniport. + +Revision History: + When What + ---------- ---------------------------------------------- + 12-18-2012 Created + +Notes: + +--*/ +#pragma once + +EXTERN_C +VOID WwanAdjustDhcpSettings(__in NET_LUID AdapterNetLuid, __in GUID AdapterNetCfgId, __in BOOLEAN EnableDhcp); + +EXTERN_C +NDIS_STATUS +WwanUpdateIPStack( + __in NDIS_HANDLE MiniportAdapterHandle, + __in PWWAN_IP_ADDRESS_STATE IpAddressState, + __in NET_LUID AdapterNetLuid, + __in GUID AdapterNetCfgId, + __in ULONG AdapterIfIndex, + __in BOOLEAN IsDeviceReportedChange); diff --git a/network/wwan/cxwmbclass/inc/adapter.h b/network/wwan/cxwmbclass/inc/adapter.h new file mode 100644 index 000000000..09f83bc2a --- /dev/null +++ b/network/wwan/cxwmbclass/inc/adapter.h @@ -0,0 +1,49 @@ +#pragma once + +// packet and header sizes +#define MBB_MAX_PACKET_SIZE (1514) + +// maximum link speed for send and recv in bps +#define MBB_MEDIA_MAX_SPEED 1'000'000'000 + +// supported filters +#define WMBCLASS_MAX_WOL_PATTERN (256) +#define WMBCLASS_MAX_MBIM_WOL_PATTERN (192) + +// +// Context for each NetAdapter instance. +// Each NetAdapter instance corresponds to an IP interface +// +typedef struct _WMBCLASS_NETADAPTER_CONTEXT +{ + PWMBCLASS_DEVICE_CONTEXT WmbDeviceContext; // Wdf device context + NETADAPTER NetAdapter; // NetAdapter object + + ULONG ConnectionId; + ULONG SessionId; + MBB_CONNECTION_STATE ConnectionState; + + // RxQuere-related objects + + WDFLOOKASIDE NtbLookasideList; + WDFLOOKASIDE ReceiveNdpLookasideList; + + LIST_ENTRY ReceiveNdpList; + NETPACKETQUEUE TxQueue; // Tx Queue object + NETPACKETQUEUE RxQueue; // Rx Queue object + BOOLEAN AllowRxTraffic; +} WMBCLASS_NETADAPTER_CONTEXT, *PWMBCLASS_NETADAPTER_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WMBCLASS_NETADAPTER_CONTEXT, WmbClassGetNetAdapterContext); + +// +// NetAdapter functions +// + +EVT_NET_ADAPTER_CREATE_TXQUEUE EvtAdapterCreateTxQueue; +EVT_NET_ADAPTER_CREATE_RXQUEUE EvtAdapterCreateRxQueue; + +EVT_WDF_DEVICE_CONTEXT_DESTROY MbbDestroyAdapterContext; + +NTSTATUS +WmbClassAdapterStart(_In_ NETADAPTER netAdapter); diff --git a/network/wwan/cxwmbclass/inc/align.h b/network/wwan/cxwmbclass/inc/align.h new file mode 100644 index 000000000..5c8117d39 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/align.h @@ -0,0 +1,168 @@ +/*++ + +Copyright (c) 1988-1992 Microsoft Corporation + +Module Name: + + Align.h + +Abstract: + + +Author: + + John Rogers (JohnRo) 15-May-1991 + +Environment: + + This code assumes that sizeof(DWORD) >= sizeof(PVOID). + +Revision History: + + 15-May-1991 JohnRo + Created align.h for NT/LAN from OS/2 1.2 HPFS pbmacros.h. + 19-Jun-1991 JohnRo + Make sure pointer-to-wider-then-byte doesn't get messed up. + 10-Jul-1991 JohnRo + Added ALIGN_BYTE and ALIGN_CHAR for completeness. + 21-Aug-1991 CliffV + Fix ROUND_DOWN_* to include ~ + 03-Dec-1991 JohnRo + Worst-case on MIPS is 8-byte alignment. + Added COUNT_IS_ALIGNED() and POINTER_IS_ALIGNED() macros. + 26-Jun-1992 JohnRo + RAID 9933: ALIGN_WORST should be 8 for x86 builds. + +--*/ + +#ifndef _ALIGN_ +#define _ALIGN_ + + +// BOOL +// COUNT_IS_ALIGNED( +// IN DWORD Count, +// IN DWORD Pow2 // undefined if this isn't a power of 2. +// ); +// +#define COUNT_IS_ALIGNED(Count,Pow2) \ + ( ( ( (Count) & (((Pow2)-1)) ) == 0) ? TRUE : FALSE ) + +// BOOL +// POINTER_IS_ALIGNED( +// IN PVOID Ptr, +// IN DWORD Pow2 // undefined if this isn't a power of 2. +// ); +// +#define POINTER_IS_ALIGNED(Ptr,Pow2) \ + ( ( ( ((ULONG_PTR)(Ptr)) & (((Pow2)-1)) ) == 0) ? TRUE : FALSE ) + + +// Note ............. +// There is a subtle issue with all these alignment methods +// The way the alignment is done depends on the lValue assignment of these MACRO +// For example: +// UINT64 fileSizeAlligned = ROUND_UP_COUNT(fileSize, pageSize) +// will do a correct 64 bit aligned rounding up +// UINT32 pagesInFileCount = ROUND_UP_COUNT(fileSize, pageSize) / pageSize; +// this will truncate the pageSize to UINT32 when evaluating ~(Pow2-1) below +// causing the result to truncate the most significant 32 bits in fileSize + + +#define ROUND_DOWN_COUNT(Count,Pow2) \ + ( (Count) & (~(((LONG)(Pow2))-1)) ) + +#define ROUND_DOWN_POINTER(Ptr,Pow2) \ + ( (PVOID) ROUND_DOWN_COUNT( ((ULONG_PTR)(Ptr)), (Pow2) ) ) + + +// If Count is not already aligned, then +// round Count up to an even multiple of "Pow2". "Pow2" must be a power of 2. +// +// DWORD +// ROUND_UP_COUNT( +// IN DWORD Count, +// IN DWORD Pow2 +// ); +#define ROUND_UP_COUNT(Count,Pow2) \ + ( ((Count)+(Pow2)-1) & (~(((LONG)(Pow2))-1)) ) + +// PVOID +// ROUND_UP_POINTER( +// IN PVOID Ptr, +// IN DWORD Pow2 +// ); + +// If Ptr is not already aligned, then round it up until it is. +#define ROUND_UP_POINTER(Ptr,Pow2) \ + ( (PVOID) ( (((ULONG_PTR)(Ptr))+(Pow2)-1) & (~(((LONG)(Pow2))-1)) ) ) + + +// Usage: myPtr = ROUND_UP_POINTER( unalignedPtr, ALIGN_LPVOID ) + +#define ALIGN_BYTE sizeof(UCHAR) +#define ALIGN_CHAR sizeof(CHAR) +#define ALIGN_DESC_CHAR sizeof(DESC_CHAR) +#define ALIGN_DWORD sizeof(DWORD) +#define ALIGN_LONG sizeof(LONG) +#define ALIGN_LPBYTE sizeof(LPBYTE) +#define ALIGN_LPDWORD sizeof(LPDWORD) +#define ALIGN_LPSTR sizeof(LPSTR) +#define ALIGN_LPTSTR sizeof(LPTSTR) +#define ALIGN_LPVOID sizeof(PVOID) +#define ALIGN_LPWORD sizeof(LPWORD) +#define ALIGN_TCHAR sizeof(TCHAR) +#define ALIGN_WCHAR sizeof(WCHAR) +#define ALIGN_WORD sizeof(WORD) + +// +// For now, use a hardcoded constant. however, this should be visited again +// and maybe changed to sizeof(QUAD). +// + +#define ALIGN_QUAD 8 + +#if defined(_X86_) + +#define ALIGN_WORST 8 + +#elif defined(_AMD64_) + +#define ALIGN_WORST 8 + +#elif defined(_ARM_) + +#define ALIGN_WORST 8 + +#elif defined(_ARM64_) + +#define ALIGN_WORST 8 + +#elif defined(_ALPHA_) + +// +// Worst-case alignment on ALPHA is 8 bytes (for double). Specify this here, +// in case our allocator is used for structures containing this. (That is, +// even though NT/LAN doesn't need this for our data structures, let's be +// permissive.) The alignment requirements apply to Alpha. +// + +#define ALIGN_WORST 8 + +#elif defined(_IA64_) + +// +// IA64 note for QUAD: The NT QUAD type definition is NOT the EM 16byte quad type. +// Because of some NT constraints, QUAD type size cannot be changed. +// + +#define ALIGN_WORST 16 + +#else // none of the above + +#error "Unknown alignment requirements for align.h" + +#endif // none of the above + +#endif // _ALIGN_ + diff --git a/network/wwan/cxwmbclass/inc/data.h b/network/wwan/cxwmbclass/inc/data.h new file mode 100644 index 000000000..4ac1a8abc --- /dev/null +++ b/network/wwan/cxwmbclass/inc/data.h @@ -0,0 +1,185 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +//////////////////////////////////////////////////////////////////////////////// +#pragma once + +#define MBB_DEFAULT_SESSION_ID 0 + +typedef struct _DSS_PACKET +{ + WDFMEMORY Data; + PMDL Mdl; +} DSS_PACKET, *PDSS_PACKET; + +typedef struct _MBB_PORT MBB_PORT, *PMBB_PORT; + +typedef struct _MINIPORT_DRIVER_CONTEXT +{ + WDFDRIVER hDriver; +} MINIPORT_DRIVER_CONTEXT, *PMINIPORT_DRIVER_CONTEXT; + +typedef struct _MBB_RECEIVE_QUEUE +{ + // + // Queue State + // + BOOLEAN LookasideList; + NDIS_SPIN_LOCK Lock; + KEVENT QueueEmptyEvent; + // + // Track Receives + // + LIST_ENTRY ReceivedQueue; + // + // Resources + // + NDIS_HANDLE NblPool; + NPAGED_LOOKASIDE_LIST ReceiveLookasideList; + +} MBB_RECEIVE_QUEUE, *PMBB_RECEIVE_QUEUE; + +typedef struct _MBB_NDIS_RECEIVE_CONTEXT +{ + // + // Resources + // + + PMDL Mdl; + PUCHAR ReceiveNtbBuffer; + WDFLOOKASIDE ReceiveLookasideList; + PMBB_RECEIVE_QUEUE RecvQueue; + MBB_BUS_HANDLE BusHandle; + MBB_RECEIVE_CONTEXT BusContext; + PWMBCLASS_DEVICE_CONTEXT WmbDeviceContext; + // + // Parse state + // + ULONG NtbSequence; + WDFMEMORY ReceiveLookasideBufferMemory; + + LONG TotalNdpCount; + LONG CompletedNdpCount; +} MBB_NDIS_RECEIVE_CONTEXT, *PMBB_NDIS_RECEIVE_CONTEXT; + +typedef struct _MBB_RECEIVE_NDP_CONTEXT +{ + LIST_ENTRY ReceiveNdpNode; + PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext; + WDFMEMORY ReceiveNdpLookasideBufferMemory; + PVOID Nth; + PVOID Ndp; + ULONG CurrentDatagramIndex; + ULONG IndicatedPackets; + PWMBCLASS_NETADAPTER_CONTEXT NetAdapterContext; +} MBB_RECEIVE_NDP_CONTEXT, *PMBB_RECEIVE_NDP_CONTEXT; + +extern MINIPORT_DRIVER_CONTEXT GlobalControl; + +typedef enum +{ + MbbNdpTypeNoCrc = 0, + MbbNdpTypeCrc, + MbbNdpTypeIps, + MbbNdpTypeVendor_1, // Vendor with session id X (need not be 1) + MbbNdpTypeVendor_2, // Vendor with session id Y (need not be X + 1) + MbbNdpTypeVendor_3, + MbbNdpTypeVendor_Max, // Max 4 vendor sessions in one NTB + MbbNdpTypeMax + +} MBB_NDP_TYPE; + +typedef struct _MBB_PACKET_CONTEXT +{ + PMDL DataStartMdl; + PMDL DataEndMdl; + PMDL PaddingMdl; + PMDL ModifiedMdl; + MDL OriginalMdl; + +} MBB_PACKET_CONTEXT, *PMBB_PACKET_CONTEXT; + +typedef struct _MBB_NDP_HEADER_ENTRY +{ + MBB_NDP_TYPE NdpType; + ULONG SessionId; + ULONG DatagramOffset; + ULONG DatagramLength; + ULONG NextEntryIndex; + PNET_BUFFER NetBuffer; + PNET_BUFFER_LIST NetBufferList; + + union + { + NET_PACKET* NetPacket; + PDSS_PACKET DssPacket; + }; + MBB_PACKET_CONTEXT NetPacketContext; +} MBB_NDP_HEADER_ENTRY, *PMBB_NDP_HEADER_ENTRY; + +typedef struct _MBB_NTB_BUILD_CONTEXT +{ + LIST_ENTRY NtbQLink; + // + // Read-only values + // + BOOLEAN IsNtb32Bit; + ULONG NtbHeaderSize; + ULONG NdpHeaderFixedSize; + ULONG NdpDatagramEntrySize; + ULONG NtbOutMaxSize; + USHORT NtbOutMaxDatagrams; + USHORT NdpOutDivisor; + USHORT NdpOutPayloadRemainder; + USHORT NdpOutAlignment; + PVOID PaddingBuffer; + WDFLOOKASIDE NtbLookasideList; + // + // Network Transfer Header(NTH) + // + union + { + NCM_NTH16 Nth16; + NCM_NTH32 Nth32; + }; + PMDL NthMdl; + // + // NDP Header + // + PMDL NdpMdl; + ULONG NdpSize; + PVOID NdpBuffer; + // + // NDP Datagrams + // + ULONG DatagramCount; + ULONG DatagramLength; + PMDL DatagramLastMdl; + + WDFMEMORY NtbLookasideBufferMemory; + WDFMEMORY NdpBufferMemory; + NETPACKETQUEUE NetTxQueue; + NETADAPTER NetAdapter; + NET_RING_COLLECTION const* NetDatapathDescriptor; + +#if DBG + // + // Testing + // + PCHAR ScratchBuffer; + ULONG ScratchLength; +#endif + + // + // NDP Headers. Varialble length array is limited + // to NdpMaxDatagrams. NdpFirstDatagramEntry of -1 + // is invalid. + // + ULONG NdpFirstDatagramEntry[MbbNdpTypeMax]; + MBB_NDP_HEADER_ENTRY NdpDatagramEntries[ANYSIZE_ARRAY]; + +} MBB_NTB_BUILD_CONTEXT, *PMBB_NTB_BUILD_CONTEXT; diff --git a/network/wwan/cxwmbclass/inc/device.h b/network/wwan/cxwmbclass/inc/device.h new file mode 100644 index 000000000..519b4d719 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/device.h @@ -0,0 +1,51 @@ +#pragma once + +// "Device" in nawmbclass.sys represents an MBB device (or a modem). It may be embbeded or USB-plugged. +// A device may contain multiple NetAdapter instances for the support of MPDP. +// Each NetAdapter instance in a device corresponds to one PDP context in the modem. +// Each NetAdapter instance in a device presents an IP interface to TCP/IP. +// +// "Device" in nawmbclass.sys is the equivalent of "Adapter" in wmbclass.sys. +// Its context is similar to MINIPORT_ADAPTER_CONTEXT in wmbclass.sys. +// +// See wmbclass.h for the definition of MBB_DEVICE_CONTEXT + +typedef struct _WMBCLASS_DEVICE_CONTEXT +{ + void* WdfTriageInfoPtr; + + WDFDEVICE WdfDevice; + bool m_armedWake; + ULONG TraceInstance; + + MBB_BUS_HANDLE BusHandle; + MBB_BUS_PARAMETERS BusParams; + + ULONGLONG DSSPacketsReceivedCount; + ULONGLONG DSSPacketsSentCount; + + LONG NtbSequenceNumber; + + WDFLOOKASIDE ReceiveLookasideList; + PUCHAR sharedPaddingBuffer; + + struct + { + WDFSPINLOCK WdfRecvSpinLock; + struct _WMBCLASS_NETADAPTER_CONTEXT* NetAdapterContext; // the context of the netAdapter instance if this session is in use + } Sessions[MBB_MAX_NUMBER_OF_SESSIONS]; + +} WMBCLASS_DEVICE_CONTEXT, *PWMBCLASS_DEVICE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WMBCLASS_DEVICE_CONTEXT, WmbClassGetDeviceContext); + +EVT_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware; +EVT_WDF_DEVICE_RELEASE_HARDWARE EvtDeviceReleaseHardware; +EVT_WDF_DEVICE_SURPRISE_REMOVAL EvtDeviceSurpriseRemoval; + +EVT_MBB_DEVICE_SEND_MBIM_FRAGMENT EvtMbbDeviceSendMbimFragment; +EVT_MBB_DEVICE_RECEIVE_MBIM_FRAGMENT EvtMbbDeviceReceiveMbimFragment; +EVT_MBB_DEVICE_CREATE_ADAPTER EvtMbbDeviceCreateAdapter; +//EVT_NET_DEVICE_RESET EvtMbbDeviceReset; + +EVT_WDF_OBJECT_CONTEXT_CLEANUP EvtAdapterCleanup; diff --git a/network/wwan/cxwmbclass/inc/mbbfastio.h b/network/wwan/cxwmbclass/inc/mbbfastio.h new file mode 100644 index 000000000..6b2114a2a --- /dev/null +++ b/network/wwan/cxwmbclass/inc/mbbfastio.h @@ -0,0 +1,102 @@ +//This header file depends on and defines NDIS_SUPPORT_NDIS670 or higher + +#pragma once +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2 || NDIS_SUPPORT_NDIS670) + +typedef +_IRQL_requires_max_(DISPATCH_LEVEL) +_Function_class_(FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE) +VOID +FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE( + _In_ PVOID MiniportAdapterContext, + _In_ PNET_BUFFER_LIST NetBufferList, + _In_ ULONG SendCompleteFlags + ); +typedef FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE (*FastIOSendNetBufferListsCompleteHandler); +typedef +_IRQL_requires_max_(DISPATCH_LEVEL) +_Function_class_(FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS) +VOID +FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS( + _In_ PVOID MiniportAdapterContext, + _In_ PNET_BUFFER_LIST NetBufferList, + _In_ ULONG SessionId, + _In_ ULONG NumberOfNetBufferLists, + _In_ ULONG ReceiveFlags + ); +typedef FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS (*FastIOIndicateReceiveNetBufferListsHandler); +typedef +_IRQL_requires_max_(DISPATCH_LEVEL) +_Function_class_(FASTIO_SEND_NET_BUFFER_LISTS) +VOID +FASTIO_SEND_NET_BUFFER_LISTS( + _In_ PVOID ModemContext, + _In_ PNET_BUFFER_LIST NetBufferList, + _In_ ULONG SessionId, + _In_ ULONG SendFlags + ); +typedef FASTIO_SEND_NET_BUFFER_LISTS (*FastIOSendNetBufferListsHandler); +typedef +_IRQL_requires_max_(DISPATCH_LEVEL) +_Function_class_(FASTIO_RETURN_NET_BUFFER_LISTS) +VOID +FASTIO_RETURN_NET_BUFFER_LISTS( + _In_ PVOID ModemContext, + _In_ PNET_BUFFER_LIST NetBufferList, + _In_ ULONG ReturnFlags + ); +typedef FASTIO_RETURN_NET_BUFFER_LISTS (*FastIOReturnNetBufferListsHandler); +typedef +_IRQL_requires_max_(DISPATCH_LEVEL) +_Function_class_(FASTIO_CANCEL_SEND) +VOID +FASTIO_CANCEL_SEND( + _In_ PVOID ModemContext, + _In_ PVOID CancelId + ); +typedef FASTIO_CANCEL_SEND (*FastIOCancelSendHandler); +typedef +_IRQL_requires_(PASSIVE_LEVEL) +_Function_class_(FASTIO_HALT) +VOID +FASTIO_HALT( + _In_ PVOID ModemContext, + _In_ NDIS_HALT_ACTION HaltAction + ); +typedef FASTIO_HALT (*FastIOHaltHandler); +typedef +_IRQL_requires_(PASSIVE_LEVEL) +_Function_class_(FASTIO_PAUSE) +NDIS_STATUS +FASTIO_PAUSE( + _In_ PVOID ModemContext + ); +typedef FASTIO_PAUSE (*FastIOPauseHandler); +typedef +_When_(ShutdownAction==NdisShutdownPowerOff, _IRQL_requires_(PASSIVE_LEVEL)) +_When_(ShutdownAction==NdisShutdownBugCheck, _IRQL_requires_(HIGH_LEVEL)) +_Function_class_(FASTIO_SHUTDOWN) +VOID +FASTIO_SHUTDOWN( + _In_ PVOID ModemContext, + _In_ NDIS_SHUTDOWN_ACTION ShutdownAction + ); +typedef FASTIO_SHUTDOWN (*FastIOShutdownHandler); +typedef +_IRQL_requires_max_(DISPATCH_LEVEL) +_Function_class_(FASTIO_RESET) +NDIS_STATUS +FASTIO_RESET( + _In_ PVOID ModemContext + ); +typedef FASTIO_RESET (*FastIOResetHandler); +typedef +_IRQL_requires_(PASSIVE_LEVEL) +_Function_class_(FASTIO_RESTART) +NDIS_STATUS +FASTIO_RESTART( + _In_ PVOID ModemContext + ); +typedef FASTIO_RESTART (*FastIORestartHandler); + +#endif // (NTDDI_VERSION >= NTDDI_WIN10_RS2 || NDIS_SUPPORT_NDIS670) diff --git a/network/wwan/cxwmbclass/inc/mbbmessages.h b/network/wwan/cxwmbclass/inc/mbbmessages.h new file mode 100644 index 000000000..eb7542072 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/mbbmessages.h @@ -0,0 +1,3274 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.01.0625 */ +/* at Mon Jan 18 19:14:07 2038 + */ +/* @@MIDL_FILE_HEADING( ) */ + + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + + +#ifndef __MbbMessages_h__ +#define __MbbMessages_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#ifndef DECLSPEC_XFGVIRT +#if _CONTROL_FLOW_GUARD_XFG +#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func)) +#else +#define DECLSPEC_XFGVIRT(base, func) +#endif +#endif + +/* Forward Declarations */ + +/* header files for imported files */ +// #include "wtypes.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_MbbMessages_0000_0000 */ +/* [local] */ + +// +// Copyright (C) Microsoft. All rights reserved. +// +#include +// +// Service Ids +// +// Invald GUID +// 00000000-0000-0000-0000-000000000000 +DEFINE_GUID( MBB_UUID_INVALID, 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ); +#define MBB_UUID_INVALID_CONSTANT { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } +// Basic IP Connectivity +// a289cc33-bcbb-8b4f-b6b0-133ec2aae6df +DEFINE_GUID( MBB_UUID_BASIC_CONNECT, 0xa289cc33, 0xbcbb, 0x8b4f, 0xb6, 0xb0, 0x13, 0x3e, 0xc2, 0xaa, 0xe6, 0xdf ); +#define MBB_UUID_BASIC_CONNECT_CONSTANT { 0xa289cc33, 0xbcbb, 0x8b4f, { 0xb6, 0xb0, 0x13, 0x3e, 0xc2, 0xaa, 0xe6, 0xdf } } +// SMS +// 533fbeeb-14fe-4467-9f90-33a223e56c3f +DEFINE_GUID( MBB_UUID_SMS, 0x533fbeeb, 0x14fe, 0x4467, 0x9f, 0x90, 0x33, 0xa2, 0x23, 0xe5, 0x6c, 0x3f ); +#define MBB_UUID_SMS_CONSTANT { 0x533fbeeb, 0x14fe, 0x4467, { 0x9f, 0x90, 0x33, 0xa2, 0x23, 0xe5, 0x6c, 0x3f } } +// USSD +// e550a0c8-5e82-479e-82f7-10abf4c3351f +DEFINE_GUID( MBB_UUID_USSD, 0xe550a0c8, 0x5e82, 0x479e, 0x82, 0xf7, 0x10, 0xab, 0xf4, 0xc3, 0x35, 0x1f ); +#define MBB_UUID_USSD_CONSTANT { 0xe550a0c8, 0x5e82, 0x479e, { 0x82, 0xf7, 0x10, 0xab, 0xf4, 0xc3, 0x35, 0x1f } } +// Phonebook +// 4bf38476-1e6a-41db-b1d8-bed289c25bdb +DEFINE_GUID( MBB_UUID_PHONEBOOK, 0x4bf38476, 0x1e6a, 0x41db, 0xb1, 0xd8, 0xbe, 0xd2, 0x89, 0xc2, 0x5b, 0xdb ); +#define MBB_UUID_PHONEBOOK_CONSTANT { 0x4bf38476, 0x1e6a, 0x41db, { 0xb1, 0xd8, 0xbe, 0xd2, 0x89, 0xc2, 0x5b, 0xdb } } +// SIM Application Toolkit +// d8f20131-fcb5-4e17-8602-d6ed3816164c +DEFINE_GUID( MBB_UUID_SAT, 0xd8f20131, 0xfcb5, 0x4e17, 0x86, 0x02, 0xd6, 0xed, 0x38, 0x16, 0x16, 0x4c ); +#define MBB_UUID_SAT_CONSTANT { 0xd8f20131, 0xfcb5, 0x4e17, { 0x86, 0x02, 0xd6, 0xed, 0x38, 0x16, 0x16, 0x4c } } +// Windows 7 Vendor Extension +// b492e7e2-adba-499d-8401-7794bb913c1c +DEFINE_GUID( MBB_UUID_MS_VENDOR_EXTENSION, 0xb492e7e2, 0xadba, 0x499d, 0x84, 0x01, 0x77, 0x94, 0xbb, 0x91, 0x3c, 0x1c ); +#define MBB_UUID_MS_VENDOR_EXTENSION_CONSTANT { 0xb492e7e2, 0xadba, 0x499d, { 0x84, 0x01, 0x77, 0x94, 0xbb, 0x91, 0x3c, 0x1c } } +// Authentication +// 1d2b5ff7-0aa1-48b2-aa52-50f15767174e +DEFINE_GUID( MBB_UUID_AUTH, 0x1d2b5ff7, 0x0aa1, 0x48b2, 0xaa, 0x52, 0x50, 0xf1, 0x57,0x67, 0x17, 0x4e ); +#define MBB_UUID_AUTH_CONSTANT { 0x1d2b5ff7, 0x0aa1, 0x48b2, { 0xaa, 0x52, 0x50, 0xf1, 0x57,0x67, 0x17, 0x4e } } +// Device Service Stream +// c08a26dd-7718-4382-8482-6e0d583c4d0e +DEFINE_GUID( MBB_UUID_DSS, 0xc08a26dd, 0x7718, 0x4382, 0x84, 0x82, 0x6e, 0x0d, 0x58, 0x3c, 0x4d, 0x0e ); +#define MBB_UUID_DSS_CONSTANT { 0xc08a26dd, 0x7718, 0x4382, { 0x84, 0x82, 0x6e, 0x0d, 0x58, 0x3c, 0x4d, 0x0e } } +// Multi-carrier device service +// 8b569648-628d-4653-9b9f-1025404424e1 +DEFINE_GUID( MBB_UUID_MULTICARRIER, 0x8b569648, 0x628d, 0x4653, 0x9b, 0x9f, 0x10, 0x25, 0x40, 0x44, 0x24, 0xe1 ); +#define MBB_UUID_MULTICARRIER_CONSTANT { 0x8b569648, 0x628d, 0x4653, { 0x9b, 0x9f, 0x10, 0x25, 0x40, 0x44, 0x24, 0xe1 } } +// Host Shutdown device service +// 883b7c26-985f-43fa-9804-27d7fb80959c +DEFINE_GUID( MBB_UUID_HOSTSHUTDOWN, 0x883b7c26, 0x985f, 0x43fa, 0x98, 0x04, 0x27, 0xd7, 0xfb, 0x80, 0x95, 0x9c ); +#define MBB_UUID_HOSTSHUTDOWN_CONSTANT { 0x883b7c26, 0x985f, 0x43fa, { 0x98, 0x04, 0x27, 0xd7, 0xfb, 0x80, 0x95, 0x9c } } +// MBIM 2.0 voice extensions +// 8d8b9eba-37be-449b-8f1e-61cb034a702e +DEFINE_GUID( MBB_UUID_VOICEEXTENSIONS, 0x8d8b9eba, 0x37be, 0x449b, 0x8f, 0x1e, 0x61, 0xcb, 0x03, 0x4a, 0x70, 0x2e ); +#define MBB_UUID_VOICEEXTENSIONS_CONSTANT { 0x8d8b9eba, 0x37be, 0x449b, { 0x8f, 0x1e, 0x61, 0xcb, 0x03, 0x4a, 0x70, 0x2e } } +// Low-Level UICC Access +// c2f6588e-f037-4bc9-8665-f4d44bd09367 +DEFINE_GUID( MBB_UUID_UICC_LOW_LEVEL, 0xc2f6588e, 0xf037, 0x4bc9, 0x86, 0x65, 0xf4, 0xd4, 0x4b, 0xd0, 0x93, 0x67 ); +#define MBB_UUID_UICC_LOW_LEVEL_CONSTANT { 0xc2f6588e, 0xf037, 0x4bc9, { 0x86, 0x65, 0xf4, 0xd4, 0x4b, 0xd0, 0x93, 0x67 } } +// Selective Absorption Rate (SAR) control +// 68223d04-9f6c-4e0f-822d-28441fb72340 +DEFINE_GUID( MBB_UUID_SARCONTROL, 0x68223d04, 0x9f6c, 0x4e0f, 0x82, 0x2d, 0x28, 0x44, 0x1f, 0xb7, 0x23, 0x40 ); +#define MBB_UUID_SARCONTROL_CONSTANT { 0x68223d04, 0x9f6c, 0x4e0f, { 0x82, 0x2d, 0x28, 0x44, 0x1f, 0xb7, 0x23, 0x40 } } +// Basic IP Connectivity Extensions (a private Microsoft service not approved by MBIM USB forum as of 2016/11/09) +// 3d01dcc5-fef5-4d05-0d3a-bef7058e9aaf +DEFINE_GUID( MBB_UUID_BASIC_CONNECT_EXTENSIONS, 0x3d01dcc5, 0xfef5, 0x4d05, 0x0d, 0x3a, 0xbe, 0xf7, 0x05, 0x8e, 0x9a, 0xaf ); +#define MBB_UUID_BASIC_CONNECT_EXT_CONSTANT { 0x3d01dcc5, 0xfef5, 0x4d05, { 0x0d, 0x3a, 0xbe, 0xf7, 0x05, 0x8e, 0x9a, 0xaf } } +// DeviceService GUID for Modem Log Transfer (parameter for DSS connect/disconnect request to open/close DSS data channel) +// 0ebb1ceb-af2d-484d-8df3-53bc51fd162c +DEFINE_GUID( MBB_UUID_MODEM_LOG_TRANSFER, 0x0ebb1ceb, 0xaf2d, 0x484d, 0x8d, 0xf3, 0x53, 0xbc, 0x51, 0xfd, 0x16, 0x2c ); +#define MBB_UUID_MODEM_LOG_TRANSFER_CONSTANT { 0x0ebb1ceb, 0xaf2d, 0x484d, { 0x8d, 0xf3, 0x53, 0xbc, 0x51, 0xfd, 0x16, 0x2c } } +// +// Context Type GUIDs +// +// MBIMContextTypeNone +// B43F758C-A560-4B46-B35E-C5869641FB54 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_NONE, 0xB43F758C, 0xA560, 0x4B46, 0xB3, 0x5E, 0xC5, 0x86, 0x96, 0x41, 0xFB, 0x54 ); +// MBIMContextTypeInternet +// 7E5E2A7E-4E6F-7272-736B-656E7E5E2A7E +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_INTERNET, 0x7E5E2A7E, 0x4E6F, 0x7272, 0x73, 0x6B, 0x65, 0x6E, 0x7E, 0x5E, 0x2A, 0x7E ); +// MBIMContextTypeVpn +// 9B9F7BBE-8952-44B7-83AC-CA41318DF7A0 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_VPN, 0x9B9F7BBE, 0x8952, 0x44B7, 0x83, 0xAC, 0xCA, 0x41, 0x31, 0x8D, 0xF7, 0xA0 ); +// MBIMContextTypeVoice +// 88918294-0EF4-4396-8CCA-A8588FBC02B2 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_VOICE, 0x88918294, 0x0EF4, 0x4396, 0x8C, 0xCA, 0xA8, 0x58, 0x8F, 0xBC, 0x02, 0xB2 ); +// MBIMContextTypeVideoShare +// 05A2A716-7C34-4B4D-9A91-C5EF0C7AAACC +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_VIDEO_SHARE, 0x05A2A716,0x7C34, 0x4B4D, 0x9A, 0x91, 0xC5, 0xEF, 0x0C, 0x7A, 0xAA, 0xCC ); +// MBIMContextTypePurchase +// B3272496-AC6C-422B-A8C0-ACF687A27217 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_PURCHASE, 0xB3272496, 0xAC6C, 0x422B, 0xA8, 0xC0, 0xAC, 0xF6, 0x87, 0xA2, 0x72, 0x17 ); +// MBIMContextTypeIMS +// 21610D01-3074-4BCE-9425-B53A07D697D6 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_IMS, 0x21610D01, 0x3074, 0x4BCE, 0x94, 0x25, 0xB5, 0x3A, 0x07, 0xD6, 0x97, 0xD6 ); +// MBIMContextTypeMMS +// 46726664-7269-6BC6-9624-D1D35389ACA9 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_MMS, 0x46726664, 0x7269, 0x6BC6, 0x96, 0x24, 0xD1, 0xD3, 0x53, 0x89, 0xAC, 0xA9 ); +// MBIMContextTypeLocal +// A57A9AFC-B09F-45D7-BB40-033C39F60DB9 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_LOCAL, 0xA57A9AFC, 0xB09F, 0x45D7, 0xBB, 0x40, 0x03, 0x3C, 0x39, 0xF6, 0x0D, 0xB9 ); +// MBIMMsContextTypeAdmin +// 5f7e4c2e-e80b-40a9-a239-f0abcfd11f4b +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_MS_ADMIN, 0x5f7e4c2e, 0xe80b, 0x40a9, 0xa2, 0x39, 0xf0, 0xab, 0xcf, 0xd1, 0x1f, 0x4b ); +// MBIMMSContextTypeApp +// 74d88a3d-dfbd-4799-9a8c-7310a37bb2ee +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_MS_APP, 0x74d88a3d, 0xdfbd, 0x4799, 0x9a, 0x8c, 0x73, 0x10, 0xa3, 0x7b, 0xb2, 0xee ); +// MBIMMsContextTypeXcap +// 50d378a7-baa5-4a50-b872-3fe5bb463411 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_MS_XCAP, 0x50d378a7, 0xbaa5, 0x4a50, 0xb8, 0x72, 0x3f, 0xe5, 0xbb, 0x46, 0x34, 0x11 ); +// MBIMMsContextTypeTethering +// 5e4e0601-48dc-4e2b-acb8-08b4016bbaac +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_MS_TETHERING, 0x5e4e0601, 0x48dc, 0x4e2b, 0xac, 0xb8, 0x08, 0xb4, 0x01, 0x6b, 0xba, 0xac ); +// MBIMMsContextTypeEmergencyCalling +// 5f41adb8-204e-4d31-9da8-b3c970e360f2 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_MS_EMERGENCYCALL, 0x5f41adb8, 0x204e, 0x4d31, 0x9d, 0xa8, 0xb3, 0xc9, 0x70, 0xe3, 0x60, 0xf2 ); +// 9C494542-A43B-4EA5-B8B7-53310E71DF10 +DEFINE_GUID( MBB_UUID_CONTEXT_TYPE_CUSTOM, 0x9C494542, 0xA43B, 0x4EA5, 0xB8, 0xB7, 0x53, 0x31, 0x0E, 0x71, 0xDF, 0x10); +// 146FED19-EB71-42A7-B3EB-3875DEA61D92 +DEFINE_GUID(GUID_USB_CAPABILITY_DEVICE_TYPE, 0x146FED19, 0xEB71, 0x42A7, 0xB3, 0xEB, 0x38, 0x75, 0xDE, 0xA6, 0x1D, 0x92); +#define MBB_STATUS_SUCCESS( STATUS ) \ + ( \ + ((STATUS) == MBB_STATUS_SUCCESS) || \ + ((STATUS) == MBB_STATUS_SMS_MORE_DATA) \ + ) +#define MBB_STATUS_IS_BASIC(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_BASIC_START) && ((MBBSTATUS) < MBB_STATUS_BASIC_END)) +#define MBB_STATUS_BASIC_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_BASIC_START) +#define MBB_STATUS_BASIC_COUNT() (MBB_STATUS_BASIC_END-MBB_STATUS_BASIC_START) +#define MBB_STATUS_IS_SMS(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_SMS_START) && ((MBBSTATUS) < MBB_STATUS_SMS_END)) +#define MBB_STATUS_SMS_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_SMS_START) +#define MBB_STATUS_SMS_COUNT() (MBB_STATUS_SMS_END-MBB_STATUS_SMS_START) +#define MBB_STATUS_IS_UICC(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_UICC_START) && ((MBBSTATUS) < MBB_STATUS_UICC_END)) +#define MBB_STATUS_UICC_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_UICC_START) +#define MBB_STATUS_UICC_COUNT() (MBB_STATUS_UICC_END-MBB_STATUS_UICC_START) +#define MBB_UUID_TO_NET(_dest, _src) \ +{ \ + (_dest)->Data1 = RtlUlongByteSwap((_src)->Data1); \ + (_dest)->Data2 = RtlUshortByteSwap((_src)->Data2); \ + (_dest)->Data3 = RtlUshortByteSwap((_src)->Data3); \ + RtlCopyMemory((_dest)->Data4, (_src)->Data4, sizeof((_src)->Data4)); \ + \ +} +#define MBB_UUID_TO_HOST(_dest, _src) MBB_UUID_TO_NET(_dest, _src) +#define MBB_IS_DEVICE_REGISTERED( _State_ ) \ +( \ + ( (_State_) == MbbRegisterStateHome ) || \ + ( (_State_) == MbbRegisterStateRoaming ) || \ + ( (_State_) == MbbRegisterStatePartner ) \ +) +#include +#define MBB_MAXIMUM_DATA_CLASS_NAME_LENGTH ( 11 ) + +#define MBB_MAXIMUM_DEVICE_ID_LENGTH ( 17 ) + +#define MBB_MAXIMUM_FIRMWARE_INFO_LENGTH ( 31 ) + +#define MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH ( 15 ) + +#define MBB_MAXIMUM_SIM_ICC_ID_LENGTH ( 20 ) + +#define MBB_MAXIMUM_TELEPHONE_NUMBER_LENGTH ( 15 ) + +#define MBB_MAXIMUM_TELEPHONE_NUMBER_ERRATA_LENGTH ( 22 ) + +#define MBB_MAXIMUM_PIN_LENGTH ( 16 ) + +#define MBB_MAXIMUM_PROVIDER_ID_LENGTH ( 6 ) + +#define MBB_MAXIMUM_PROVIDER_NAME_LENGTH ( 20 ) + +#define MBB_MAXIMUM_ROAMING_TEXT_LENGTH ( 63 ) + +#define MBB_MAXIMUM_ACCESS_STRING_LENGTH ( 100 ) + +#define MBB_MAXIMUM_USERNAME_LENGTH ( 255 ) + +#define MBB_MAXIMUM_PASSWORD_LENGTH ( 255 ) + +#define MBB_MAXIMUM_SMS_ADDRESS_LENGTH ( 20 ) + +#define MBB_MAXIMUM_SMS_CDMA_ADDRESS_LENGTH ( 49 ) + +#define MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH ( 21 ) + +#define MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH ( 160 ) + +#define MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH ( 183 ) + +#define MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH ( 255 ) + +#define MBB_USSD_STRING_LEN_MAX ( 160 ) + +#define MBB_RSSI_DISABLE ( 0xffffffff ) + +#define MBB_RSSI_DEFAULT ( 0 ) + +#define MBB_SET_CONTEXT_STATE_EX3_MIN_TLV_CNT ( 3 ) + +#define MBB_CONTEXT_STATE_EX3_MIN_TLV_CNT ( 1 ) + +#define MBIM_VERSION_1_0 ( 0x100 ) + +#define MBIM_MS_EXTENDED_VER_1_0 ( 0x100 ) + +#define MBIM_MS_EXTENDED_VER_2_0 ( 0x200 ) + +#define MBIM_MS_EXTENDED_VER_3_0 ( 0x300 ) + +#define MBB_MS_DEVICE_CAPS_INFO_V3_MIN_TLV_CNT ( 6 ) + +#define MBB_TLV_TYPE_RESERVED ( 0 ) + +#define MBB_TLV_TYPE_UE_POLICIES ( 1 ) + +#define MBB_TLV_TYPE_SINGLE_NSSAI ( 2 ) + +#define MBB_TLV_TYPE_ALLOWED_NSSAI ( 3 ) + +#define MBB_TLV_TYPE_CFG_NSSAI ( 4 ) + +#define MBB_TLV_TYPE_DFLT_CFG_NSSAI ( 5 ) + +#define MBB_TLV_TYPE_PRECFG_DFLT_CFG_NSSAI ( 6 ) + +#define MBB_TLV_TYPE_REJ_NSSAI ( 7 ) + +#define MBB_TLV_TYPE_LADN ( 8 ) + +#define MBB_TLV_TYPE_TAI ( 9 ) + +#define MBB_TLV_TYPE_WCHAR_STR ( 10 ) + +#define MBB_TLV_TYPE_UINT16_TBL ( 11 ) + +#define MBB_TLV_TYPE_EAP_PACKET ( 12 ) + +#define MBB_TLV_TYPE_PCO ( 13 ) + +#define MBB_TLV_TYPE_ROUTE_SELECTION_DESCRIPTORS ( 14 ) + +#define MBB_TLV_TYPE_TRAFFIC_PARAMETERS ( 15 ) + +#define MBB_TLV_TYPE_WAKE_COMMAND ( 16 ) + +#define MBB_TLV_TYPE_WAKE_PACKET ( 17 ) + +#define MBB_NW_PARAMS_INFO_CONFIG_TLV_CNT ( 6 ) + +#define MBB_NW_PARAMS_INFO_UE_POLICIES_TLV_CNT ( 1 ) + +typedef unsigned short MBB_TLV_TYPE; + +typedef +enum _USB_CAP_DEVICE_TYPE + { + USB_CAP_DEVICE_TYPE_USB = 0, + USB_CAP_DEVICE_TYPE_UDE_MBIM = 1, + USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO = 2, + USB_CAP_DEVICE_TYPE_MAXIMUM = ( USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO + 1 ) + } USB_CAP_DEVICE_TYPE; + +typedef struct _USB_CAP_DEVICE_INFO_HEADER + { + USB_CAP_DEVICE_TYPE DeviceType; + UCHAR DeviceMinorVersion; + UCHAR DeviceMajorVersion; + ULONG Reserved; + } USB_CAP_DEVICE_INFO_HEADER; + +typedef struct _USB_CAP_DEVICE_INFO_HEADER *PUSB_CAP_DEVICE_INFO_HEADER; + +typedef struct _USB_CAP_DEVICE_INFO + { + USB_CAP_DEVICE_INFO_HEADER DeviceInfoHeader; + } USB_CAP_DEVICE_INFO; + +typedef struct _USB_CAP_DEVICE_INFO *PUSB_CAP_DEVICE_INFO; + +typedef +enum _MBB_NBL_TYPE + { + MBB_NBL_TYPE_IP = 0, + MBB_NBL_TYPE_DSS = 1, + MBB_NBL_TYPE_MAXIMUM = ( MBB_NBL_TYPE_DSS + 1 ) + } MBB_NBL_TYPE; + +typedef +enum _MBB_STATUS + { + MBB_STATUS_SUCCESS = 0, + MBB_STATUS_BASIC_START = 0, + MBB_STATUS_BUSY = 1, + MBB_STATUS_FAILURE = 2, + MBB_STATUS_SIM_NOT_INSERTED = 3, + MBB_STATUS_BAD_SIM = 4, + MBB_STATUS_PIN_REQUIRED = 5, + MBB_STATUS_PIN_DISABLED = 6, + MBB_STATUS_NOT_REGISTERED = 7, + MBB_STATUS_PROVIDERS_NOT_FOUND = 8, + MBB_STATUS_NO_DEVICE_SUPPORT = 9, + MBB_STATUS_PROVIDER_NOT_VISIBLE = 10, + MBB_STATUS_DATA_CLASS_NOT_AVAILABLE = 11, + MBB_STATUS_PACKET_SVC_DETACHED = 12, + MBB_STATUS_MAX_ACTIVATED_CONTEXTS = 13, + MBB_STATUS_NOT_INITIALIZED = 14, + MBB_STATUS_VOICE_CALL_IN_PROGRESS = 15, + MBB_STATUS_CONTEXT_NOT_ACTIVATED = 16, + MBB_STATUS_SERVICE_NOT_ACTIVATED = 17, + MBB_STATUS_INVALID_ACCESS_STRING = 18, + MBB_STATUS_INVALID_USER_NAME_PWD = 19, + MBB_STATUS_RADIO_POWER_OFF = 20, + MBB_STATUS_INVALID_PARAMETERS = 21, + MBB_STATUS_READ_FAILURE = 22, + MBB_STATUS_WRITE_FAILURE = 23, + MBB_STATUS_DENIED_POLICY = 24, + MBB_STATUS_NO_PHONEBOOK = 25, + MBB_STATUS_PARAMETER_TOO_LONG = 26, + MBB_STATUS_STK_BUSY = 27, + MBB_STATUS_OPERATION_NOT_ALLOWED = 28, + MBB_STATUS_MEMORY_FAILURE = 29, + MBB_STATUS_INVALID_MEMORY_INDEX = 30, + MBB_STATUS_MEMORY_FULL = 31, + MBB_STATUS_FILTER_NOT_SUPPORTED = 32, + MBB_STATUS_DSS_INSTANCE_LIMIT = 33, + MBB_STATUS_INVALID_DEVICE_SERVICE_OPERATION = 34, + MBB_STATUS_AUTH_INCORRECT_AUTN = 35, + MBB_STATUS_AUTH_SYNC_FAILURE = 36, + MBB_STATUS_AUTH_AMF_NOT_SET = 37, + MBB_STATUS_CONTEXT_NOT_SUPPORTED = 38, + MBB_STATUS_SHAREABILITY_CONDITION_ERROR = 39, + MBB_STATUS_PIN_FAILURE = 40, + MBB_STATUS_NO_LTE_ATTACH_CONFIG = 41, + MBB_STATUS_SESSION_ALREADY_EXISTS = 42, + MBB_STATUS_BASIC_END = ( MBB_STATUS_SESSION_ALREADY_EXISTS + 1 ) , + MBB_STATUS_SMS_UNKNOWN_SMSC_ADDRESS = 100, + MBB_STATUS_SMS_START = 100, + MBB_STATUS_SMS_NETWORK_TIMEOUT = 101, + MBB_STATUS_SMS_LANG_NOT_SUPPORTED = 102, + MBB_STATUS_SMS_ENCODING_NOT_SUPPORTED = 103, + MBB_STATUS_SMS_FORMAT_NOT_SUPPORTED = 104, + MBB_STATUS_SMS_MORE_DATA = 105, + MBB_STATUS_SMS_END = ( MBB_STATUS_SMS_MORE_DATA + 1 ) , + MBB_STATUS_UICC_NO_LOGICAL_CHANNELS = 0x87430001, + MBB_STATUS_UICC_START = 0x87430001, + MBB_STATUS_UICC_SELECT_FAILED = 0x87430002, + MBB_STATUS_UICC_INVALID_LOGICAL_CHANNEL = 0x87430003, + MBB_STATUS_UICC_END = ( MBB_STATUS_UICC_INVALID_LOGICAL_CHANNEL + 1 ) + } MBB_STATUS; + +typedef +enum _MBB_ERROR + { + MBB_ERROR_NONE = 0, + MBB_ERROR_TIMEOUT_FRAGMENT = 1, + MBB_ERROR_FRAGMENT_OUT_OF_SEQUENCE = 2, + MBB_ERROR_LENGTH_MISMATCH = 3, + MBB_ERROR_DUPLICATE_TID = 4, + MBB_ERROR_NOT_OPENED = 5, + MBB_ERROR_UNKNOWN = 6, + MBB_ERROR_CANCEL = 7, + MBB_ERROR_MAX_TRANSFER = 8 + } MBB_ERROR; + +typedef +enum _MBB_MESSAGE_TYPE + { + MBB_MESSAGE_TYPE_NONE = 0, + MBB_MESSAGE_TYPE_OPEN = 0x1, + MBB_MESSAGE_TYPE_CLOSE = 0x2, + MBB_MESSAGE_TYPE_COMMAND = 0x3, + MBB_MESSAGE_TYPE_HOST_ERROR = 0x4, + MBB_MESSAGE_TYPE_OPEN_DONE = 0x80000001, + MBB_MESSAGE_TYPE_CLOSE_DONE = 0x80000002, + MBB_MESSAGE_TYPE_COMMAND_DONE = 0x80000003, + MBB_MESSAGE_TYPE_FUNCTION_ERROR = 0x80000004, + MBB_MESSAGE_TYPE_INDICATE_STATUS = 0x80000007 + } MBB_MESSAGE_TYPE; + +typedef +enum _MBB_COMMAND_TYPE + { + MBB_COMMAND_TYPE_QUERY = 0, + MBB_COMMAND_TYPE_SET = 1 + } MBB_COMMAND_TYPE; + +typedef struct _MBB_MESSAGE_HEADER + { + MBB_MESSAGE_TYPE MessageType; + ULONG MessageLength; + ULONG MessageTransactionId; + } MBB_MESSAGE_HEADER; + +typedef struct _MBB_MESSAGE_HEADER *PMBB_MESSAGE_HEADER; + +typedef struct _MBB_FRAGMENT_HEADER + { + ULONG TotalFragments; + ULONG CurrentFragment; + } MBB_FRAGMENT_HEADER; + +typedef struct _MBB_FRAGMENT_HEADER *PMBB_FRAGMENT_HEADER; + +typedef struct _MBB_COMMAND + { + GUID ServiceId; + ULONG CommandId; + } MBB_COMMAND; + +typedef struct _MBB_COMMAND *PMBB_COMMAND; + +typedef struct _MBB_COMMAND_HEADER + { + MBB_MESSAGE_HEADER MessageHeader; + MBB_FRAGMENT_HEADER FragmentHeader; + MBB_COMMAND Command; + MBB_COMMAND_TYPE CommandType; + ULONG InformationBufferLength; + } MBB_COMMAND_HEADER; + +typedef struct _MBB_COMMAND_HEADER *PMBB_COMMAND_HEADER; + +typedef struct _MBB_COMMAND_FRAGMENT_HEADER + { + MBB_MESSAGE_HEADER MessageHeader; + MBB_FRAGMENT_HEADER FragmentHeader; + } MBB_COMMAND_FRAGMENT_HEADER; + +typedef struct _MBB_COMMAND_FRAGMENT_HEADER *PMBB_COMMAND_FRAGMENT_HEADER; + +typedef struct _MBB_COMMAND_DONE_HEADER + { + MBB_MESSAGE_HEADER MessageHeader; + MBB_FRAGMENT_HEADER FragmentHeader; + MBB_COMMAND Command; + MBB_STATUS MbbStatus; + ULONG InformationBufferLength; + } MBB_COMMAND_DONE_HEADER; + +typedef struct _MBB_COMMAND_DONE_HEADER *PMBB_COMMAND_DONE_HEADER; + +typedef struct _MBB_INDICATE_STATUS_HEADER + { + MBB_MESSAGE_HEADER MessageHeader; + MBB_FRAGMENT_HEADER FragmentHeader; + MBB_COMMAND Command; + ULONG InformationBufferLength; + } MBB_INDICATE_STATUS_HEADER; + +typedef struct _MBB_INDICATE_STATUS_HEADER *PMBB_INDICATE_STATUS_HEADER; + +typedef struct _MBB_OPEN_MESSAGE + { + MBB_MESSAGE_HEADER MessageHeader; + ULONG MaximumControlTransfer; + } MBB_OPEN_MESSAGE; + +typedef struct _MBB_OPEN_MESSAGE *PMBB_OPEN_MESSAGE; + +typedef struct _MBB_OPEN_MESSAGE_FASTIO + { + MBB_MESSAGE_HEADER MessageHeader; + ULONG MaximumControlTransfer; + PVOID AdapterContext; + PVOID SendNetBufferListsCompleteHandler; + PVOID ReceiveNetBufferListsHandler; + } MBB_OPEN_MESSAGE_FASTIO; + +typedef struct _MBB_OPEN_MESSAGE_FASTIO *PMBB_OPEN_MESSAGE_FASTIO; + +typedef struct _MBB_CLOSE_MESSAGE + { + MBB_MESSAGE_HEADER MessageHeader; + } MBB_CLOSE_MESSAGE; + +typedef struct _MBB_CLOSE_MESSAGE *PMBB_CLOSE_MESSAGE; + +typedef struct _MBB_OPEN_DONE + { + MBB_MESSAGE_HEADER MessageHeader; + MBB_STATUS MbbStatus; + } MBB_OPEN_DONE; + +typedef struct _MBB_OPEN_DONE *PMBB_OPEN_DONE; + +typedef struct _MBB_OPEN_DONE_FASTIO + { + MBB_MESSAGE_HEADER MessageHeader; + MBB_STATUS MbbStatus; + PVOID ModemContext; + PVOID SendNetBufferListsHandler; + PVOID ReturnNetBufferListsHandler; + PVOID CancelSendHandler; + PVOID HaltHandler; + PVOID PauseHandler; + PVOID ShutdownHandler; + PVOID ResetHandler; + PVOID RestartHandler; + } MBB_OPEN_DONE_FASTIO; + +typedef struct _MBB_OPEN_DONE_FASTIO *PMBB_OPEN_DONE_FASTIO; + +typedef struct _MBB_CLOSE_DONE + { + MBB_MESSAGE_HEADER MessageHeader; + MBB_STATUS MbbStatus; + } MBB_CLOSE_DONE; + +typedef struct _MBB_CLOSE_DONE *PMBB_CLOSE_DONE; + +typedef struct _MBB_ERROR_MESSAGE + { + MBB_MESSAGE_HEADER MessageHeader; + MBB_ERROR ErrorCode; + } MBB_ERROR_MESSAGE; + +typedef struct _MBB_ERROR_MESSAGE *PMBB_ERROR_MESSAGE; + +typedef +enum _MBB_BASIC_CID + { + MBB_BASIC_CID_DEVICE_CAPS = 1, + MBB_BASIC_CID_SUBSCRIBER_READY_INFO = 2, + MBB_BASIC_CID_RADIO_STATE = 3, + MBB_BASIC_CID_PIN_INFO = 4, + MBB_BASIC_CID_PIN_LIST = 5, + MBB_BASIC_CID_HOME_PROVIDER = 6, + MBB_BASIC_CID_PREFERRED_PROVIDERS = 7, + MBB_BASIC_CID_VISIBLE_PROVIDERS = 8, + MBB_BASIC_CID_REGISTER_STATE = 9, + MBB_BASIC_CID_PACKET_SERVICE = 10, + MBB_BASIC_CID_SIGNAL_STATE = 11, + MBB_BASIC_CID_CONNECT = 12, + MBB_BASIC_CID_PROVISIONED_CONTEXTS = 13, + MBB_BASIC_CID_SERVICE_ACTIVATION = 14, + MBB_BASIC_CID_IP_ADDRESS_INFO = 15, + MBB_BASIC_CID_DEVICE_SERVICES = 16, + MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES = 19, + MBB_BASIC_CID_PACKET_STATISTICS = 20, + MBB_BASIC_CID_NETWORK_IDLE_HINT = 21, + MBB_BASIC_CID_EMERGENCY_MODE = 22, + MBB_BASIC_CID_PACKET_FILTERS = 23, + MBB_BASIC_CID_MULTICARRIER_PROVIDERS = 24, + MBB_BASIC_CID_MAXIMUM = ( MBB_BASIC_CID_MULTICARRIER_PROVIDERS + 1 ) + } MBB_BASIC_CID; + +typedef +enum _MBB_SMS_CID + { + MBB_SMS_CID_CONFIGURATION = 1, + MBB_SMS_CID_READ = 2, + MBB_SMS_CID_SEND = 3, + MBB_SMS_CID_DELETE = 4, + MBB_SMS_CID_STATUS = 5, + MBB_SMS_CID_MAXIMUM = ( MBB_SMS_CID_STATUS + 1 ) + } MBB_SMS_CID; + +typedef +enum _MBB_VENDOR_CID + { + MBB_VENDOR_CID_MS_VENDOR_SPECIFIC = 1, + MBB_VENDOR_CID_MAXIMUM = ( MBB_VENDOR_CID_MS_VENDOR_SPECIFIC + 1 ) + } MBB_VENDOR_CID; + +typedef +enum _MBB_USSD_CID + { + MBB_USSD_CID_USSD = 1, + MBB_USSD_CID_MAXIMUM = ( MBB_USSD_CID_USSD + 1 ) + } MBB_USSD_CID; + +typedef +enum _MBB_PHONEBOOK_CID + { + MBB_PHONEBOOK_CID_CONFIGURATION = 1, + MBB_PHONEBOOK_CID_READ = 2, + MBB_PHONEBOOK_CID_DELETE = 3, + MBB_PHONEBOOK_CID_SAVE = 4, + MBB_PHONEBOOK_CID_MAXIMUM = ( MBB_PHONEBOOK_CID_SAVE + 1 ) + } MBB_PHONEBOOK_CID; + +typedef +enum _MBB_SAT_CID + { + MBB_SAT_CID_PAC = 1, + MBB_SAT_CID_TERMINAL_RESPONSE = 2, + MBB_SAT_CID_ENVELOPE = 3, + MBB_SAT_CID_MAXIMUM = ( MBB_SAT_CID_ENVELOPE + 1 ) + } MBB_SAT_CID; + +typedef +enum _MBB_AUTH_CID + { + MBB_AUTH_CID_AKA = 1, + MBB_AUTH_CID_AKAP = 2, + MBB_AUTH_CID_SIM = 3, + MBB_AUTH_CID_MAXIUM = ( MBB_AUTH_CID_SIM + 1 ) + } MBB_AUTH_CID; + +typedef +enum _MBB_DSS_CID + { + MBB_DSS_CID_CONNECT = 1, + MBB_DSS_CID_MAXIUM = ( MBB_DSS_CID_CONNECT + 1 ) + } MBB_DSS_CID; + +typedef +enum _MBB_MULTICARRIER_CID + { + MBB_MULTICARRIER_CID_CAPABILITIES = 1, + MBB_MULTICARRIER_CID_LOCATION_INFO = 2, + MBB_MULTICARRIER_CID_CURRENT_CID_LIST = 3, + MBB_MULTICARRIER_CID_MAXIMUM = ( MBB_MULTICARRIER_CID_CURRENT_CID_LIST + 1 ) + } MBB_MULTICARRIER_CID; + +typedef +enum _MBB_HOSTSHUTDOWN_CID + { + MBB_HOSTSHUTDOWN_CID_ONE = 1, + MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN = 2, + MBB_HOSTSHUTDOWN_CID_MAX = ( MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN + 1 ) + } MBB_HOSTSHUTDOWN_CID; + +typedef +enum _MBB_VOICEEXTENSIONS_CID + { + MBB_VOICEEXTENSIONS_CID_SYS_CAPS = 1, + MBB_VOICEEXTENSIONS_CID_DEVICE_CAPS_V2 = 2, + MBB_VOICEEXTENSIONS_CID_SYS_SLOTMAPPINGS = 3, + MBB_VOICEEXTENSIONS_CID_SLOT_INFO_STATUS = 4, + MBB_VOICEEXTENSIONS_CID_DEVICE_BINDINGS = 5, + MBB_VOICEEXTENSIONS_CID_REGISTER_STATE_V2 = 6, + MBB_VOICEEXTENSIONS_CID_IMS_VOICE_STATE = 7, + MBB_VOICEEXTENSIONS_CID_SIGNAL_STATE_V2 = 8, + MBB_VOICEEXTENSIONS_CID_LOCATION_STATE = 9, + MBB_VOICEEXTENSIONS_CID_NITZ = 10, + MBB_VOICEEXTENSIONS_CID_MAX = ( MBB_VOICEEXTENSIONS_CID_NITZ + 1 ) + } MBB_VOICEEXTENSIONS_CID; + +typedef +enum _MBB_UICC_CID + { + MBB_UICC_CID_ATR = 1, + MBB_UICC_CID_OPEN_CHANNEL = 2, + MBB_UICC_CID_CLOSE_CHANNEL = 3, + MBB_UICC_CID_APDU = 4, + MBB_UICC_CID_TERMINAL_CAPABILITY = 5, + MBB_UICC_CID_RESET = 6, + MBB_UICC_CID_APP_LIST = 7, + MBB_UICC_CID_FILE_STATUS = 8, + MBB_UICC_CID_ACCESS_BINARY = 9, + MBB_UICC_CID_ACCESS_RECORD = 10, + MBB_UICC_CID_MAXIMUM = ( MBB_UICC_CID_ACCESS_RECORD + 1 ) + } MBB_UICC_CID; + +typedef +enum _MBB_SAR_CID + { + MBB_SAR_CID_CONFIG = 1, + MBB_SAR_CID_TRANSMISSION_STATUS = 2, + MBB_SAR_CID_MAXIMUM = ( MBB_SAR_CID_TRANSMISSION_STATUS + 1 ) + } MBB_SAR_CID; + +typedef +enum _MBB_BASICCONNECTEXT_CID + { + MBB_BASICCONNECTEXT_CID_PROVISIONED_CONTEXT_V2 = 1, + MBB_BASICCONNECTEXT_CID_NETWORK_BLACKLIST = 2, + MBB_BASICCONNECTEXT_CID_LTE_ATTACH_CONFIG = 3, + MBB_BASICCONNECTEXT_CID_LTE_ATTACH_STATUS = 4, + MBB_BASICCONNECTEXT_CID_SYS_CAPS = 5, + MBB_BASICCONNECTEXT_CID_DEVICE_CAPS_V2 = 6, + MBB_BASICCONNECTEXT_CID_DEVICE_SLOT_MAPPINGS = 7, + MBB_BASICCONNECTEXT_CID_SLOT_INFO_STATUS = 8, + MBB_BASICCONNECTEXT_CID_PCO = 9, + MBB_BASICCONNECTEXT_CID_DEVICE_RESET = 10, + MBB_BASICCONNECTEXT_CID_BASE_STATIONS_INFO = 11, + MBB_BASICCONNECTEXT_CID_LOCATION_INFO_STATUS = 12, + MBB_BASICCONNECTEXT_CID_MODEM_LOGGING_CONFIG = 13, + MBB_BASICCONNECTEXT_CID_PIN_INFO_EX2 = 14, + MBB_BASICCONNECTEXT_CID_VERSION = 15, + MBB_BASICCONNECTEXT_CID_MODEM_CONFIG = 16, + MBB_BASICCONNECTEXT_CID_REGISTRATION_PARAMS = 17, + MBB_BASICCONNECTEXT_CID_NETWORK_PARAMS = 18, + MBB_BASICCONNECTEXT_CID_WAKE_REASON = 19, + MBB_BASICCONNECTEXT_CID_MAXIMUM = ( MBB_BASICCONNECTEXT_CID_WAKE_REASON + 1 ) + } MBB_BASICCONNECTEXT_CID; + +typedef +enum _MBB_DEVICE_TYPE + { + MbbDeviceTypeUnknown = 0, + MbbDeviceTypeEmbedded = 1, + MbbDeviceTypeRemovable = 2, + MbbDeviceTypeRemote = 3, + MbbDeviceTypeMaximum = ( MbbDeviceTypeRemote + 1 ) + } MBB_DEVICE_TYPE; + +typedef +enum _MBB_CELLULAR_CLASS + { + MbbCellularClassInvalid = 0, + MbbCellularClassGsm = 1, + MbbCellularClassCdma = 2, + MbbCellularClassMaximum = ( MbbCellularClassCdma + 1 ) + } MBB_CELLULAR_CLASS; + +typedef +enum _MBB_VOICE_CLASS + { + MbbVoiceClassInvalid = 0, + MbbVoiceClassNoVoice = 1, + MbbVoiceClassSeparateVoiceData = 2, + MbbVoiceClassSimultaneousVoiceData = 3, + MbbVoiceClassMaximum = ( MbbVoiceClassSimultaneousVoiceData + 1 ) + } MBB_VOICE_CLASS; + +typedef +enum _MBB_SIM_CLASS + { + MbbSimClassInvalid = 0, + MbbSimClassSimLogical = 1, + MbbSimClassSimRemovable = 2, + MbbSimClassMaximum = ( MbbSimClassSimRemovable + 1 ) + } MBB_SIM_CLASS; + +typedef +enum _MBB_DATA_CLASS_VALUE + { + MbbDataClassNone = 0, + MbbDataClassGprs = 0x1, + MbbDataClassEdge = 0x2, + MbbDataClassUmts = 0x4, + MbbDataClassHsdpa = 0x8, + MbbDataClassHsupa = 0x10, + MbbDataClassLte = 0x20, + MbbDataClass5G = 0x40, + MbbDataClass_UNUSED = 0x80, + MbbDataClassTdScdma = 0x1000, + MbbDataClass1xRtt = 0x10000, + MbbDataClass1xEvdo = 0x20000, + MbbDataClass1xEvdoReva = 0x40000, + MbbDataClass1xEvdv = 0x80000, + MbbDataClass3xRtt = 0x100000, + MbbDataClass1xEvdoRevb = 0x200000, + MbbDataClassUmb = 0x400000, + MbbDataClassCustom = 0x80000000 + } MBB_DATA_CLASS_VALUE; + +typedef +enum _MBB_DATA_SUBCLASS_VALUE + { + MbbDataSubClassNone = 0, + MbbDataSubClass5GENDC = 0x1, + MbbDataSubClass5GNR = 0x2, + MbbDataSubClass5GNEDC = 0x4, + MbbDataSubClass5GELTE = 0x8, + MbbDataSubClassNGENDC = 0x10 + } MBB_DATA_SUBCLASS_VALUE; + +typedef +enum _MBB_FREQUENCY_RANGE + { + MbbFrequencyRangeUnknown = 0, + MbbFrequencyRange1 = 1, + MbbFrequencyRange2 = 2, + MbbFrequencyRange1AndRange2 = 3, + MbbFrequencyRangeMaximum = ( MbbFrequencyRange1AndRange2 + 1 ) + } MBB_FREQUENCY_RANGE; + +typedef +enum _MBB_BAND_CLASS_VALUE + { + MbbBandClassUnknown = 0, + MbbBandClass0 = 0x1, + MbbBandClassI = 0x2, + MbbBandClassII = 0x4, + MbbBandClassIII = 0x8, + MbbBandClassIV = 0x10, + MbbBandClassV = 0x20, + MbbBandClassVI = 0x40, + MbbBandClassVII = 0x80, + MbbBandClassVIII = 0x100, + MbbBandClassIX = 0x200, + MbbBandClassX = 0x400, + MbbBandClassXI = 0x800, + MbbBandClassXII = 0x1000, + MbbBandClassXIII = 0x2000, + MbbBandClassXIV = 0x4000, + MbbBandClassXV = 0x8000, + MbbBandClassXVI = 0x10000, + MbbBandClassXVII = 0x20000, + MbbBandClassCustom = 0x80000000 + } MBB_BAND_CLASS_VALUE; + +typedef +enum _MBB_SMS_CAPS_VALUE + { + MbbSmsCapsNone = 0, + MbbSmsCapsPduReceive = 0x1, + MbbSmsCapsPduSend = 0x2, + MbbSmsCapsTextReceive = 0x4, + MbbSmsCapsTextSend = 0x8 + } MBB_SMS_CAPS_VALUE; + +typedef +enum _MBB_CONTROL_CAPS_VALUE + { + MbbControlCapsNone = 0, + MbbControlCapsRegManual = 0x1, + MbbControlCapsHwRadioSwitch = 0x2, + MbbControlCapsCdmaMobileIp = 0x4, + MbbControlCapsCdmaSimpleIp = 0x8, + MbbControlCapsMultiCarrier = 0x10, + MbbControlCapsESIM = 0x20, + MbbControlCapsUEPolicyRouteSelection = 0x40, + MbbControlCapsSIMHotSwapCapable = 0x80 + } MBB_CONTROL_CAPS_VALUE; + +typedef +enum _MBB_READY_STATE + { + MbbReadyStateOff = 0, + MbbReadyStateInitialized = 1, + MbbReadyStateSimNotInserted = 2, + MbbReadyStateBadSim = 3, + MbbReadyStateFailure = 4, + MbbReadyStateNotActivated = 5, + MbbReadyStateDeviceLocked = 6, + MbbReadyStateNoEsimProfile = 7, + MbbReadyStateMaximum = ( MbbReadyStateNoEsimProfile + 1 ) + } MBB_READY_STATE; + +typedef +enum _MBB_READY_INFO_FLAGS + { + MbbReadyInfoFlagsNone = 0, + MbbReadyInfoFlagsUniqueId = 1 + } MBB_READY_INFO_FLAGS; + +typedef +enum _MBB_EMERGENCY_MODE + { + MbbEmergencyModeOff = 0, + MbbEmergencyModeOn = 1, + MbbEmergencyModeMaximum = ( MbbEmergencyModeOn + 1 ) + } MBB_EMERGENCY_MODE; + +typedef +enum _MBB_RADIO_STATE + { + MbbRadioStateOff = 0, + MbbRadioStateOn = 1, + MbbRadioStateMaximum = ( MbbRadioStateOn + 1 ) + } MBB_RADIO_STATE; + +typedef +enum _MBB_PIN_TYPE + { + MbbPinTypeNone = 0, + MbbPinTypeCustom = 1, + MbbPinTypePin1 = 2, + MbbPinTypePin2 = 3, + MbbPinTypeDeviceSimPin = 4, + MbbPinTypeDeviceFirstSimPin = 5, + MbbPinTypeNetworkPin = 6, + MbbPinTypeNetworkSubsetPin = 7, + MbbPinTypeSvcProviderPin = 8, + MbbPinTypeCorporatePin = 9, + MbbPinTypeSubsidyLock = 10, + MbbPinTypePuk1 = 11, + MbbPinTypePuk2 = 12, + MbbPinTypeDeviceFirstSimPuk = 13, + MbbPinTypeNetworkPuk = 14, + MbbPinTypeNetworkSubsetPuk = 15, + MbbPinTypeSvcProviderPuk = 16, + MbbPinTypeCorporatePuk = 17, + MbbPinTypeNev = 18, + MbbPinTypeAdm = 19, + MbbPinTypeMaximum = ( MbbPinTypeAdm + 1 ) + } MBB_PIN_TYPE; + +typedef +enum _MBB_PIN_STATE + { + MbbPinStateUnlocked = 0, + MbbPinStateLocked = 1, + MbbPinStateMaximum = ( MbbPinStateLocked + 1 ) + } MBB_PIN_STATE; + +typedef +enum _MBB_PIN_OPERATION + { + MbbPinOperationEnter = 0, + MbbPinOperationEnable = 1, + MbbPinOperationDisable = 2, + MbbPinOperationChange = 3, + MbbPinOperationMaximum = ( MbbPinOperationChange + 1 ) + } MBB_PIN_OPERATION; + +typedef +enum _MBB_PIN_MODE + { + MbbPinModeNotSupported = 0, + MbbPinModeEnabled = 1, + MbbPinModeDisabled = 2, + MbbPinModeMaximum = ( MbbPinModeDisabled + 1 ) + } MBB_PIN_MODE; + +typedef +enum _MBB_PIN_FORMAT + { + MbbPinFormatUnknown = 0, + MbbPinFormatNumeric = 1, + MbbPinFormatAlphaNumeric = 2, + MbbPinFormatMaximum = ( MbbPinFormatAlphaNumeric + 1 ) + } MBB_PIN_FORMAT; + +typedef +enum _MBB_PROVIDER_STATE_VALUE + { + MbbProviderStateHome = 0x1, + MbbProviderStateForbidden = 0x2, + MbbProviderStatePreferred = 0x4, + MbbProviderStateVisible = 0x8, + MbbProviderStateRegistered = 0x10, + MbbProviderStatePreferredMulticarrier = 0x20 + } MBB_PROVIDER_STATE_VALUE; + +typedef +enum _MBB_REGISTER_ACTION + { + MbbRegisterActionAutomatic = 0, + MbbRegisterActionManual = 1, + MbbRegisterActionMaximum = ( MbbRegisterActionManual + 1 ) + } MBB_REGISTER_ACTION; + +typedef +enum _MBB_REGISTER_STATE + { + MbbRegisterStateUnknown = 0, + MbbRegisterStateDeregistered = 1, + MbbRegisterStateSearching = 2, + MbbRegisterStateHome = 3, + MbbRegisterStateRoaming = 4, + MbbRegisterStatePartner = 5, + MbbRegisterStateDenied = 6, + MbbRegisterStateMaximum = ( MbbRegisterStateDenied + 1 ) + } MBB_REGISTER_STATE; + +typedef +enum _MBB_REGISTER_MODE + { + MbbRegisterModeUnknown = 0, + MbbRegisterModeAutomatic = 1, + MbbRegisterModeManual = 2, + MbbRegisterModeMaximum = ( MbbRegisterModeManual + 1 ) + } MBB_REGISTER_MODE; + +typedef +enum _MBB_PACKET_SERVICE_ACTION + { + MbbPacketServiceActionAttach = 0, + MbbPacketServiceActionDetach = 1, + MbbPacketServiceActionMaximum = ( MbbPacketServiceActionDetach + 1 ) + } MBB_PACKET_SERVICE_ACTION; + +typedef +enum _MBB_PACKET_SERVICE_STATE + { + MbbPacketServiceStateUnknown = 0, + MbbPacketServiceStateAttaching = 1, + MbbPacketServiceStateAttached = 2, + MbbPacketServiceStateDetaching = 3, + MbbPacketServiceStateDetached = 4, + MbbPacketServiceStateMaximum = ( MbbPacketServiceStateDetached + 1 ) + } MBB_PACKET_SERVICE_STATE; + +typedef +enum _MBB_CONTEXT_IP_TYPE + { + MbbContextIPTypeDefault = 0, + MbbContextIPTypeIPv4 = 1, + MbbContextIPTypeIPv6 = 2, + MbbContextIPTypeIPv4v6 = 3, + MbbContextIPTypeIPv4AndIPv6 = 4, + MbbContextIPTypeMaximum = ( MbbContextIPTypeIPv4AndIPv6 + 1 ) + } MBB_CONTEXT_IP_TYPE; + +typedef +enum _MBB_ACTIVATION_COMMAND + { + MbbActivationCommandDeactivate = 0, + MbbActivationCommandActivate = 1, + MbbActivationCommandCancel = 2, + MbbActivationCommandMaximum = ( MbbActivationCommandCancel + 1 ) + } MBB_ACTIVATION_COMMAND; + +typedef +enum _MBB_COMPRESSION + { + MbbCompressionNone = 0, + MbbCompressionEnable = 1, + MbbCompressionMaximum = ( MbbCompressionEnable + 1 ) + } MBB_COMPRESSION; + +typedef +enum _MBB_AUTH_PROTOCOL + { + MbbAuthProtocolNone = 0, + MbbAuthProtocolPap = 1, + MbbAuthProtocolChap = 2, + MbbAuthProtocolMsChapV2 = 3, + MbbAuthProtocolMaximum = ( MbbAuthProtocolMsChapV2 + 1 ) + } MBB_AUTH_PROTOCOL; + +typedef +enum _MBB_ACTIVATION_STATE + { + MbbActivationStateUnknown = 0, + MbbActivationStateActivated = 1, + MbbActivationStateActivating = 2, + MbbActivationStateDeactivated = 3, + MbbActivationStateDeactivating = 4, + MbbActivationStateMaximum = ( MbbActivationStateDeactivating + 1 ) + } MBB_ACTIVATION_STATE; + +typedef +enum _MBB_VOICE_CALL_STATE + { + MbbVoiceCallStateNone = 0, + MbbVoiceCallStateInProgress = 1, + MbbVoiceCallStateHangUp = 2, + MbbVoiceCallStateMaximum = ( MbbVoiceCallStateHangUp + 1 ) + } MBB_VOICE_CALL_STATE; + +typedef +enum _MBB_SMS_FORMAT + { + MbbSmsFormatPdu = 0, + MbbSmsFormatCdma = 1, + MbbSmsFormatMaximum = ( MbbSmsFormatCdma + 1 ) + } MBB_SMS_FORMAT; + +typedef +enum _MBB_SMS_FLAG + { + MbbSmsFlagAll = 0, + MbbSmsFlagIndex = 1, + MbbSmsFlagNew = 2, + MbbSmsFlagOld = 3, + MbbSmsFlagSent = 4, + MbbSmsFlagDraft = 5, + MbbSmsFlagMaximum = ( MbbSmsFlagDraft + 1 ) + } MBB_SMS_FLAG; + +typedef +enum _MBB_SMS_CDMA_LANGUAGE + { + MbbSmsCdmaLanguageUnknown = 0, + MbbSmsCdmaLanguageEnglish = 1, + MbbSmsCdmaLanguageFrench = 2, + MbbSmsCdmaLanguageSpanish = 3, + MbbSmsCdmaLanguageJapanese = 4, + MbbSmsCdmaLanguageKorean = 5, + MbbSmsCdmaLanguageChinese = 6, + MbbSmsCdmaLanguageHebrew = 7, + MbbSmsCdmaLanguageMaximum = ( MbbSmsCdmaLanguageHebrew + 1 ) + } MBB_SMS_CDMA_LANGUAGE; + +typedef +enum _MBB_SMS_CDMA_ENCODING + { + MbbSmsCdmaEncodingOctet = 0, + MbbSmsCdmaEncodingEpm = 1, + MbbSmsCdmaEncoding7BitAscii = 2, + MbbSmsCdmaEncodingIa5 = 3, + MbbSmsCdmaEncodingUnicode = 4, + MbbSmsCdmaEncodingShiftJis = 5, + MbbSmsCdmaEncodingKorean = 6, + MbbSmsCdmaEncodingLatinHebrew = 7, + MbbSmsCdmaEncodingLatin = 8, + MbbSmsCdmaEncodingGsm7Bit = 9, + MbbSmsCdmaEncodingMaximum = ( MbbSmsCdmaEncodingGsm7Bit + 1 ) + } MBB_SMS_CDMA_ENCODING; + +typedef +enum _MBB_SMS_MESSAGE_STATUS + { + MbbSmsMessageStatusNew = 0, + MbbSmsMessageStatusOld = 1, + MbbSmsMessageStatusDraft = 2, + MbbSmsMessageStatusSent = 3, + MbbSmsMessageStatusMaximum = ( MbbSmsMessageStatusSent + 1 ) + } MBB_SMS_MESSAGE_STATUS; + +typedef +enum _MBB_REG_FLAGS_VALUE + { + MbbRegFlagsNone = 0, + MbbRegFlagsNoManualReg = 0x1, + MbbRegFlagsPSAutoAttach = 0x2 + } MBB_REG_FLAGS_VALUE; + +typedef +enum _MBB_SMS_STATUS_FLAGS_VALUE + { + MbbSmsFlagNone = 0, + MbbSmsFlagMessageStoreFull = 1, + MbbSmsFlagNewMessage = 2 + } MBB_SMS_STATUS_FLAGS_VALUE; + +typedef struct _MBB_STRING + { + ULONG Offset; + ULONG Size; + } MBB_STRING; + +typedef struct _MBB_STRING *PMBB_STRING; + +typedef struct _MBB_ARRAY_ELEMENT + { + ULONG Offset; + ULONG Size; + } MBB_ARRAY_ELEMENT; + +typedef struct _MBB_ARRAY_ELEMENT *PMBB_ARRAY_ELEMENT; + +typedef struct _MBB_ARRAY_ELEMENT2 + { + ULONG Size; + ULONG Offset; + } MBB_ARRAY_ELEMENT2; + +typedef struct _MBB_ARRAY_ELEMENT2 *PMBB_ARRAY_ELEMENT2; + +typedef +enum _MBB_DSS_PAYLOAD_SUPPORT + { + MbbDssPayloadNone = 0, + MbbDssPayloadHostToDevice = 0x1, + MbbDssPayloadDeviceToHost = 0x2 + } MBB_DSS_PAYLOAD_SUPPORT; + +typedef +enum _MBB_DSS_LINK_STATE + { + MbbDssLinkDeactivate = 0, + MbbDssLinkActivate = 0x1 + } MBB_DSS_LINK_STATE; + +typedef +enum _MBB_IP_CONFIGURATION_FLAGS_VALUE + { + MbbIpFlagsNone = 0, + MbbIpFlagsAddressAvailable = 0x1, + MbbIpFlagsGatewayAvailable = 0x2, + MbbIpFlagsDnsServerAvailable = 0x4, + MbbIpFlagsMTUAvailable = 0x8 + } MBB_IP_CONFIGURATION_FLAGS_VALUE; + +typedef +enum _MBB_NETWORK_IDLE_HINT_STATE + { + MbbNetworkIdleHintDisabled = 0, + MbbNetworkIdleHintEnabled = 1 + } MBB_NETWORK_IDLE_HINT_STATE; + +typedef +enum _MBB_SAR_BACKOFF_STATE + { + MbbSarBackoffStatusDisabled = 0, + MbbSarBackoffStatusEnabled = 1, + MbbSarBackoffStatusMaximum = ( MbbSarBackoffStatusEnabled + 1 ) + } MBB_SAR_BACKOFF_STATE; + +typedef +enum _MBB_SAR_CONTROL_MODE + { + MbbSarControlModeDevice = 0, + MbbSarControlModeOS = 1, + MbbSarControlModeMaximum = ( MbbSarControlModeOS + 1 ) + } MBB_SAR_CONTROL_MODE; + +typedef +enum _MBB_SAR_WIFI_HARDWARE_INTEGRATION + { + MbbSarWifiHardwareNotIntegrated = 0, + MbbSarWifiHardwareIntegrated = 1, + MbbSarWifiHardwareIntegrationMaximum = ( MbbSarWifiHardwareIntegrated + 1 ) + } MBB_SAR_WIFI_HARDWARE_INTEGRATION; + +typedef +enum _MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE + { + MbbTransmissionNotificationDisabled = 0, + MbbTransmissionNotificationEnabled = 1, + MbbTransmissionNotificationMaximum = ( MbbTransmissionNotificationEnabled + 1 ) + } MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE; + +typedef +enum _MBB_SAR_TRANSMISSION_STATUS + { + MbbTransmissionStateInactive = 0, + MbbTransmissionStateActive = 1, + MbbTransmissionStateMaximum = ( MbbTransmissionStateActive + 1 ) + } MBB_SAR_TRANSMISSION_STATUS; + +typedef +enum _MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL + { + MbbMsContextRoamingControlHomeOnly = 0, + MbbMsContextRoamingControlPartnerOnly = 1, + MbbMsContextRoamingControlNonPartnerOnly = 2, + MbbMsContextRoamingControlHomeAndPartner = 3, + MbbMsContextRoamingControlHomeAndNonPartner = 4, + MbbMsContextRoamingControlPartnerAndNonPartner = 5, + MbbMsContextRoamingControlAllowAll = 6, + MbbMsContextRoamingControlMaximum = ( MbbMsContextRoamingControlAllowAll + 1 ) + } MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL; + +typedef +enum _MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE + { + MbbMsContextMediaTypeCellularOnly = 0, + MbbMsContextMediaTypeWifiOnly = 1, + MbbMsContextMediaTypeAll = 2, + MbbMsContextMediaTypeMaximum = ( MbbMsContextMediaTypeAll + 1 ) + } MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE; + +typedef +enum _MBB_BASICCONNECTEXT_CONTEXT_ENABLE + { + MbbMsContextDisabled = 0, + MbbMsContextEnabled = 1, + MbbMsContextEnableMaximum = ( MbbMsContextEnabled + 1 ) + } MBB_BASICCONNECTEXT_CONTEXT_ENABLE; + +typedef +enum _MBB_BASICCONNECTEXT_CONTEXT_SOURCE + { + MbbMsContextSourceAdmin = 0, + MbbMsContextSourceUser = 1, + MbbMsContextSourceOperator = 2, + MbbMsContextSourceModem = 3, + MbbMsContextSourceDevice = 4, + MbbMsContextSourceMaximum = ( MbbMsContextSourceDevice + 1 ) + } MBB_BASICCONNECTEXT_CONTEXT_SOURCE; + +typedef +enum _MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS + { + MbbMsContextOperationDefault = 0, + MbbMsContextOperationDelete = 1, + MbbMsContextOperationRestoreFactory = 2, + MbbMsContextOperationMaximum = ( MbbMsContextOperationRestoreFactory + 1 ) + } MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS; + +typedef +enum _MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE + { + MbbMsNetworkBlacklistStateNotActuated = 0, + MbbMsNetworkBlacklistSIMProviderActuated = 1, + MbbMsNetworkBlacklistNetworkProviderActuated = 2, + MbbMsNetworkBlacklistStateMaximum = ( MbbMsNetworkBlacklistNetworkProviderActuated + 1 ) + } MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE; + +typedef +enum _MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE + { + MbbMsNetworkBlacklistTypeSIM = 0, + MbbMsNetworkBlacklistTypeNetwork = 1, + MbbMsNetworkBlacklistTypeMaximum = ( MbbMsNetworkBlacklistTypeNetwork + 1 ) + } MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE; + +typedef +enum _MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL + { + MbbMsLteAttachContextRoamingControlHome = 0, + MbbMsLteAttachContextRoamingControlPartner = 1, + MbbMsLteAttachContextRoamingControlNonPartner = 2, + MbbMsLteAttachContextRoamingControlMaximum = ( MbbMsLteAttachContextRoamingControlNonPartner + 1 ) + } MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL; + +typedef +enum _MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS + { + MbbMsLteAttachContextOperationDefault = 0, + MbbMsLteAttachContextOperationRestoreFactory = 1, + MbbMsLteAttachContextOperationMaximum = ( MbbMsLteAttachContextOperationRestoreFactory + 1 ) + } MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS; + +typedef +enum _MBB_BASICCONNECTEXT_LTEATTACH_STATE + { + MbbMsLteAttachStateDetached = 0, + MbbMsLteAttachStateAttached = 1, + MbbMsLteAttachStateMaximum = ( MbbMsLteAttachStateAttached + 1 ) + } MBB_BASICCONNECTEXT_LTEATTACH_STATE; + +typedef +enum _MBB_BASICCONNECTEXT_UICCSLOT_STATE + { + MbbMsUiccSlotStateUnknown = 0, + MbbMsUiccSlotStateOffEmpty = 1, + MbbMsUiccSlotStateOff = 2, + MbbMsUiccSlotStateEmpty = 3, + MbbMsUiccSlotStateNotReady = 4, + MbbMsUiccSlotStateActive = 5, + MbbMsUiccSlotStateError = 6, + MbbMsUiccSlotStateActiveEsim = 7, + MbbMsUiccSlotStateActiveEsimNoProfiles = 8 + } MBB_BASICCONNECTEXT_UICCSLOT_STATE; + +typedef +enum _MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG + { + MbbMsModemLoggingLevelProd = 0, + MbbMsModemLoggingLevelLabVerbose = 1, + MbbMsModemLoggingLevelLabMedium = 2, + MbbMsModemLoggingLevelLabLow = 3, + MbbMsModemLoggingLevelOem = 4, + MbbMsModemLoggingLevelMaximum = ( MbbMsModemLoggingLevelOem + 1 ) + } MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG; + +typedef +enum _MBB_PCO_TYPE + { + MbbPcoTypeComplete = 0, + MbbPcoTypePartial = 1, + MbbPcoTypeMaximum = ( MbbPcoTypePartial + 1 ) + } MBB_PCO_TYPE; + +typedef struct _MBB_DEVICE_CAPS + { + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + MBB_SIM_CLASS SimClass; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONG dwMaxSessions; + MBB_STRING CustomDataClass; + MBB_STRING DeviceIdString; + MBB_STRING FirmwareInfo; + MBB_STRING HardwareInfo; + UCHAR DataBuffer[ 1 ]; + } MBB_DEVICE_CAPS; + +typedef struct _MBB_DEVICE_CAPS *PMBB_DEVICE_CAPS; + +typedef struct _MBB_SUBSCRIBER_READY_INFO + { + MBB_READY_STATE ReadyState; + MBB_STRING SubscriberId; + MBB_STRING SimIccId; + MBB_READY_INFO_FLAGS ReadyInfoFlags; + ULONG TelephoneNumberCount; + MBB_STRING TelephoneNumbers[ 1 ]; + } MBB_SUBSCRIBER_READY_INFO; + +typedef struct _MBB_SUBSCRIBER_READY_INFO *PMBB_SUBSCRIBER_READY_INFO; + +typedef +enum _MBB_SUBSCRIBER_READY_STATUS_FLAGS + { + MbbSubscriberReadyStatusFlagNone = 0, + MbbSubscriberReadyStatusFlagESim = 0x1, + MbbSubscriberReadyStatusFlagSIMRemovabilityKnown = 0x2, + MbbSubscriberReadyStatusFlagSIMRemovable = 0x4 + } MBB_SUBSCRIBER_READY_STATUS_FLAGS; + +typedef struct _MBB_SUBSCRIBER_READY_INFO_EX3 + { + MBB_READY_STATE ReadyState; + MBB_SUBSCRIBER_READY_STATUS_FLAGS StatusFlags; + MBB_STRING SubscriberId; + MBB_STRING SimIccId; + MBB_READY_INFO_FLAGS ReadyInfoFlags; + ULONG TelephoneNumberCount; + MBB_STRING TelephoneNumbers[ 1 ]; + } MBB_SUBSCRIBER_READY_INFO_EX3; + +typedef struct _MBB_SUBSCRIBER_READY_INFO_EX3 *PMBB_SUBSCRIBER_READY_INFO_EX3; + +typedef struct _MBB_QUERY_RADIO_STATE + { + MBB_RADIO_STATE HwRadioState; + MBB_RADIO_STATE SwRadioState; + } MBB_QUERY_RADIO_STATE; + +typedef struct _MBB_QUERY_RADIO_STATE *PMBB_QUERY_RADIO_STATE; + +typedef struct _MBB_PIN_INFO + { + MBB_PIN_TYPE PinType; + MBB_PIN_STATE PinState; + ULONG AttemptsRemaining; + } MBB_PIN_INFO; + +typedef struct _MBB_PIN_INFO *PMBB_PIN_INFO; + +typedef struct _MBB_PIN_ACTION + { + MBB_PIN_TYPE PinType; + MBB_PIN_OPERATION PinOperation; + MBB_STRING Pin; + MBB_STRING NewPin; + UCHAR DataBuffer[ 1 ]; + } MBB_PIN_ACTION; + +typedef struct _MBB_PIN_ACTION *PMBB_PIN_ACTION; + +typedef struct _MBB_PIN_DESCRIPTION + { + MBB_PIN_MODE PinMode; + MBB_PIN_FORMAT PinFormat; + ULONG PinLengthMin; + ULONG PinLengthMax; + } MBB_PIN_DESCRIPTION; + +typedef struct _MBB_PIN_DESCRIPTION *PMBB_PIN_DESCRIPTION; + +typedef struct _MBB_PIN_LIST + { + MBB_PIN_DESCRIPTION PinDescPin1; + MBB_PIN_DESCRIPTION PinDescPin2; + MBB_PIN_DESCRIPTION PinDescDeviceSimPin; + MBB_PIN_DESCRIPTION PinDescDeviceFirstSimPin; + MBB_PIN_DESCRIPTION PinDescNetworkPin; + MBB_PIN_DESCRIPTION PinDescNetworkSubsetPin; + MBB_PIN_DESCRIPTION PinDescSvcProviderPin; + MBB_PIN_DESCRIPTION PinDescCorporatePin; + MBB_PIN_DESCRIPTION PinDescSubsidyLock; + MBB_PIN_DESCRIPTION PinDescCustom; + } MBB_PIN_LIST; + +typedef struct _MBB_PIN_LIST *PMBB_PIN_LIST; + +typedef struct _MBB_PROVIDER + { + MBB_STRING ProviderId; + ULONG ProviderState; + MBB_STRING ProviderName; + MBB_CELLULAR_CLASS CellularClass; + ULONG Rssi; + ULONG ErrorRate; + } MBB_PROVIDER; + +typedef struct _MBB_PROVIDER *PMBB_PROVIDER; + +typedef struct _MBB_PROVIDER_LIST + { + ULONG ProviderCount; + MBB_ARRAY_ELEMENT Providers[ 1 ]; + } MBB_PROVIDER_LIST; + +typedef struct _MBB_PROVIDER_LIST *PMBB_PROVIDER_LIST; + +typedef struct _MBB_REGISTRATION_STATE + { + ULONG NetworkError; + MBB_REGISTER_STATE RegisterState; + MBB_REGISTER_MODE RegisterMode; + ULONG AvailableDataClasses; + MBB_CELLULAR_CLASS CurrentCellularClass; + MBB_STRING ProviderId; + MBB_STRING ProviderName; + MBB_STRING RoamingText; + ULONG RegFlags; + UCHAR DataBuffer[ 1 ]; + } MBB_REGISTRATION_STATE; + +typedef struct _MBB_REGISTRATION_STATE *PMBB_REGISTRATION_STATE; + +typedef struct _MBB_SET_REGISTER_STATE + { + MBB_STRING ProviderId; + MBB_REGISTER_ACTION RegisterAction; + ULONG DataClass; + UCHAR DataBuffer[ 1 ]; + } MBB_SET_REGISTER_STATE; + +typedef struct _MBB_SET_REGISTER_STATE *PMBB_SET_REGISTER_STATE; + +typedef struct _MBB_SET_PACKET_SERVICE + { + MBB_PACKET_SERVICE_ACTION PacketServiceAction; + } MBB_SET_PACKET_SERVICE; + +typedef struct _MBB_SET_PACKET_SERVICE *PMBB_SET_PACKET_SERVICE; + +typedef struct _MBB_PACKET_SERVICE + { + ULONG NetworkError; + MBB_PACKET_SERVICE_STATE PacketServiceState; + ULONG HighestAvailableDataClass; + ULONGLONG UplinkSpeed; + ULONGLONG DownlinkSpeed; + } MBB_PACKET_SERVICE; + +typedef struct _MBB_PACKET_SERVICE *PMBB_PACKET_SERVICE; + +typedef struct _MBB_PACKET_SERVICE_INFO_V2 + { + ULONG NetworkError; + MBB_PACKET_SERVICE_STATE PacketServiceState; + MBB_DATA_CLASS_VALUE CurrentDataClass; + ULONGLONG UplinkSpeed; + ULONGLONG DownlinkSpeed; + MBB_FREQUENCY_RANGE FrequencyRange; + } MBB_PACKET_SERVICE_INFO_V2; + +typedef struct _MBB_PACKET_SERVICE_INFO_V2 *PMBB_PACKET_SERVICE_INFO_V2; + +typedef struct _MBB_PLMN + { + USHORT Mcc; + USHORT Mnc; + } MBB_PLMN; + +typedef struct _MBB_PLMN *PMBB_PLMN; + +typedef struct _MBB_TAI + { + MBB_PLMN Plmn; + ULONG Tac; + } MBB_TAI; + +typedef struct _MBB_TAI *PMBB_TAI; + +typedef struct _MBB_PACKET_SERVICE_INFO_V3 + { + ULONG NetworkError; + MBB_PACKET_SERVICE_STATE PacketServiceState; + MBB_DATA_CLASS_VALUE CurrentDataClass; + ULONGLONG UplinkSpeed; + ULONGLONG DownlinkSpeed; + MBB_FREQUENCY_RANGE FrequencyRange; + MBB_DATA_SUBCLASS_VALUE CurrentDataSubClass; + MBB_TAI TrackingAreaId; + } MBB_PACKET_SERVICE_INFO_V3; + +typedef struct _MBB_PACKET_SERVICE_INFO_V3 *PMBB_PACKET_SERVICE_INFO_V3; + +typedef struct _MBB_SET_SIGNAL_INDICATION + { + ULONG RssiInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; + } MBB_SET_SIGNAL_INDICATION; + +typedef struct _MBB_SET_SIGNAL_INDICATION *PMBB_SET_SIGNAL_INDICATION; + +typedef struct _MBB_SIGNAL_STATE + { + ULONG Rssi; + ULONG ErrorRate; + ULONG RssiInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; + } MBB_SIGNAL_STATE; + +typedef struct _MBB_SIGNAL_STATE *PMBB_SIGNAL_STATE; + +typedef struct _MBB_SET_CONTEXT_STATE + { + ULONG SessionId; + MBB_ACTIVATION_COMMAND ActivationCommand; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + MBB_CONTEXT_IP_TYPE IPType; + GUID ContextType; + CHAR DataBuffer[ 1 ]; + } MBB_SET_CONTEXT_STATE; + +typedef struct _MBB_SET_CONTEXT_STATE *PMBB_SET_CONTEXT_STATE; + +typedef +enum _MBB_ACCESS_MEDIA_PREF + { + MbbAccessMediaPrefNone = 0, + MbbAccessMediaPref3GPP = 1, + MbbAccessMediaPref3GPPPreferred = 2, + MbbAccessMediaPrefMaximum = ( MbbAccessMediaPref3GPPPreferred + 1 ) + } MBB_ACCESS_MEDIA_PREF; + +typedef struct _MBB_SET_CONTEXT_STATE_EX3 + { + ULONG SessionId; + MBB_ACTIVATION_COMMAND ActivationCommand; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + MBB_CONTEXT_IP_TYPE IPType; + GUID ContextType; + MBB_ACCESS_MEDIA_PREF MediaPreference; + } MBB_SET_CONTEXT_STATE_EX3; + +typedef struct _MBB_SET_CONTEXT_STATE_EX3 *PMBB_SET_CONTEXT_STATE_EX3; + +typedef struct _MBB_QUERY_CONTEXT_EX3 + { + ULONG SessionId; + } MBB_QUERY_CONTEXT_EX3; + +typedef struct _MBB_QUERY_CONTEXT_EX3 *PMBB_QUERY_CONTEXT_EX3; + +typedef struct _MBB_CONTEXT_STATE + { + ULONG SessionId; + MBB_ACTIVATION_STATE ActivationState; + MBB_VOICE_CALL_STATE VoiceCallState; + MBB_CONTEXT_IP_TYPE IPType; + GUID ContextType; + ULONG NetworkError; + } MBB_CONTEXT_STATE; + +typedef struct _MBB_CONTEXT_STATE *PMBB_CONTEXT_STATE; + +typedef struct _MBB_CONTEXT_STATE_EX3 + { + ULONG SessionId; + MBB_ACTIVATION_STATE ActivationState; + MBB_VOICE_CALL_STATE VoiceCallState; + MBB_CONTEXT_IP_TYPE IPType; + GUID ContextType; + ULONG NetworkError; + MBB_ACCESS_MEDIA_PREF MediaPreference; + } MBB_CONTEXT_STATE_EX3; + +typedef struct _MBB_CONTEXT_STATE_EX3 *PMBB_CONTEXT_STATE_EX3; + +typedef struct _MBB_SET_CONTEXT + { + ULONG ContextId; + GUID ContextType; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + MBB_STRING ProviderId; + UCHAR DataBuffer[ 1 ]; + } MBB_SET_CONTEXT; + +typedef struct _MBB_SET_CONTEXT *PMBB_SET_CONTEXT; + +typedef struct _MBB_CONTEXT + { + ULONG ContextId; + GUID ContextType; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[ 1 ]; + } MBB_CONTEXT; + +typedef struct _MBB_CONTEXT *PMBB_CONTEXT; + +typedef struct _MBB_CONTEXT_LIST + { + ULONG ContextCount; + MBB_ARRAY_ELEMENT Contexts[ 1 ]; + } MBB_CONTEXT_LIST; + +typedef struct _MBB_CONTEXT_LIST *PMBB_CONTEXT_LIST; + +typedef struct _MBB_SERVICE_ACTIVATION + { + CHAR VendorSpecificBuffer[ 1 ]; + } MBB_SERVICE_ACTIVATION; + +typedef struct _MBB_SERVICE_ACTIVATION *PMBB_SERVICE_ACTIVATION; + +typedef struct _MBB_SERVICE_ACTIVATION_STATUS + { + ULONG NetworkError; + CHAR VendorSpecificBuffer[ 1 ]; + } MBB_SERVICE_ACTIVATION_STATUS; + +typedef struct _MBB_SERVICE_ACTIVATION_STATUS *PMBB_SERVICE_ACTIVATION_STATUS; + +typedef struct _MBB_IPV4_ADDRESS + { + ULONG OnLinkPrefixLength; + UCHAR IPV4Address[ 4 ]; + } MBB_IPV4_ADDRESS; + +typedef struct _MBB_IPV4_ADDRESS *PMBB_IPV4_ADDRESS; + +typedef struct _MBB_IPV6_ADDRESS + { + ULONG OnLinkPrefixLength; + UCHAR IPV6Address[ 16 ]; + } MBB_IPV6_ADDRESS; + +typedef struct _MBB_IPV6_ADDRESS *PMBB_IPV6_ADDRESS; + +typedef struct _MBB_IP_ADDRESS_INFO + { + ULONG SessionId; + ULONG IPv4Flags; + ULONG IPv6Flags; + ULONG IPv4AddressCount; + ULONG IPv4AddressOffset; + ULONG IPv6AddressCount; + ULONG IPv6AddressOffset; + ULONG IPv4GatewayOffset; + ULONG IPv6GatewayOffset; + ULONG IPv4DnsServerCount; + ULONG IPv4DnsServerOffset; + ULONG IPv6DnsServerCount; + ULONG IPv6DnsServerOffset; + ULONG IPv4MTU; + ULONG IPv6MTU; + } MBB_IP_ADDRESS_INFO; + +typedef struct _MBB_IP_ADDRESS_INFO *PMBB_IP_ADDRESS_INFO; + +typedef struct _MBB_PACKET_STATISTICS + { + ULONG InDiscards; + ULONG InErrors; + ULONGLONG InOctets; + ULONGLONG InPackets; + ULONGLONG OutOctets; + ULONGLONG OutPackets; + ULONG OutErrors; + ULONG OutDiscards; + } MBB_PACKET_STATISTICS; + +typedef struct _MBB_PACKET_STATISTICS *PMBB_PACKET_STATISTICS; + +typedef +enum _MBB_VISIBLE_PROVIDERS_ACTION_VALUE + { + MbbVisibleProvidersActionFull = 0, + MbbVisibleProvidersActionMulticarrier = 0x1, + MbbVisibleProvidersActionMax = ( MbbVisibleProvidersActionMulticarrier + 1 ) + } MBB_VISIBLE_PROVIDERS_ACTION_VALUE; + +typedef struct _MBB_GET_VISIBLE_PROVIDERS + { + ULONG Action; + } MBB_GET_VISIBLE_PROVIDERS; + +typedef struct _MBB_GET_VISIBLE_PROVIDERS *PMBB_GET_VISIBLE_PROVIDERS; + +typedef +enum _MBB_SMS_STORAGE_STATE + { + MbbSmsStorageNotInitialized = 0, + MbbSmsStorageInitialized = 1 + } MBB_SMS_STORAGE_STATE; + +typedef struct _MBB_SET_SMS_CONFIGURATION + { + MBB_SMS_FORMAT SmsFormat; + MBB_STRING ScAddress; + UCHAR DataBuffer[ 1 ]; + } MBB_SET_SMS_CONFIGURATION; + +typedef struct _MBB_SET_SMS_CONFIGURATION *PMBB_SET_SMS_CONFIGURATION; + +typedef struct _MBB_SMS_CONFIGURATION + { + MBB_SMS_STORAGE_STATE SmsStorageState; + MBB_SMS_FORMAT SmsFormat; + ULONG MaxMessages; + ULONG CdmaShortMessageSize; + MBB_STRING ScAddress; + UCHAR DataBuffer[ 1 ]; + } MBB_SMS_CONFIGURATION; + +typedef struct _MBB_SMS_CONFIGURATION *PMBB_SMS_CONFIGURATION; + +typedef struct _MBB_SMS_READ + { + MBB_SMS_FORMAT SmsFormat; + MBB_SMS_FLAG SmsFlag; + ULONG MessageIndex; + } MBB_SMS_READ; + +typedef struct _MBB_SMS_READ *PMBB_SMS_READ; + +typedef struct _MBB_SMS_CDMA_RECORD + { + ULONG MessageIndex; + MBB_SMS_MESSAGE_STATUS MessageStatus; + MBB_STRING Address; + MBB_STRING TimeStamp; + MBB_SMS_CDMA_ENCODING EncodingId; + MBB_SMS_CDMA_LANGUAGE LanguageId; + MBB_ARRAY_ELEMENT EncodedMessage; + ULONG SizeInCharacters; + UCHAR DataBuffer[ 1 ]; + } MBB_SMS_CDMA_RECORD; + +typedef struct _MBB_SMS_CDMA_RECORD *PMBB_SMS_CDMA_RECORD; + +typedef struct _MBB_SMS_PDU_RECORD + { + ULONG MessageIndex; + MBB_SMS_MESSAGE_STATUS MessageStatus; + MBB_ARRAY_ELEMENT PduData; + UCHAR DataBuffer[ 1 ]; + } MBB_SMS_PDU_RECORD; + +typedef struct _MBB_SMS_PDU_RECORD *PMBB_SMS_PDU_RECORD; + +typedef struct _MBB_SMS_RECEIVE + { + MBB_SMS_FORMAT SmsFormat; + ULONG MessageCount; + MBB_ARRAY_ELEMENT MessageElement[ 1 ]; + } MBB_SMS_RECEIVE; + +typedef struct _MBB_SMS_RECEIVE *PMBB_SMS_RECEIVE; + +typedef struct _MBB_SMS_SEND_PDU + { + MBB_ARRAY_ELEMENT PduData; + UCHAR DataBuffer[ 1 ]; + } MBB_SMS_SEND_PDU; + +typedef struct _MBB_SMS_SEND_PDU *PMBB_SMS_SEND_PDU; + +typedef struct _MBB_SMS_SEND_CDMA + { + MBB_SMS_CDMA_ENCODING EncodingId; + MBB_SMS_CDMA_LANGUAGE LanguageId; + MBB_STRING Address; + MBB_ARRAY_ELEMENT EncodedMessage; + ULONG SizeInCharacters; + UCHAR DataBuffer[ 1 ]; + } MBB_SMS_SEND_CDMA; + +typedef struct _MBB_SMS_SEND_CDMA *PMBB_SMS_SEND_CDMA; + +typedef struct _MBB_SMS_SEND + { + MBB_SMS_FORMAT SmsFormat; + /* [switch_is] */ /* [switch_type] */ union __MIDL___MIDL_itf_MbbMessages_0000_0000_0001 + { + /* [case()] */ MBB_SMS_SEND_PDU Pdu; + /* [case()] */ MBB_SMS_SEND_CDMA Cdma; + } u; + } MBB_SMS_SEND; + +typedef struct _MBB_SMS_SEND *PMBB_SMS_SEND; + +typedef struct _MBB_SMS_SEND_STATUS + { + ULONG MessageReference; + } MBB_SMS_SEND_STATUS; + +typedef struct _MBB_SMS_SEND_STATUS *PMBB_SMS_SEND_STATUS; + +typedef struct _MBB_SMS_DELETE + { + MBB_SMS_FLAG SmsFlags; + ULONG MessageIndex; + } MBB_SMS_DELETE; + +typedef struct _MBB_SMS_DELETE *PMBB_SMS_DELETE; + +typedef struct _MBB_SMS_STATUS + { + ULONG StatusFlags; + ULONG MessageIndex; + } MBB_SMS_STATUS; + +typedef struct _MBB_SMS_STATUS *PMBB_SMS_STATUS; + +typedef +enum _MBB_USSD_ACTION + { + MbbUSSDInitiate = 0, + MbbUSSDContinue = 1, + MbbUSSDCancel = 2 + } MBB_USSD_ACTION; + +typedef +enum _MBB_USSD_RESPONSE + { + MbbUSSDNoActionRequired = 0, + MbbUSSDActionRequired = 1, + MbbUSSDTerminated = 2, + MbbUSSDOtherLocalClient = 3, + MbbUSSDOperationNotSupported = 4, + MbbUSSDNetworkTimeOut = 5 + } MBB_USSD_RESPONSE; + +typedef +enum _MBB_USSD_SESSION_STATE + { + MbbUSSDNewSession = 0, + MbbUSSDExistingSession = 1 + } MBB_USSD_SESSION_STATE; + +typedef struct _MBB_SET_USSD + { + MBB_USSD_ACTION USSDAction; + ULONG USSDDataCodingScheme; + MBB_ARRAY_ELEMENT USSDPayload; + UCHAR DataBuffer[ 1 ]; + } MBB_SET_USSD; + +typedef struct _MBB_SET_USSD *PMBB_SET_USSD; + +typedef struct _MBB_USSD + { + MBB_USSD_RESPONSE USSDResponse; + MBB_USSD_SESSION_STATE USSDSessionState; + ULONG USSDDataCodingScheme; + MBB_ARRAY_ELEMENT USSDPayload; + UCHAR DataBuffer[ 1 ]; + } MBB_USSD; + +typedef struct _MBB_USSD *PMBB_USSD; + +typedef struct _MBB_AKA_AUTH_CHALLENGE + { + UCHAR Rand[ 16 ]; + UCHAR Autn[ 16 ]; + } MBB_AKA_AUTH_CHALLENGE; + +typedef struct _MBB_AKA_AUTH_CHALLENGE *PMBB_AKA_AUTH_CHALLENGE; + +typedef struct _MBB_AKA_AUTH_RESPONSE + { + UCHAR Res[ 16 ]; + ULONG ResLength; + UCHAR IK[ 16 ]; + UCHAR CK[ 16 ]; + UCHAR Auts[ 14 ]; + } MBB_AKA_AUTH_RESPONSE; + +typedef struct _MBB_AKA_AUTH_RESPONSE *PMBB_AKA_AUTH_RESPONSE; + +typedef struct _MBB_AKAP_AUTH_CHALLENGE + { + UCHAR Rand[ 16 ]; + UCHAR Autn[ 16 ]; + MBB_STRING NetworkName; + UCHAR DataBuffer[ 1 ]; + } MBB_AKAP_AUTH_CHALLENGE; + +typedef struct _MBB_AKAP_AUTH_CHALLENGE *PMBB_AKAP_AUTH_CHALLENGE; + +typedef struct _MBB_AKAP_AUTH_RESPONSE + { + UCHAR Res[ 16 ]; + ULONG ResLength; + UCHAR IK[ 16 ]; + UCHAR CK[ 16 ]; + UCHAR Auts[ 14 ]; + } MBB_AKAP_AUTH_RESPONSE; + +typedef struct _MBB_AKAP_AUTH_RESPONSE *PMBB_AKAP_AUTH_RESPONSE; + +typedef struct _MBB_SIM_AUTH_CHALLENGE + { + UCHAR Rand1[ 16 ]; + UCHAR Rand2[ 16 ]; + UCHAR Rand3[ 16 ]; + ULONG n; + } MBB_SIM_AUTH_CHALLENGE; + +typedef struct _MBB_SIM_AUTH_CHALLENGE *PMBB_SIM_AUTH_CHALLENGE; + +typedef struct _MBB_SIM_AUTH_RESPONSE + { + UCHAR Sres1[ 4 ]; + UCHAR Kc1[ 8 ]; + UCHAR Sres2[ 4 ]; + UCHAR Kc2[ 8 ]; + UCHAR Sres3[ 4 ]; + UCHAR Kc3[ 8 ]; + ULONG n; + } MBB_SIM_AUTH_RESPONSE; + +typedef struct _MBB_SIM_AUTH_RESPONSE *PMBB_SIM_AUTH_RESPONSE; + +typedef struct _MBB_PACKET_FILTERS + { + ULONG SessionId; + ULONG PacketFiltersCount; + MBB_ARRAY_ELEMENT ArrayElement[ 1 ]; + } MBB_PACKET_FILTERS; + +typedef struct _MBB_PACKET_FILTERS *PMBB_PACKET_FILTERS; + +typedef struct _MBB_SINGLE_PACKET_FILTER + { + ULONG FilterSize; + ULONG PacketFilterOffset; + ULONG PacketMaskOffset; + UCHAR DataBuffer[ 1 ]; + } MBB_SINGLE_PACKET_FILTER; + +typedef struct _MBB_SINGLE_PACKET_FILTER *PMBB_SINGLE_PACKET_FILTER; + +typedef struct _MBB_SINGLE_PACKET_FILTER_V2 + { + ULONG FilterSize; + ULONG PacketFilterOffset; + ULONG PacketMaskOffset; + ULONG FilterId; + UCHAR DataBuffer[ 1 ]; + } MBB_SINGLE_PACKET_FILTER_V2; + +typedef struct _MBB_SINGLE_PACKET_FILTER_V2 *PMBB_SINGLE_PACKET_FILTER_V2; + +typedef struct _MBB_NETWORK_IDLE_HINT + { + MBB_NETWORK_IDLE_HINT_STATE NetworkIdleHintState; + } MBB_NETWORK_IDLE_HINT; + +typedef struct _MBB_NETWORK_IDLE_HINT *PMBB_NETWORK_IDLE_HINT; + +typedef struct _MBB_DEVICE_SERVICE_ELEMENT + { + GUID DeviceServiceId; + MBB_DSS_PAYLOAD_SUPPORT DSSPayload; + ULONG MaxDSSInstances; + ULONG CIDCount; + ULONG CIDList[ 1 ]; + } MBB_DEVICE_SERVICE_ELEMENT; + +typedef struct _MBB_DEVICE_SERVICE_ELEMENT *PMBB_DEVICE_SERVICE_ELEMENT; + +typedef struct _MBB_DEVICE_SERVICES_HEADER + { + ULONG DeviceServicesCount; + ULONG MaxDSSSessions; + MBB_ARRAY_ELEMENT ArrayElement[ 1 ]; + } MBB_DEVICE_SERVICES_HEADER; + +typedef struct _MBB_DEVICE_SERVICES_HEADER *PMBB_DEVICE_SERVICES_HEADER; + +typedef struct _MBB_SUBSCRIBE_EVENT_ENTRY + { + GUID DeviceServiceId; + ULONG CIDCount; + ULONG CIDList[ 1 ]; + } MBB_SUBSCRIBE_EVENT_ENTRY; + +typedef struct _MBB_SUBSCRIBE_EVENT_ENTRY *PMBB_SUBSCRIBE_EVENT_ENTRY; + +typedef struct _MBB_SUBSCRIBE_EVENT_LIST + { + ULONG Count; + MBB_ARRAY_ELEMENT ArrayElement[ 1 ]; + } MBB_SUBSCRIBE_EVENT_LIST; + +typedef struct _MBB_SUBSCRIBE_EVENT_LIST *PMBB_SUBSCRIBE_EVENT_LIST; + +typedef struct _MBB_SET_DSS_CONNECT + { + GUID DeviceServiceId; + ULONG DssSessionId; + MBB_DSS_LINK_STATE DssLinkState; + } MBB_SET_DSS_CONNECT; + +typedef struct _MBB_SET_DSS_CONNECT *PMBB_SET_DSS_CONNECT; + +typedef struct _MBB_SET_DSS_CLOSE + { + ULONG DssSessionId; + } MBB_SET_DSS_CLOSE; + +typedef struct _MBB_SET_DSS_CLOSE *PMBB_SET_DSS_CLOSE; + +typedef struct _MBB_MULTICARRIER_CURRENT_CID_LIST + { + ULONG CIDCount; + ULONG CIDList[ 1 ]; + } MBB_MULTICARRIER_CURRENT_CID_LIST; + +typedef struct _MBB_MULTICARRIER_CURRENT_CID_LIST *PMBB_MULTICARRIER_CURRENT_CID_LIST; + +typedef +enum _MBB_UICC_APP_TYPE + { + MbbUiccAppTypeUnknown = 0, + MbbUiccAppTypeMf = 1, + MbbUiccAppTypeMfSIM = 2, + MbbUiccAppTypeMfRUIM = 3, + MbbUiccAppTypeUSIM = 4, + MbbUiccAppTypeCSIM = 5, + MbbUiccAppTypeISIM = 6, + MbbUiccAppTypeMax = ( MbbUiccAppTypeISIM + 1 ) + } MBB_UICC_APP_TYPE; + +typedef struct _MBB_UICC_APP_INFO + { + MBB_UICC_APP_TYPE AppType; + MBB_ARRAY_ELEMENT AppId; + MBB_ARRAY_ELEMENT AppName; + ULONG NumPins; + MBB_ARRAY_ELEMENT PinRef; + UCHAR DataBuffer[ 1 ]; + } MBB_UICC_APP_INFO; + +typedef struct _MBB_UICC_APP_INFO *PMBB_UICC_APP_INFO; + +typedef struct _MBB_UICC_APP_LIST + { + ULONG Version; + ULONG AppCount; + ULONG ActiveAppIndex; + ULONG AppListSize; + MBB_ARRAY_ELEMENT DataBuffer[ 1 ]; + } MBB_UICC_APP_LIST; + +typedef struct _MBB_UICC_APP_LIST *PMBB_UICC_APP_LIST; + +typedef +enum _MBB_UICC_FILE_ACCESSIBILITY + { + MbbUiccFileAccessibilityUnknown = 0, + MbbUiccFileAccessibilityNotShareable = 1, + MbbUiccFileAccessibilityShareable = 2, + MbbUiccFileAccessibilityMax = ( MbbUiccFileAccessibilityShareable + 1 ) + } MBB_UICC_FILE_ACCESSIBILITY; + +typedef +enum _MBB_UICC_FILE_TYPE + { + MbbUiccFileTypeUnknown = 0, + MbbUiccFileTypeWorkingEf = 1, + MbbUiccFileTypeInternalEf = 2, + MbbUiccFileTypeDfOrAdf = 3, + MbbUiccFileTypeMax = ( MbbUiccFileTypeDfOrAdf + 1 ) + } MBB_UICC_FILE_TYPE; + +typedef +enum _MBB_UICC_FILE_STRUCTURE + { + MbbUiccFileStructureUnknown = 0, + MbbUiccFileStructureTransparent = 1, + MbbUiccFileStructureCyclic = 2, + MbbUiccFileStructureLinear = 3, + MbbUiccFileStructureBertlv = 4, + MbbUiccFileStructureMax = ( MbbUiccFileStructureBertlv + 1 ) + } MBB_UICC_FILE_STRUCTURE; + +typedef struct _MBB_UICC_FILE_PATH + { + ULONG Version; + MBB_ARRAY_ELEMENT AppId; + MBB_ARRAY_ELEMENT FilePath; + UCHAR DataBuffer[ 1 ]; + } MBB_UICC_FILE_PATH; + +typedef struct _MBB_UICC_FILE_PATH *PMBB_UICC_FILE_PATH; + +typedef struct _MBB_UICC_FILE_STATUS + { + ULONG Version; + ULONG StatusWord1; + ULONG StatusWord2; + MBB_UICC_FILE_ACCESSIBILITY FileAccessibility; + MBB_UICC_FILE_TYPE FileType; + MBB_UICC_FILE_STRUCTURE FileStructure; + ULONG ItemCount; + ULONG ItemSize; + MBB_PIN_TYPE FileLockStatus[ 4 ]; + } MBB_UICC_FILE_STATUS; + +typedef struct _MBB_UICC_FILE_STATUS *PMBB_UICC_FILE_STATUS; + +typedef struct _MBB_UICC_ACCESS_BINARY + { + ULONG Version; + MBB_ARRAY_ELEMENT AppId; + MBB_ARRAY_ELEMENT UiccFilePath; + ULONG FileOffset; + ULONG NumberOfBytes; + MBB_ARRAY_ELEMENT LocalPin; + MBB_ARRAY_ELEMENT BinaryData; + UCHAR DataBuffer[ 1 ]; + } MBB_UICC_ACCESS_BINARY; + +typedef struct _MBB_UICC_ACCESS_BINARY *PMBB_UICC_ACCESS_BINARY; + +typedef struct _MBB_UICC_ACCESS_RECORD + { + ULONG Version; + MBB_ARRAY_ELEMENT AppId; + MBB_ARRAY_ELEMENT UiccFilePath; + ULONG RecordNumber; + MBB_ARRAY_ELEMENT LocalPin; + MBB_ARRAY_ELEMENT RecordData; + UCHAR DataBuffer[ 1 ]; + } MBB_UICC_ACCESS_RECORD; + +typedef struct _MBB_UICC_ACCESS_RECORD *PMBB_UICC_ACCESS_RECORD; + +typedef struct _MBB_UICC_RESPONSE + { + ULONG Version; + ULONG StatusWord1; + ULONG StatusWord2; + MBB_ARRAY_ELEMENT ResponseData; + UCHAR DataBuffer[ 1 ]; + } MBB_UICC_RESPONSE; + +typedef struct _MBB_UICC_RESPONSE *PMBB_UICC_RESPONSE; + +typedef struct _MBB_PIN_APP + { + ULONG Version; + MBB_ARRAY_ELEMENT AppId; + UCHAR DataBuffer[ 1 ]; + } MBB_PIN_APP; + +typedef struct _MBB_PIN_APP *PMBB_PIN_APP; + +typedef struct _MBB_PIN_ACTION_EX2 + { + MBB_PIN_TYPE PinType; + MBB_PIN_OPERATION PinOperation; + MBB_STRING Pin; + MBB_STRING NewPin; + MBB_ARRAY_ELEMENT AppId; + UCHAR DataBuffer[ 1 ]; + } MBB_PIN_ACTION_EX2; + +typedef struct _MBB_PIN_ACTION_EX2 *PMBB_PIN_ACTION_EX2; + +typedef struct _MBB_SYS_CAPS_INFO + { + ULONG NumberOfExecutors; + ULONG NumberOfSlots; + ULONG Concurrency; + } MBB_SYS_CAPS_INFO; + +typedef struct _MBB_SYS_CAPS_INFO *PMBB_SYS_CAPS_INFO; + +typedef struct _MBB_DEVICE_CAPS_V2 + { + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + MBB_SIM_CLASS SimClass; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONG dwMaxSessions; + MBB_STRING CustomDataClass; + MBB_STRING DeviceIdString; + MBB_STRING FirmwareInfo; + MBB_STRING HardwareInfo; + ULONG DeviceIndex; + UCHAR DataBuffer[ 1 ]; + } MBB_DEVICE_CAPS_V2; + +typedef struct _MBB_DEVICE_CAPS_V2 *PMBB_DEVICE_CAPS_V2; + +typedef struct _MBB_DEVICE_SLOT_MAPPING_INFO + { + ULONG MapCount; + MBB_ARRAY_ELEMENT SlotMapList[ 1 ]; + } MBB_DEVICE_SLOT_MAPPING_INFO; + +typedef struct _MBB_DEVICE_SLOT_MAPPING_INFO *PMBB_DEVICE_SLOT_MAPPING_INFO; + +typedef +enum _MBB_UICCSLOT_STATE + { + MbbUiccSlotStateOffEmpty = 0, + MbbUiccSlotStateOff = 1, + MbbUiccSlotStateEmpty = 2, + MbbUiccSlotStateNotReady = 3, + MbbUiccSlotStateActive = 4, + MbbUiccSlotStateError = 5 + } MBB_UICCSLOT_STATE; + +typedef struct _MBB_SLOT_INFO_REQ + { + ULONG SlotIndex; + } MBB_SLOT_INFO_REQ; + +typedef struct _MBB_SLOT_INFO_REQ *PMBB_SLOT_INFO_REQ; + +typedef struct _MBB_SLOT_INFO + { + ULONG SlotIndex; + MBB_UICCSLOT_STATE State; + } MBB_SLOT_INFO; + +typedef struct _MBB_SLOT_INFO *PMBB_SLOT_INFO; + +typedef struct _MBB_DEVICE_BINDINGS_INFO + { + ULONG ApplicationCount; + MBB_ARRAY_ELEMENT ApplicationList[ 1 ]; + } MBB_DEVICE_BINDINGS_INFO; + +typedef struct _MBB_DEVICE_BINDINGS_INFO *PMBB_DEVICE_BINDINGS_INFO; + +typedef +enum _MBB_REGISTRATION_VOICE_CLASS + { + MbbRegistrationVoiceClassVoiceCentric = 0, + MbbRegistrationVoiceClassDataCentric = 1 + } MBB_REGISTRATION_VOICE_CLASS; + +typedef +enum _MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE + { + MbbRegistrationVoiceDomainPreferenceCsOnly = 0, + MbbRegistrationVoiceDomainPreferenceCsPreferred = 1, + MbbRegistrationVoiceDomainPreferenceImsPreferred = 2, + MbbRegistrationVoiceDomainPreferenceImsOnly = 3 + } MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE; + +typedef +enum _MBB_REGISTRATION_VOICE_SUPPORT + { + MbbRegistrationVoiceSupportNone = 0, + MbbRegistrationVoiceSupportIms = 0x1, + MbbRegistrationVoiceSupportEmergencyAttach = 0x2, + MbbRegistrationVoiceSupportCs = 0x4, + MbbRegistrationVoiceSupportCsfb = 0x8, + MbbRegistrationVoiceSupport1xCsfb = 0x10, + MbbRegistrationVoiceSupportCsEmergency = 0x20 + } MBB_REGISTRATION_VOICE_SUPPORT; + +typedef +enum _MBB_REGISTRATION_CDMA_ROAM_MODE + { + MbbRegistrationCdmaRoamModeAutomatic = 0, + MbbRegistrationCdmaRoamModeHomeOnly = 1 + } MBB_REGISTRATION_CDMA_ROAM_MODE; + +typedef struct _MBB_SET_REGISTER_STATE_V2 + { + MBB_STRING ProviderId; + MBB_REGISTER_ACTION RegisterAction; + ULONG DataClass; + MBB_REGISTRATION_VOICE_CLASS VoiceClass; + MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE VoiceDomain; + MBB_REGISTRATION_CDMA_ROAM_MODE CdmaRoamMode; + MBB_ARRAY_ELEMENT AcquisitionOrder[ 1 ]; + } MBB_SET_REGISTER_STATE_V2; + +typedef struct _MBB_SET_REGISTER_STATE_V2 *PMBB_SET_REGISTER_STATE_V2; + +typedef struct _MBB_REGISTRATION_STATE_V2 + { + ULONG NetworkError; + MBB_REGISTER_STATE RegisterState; + MBB_REGISTER_MODE RegisterMode; + ULONG AvailableDataClasses; + MBB_CELLULAR_CLASS CurrentCellularClass; + MBB_STRING ProviderId; + MBB_STRING ProviderName; + MBB_STRING RoamingText; + ULONG RegFlags; + MBB_REGISTRATION_VOICE_SUPPORT VoiceSupport; + ULONG CurrentRATClass; + UCHAR DataBuffer[ 1 ]; + } MBB_REGISTRATION_STATE_V2; + +typedef struct _MBB_REGISTRATION_STATE_V2 *PMBB_REGISTRATION_STATE_V2; + +typedef struct _MBB_REGISTRATION_STATE_INFOS_V2 + { + ULONG ElementCount; + MBB_ARRAY_ELEMENT RegistrationStateList[ 1 ]; + } MBB_REGISTRATION_STATE_INFOS_V2; + +typedef struct _MBB_REGISTRATION_STATE_INFOS_V2 *PMBB_REGISTRATION_STATE_INFOS_V2; + +typedef struct _MBB_REGISTRATION_STATE_INFO_V2 + { + ULONG NetworkError; + MBB_REGISTER_STATE RegisterState; + MBB_REGISTER_MODE RegisterMode; + ULONG AvailableDataClasses; + MBB_CELLULAR_CLASS CurrentCellularClass; + MBB_STRING ProviderId; + MBB_STRING ProviderName; + MBB_STRING RoamingText; + ULONG RegistrationFlag; + ULONG PreferredDataClasses; + UCHAR DataBuffer[ 1 ]; + } MBB_REGISTRATION_STATE_INFO_V2; + +typedef struct _MBB_REGISTRATION_STATE_INFO_V2 *PMBB_REGISTRATION_STATE_INFO_V2; + +typedef +enum _MBB_IMS_VOICE_STATUS + { + MbbImsVoiceStatusUnknown = 0, + MbbImsVoiceStatusUnregistered = 1, + MbbImsVoiceStatusRegistered = 2 + } MBB_IMS_VOICE_STATUS; + +typedef struct _MBB_SET_IMS_VOICE_STATE + { + MBB_IMS_VOICE_STATUS ImsVoiceStatus; + } MBB_SET_IMS_VOICE_STATE; + +typedef struct _MBB_SET_IMS_VOICE_STATE *PMBB_SET_IMS_VOICE_STATE; + +typedef struct _MBB_IMS_VOICE_STATE + { + MBB_IMS_VOICE_STATUS ImsVoiceStatus; + } MBB_IMS_VOICE_STATE; + +typedef struct _MBB_IMS_VOICE_STATE *PMBB_IMS_VOICE_STATE; + +typedef struct _MBB_SET_SIGNAL_INDICATION_V2 + { + ULONG RssiInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; + ULONG SnrThreshold; + } MBB_SET_SIGNAL_INDICATION_V2; + +typedef struct _MBB_SET_SIGNAL_INDICATION_V2 *PMBB_SET_SIGNAL_INDICATION_V2; + +typedef struct _MBB_SIGNAL_STATE_V2 + { + ULONG Rssi; + ULONG ErrorRate; + ULONG RssiInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; + ULONG Snr; + ULONG SnrThreshold; + ULONG DataClass; + } MBB_SIGNAL_STATE_V2; + +typedef struct _MBB_SIGNAL_STATE_V2 *PMBB_SIGNAL_STATE_V2; + +typedef struct _MBB_RSRP_SNR_INFO + { + ULONG RSRP; + ULONG SNR; + ULONG RSRPThreshold; + ULONG SNRThreshold; + MBB_DATA_CLASS_VALUE SystemType; + } MBB_RSRP_SNR_INFO; + +typedef struct _MBB_RSRP_SNR_INFO *PMBB_RSRP_SNR_INFO; + +typedef struct _MBB_RSRP_SNR + { + ULONG ElementCount; + MBB_RSRP_SNR_INFO DataBuffer[ 1 ]; + } MBB_RSRP_SNR; + +typedef struct _MBB_RSRP_SNR *PMBB_RSRP_SNR; + +typedef struct _MBB_SIGNAL_STATE_INFO_V2 + { + ULONG Rssi; + ULONG ErrorRate; + ULONG SignalStrengthInterval; + ULONG RssiThreshold; + ULONG ErrorRateThreshold; + ULONG RsrpSnrOffset; + ULONG RsrpSnrSize; + MBB_RSRP_SNR DataBuffer; + } MBB_SIGNAL_STATE_INFO_V2; + +typedef struct _MBB_SIGNAL_STATE_INFO_V2 *PMBB_SIGNAL_STATE_INFO_V2; + +typedef struct _MBB_SIGNAL_STATE_INFOS_V2 + { + ULONG ElementCount; + MBB_ARRAY_ELEMENT SignalStateList[ 1 ]; + } MBB_SIGNAL_STATE_INFOS_V2; + +typedef struct _MBB_SIGNAL_STATE_INFOS_V2 *PMBB_SIGNAL_STATE_INFOS_V2; + +typedef +enum _MBB_LOCATION_TRIGGER_MODE + { + MbbLocationTriggerNone = 0, + MbbLocationTriggerAreaCode = 1, + MbbLocationTriggerAreaCellId = 2 + } MBB_LOCATION_TRIGGER_MODE; + +typedef struct _MBB_SET_LOCATION_STATE + { + MBB_LOCATION_TRIGGER_MODE Trigger; + } MBB_SET_LOCATION_STATE; + +typedef struct _MBB_SET_LOCATION_STATE *PMBB_SET_LOCATION_STATE; + +typedef struct _MBB_LOCATION_STATE_INFO + { + MBB_LOCATION_TRIGGER_MODE Trigger; + ULONG DataClass; + ULONG AreaCode; + ULONG CellId; + } MBB_LOCATION_STATE_INFO; + +typedef struct _MBB_LOCATION_STATE_INFO *PMBB_LOCATION_STATE_INFO; + +typedef struct _MBB_NITZ_INFO + { + ULONG Year; + ULONG Month; + ULONG Day; + ULONG Hour; + ULONG Minute; + ULONG Second; + ULONG TimeZoneOffsetMinutes; + ULONG DaylightSavingTimeOffsetMinutes; + ULONG DataClasses; + } MBB_NITZ_INFO; + +typedef struct _MBB_NITZ_INFO *PMBB_NITZ_INFO; + +typedef struct _MBB_ATR_INFO + { + MBB_ARRAY_ELEMENT2 Atr; + UCHAR DataBuffer[ 1 ]; + } MBB_ATR_INFO; + +typedef struct _MBB_ATR_INFO *PMBB_ATR_INFO; + +typedef struct _MBB_SET_UICC_OPEN_CHANNEL + { + MBB_ARRAY_ELEMENT2 AppId; + ULONG SelectP2Arg; + ULONG ChannelGroup; + UCHAR DataBuffer[ 1 ]; + } MBB_SET_UICC_OPEN_CHANNEL; + +typedef struct _MBB_SET_UICC_OPEN_CHANNEL *PMBB_SET_UICC_OPEN_CHANNEL; + +typedef struct _MBB_UICC_OPEN_CHANNEL_INFO + { + UCHAR Status[ 4 ]; + ULONG Channel; + MBB_ARRAY_ELEMENT2 Response; + UCHAR DataBuffer[ 1 ]; + } MBB_UICC_OPEN_CHANNEL_INFO; + +typedef struct _MBB_UICC_OPEN_CHANNEL_INFO *PMBB_UICC_OPEN_CHANNEL_INFO; + +typedef struct _MBB_SET_UICC_CLOSE_CHANNEL + { + ULONG Channel; + ULONG ChannelGroup; + ULONG SelectP2Arg; + } MBB_SET_UICC_CLOSE_CHANNEL; + +typedef struct _MBB_SET_UICC_CLOSE_CHANNEL *PMBB_SET_UICC_CLOSE_CHANNEL; + +typedef struct _MBB_UICC_CLOSE_CHANNEL_INFO + { + UCHAR Status[ 4 ]; + } MBB_UICC_CLOSE_CHANNEL_INFO; + +typedef struct _MBB_UICC_CLOSE_CHANNEL_INFO *PMBB_UICC_CLOSE_CHANNEL_INFO; + +typedef +enum _MBB_UICC_SECURE_MESSAGING + { + MbbUiccSecureMessagingNone = 0, + MbbUiccSecureMessagingNoHdrAuth = 1 + } MBB_UICC_SECURE_MESSAGING; + +typedef +enum _MBB_UICC_CLASS_BYTE_TYPE + { + MbbUiccClassByteTypeInterindustry = 0, + MbbUiccClassByteTypeExtended = 1 + } MBB_UICC_CLASS_BYTE_TYPE; + +typedef struct _MBB_SET_UICC_APDU + { + ULONG Channel; + MBB_UICC_SECURE_MESSAGING SecureMessaging; + MBB_UICC_CLASS_BYTE_TYPE Type; + MBB_ARRAY_ELEMENT2 Command; + UCHAR DataBuffer[ 1 ]; + } MBB_SET_UICC_APDU; + +typedef struct _MBB_SET_UICC_APDU *PMBB_SET_UICC_APDU; + +typedef struct _MBB_UICC_APDU_INFO + { + UCHAR Status[ 4 ]; + MBB_ARRAY_ELEMENT2 Response; + UCHAR DataBuffer[ 1 ]; + } MBB_UICC_APDU_INFO; + +typedef struct _MBB_UICC_APDU_INFO *PMBB_UICC_APDU_INFO; + +typedef struct _MBB_UICC_TERMINAL_CAPABILITY_TLV + { + UCHAR Data[ 3 ]; + } MBB_UICC_TERMINAL_CAPABILITY_TLV; + +typedef struct _MBB_UICC_TERMINAL_CAPABILITY_TLV *PMBB_UICC_TERMINAL_CAPABILITY_TLV; + +typedef struct _MBB_SET_UICC_TERMINAL_CAPABILITY + { + ULONG ElementCount; + MBB_ARRAY_ELEMENT CapabilityList[ 1 ]; + } MBB_SET_UICC_TERMINAL_CAPABILITY; + +typedef struct _MBB_SET_UICC_TERMINAL_CAPABILITY *PMBB_SET_UICC_TERMINAL_CAPABILITY; + +typedef struct _MBB_UICC_TERMINAL_CAPABILITY_INFO + { + ULONG ElementCount; + MBB_ARRAY_ELEMENT CapabilityList[ 1 ]; + } MBB_UICC_TERMINAL_CAPABILITY_INFO; + +typedef struct _MBB_UICC_TERMINAL_CAPABILITY_INFO *PMBB_UICC_TERMINAL_CAPABILITY_INFO; + +typedef +enum _MBB_UICC_PASSTHROUGH_ACTION + { + MbbUiccPassThroughDisable = 0, + MbbUiccPassThroughEnable = 1 + } MBB_UICC_PASSTHROUGH_ACTION; + +typedef +enum _MBB_UICC_PASSTHROUGH_STATUS + { + MbbUiccPassThroughDisabled = 0, + MbbUiccPassThroughEnabled = 1 + } MBB_UICC_PASSTHROUGH_STATUS; + +typedef struct _MBB_SET_UICC_RESET + { + MBB_UICC_PASSTHROUGH_ACTION PassThroughAction; + } MBB_SET_UICC_RESET; + +typedef struct _MBB_SET_UICC_RESET *PMBB_SET_UICC_RESET; + +typedef struct _MBB_UICC_RESET_INFO + { + MBB_UICC_PASSTHROUGH_STATUS PassThroughStatus; + } MBB_UICC_RESET_INFO; + +typedef struct _MBB_UICC_RESET_INFO *PMBB_UICC_RESET_INFO; + +typedef struct _MBB_SAR_CONFIG_INDICES + { + ULONG SarAntennaIndex; + ULONG SarBackoffIndex; + } MBB_SAR_CONFIG_INDICES; + +typedef struct _MBB_SAR_CONFIG_INDICES *PMBB_SAR_CONFIG_INDICES; + +typedef struct _MBB_SAR_CONFIG_INFO + { + MBB_SAR_CONTROL_MODE SarMode; + MBB_SAR_BACKOFF_STATE SarBackoffStatus; + MBB_SAR_WIFI_HARDWARE_INTEGRATION SarWifiIntegration; + ULONG ElementCount; + MBB_ARRAY_ELEMENT Configurations[ 1 ]; + } MBB_SAR_CONFIG_INFO; + +typedef struct _MBB_SAR_CONFIG_INFO *PMBB_SAR_CONFIG_INFO; + +typedef struct _MBB_SET_SAR_CONFIG + { + MBB_SAR_CONTROL_MODE SarMode; + MBB_SAR_BACKOFF_STATE SarBackoffStatus; + ULONG ElementCount; + MBB_ARRAY_ELEMENT Configurations[ 1 ]; + } MBB_SET_SAR_CONFIG; + +typedef struct _MBB_SET_SAR_CONFIG *PMBB_SET_SAR_CONFIG; + +typedef struct _MBB_SAR_TRANSMISSION_STATUS_INFO + { + MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE ChannelNotification; + MBB_SAR_TRANSMISSION_STATUS TransmissionStatus; + ULONG HysteresisTimer; + } MBB_SAR_TRANSMISSION_STATUS_INFO; + +typedef struct _MBB_SAR_TRANSMISSION_STATUS_INFO *PMBB_SAR_TRANSMISSION_STATUS_INFO; + +typedef struct _MBB_SET_SAR_TRANSMISSION_STATUS + { + MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE ChannelNotification; + ULONG HysteresisTimer; + } MBB_SET_SAR_TRANSMISSION_STATUS; + +typedef struct _MBB_SET_SAR_TRANSMISSION_STATUS *PMBB_SET_SAR_TRANSMISSION_STATUS; + +typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 + { + MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS Operation; + GUID ContextType; + MBB_CONTEXT_IP_TYPE IPType; + MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; + MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; + MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; + MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[ 1 ]; + } MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2; + +typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 *PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2; + +typedef struct _MBB_MS_CONTEXT_V2 + { + ULONG ContextId; + GUID ContextType; + MBB_CONTEXT_IP_TYPE IPType; + MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; + MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; + MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; + MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[ 1 ]; + } MBB_MS_CONTEXT_V2; + +typedef struct _MBB_MS_CONTEXT_V2 *PMBB_MS_CONTEXT_V2; + +typedef struct _MBB_MS_NETWORK_BLACKLIST_PROVIDER + { + ULONG MCC; + ULONG MNC; + MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE NetworkBlacklistType; + } MBB_MS_NETWORK_BLACKLIST_PROVIDER; + +typedef struct _MBB_MS_NETWORK_BLACKLIST_PROVIDER *PMBB_MS_NETWORK_BLACKLIST_PROVIDER; + +typedef struct _MBB_MS_NETWORK_BLACKLIST_INFO + { + MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE BlacklistState; + ULONG ElementCount; + MBB_ARRAY_ELEMENT Contexts[ 1 ]; + } MBB_MS_NETWORK_BLACKLIST_INFO; + +typedef struct _MBB_MS_NETWORK_BLACKLIST_INFO *PMBB_MS_NETWORK_BLACKLIST_INFO; + +typedef struct _MBB_MS_VERSION_INFO + { + USHORT bcdMBIMVersion; + USHORT bcdMBIMExtendedVersion; + } MBB_MS_VERSION_INFO; + +typedef struct _MBB_MS_VERSION_INFO *PMBB_MS_VERSION_INFO; + +typedef struct _MBB_MS_LTE_ATTACH_CONTEXT + { + MBB_CONTEXT_IP_TYPE IPType; + MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL Roaming; + MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[ 1 ]; + } MBB_MS_LTE_ATTACH_CONTEXT; + +typedef struct _MBB_MS_LTE_ATTACH_CONTEXT *PMBB_MS_LTE_ATTACH_CONTEXT; + +typedef struct _MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG + { + MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS Operation; + ULONG ElementCount; + MBB_ARRAY_ELEMENT Contexts[ 1 ]; + } MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG; + +typedef struct _MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG *PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG; + +typedef struct _MBB_MS_LTE_ATTACH_CONFIG_INFO + { + ULONG ElementCount; + MBB_ARRAY_ELEMENT Contexts[ 1 ]; + } MBB_MS_LTE_ATTACH_CONFIG_INFO; + +typedef struct _MBB_MS_LTE_ATTACH_CONFIG_INFO *PMBB_MS_LTE_ATTACH_CONFIG_INFO; + +typedef struct _MBB_MS_LTE_ATTACH_STATUS + { + MBB_BASICCONNECTEXT_LTEATTACH_STATE LteAttachState; + MBB_CONTEXT_IP_TYPE IPType; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[ 1 ]; + } MBB_MS_LTE_ATTACH_STATUS; + +typedef struct _MBB_MS_LTE_ATTACH_STATUS *PMBB_MS_LTE_ATTACH_STATUS; + +typedef struct _MBB_MS_LTE_ATTACH_STATUS_V2 + { + MBB_BASICCONNECTEXT_LTEATTACH_STATE LteAttachState; + ULONG NetworkError; + MBB_CONTEXT_IP_TYPE IPType; + MBB_STRING AccessString; + MBB_STRING UserName; + MBB_STRING Password; + MBB_COMPRESSION Compression; + MBB_AUTH_PROTOCOL AuthProtocol; + UCHAR DataBuffer[ 1 ]; + } MBB_MS_LTE_ATTACH_STATUS_V2; + +typedef struct _MBB_MS_LTE_ATTACH_STATUS_V2 *PMBB_MS_LTE_ATTACH_STATUS_V2; + +typedef struct _MBB_MS_SYS_CAPS_INFO + { + ULONG NumberOfExecutors; + ULONG NumberOfSlots; + ULONG Concurrency; + ULONG64 ModemId; + } MBB_MS_SYS_CAPS_INFO; + +typedef struct _MBB_MS_SYS_CAPS_INFO *PMBB_MS_SYS_CAPS_INFO; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V2 + { + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + MBB_SIM_CLASS SimClass; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONG dwMaxSessions; + MBB_STRING CustomDataClass; + MBB_STRING DeviceIdString; + MBB_STRING FirmwareInfo; + MBB_STRING HardwareInfo; + ULONG ExecutorIndex; + UCHAR DataBuffer[ 1 ]; + } MBB_MS_DEVICE_CAPS_INFO_V2; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V2 *PMBB_MS_DEVICE_CAPS_INFO_V2; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3_OBS + { + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + ULONG SimClassBitMasks; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONGLONG MiscCaps; + ULONG dwMaxSessions; + ULONG ExecutorIndex; + ULONG WcdmaBandClass; + } MBB_MS_DEVICE_CAPS_INFO_V3_OBS; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3_OBS *PMBB_MS_DEVICE_CAPS_INFO_V3_OBS; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3 + { + MBB_DEVICE_TYPE DeviceType; + MBB_CELLULAR_CLASS CellularClass; + MBB_VOICE_CLASS VoiceClass; + ULONG SimClassBitMasks; + ULONG DataClass; + ULONG SmsCaps; + ULONG ControlCaps; + ULONGLONG DataSubClass; + ULONG dwMaxSessions; + ULONG ExecutorIndex; + ULONG WcdmaBandClass; + } MBB_MS_DEVICE_CAPS_INFO_V3; + +typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3 *PMBB_MS_DEVICE_CAPS_INFO_V3; + +typedef struct _MBB_MS_DEVICE_SLOT_MAPPING_INFO + { + ULONG MapCount; + MBB_ARRAY_ELEMENT SlotMapList[ 1 ]; + } MBB_MS_DEVICE_SLOT_MAPPING_INFO; + +typedef struct _MBB_MS_DEVICE_SLOT_MAPPING_INFO *PMBB_MS_DEVICE_SLOT_MAPPING_INFO; + +typedef struct _MBB_MS_SLOT_INFO_REQ + { + ULONG SlotIndex; + } MBB_MS_SLOT_INFO_REQ; + +typedef struct _MBB_MS_SLOT_INFO_REQ *PMBB_MS_SLOT_INFO_REQ; + +typedef struct _MBB_MS_SLOT_INFO + { + ULONG SlotIndex; + MBB_BASICCONNECTEXT_UICCSLOT_STATE State; + } MBB_MS_SLOT_INFO; + +typedef struct _MBB_MS_SLOT_INFO *PMBB_MS_SLOT_INFO; + +typedef struct _MBB_MS_PCO_VALUE + { + ULONG SessionId; + ULONG PcoDataSize; + MBB_PCO_TYPE PcoDataType; + UCHAR PcoDataBuffer[ 1 ]; + } MBB_MS_PCO_VALUE; + +typedef struct _MBB_MS_PCO_VALUE *PMBB_MS_PCO_VALUE; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ + { + ULONG MaxGSMCount; + ULONG MaxUMTSCount; + ULONG MaxTDSCDMACount; + ULONG MaxLTECount; + ULONG MaxCDMACount; + } MBB_MS_BASE_STATIONS_INFO_REQ; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ *PMBB_MS_BASE_STATIONS_INFO_REQ; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ_V2 + { + ULONG MaxGSMCount; + ULONG MaxUMTSCount; + ULONG MaxTDSCDMACount; + ULONG MaxLTECount; + ULONG MaxCDMACount; + ULONG MaxNRCount; + } MBB_MS_BASE_STATIONS_INFO_REQ_V2; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ_V2 *PMBB_MS_BASE_STATIONS_INFO_REQ_V2; + +typedef struct _MBB_MS_BASE_STATIONS_INFO + { + MBB_DATA_CLASS_VALUE SystemType; + MBB_ARRAY_ELEMENT GSMServingCell; + MBB_ARRAY_ELEMENT UMTSServingCell; + MBB_ARRAY_ELEMENT TDSCDMAServingCell; + MBB_ARRAY_ELEMENT LTEServingCell; + MBB_ARRAY_ELEMENT GSMNmr; + MBB_ARRAY_ELEMENT UMTSMrl; + MBB_ARRAY_ELEMENT TDSCDMAMrl; + MBB_ARRAY_ELEMENT LTEMrl; + MBB_ARRAY_ELEMENT CDMAMrl; + UCHAR DataBuffer[ 1 ]; + } MBB_MS_BASE_STATIONS_INFO; + +typedef struct _MBB_MS_BASE_STATIONS_INFO *PMBB_MS_BASE_STATIONS_INFO; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_V2 + { + MBB_DATA_CLASS_VALUE SystemType; + MBB_DATA_SUBCLASS_VALUE SystemSubType; + MBB_ARRAY_ELEMENT GSMServingCell; + MBB_ARRAY_ELEMENT UMTSServingCell; + MBB_ARRAY_ELEMENT TDSCDMAServingCell; + MBB_ARRAY_ELEMENT LTEServingCell; + MBB_ARRAY_ELEMENT GSMNmr; + MBB_ARRAY_ELEMENT UMTSMrl; + MBB_ARRAY_ELEMENT TDSCDMAMrl; + MBB_ARRAY_ELEMENT LTEMrl; + MBB_ARRAY_ELEMENT CDMAMrl; + MBB_ARRAY_ELEMENT NRServingCells; + MBB_ARRAY_ELEMENT NRNeighborCells; + UCHAR DataBuffer[ 1 ]; + } MBB_MS_BASE_STATIONS_INFO_V2; + +typedef struct _MBB_MS_BASE_STATIONS_INFO_V2 *PMBB_MS_BASE_STATIONS_INFO_V2; + +typedef struct _MBB_MODEM_LOGGING_CONFIG + { + ULONG Version; + ULONG MaxSegmentSize; + ULONG MaxFlushTime; + MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG LevelConfig; + } MBB_MODEM_LOGGING_CONFIG; + +typedef struct _MBB_MODEM_LOGGING_CONFIG *PMBB_MODEM_LOGGING_CONFIG; + +typedef struct _MBB_TLV_IE + { + MBB_TLV_TYPE Type; + UCHAR Reserved; + UCHAR PaddingLength; + ULONG DataLength; + } MBB_TLV_IE; + +typedef struct _MBB_TLV_IE *PMBB_TLV_IE; + +typedef +enum _MBB_ACCESS_TYPE + { + MbbAccessUnknown = 0, + MbbAccess3GPP = 1, + MbbAccessNon3GPP = 2, + MbbAccessMaximum = ( MbbAccessNon3GPP + 1 ) + } MBB_ACCESS_TYPE; + +typedef struct _MBB_PRE_DFLT_NSSAI_INFO + { + MBB_ACCESS_TYPE AccessType; + MBB_TLV_IE PreferredNSSAI; + } MBB_PRE_DFLT_NSSAI_INFO; + +typedef struct _MBB_PRE_DFLT_NSSAI_INFO *PMBB_PRE_DFLT_NSSAI_INFO; + +typedef struct _MBB_SNSSAI_INFO + { + UCHAR SnssaiLength; + UCHAR Sst; + } MBB_SNSSAI_INFO; + +typedef struct _MBB_SNSSAI_INFO *PMBB_SNSSAI_INFO; + +typedef struct _MBB_TAI_LIST_SINGLE_PLMN + { + MBB_PLMN Plmn; + UCHAR ElementCount; + ULONG TacList[ 1 ]; + } MBB_TAI_LIST_SINGLE_PLMN; + +typedef struct _MBB_TAI_LIST_SINGLE_PLMN *PMBB_TAI_LIST_SINGLE_PLMN; + +typedef struct _MBB_TAI_LIST_MULTI_PLMNS + { + UCHAR ElementCount; + MBB_TAI TaiList[ 1 ]; + } MBB_TAI_LIST_MULTI_PLMNS; + +typedef struct _MBB_TAI_LIST_MULTI_PLMNS *PMBB_TAI_LIST_MULTI_PLMNS; + +typedef struct _MBB_TAI_LIST_INFO + { + UCHAR ListType; + /* [switch_is] */ /* [switch_type] */ union __MIDL___MIDL_itf_MbbMessages_0000_0000_0002 + { + /* [case()] */ MBB_TAI_LIST_SINGLE_PLMN SinglePlmnTaiList; + /* [case()] */ MBB_TAI_LIST_MULTI_PLMNS MultiPlmnsTaiList; + } u; + } MBB_TAI_LIST_INFO; + +typedef struct _MBB_TAI_LIST_INFO *PMBB_TAI_LIST_INFO; + +typedef struct _MBB_DNN + { + UCHAR DnnLength; + } MBB_DNN; + +typedef struct _MBB_DNN *PMBB_DNN; + +typedef struct _MBB_LADN + { + MBB_DNN Dnn; + } MBB_LADN; + +typedef struct _MBB_LADN *PMBB_LADN; + +typedef +enum _MBB_MODEM_CONFIG_STATUS + { + ModemConfigStatusUnknown = 0, + ModemConfigStatusStarted = 1, + ModemConfigStatusCompleted = 2, + ModemConfigStatusMaximum = ( ModemConfigStatusCompleted + 1 ) + } MBB_MODEM_CONFIG_STATUS; + +typedef struct _MBB_MODEM_CONFIG_INFO + { + MBB_MODEM_CONFIG_STATUS ConfigStatus; + MBB_TLV_IE ConfigName; + } MBB_MODEM_CONFIG_INFO; + +typedef struct _MBB_MODEM_CONFIG_INFO *PMBB_MODEM_CONFIG_INFO; + +typedef +enum _MBB_MICO_MODE + { + MicoModeDisabled = 0, + MicoModeEnabled = 1, + MicoModeUnsupported = 2, + MBIMMicoModeDefault = 3, + MicoModeMaximum = ( MBIMMicoModeDefault + 1 ) + } MBB_MICO_MODE; + +typedef +enum _MBB_DRX_PARAMS + { + DRXNotSpecified = 0, + MBIMDRXNotSupported = 1, + DRXCycle32 = 2, + DRXCycle64 = 3, + DRXCycle128 = 4, + DRXCycle256 = 5, + DRXCycleMaximum = ( DRXCycle256 + 1 ) + } MBB_DRX_PARAMS; + +typedef +enum _MBB_DEFAULT_PDU_HINT + { + MBIMDefaultPDUSessionActivationUnlikely = 0, + MBIMDefaultPDUSessionActivationLikely = 1, + DefaultPDUMaximum = ( MBIMDefaultPDUSessionActivationLikely + 1 ) + } MBB_DEFAULT_PDU_HINT; + +typedef +enum _MBB_MS_LADN_IND + { + LADNInfoNotNeeded = 0, + LADNInfoRequested = 1, + LADNInfoMaximum = ( LADNInfoRequested + 1 ) + } MBB_MS_LADN_IND; + +typedef struct _MBB_REGISTRATION_PARAMS_INFO + { + MBB_MICO_MODE MicoMode; + MBB_DRX_PARAMS DRXParams; + MBB_MS_LADN_IND LADNInfo; + MBB_DEFAULT_PDU_HINT DefaultPDUHint; + ULONG ReRegisterIfNeeded; + } MBB_REGISTRATION_PARAMS_INFO; + +typedef struct _MBB_REGISTRATION_PARAMS_INFO *PMBB_REGISTRATION_PARAMS_INFO; + +typedef +enum _MBB_MICO_IND + { + RaaiTypeRaNotAllocated = 0, + RaaiTypeRaAllocated = 1, + RaaiTypeNotAvailable = 0xffffffff + } MBB_MICO_IND; + +typedef struct _MBB_NW_PARAMS_QUERY_INFO + { + USHORT AreConfigurationsNeeded; + USHORT AreUEPoliciesNeeded; + } MBB_NW_PARAMS_QUERY_INFO; + +typedef struct _MBB_NW_PARAMS_QUERY_INFO *PMBB_NW_PARAMS_QUERY_INFO; + +typedef struct _MBB_NW_PARAMS_INFO + { + MBB_MICO_IND MicoInd; + MBB_DRX_PARAMS DRXParams; + } MBB_NW_PARAMS_INFO; + +typedef struct _MBB_NW_PARAMS_INFO *PMBB_NW_PARAMS_INFO; + +typedef +enum _MBB_WAKE_TYPE + { + WakeTypeCIDResponse = 0, + WakeTypeCIDIndication = 1, + WakeTypePacket = 2 + } MBB_WAKE_TYPE; + +typedef struct _MBB_WAKE_REASON + { + MBB_WAKE_TYPE WakeType; + ULONG SessionId; + } MBB_WAKE_REASON; + +typedef struct _MBB_WAKE_REASON *PMBB_WAKE_REASON; + +typedef struct _MBB_WAKE_COMMAND + { + MBB_COMMAND Command; + ULONG PayloadOffset; + ULONG PayloadSize; + UCHAR DataBuffer[ 1 ]; + } MBB_WAKE_COMMAND; + +typedef struct _MBB_WAKE_COMMAND *PMBB_WAKE_COMMAND; + +typedef struct _MBB_WAKE_PACKET + { + ULONG FilterId; + ULONG OriginalPacketSize; + ULONG SavedPacketOffset; + ULONG SavedPacketSize; + UCHAR DataBuffer[ 1 ]; + } MBB_WAKE_PACKET; + +typedef struct _MBB_WAKE_PACKET *PMBB_WAKE_PACKET; + +#include + + +extern RPC_IF_HANDLE __MIDL_itf_MbbMessages_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_MbbMessages_0000_0000_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/network/wwan/cxwmbclass/inc/mbbncm.h b/network/wwan/cxwmbclass/inc/mbbncm.h new file mode 100644 index 000000000..9731dedf2 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/mbbncm.h @@ -0,0 +1,431 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +#pragma once + +#define NCM10_CC_INTERFACE_CLASS (0x02) +#define NCM10_CC_INTERFACE_SUBCLASS (0x0d) +#define NCM10_CC_INTERFACE_PROTOCOL (0x00) + +#define MBIM_CC_INTERFACE_CLASS (0x02) +#define MBIM_CC_INTERFACE_SUBCLASS (0x0e) +#define MBIM_CC_INTERFACE_PROTOCOL (0x00) +#define MBIM_CC_INTERFACE_NBL_PROTOCOL (0x01) +#define MBIM_CC_INTERFACE_NETPACKET_PROTOCOL (0x02) + + +#define MBIM_DC_INTERFACE_CLASS (0x0A) +#define MBIM_DC_INTERFACE_SUBCLASS (0x00) +#define MBIM_DC_INTERFACE_PROTOCOL (0x02) + +#define MBIM_MBB_FUNCDESC_MIN_VERSION (0x0100) +#define MBIM_MBB_FUNCDESC_EXTENDED_MIN_VERSION (0x0100) + +#define SEND_ENCAPSULATE_COMMAND (0x00) +#define GET_ENCAPSULATE_RESPONSE (0x01) +#define RESET_FUNCTION (0x05) +#define SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER (0x41) +#define GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER (0x42) +#define SET_PACKET_FILTER (0x43) +#define GET_STATISTIC (0x44) + +#define GET_NTB_PARAMETERS (0x80) +#define GET_NBT_FORMAT (0x83) +#define SET_NBT_FORMAT (0x84) +#define GET_NTB_INPUT_SIZE (0x85) +#define SET_NTB_INPUT_SIZE (0x86) +#define GET_MAX_DATAGRAM_SIZE (0x87) + + +#define MBIM_MIN_SEGMENT_SIZE (1280) +#define MBIM_MAX_PACKET_FILTER_SIZE (192) +#define MBIM_MIN_NUMBER_OF_PACKET_FILTERS (16) +#define MBIM_MIN_MTU_SIZE (1280) +#define MBIM_MAX_MTU_SIZE (1500) + +#define USB_CDC_CS_DESCRIPTOR_TYPE (0x24) + +#define USB_CDC_CS_DESCRIPTOR_SUBTYPE (0x0) +#define USB_CDC_UNION_DESCRIPTOR_SUBTYPE (0x6) +#define USB_CDC_CS_ECM_DESCRIPTOR_SUBTYPE (0xf) +#define USB_CDC_CS_NCM_DESCRIPTOR_SUBTYPE (0x1a) +#define USB_CDC_CS_MBB_DESCRIPTOR_SUBTYPE (0x1b) +#define USB_CDC_CS_MBB_DESCRIPTOR_EXTENDED_SUBTYPE (0x1c) + + +#define USB_CDC_NOTIFICATION_NETWORK_CONNECTION (0x00) +#define USB_CDC_NOTIFICATION_RESPONSE_AVAILABLE (0x01) +#define USB_CDC_NOTIFICATION_CONNECTION_SPEED_CHANGE (0x2a) + +#define NCM_NETWORK_CAPS_SET_FILTER_SUPPORTED (1 << 0) +#define NCM_NETWORK_CAPS_GET_SET_ADDRESS_SUPPORTED (1 << 1) +#define NCM_NETWORK_CAPS_ENCAPSULATED_COMMAND_SUPPORTED (1 << 2) +#define NCM_NETWORK_CAPS_MAX_DATAGRAM_SUPPORTED (1 << 3) +#define NCM_NETWORK_CAPS_GET_SET_CRC_SUPPORTED (1 << 4) +#define NCM_NETWORK_CAPS_GET_8_BYTE_INPUT_SIZE_SUPPORTED (1 << 5) + +#define NCM_NTB_FORMAT_16_BIT (1 << 0) +#define NCM_NTB_FORMAT_32_BIT (1 << 1) + +#define NCM_PACKET_FILTER_DIRECTED (1 << 2) + +#define NCM_SET_NTB_FORMAT_16_BIT (0x0) +#define NCM_SET_NTB_FORMAT_32_BIT (0x1) + + + +#define NCM_STAT_RESERVED 0x00 +#define NCM_XMIT_OK 0x01 +#define NCM_RCV_OK 0x02 +#define NCM_XMIT_ERROR 0x03 +#define NCM_RCV_ERROR 0x04 +#define NCM_RCV_NO_BUFFER 0x05 +#define NCM_DIRECTED_BYTES_XMIT 0x06 +#define NCM_DIRECTED_FRAMES_XMIT 0x07 +#define NCM_MULTICAST_BYTES_XMIT 0x08 +#define NCM_MULTICAST_FRAMES_XMIT 0x09 +#define NCM_BROADCAST_BYTES_XMIT 0x0A +#define NCM_BROADCAST_FRAMES_XMIT 0x0B +#define NCM_DIRECTED_BYTES_RCV 0x0C +#define NCM_DIRECTED_FRAMES_RCV 0x0D +#define NCM_MULTICAST_BYTES_RCV 0x0E +#define NCM_MULTICAST_FRAMES_RCV 0x0F +#define NCM_BROADCAST_BYTES_RCV 0x10 +#define NCM_BROADCAST_FRAMES_RCV 0x11 +#define NCM_RCV_CRC_ERROR 0x12 +#define NCM_TRANSMIT_QUEUE_LENGTH 0x13 +#define NCM_RCV_ERROR_ALIGNMENT 0x14 +#define NCM_XMIT_ONE_COLLISION 0x15 +#define NCM_XMIT_MORE_COLLISIONS 0x16 +#define NCM_XMIT_DEFERRED 0x17 +#define NCM_XMIT_MAX_COLLISIONS 0x18 +#define NCM_RCV_OVERRUN 0x19 +#define NCM_XMIT_UNDERRUN 0x1A +#define NCM_XMIT_HEARTBEAT_FAILURE 0x1B +#define NCM_XMIT_TIMES_CRS_LOST 0x1C +#define NCM_XMIT_LATE_COLLISIONS 0x1D + +#define NCM_NDP_SESSION_SHIFT 24 +#define NCM_NDP_SIGNATURE_MASK 0x00FFFFFF + +#define NCM_NTH16_SIG 'HMCN' +#define NCM_NTH32_SIG 'hmcn' + +#define NCM_NDP16_IPS 'SPI' +#define NCM_NDP16_VENDOR 'SSD' + +#define NCM_NDP32_IPS 'spi' +#define NCM_NDP32_VENDOR 'ssd' + +#define NCM_CID_SIG 'dcbm' + +#pragma pack( push,1) + +typedef struct _NCM_NTB_PARAMETER { + + USHORT wLength; + USHORT bmNtbFormatSupported; + ULONG dwNtbInMaxSize; + USHORT wNdpInDivisor; + USHORT wNdpInPayloadRemainder; + USHORT wNdpInAlignment; + USHORT wReserved1; + ULONG dwNtbOutMaxSize; + USHORT wNdpOutDivisor; + USHORT wNdpOutPayloadRemainder; + USHORT wNdpOutAlignment; + USHORT wNtbOutMaxDatagrams; + +} NCM_NTB_PARAMETER, *PNCM_NTB_PARAMETER; + +typedef struct _USB_CS_DESCRIPTOR { + + BYTE bLength; + BYTE bDescriptorType; + BYTE bSubType; + +} USB_CS_DESCRIPTOR, *PUSB_CS_DESCRIPTOR; + +typedef struct _USB_CS_UNION_DESCRIPTOR { + + BYTE bLength; + BYTE bDescriptorType; + BYTE bSubType; + BYTE bControlInterface; + BYTE bSubordinateInterface[1]; + +} USB_CS_UNION_DESCRIPTOR, *PUSB_CS_UNION_DESCRIPTOR; + + +typedef struct _USB_CS_CDC_DESCRIPTOR { + + BYTE bLength; + BYTE bDescriptorType; + BYTE bSubType; + USHORT wCDCVersion; + +} USB_CS_CDC_DESCRIPTOR, *PUSB_CS_CDC_DESCRIPTOR; + +typedef struct _USB_CS_ECM_DESCRIPTOR { + + BYTE bLength; + BYTE bDescriptorType; + BYTE bSubType; + BYTE iMacAddress; + ULONG bmEthernetStatistics; + USHORT wMaxSegmentSize; + USHORT wNumberMCFilters; + BYTE bNumberPowerFilters; + +} USB_CS_ECM_DESCRIPTOR, *PUSB_CS_ECM_DESCRIPTOR; + +typedef struct _USB_CS_NCM_DESCRIPTOR { + + BYTE bLength; + BYTE bDescriptorType; + BYTE bSubType; + USHORT wNcmVersion; + BYTE bmNetworkCapabilities; + +} USB_CS_NCM_DESCRIPTOR, *PUSB_CS_NCM_DESCRIPTOR; + + +typedef struct _USB_CS_MBB_DESCRIPTOR { + + BYTE bLength; + BYTE bDescriptorType; + BYTE bSubType; + USHORT wMbbVersion; + USHORT wMaxControlMessage; + BYTE bNumberPowerFilters; + BYTE bMaxFilterSize; + USHORT wMaxSegmentSize; + BYTE bmNetworkCapabilities; + +} USB_CS_MBB_DESCRIPTOR, *PUSB_CS_MBB_DESCRIPTOR; + +typedef struct _USB_CS_MBB_DESCRIPTOR_EXTENDED { + + BYTE bLength; + BYTE bDescriptorType; + BYTE bSubType; + USHORT wMbbVersion; + BYTE bMaxOutstandingCommandMessages; + USHORT wMTU; + +} USB_CS_MBB_DESCRIPTOR_EXTENDED, *PUSB_CS_MBB_DESCRIPTOR_EXTENDED; + +typedef struct _USB_CDC_NOTIFICATION { + + BYTE bmRequestType; + BYTE bNotificationCode; + USHORT wValue; + USHORT wIndex; + USHORT wLength; + +} USB_CDC_NOTIFICATION, *PUSB_CDC_NOTIFICATION; + +typedef struct _USB_CDC_NOTIFICATION_SPEED_CHANGE { + + USB_CDC_NOTIFICATION NotificationHeader; + ULONG DownLinkBitRate; + ULONG UpLinkBitRate; + +} USB_CDC_NOTIFICATION_SPEED_CHANGE, *PUSB_CDC_NOTIFICATION_SPEED_CHANGE; + + +typedef struct _NCM_NTH16 { + + ULONG dwSignature; + USHORT wHeaderLength; + USHORT wSequence; + USHORT wBlockLength; + USHORT wFpIndex; + +} NCM_NTH16, *PNCM_NTH16; + +typedef struct _NCM_NTH32 { + + ULONG dwSignature; + USHORT wHeaderLength; + USHORT wSequence; + ULONG dwBlockLength; + ULONG dwFpIndex; + +} NCM_NTH32, *PNCM_NTH32; + +typedef struct _NCM_NDP16_DATAGRAM { + + USHORT wDatagramIndex; + USHORT wDatagramLength; + +} NCM_NDP16_DATAGRAM, *PNCM_NDP16_DATAGRAM; + + +typedef struct _NCM_NDP16 { + + ULONG dwSignature; + USHORT wLength; + USHORT wNextFpIndex; + + NCM_NDP16_DATAGRAM Datagram[1]; + +} NCM_NDP16, *PNCM_NDP16; + + +typedef struct _NCM_NDP32_DATAGRAM { + + ULONG dwDatagramIndex; + ULONG dwDatagramLength; + +} NCM_NDP32_DATAGRAM, *PNCM_NDP32_DATAGRAM; + + +typedef struct _NCM_NDP32 { + + ULONG dwSignature; + USHORT wLength; + USHORT wReserved6; + ULONG dwNextFpIndex; + ULONG dwReserved12; + + NCM_NDP32_DATAGRAM Datagram[1]; + +} NCM_NDP32, *PNCM_NDP32; + + +#pragma pack( pop) + +// +// NTB +// + +#define MBB_NTB_GET_OFFSET(NTH,_X_) ((ULONG)(((SIZE_T)(_X_))-((SIZE_T)(NTH)))) +#define MBB_NTB_GET_SEQUENCE(NTH) (((PNCM_NTH32)(NTH))->wSequence) +#define MBB_NTB_GET_SIGNATURE(NTH) (((PNCM_NTH32)(NTH))->dwSignature) +#define MBB_NTB_GET_HEADER_LENGTH(NTH) (((PNCM_NTH32)(NTH))->wHeaderLength) +#define MBB_NTB_IS_32BIT(NTH) (MBB_NTB_GET_SIGNATURE(NTH) == NCM_NTH32_SIG) +#define MBB_NTB_IS_16BIT(NTH) (MBB_NTB_GET_SIGNATURE(NTH) == NCM_NTH16_SIG) + +// +// NTB32 + +#define MBB_NTH32_GET_SEQUENCE(NTH) MBB_NTB_GET_SEQUENCE(NTH) +#define MBB_NTH32_GET_SIGNATURE(NTH) MBB_NTB_GET_SIGNATURE(NTH) +#define MBB_NTH32_GET_HEADER_LENGTH(NTH) MBB_NTB_GET_HEADER_LENGTH(NTH) +#define MBB_NTH32_GET_BLOCK_LENGTH(NTH) ((NTH)->dwBlockLength) +#define MBB_NTH32_GET_FIRST_NDP_OFFSET(NTH) ((NTH)->dwFpIndex) +#define MBB_NTH32_GET_FIRST_NDP(NTH) ((MBB_NTH32_GET_FIRST_NDP_OFFSET(NTH) != 0)? ((PNCM_NDP32)(((PCHAR)(NTH)) + MBB_NTH32_GET_FIRST_NDP_OFFSET(NTH))): NULL) +#define MBB_NTH32_IS_VALID_BLOCK_LENGTH(NTH,MAXLEN) (MBB_NTH32_GET_BLOCK_LENGTH(NTH) <= (MAXLEN)) +#define MBB_NTH32_IS_VALID_HEADER_LENGTH(NTH) (MBB_NTB_GET_HEADER_LENGTH(NTH) == sizeof(NCM_NTH32)) +#define MBB_NTH32_IS_VALID_SIGNATURE(NTH) (MBB_NTB_GET_SIGNATURE(NTH) == NCM_NTH32_SIG) +#define MBB_NTH32_IS_VALID_FIRST_NDP(NTH) \ + ( \ + MBB_NTH32_GET_FIRST_NDP_OFFSET(NTH)<= (ULONG_MAX - sizeof(NCM_NDP32)) && \ + (MBB_NTH32_GET_FIRST_NDP_OFFSET(NTH) + sizeof(NCM_NDP32)) <= MBB_NTH32_GET_BLOCK_LENGTH(NTH) \ + ) + +#define MBB_NDP32_GET_SIGNATURE(NDP) ((NDP)->dwSignature) +#define MBB_NDP32_GET_SESSIONID(NDP) (MBB_NDP32_GET_SIGNATURE(NDP) >> NCM_NDP_SESSION_SHIFT) +#define MBB_NDP32_GET_SIGNATURE_TYPE(NDP) (MBB_NDP32_GET_SIGNATURE(NDP) & NCM_NDP_SIGNATURE_MASK) +#define MBB_NDP32_GET_LENGTH(NDP) ((NDP)->wLength) +#define MBB_NDP32_GET_NEXT_NDP_OFFSET(NDP) ((NDP)->dwNextFpIndex) +#define MBB_NDP32_GET_NEXT_NDP(NTH,NDP) ((MBB_NDP32_GET_NEXT_NDP_OFFSET(NDP) != 0)? ((PNCM_NDP32)(((PCHAR)(NTH)) + MBB_NDP32_GET_NEXT_NDP_OFFSET(NDP))): NULL) +#define MBB_NDP32_GET_DATAGRAM_COUNT(NDP) ((MBB_NDP32_GET_LENGTH(NDP)-FIELD_OFFSET(NCM_NDP32,Datagram)) / sizeof(NCM_NDP32_DATAGRAM)) +#define MBB_NDP32_GET_DATAGRAM_OFFSET(NDP,IDX) ((NDP)->Datagram[(IDX)].dwDatagramIndex) +#define MBB_NDP32_GET_DATAGRAM_LENGTH(NDP,IDX) ((NDP)->Datagram[(IDX)].dwDatagramLength) +#define MBB_NDP32_GET_DATAGRAM(NTH,NDP,IDX) ((MBB_NDP32_GET_DATAGRAM_OFFSET(NDP,IDX) != 0)? (((PCHAR)(NTH)) + MBB_NDP32_GET_DATAGRAM_OFFSET(NDP,IDX)): NULL) +#define MBB_NDP32_IS_DATAGRAM_PRESENT(NDP,IDX) ((FIELD_OFFSET(NCM_NDP32,Datagram)+((IDX)*sizeof(NCM_NDP32_DATAGRAM))) <= MBB_NDP32_GET_LENGTH(NDP)) + +#define MBB_NTB32_IS_END_DATAGRAM(NTH,NDP,IDX) \ + ( \ + MBB_NDP32_IS_DATAGRAM_PRESENT(NDP,IDX) && \ + ( \ + MBB_NDP32_GET_DATAGRAM_OFFSET(NDP,IDX) == 0 || \ + MBB_NDP32_GET_DATAGRAM_LENGTH(NDP,IDX) == 0 \ + ) \ + ) +#define MBB_NTB32_IS_VALID_DATAGRAM(NTH,NDP,IDX) \ + ( \ + MBB_NDP32_IS_DATAGRAM_PRESENT(NDP,IDX) && \ + MBB_NDP32_GET_DATAGRAM_OFFSET(NDP,IDX) != 0 && \ + MBB_NDP32_GET_DATAGRAM_LENGTH(NDP,IDX) != 0 && \ + MBB_NDP32_GET_DATAGRAM_OFFSET(NDP,IDX) < MBB_NTH32_GET_BLOCK_LENGTH(NTH) && \ + MBB_NDP32_GET_DATAGRAM_OFFSET(NDP,IDX) <= (ULONG_MAX - MBB_NDP32_GET_DATAGRAM_LENGTH(NDP,IDX)) && \ + (MBB_NDP32_GET_DATAGRAM_OFFSET(NDP,IDX) + MBB_NDP32_GET_DATAGRAM_LENGTH(NDP,IDX)) <= MBB_NTH32_GET_BLOCK_LENGTH(NTH) \ + ) +#define MBB_NTB32_IS_VALID_NDP_LENGTH(NTH,NDP) \ + ( \ + (MBB_NTB_GET_OFFSET(NTH,NDP) < MBB_NTH32_GET_BLOCK_LENGTH(NTH)) && \ + (MBB_NDP32_GET_LENGTH(NDP) >= FIELD_OFFSET(NCM_NDP32,Datagram)) && \ + (MBB_NTB_GET_OFFSET(NTH,NDP) <= ULONG_MAX - MBB_NDP32_GET_LENGTH(NDP)) && \ + ((MBB_NTB_GET_OFFSET(NTH,NDP)+MBB_NDP32_GET_LENGTH(NDP)) <= MBB_NTH32_GET_BLOCK_LENGTH(NTH)) \ + ) +#define MBB_NTB32_IS_VALID_NDP_SIGNATURE(NDP) \ + ( \ + ((MBB_NDP32_GET_SIGNATURE(NDP) & NCM_NDP_SIGNATURE_MASK) == NCM_NDP32_IPS) || \ + ((MBB_NDP32_GET_SIGNATURE(NDP) & NCM_NDP_SIGNATURE_MASK) == NCM_NDP32_VENDOR) \ + ) + +// +// NTB16 +// + +#define MBB_NTH16_GET_SEQUENCE(NTH) MBB_NTB_GET_SEQUENCE(NTH) +#define MBB_NTH16_GET_SIGNATURE(NTH) MBB_NTB_GET_SIGNATURE(NTH) +#define MBB_NTH16_GET_HEADER_LENGTH(NTH) MBB_NTB_GET_HEADER_LENGTH(NTH) +#define MBB_NTH16_GET_BLOCK_LENGTH(NTH) ((NTH)->wBlockLength) +#define MBB_NTH16_GET_FIRST_NDP_OFFSET(NTH) ((NTH)->wFpIndex) +#define MBB_NTH16_GET_FIRST_NDP(NTH) ((MBB_NTH16_GET_FIRST_NDP_OFFSET(NTH) != 0)? ((PNCM_NDP16)(((PCHAR)(NTH)) + MBB_NTH16_GET_FIRST_NDP_OFFSET(NTH))): NULL) +#define MBB_NTH16_IS_VALID_BLOCK_LENGTH(NTH,MAXLEN) (MBB_NTH16_GET_BLOCK_LENGTH(NTH) <= (MAXLEN)) +#define MBB_NTH16_IS_VALID_HEADER_LENGTH(NTH) (MBB_NTB_GET_HEADER_LENGTH(NTH) == sizeof(NCM_NTH16)) +#define MBB_NTH16_IS_VALID_SIGNATURE(NTH) (MBB_NTB_GET_SIGNATURE(NTH) == NCM_NTH16_SIG) +#define MBB_NTH16_IS_VALID_FIRST_NDP(NTH) \ + ( \ + MBB_NTH16_GET_FIRST_NDP_OFFSET(NTH) <= (USHRT_MAX - sizeof(NCM_NDP16)) &&\ + (MBB_NTH16_GET_FIRST_NDP_OFFSET(NTH) + sizeof(NCM_NDP16)) <= MBB_NTH16_GET_BLOCK_LENGTH(NTH) \ + ) + +#define MBB_NDP16_GET_SIGNATURE(NDP) ((NDP)->dwSignature) +#define MBB_NDP16_GET_SESSIONID(NDP) (MBB_NDP16_GET_SIGNATURE(NDP) >> NCM_NDP_SESSION_SHIFT) +#define MBB_NDP16_GET_SIGNATURE_TYPE(NDP) (MBB_NDP16_GET_SIGNATURE(NDP) & NCM_NDP_SIGNATURE_MASK) +#define MBB_NDP16_GET_LENGTH(NDP) ((NDP)->wLength) +#define MBB_NDP16_GET_NEXT_NDP_OFFSET(NDP) ((NDP)->wNextFpIndex) +#define MBB_NDP16_GET_NEXT_NDP(NTH,NDP) ((MBB_NDP16_GET_NEXT_NDP_OFFSET(NDP) != 0)? ((PNCM_NDP16)(((PCHAR)(NTH)) + MBB_NDP16_GET_NEXT_NDP_OFFSET(NDP))): NULL) +#define MBB_NDP16_GET_DATAGRAM_COUNT(NDP) ((MBB_NDP16_GET_LENGTH(NDP)-FIELD_OFFSET(NCM_NDP16,Datagram)) / sizeof(NCM_NDP16_DATAGRAM)) +#define MBB_NDP16_GET_DATAGRAM_OFFSET(NDP,IDX) ((NDP)->Datagram[(IDX)].wDatagramIndex) +#define MBB_NDP16_GET_DATAGRAM_LENGTH(NDP,IDX) ((NDP)->Datagram[(IDX)].wDatagramLength) +#define MBB_NDP16_GET_DATAGRAM(NTH,NDP,IDX) ((MBB_NDP16_GET_DATAGRAM_OFFSET(NDP,IDX) != 0)? (((PCHAR)(NTH)) + MBB_NDP16_GET_DATAGRAM_OFFSET(NDP,IDX)): NULL) +#define MBB_NDP16_IS_DATAGRAM_PRESENT(NDP,IDX) ((FIELD_OFFSET(NCM_NDP16,Datagram)+((IDX)*sizeof(NCM_NDP16_DATAGRAM))) <= MBB_NDP16_GET_LENGTH(NDP)) + +#define MBB_NTB16_IS_END_DATAGRAM(NTH,NDP,IDX) \ + ( \ + MBB_NDP16_IS_DATAGRAM_PRESENT(NDP,IDX) && \ + ( \ + MBB_NDP16_GET_DATAGRAM_OFFSET(NDP,IDX) == 0 || \ + MBB_NDP16_GET_DATAGRAM_LENGTH(NDP,IDX) == 0 \ + ) \ + ) +#define MBB_NTB16_IS_VALID_DATAGRAM(NTH,NDP,IDX) \ + ( \ + MBB_NDP16_IS_DATAGRAM_PRESENT(NDP,IDX) && \ + MBB_NDP16_GET_DATAGRAM_OFFSET(NDP,IDX) != 0 && \ + MBB_NDP16_GET_DATAGRAM_LENGTH(NDP,IDX) != 0 && \ + MBB_NDP16_GET_DATAGRAM_OFFSET(NDP,IDX) < MBB_NTH16_GET_BLOCK_LENGTH(NTH) && \ + MBB_NDP16_GET_DATAGRAM_OFFSET(NDP,IDX) <= (USHRT_MAX - MBB_NDP16_GET_DATAGRAM_LENGTH(NDP,IDX)) &&\ + (MBB_NDP16_GET_DATAGRAM_OFFSET(NDP,IDX) + MBB_NDP16_GET_DATAGRAM_LENGTH(NDP,IDX)) <= MBB_NTH16_GET_BLOCK_LENGTH(NTH) \ + ) +#define MBB_NTB16_IS_VALID_NDP_LENGTH(NTH,NDP) \ + ( \ + (MBB_NTB_GET_OFFSET(NTH,NDP) < MBB_NTH16_GET_BLOCK_LENGTH(NTH)) && \ + (MBB_NDP16_GET_LENGTH(NDP) >= FIELD_OFFSET(NCM_NDP16,Datagram)) && \ + (MBB_NTB_GET_OFFSET(NTH,NDP) <= (ULONG)(USHRT_MAX - MBB_NDP16_GET_LENGTH(NDP))) &&\ + ((MBB_NTB_GET_OFFSET(NTH,NDP)+MBB_NDP16_GET_LENGTH(NDP)) <= MBB_NTH16_GET_BLOCK_LENGTH(NTH)) \ + ) +#define MBB_NTB16_IS_VALID_NDP_SIGNATURE(NDP) \ + ( \ + ((MBB_NDP16_GET_SIGNATURE(NDP) & NCM_NDP_SIGNATURE_MASK) == NCM_NDP16_IPS) || \ + ((MBB_NDP16_GET_SIGNATURE(NDP) & NCM_NDP_SIGNATURE_MASK) == NCM_NDP16_VENDOR) \ + ) + diff --git a/network/wwan/cxwmbclass/inc/power.h b/network/wwan/cxwmbclass/inc/power.h new file mode 100644 index 000000000..4aa8593a0 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/power.h @@ -0,0 +1,7 @@ +#pragma once + +EVT_WDF_DEVICE_D0_ENTRY EvtDeviceD0Entry; +EVT_WDF_DEVICE_D0_EXIT EvtDeviceD0Exit; +EVT_WDF_DEVICE_ARM_WAKE_FROM_S0 EvtDeviceArmWakeFromS0; +EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0 EvtDeviceDisarmWakeFromS0; +EVT_NET_DEVICE_PREVIEW_WAKE_SOURCE EvtDevicePreviewBitmapPattern; diff --git a/network/wwan/cxwmbclass/inc/precomp.h b/network/wwan/cxwmbclass/inc/precomp.h new file mode 100644 index 000000000..57a1aa3f2 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/precomp.h @@ -0,0 +1,52 @@ +#pragma once + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mbbfastio.h" + +#define INITGUID +#include + +#include +#include "mbbncm.h" +#include "mbbmessages.h" + +#define MBB_MAX_NUMBER_OF_SESSIONS 17 // including the default session for the physical/primary interface +#define MBB_DEFAULT_SESSION_ID 0 // for physical/primay interface. Must be 0. Do NOT change it. +#define MBB_INVALID_SESSION_ID MBB_MAX_NUMBER_OF_SESSIONS + +#define WMBCLASS_RADIO_STATE_OFF 0 +#define WMBCLASS_RADIO_STATE_ON 1 + +#include "BusInterface.h" +#include "BusFastIO.h" + +#include "align.h" +#include "device.h" +#include "adapter.h" +#include "data.h" +#include "txqueue.h" +#include "util.h" +#include "usbbus.h" +#include "utils.h" diff --git a/network/wwan/cxwmbclass/inc/rxqueue.h b/network/wwan/cxwmbclass/inc/rxqueue.h new file mode 100644 index 000000000..0db01a789 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/rxqueue.h @@ -0,0 +1,22 @@ +#pragma once + +typedef struct _MBB_RXQUEUE_CONTEXT +{ + PWMBCLASS_NETADAPTER_CONTEXT NetAdapterContext; + LONG NotificationEnabled; + NET_RING_COLLECTION const* DatapathDescriptor; + NET_EXTENSION ReturnContextExtension; + NET_EXTENSION VirtualAddressExtension; +} MBB_RXQUEUE_CONTEXT, *PMBB_RXQUEUE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(MBB_RXQUEUE_CONTEXT, MbbGetRxQueueContext); + +EVT_WDF_OBJECT_CONTEXT_DESTROY EvtRxQueueDestroy; + +EVT_PACKET_QUEUE_SET_NOTIFICATION_ENABLED EvtRxQueueSetNotificationEnabled; +EVT_PACKET_QUEUE_ADVANCE EvtRxQueueAdvance; +EVT_PACKET_QUEUE_CANCEL EvtRxQueueCancel; + +VOID MbbNdisReceiveCallback(_In_ MBB_PROTOCOL_HANDLE ProtocolHandle, _In_ MBB_RECEIVE_CONTEXT ReceiveContext, _In_ PMDL Mdl); + +VOID EvtAdapterReturnRxBuffer(_In_ NETADAPTER Adapter, _In_ NET_FRAGMENT_RETURN_CONTEXT_HANDLE RxBufferReturnContext); diff --git a/network/wwan/cxwmbclass/inc/txqueue.h b/network/wwan/cxwmbclass/inc/txqueue.h new file mode 100644 index 000000000..239a9f420 --- /dev/null +++ b/network/wwan/cxwmbclass/inc/txqueue.h @@ -0,0 +1,19 @@ +#pragma once + +typedef struct _MBB_TXQUEUE_CONTEXT +{ + PWMBCLASS_NETADAPTER_CONTEXT NetAdapterContext; + LONG NotificationEnabled; + UINT32 CompletionBatchSize; + NET_RING_COLLECTION const* DatapathDescriptor; + NET_EXTENSION MdlExtension; +} MBB_TXQUEUE_CONTEXT, *PMBB_TXQUEUE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(MBB_TXQUEUE_CONTEXT, MbbGetTxQueueContext); + +EVT_WDF_OBJECT_CONTEXT_DESTROY EvtTxQueueDestroy; +EVT_PACKET_QUEUE_SET_NOTIFICATION_ENABLED EvtTxQueueSetNotificationEnabled; +EVT_PACKET_QUEUE_CANCEL EvtTxQueueCancel; +EVT_PACKET_QUEUE_ADVANCE EvtTxQueueAdvance; + +EVT_MBB_DEVICE_SEND_DEVICE_SERVICE_SESSION_DATA EvtMbbDeviceSendDeviceServiceSessionData; diff --git a/network/wwan/cxwmbclass/inc/usbbus.h b/network/wwan/cxwmbclass/inc/usbbus.h new file mode 100644 index 000000000..3fc87948c --- /dev/null +++ b/network/wwan/cxwmbclass/inc/usbbus.h @@ -0,0 +1,250 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +#define ALLOCATE_PAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_PAGED, _y, 'UBMW') + +#define FREE_POOL(_x) \ + { \ + ExFreePool(_x); \ + _x = NULL; \ + }; + +#define INITIALIZE_PASSIVE_LOCK(__lock) KeInitializeGuardedMutex(__lock) + +#define ACQUIRE_PASSIVE_LOCK(__lock) KeAcquireGuardedMutex(__lock) + +#define RELEASE_PASSIVE_LOCK(__lock) KeReleaseGuardedMutex(__lock) + +#define WMB_PUSH_LOCK EX_PUSH_LOCK + +#define INIT_PUSHLOCK(PushLock) ExInitializePushLock(PushLock) + +#define ACQUIRE_PUSHLOCK_EXCLUSIVE(PushLock) \ + do \ + { \ + KeEnterCriticalRegion(); \ + ExAcquirePushLockExclusive((PushLock)); \ + } while (0) + +#define RELEASE_PUSHLOCK_EXCLUSIVE(PushLock) \ + do \ + { \ + ExReleasePushLockExclusive((PushLock)); \ + KeLeaveCriticalRegion(); \ + } while (0) + +#define ACQUIRE_PUSHLOCK_SHARED(PushLock) \ + do \ + { \ + KeEnterCriticalRegion(); \ + ExAcquirePushLockShared((PushLock)); \ + } while (0) + +#define RELEASE_PUSHLOCK_SHARED(PushLock) \ + do \ + { \ + ExReleasePushLockShared((PushLock)); \ + KeLeaveCriticalRegion(); \ + } while (0) + +#define MAX_PREALLOCATED_WRITE_REQUESTS (20) + +//#define DEFAULT_INTERRUPT_PIPE_READ_SIZE (8) +#define DEFAULT_IO_TIMEOUT (10) + +#define MAX_HOST_NTB_SIZE (0x10000) +#define MAX_HOST_NTB_SIZE_FOR_UDE_MBIM (0x20000) +#define MAX_OUT_DATAGRAMS (64) + +#define INTERRUPT_REASSEMBLY_BUFFER_SIZE (64) + +#define MIN_CONTROL_MESSAGE_SIZE (64) +#define MAX_CONTROL_MESSAGE_SIZE (4096) + +#define ALT_DATA_SETTING_0_PIPES (0) +#define ALT_DATA_SETTING_1_PIPES (2) + +#define INITIAL_OPEN_TIMEOUT (5) +#define MAX_OPEN_RETRY_ATTEMPTS (4) + +#define PENDING_BULK_IN_READS (3) +#define PENDING_BULK_IN_READS_FOR_UDE_MBIM (10) + +typedef enum _BUS_STATE +{ + + BUS_STATE_CLOSED = 0, + BUS_STATE_CLOSING, + + BUS_STATE_OPENING, + BUS_STATE_OPENED + +} BUS_STATE, + *PBUS_STATE; + +typedef struct _POWER_FILTER_LOOKUP +{ + + ULONG PatternId; + BOOLEAN InUse; + +} POWER_FILTER_LOOKUP, *PPOWER_FILTER_LOOKUP; + +typedef struct _BUS_OBJECT +{ + + KGUARDED_MUTEX Lock; + BUS_STATE State; + + PDEVICE_OBJECT Pdo; + PDEVICE_OBJECT Fdo; + PDEVICE_OBJECT NextDeviceObject; + + MBB_PROTOCOL_HANDLE ProtocolHandle; + MBB_BUS_RESPONSE_AVAILABLE_CALLBACK ResponseAvailableCallback; + + MBB_BUS_DATA_RECEIVE_CALLBACK ReceiveDataCallback; + + MBB_BUS_SS_IDLE_CONFIRM_CALLBACK IdleConfirmCallback; + MBB_BUS_SS_IDLE_NOTIFICATION_COMPLETE_CALLBACK IdleNotificationComplete; + + WDFDEVICE WdfDevice; + WDFUSBDEVICE WdfUsbDevice; + + USHORT MaxControlChannelSize; + + USHORT MaxSegmentSize; + BYTE NcmParams; + BOOLEAN NtbFormat32Bit; + BYTE PowerFiltersSupported; + BYTE MaxPowerFilterSize; + + BYTE MaxOutstandingCommandMessages; + USHORT MTU; + + NCM_NTB_PARAMETER NtbParam; + + PWSTR Manufacturer; + PWSTR Model; + + ULONG MaxBulkInTransfer; + ULONG BulkInHeaderSize; + + BOOLEAN ChainedMdlsSupported; + + PIRP UsbSsIrp; + USB_IDLE_CALLBACK_INFO UsbSsCallback; + + KEVENT UsbSsIrpComplete; + + PPOWER_FILTER_LOOKUP PowerFilterTable; + + PUCHAR SyncInterruptReadBuffer; + + UCHAR InterruptReassemnblyBuffer[INTERRUPT_REASSEMBLY_BUFFER_SIZE]; + ULONG CurrentOffset; + ULONG ExpectLength; + + USHORT MbimVersion; + USHORT MbimExtendedVersion; + BOOLEAN RemoteWakeCapable; + + USB_CAP_DEVICE_INFO UsbCapDeviceInfo; + PVOID ModemContext; + + FastIOSendNetBufferListsHandler SendNetBufferListsHandler; + FastIOReturnNetBufferListsHandler ReturnNetBufferListsHandler; + FastIOCancelSendHandler CancelSendHandler; + FastIOHaltHandler HaltHandler; + FastIOPauseHandler PauseHandler; + FastIOShutdownHandler ShutdownHandler; + FastIOResetHandler ResetHandler; + FastIORestartHandler RestartHandler; +} BUS_OBJECT, *PBUS_OBJECT; + +typedef struct _WDF_DEVICE_INFO +{ + + PBUS_OBJECT BusObject; + +} WDF_DEVICE_INFO, *PWDF_DEVICE_INFO; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WDF_DEVICE_INFO, GetWdfDeviceInfo) + +// +// put this in the NIC data structure +// +typedef struct _USB_DEVICE_CONTEXT +{ + size_t NumberOfPipes; + + WDFWAITLOCK PipeStateLock; + + UCHAR UsbCommunicationInterfaceIndex; + UCHAR UsbDataInterfaceIndex; + + UCHAR UsbCommunicationInterfaceSetting; + UCHAR UsbDataInterfaceSetting; + + UCHAR WdfCommunicationInterfaceIndex; + UCHAR WdfDataInterfaceIndex; + + BOOLEAN BulkInputPipeConfigured; + BOOLEAN BulkInputPipeStarted; + ULONG BulkInputPipeMaxPacket; + WDFUSBPIPE BulkInputPipe; + + BOOLEAN BulkOutputPipeConfigured; + BOOLEAN BulkOutputPipeStarted; + ULONG BulkOutputPipeMaxPacket; + WDFUSBPIPE BulkOutputPipe; + + WDFUSBPIPE InterruptPipe; + + WDFIOTARGET InterruptPipeIoTarget; + ULONG InterruptPipeMaxPacket; + + WDFLOOKASIDE LookasideList; + + WDFSPINLOCK WriteCollectionLock; + WDFCOLLECTION WriteRequestCollection; + + WDFWORKITEM BulkPipeResetWorkitem; + LONG BulkPipeResetFlag; + EX_RUNDOWN_REF BulkPipeResetRundown; + PBUS_OBJECT BusObject; +} USB_DEVICE_CONTEXT, *PUSB_DEVICE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(USB_DEVICE_CONTEXT, GetUsbDeviceContext) + +typedef struct _REQUEST_CONTEXT +{ + + PVOID CallbackContext; + union + { + + MBB_BUS_SEND_COMPLETION_CALLBACK Send; + MBB_BUS_RECEIVE_COMPLETION_CALLBACK Receive; + + } Callback; + + MBB_PROTOCOL_HANDLE ProtocolHandle; + + PUSB_DEVICE_CONTEXT UsbDeviceContext; + + PVOID Buffer; + ULONG BufferLength; + +} REQUEST_CONTEXT, *PREQUEST_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(REQUEST_CONTEXT, GetRequestContext) + +VOID MbbBusMiniportUsbIdle(PVOID Context); + +NTSTATUS +PreAllocateWriteRequests(WDFUSBDEVICE UsbDevice); + +#define IS_USB_DEVICE_REMOTE_WAKE_CAPABLE(deviceInformation) \ + ((deviceInformation.Traits & WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE) > 0 ? TRUE : FALSE); diff --git a/network/wwan/cxwmbclass/inc/util.h b/network/wwan/cxwmbclass/inc/util.h new file mode 100644 index 000000000..b42d5233f --- /dev/null +++ b/network/wwan/cxwmbclass/inc/util.h @@ -0,0 +1,41 @@ +// +// Copyright (c) 2010 Microsoft Corporation +// + +typedef enum +{ + MbbPoolTagDefault = '0CBM', + MbbPoolTagNtbSend = '1CBM', + MbbPoolTagNblSend = '2CBM', + MbbPoolTagNbSend = '3CBM', + MbbPoolTagMdlReceive = '6CBM' +} MBB_POOL_TAG; + +#define ALLOCATE_NONPAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_NON_PAGED, _y, MbbPoolTagDefault) +#define ALLOCATE_NONPAGED_POOL_WITH_TAG(_x, _y) ExAllocatePool2(POOL_FLAG_NON_PAGED, _x, _y) + +#define FREE_POOL(_x) \ + { \ + ExFreePool(_x); \ + _x = NULL; \ + }; + +#define MIN(_X_, _Y_) (((_X_) < (_Y_)) ? (_X_) : (_Y_)) +#define MAX(_X_, _Y_) (((_X_) > (_Y_)) ? (_X_) : (_Y_)) + +#define ALIGN_FLOOR(_VALUE_, _ALIGN_) ALIGN_DOWN_BY(_VALUE_, _ALIGN_) +#define ALIGN_CIELING(_VALUE_, _ALIGN_) ALIGN_UP_BY(_VALUE_, _ALIGN_) +#define ALIGN(_VALUE_, _ALIGN_) ALIGN_CIELING(_VALUE_, _ALIGN_) +#define ALIGN_AT_OFFSET(_VALUE_, _ALIGN_, _OFFSET_) \ + (((SIZE_T)(_VALUE_) <= (ALIGN_FLOOR(_VALUE_, _ALIGN_) + (_OFFSET_))) ? (ALIGN_FLOOR(_VALUE_, _ALIGN_) + (_OFFSET_)) \ + : (ALIGN(_VALUE_, _ALIGN_) + (_OFFSET_))) + +NTSTATUS +MbbNtbValidate(_In_ PVOID Nth, _In_ ULONG BufferLength, _In_ BOOLEAN Is32Bit, _Out_opt_ ULONG* NdpCount); + +NTSTATUS +CreateNonPagedWdfMemory(_In_ ULONG ObjectSize, _Out_ WDFMEMORY* WdfMemory, _Out_opt_ PVOID* ObjectMemory, _In_ WDFOBJECT Parent, _In_ ULONG PoolTag); + +PMDL AllocateNonPagedMdl(_In_reads_bytes_(Length) PVOID VirtualAddress, _In_ ULONG Length); + +VOID MbbRecvCancelNdps(_In_ PWMBCLASS_DEVICE_CONTEXT DeviceContext, _In_ ULONG SessionId); diff --git a/network/wwan/cxwmbclass/inc/utils.h b/network/wwan/cxwmbclass/inc/utils.h new file mode 100644 index 000000000..06b15264f --- /dev/null +++ b/network/wwan/cxwmbclass/inc/utils.h @@ -0,0 +1,61 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + +NTSTATUS +SendSyncControlCommand( + __in WDFUSBDEVICE WdfUsbDevice, + __in WDF_USB_BMREQUEST_DIRECTION Direction, + __in WDF_USB_BMREQUEST_RECIPIENT Recipient, + __in BYTE Request, + __in USHORT Value, + __inout_bcount_opt(BufferLength) PUCHAR Buffer, + __in ULONG BufferLength, + __out_opt PULONG BytesTransfered); + +NTSTATUS +TransactControlChannel( + __in PBUS_OBJECT BusObject, + __in ULONG TimeOut, + __in_bcount_opt(InBufferLength) PUCHAR InBuffer, + __in ULONG InBufferLength, + __out_bcount_opt(OutBufferLength) PUCHAR OutBuffer, + __in ULONG OutBufferLength, + __out PULONG BytesRead); + +NTSTATUS +ReadInterrupt(_In_ PBUS_OBJECT BusObject, _Inout_updates_bytes_(BufferLength) PUCHAR Buffer, _In_ ULONG BufferLength, _In_ ULONG Timeout, _Out_ PULONG BytesRead); + +NTSTATUS +GetDeviceString(__in WDFUSBDEVICE UsbDevice, __in UCHAR Index, __out PWSTR* String); + +NTSTATUS +MbbBusSetPacketFilter(__in MBB_BUS_HANDLE BusHandle, __in ULONG PacketFilter); + +NTSTATUS +MbbBusSetNtbInSize(__in MBB_BUS_HANDLE BusHandle, __in ULONG InSize); + +NTSTATUS +MbbBusGetStat(__in MBB_BUS_HANDLE BusHandle, __in USHORT StatIndex, __out ULONGLONG* Value); + +NTSTATUS +MbbBusSetNtbFormat(__in MBB_BUS_HANDLE BusHandle, __in USHORT Format); + +NTSTATUS +MbbBusResetFunction(__in MBB_BUS_HANDLE BusHandle); + +ULONG +ProcessInterruptPipeRead( + PBUS_OBJECT BusObject, + __in_ecount(NewFragmentLength) PCUCHAR NewFragment, + ULONG NewFragmentLength, + __out_ecount(MessageBufferSize) PUCHAR CompleteMessageBuffer, + ULONG MessageBufferSize); + +NTSTATUS +WaitForResponseAvailible(PBUS_OBJECT BusObject, ULONG TimeOut); + +NTSTATUS +MbbBusResetDeviceAndSetParms(__in PBUS_OBJECT BusObject); + +BOOLEAN IsUsbCapDeviceInfoValid(_In_ USB_CAP_DEVICE_INFO UsbCapDeviceInfo, _In_ ULONG CapResultLength); diff --git a/network/wwan/cxwmbclass/init.c b/network/wwan/cxwmbclass/init.c deleted file mode 100644 index 17a8bb12e..000000000 --- a/network/wwan/cxwmbclass/init.c +++ /dev/null @@ -1,2269 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -#include "precomp.h" -#include "init.tmh" -#include "WMBClassTelemetry.h" - -MINIPORT_DRIVER_CONTEXT GlobalControl = {0}; - -const NDIS_OID WmbClassSupportedOids[] = -{ - - OID_GEN_SUPPORTED_LIST, - OID_GEN_MEDIA_IN_USE, - OID_GEN_MAXIMUM_LOOKAHEAD, - OID_GEN_MAXIMUM_TOTAL_SIZE, - OID_GEN_TRANSMIT_BUFFER_SPACE, - OID_GEN_RECEIVE_BUFFER_SPACE, - OID_GEN_TRANSMIT_BLOCK_SIZE, - OID_GEN_RECEIVE_BLOCK_SIZE, - OID_GEN_VENDOR_DESCRIPTION, - OID_GEN_DRIVER_VERSION, - OID_GEN_VENDOR_ID, - OID_GEN_VENDOR_DRIVER_VERSION, - OID_GEN_CURRENT_LOOKAHEAD, - OID_GEN_MAXIMUM_FRAME_SIZE, - OID_GEN_MAXIMUM_SEND_PACKETS, - OID_GEN_XMIT_OK, - OID_GEN_RCV_OK, - OID_GEN_XMIT_ERROR, - OID_GEN_RCV_ERROR, - OID_GEN_RCV_NO_BUFFER, - OID_GEN_PHYSICAL_MEDIUM, - OID_GEN_STATISTICS, - OID_GEN_MEDIA_SUPPORTED, - OID_GEN_CURRENT_PACKET_FILTER, - OID_PM_PARAMETERS, - OID_PM_ADD_WOL_PATTERN, - OID_PM_REMOVE_WOL_PATTERN, - OID_WWAN_DRIVER_CAPS, - OID_WWAN_DEVICE_CAPS, - OID_WWAN_READY_INFO, - OID_WWAN_RADIO_STATE, - OID_WWAN_PIN_EX, - OID_WWAN_PIN_LIST, - OID_WWAN_HOME_PROVIDER, - OID_WWAN_PREFERRED_PROVIDERS, - OID_WWAN_VISIBLE_PROVIDERS, - OID_WWAN_REGISTER_STATE, - OID_WWAN_PACKET_SERVICE, - OID_WWAN_SIGNAL_STATE, - OID_WWAN_CONNECT, - OID_WWAN_PROVISIONED_CONTEXTS, - OID_WWAN_SERVICE_ACTIVATION, - OID_WWAN_SMS_CONFIGURATION, - OID_WWAN_SMS_READ, - OID_WWAN_SMS_SEND, - OID_WWAN_SMS_DELETE, - OID_WWAN_SMS_STATUS, - OID_WWAN_VENDOR_SPECIFIC, - OID_WWAN_USSD, - OID_WWAN_AUTH_CHALLENGE, - OID_WWAN_ENUMERATE_DEVICE_SERVICES, - OID_WWAN_DEVICE_SERVICE_COMMAND, - OID_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS, - OID_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS, - OID_WWAN_DEVICE_SERVICE_SESSION, - OID_WWAN_DEVICE_SERVICE_SESSION_WRITE, - OID_WWAN_PREFERRED_MULTICARRIER_PROVIDERS, - OID_WWAN_CREATE_MAC, - OID_WWAN_DELETE_MAC, - OID_WWAN_UICC_FILE_STATUS, - OID_WWAN_UICC_ACCESS_BINARY, - OID_WWAN_UICC_ACCESS_RECORD, - OID_WWAN_PIN_EX2, - OID_WWAN_MBIM_VERSION, - OID_WWAN_SYS_CAPS, - OID_WWAN_DEVICE_CAPS_EX, - OID_WWAN_SYS_SLOTMAPPINGS, - OID_WWAN_SLOT_INFO_STATUS, - OID_WWAN_DEVICE_BINDINGS, - OID_WWAN_REGISTER_STATE_EX, - OID_WWAN_IMS_VOICE_STATE, - OID_WWAN_SIGNAL_STATE_EX, - OID_WWAN_LOCATION_STATE, - OID_WWAN_NITZ, - OID_WWAN_NETWORK_IDLE_HINT, - OID_WWAN_PRESHUTDOWN, - OID_WWAN_UICC_ATR, - OID_WWAN_UICC_OPEN_CHANNEL, - OID_WWAN_UICC_CLOSE_CHANNEL, - OID_WWAN_UICC_APDU, - OID_WWAN_UICC_TERMINAL_CAPABILITY, - OID_WWAN_SAR_CONFIG, - OID_WWAN_SAR_TRANSMISSION_STATUS, - OID_WWAN_LTE_ATTACH_CONFIG, - OID_WWAN_LTE_ATTACH_STATUS, - OID_WWAN_NETWORK_BLACKLIST, - OID_WWAN_PCO, - OID_WWAN_UICC_RESET, - OID_WWAN_DEVICE_RESET, - OID_WWAN_BASE_STATIONS_INFO, - OID_WWAN_UICC_APP_LIST, -}; - -const UINT WmbClassSupportedOidsNum = sizeof(WmbClassSupportedOids) / sizeof(NDIS_OID); - -//volatile ULONG MbbGlobalTestFlags = MbbTestFlagNone; - -DRIVER_INITIALIZE DriverEntry; - -NDIS_STATUS -InitializeGeneralAttributes( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PNDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES GeneralAttributes, - __out PNDIS_PM_CAPABILITIES PnpCaps - ); - -MINIPORT_UNLOAD MbbNdisDriverUnload; - -MINIPORT_INITIALIZE MbbNdisMiniportInitialize; - -MINIPORT_SHUTDOWN MbbNdisMiniportShutdownEx; - -MINIPORT_HALT MbbNdisMiniportHaltEx; - -MINIPORT_SET_OPTIONS MbbNdisMiniportSetOption; - -MINIPORT_PAUSE MbbNdisMiniportPause; - -MINIPORT_RESTART MbbNdisMiniportRestart; - -MINIPORT_DEVICE_PNP_EVENT_NOTIFY MbbNdisMiniportDevicePnPEventNotify; - -MINIPORT_RESET MbbNdisMiniportResetEx; - -MINIPORT_CHECK_FOR_HANG MbbNdisMiniportCheckForHangEx; - -MINIPORT_IDLE_NOTIFICATION MbbNdisMiniportIdleNotification; - -MINIPORT_CANCEL_IDLE_NOTIFICATION MbbNdisMiniportCancelIdleNotification; - -NTSTATUS -SendOpenCommand( - PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -NTSTATUS -SendCloseCommand( - PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -VOID -MbbNdisResponseFragmentAvailable( - __in MBB_PROTOCOL_HANDLE ProtocolHandle - ); - - -NDIS_STATUS -MbbNdisAdapterReadParameters( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -VOID -AdapterPauseHandler( - PSTATE_CHANGE_EVENT StateChange - ); - -VOID -AdapterRestartHandler( - PSTATE_CHANGE_EVENT StateChange - ); - - -VOID -AdapterPowerHandler( - PSTATE_CHANGE_EVENT StateChange - ); - -VOID -AdapterResetHandler( - PSTATE_CHANGE_EVENT StateChange - ); - - -VOID -MbbNdisMiniportBusIdleConfirm( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in DEVICE_POWER_STATE PowerState - ); - -VOID -MbbNdisMiniportIdleNotificationComplete( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in NTSTATUS Status - ); - -VOID -MbbSystemPowerNotification( - _In_ NDIS_HANDLE MiniportAdapterContext, - _In_ NDIS_MINIPORT_SYSPOWER_NOTIFY const *SystemPowerNotification - ); - -void -NTAPI MbbDumpAdapterState( - _In_ LPCGUID SourceId, - _In_ ULONG IsEnabled, - _In_ UCHAR Level, - _In_ ULONGLONG MatchAnyKeyword, - _In_ ULONGLONG MatchAllKeywords, - _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, - _In_opt_ PVOID CallbackContext -); - -#pragma alloc_text(PAGE, MbbNdisDriverUnload) -#pragma alloc_text(PAGE, MbbNdisMiniportHaltEx) -#pragma alloc_text(PAGE, MbbNdisMiniportPause) -#pragma alloc_text(PAGE, MbbNdisMiniportRestart) -#pragma alloc_text(PAGE, MbbNdisMiniportDevicePnPEventNotify) -#pragma alloc_text(PAGE, MbbNdisMiniportInitialize) -#pragma alloc_text(PAGE, InitializeGeneralAttributes) -#pragma alloc_text(PAGE, DriverEntry) - -NTSTATUS -DriverEntry( - PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath - ) -/*++ -Routine Description: - - In the context of its DriverEntry function, a miniport driver associates - itself with NDIS, specifies the NDIS version that it is using, and - registers its entry points. - - -Arguments: - PVOID DriverObject - pointer to the driver object. - PVOID RegistryPath - pointer to the driver registry path. - - Return Value: - - NDIS_STATUS_xxx code - ---*/ -{ - NDIS_STATUS Status = STATUS_UNSUCCESSFUL; - NDIS_MINIPORT_DRIVER_CHARACTERISTICS Characteristics; - WDF_DRIVER_CONFIG config; - NTSTATUS ntStatus; - - PAGED_CODE(); - - do - { - WPP_INIT_TRACING(DriverObject,RegistryPath); - TraceLoggingRegister(g_hLoggingProvider); - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK); - - InitializeListHead( &GlobalControl.AdapterList ); - NdisAllocateSpinLock( &GlobalControl.AdapterListLock ); - - ntStatus=EtwRegister(&WmbclassServiceTrace, MbbDumpAdapterState, NULL, &GlobalControl.TraceHandle); - - if (!NT_SUCCESS(ntStatus)){ - - TraceError(WMBCLASS_INIT, "EtwRegister failed %08lx", ntStatus); - Status = ntStatus; - break; - } - - MbbWriteEvent( - &WMBCLASS_DRIVER_LOAD, - NULL, - NULL, - 1, - &RegistryPath->Buffer, - RegistryPath->Length - ); - - ntStatus=EtwRegister(&WmbclassServiceTraceOpn, NULL, NULL, &GlobalControl.TraceHandleOpn); - - if (!NT_SUCCESS(ntStatus)){ - - TraceError(WMBCLASS_INIT, "EtwRegister(Opn) failed %08lx", ntStatus); - // - // Don't fail the driver load if OPN trace handle cannot be registered - // - } - - // - // Set WdfDriverInitNoDispatchOverride flag to tell the framework - // not to provide dispatch routines for the driver. In other words, - // the framework must not intercept IRPs that the I/O manager has - // directed to the driver. In this case, it will be handled by NDIS - // port driver. - // - config.DriverInitFlags |= WdfDriverInitNoDispatchOverride; - - ntStatus = WdfDriverCreate(DriverObject, - RegistryPath, - WDF_NO_OBJECT_ATTRIBUTES, - &config, - &GlobalControl.hDriver); //vm control - - if (!NT_SUCCESS(ntStatus)){ - - TraceError(WMBCLASS_INIT, "WdfDriverCreate failed %08lx", ntStatus); - Status = NDIS_STATUS_FAILURE; - break; - } - - // - // Fill in the Miniport characteristics structure with the version numbers - // and the entry points for driver-supplied MiniportXxx - // - NdisZeroMemory(&Characteristics, sizeof(Characteristics)); - - - Characteristics.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS, - Characteristics.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS); - Characteristics.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_3; - Characteristics.MajorNdisVersion = 6; - Characteristics.MinorNdisVersion = 80; - Characteristics.MajorDriverVersion = 1; - Characteristics.MinorDriverVersion = 0; - - // - // Init/PnP handlers - // - Characteristics.UnloadHandler = MbbNdisDriverUnload; - - Characteristics.InitializeHandlerEx = MbbNdisMiniportInitialize; - Characteristics.HaltHandlerEx = MbbNdisMiniportHaltEx; - - Characteristics.RestartHandler = MbbNdisMiniportRestart; - Characteristics.PauseHandler = MbbNdisMiniportPause; - - Characteristics.DevicePnPEventNotifyHandler = MbbNdisMiniportDevicePnPEventNotify; - - Characteristics.ShutdownHandlerEx = MbbNdisMiniportShutdownEx; - - Characteristics.SetOptionsHandler = MbbNdisMiniportSetOption; - -#if 0 - // - // reset - // - Characteristics.ResetHandlerEx = MbbNdisMiniportResetEx; - Characteristics.CheckForHangHandlerEx = MbbNdisMiniportCheckForHangEx; - -#endif - // - // Query/Set/Method requests handlers - // - Characteristics.OidRequestHandler = MbbNdisMiniportOidRequest; - Characteristics.CancelOidRequestHandler = MbbNdisMiniportCancelOidRequest; - - // - // Send/Receive handlers - // - Characteristics.SendNetBufferListsHandler = MbbNdisMiniportSendNetBufferLists; - Characteristics.ReturnNetBufferListsHandler = MbbNdisMiniportReturnNetBufferLists; - Characteristics.CancelSendHandler = MbbNdisMiniportCancelSend; - - Characteristics.Flags = NDIS_WDM_DRIVER; - - TraceVerbose(WMBCLASS_INIT, "Calling NdisMRegisterMiniportDriver..."); - // - // Register with IP Helper for IP change notifications. - // - ntStatus = MbbIpInitialize( &GlobalControl ); - if( ntStatus != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to initialize IP subsystem, status=%!STATUS!", ntStatus ); - Status = NDIS_STATUS_FAILURE; - break; - } - // - // Registers miniport's entry points with the NDIS library as the first - // step in NIC driver initialization. The NDIS will call the - // MiniportInitialize when the device is actually started by the PNP - // manager. - // - if( (Status = NdisMRegisterMiniportDriver( - DriverObject, - RegistryPath, - (PNDIS_HANDLE)&GlobalControl, - &Characteristics, - &GlobalControl.NdisDriverHandle - )) != NDIS_STATUS_SUCCESS ) - { - TraceError(WMBCLASS_INIT, "NdisMRegisterMiniportDriver() failed %08lx", Status); - break; - } - } - while( FALSE ); - - if( NT_ERROR(Status) ) - { - MbbIpCleanup( &GlobalControl ); - - if (GlobalControl.TraceHandle != 0) - { - EtwUnregister(GlobalControl.TraceHandle); - TraceLoggingUnregister(g_hLoggingProvider); - GlobalControl.TraceHandle=0; - } - - if (GlobalControl.TraceHandleOpn != 0) - { - EtwUnregister(GlobalControl.TraceHandleOpn); - GlobalControl.TraceHandleOpn=0; - } - - WPP_CLEANUP(DriverObject); - } - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return Status; -} - -VOID -MbbNdisDriverUnload( - __in PDRIVER_OBJECT DriverObject - ) -/*++ - -Routine Description: - - The unload handler is called during driver unload to free up resources - acquired in DriverEntry. Note that an unload handler differs from - a MiniportHalt function in that the unload handler has a more global - scope, whereas the scope of the MiniportHalt function is restricted - to a particular miniport driver instance. - - During an unload operation, an NDIS 6.0 miniport driver must deregister - the miniport driver by calling NdisMDeregisterMiniportDriver - and passing the MiniportDriverHandle as a parameter. - The driver obtained the MiniportDriverHandle when it called - NdisMRegisterMiniportDriver. - - Runs at IRQL = PASSIVE_LEVEL. - -Arguments: - - DriverObject Not used - -Return Value: - - None - ---*/ -{ - PAGED_CODE(); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - UNREFERENCED_PARAMETER(DriverObject); - - MbbIpCleanup( &GlobalControl ); - - WdfDriverMiniportUnload(WdfGetDriver()); - - NdisMDeregisterMiniportDriver(GlobalControl.NdisDriverHandle); - - if (GlobalControl.TraceHandle != 0) - { - EtwUnregister(GlobalControl.TraceHandle); - TraceLoggingUnregister(g_hLoggingProvider); - GlobalControl.TraceHandle=0; - } - - if (GlobalControl.TraceHandleOpn != 0) - { - EtwUnregister(GlobalControl.TraceHandleOpn); - GlobalControl.TraceHandleOpn=0; - } - - ASSERT( IsListEmpty( &GlobalControl.AdapterList ) ); - NdisFreeSpinLock( &GlobalControl.AdapterListLock ); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - WPP_CLEANUP(DriverObject); -} - -NDIS_STATUS -MbbNdisMiniportInitialize( - __in NDIS_HANDLE MiniportAdapterHandle, - __in NDIS_HANDLE MiniportDriverContext, - __in PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters - ) -/*++ -Routine Description: - - The MiniportInitialize function is a required function. Here is the - list of things this function typically performs: - - Set the miniport attributes. - Read configuration parameters from the registry. - Allocate memory. - Allocate the NET_BUFFER_LIST pool and the NET_BUFFER pool. - Do hardware specific initialization like registering interrupt handlers/ set DMA resources etc. - Read and write to the bus-specific configuration space. - - MiniportInitialize runs at IRQL = PASSIVE_LEVEL. - -Arguments: - - MiniportAdapterHandle The handle NDIS uses to refer to us - MiniportDriverContext Handle passed to NDIS when we registered the driver - MiniportInitParameters Initialization parameters contains a pointer - to a list of the allocated hardware resources - for the miniport adapter - -Return Value: - - NDIS_STATUS_xxx code - ---*/ -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - BOOLEAN SendQueueInitialized = FALSE; - BOOLEAN RecvQueueInitialized = FALSE; - NDIS_MINIPORT_ADAPTER_ATTRIBUTES MiniportAttributes; - NDIS_MINIPORT_SS_CHARACTERISTICS SelectiveSuspend; - PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; - ULONG_PTR ModelNameLength=0; - ULONG TempInstance=0; - NDIS_PM_CAPABILITIES PnpCaps; - int i = 0; - PMBB_PORT DefaultPort = NULL; - - PAGED_CODE(); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - -#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocates a miniport adapter attributes structure, released in MbbNdisMiniportHaltEx.") - Adapter=ALLOCATE_NONPAGED_POOL(sizeof(*Adapter)); - - if (Adapter == NULL) - { - - TraceError(WMBCLASS_INIT, "[Init] FAILED to allocate adapter context"); - Status=NDIS_STATUS_RESOURCES; - goto Cleanup; - } - - NdisZeroMemory(Adapter,sizeof(*Adapter)); - - // - // init elements of the adapter structure - // - NdisAllocateSpinLock(&Adapter->Lock); - - Adapter->TraceInstance=InterlockedIncrement(&GlobalControl.CurrentTraceInstance); - TempInstance=Adapter->TraceInstance; - - Adapter->MiniportAdapterHandle = MiniportAdapterHandle; - - Adapter->IfIndex=MiniportInitParameters->IfIndex; - Adapter->NetLuid=MiniportInitParameters->NetLuid; - Adapter->MaxActivatedContexts = 1; // initialize to 1.OID_WWAN_DRIVER_CAPS should return the correct value. - Adapter->SurpriseRemoved = FALSE; - - RtlInitAnsiString(&Adapter->FriendlyName, NULL); - - NdisAllocateSpinLock(&Adapter->PortsLock); - - NdisAllocateSpinLock(&Adapter->SessionIdPortTableLock); - - //Initialize all session Ids as available - for(i=0; i < ARRAYSIZE(Adapter->SessionIdPortTable); i++) - { - Adapter->SessionIdPortTable[i].InUse = FALSE; - Adapter->SessionIdPortTable[i].PortNumber = (ULONG)MBB_INVALID_PORT_NUMBER; - } - - MbbWriteEvent( - &INITIALIZE_EVENT, - NULL, - NULL, - 1, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance) - ); - - // - // object managed state of adapter while processing power and pnp events - // - Status=InitAdapterStateObject( - &Adapter->AdapterState, - Adapter->MiniportAdapterHandle, - AdapterPauseHandler, - AdapterRestartHandler, - AdapterPowerHandler, - AdapterResetHandler, - AdapterStallClearHandler - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "InitAdapterStateObject with %!STATUS!", Status); - goto Cleanup; - - } - - - Status=GetDeviceFriendlyName( MiniportAdapterHandle, &Adapter->FriendlyName); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] GetDeviceFriendlyName with %!STATUS!", Status); - goto Cleanup; - - } - - NdisMGetDeviceProperty( - MiniportAdapterHandle, - &Adapter->Pdo, - &Adapter->Fdo, - &Adapter->NextDeviceObject, - NULL, - NULL - ); - - - Status=MbbBusInitialize( - Adapter->Pdo, - Adapter->Fdo, - Adapter->NextDeviceObject, - MbbNdisResponseFragmentAvailable, - MbbNdisReceiveCallback, - MbbNdisMiniportBusIdleConfirm, - MbbNdisMiniportIdleNotificationComplete, - Adapter, - GlobalControl.TraceHandle, - Adapter->TraceInstance, - &Adapter->BusHandle - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] MbbBusInitialize with %!STATUS!", Status); - goto Cleanup; - - } - // - // Initialize the OID/CID handlers before the device is OPENED. - // Once the device is opened and the interrupt pipe is connected - // ReqMgr will start receiving unsolicited indications from the device. - // - Status = MbbBusQueryBusParameters( - Adapter->BusHandle, - &Adapter->BusParams - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] MbbBusQueryBusParameters() with %!STATUS!", Status); - goto Cleanup; - } - - if( (Status = MbbReqMgrInitialize( - &(Adapter->RequestManagerAllocation), - Adapter - )) != NDIS_STATUS_SUCCESS ) - { - goto Cleanup; - } - MbbAdapterSetRequestManager( - Adapter, - &(Adapter->RequestManagerAllocation) - ); - - if (Adapter->BusParams.PowerFiltersSupported > 0) - { - ULONG i = 0; - - Adapter->PowerFilterTable=(PPOWER_FILTER_LOOKUP)ALLOCATE_NONPAGED_POOL(sizeof(POWER_FILTER_LOOKUP) * Adapter->BusParams.PowerFiltersSupported); - - if (Adapter->PowerFilterTable == NULL) - { - TraceError(USBBUS_ALL, "power filter table"); - Status=STATUS_NO_MEMORY; - goto Cleanup; - - } - - RtlZeroMemory(Adapter->PowerFilterTable, sizeof(POWER_FILTER_LOOKUP) * Adapter->BusParams.PowerFiltersSupported); - - for (i = 0; i < Adapter->BusParams.PowerFiltersSupported; i++) - { - Adapter->PowerFilterTable[i].PortNumber = MBB_INVALID_PORT_NUMBER; - } - } - - - Status=MbbBusOpen(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FastIOSendNetBufferListsComplete, FastIOIndicateReceiveNetBufferLists); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] MbbBusOpen(1) with %!STATUS!", Status); - - MbbBusClose(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), TRUE); - - Status=MbbBusOpen(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FastIOSendNetBufferListsComplete, FastIOIndicateReceiveNetBufferLists); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] MbbBusOpen(2) with %!STATUS!", Status); - - goto Cleanup; - } - } - // - // Set the miniport registration attributes with NDIS - // - NdisZeroMemory(&MiniportAttributes, sizeof(MiniportAttributes)); - MiniportAttributes.RegistrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES; - MiniportAttributes.RegistrationAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1; - MiniportAttributes.RegistrationAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES); - - MiniportAttributes.RegistrationAttributes.MiniportAdapterContext = Adapter; - MiniportAttributes.RegistrationAttributes.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_NDIS_WDM | - NDIS_MINIPORT_ATTRIBUTES_SURPRISE_REMOVE_OK | - NDIS_MINIPORT_ATTRIBUTES_NO_PAUSE_ON_SUSPEND ; - - MiniportAttributes.RegistrationAttributes.CheckForHangTimeInSeconds = WMBCLASS_CHECK_FOR_HANG_INTERVAL; - MiniportAttributes.RegistrationAttributes.InterfaceType = WMBCLASS_INTERFACE_TYPE; - - Status=NdisMSetMiniportAttributes( - MiniportAdapterHandle, - &MiniportAttributes - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] NdisMSetMiniportAttributes(registration) with Status=%!STATUS!", Status); - goto Cleanup; - - } - - Status = MbbAdapterQueryDeviceId( Adapter ); - if( NT_ERROR( Status ) ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to query DeviceId with NdisStatus=%!STATUS!", Status ); - goto Cleanup; - } - - Status=InitializeGeneralAttributes(Adapter,&MiniportAttributes.GeneralAttributes,&PnpCaps); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] InitializeGeneralAttributes with Status=%!STATUS!", Status); - goto Cleanup; - - } - - Status=NdisMSetMiniportAttributes( - MiniportAdapterHandle, - &MiniportAttributes - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "[Init] NdisMSetMiniportAttributes(general) with Status=%!STATUS!", Status); - goto Cleanup; - - } - - - // - // init the stat structure - // - Adapter->Stats.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - Adapter->Stats.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1; - Adapter->Stats.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; - - Adapter->Stats.SupportedStatistics= \ - NDIS_STATISTICS_XMIT_OK_SUPPORTED \ - | NDIS_STATISTICS_RCV_OK_SUPPORTED \ - | NDIS_STATISTICS_XMIT_ERROR_SUPPORTED \ - | NDIS_STATISTICS_RCV_ERROR_SUPPORTED \ - | NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED \ - | NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED \ - | NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED \ - | NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED \ - | NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED \ - | NDIS_STATISTICS_BYTES_RCV_SUPPORTED \ - | NDIS_STATISTICS_BYTES_XMIT_SUPPORTED \ - | NDIS_STATISTICS_RCV_DISCARDS_SUPPORTED \ - | NDIS_STATISTICS_XMIT_DISCARDS_SUPPORTED; - - if( (Status = MbbNdisAdapterReadParameters( Adapter )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to read adapter parameters, status=%!STATUS!", Status ); - goto Cleanup; - } - - Status=RtlStringCbLengthW( - Adapter->BusParams.Model, - sizeof(Adapter->BusParams.Model), - &ModelNameLength - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "RtlStringCbLength with %!STATUS!", Status); - goto Cleanup; - - } - - if (Adapter->OverrideDeviceName) - { - if (ModelNameLength > 0) - { - // - // Update the device name with the model from the USB descriptor - // - Status = IoSetDevicePropertyData( - Adapter->Pdo, - &DEVPKEY_Device_FriendlyName, - 0, - PLUGPLAY_PROPERTY_PERSISTENT, - DEVPROP_TYPE_STRING, - (ULONG)ModelNameLength + sizeof(WCHAR), - Adapter->BusParams.Model - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "IoSetDevicePropertyData with %!STATUS!", Status); - - Status=STATUS_SUCCESS; - - } - } - } - // - // Initialize the data queues. - // They would not be active until the miniport is put in the started state. - // - if( (Status = MbbSendQInitialize( - &Adapter->SendQueue, - MAX_PENDING_SENDS, - DrainCompleteCallback, - Adapter, - Adapter, - Adapter->BusHandle, - Adapter->MiniportAdapterHandle - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to initialize send queue, status=%!STATUS!", Status ); - goto Cleanup; - } - SendQueueInitialized = TRUE; - - if( (Status = MbbRecvQInitialize( - &Adapter->ReceiveQueue, - DrainCompleteCallback, - Adapter, - Adapter->MiniportAdapterHandle - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to initialize receive queue, status=%!STATUS!", Status ); - goto Cleanup; - } - RecvQueueInitialized = TRUE; - - // Perform some requests that we need to do to get setup - if( (Status = MbbAdapterPerformInitialRequests( Adapter )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[Init] FAILED to perform initial requests, status=%!STATUS!", Status ); - goto Cleanup; - } - -//#define TEST_CODE -#ifdef TEST_CODE - MbbAdapterConfigureDeviceServiceSubscription( - Adapter, - FALSE, - NDIS_WWAN_WAKE_ON_REGISTER_STATE_ENABLED | - NDIS_WWAN_WAKE_ON_SMS_RECEIVE_ENABLED | - NDIS_WWAN_WAKE_ON_USSD_RECEIVE_ENABLED | - NDIS_WWAN_WAKE_ON_PACKET_STATE_ENABLED | - NDIS_WWAN_WAKE_ON_UICC_CHANGE_ENABLED - ); - - MbbAdapterConfigureDeviceServiceSubscription( - Adapter, - TRUE, - NDIS_WWAN_WAKE_ON_REGISTER_STATE_ENABLED | - NDIS_WWAN_WAKE_ON_SMS_RECEIVE_ENABLED | - NDIS_WWAN_WAKE_ON_USSD_RECEIVE_ENABLED | - NDIS_WWAN_WAKE_ON_PACKET_STATE_ENABLED | - NDIS_WWAN_WAKE_ON_UICC_CHANGE_ENABLED - ); - - { - UCHAR Mask=0xff; - UCHAR Pattern[8]={1,2,3,4,5,6,7,8}; - - MbbUtilSetPowerFilterPattern( - Adapter, - MBB_DEFAULT_SESSION_ID, - 1, - &Mask, - sizeof(Mask), - (PCUCHAR)&Pattern, - sizeof(Pattern) - ); - - MbbAdapterConfigurePacketFilters(Adapter,TRUE); - } -#endif - - MbbAdapterSetShutdownNotificationCapabilities( Adapter ); - - TraceLoggingWrite( - g_hLoggingProvider, - "ShutdownCapability", - TraceLoggingUInt64(Adapter->AdapterFlags.IsPreshutdownCapable, "IsPreshutdownCapable"), - TraceLoggingUInt64(Adapter->AdapterFlags.ShutdownNotificationCapable, "ShutdownNotificationCapable"), - TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); - - MbbAdapterSetOptionalServiceSupport(Adapter); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: OptionalServiceCapability SAR %d NetworkBlacklist %d ProvisionedContextV2 %d LTEAttachConfig %d MultiSIM %d UiccLowLevel %d PCO %d DeviceReset %d BaseStationsInfo %d", - Adapter->AdapterFlags.IsSARCapable, Adapter->AdapterFlags.IsNetworkBlacklistCapable, Adapter->AdapterFlags.IsProvisionedContextV2Capable, - Adapter->AdapterFlags.IsLTEAttachConfigCapable, Adapter->AdapterFlags.IsMultiSIMCapable, Adapter->AdapterFlags.IsUiccLowLevelCapable, - Adapter->AdapterFlags.IsPcoCapable, Adapter->AdapterFlags.IsDeviceResetCapable, Adapter->AdapterFlags.IsBaseStationsInfoCapable); - - TraceLoggingWrite( - g_hLoggingProvider, - "OptionalServiceCapability", - TraceLoggingUInt64(Adapter->AdapterFlags.IsSARCapable, "IsSARCapable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsNetworkBlacklistCapable, "IsNetworkBlacklistCapable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsProvisionedContextV2Capable, "IsProvisionedContextV2Capable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsLTEAttachConfigCapable, "IsLTEAttachConfigCapable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsMultiSIMCapable, "IsMultiSIMCapable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsUiccLowLevelCapable, "IsUiccLowLevelCapable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsDeviceCapsV2Capable, "IsDeviceCapsV2Capable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsPcoCapable, "IsPcoCapable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsDeviceResetCapable, "IsDeviceResetCapable"), - TraceLoggingUInt64(Adapter->AdapterFlags.IsBaseStationsInfoCapable, "IsBaseStationsInfoCapable"), - TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); - - MbbDriverAddAdapter( &GlobalControl, Adapter ); - - // Clear the adapter port list - NdisZeroMemory(Adapter->PortList, sizeof(MBB_PORT*) * MBB_MAX_NUMBER_OF_PORTS); - - // Allocate the adapter port corresponding to default NDIS port ( port number 0). We are - // not managing port 0, however the adapter maintains a list of ports on which data/control traffic flows. - // Instead of managing Port 0 separately, we will attach it to the list of ports maintained by the adapter itself. - - Status = MbbWwanAllocatePort(Adapter, FALSE, &DefaultPort); // FALSE because we dont want to handle NDIS default port ourselves. - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "MbbWwanAllocatePort failed with %!STATUS!", Status); - goto Cleanup; - } - - ASSERT(DefaultPort->PortNumber == DEFAULT_NDIS_PORT_NUMBER); - - // Add the port to adapter ports list - MbbWwanAddPortToAdapterList(Adapter,&DefaultPort); - -Cleanup: - - if (Status != NDIS_STATUS_SUCCESS) - { - if (Adapter != NULL) - { - PMBB_REQUEST_MANAGER RequestManager; - PMBB_PORT Port = NULL; - - if (Adapter->BusHandle != NULL) - { - MbbBusClose(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FALSE); - } - - if( SendQueueInitialized == TRUE ) - MbbSendQCleanup( &Adapter->SendQueue ); - - if( RecvQueueInitialized == TRUE ) - MbbRecvQCleanup( &Adapter->ReceiveQueue ); - - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) != NULL ) - { - MbbReqMgrCleanup( RequestManager ); - } - - WaitStallClearComplete(&Adapter->AdapterState); - - if (Adapter->BusHandle != NULL) - { - MbbBusCleanup(Adapter->BusHandle); - Adapter->BusHandle = NULL; - } - - if((Port = Adapter->PortList[0]) != NULL) // if default port is allocated - { - // remove it from the adapter port list - MbbWwanRemovePortFromAdapterList(Adapter,Port); - - // Deallocate the port. It will get cleaned up when - // its reference goes to 0 - MbbWwanDeallocatePort(Port); - } - - FreeAdapterBlock(Adapter); - Adapter=NULL; - } - - TraceError(WMBCLASS_INIT, "[Init] miniport init failed with %08lx", Status); - } - - MbbWriteEvent( - &INITIALIZE_EXIT_EVENT, - NULL, - NULL, - 2, - &TempInstance, - sizeof(TempInstance), - &Status, - sizeof(Status) - ); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return Status; - -} - -/****************************************************************************/ -/* InitializeGeneralizeAttributes */ -/****************************************************************************/ -/* */ -/* Routine Description: */ -/* */ -/* Queries the device for information and initializes the general */ -/* attributes structure */ -/* */ -/* Arguments: */ -/* */ -/* Adapter - Pointer to the adapter structure */ -/* GeneralAttributes - Pointer to the general attributes structure */ -/* (Zeroed out by the caller) */ -/* */ -/* Return: */ -/* */ -/* NDIS_STATUS_SUCCESS on succes, error code otherwise */ -/* */ -/****************************************************************************/ - -NDIS_STATUS -InitializeGeneralAttributes( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PNDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES GeneralAttributes, - __out PNDIS_PM_CAPABILITIES PnpCaps - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - NDIS_STRING IfTypeStr = NDIS_STRING_CONST("*IfType"); - ULONG MediaState; - DWORD MaxPowerFilterSize = 0; - - PAGED_CODE(); - - GeneralAttributes->Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES; - GeneralAttributes->Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;//6.2 - GeneralAttributes->Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;//6.2 - - GeneralAttributes->MediaType = NdisMediumWirelessWan; - GeneralAttributes->PhysicalMediumType = NdisPhysicalMediumWirelessWan; - - if (Adapter->BusParams.IsErrataDevice) - { - GeneralAttributes->MtuSize = Adapter->BusParams.MTU; - GeneralAttributes->LookaheadSize = Adapter->BusParams.MTU; - } else { - GeneralAttributes->MtuSize = Adapter->BusParams.MaxSegmentSize; - GeneralAttributes->LookaheadSize = Adapter->BusParams.MaxSegmentSize; - } - - GeneralAttributes->MacAddressLength=0; - // - // Update the link speed in the adapter structure as well as - // general attributes - // - - Adapter->CurrentLinkSpeed = 0; - Adapter->MaxLinkSpeed = 100L*1000*1000; - - GeneralAttributes->MaxXmitLinkSpeed = Adapter->MaxLinkSpeed; - GeneralAttributes->XmitLinkSpeed = Adapter->CurrentLinkSpeed; - - GeneralAttributes->MaxRcvLinkSpeed = Adapter->MaxLinkSpeed; - GeneralAttributes->RcvLinkSpeed = Adapter->CurrentLinkSpeed; - - // Setting this to connected so that the filter driver state is also connected. - // The media connect state corresponding to the NDIS ports handled by this miniport - // will be indicated using NDIS_STATUS_PORT_STATE indication, which will be - // converted to NDIS_STATUS_LINK_STATE indications by the filter driver. - GeneralAttributes->MediaConnectState = MediaConnectStateDisconnected; - - GeneralAttributes->MediaDuplexState = MediaDuplexStateUnknown; - - RtlZeroMemory(PnpCaps,sizeof(*PnpCaps)); - - PnpCaps->Header.Type=NDIS_OBJECT_TYPE_DEFAULT; - PnpCaps->Header.Revision=NDIS_PM_CAPABILITIES_REVISION_2; - PnpCaps->Header.Size=NDIS_SIZEOF_NDIS_PM_CAPABILITIES_REVISION_2; - - PnpCaps->MediaSpecificWakeUpEvents = NDIS_WWAN_WAKE_ON_REGISTER_STATE_SUPPORTED | - NDIS_WWAN_WAKE_ON_SMS_RECEIVE_SUPPORTED | - NDIS_WWAN_WAKE_ON_USSD_RECEIVE_SUPPORTED | - NDIS_WWAN_WAKE_ON_PACKET_STATE_SUPPORTED | - NDIS_WWAN_WAKE_ON_UICC_CHANGE_SUPPORTED; - - PnpCaps->MinLinkChangeWakeUp = NdisDeviceStateD2; - - PnpCaps->SupportedWakeUpEvents=NDIS_PM_WAKE_ON_MEDIA_DISCONNECT_SUPPORTED; - - if (Adapter->BusParams.PowerFiltersSupported > 0) - { - PnpCaps->SupportedWoLPacketPatterns = NDIS_PM_WOL_BITMAP_PATTERN_SUPPORTED; - PnpCaps->NumTotalWoLPatterns = Adapter->BusParams.PowerFiltersSupported; - - if (Adapter->BusParams.IsErrataDevice) - { - // For errata devices we will report the device specific max pattern size. - // 192 bytes is the maximum power filter size as per the MBIM spec. - // If a device reports more than 192 bytes as the power filter size, we - // normalize it here to 192 bytes. This will prevent erroneous devices - // from indicating arbitrary pattern size. This needs to change with any - // MBIM spec revision. - - if(Adapter->BusParams.MaxPowerFilterSize > WMBCLASS_MAX_MBIM_WOL_PATTERN) - { - MaxPowerFilterSize = WMBCLASS_MAX_MBIM_WOL_PATTERN; - } - else - { - MaxPowerFilterSize = Adapter->BusParams.MaxPowerFilterSize; - } - } - else - { - // To maintain backward compatibility with Win8 devices, we continue - // reporting 256 bytes as the wake pattern size. - MaxPowerFilterSize = WMBCLASS_MAX_WOL_PATTERN; - } - - PnpCaps->MaxWoLPatternSize = MaxPowerFilterSize; - PnpCaps->MaxWoLPatternOffset = MaxPowerFilterSize; - PnpCaps->MinPatternWakeUp = NdisDeviceStateD2; - } - - if (Adapter->BusParams.SelectiveSuspendSupported) - { - PnpCaps->Flags |= NDIS_PM_SELECTIVE_SUSPEND_SUPPORTED; - } - - GeneralAttributes->PowerManagementCapabilitiesEx = PnpCaps; - - GeneralAttributes->MacOptions = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | NDIS_MAC_OPTION_NO_LOOPBACK; - - GeneralAttributes->MaxMulticastListSize=0; - - // - // Although MB device has no mac address DHCP requires a hardware id. - // - RtlCopyMemory( - GeneralAttributes->CurrentMacAddress, - Adapter->MACAddress, - MBB_MAC_ADDRESS_LENGTH - ); - RtlCopyMemory( - GeneralAttributes->PermanentMacAddress, - Adapter->MACAddress, - MBB_MAC_ADDRESS_LENGTH - ); - GeneralAttributes->MacAddressLength = MBB_MAC_ADDRESS_LENGTH; - - GeneralAttributes->IfType = IF_TYPE_WWANPP; - - GeneralAttributes->RecvScaleCapabilities = NULL; - - GeneralAttributes->AccessType = NET_IF_ACCESS_POINT_TO_POINT; - GeneralAttributes->ConnectionType = NET_IF_CONNECTION_DEDICATED; - GeneralAttributes->DirectionType = NET_IF_DIRECTION_SENDRECEIVE; - GeneralAttributes->SupportedPacketFilters = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_PROMISCUOUS; - - GeneralAttributes->IfConnectorPresent = TRUE; - - GeneralAttributes->SupportedStatistics = - NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV | - NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV | - NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS | - NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR | - NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT | - NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | - NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR | - NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV | - NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT ; - - GeneralAttributes->SupportedPauseFunctions = NdisPauseFunctionsUnknown; - GeneralAttributes->DataBackFillSize = 0; - GeneralAttributes->ContextBackFillSize = 0; - - GeneralAttributes->SupportedOidList = (PNDIS_OID)&WmbClassSupportedOids[0]; - GeneralAttributes->SupportedOidListLength = WmbClassSupportedOidsNum*sizeof(NDIS_OID); - - GeneralAttributes->AutoNegotiationFlags = 0; - - return Status; -} - - -VOID -MbbNdisMiniportShutdownEx( - __in NDIS_HANDLE MiniportAdapterContext, - __in NDIS_SHUTDOWN_ACTION ShutdownAction - ) - -{ - UNREFERENCED_PARAMETER(ShutdownAction); - - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] SHUTTING DOWN Adapter=0x%p", Adapter); - - MbbAdapterSendNetworkShutdownHint(Adapter); - - if (MbbBusIsFastIO(Adapter->BusHandle)) - { - MbbBusShutdown(Adapter->BusHandle, ShutdownAction); - } - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; -} - -VOID -MbbNdisMiniportHaltEx( - __in NDIS_HANDLE MiniportAdapterContext, - __in NDIS_HALT_ACTION HaltAction - ) -/*++ -Description: - Close the MBIM protocol before cleaning up the request manager. - Once MBIM CLOSE is sent the device should not queue any more notifications. ---*/ -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - ULONG TempInstance=Adapter->TraceInstance; - NDIS_STATUS TempStatus=NDIS_STATUS_SUCCESS; - PMBB_REQUEST_MANAGER RequestManager; - PMBB_PORT Port = NULL; - - UNREFERENCED_PARAMETER(HaltAction); - - PAGED_CODE(); - - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] HALTING Adapter=0x%p", Adapter ); - - MbbWriteEvent( - &HALT_EVENT, - NULL, - NULL, - 1, - &TempInstance, - sizeof(TempInstance) - ); - - MbbSendQCleanup( &Adapter->SendQueue ); - MbbRecvQCleanup( &Adapter->ReceiveQueue ); - - if (Adapter->BusHandle != NULL) - { - if (MbbBusIsFastIO(Adapter->BusHandle)) - { - MbbBusHalt(Adapter->BusHandle, HaltAction); - } - MbbBusClose(Adapter->BusHandle,MbbLibraryGetNextTransactionId(), FALSE); - } - - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) != NULL ) - { - MbbReqMgrCleanup( RequestManager ); - } - else - { - TraceError(WMBCLASS_INIT, "[MbbAdapter] FAILED to reference RequestManager on Adapter=0x%p for HALT", Adapter ); - } - - WaitStallClearComplete(&Adapter->AdapterState); - - if (Adapter->BusHandle != NULL) - { - MbbBusCleanup(Adapter->BusHandle); - Adapter->BusHandle=NULL; - } - - while ((Port = Adapter->PortList[0]) != NULL) // if default port is allocated - { - // remove it from the adapter port list - if (MbbWwanRemovePortFromAdapterList(Adapter, Port)) - { - TempStatus = MbbWwanDeactivatePort(Adapter, Port); - if (TempStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_INIT, "MbbWwanDeactivatePort failed with status = 0x%x", TempStatus); - } - - // Deallocate the port. It will get cleaned up when - // its reference goes to 0 - MbbWwanDeallocatePort(Port); - } - else - { - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Port(0x%p) was already removed", Port); - } - } - - ASSERT(Adapter->PortList[0] == NULL); - - MbbDriverRemoveAdapter( &GlobalControl, Adapter ); - - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] HALTED Adapter=0x%p", Adapter ); - - MbbWriteEvent( - &HALT_EXIT_EVENT, - NULL, - NULL, - 2, - &TempInstance, - sizeof(TempInstance), - &TempStatus, - sizeof(TempStatus) - ); - - return; -} - -NDIS_STATUS -MbbNdisMiniportSetOption( - __in NDIS_HANDLE NdisDriverHandle, - __in NDIS_HANDLE DriverContext - ) - -{ - NDIS_MINIPORT_SS_CHARACTERISTICS SelectiveSuspendChars = {0}; - NDIS_MINIPORT_SYSPOWER_NOTIFY_CHARACTERISTICS SysPowerChars = {0}; - NDIS_STATUS Status=NDIS_STATUS_SUCCESS; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - SelectiveSuspendChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_SS_CHARACTERISTICS; - SelectiveSuspendChars.Header.Revision = NDIS_MINIPORT_SS_CHARACTERISTICS_REVISION_1; - SelectiveSuspendChars.Header.Size = sizeof(SelectiveSuspendChars); - - // - // Set the two function callbacks used by NDIS - // - SelectiveSuspendChars.IdleNotificationHandler = &MbbNdisMiniportIdleNotification; - SelectiveSuspendChars.CancelIdleNotificationHandler = &MbbNdisMiniportCancelIdleNotification; - - Status = NdisSetOptionalHandlers( - NdisDriverHandle, - (PVOID)&SelectiveSuspendChars - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "NdisMSetMiniportAttributes(general) with %08lx", Status); - goto Cleanup; - - } - - SysPowerChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_SYSPOWER_NOTIFICATION; - SysPowerChars.Header.Revision = NDIS_MINIPORT_SYSPOWER_NOTIFY_CHARACTERISTICS_REVISION_1; - SysPowerChars.Header.Size = NDIS_SIZEOF_MINIPORT_SYSPOWER_NOTIFY_CHARACTERISTICS_REVISION_1; - - SysPowerChars.SysPowerNotifyHandler = MbbSystemPowerNotification; - - Status = NdisSetOptionalHandlers( - NdisDriverHandle, - (PVOID)&SysPowerChars - ); - - if (NT_ERROR(Status)) - { - TraceError(WMBCLASS_INIT, "NdisMSetMiniportAttributes(general) with %08lx SysPowerCcaps", Status); - goto Cleanup; - } -Cleanup: - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return Status; -} - -NDIS_STATUS -MbbNdisMiniportIdleNotification( - __in NDIS_HANDLE MiniportAdapterContext, - __in BOOLEAN ForceIdle - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - NTSTATUS Status=NDIS_STATUS_SUCCESS; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - Status=MbbBusIdleNotification(Adapter->BusHandle, ForceIdle); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return Status; -} - - -VOID -MbbNdisMiniportCancelIdleNotification( - __in NDIS_HANDLE MiniportAdapterContext - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - MbbBusCancelIdleNotification(Adapter->BusHandle); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; -} - - -VOID -MbbNdisMiniportBusIdleConfirm( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in DEVICE_POWER_STATE PowerState - ) - -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - NdisMIdleNotificationConfirm( - Adapter->MiniportAdapterHandle, - PowerState - ); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; - -} - -VOID -MbbNdisMiniportIdleNotificationComplete( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in NTSTATUS Status - ) - -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - NdisMIdleNotificationCompleteEx(Adapter->MiniportAdapterHandle, Status); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; - -} - -VOID -MbbSystemPowerNotification( - _In_ NDIS_HANDLE MiniportAdapterContext, - _In_ NDIS_MINIPORT_SYSPOWER_NOTIFY const *SystemPowerNotification - ) - -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Entered"); - - NdisAcquireSpinLock(&Adapter->Lock); - - Adapter->LastLowSystemPowerState=*SystemPowerNotification; - - NdisReleaseSpinLock(&Adapter->Lock); - - TraceInfo(WMBCLASS_POWER, "%!FUNC!: TargetSystemPowerState S%d EffectiveSystemPowerState S%d", - SystemPowerNotification->TargetSystemState - PowerSystemWorking, - SystemPowerNotification->EffectiveSystemState - PowerSystemWorking); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; - -} - -VOID -DrainCompleteCallback( - PVOID Context - ) - -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)Context; - BOOLEAN CompletePause=FALSE; - BOOLEAN ResetComplete=FALSE; - BOOLEAN StallClear=FALSE; - PMBB_REQUEST_CONTEXT Request=NULL; - PSTATE_CHANGE_EVENT StateChange=NULL; - NDIS_STATUS TempStatus=NDIS_STATUS_SUCCESS; - - TraceInfo(WMBCLASS_INIT, "Entered Pending=%d", Adapter->AdapterState.PendingActions-1); - - NdisAcquireSpinLock(&Adapter->Lock); - - ASSERT(Adapter->AdapterState.PendingActions > 0); - - Adapter->AdapterState.PendingActions--; - - if (Adapter->AdapterState.PendingActions == 0) - { - StateChange=Adapter->AdapterState.RunningEvent; - - NdisReleaseSpinLock(&Adapter->Lock); - - switch (StateChange->EventType) - { - - case STATE_CHANGE_TYPE_PAUSE: - - CompletePause=TRUE; - - break; - - case STATE_CHANGE_TYPE_POWER: - - Request=StateChange->Power.Request; - - break; - - case STATE_CHANGE_TYPE_RESET: - - ResetComplete=TRUE; - - break; - - case STATE_CHANGE_TYPE_STALL_CLEAR: - - StallClear=TRUE; - - break; - - default: - - ASSERT(0); - break; - } - - if (ResetComplete) - { - if ((Adapter->AdapterState.CurrentPowerState == NetDeviceStateD0) && Adapter->AdapterState.Started) - { - // - // powered up, start send queue - // - DrainComplete( &(Adapter->SendQueue.QueueDrainObject) ); - - } - - TempStatus=StateChange->Reset.PipeStartStatus; - - MbbWriteEvent( - &RESET_COMPLETE_EVENT, - NULL, - NULL, - 2, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &TempStatus, - sizeof(TempStatus) - ); - - - if (!NT_SUCCESS(StateChange->Reset.PipeStartStatus)) - { - TraceError(WMBCLASS_INIT, "Reset failed %!STATUS!",StateChange->Reset.PipeStartStatus); - } - - NdisMResetComplete( - Adapter->MiniportAdapterHandle, - StateChange->Reset.PipeStartStatus, - FALSE - ); - - - } - - - if (Request) - { - TraceInfo(WMBCLASS_INIT, "Completing set power request"); - - MbbReqMgrQueueEvent( - Request->RequestManager, - Request, - MbbRequestEventSendComplete, - (PVOID)(NDIS_STATUS_SUCCESS), - 0 - ); - } - - - if (CompletePause) - { - TraceInfo(WMBCLASS_INIT, "Completing Pause"); - - MbbWriteEvent( - &PAUSE_COMPLETE_EVENT, - NULL, - NULL, - 2, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &TempStatus, - sizeof(TempStatus) - ); - - - NdisMPauseComplete(Adapter->MiniportAdapterHandle); - } - - if (StallClear) - { - TraceInfo(WMBCLASS_INIT, "Stall cleared"); - - MbbAdapterLock(Adapter); - - Adapter->AdapterState.Hung=FALSE; - KeSetEvent(&Adapter->AdapterState.StallClearCompleteEvent, IO_NO_INCREMENT, FALSE); - - MbbAdapterUnlock(Adapter); - - } - - Adapter->AdapterState.RunningEvent=NULL; - - CompleteStateChange( - &Adapter->AdapterState, - StateChange - ); - - NdisAcquireSpinLock(&Adapter->Lock); - } - - NdisReleaseSpinLock(&Adapter->Lock); - - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Exited"); - - return; -} - - -NDIS_STATUS -MbbNdisMiniportPause( - __in NDIS_HANDLE MiniportAdapterContext, - __in PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters - ) - -{ - - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - PSTATE_CHANGE_EVENT StateChange=NULL; - NDIS_STATUS Status=STATUS_INSUFFICIENT_RESOURCES; - - UNREFERENCED_PARAMETER(MiniportPauseParameters); - - PAGED_CODE(); - - MbbWriteEvent( - &PAUSE_EVENT, - NULL, - NULL, - 1, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance) - ); - - - StateChange = AllocateStateChangeEvent(&Adapter->AdapterState); - - if (StateChange != NULL) - { - StateChange->EventType=STATE_CHANGE_TYPE_PAUSE; - StateChange->Context1=Adapter; - - QueueStateChangeEvent(&Adapter->AdapterState,StateChange); - - Status= STATUS_PENDING; - - } - - - MbbWriteEvent( - &PAUSE_EXIT_EVENT, - NULL, - NULL, - 2, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &Status, - sizeof(Status) - ); - - - return Status; -} - - - -NDIS_STATUS -MbbNdisMiniportRestart( - __in NDIS_HANDLE MiniportAdapterContext, - __in PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters - ) - -{ - - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - NDIS_STATUS Status=STATUS_INSUFFICIENT_RESOURCES; - PSTATE_CHANGE_EVENT StateChange=NULL; - - UNREFERENCED_PARAMETER(MiniportRestartParameters); - - PAGED_CODE(); - - MbbWriteEvent( - &RESTART_EVENT, - NULL, - NULL, - 1, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance) - ); - - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] RESUMING Adapter=0x%p", Adapter ); - - StateChange = AllocateStateChangeEvent(&Adapter->AdapterState); - - if (StateChange != NULL) - { - StateChange->EventType=STATE_CHANGE_TYPE_RESTART; - StateChange->Context1=Adapter; - - QueueStateChangeEvent(&Adapter->AdapterState,StateChange); - - Status=STATUS_PENDING; - } - else - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to resume Adapter=0x%p", Adapter ); - } - - - MbbWriteEvent( - &RESTART_EXIT_EVENT, - NULL, - NULL, - 2, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &Status, - sizeof(Status) - ); - - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] RESUMING Adapter=0x%p Complete", Adapter); - - return Status; - -} - - - -VOID -MbbNdisMiniportDevicePnPEventNotify( - __in NDIS_HANDLE MiniportAdapterContext, - __in PNET_DEVICE_PNP_EVENT NetDevicePnPEvent - ) - -{ - - PMBB_REQUEST_MANAGER RequestManager; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MiniportAdapterContext; - - PAGED_CODE(); - - if( NetDevicePnPEvent->DevicePnPEvent == NdisDevicePnPEventSurpriseRemoved ) - { - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] SURPRISE_REMOVAL Adapter=0x%p. Cancelling OID requests", Adapter ); - // The Surprise Removed Flag is not used anywhere. It is just there for debugging purposes, so no need to set it under a lock - Adapter->SurpriseRemoved = TRUE; - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to reference RequestManager for SURPRISE_REMOVAL" ); - return; - } - // Adapter Now Surprise removed, so now close the Request Manager so that no more requests are allowed - // Pass that information to the MbbRrqMgrCancelRequests Call - MbbReqMgrCancelRequests( RequestManager, TRUE); - MbbReqMgrDeref( RequestManager ); - } - - return ; -} - -// -// Driver routines -// -_Acquires_lock_( Driver->AdapterListLock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, Driver ) -VOID -MbbDriverLockAdapterList( - __in PMINIPORT_DRIVER_CONTEXT Driver - ) -{ - NdisAcquireSpinLock( &Driver->AdapterListLock ); -} - -_Releases_lock_( Driver->AdapterListLock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, Driver ) -VOID -MbbDriverUnlockAdapterList( - __in PMINIPORT_DRIVER_CONTEXT Driver - ) -{ - NdisReleaseSpinLock( &Driver->AdapterListLock ); -} - -VOID -MbbDriverAddAdapter( - __in PMINIPORT_DRIVER_CONTEXT Driver, - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - MbbDriverLockAdapterList( Driver ); - InsertTailList( &Driver->AdapterList, &Adapter->DriverLink ); - MbbAdapterRef( Adapter ); - MbbDriverUnlockAdapterList( Driver ); -} - -VOID -MbbDriverRemoveAdapter( - __in PMINIPORT_DRIVER_CONTEXT Driver, - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - MbbDriverLockAdapterList( Driver ); - RemoveEntryList( &Adapter->DriverLink ); - MbbAdapterDeref( Adapter ); - MbbDriverUnlockAdapterList( Driver ); -} - -PMINIPORT_ADAPTER_CONTEXT -MbbDriverFindAdapterByNetLuid( - __in PMINIPORT_DRIVER_CONTEXT Driver, - __in PNET_LUID NetLuid - ) -{ - PLIST_ENTRY ListEntry; - PMINIPORT_ADAPTER_CONTEXT Adapter; - - MbbDriverLockAdapterList( Driver ); - for( ListEntry = Driver->AdapterList.Flink, Adapter = NULL; - ListEntry != &Driver->AdapterList; - ListEntry = ListEntry->Flink, Adapter = NULL ) - { - Adapter = CONTAINING_RECORD( - ListEntry, - MINIPORT_ADAPTER_CONTEXT, - DriverLink - ); - if( RtlCompareMemory( - &Adapter->NetLuid, - NetLuid, - sizeof(NET_LUID) - ) == sizeof(NET_LUID) ) - { - MbbAdapterRef( Adapter ); - break; - } - } - MbbDriverUnlockAdapterList( Driver ); - - return Adapter; -} - -NDIS_STATUS -MbbNdisAdapterReadParameters( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - NDIS_HANDLE ConfigurationHandle = NULL; - PNDIS_CONFIGURATION_PARAMETER pParameter = NULL; - NDIS_STRING NetCfgGuid = RTL_CONSTANT_STRING(MBB_REGVAL_NETCFGID); - NDIS_STRING NameOverride = RTL_CONSTANT_STRING(MBB_REGVAL_OVERRIDE_NAME); - NDIS_STRING RadioOffRegString = RTL_CONSTANT_STRING(MBB_REGVAL_RADIO_OFF); - NDIS_CONFIGURATION_OBJECT ConfigObject; - - do - { - // - // Open the registry for this adapter to read advanced - // configuration parameters stored by the INF file. - // - ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; - ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; - ConfigObject.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT); - ConfigObject.NdisHandle = Adapter->MiniportAdapterHandle; - ConfigObject.Flags = 0; - - if( (NdisStatus = NdisOpenConfigurationEx( - &ConfigObject, - &ConfigurationHandle - ))!= NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to open configuration, status=%!STATUS!", NdisStatus ); - break; - } - - // NetCfgInstanceId - NdisReadConfiguration( - &NdisStatus, - &pParameter, - ConfigurationHandle, - &NetCfgGuid, - NdisParameterString - ); - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to read NetCfgId, status=%!STATUS!", NdisStatus ); - break; - } - if( (NdisStatus = RtlGUIDFromString( - &pParameter->ParameterData.StringData, - &Adapter->NetCfgId - )) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to convert NetCfgId string to guid, status=%!STATUS!", NdisStatus ); - break; - } - - // DeviceNameOverride - NdisReadConfiguration( - &NdisStatus, - &pParameter, - ConfigurationHandle, - &NameOverride, - NdisParameterInteger - ); - - if ( NdisStatus == NDIS_STATUS_SUCCESS ) - { - if (pParameter->ParameterType == NdisParameterInteger) - { - Adapter->OverrideDeviceName = pParameter->ParameterData.IntegerData != 0; - - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Name override set to %d", Adapter->OverrideDeviceName); - } - } - else - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to read name override setting, status=%!STATUS!", NdisStatus ); - NdisStatus = NDIS_STATUS_SUCCESS; - } - - // RadioState: Default = ON - Adapter->RadioOff = FALSE; - NdisReadConfiguration( - &NdisStatus, - &pParameter, - ConfigurationHandle, - &RadioOffRegString, - NdisParameterInteger - ); - - if ( NdisStatus == NDIS_STATUS_SUCCESS ) - { - if (pParameter->ParameterType == NdisParameterInteger) - { - // Non zero value in registry means the radio should be OFF - Adapter->RadioOff = (pParameter->ParameterData.IntegerData != 0); - - TraceInfo( WMBCLASS_INIT, "[MbbAdapter] Persisted radio state %s", Adapter->RadioOff ? "OFF" : "ON"); - } - } - else - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] FAILED to read radio state, status=%!STATUS!", NdisStatus ); - NdisStatus = NDIS_STATUS_SUCCESS; - } - - } - while(FALSE); - - if( ConfigurationHandle != NULL ) - { - NdisCloseConfiguration( ConfigurationHandle ); - } - - return NdisStatus; -} - -void -NTAPI MbbDumpAdapterState( - _In_ LPCGUID SourceId, - _In_ ULONG IsEnabled, - _In_ UCHAR Level, - _In_ ULONGLONG MatchAnyKeyword, - _In_ ULONGLONG MatchAllKeywords, - _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, - _In_opt_ PVOID CallbackContext -) -{ - if(IsEnabled == EVENT_CONTROL_CODE_CAPTURE_STATE) - { - PLIST_ENTRY ListEntry; - PMINIPORT_ADAPTER_CONTEXT* Adapters = NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - PMINIPORT_DRIVER_CONTEXT Driver = &GlobalControl; - ULONG numberOfAdapters = 0, x = 0, y = 0; - - do - { - // Get the adapter context - MbbDriverLockAdapterList( Driver ); - - for( ListEntry = Driver->AdapterList.Flink, Adapter = NULL; - ListEntry != &Driver->AdapterList; - ListEntry = ListEntry->Flink, Adapter = NULL ) - { - if((Adapter = CONTAINING_RECORD( - ListEntry, - MINIPORT_ADAPTER_CONTEXT, - DriverLink - ))!=NULL) - { - numberOfAdapters++; - } - } - - if(numberOfAdapters == 0) - { - MbbDriverUnlockAdapterList( Driver ); - break; - } - - // Allocate an array of pointers - Adapters = ALLOCATE_NONPAGED_POOL(sizeof(Adapter) * numberOfAdapters); - - if(Adapters == NULL) - { - MbbDriverUnlockAdapterList( Driver ); - break; - } - - NdisZeroMemory(Adapters, sizeof(Adapter) * numberOfAdapters); - - numberOfAdapters = 0; - - for( ListEntry = Driver->AdapterList.Flink, Adapter = NULL; - ListEntry != &Driver->AdapterList; - ListEntry = ListEntry->Flink, Adapter = NULL ) - { - if((Adapter = CONTAINING_RECORD( - ListEntry, - MINIPORT_ADAPTER_CONTEXT, - DriverLink - ))!=NULL) - { - Adapters[numberOfAdapters++] = Adapter; - - // Take a ref on the adapter so that it doesnt - // get cleaned up while processing - MbbAdapterRef(Adapter); - } - } - - MbbDriverUnlockAdapterList( Driver ); - - // Now log the state of each adapter - for(x = 0; x < numberOfAdapters; x++) - { - MBB_CELLULAR_CLASS AdapterSupportedCellularClass; - MBB_CELLULAR_CLASS AdapterCurrentCellularClass; - ULONG MaxActivatedContexts = 0; - ULONG NumberOfPorts = 0; - PMBB_PORT* PortList = NULL; - ULONG RefCount = 0; - ULONG PendingRequests = 0; - BOOL RadioOff = TRUE; - - Adapter = Adapters[x]; - - MbbAdapterLock(Adapter); - AdapterSupportedCellularClass = Adapter->AdapterSupportedCellularClass; - AdapterCurrentCellularClass = Adapter->AdapterCurrentCellularClass; - MbbAdapterUnlock(Adapter); - - MbbAdapterPortsLock(Adapter); - MaxActivatedContexts = Adapter->MaxActivatedContexts; - NumberOfPorts = Adapter->NumberOfPorts; - PortList = ALLOCATE_NONPAGED_POOL(sizeof(PMBB_PORT) * NumberOfPorts); - - if(PortList == NULL) - { - MbbAdapterPortsUnlock(Adapter); - MbbAdapterDeref(Adapter); - continue; - } - - // Copy the port information of the adapter under adapter ports lock - NdisMoveMemory(PortList, &(Adapter->PortList), sizeof(PMBB_PORT)* NumberOfPorts); - MbbAdapterPortsUnlock(Adapter); - - // Pending request count - MbbReqMgrLockManager(Adapter->RequestManager); - - for( ListEntry = Adapter->RequestManager->PendingRequestQueue.Flink; - ListEntry != &(Adapter->RequestManager->PendingRequestQueue); - ListEntry = ListEntry->Flink) - { - PendingRequests++; - } - - MbbReqMgrUnlockManager(Adapter->RequestManager); - - RadioOff = Adapter->RadioOff; - - InterlockedExchange(&RefCount, Adapter->Reference); - - MbbWriteEvent( - &ADAPTER_CONTEXT, - NULL, - NULL, - 21, - Adapter->FriendlyName.Buffer, - ((Adapter->FriendlyName.Buffer) ? Adapter->FriendlyName.Length + 1 : 0), // 1 - &(Adapter->IfIndex), - sizeof(Adapter->IfIndex), // 2 - Adapter->MACAddress, - MBB_MAC_ADDRESS_LENGTH, // 3 - &(Adapter->NetCfgId), - sizeof(Adapter->NetCfgId), // 4 - &RadioOff, - sizeof(RadioOff), // 5 - &(Adapter->MaxLinkSpeed), - sizeof(Adapter->MaxLinkSpeed), // 6 - &(Adapter->CurrentLinkSpeed), - sizeof(Adapter->CurrentLinkSpeed), // 7 - &(Adapter->UplinkSpeed), - sizeof(Adapter->UplinkSpeed), // 8 - &(Adapter->DownlinkSpeed), - sizeof(Adapter->DownlinkSpeed), // 9 - &(Adapter->AvailableDataClass), - sizeof(Adapter->AvailableDataClass), // 10 - &(Adapter->AvailableDataClassValid), - sizeof(BOOL), // 11 - &AdapterSupportedCellularClass, - sizeof(Adapter->AdapterSupportedCellularClass), // 12 - &AdapterCurrentCellularClass, - sizeof(Adapter->AdapterCurrentCellularClass), // 13 - &(Adapter->GenXmitFramesOk), - sizeof(Adapter->GenXmitFramesOk), // 14 - &(Adapter->Stats.ifOutDiscards), - sizeof(Adapter->Stats.ifOutDiscards), // 15 - &(Adapter->GenRcvFramesOk), - sizeof(Adapter->GenRcvFramesOk), // 16 - &(Adapter->Stats.ifInDiscards), - sizeof(Adapter->Stats.ifInDiscards), // 17 - &MaxActivatedContexts, - sizeof(Adapter->MaxActivatedContexts), // 18 - &NumberOfPorts, - sizeof(Adapter->NumberOfPorts), // 19 - &RefCount, - sizeof(Adapter->Reference), // 20 - &PendingRequests, - sizeof(PendingRequests) // 21 - ); - - MbbAdapterDeref(Adapter); - - // Log port information - for(y = 0; y < NumberOfPorts; y++) - { - NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; - BOOL ConnectionUp = FALSE; - ULONG ConnectionId = 0; - LONG SessionId = MBB_INVALID_SESSION_ID; - ULONG RefCount = 0; - - PMBB_PORT Port = PortList[y]; - - MBB_ACQUIRE_PORT_LOCK(Port); - - PortNumber = Port->PortNumber; - ConnectionUp = Port->ConnectionState.ConnectionUp; - ConnectionId = Port->ConnectionId; - SessionId = Port->SessionId; - - MBB_RELEASE_PORT_LOCK(Port); - - InterlockedExchange(&RefCount, Port->RefCount.RefCount); - - MbbWriteEvent( - &PORT_CONTEXT, - NULL, - NULL, - 5, - &PortNumber, - sizeof(Port->PortNumber), // 1 - &ConnectionUp, - sizeof(ConnectionUp), // 2 - &ConnectionId, - sizeof(Port->ConnectionId), // 3 - &SessionId, - sizeof(Port->SessionId), // 4 - &RefCount, - sizeof(Port->RefCount.RefCount) // 5 - ); - } - - if(PortList != NULL) - { - FREE_POOL(PortList); - PortList = NULL; - } - } - }while(FALSE); - - if(Adapters != NULL) - { - FREE_POOL(Adapters); - Adapters = NULL; - } - } -} - diff --git a/network/wwan/cxwmbclass/port.c b/network/wwan/cxwmbclass/port.c deleted file mode 100644 index d5ca11861..000000000 --- a/network/wwan/cxwmbclass/port.c +++ /dev/null @@ -1,825 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - port.c - -Abstract: - Implements the functionality needed by ports - -Revision History: - When What - ---------- ---------------------------------------------- - 12-13-2012 Created - -Notes: - ---*/ - -#include "precomp.h" -#include "port.tmh" - -NDIS_STATUS -MbbWwanAllocateBasePort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _Outptr_result_nullonfailure_ PMBB_PORT* Port - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PMBB_PORT newPort = NULL; - - *Port = NULL; - - do - { - // Allocate a PORT data structure - newPort = ALLOCATE_NONPAGED_POOL_WITH_TAG(sizeof(MBB_PORT), MbbPoolTagPort); - - if (newPort == NULL) - { - TraceError(WMBCLASS_OID, "Failed to allocate %d bytes for port\n",sizeof(MBB_PORT)); - Status = NDIS_STATUS_RESOURCES; - break; - } - - // Clear everything - NdisZeroMemory(newPort, sizeof(MBB_PORT)); - - // Allocate memory for fields inside the PORT structure - NdisAllocateSpinLock(&(newPort->Lock)); - - // Reference the adapter since the port is going to be using it - // this reference will be removed in the port cleanup routine - MbbAdapterRef(Adapter); - - // Save the passed data into the PORT - newPort->MiniportAdapterHandle = Adapter->MiniportAdapterHandle; - newPort->Adapter = Adapter; - newPort->State = PortDeactivated; - newPort->PortNumber = DEFAULT_NDIS_PORT_NUMBER; - newPort->SessionId = MBB_INVALID_SESSION_ID; //no active session - - // Return the newly created structure to the caller - *Port = newPort; - }while(FALSE); - - return Status; -} - -VOID -MbbWwanFreeBasePort( - _In_ __drv_freesMem(Mem) PMBB_PORT Port - ) -{ - if(Port != NULL) - { - NdisFreeSpinLock(&(Port->Lock)); - - if( Port->IpAddressInfo != NULL ) - { - FREE_POOL(Port->IpAddressInfo); - } - - // Dereference the adapter - MbbAdapterDeref(Port->Adapter); - - FREE_POOL(Port); - Port = NULL; - } -} - -NDIS_STATUS -MbbWwanAllocatePort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ BOOLEAN fAllocateNdisPort, - _Outptr_result_nullonfailure_ PMBB_PORT* Port - ) -{ - - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PMBB_PORT newPort = NULL; - NDIS_PORT_CHARACTERISTICS portChar; - - *Port = NULL; - - do - { - Status = MbbWwanAllocateBasePort(Adapter, &newPort); - - if (Status != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "Failed to allocate base port structure\n"); - break; - } - - // Initialize the intial reference count to 1 - InitializeRefCount(&newPort->RefCount, MbbWwanFreePort); - - if(fAllocateNdisPort) - { - // Call NDIS to allocate the port - NdisZeroMemory(&portChar, sizeof(NDIS_PORT_CHARACTERISTICS)); - - - portChar.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - portChar.Header.Revision = NDIS_PORT_CHARACTERISTICS_REVISION_1; - portChar.Header.Size = sizeof(NDIS_PORT_CHARACTERISTICS); - - portChar.Flags = NDIS_PORT_CHAR_USE_DEFAULT_AUTH_SETTINGS; - portChar.Type = NdisPortTypeUndefined; - portChar.MediaConnectState = MediaConnectStateUnknown; - portChar.XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; - portChar.RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; - portChar.Direction = NET_IF_DIRECTION_SENDRECEIVE; - portChar.SendControlState = NdisPortControlStateUnknown; - portChar.RcvControlState = NdisPortControlStateUnknown; - portChar.SendAuthorizationState = NdisPortControlStateUncontrolled; // Ignored - portChar.RcvAuthorizationState = NdisPortControlStateUncontrolled; // Ignored - - Status = NdisMAllocatePort(Adapter->MiniportAdapterHandle, &portChar); - - if (Status != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "Failed to allocate NDIS port. Status = 0x%08x\n", Status); - break; - } - - TraceInfo(WMBCLASS_OID, "Associated Port Number %lu with allocated port\n", portChar.PortNumber); - - // Assign the NDIS port number that has been allocated to this port - newPort->PortNumber = portChar.PortNumber; - } - else - { - // means it the default ndis port - newPort->SessionId = 0; - } - - *Port = newPort; - }while(FALSE); - - if(Status != NDIS_STATUS_SUCCESS) - { - if(newPort != NULL) - { - MbbWwanDeallocatePort(newPort); - } - } - - return Status; -} - -VOID -MbbWwanDeallocatePort( - _In_ PMBB_PORT Port - ) -{ - // remove the intial reference count - Dereference(Port); -} - - -VOID -MbbWwanFreePort( - PREF_COUNT RefObj - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PMBB_PORT Port = NULL; - - Port = CONTAINING_RECORD(RefObj, MBB_PORT, RefCount); - - ASSERT(Port!=NULL); - - if(IS_ALLOCATED_PORT_NUMBER(Port->PortNumber)) - { - // Free the NDIS port. We do not manage default NDIS port ( port number 0 ) - Status = NdisMFreePort(Port->Adapter->MiniportAdapterHandle, Port->PortNumber); - ASSERT(Status == NDIS_STATUS_SUCCESS); - } - - // Free the base port structure - MbbWwanFreeBasePort(Port); -} - -// Port will not be deleted while in this function because the caller should take a ref before calling this function. -NDIS_STATUS -MbbWwanActivatePort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - NET_PNP_EVENT_NOTIFICATION NetPnpEventNotification; - NDIS_PORT NdisPort; - PNDIS_PORT_CHARACTERISTICS PortChar; - NDIS_PORT_NUMBER PortNumberToActivate = DEFAULT_NDIS_PORT_NUMBER; - BOOLEAN PortActive = FALSE; - - do - { - if(!Port) - { - Status = NDIS_STATUS_FAILURE; - break; - } - - MBB_ACQUIRE_PORT_LOCK(Port); - - if(!IS_ALLOCATED_PORT_NUMBER(Port->PortNumber)) - { - // we do not handle DEFAULT_NDIS_PORT_NUMBER - Status = NDIS_STATUS_SUCCESS; - MBB_RELEASE_PORT_LOCK(Port); - break; - } - - if(Port->State == PortActivated) - { - TraceInfo(WMBCLASS_OID, "Requested port with ndis port number %lu is already activated",Port->PortNumber); - Status = NDIS_STATUS_SUCCESS; - MBB_RELEASE_PORT_LOCK(Port); - break; - } - - if(Port->State != PortDeactivated) - { - Status = NDIS_STATUS_INVALID_PORT_STATE; - MBB_RELEASE_PORT_LOCK(Port); - break; - } - - // set port state to activating - Port->State = PortActivating; - - PortNumberToActivate = Port->PortNumber; - - MBB_RELEASE_PORT_LOCK(Port); - - NdisZeroMemory(&NetPnpEventNotification, sizeof(NET_PNP_EVENT_NOTIFICATION)); - NdisZeroMemory(&NdisPort, sizeof(NDIS_PORT)); - - NetPnpEventNotification.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NetPnpEventNotification.Header.Revision = NET_PNP_EVENT_NOTIFICATION_REVISION_1; - NetPnpEventNotification.Header.Size = sizeof(NET_PNP_EVENT_NOTIFICATION); - - NetPnpEventNotification.NetPnPEvent.NetEvent = NetEventPortActivation; - - - // Refill the characteristics structure for the port - PortChar = &(NdisPort.PortCharacteristics); - - PortChar->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - PortChar->Header.Revision = NDIS_PORT_CHARACTERISTICS_REVISION_1; - PortChar->Header.Size = sizeof(NDIS_PORT_CHARACTERISTICS); - - PortChar->Flags = NDIS_PORT_CHAR_USE_DEFAULT_AUTH_SETTINGS; - PortChar->Type = NdisPortTypeUndefined; - PortChar->MediaConnectState = MediaConnectStateUnknown; - PortChar->XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; - PortChar->RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; - PortChar->Direction = NET_IF_DIRECTION_SENDRECEIVE; - PortChar->SendControlState = NdisPortControlStateUnknown; - PortChar->RcvControlState = NdisPortControlStateUnknown; - PortChar->SendAuthorizationState = NdisPortControlStateUncontrolled; // Ignored - PortChar->RcvAuthorizationState = NdisPortControlStateUncontrolled; // Ignored - PortChar->PortNumber = PortNumberToActivate; - - - // Single port is being activated - NdisPort.Next = NULL; - - // We need to save a pointer to the NDIS_PORT in the NetPnPEvent::Buffer field - NetPnpEventNotification.NetPnPEvent.Buffer = (PVOID)&NdisPort; - NetPnpEventNotification.NetPnPEvent.BufferLength = sizeof(NDIS_PORT); - - Status = NdisMNetPnPEvent(Port->MiniportAdapterHandle, &NetPnpEventNotification); - - if (Status != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "Failed to activate NDIS port %d. Status = 0x%08x\n", PortNumberToActivate, Status); - } - else - { - TraceInfo( WMBCLASS_OID, "Activated Port Number %d\n", PortNumberToActivate); - PortActive = TRUE; - } - - - MBB_ACQUIRE_PORT_LOCK(Port); - - if(PortActive) - { - // set the port state to activated or reset it to initialized in case of failure - Port->State = PortActivated; - Reference(Port); // for activation - } - else - { - Port->State = PortDeactivated; - } - - MBB_RELEASE_PORT_LOCK(Port); - - }while(FALSE); - - return Status; -} - -NDIS_STATUS -MbbWwanDeactivatePort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - NET_PNP_EVENT_NOTIFICATION NetPnpEventNotification; - NDIS_PORT_NUMBER PortNumberArray[1]; - NDIS_PORT_NUMBER PortNumberToDeactivate = DEFAULT_NDIS_PORT_NUMBER; - - do - { - if(!Port) - { - Status = NDIS_STATUS_FAILURE; - break; - } - - MBB_ACQUIRE_PORT_LOCK(Port); - - if(!IS_ALLOCATED_PORT_NUMBER(Port->PortNumber)) - { - // we do not handle DEFAULT_NDIS_PORT_NUMBER - Status = NDIS_STATUS_SUCCESS; - MBB_RELEASE_PORT_LOCK(Port); - break; - } - - if(Port->State == PortDeactivated) - { - TraceInfo(WMBCLASS_OID, "Requested port with ndis port number %lu is already deactivated",Port->PortNumber); - Status = NDIS_STATUS_SUCCESS; - MBB_RELEASE_PORT_LOCK(Port); - break; - } - - if(Port->State != PortActivated) - { - Status = NDIS_STATUS_INVALID_PORT_STATE; - MBB_RELEASE_PORT_LOCK(Port); - break; - } - - // set port state to deactivating - Port->State = PortDeactivating; - - PortNumberToDeactivate = Port->PortNumber; - - MBB_RELEASE_PORT_LOCK(Port); - - - NdisZeroMemory(&NetPnpEventNotification, sizeof(NET_PNP_EVENT_NOTIFICATION)); - - NetPnpEventNotification.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NetPnpEventNotification.Header.Revision = NET_PNP_EVENT_NOTIFICATION_REVISION_1; - NetPnpEventNotification.Header.Size = sizeof(NET_PNP_EVENT_NOTIFICATION); - - - NetPnpEventNotification.NetPnPEvent.NetEvent = NetEventPortDeactivation; - - // We need to save a pointer to the NDIS_PORT_NUMBER in the NetPnPEvent::Buffer field - PortNumberArray[0] = PortNumberToDeactivate; - NetPnpEventNotification.NetPnPEvent.Buffer = (PVOID)PortNumberArray; - NetPnpEventNotification.NetPnPEvent.BufferLength = sizeof(NDIS_PORT_NUMBER); - - Status = NdisMNetPnPEvent(Port->MiniportAdapterHandle, &NetPnpEventNotification); - - if (Status != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "Failed to deactivate NDIS port %d. Status = 0x%08x\n", PortNumberToDeactivate, Status); - } - else - { - TraceInfo( WMBCLASS_OID, "Deactivated Port Number %d\n", PortNumberToDeactivate); - } - - // set the port state to PortDeactivated, because there is little we can do if the call to NdisMSetPnPEvent fails apart - // from logging the error. Setting the state to PortDeactivated will enable port re-use. - - MBB_ACQUIRE_PORT_LOCK(Port); - - Port->State = PortDeactivated; - - MBB_RELEASE_PORT_LOCK(Port); - - Dereference(Port); // this reference was added for activation - - }while(FALSE); - - return Status; -} - -_Requires_lock_not_held_(&Adapter->PortsLock) -VOID -MbbWwanAddPortToAdapterList( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT* PortToAdd - ) -{ - if(Adapter && PortToAdd && *PortToAdd) - { - MbbAdapterPortsLock(Adapter); - - // Add a reference to the port since now this port is being - // added to the adapter's port list - Reference(*PortToAdd); - - Adapter->PortList[Adapter->NumberOfPorts] = *PortToAdd; - Adapter->NumberOfPorts++; - - MbbAdapterPortsUnlock(Adapter); - } -} - -_Requires_lock_not_held_(&Adapter->PortsLock) -BOOL -MbbWwanRemovePortFromAdapterList( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT PortToRemove -) -{ - ULONG NumberOfPorts = 0; - ULONG i = 0; - BOOLEAN IsPortInAdapterList = FALSE; - - if (Adapter && PortToRemove) - { - MbbAdapterPortsLock(Adapter); - - NumberOfPorts = Adapter->NumberOfPorts; - - if (NumberOfPorts != 0 && NumberOfPorts <= Adapter->MaxActivatedContexts) - { - // first find the index of the port to be deleted in the adapter list - for (i = 0; i < NumberOfPorts; i++) - { - if (Adapter->PortList[i] == PortToRemove) - { - Adapter->PortList[i] = NULL; - IsPortInAdapterList = TRUE; - break; - } - } - - if (IsPortInAdapterList == FALSE) - { - MbbAdapterPortsUnlock(Adapter); - return FALSE; - } - - _Analysis_assume_(NumberOfPorts > 0); - - NumberOfPorts = NumberOfPorts - 1; - - // now shift all the ports after this port to the left - for (; i < NumberOfPorts; i++) - { - Adapter->PortList[i] = Adapter->PortList[i + 1]; - Adapter->PortList[i + 1] = NULL; - } - - // decrement the count of ports - Adapter->NumberOfPorts--; - } - - MbbAdapterPortsUnlock(Adapter); - - // Remove the reference to the port since now this port has been - // removed from the adapter's port list - - Dereference(PortToRemove); - return TRUE; - } - return FALSE; -} -_Requires_lock_not_held_(&Adapter->PortsLock) -PMBB_PORT -MbbWwanTranslatePortNumberToPort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ NDIS_PORT_NUMBER PortNumber - ) -{ - ULONG i = 0; - PMBB_PORT tempPort; - - MbbAdapterPortsLock(Adapter); - - for (i = 0; i < Adapter->NumberOfPorts; i++) - { - tempPort = Adapter->PortList[i]; - - MBB_ACQUIRE_PORT_LOCK(tempPort); - - if (tempPort->PortNumber == PortNumber) - { - // Add a reference and return - Reference(tempPort); - MBB_RELEASE_PORT_LOCK(tempPort); - MbbAdapterPortsUnlock(Adapter); - return tempPort; - } - - MBB_RELEASE_PORT_LOCK(tempPort); - } - - MbbAdapterPortsUnlock(Adapter); - - return NULL; -} - -_Requires_lock_not_held_(&Adapter->PortsLock) -PMBB_PORT -MbbWwanTranslateSessionIdToPort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ ULONG SessionId - ) -{ - ULONG i = 0; - PMBB_PORT tempPort = NULL; - - do - { - if(SessionId == MBB_INVALID_SESSION_ID) - { - break; - } - - MbbAdapterPortsLock(Adapter); - - for (i = 0; i < Adapter->NumberOfPorts; i++) - { - tempPort = Adapter->PortList[i]; - - MBB_ACQUIRE_PORT_LOCK(tempPort); - - if (tempPort->SessionId == SessionId) - { - // Add a reference and return - Reference(tempPort); - MBB_RELEASE_PORT_LOCK(tempPort); - MbbAdapterPortsUnlock(Adapter); - return tempPort; - } - - MBB_RELEASE_PORT_LOCK(tempPort); - } - - MbbAdapterPortsUnlock(Adapter); - }while(FALSE); - - return NULL; -} - -_Requires_lock_not_held_(&Port->Lock) -VOID -MbbWwanSetPortConnectionId( - __in PMBB_PORT Port, - __in ULONG ConnectionId - ) -{ - if(Port != NULL) - { - MBB_ACQUIRE_PORT_LOCK(Port); - Port->ConnectionId = ConnectionId; - MBB_RELEASE_PORT_LOCK(Port); - } -} - -_Requires_lock_not_held_(&Port->Lock) -ULONG -MbbWwanGetPortConnectionId( - __in PMBB_PORT Port - ) -{ - ULONG ConnectionId = 0; - - if(Port != NULL) - { - MBB_ACQUIRE_PORT_LOCK(Port); - ConnectionId = Port->ConnectionId; - MBB_RELEASE_PORT_LOCK(Port); - } - - return ConnectionId; -} - -_Requires_lock_not_held_(&Port->Lock) -NDIS_STATUS -MbbWwanSetPortSessionId( - __in PMBB_PORT Port - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - - ULONG MaxActivatedContexts = 0; - BOOLEAN fSessionIdFound = FALSE; - UINT i = 0; - - if(!Port) - { - return NDIS_STATUS_INVALID_PARAMETER; - } - - Adapter = Port->Adapter; - - MbbAdapterPortsLock(Adapter); - MaxActivatedContexts = Adapter->MaxActivatedContexts; - MbbAdapterPortsUnlock(Adapter); - - // Get a session Id and assign it to the port - MbbAdapterSessionIdPortTableLock(Adapter); - - MBB_ACQUIRE_PORT_LOCK(Port); - - if(Port->PortNumber == DEFAULT_NDIS_PORT_NUMBER) - { - if(MaxActivatedContexts >= 1) - { - // We dont check for Adapter->SessionIdPortTable[0].InUse flag here - // because if we send a connect request to the device with a session Id that - // is already connected, the device is supposed to succeed the call as per the MBIM spec. - // Also this is existing Win8 behavior. - - Port->SessionId = MBB_DEFAULT_SESSION_ID; - fSessionIdFound = TRUE; - } - else - { - TraceError( WMBCLASS_UTIL, "[MbbWwanSetPortSessionId] Device should support atleast 1 context"); - } - } - else - { - for(i = 1; i < MaxActivatedContexts; i++) - { - // We check for Adapter->SessionIdPortTable[0].InUse flag here because - // at this instant there can be multiple PDP contexts connected and we need to - // find an available session Id that can be used for this new PDP context. - - if(!Adapter->SessionIdPortTable[i].InUse) - { - // free session id slot - Port->SessionId = i; - fSessionIdFound = TRUE; - break; - } - } - } - - if(fSessionIdFound) - { - Adapter->SessionIdPortTable[Port->SessionId].InUse = TRUE; - Adapter->SessionIdPortTable[Port->SessionId].PortNumber = Port->PortNumber; - } - else - { - Status = NDIS_STATUS_FAILURE; - } - - MBB_RELEASE_PORT_LOCK(Port); - - MbbAdapterSessionIdPortTableUnlock(Adapter); - - return Status; -} - -_Requires_lock_not_held_(&Port->Lock) -LONG -MbbWwanGetPortSessionId( - __in PMBB_PORT Port - ) -{ - LONG SessionId = MBB_INVALID_SESSION_ID; - - if(Port != NULL) - { - MBB_ACQUIRE_PORT_LOCK(Port); - SessionId = Port->SessionId; - MBB_RELEASE_PORT_LOCK(Port); - } - - return SessionId; -} - -_Requires_lock_not_held_(&Port->Lock) -VOID -MbbWwanResetPortSessionId( - __in PMBB_PORT Port, - __in BOOLEAN ReturnSessionId - ) -{ - if(Port != NULL) - { - PMINIPORT_ADAPTER_CONTEXT Adapter = Port->Adapter; - ULONG SessionId = (ULONG)MBB_INVALID_SESSION_ID; - - MBB_ACQUIRE_PORT_LOCK(Port); - SessionId = Port->SessionId; - - // set the session id of the default port to 0 always. - // this is because when service starts, get connection - // state requests arrive on Port no 0. If the session id - // is set to -1, these requests will fail. - - Port->SessionId = (IS_ALLOCATED_PORT_NUMBER(Port->PortNumber)) ? - MBB_INVALID_SESSION_ID : MBB_DEFAULT_SESSION_ID ; - MBB_RELEASE_PORT_LOCK(Port); - - TraceInfo( WMBCLASS_UTIL, "[MbbWwanResetPortSessionId] Resetting Port session ID for port number %lu. Session ID: [%lu] -> [%lu]", Port->PortNumber, SessionId, Port->SessionId); - - if(ReturnSessionId) - { - // this implies that a session id was actually alloted - // to this port. Hence it needs to be returned. - MbbWwanReturnSessionId(Adapter,SessionId); - } - else - { - TraceInfo( WMBCLASS_UTIL, "[MbbWwanResetPortSessionId] Not returning session id = %d to adapter for port number %lu. This may be expected.", SessionId, Port->PortNumber); - } - } -} - -_Requires_lock_not_held_(&Adapter->PortsLock) -_Requires_lock_not_held_(&Adapter->SessionIdPortTableLock) -NDIS_STATUS -MbbWwanReturnSessionId( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in ULONG SessionId) -{ - - ULONG MaxActivatedContexts = 0; - - /* SessionId is acquired whenever a context activation request comes. - * But it is returned in the following cases: - * 1) Successful context deactivation. - * 2) Failed context activation attempt. - * 3) When port is torn down before context deactivation. - */ - - MbbAdapterPortsLock(Adapter); - MaxActivatedContexts = Adapter->MaxActivatedContexts; - MbbAdapterPortsUnlock(Adapter); - - if(SessionId != MBB_INVALID_SESSION_ID - && SessionId < MaxActivatedContexts) - { - TraceInfo( WMBCLASS_UTIL, "[MbbWwanReturnSessionId] Returning session id %lu to adapter",SessionId); - - MbbAdapterSessionIdPortTableLock(Adapter); - - Adapter->SessionIdPortTable[SessionId].InUse = FALSE; - Adapter->SessionIdPortTable[SessionId].PortNumber = (ULONG)MBB_INVALID_PORT_NUMBER; - - MbbAdapterSessionIdPortTableUnlock(Adapter); - } - - return NDIS_STATUS_SUCCESS; -} - -_Requires_lock_not_held_(&Adapter->PortsLock) -DWORD -MbbWwanGetNumPortsConnected( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ) -{ - ULONG NumConnectedPorts = 0; - ULONG i = 0; - - if(Adapter) - { - MbbAdapterPortsLock(Adapter); - - for(i = 0; i < Adapter->NumberOfPorts && NumConnectedPorts < MBB_MAX_NUMBER_OF_PORTS; i++) - { - PMBB_PORT Port = Adapter->PortList[i]; - - MBB_ACQUIRE_PORT_LOCK(Port); - - if(Port->ConnectionState.ConnectionUp) - { - ASSERT(Port->SessionId != MBB_INVALID_SESSION_ID && (ULONG)Port->SessionId < Adapter->MaxActivatedContexts); - NumConnectedPorts++; - } - - MBB_RELEASE_PORT_LOCK(Port); - } - - MbbAdapterPortsUnlock(Adapter); - } - - return NumConnectedPorts; -} - diff --git a/network/wwan/cxwmbclass/port.h b/network/wwan/cxwmbclass/port.h deleted file mode 100644 index fd54b0e4b..000000000 --- a/network/wwan/cxwmbclass/port.h +++ /dev/null @@ -1,252 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - port.h - -Abstract: - Contains port declarations. - -Revision History: - When What - ---------- ---------------------------------------------- - 11-21-2012 Created - -Notes: - ---*/ -#pragma once - -#define DEFAULT_NDIS_PORT_NUMBER 0 - -// port lock manipulation macros -#define MBB_ACQUIRE_PORT_LOCK(_Port) \ - NdisAcquireSpinLock(&(_Port->Lock)) - -#define MBB_RELEASE_PORT_LOCK(_Port) \ - NdisReleaseSpinLock(&(_Port->Lock)) - -#define MBB_PORT_SET_SESSION_ID(_Port,_SessionId) \ - (_Port)->SessionId = (_SessionId) - -#define MBB_PORT_RESET_SESSION_ID(_Port) \ - (_Port)->SessionId = MBB_INVALID_SESSION_ID - - -typedef struct _REF_COUNT *PREF_COUNT; - -typedef VOID (*REFERENCE_OBJECT_CLEANUP_FN)(PREF_COUNT RefObj); - - -typedef struct _REF_COUNT -{ - ULONG RefCount; - REFERENCE_OBJECT_CLEANUP_FN Cleanup; -} REF_COUNT, *PREF_COUNT; - - -LONG -__inline ReferenceRefCount(PREF_COUNT RefCountObj) -{ - LONG newRef = InterlockedIncrement((volatile LONG *)&RefCountObj->RefCount); - ASSERT(newRef > 0); - - return newRef; -} - -LONG -__inline DereferenceRefCount(PREF_COUNT RefCountObj) -{ - LONG newRef = InterlockedDecrement((volatile LONG *)&RefCountObj->RefCount); - - ASSERT(newRef >= 0); - - if( newRef == 0 ) - { - RefCountObj->Cleanup(RefCountObj); - } - - return newRef; -} - -#define Reference(x) ReferenceRefCount(&(x)->RefCount) - -#define Dereference(x) DereferenceRefCount(&(x)->RefCount) - -VOID -__inline InitializeRefCount( - IN PREF_COUNT RefCountObj, - IN REFERENCE_OBJECT_CLEANUP_FN CleanupFn -) -{ - RefCountObj->Cleanup = CleanupFn; - RefCountObj->RefCount= 1; -} - - -// Just a busy wait for PortList refcount to go to 0 -//#define MBB_WAIT_FOR_PORTLIST_REFCOUNT(_Adapter) \ - // MP_VERIFY_PASSIVE_IRQL(); \ - // while (_Adapter->PortRefCount != 0) NdisMSleep(10); -// Macro to verify if this port number is allocated/"registered" with NDIS - -#define IS_ALLOCATED_PORT_NUMBER(_PortNumber) (_PortNumber != DEFAULT_NDIS_PORT_NUMBER) - -typedef enum _MBB_PORT_STATE -{ - PortDeactivated = 0, - PortActivating, - PortActivated, - PortDeactivating -} MBB_PORT_STATE; - - -typedef struct _MBB_PORT -{ - /** - * The handle by which NDIS recognizes this adapter. This handle needs to be passed - * in for many of the calls made to NDIS - */ - NDIS_HANDLE MiniportAdapterHandle; - - PMINIPORT_ADAPTER_CONTEXT Adapter; // Miniport adapter context - - NDIS_PORT_NUMBER PortNumber; // NDIS allocate port number - - /** State of the PORT.*/ - MBB_PORT_STATE State; - - UCHAR MACAddress[MBB_MAC_ADDRESS_LENGTH]; - - /** Refcount tracking operations that would block Pause/Restart, etc operations */ - REF_COUNT RefCount;// Used by Port/MP - - ULONG ConnectionId; - - LONG SessionId; - - MBB_CONNECTION_STATE ConnectionState; - - PMBB_IP_ADDRESS_INFO IpAddressInfo; - - BOOLEAN HasNoMatchWolPattern; - - /** Lock used to protect the PORT data including PortNumber, State and ConnectionCtx*/ - NDIS_SPIN_LOCK Lock; -} MBB_PORT, *PMBB_PORT; - -NDIS_STATUS -MbbWwanAllocateBasePort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _Outptr_result_nullonfailure_ PMBB_PORT* Port - ); - -VOID -MbbWwanFreeBasePort( - _In_ __drv_freesMem(Mem) PMBB_PORT Port - ); - -NDIS_STATUS -MbbWwanAllocatePort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ BOOLEAN fAllocateNdisPort, - _Outptr_result_nullonfailure_ PMBB_PORT* Port - ); - - -VOID -MbbWwanDeallocatePort( - _In_ PMBB_PORT Port - ); - -VOID -MbbWwanFreePort( - _In_ PREF_COUNT RefObj - ); - -NDIS_STATUS -MbbWwanActivatePort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port - ); - -NDIS_STATUS -MbbWwanDeactivatePort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port - ); - -_Requires_lock_not_held_(&Adapter->PortsLock) -VOID -MbbWwanAddPortToAdapterList( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT* PortToAdd - ); - -_Requires_lock_not_held_(&Adapter->PortsLock) -BOOL -MbbWwanRemovePortFromAdapterList( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT PortToRemove - ); - -_Requires_lock_not_held_(&Adapter->PortsLock) -PMBB_PORT -MbbWwanTranslatePortNumberToPort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ NDIS_PORT_NUMBER PortNumber - ); - -_Requires_lock_not_held_(&Adapter->PortsLock) -PMBB_PORT -MbbWwanTranslateSessionIdToPort( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ ULONG SessionId - ); - -_Requires_lock_not_held_(&Port->Lock) -VOID -MbbWwanSetPortConnectionId( - __in PMBB_PORT Port, - __in ULONG ConnectionId - ); - -_Requires_lock_not_held_(&Port->Lock) -ULONG -MbbWwanGetPortConnectionId( - __in PMBB_PORT Port - ); - -_Requires_lock_not_held_(&Port->Lock) -NDIS_STATUS -MbbWwanSetPortSessionId( - __in PMBB_PORT Port - ); - -_Requires_lock_not_held_(&Port->Lock) -LONG -MbbWwanGetPortSessionId( - __in PMBB_PORT Port - ); - -_Requires_lock_not_held_(&Port->Lock) -VOID -MbbWwanResetPortSessionId( - __in PMBB_PORT Port, - __in BOOLEAN ReturnSessionId - ); - -_Requires_lock_not_held_(&Adapter->PortsLock) -_Requires_lock_not_held_(&Adapter->SessionIdPortTableLock) -NDIS_STATUS -MbbWwanReturnSessionId( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in ULONG SessionId - ); - -_Requires_lock_not_held_(&Adapter->PortsLock) -DWORD -MbbWwanGetNumPortsConnected( - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); diff --git a/network/wwan/cxwmbclass/power.cpp b/network/wwan/cxwmbclass/power.cpp new file mode 100644 index 000000000..5a67ed1a4 --- /dev/null +++ b/network/wwan/cxwmbclass/power.cpp @@ -0,0 +1,117 @@ +//------------------------------------------------------------------------------- +// Net Adapter source file +// +// Copyright (c) Microsoft Corporation. All rights reserved. + +#include "precomp.h" + +#include "power.h" +#include "device.h" +#include "adapter.h" + +_Use_decl_annotations_ NTSTATUS EvtDeviceD0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE previousPowerState) +{ + NTSTATUS status = STATUS_SUCCESS; + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(Device); + UNREFERENCED_PARAMETER(previousPowerState); + do + { + if (MbbBusIsStoped(deviceContext->BusHandle)) + { + // + // device was in d3, open it again + // + status = MbbBusStart(deviceContext->BusHandle); + + if (!NT_SUCCESS(status)) + { + WdfDeviceSetFailed(deviceContext->WdfDevice, WdfDeviceFailedAttemptRestart); + break; + } + } + else + { + MbbBusSetNotificationState(deviceContext->BusHandle, TRUE); + } + // Allow sessions to receive data from this point since RxQueueCreate happens later after D0Entry. We need cache NDPs receive before RxQueueCreate + for (int i = 0; i < MBB_MAX_NUMBER_OF_SESSIONS; i++) + { + if (deviceContext->Sessions[i].NetAdapterContext == NULL) + { + continue; + } + deviceContext->Sessions[i].NetAdapterContext->AllowRxTraffic = TRUE; + } + MbbBusStartDataPipes(deviceContext->BusHandle); + } while (FALSE); + + return status; +} + +_Use_decl_annotations_ NTSTATUS EvtDeviceD0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetPowerState) +{ + UNREFERENCED_PARAMETER(TargetPowerState); + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(Device); + + MbbBusStopDataPipes(deviceContext->BusHandle); + // + // If the device is not armed for wake, close has been sent by MbbCx. All response available notifications from close in MbbCx to EvtDeviceD0Exit will be ignored. + // + // If the device is armed for wake, No response available notification after EvtDeviceArmWakeFromS0 where we stop the notification. + if (!deviceContext->m_armedWake) + { + MbbBusStop(deviceContext->BusHandle); + } + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ NTSTATUS EvtDevicePreviewBitmapPattern(WDFDEVICE Device, NETWAKESOURCE BitmapPattern) +{ + // We don't need to look at the pattern itself, only how many we currently have + UNREFERENCED_PARAMETER(BitmapPattern); + + NET_WAKE_SOURCE_LIST wakeSourceList; + NET_WAKE_SOURCE_LIST_INIT(&wakeSourceList); + NetDeviceGetWakeSourceList(Device, &wakeSourceList); + + auto const wakeSourceCount = NetWakeSourceListGetCount(&wakeSourceList); + size_t numberOfPowerFilters = 0; + + // Count how many power filters are currently stored for this device + for (size_t i = 0; i < wakeSourceCount; i++) + { + auto wakeSource = NetWakeSourceListGetElement(&wakeSourceList, i); + auto const wakeSourceType = NetWakeSourceGetType(wakeSource); + + if (wakeSourceType == NetWakeSourceTypeBitmapPattern) + { + numberOfPowerFilters++; + } + } + + auto const deviceContext = WmbClassGetDeviceContext(Device); + auto const maxPowerFilters = deviceContext->BusParams.PowerFiltersSupported; + + NT_ASSERT(numberOfPowerFilters <= maxPowerFilters); + + if (numberOfPowerFilters == maxPowerFilters) + { + return STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL; + } + + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ NTSTATUS EvtDeviceArmWakeFromS0(WDFDEVICE Device) +{ + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(Device); + deviceContext->m_armedWake = true; + MbbBusSetNotificationState(deviceContext->BusHandle, FALSE); + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ VOID EvtDeviceDisarmWakeFromS0(WDFDEVICE Device) +{ + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(Device); + deviceContext->m_armedWake = false; +} diff --git a/network/wwan/cxwmbclass/precomp.h b/network/wwan/cxwmbclass/precomp.h deleted file mode 100644 index c825e4d40..000000000 --- a/network/wwan/cxwmbclass/precomp.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define INITGUID -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "wmbclass.h" -#include "port.h" -#include "WwanDrvCmn.h" -#include "adapter.h" -#include "send.h" -#include "receive.h" -#include "RequestManager.h" -#include "IpAddress.h" -#include "IpAddressCmn.h" -#include "util.h" -#include "MbbFastIODataPlane.h" -#include "MbbFastIOControlPlane.h" -#include diff --git a/network/wwan/cxwmbclass/product.pbxproj b/network/wwan/cxwmbclass/product.pbxproj deleted file mode 100644 index 8de56fe44..000000000 --- a/network/wwan/cxwmbclass/product.pbxproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - v110 - Utility - - - - - false - - - \ No newline at end of file diff --git a/network/wwan/cxwmbclass/receive.c b/network/wwan/cxwmbclass/receive.c deleted file mode 100644 index 078fe8109..000000000 --- a/network/wwan/cxwmbclass/receive.c +++ /dev/null @@ -1,1961 +0,0 @@ -/*************************************************************************** - -Copyright (c) 2010 Microsoft Corporation - -Module Name: - Receive.c - -Abstract: - This module contains routines that parse data coming from the network. - Verifications on the receive path are very light. Alignment checks and - max size checks are not made. These constraints are meant for the device - rather than for the host. NTBs are only checked for buffer overflow and - malformed data. - -Environment: - kernel mode only - -Notes: - -Revision History: - 3/22/2011 : created - -Authors: - TriRoy - -****************************************************************************/ - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// INCLUDES -// -//////////////////////////////////////////////////////////////////////////////// -#include "precomp.h" -#include "receive.tmh" - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// -#define MBB_ETHER_TYPE_IPV4 0x0800 -#define MBB_ETHER_TYPE_IPV6 0x86dd - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// TYPEDEFS -// -//////////////////////////////////////////////////////////////////////////////// - -typedef struct _MBB_NDIS_RECEIVE_NDP_CONTEXT -{ - LIST_ENTRY NblQueue; - // - // Resources - // - PNET_BUFFER_LIST FirstNbl; - PNET_BUFFER_LIST CurrentNbl; - ULONG NblCount; - - SESSIONID_PORTNUMBER_ENTRY SessionIdPortNumberEntry; -}MBB_NDIS_RECEIVE_NDP_CONTEXT,*PMBB_NDIS_RECEIVE_NDP_CONTEXT; - -typedef struct _MBB_NDIS_RECEIVE_CONTEXT -{ - LIST_ENTRY ReceivedQLink; - NDIS_SPIN_LOCK Lock; - - // - // Protected by lock - // - - MBB_NDIS_RECEIVE_NDP_CONTEXT ReceiveNdpContext[MBB_MAX_NUMBER_OF_PORTS]; - - // - // Resources - // - PMDL Mdl; - PNPAGED_LOOKASIDE_LIST ReceiveLookasideList; - PMBB_RECEIVE_QUEUE RecvQueue; - PMINIPORT_ADAPTER_CONTEXT AdapterContext; - MBB_BUS_HANDLE BusHandle; - MBB_RECEIVE_CONTEXT BusContext; - // - // Parse state - // - ULONG NtbSequence; - -} MBB_NDIS_RECEIVE_CONTEXT, -*PMBB_NDIS_RECEIVE_CONTEXT; - -typedef struct _MBB_NBL_RECEIVE_CONTEXT -{ - LIST_ENTRY NblQLink; - PNET_BUFFER_LIST NetBufferList; - PMBB_NDIS_RECEIVE_CONTEXT Receive; -} MBB_NBL_RECEIVE_CONTEXT, -*PMBB_NBL_RECEIVE_CONTEXT; - -typedef -__callback NDIS_STATUS -(*MBB_NDP_CALLBACK)( - __in PVOID Nth, - __in PVOID Ndp, - __in PVOID Context - ); - -typedef -__callback NDIS_STATUS -(*MBB_DATAGRAM_CALLBACK)( - __in PVOID Nth, - __in ULONG NdpSignature, - __in PVOID Datagram, - __in ULONG DatagramLength, - __in ULONG SessionId, - __in PVOID Context - ); - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// PROTOTYPES -// -//////////////////////////////////////////////////////////////////////////////// - -// -// NTB -// - -NDIS_STATUS -MbbNtbValidate( - __in PVOID Nth, - __in ULONG BufferLength, - __in BOOLEAN Is32Bit - ); - -NDIS_STATUS -MbbNtbParse( - __in PVOID Nth, - __in ULONG BufferLength, - __in MBB_NDP_CALLBACK Callback, - __in PVOID Context - ); - -// -// NTB32 -// - -// Validation - -NDIS_STATUS -MbbNtbValidateNth32( - __in PNCM_NTH32 Nth, - __in ULONG BufferLength - ); - -NDIS_STATUS -MbbNtbValidateNdp32( - __in PNCM_NTH32 Nth, - __in PNCM_NDP32 Ndp - ); - -NDIS_STATUS -MbbNtbDetectNdp32Loop( - __in PNCM_NTH32 Nth - ); - -// Parsing - -NDIS_STATUS -MbbNtbParseNth32( - __in PNCM_NTH32 Nth, - __in ULONG BufferLength, - __in MBB_NDP_CALLBACK Callback, - __in PVOID Context - ); - -NDIS_STATUS -MbbNtbParseNdp32( - __in PNCM_NTH32 Nth, - __in PNCM_NDP32 Ndp, - __in MBB_DATAGRAM_CALLBACK Callback, - __in PVOID Context - ); - -// -// NTB16 -// - -// Validation - -NDIS_STATUS -MbbNtbValidateNth16( - __in PNCM_NTH16 Nth, - __in ULONG BufferLength - ); - -NDIS_STATUS -MbbNtbValidateNdp16( - __in PNCM_NTH16 Nth, - __in PNCM_NDP16 Ndp - ); - -NDIS_STATUS -MbbNtbDetectNdp16Loop( - __in PNCM_NTH16 Nth - ); - -// Parsing - -NDIS_STATUS -MbbNtbParseNth16( - __in PNCM_NTH16 Nth, - __in ULONG BufferLength, - __in MBB_NDP_CALLBACK Callback, - __in PVOID Context - ); - -NDIS_STATUS -MbbNtbParseNdp16( - __in PNCM_NTH16 Nth, - __in PNCM_NDP16 Ndp, - __in MBB_DATAGRAM_CALLBACK Callback, - __in PVOID Context - ); - -// -// RecvQ -// - -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( SpinLock, RecvQueue->Lock ) -__drv_when( DispatchLevel == FALSE, __drv_raisesIRQL(DISPATCH_LEVEL)) -FORCEINLINE -VOID -MbbRecvQLock( - __in __drv_at( RecvQueue->Lock, __drv_acquiresResource( Spinlock ) ) - PMBB_RECEIVE_QUEUE RecvQueue, - __in BOOLEAN DispatchLevel - ); - -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( SpinLock, RecvQueue->Lock ) -FORCEINLINE -VOID -MbbRecvQUnlock( - __in __drv_at( RecvQueue->Lock, __drv_releasesResource( Spinlock ) ) - PMBB_RECEIVE_QUEUE RecvQueue, - __in BOOLEAN DispatchLevel - ); - -PMBB_NDIS_RECEIVE_CONTEXT -MbbRecvQQueueReceive( - __in PMBB_RECEIVE_QUEUE RecvQueue, - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_RECEIVE_CONTEXT BusContext, - __in PMDL Mdl - ); - -VOID -MbbRecvQDequeueReceive( - __in PMBB_RECEIVE_QUEUE RecvQueue, - __in PMBB_NDIS_RECEIVE_CONTEXT Receive - ); - -// -// Receive Context -// - -NDIS_STATUS -MbbReceiveParseNdp( - __in PVOID Nth, - __in PVOID Ndp, - __in PVOID Context - ); - -NDIS_STATUS -MbbReceiveAddNbl( - __in PVOID Nth, - __in ULONG NdpSignature, - __in PVOID Datagram, - __in ULONG DatagramLength, - __in ULONG SessionId, - __in PVOID Context - ); - -NDIS_STATUS -MbbReceiveDssData( - __in PVOID Nth, - __in ULONG NdpSignature, - __in PVOID Datagram, - __in ULONG DatagramLength, - __in ULONG SessionId, - __in PVOID Context - ); - -VOID -MbbReceiveRemoveNbl( - __in PMBB_NDIS_RECEIVE_CONTEXT Receive, - __in PNET_BUFFER_LIST NetBufferList - ); - -VOID -MbbReceiveCleanupNbls( - __in PMBB_NDIS_RECEIVE_CONTEXT Receive - ); - -// -// NBL -// - -__drv_allocatesMem(mem) -PNET_BUFFER_LIST -MbbNblAlloc( - __in PVOID Nth, - __in PVOID Datagram, - __in ULONG DatagramLength, - __in PMBB_NDIS_RECEIVE_CONTEXT Receive - ); - -VOID -MbbNblCleanup( - __in PNET_BUFFER_LIST NetBufferList - ); - -// -// CID RESPONSE / INDICATION PARSING -// - -NTSTATUS -MbbNdisProcessCidData( - __in_bcount(Length) PUCHAR Buffer, - __in ULONG Length, - __in PMBB_REQUEST_MANAGER RequestManager - ); - -VOID -MbbNdisProcessDeviceServiceCommandResponse( - __in_bcount(FragmentLength) PUCHAR FragmentBuffer, - __in ULONG FragmentLength, - __in PMBB_REQUEST_MANAGER RequestManager - ); - -VOID -MbbNdisProcessDeviceServiceStatusIndication( - __in_bcount(FragmentLength) PUCHAR FragmentBuffer, - __in ULONG FragmentLength, - __in PMBB_REQUEST_MANAGER RequestManager - ); - -// -// Test -// - -#if DBG - -VOID -MbbTestValidateNblChain( - __in PNET_BUFFER_LIST NblChain - ); - -#endif - - -//////////////////////////////////////////////////////////////////////////////// -// -// IMPLEMENTATION -// -//////////////////////////////////////////////////////////////////////////////// - -// -// NTB -// - -NDIS_STATUS -MbbNtbValidate( - __in PVOID Nth, - __in ULONG BufferLength, - __in BOOLEAN Is32Bit - ) -{ - if( Is32Bit == TRUE ) - return MbbNtbValidateNth32( (PNCM_NTH32)Nth, BufferLength ); - else - return MbbNtbValidateNth16( (PNCM_NTH16)Nth, BufferLength ); -} - -NDIS_STATUS -MbbNtbParse( - __in PVOID Nth, - __in ULONG BufferLength, - __in MBB_NDP_CALLBACK Callback, - __in PVOID Context - ) -/*++ - NOTE: - Assumed that NTH has already been validated. - No validations are performed during parsing. ---*/ -{ - if( MBB_NTB_IS_32BIT( Nth ) ) - { - return MbbNtbParseNth32( - ((PNCM_NTH32)Nth), - BufferLength, - Callback, - Context - ); - } - else if( MBB_NTB_IS_16BIT( Nth ) ) - { - return MbbNtbParseNth16( - ((PNCM_NTH16)Nth), - BufferLength, - Callback, - Context - ); - } - else - { - TraceError( WMBCLASS_RECEIVE, "[NTB][Seq=0x%04x] BAD NTB signature=0x%04x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_SIGNATURE( Nth ) - ); - return NDIS_STATUS_FAILURE; - } -} - -NDIS_STATUS -MbbNtbParseNdp( - __in PVOID Nth, - __in PVOID Ndp, - __in MBB_DATAGRAM_CALLBACK Callback, - __in PVOID CallbackContext - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PMBB_NDIS_RECEIVE_CONTEXT Receive = (PMBB_NDIS_RECEIVE_CONTEXT)CallbackContext; - PMINIPORT_ADAPTER_CONTEXT Adapter = Receive->AdapterContext; - SESSIONID_PORTNUMBER_ENTRY SessionIdPortNumberEntry = {0}; - ULONG SessionId = MBB_INVALID_SESSION_ID; - BOOLEAN IsDeviceServiceStream = FALSE; - - do - { - if( MBB_NTB_IS_32BIT( Nth ) ) - { - if(MBB_NDP32_GET_SIGNATURE_TYPE((PNCM_NDP32)Ndp) == NCM_NDP32_VENDOR) - { - IsDeviceServiceStream = TRUE; - } - else if(MBB_NDP32_GET_SIGNATURE_TYPE((PNCM_NDP32)Ndp) == NCM_NDP32_IPS) - { - SessionId = MBB_NDP32_GET_SESSIONID((PNCM_NDP32)Ndp ); - } - else - { - ASSERT(FALSE); - } - } - else - { - if(MBB_NDP16_GET_SIGNATURE_TYPE((PNCM_NDP16)Ndp) == NCM_NDP16_VENDOR) - { - IsDeviceServiceStream = TRUE; - } - else if(MBB_NDP16_GET_SIGNATURE_TYPE((PNCM_NDP16)(Ndp)) == NCM_NDP16_IPS) - { - SessionId = MBB_NDP16_GET_SESSIONID((PNCM_NDP16)Ndp); - } - else - { - ASSERT(FALSE); - } - } - - if(!IsDeviceServiceStream) - { - if( SessionId >= MBB_MAX_NUMBER_OF_PORTS - || SessionId == MBB_INVALID_SESSION_ID) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature sessionid=%lu for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - SessionId, - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - NdisStatus = NDIS_STATUS_INVALID_PARAMETER; - break; - } - - MbbAdapterSessionIdPortTableLock(Adapter); - - SessionIdPortNumberEntry = Adapter->SessionIdPortTable[SessionId]; - - MbbAdapterSessionIdPortTableUnlock(Adapter); - - if(!SessionIdPortNumberEntry.InUse) - { - //discard - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] FAILED to parse Ndp as session id is not in use.Session Id is %lu", - MBB_NTB_GET_SEQUENCE( Nth ), - SessionId - ); - NdisStatus = NDIS_STATUS_INVALID_PARAMETER; - break; - } - - Receive->ReceiveNdpContext[SessionId].SessionIdPortNumberEntry = SessionIdPortNumberEntry; - } - - if( MBB_NTB_IS_32BIT( Nth ) ) - { - NdisStatus = MbbNtbParseNdp32( - (PNCM_NTH32)Nth, - (PNCM_NDP32)Ndp, - Callback, - CallbackContext - ); - } - else - { - NdisStatus = MbbNtbParseNdp16( - (PNCM_NTH16)Nth, - (PNCM_NDP16)Ndp, - Callback, - CallbackContext - ); - } - }while(FALSE); - - return NdisStatus; -} - -// -// NTB32 -// - -NDIS_STATUS -MbbNtbDetectNdp32Loop( - __in PNCM_NTH32 Nth - ) -{ - PNCM_NDP32 FirstNdp; - PNCM_NDP32 Ndp; - PNCM_NDP32 LoopNdp; - - if( (FirstNdp = MBB_NTH32_GET_FIRST_NDP( Nth )) == NULL ) - return NDIS_STATUS_SUCCESS; - - if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, FirstNdp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, FirstNdp ) - ); - return NDIS_STATUS_FAILURE; - } - LoopNdp = MBB_NDP32_GET_NEXT_NDP( Nth, FirstNdp ); - - for( Ndp = FirstNdp; - Ndp != NULL && LoopNdp != NULL; - Ndp = MBB_NDP32_GET_NEXT_NDP( Nth, Ndp ) ) - { - if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, LoopNdp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, LoopNdp ) - ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, Ndp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - - if( LoopNdp == Ndp ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] Loop detected on NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - - if( (LoopNdp = MBB_NDP32_GET_NEXT_NDP( Nth, LoopNdp )) != NULL ) - { - if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, LoopNdp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, LoopNdp ) - ); - return NDIS_STATUS_FAILURE; - } - LoopNdp = MBB_NDP32_GET_NEXT_NDP( Nth, LoopNdp ); - } - } - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNtbValidateNdp32( - __in PNCM_NTH32 Nth, - __in PNCM_NDP32 Ndp - ) -{ - ULONG Index; - ULONG DatagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp); - PNCM_NDP32_DATAGRAM Datagram; - - if( ! MBB_NTB32_IS_VALID_NDP_SIGNATURE( Ndp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature=0x%08x for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NDP32_GET_SIGNATURE( Ndp ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - - if (MBB_NDP32_GET_SIGNATURE_TYPE( Ndp) == NCM_NDP32_IPS) - { - // - // Check if the session id is valid, else discard - // - - // Check if session Id is greater than maximum supported. Here - // we can also check against MaxActivatedContexts, but this would - // mean we need to take a lock for getting the value of maxactivatedcontexts - // The lock can be avoided by checking against the maximum number of ports - // supported by the class driver. SESSION_PORT_TABLE.InUse can be used - // to check whether the session id is in use. - - if( MBB_NDP32_GET_SESSIONID( Ndp ) >= MBB_MAX_NUMBER_OF_PORTS - || MBB_NDP32_GET_SESSIONID( Ndp ) == MBB_INVALID_SESSION_ID) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature sessionid=0x%02x for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - (UCHAR)MBB_NDP32_GET_SESSIONID( Ndp ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - } - - if( ! MBB_NTB32_IS_VALID_NDP_LENGTH( Nth, Ndp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID length=0x%08x for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NDP32_GET_LENGTH( Ndp ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - - for( Index = 0; - Index < DatagramCount; - Index ++ ) - { - if( MBB_NTB32_IS_END_DATAGRAM( Nth, Ndp, Index ) ) - return NDIS_STATUS_SUCCESS; - - if( ! MBB_NTB32_IS_VALID_DATAGRAM( Nth, Ndp, Index ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID datagram at index=%02d for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - Index, - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - } - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNtbValidateNth32( - __in PNCM_NTH32 Nth, - __in ULONG BufferLength - ) -{ - PNCM_NDP32 Ndp; - - if( BufferLength < sizeof(NCM_NTH32) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH Buffer length=0x%08x", BufferLength ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTH32_IS_VALID_SIGNATURE( Nth ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH signature=0x%08x", MBB_NTB_GET_SIGNATURE( Nth ) ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTH32_IS_VALID_HEADER_LENGTH( Nth ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH header length=0x%08x", MBB_NTB_GET_HEADER_LENGTH( Nth ) ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTH32_IS_VALID_BLOCK_LENGTH( Nth, BufferLength ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH block length=0x%08x", MBB_NTH32_GET_BLOCK_LENGTH( Nth ) ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTH32_IS_VALID_FIRST_NDP( Nth ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH first NDP offset=0x%08x", MBB_NTH32_GET_FIRST_NDP_OFFSET( Nth ) ); - return NDIS_STATUS_FAILURE; - } - - if( MbbNtbDetectNdp32Loop( Nth ) != NDIS_STATUS_SUCCESS ) - return NDIS_STATUS_FAILURE; - - for( Ndp = MBB_NTH32_GET_FIRST_NDP( Nth ); - Ndp != NULL; - Ndp = MBB_NDP32_GET_NEXT_NDP( Nth, Ndp ) ) - { - if( MbbNtbValidateNdp32( Nth, Ndp ) != NDIS_STATUS_SUCCESS ) - return NDIS_STATUS_FAILURE; - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNtbParseNdp32( - __in PNCM_NTH32 Nth, - __in PNCM_NDP32 Ndp, - __in MBB_DATAGRAM_CALLBACK Callback, - __in PVOID Context - ) -{ - ULONG Index; - ULONG DatagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp); - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG SessionId = MBB_NDP32_GET_SESSIONID( Ndp ); - - for( Index = 0; - Index < DatagramCount; - Index ++ ) - { - if( MBB_NTB32_IS_END_DATAGRAM( Nth, Ndp, Index ) ) - break; - - if( ! MBB_NTB32_IS_VALID_DATAGRAM( Nth, Ndp, Index ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID datagram at index=%02d for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - Index, - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - - if( (NdisStatus = Callback( - Nth, - MBB_NDP32_GET_SIGNATURE( Ndp ), - MBB_NDP32_GET_DATAGRAM( Nth, Ndp, Index ), - MBB_NDP32_GET_DATAGRAM_LENGTH(Ndp,Index), - SessionId, - Context - )) != NDIS_STATUS_SUCCESS ) - { - break; - } - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNtbParseNth32( - __in PNCM_NTH32 Nth, - __in ULONG BufferLength, - __in MBB_NDP_CALLBACK Callback, - __in PVOID Context - ) -/*++ - NOTE: - Assumed that NTH has already been validated. - No validations are performed during parsing. ---*/ -{ - PNCM_NDP32 Ndp; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - for( Ndp = MBB_NTH32_GET_FIRST_NDP( Nth ); - Ndp != NULL; - Ndp = MBB_NDP32_GET_NEXT_NDP( Nth, Ndp ) ) - { - if( (NdisStatus = Callback( - Nth, - Ndp, - Context - )) != NDIS_STATUS_SUCCESS ) - { - break; - } - } - return NdisStatus; -} - -// -// NTB16 -// - -NDIS_STATUS -MbbNtbDetectNdp16Loop( - __in PNCM_NTH16 Nth - ) -{ - PNCM_NDP16 FirstNdp; - PNCM_NDP16 Ndp; - PNCM_NDP16 LoopNdp; - - if( (FirstNdp = MBB_NTH16_GET_FIRST_NDP( Nth )) == NULL ) - return NDIS_STATUS_SUCCESS; - - if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, FirstNdp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, FirstNdp ) - ); - return NDIS_STATUS_FAILURE; - } - LoopNdp = MBB_NDP16_GET_NEXT_NDP( Nth, FirstNdp ); - - for( Ndp = FirstNdp; - Ndp != NULL && LoopNdp != NULL; - Ndp = MBB_NDP16_GET_NEXT_NDP( Nth, Ndp ) ) - { - if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, LoopNdp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, LoopNdp ) - ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, Ndp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - - if( LoopNdp == Ndp ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] Loop detected on NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - - if( (LoopNdp = MBB_NDP16_GET_NEXT_NDP( Nth, LoopNdp )) != NULL ) - { - if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, LoopNdp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID NDP at offset=0x%08x, cannot detect loop", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, LoopNdp ) - ); - return NDIS_STATUS_FAILURE; - } - LoopNdp = MBB_NDP16_GET_NEXT_NDP( Nth, LoopNdp ); - } - } - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNtbValidateNdp16( - __in PNCM_NTH16 Nth, - __in PNCM_NDP16 Ndp - ) -{ - ULONG Index; - ULONG DatagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp); - PNCM_NDP16_DATAGRAM Datagram; - - if( ! MBB_NTB16_IS_VALID_NDP_SIGNATURE( Ndp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature=0x%08x for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NDP16_GET_SIGNATURE( Ndp ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - - - if (MBB_NDP16_GET_SIGNATURE_TYPE( Ndp) == NCM_NDP16_IPS) - { - // - // Check if the session id is valid, else discard - // - - // Check if session Id is greater than maximum supported. Here - // we can also check against MaxActivatedContexts, but this would - // mean we need to take a lock for getting the value of maxactivatedcontexts - // The lock can be avoided by checking against the maximum number of ports - // supported by the class driver. SESSION_PORT_TABLE.InUse can be used - // to check whether the session id is in use. - - if( MBB_NDP16_GET_SESSIONID( Ndp ) >= MBB_MAX_NUMBER_OF_PORTS - || MBB_NDP16_GET_SESSIONID( Ndp ) == MBB_INVALID_SESSION_ID ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID signature sessionid=0x%02x for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - (UCHAR)MBB_NDP16_GET_SESSIONID( Ndp ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - } - - if( ! MBB_NTB16_IS_VALID_NDP_LENGTH( Nth, Ndp ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID length=0x%08x for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NDP16_GET_LENGTH( Ndp ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - - for( Index = 0; - Index < DatagramCount; - Index ++ ) - { - if( MBB_NTB16_IS_END_DATAGRAM( Nth, Ndp, Index ) ) - return NDIS_STATUS_SUCCESS; - - if( ! MBB_NTB16_IS_VALID_DATAGRAM( Nth, Ndp, Index ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID datagram at index=%02d for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - Index, - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - return NDIS_STATUS_FAILURE; - } - } - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNtbValidateNth16( - __in PNCM_NTH16 Nth, - __in ULONG BufferLength - ) -{ - PNCM_NDP16 Ndp; - - if( BufferLength < sizeof(NCM_NTH16) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH Buffer length=0x%08x", BufferLength ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTH16_IS_VALID_SIGNATURE( Nth ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH signature=0x%08x", MBB_NTB_GET_SIGNATURE( Nth ) ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTH16_IS_VALID_HEADER_LENGTH( Nth ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH header length=0x%08x", MBB_NTB_GET_HEADER_LENGTH( Nth ) ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTH16_IS_VALID_BLOCK_LENGTH( Nth, BufferLength ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH block length=0x%08x", MBB_NTH16_GET_BLOCK_LENGTH( Nth ) ); - return NDIS_STATUS_FAILURE; - } - - if( ! MBB_NTH16_IS_VALID_FIRST_NDP( Nth ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] INVALID NTH first NDP offset=0x%08x", MBB_NTH16_GET_FIRST_NDP_OFFSET( Nth ) ); - return NDIS_STATUS_FAILURE; - } - - if( MbbNtbDetectNdp16Loop( Nth ) != NDIS_STATUS_SUCCESS ) - return NDIS_STATUS_FAILURE; - - for( Ndp = MBB_NTH16_GET_FIRST_NDP( Nth ); - Ndp != NULL; - Ndp = MBB_NDP16_GET_NEXT_NDP( Nth, Ndp ) ) - { - if( MbbNtbValidateNdp16( Nth, Ndp ) != NDIS_STATUS_SUCCESS ) - return NDIS_STATUS_FAILURE; - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNtbParseNdp16( - __in PNCM_NTH16 Nth, - __in PNCM_NDP16 Ndp, - __in MBB_DATAGRAM_CALLBACK Callback, - __in PVOID Context - ) -{ - ULONG Index; - ULONG DatagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp); - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG SessionId = MBB_NDP16_GET_SESSIONID( Ndp ); - - for( Index = 0; - Index < DatagramCount; - Index ++ ) - { - if( MBB_NTB16_IS_END_DATAGRAM( Nth, Ndp, Index ) ) - break; - - if( ! MBB_NTB16_IS_VALID_DATAGRAM( Nth, Ndp, Index ) ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] INVALID datagram at index=%02d for NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - Index, - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - - if( (NdisStatus = Callback( - Nth, - MBB_NDP16_GET_SIGNATURE( Ndp ), - MBB_NDP16_GET_DATAGRAM( Nth, Ndp, Index ), - MBB_NDP16_GET_DATAGRAM_LENGTH(Ndp,Index), - SessionId, - Context - )) != NDIS_STATUS_SUCCESS ) - { - break; - } - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNtbParseNth16( - __in PNCM_NTH16 Nth, - __in ULONG BufferLength, - __in MBB_NDP_CALLBACK Callback, - __in PVOID Context - ) -/*++ - NOTE: - Assumed that NTH has already been validated. - No validations are performed during parsing. ---*/ -{ - PNCM_NDP16 Ndp; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - for( Ndp = MBB_NTH16_GET_FIRST_NDP( Nth ); - Ndp != NULL; - Ndp = MBB_NDP16_GET_NEXT_NDP( Nth, Ndp ) ) - { - if( (NdisStatus = Callback( - Nth, - Ndp, - Context - )) != NDIS_STATUS_SUCCESS ) - { - break; - } - } - return NdisStatus; -} - -// -// NBL -// - -__drv_allocatesMem(mem) -PNET_BUFFER_LIST -MbbNblAlloc( - __in PVOID Nth, - __in PVOID Datagram, - __in ULONG DatagramLength, - __in PMBB_NDIS_RECEIVE_CONTEXT Receive - ) -{ - BOOLEAN Success = FALSE; - NDIS_STATUS NdisStatus; - USHORT NblContextSize = ALIGN( sizeof(MBB_NBL_RECEIVE_CONTEXT), MEMORY_ALLOCATION_ALIGNMENT ); - PNET_BUFFER_LIST NetBufferList = NULL; - PMBB_NBL_RECEIVE_CONTEXT NblContext; - - do - { - if( (NetBufferList = NdisAllocateNetBufferAndNetBufferList( - Receive->RecvQueue->NblPool, - NblContextSize, - 0, - Receive->Mdl, - MBB_NTB_GET_OFFSET( Nth, Datagram ), - DatagramLength - )) == NULL ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0X%04X] FAILED to allocate NetBufferList", MBB_NTB_GET_SEQUENCE( Nth ) ); - break; - } - -#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate a net buffer list from a pool, released when miniport returns buffer list.") - if( NdisAllocateNetBufferListContext( - NetBufferList, - NblContextSize, - 0, - MbbPoolTagNblReceive - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0X%04X] FAILED to allocate NetBufferListContext", MBB_NTB_GET_SEQUENCE( Nth ) ); - break; - } - - TraceVerbose( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x][NBL=0x%p] Added NBL", - MBB_NTB_GET_SEQUENCE( Nth ), - NetBufferList - ); - - ASSERT( NET_BUFFER_CURRENT_MDL( NET_BUFFER_LIST_FIRST_NB( NetBufferList ) ) != NULL ); - - if( DatagramLength >= sizeof(IPV4_HEADER) && - ((IPV4_HEADER*)Datagram)->Version == IPV4_VERSION ) - { - NdisSetNblFlag( NetBufferList, NDIS_NBL_FLAGS_IS_IPV4 ); - NET_BUFFER_LIST_INFO( NetBufferList, NetBufferListFrameType ) = UlongToPtr(RtlUshortByteSwap( MBB_ETHER_TYPE_IPV4 )); - } - else - if( DatagramLength >= sizeof(IPV6_HEADER) && - (((IPV6_HEADER*)Datagram)->VersionClassFlow & IP_VER_MASK) == IPV6_VERSION ) - { - NdisSetNblFlag( NetBufferList, NDIS_NBL_FLAGS_IS_IPV6 ); - NET_BUFFER_LIST_INFO( NetBufferList, NetBufferListFrameType ) = UlongToPtr(RtlUshortByteSwap( MBB_ETHER_TYPE_IPV6 )); - } - else - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0X%04X] INVALID IP Header, DatagramLength=%d Version=%d", - MBB_NTB_GET_SEQUENCE( Nth ), - DatagramLength, - (DatagramLength > 0)? *((PUCHAR)Datagram): 0 - ); - break; - } - NET_BUFFER_LIST_NEXT_NBL( NetBufferList ) = NULL; - - NblContext = (PMBB_NBL_RECEIVE_CONTEXT) NET_BUFFER_LIST_CONTEXT_DATA_START( NetBufferList ); - NblContext->NetBufferList = NetBufferList; - NblContext->Receive = Receive; - - Success = TRUE; - } - while( FALSE ); - - if( Success != TRUE ) - { - if( NetBufferList != NULL ) - { - TraceVerbose( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x][NBL=0x%p] Removed failed NBL", - MBB_NTB_GET_SEQUENCE( Nth ), - NetBufferList - ); - NdisFreeNetBufferList( NetBufferList ); - NetBufferList = NULL; - } - } - return NetBufferList; -} - -VOID -MbbNblCleanup( - __in PNET_BUFFER_LIST NetBufferList - ) -{ - USHORT NblContextSize = ALIGN( sizeof(MBB_NBL_RECEIVE_CONTEXT), MEMORY_ALLOCATION_ALIGNMENT ); - PNET_BUFFER NetBuffer; - PNET_BUFFER NextNetBuffer; - PMBB_NBL_RECEIVE_CONTEXT NblContext; - - NblContext = (PMBB_NBL_RECEIVE_CONTEXT) NET_BUFFER_LIST_CONTEXT_DATA_START( NetBufferList ); - TraceVerbose( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x][NBL=0x%p] Removed NBL", - NblContext->Receive->NtbSequence, - NetBufferList - ); - NblContext->Receive = MBB_BAD_POINTER; - NdisFreeNetBufferListContext( NetBufferList, NblContextSize ); - NdisFreeNetBufferList( NetBufferList ); -} - -// -// Receive Context -// - -NDIS_STATUS -MbbReceiveParseNdp( - __in PVOID Nth, - __in PVOID Ndp, - __in PVOID Context - ) -/*++ - Just a wrapper routine. It stores the - current NDP type which will be used for all - DPs within the NDP. ---*/ -{ - NDIS_STATUS NdisStatus; - PMBB_NDIS_RECEIVE_CONTEXT Receive = (PMBB_NDIS_RECEIVE_CONTEXT)Context; - MBB_DATAGRAM_CALLBACK Callback = MbbReceiveAddNbl; - - // If this is a device service stream NDP, switch the callback - if( MBB_NTB_IS_16BIT( Nth ) ) - { - if( MBB_NDP16_GET_SIGNATURE_TYPE( (PNCM_NDP16)Ndp ) == NCM_NDP16_VENDOR ) - { - // Vendor - Callback = MbbReceiveDssData; - } - } - else - { - if( MBB_NDP32_GET_SIGNATURE_TYPE( (PNCM_NDP32)Ndp ) == NCM_NDP32_VENDOR ) - { - // Vendor - Callback = MbbReceiveDssData; - } - } - - if( (NdisStatus = MbbNtbParseNdp( - Nth, - Ndp, - Callback, - Context - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0X%04X] FAILED to parse NDP at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, Ndp ) - ); - } - return NdisStatus; -} - -NDIS_STATUS -MbbReceiveAddNbl( - __in PVOID Nth, - __in ULONG NdpSignature, - __in PVOID Datagram, - __in ULONG DatagramLength, - __in ULONG SessionId, - __in PVOID Context - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PNET_BUFFER_LIST NetBufferList; - PMBB_NBL_RECEIVE_CONTEXT NblContext; - PMBB_NDIS_RECEIVE_CONTEXT Receive = (PMBB_NDIS_RECEIVE_CONTEXT)Context; - PMBB_NDIS_RECEIVE_NDP_CONTEXT ReceiveNdpContext = &(Receive->ReceiveNdpContext[SessionId]); - - do - { - if( (NetBufferList = MbbNblAlloc( - Nth, - Datagram, - DatagramLength, - Receive - )) == NULL ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv][Seq=0x%04x] FAILED to allocate NetBufferList for Datagram at offset=0x%08x", - MBB_NTB_GET_SEQUENCE( Nth ), - MBB_NTB_GET_OFFSET( Nth, Datagram ) - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - NblContext = (PMBB_NBL_RECEIVE_CONTEXT) NET_BUFFER_LIST_CONTEXT_DATA_START( NetBufferList ); - // - // While building the NBL list we dont need the - // Receive lock since the parsing is serialized - // - InsertTailList( &ReceiveNdpContext->NblQueue, &NblContext->NblQLink ); - - if( ReceiveNdpContext->CurrentNbl != NULL ) - NET_BUFFER_LIST_NEXT_NBL(ReceiveNdpContext->CurrentNbl) = NetBufferList; - else - ReceiveNdpContext->FirstNbl = NetBufferList; - - ReceiveNdpContext->CurrentNbl = NetBufferList; - ReceiveNdpContext->NblCount++; - } - while( FALSE ); - // - // No cleanup required, caller will cleanup the - // Receive context thus freeing all NBLs and NBs. - // - return NdisStatus; -} - -VOID -MbbReceiveRemoveNbl( - __in PMBB_NDIS_RECEIVE_CONTEXT Receive, - __in PNET_BUFFER_LIST NetBufferList - ) -{ - UINT NonEmptyNblQueue = 0; - UINT ReceiveNdpIndex = 0; - PMBB_NBL_RECEIVE_CONTEXT NblContext = (PMBB_NBL_RECEIVE_CONTEXT) NET_BUFFER_LIST_CONTEXT_DATA_START( NetBufferList ); - - NdisAcquireSpinLock( &Receive->Lock ); - RemoveEntryList( &NblContext->NblQLink ); - - for(ReceiveNdpIndex = 0; ReceiveNdpIndex < ARRAYSIZE(Receive->ReceiveNdpContext); ReceiveNdpIndex++) - { - if(!IsListEmpty(&Receive->ReceiveNdpContext[ReceiveNdpIndex].NblQueue)) - { - NonEmptyNblQueue++; - } - } - - NdisReleaseSpinLock( &Receive->Lock ); - - MbbNblCleanup( NetBufferList ); - - if( NonEmptyNblQueue == 0 ) - MbbRecvQDequeueReceive( Receive->RecvQueue, Receive ); -} - -VOID -MbbReceiveCleanupNbls( - __in PMBB_NDIS_RECEIVE_CONTEXT Receive - ) -{ - UINT ReceiveNdpIndex = 0; - - for(ReceiveNdpIndex = 0; ReceiveNdpIndex < ARRAYSIZE(Receive->ReceiveNdpContext); ReceiveNdpIndex++) - { - LIST_ENTRY TempList; - PLIST_ENTRY ListEntry; - PLIST_ENTRY NextEntry; - PNET_BUFFER_LIST NetBufferList; - PMBB_NBL_RECEIVE_CONTEXT NblContext; - PMBB_NDIS_RECEIVE_NDP_CONTEXT ReceiveNdpContext = &(Receive->ReceiveNdpContext[ReceiveNdpIndex]); - - InitializeListHead( &TempList ); - - NdisAcquireSpinLock( &Receive->Lock ); - InsertHeadList( &ReceiveNdpContext->NblQueue, &TempList ); - RemoveEntryList( &ReceiveNdpContext->NblQueue ); - InitializeListHead( &ReceiveNdpContext->NblQueue ); - NdisReleaseSpinLock( &Receive->Lock ); - - for( ListEntry = TempList.Flink; - ListEntry != &TempList; - ListEntry = NextEntry ) - { - NextEntry = ListEntry->Flink; - NblContext = CONTAINING_RECORD( - ListEntry, - MBB_NBL_RECEIVE_CONTEXT, - NblQLink - ); - NetBufferList = NblContext->NetBufferList; - RemoveEntryList( ListEntry ); - MbbNblCleanup( NetBufferList ); - } - } -} - -// -// Receive Queue -// - -PMBB_NDIS_RECEIVE_CONTEXT -MbbRecvQQueueReceive( - __in PMBB_RECEIVE_QUEUE RecvQueue, - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_RECEIVE_CONTEXT BusContext, - __in PMDL Mdl - ) -/*++ - NOTE: - DrainAddRef( ) needs to be called before calling routine. ---*/ -{ - PMBB_NDIS_RECEIVE_CONTEXT Receive = NULL; - UINT i = 0; - - MbbRecvQLock( RecvQueue, FALSE ); - do - { - if( (Receive = ALLOCATE_LOOKASIDE(&RecvQueue->ReceiveLookasideList)) == NULL ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to allocate receive context" ); - break; - } - NdisAllocateSpinLock( &Receive->Lock ); - - NdisZeroMemory(Receive->ReceiveNdpContext,sizeof(Receive->ReceiveNdpContext)); - - for(i=0;i < ARRAYSIZE(Receive->ReceiveNdpContext);i++) - { - InitializeListHead(&Receive->ReceiveNdpContext[i].NblQueue ); - } - - Receive->Mdl = Mdl; - Receive->RecvQueue = RecvQueue; - Receive->AdapterContext = Adapter; - Receive->BusHandle = Adapter->BusHandle; - Receive->BusContext = BusContext; - Receive->ReceiveLookasideList = &RecvQueue->ReceiveLookasideList; - - InsertTailList( - &RecvQueue->ReceivedQueue, - &Receive->ReceivedQLink - ); - } - while( FALSE ); - MbbRecvQUnlock( RecvQueue, FALSE ); - - return Receive; -} - -VOID -MbbRecvQDequeueReceive( - __in PMBB_RECEIVE_QUEUE RecvQueue, - __in PMBB_NDIS_RECEIVE_CONTEXT Receive - ) -{ - MbbBusReturnReceiveBuffer( - Receive->BusHandle, - Receive->BusContext, - Receive->Mdl - ); - - MbbRecvQLock( RecvQueue, FALSE ); - RemoveEntryList( &Receive->ReceivedQLink ); - if( IsListEmpty( &RecvQueue->ReceivedQueue ) ) - KeSetEvent( &RecvQueue->QueueEmptyEvent, 0, FALSE ); - MbbRecvQUnlock( RecvQueue, FALSE ); - - Receive->RecvQueue = MBB_BAD_POINTER; - NdisFreeSpinLock( &Receive->Lock ); - FREE_LOOKASIDE( Receive, Receive->ReceiveLookasideList ); - - DrainRelease( &(RecvQueue->QueueDrainObject) ); -} - -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( SpinLock, RecvQueue->Lock ) -__drv_when( DispatchLevel == FALSE, __drv_raisesIRQL(DISPATCH_LEVEL)) -FORCEINLINE -VOID -MbbRecvQLock( - __in __drv_at( RecvQueue->Lock, __drv_acquiresResource( Spinlock ) ) - PMBB_RECEIVE_QUEUE RecvQueue, - __in BOOLEAN DispatchLevel - ) -{ - if( DispatchLevel == TRUE ) - { - NdisDprAcquireSpinLock( &RecvQueue->Lock ); - } - else - { - NdisAcquireSpinLock( &RecvQueue->Lock ); - } -} - -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( SpinLock, RecvQueue->Lock ) -FORCEINLINE -VOID -MbbRecvQUnlock( - __in __drv_at( RecvQueue->Lock, __drv_releasesResource( Spinlock ) ) - PMBB_RECEIVE_QUEUE RecvQueue, - __in BOOLEAN DispatchLevel - ) -{ - if( DispatchLevel == TRUE ) - { - NdisDprReleaseSpinLock( &RecvQueue->Lock ); - } - else - { - NdisReleaseSpinLock( &RecvQueue->Lock ); - } -} - -NDIS_STATUS -MbbRecvQInitialize( - __in PMBB_RECEIVE_QUEUE RecvQueue, - __in MBB_DRAIN_COMPLETE DrainCompleteCallback, - __in PVOID DrainCompleteCallbackContext, - __in NDIS_HANDLE MiniportHandle - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - USHORT NblContextSize = ALIGN( sizeof(MBB_NBL_RECEIVE_CONTEXT), MEMORY_ALLOCATION_ALIGNMENT ); - NET_BUFFER_POOL_PARAMETERS NbPoolParameters; - NET_BUFFER_LIST_POOL_PARAMETERS NblPoolParameters; - - do - { - InitializeListHead( &RecvQueue->ReceivedQueue ); - KeInitializeEvent( - &RecvQueue->QueueEmptyEvent, - NotificationEvent, - TRUE - ); - NdisAllocateSpinLock( &RecvQueue->Lock ); - - RecvQueue->NblPool = NULL; - RecvQueue->LookasideList = FALSE; - - NdisInitializeNPagedLookasideList( - &RecvQueue->ReceiveLookasideList, - NULL, - NULL, - 0, - sizeof(MBB_NDIS_RECEIVE_CONTEXT), - MbbPoolTagMdlReceive, - 0 - ); - RecvQueue->LookasideList = TRUE; - - NblPoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NblPoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; - NblPoolParameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; - NblPoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; - NblPoolParameters.fAllocateNetBuffer = TRUE; - NblPoolParameters.ContextSize = NblContextSize; - NblPoolParameters.PoolTag = MbbPoolTagNblPool; - NblPoolParameters.DataSize = 0; - - if( (RecvQueue->NblPool = NdisAllocateNetBufferListPool( - MiniportHandle, - &NblPoolParameters - )) == NULL ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to allocate NetBufferListPool" ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - InitDrainObject( - &RecvQueue->QueueDrainObject, - DrainCompleteCallback, - DrainCompleteCallbackContext - ); - TraceInfo( WMBCLASS_RECEIVE, "[Recv] Initialization complete" ); - } - while( FALSE ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - MbbRecvQCleanup( RecvQueue ); - } - return NdisStatus; -} - -VOID -MbbRecvQCleanup( - __in PMBB_RECEIVE_QUEUE RecvQueue - ) -/*++ - Description - Frees all resources allocated for the queue. - This is called from MiniportHalt so the queue should - already be empty. This routine does not call cancel - or wait for pending requests to complete since there - should not be any. ---*/ -{ - ASSERT( IsListEmpty( &RecvQueue->ReceivedQueue ) == TRUE ); - - if( RecvQueue->NblPool != NULL ) - { - NdisFreeNetBufferListPool( RecvQueue->NblPool ); - RecvQueue->NblPool = NULL; - } - if( RecvQueue->LookasideList == TRUE ) - { - NdisDeleteNPagedLookasideList( &RecvQueue->ReceiveLookasideList ); - RecvQueue->LookasideList = FALSE; - } - NdisFreeSpinLock( &RecvQueue->Lock ); - - TraceInfo( WMBCLASS_RECEIVE, "[Recv] Cleanup complete" ); -} - -VOID -MbbRecvQCancel( - __in PMBB_RECEIVE_QUEUE RecvQueue, - __in NDIS_STATUS Status, - __in BOOLEAN WaitForCompletion - ) -{ - StartDrain( &RecvQueue->QueueDrainObject ); - // - // Nothing to cancel - // - if( WaitForCompletion ) - { - TraceInfo( WMBCLASS_RECEIVE, "[Recv] Cancel, waiting for request to complete..." ); - - KeWaitForSingleObject( - &RecvQueue->QueueEmptyEvent, - Executive, - KernelMode, - FALSE, - NULL - ); - } - TraceInfo( WMBCLASS_RECEIVE, "[Recv] Cancel complete" ); -} - - - -NDIS_STATUS -MbbReceiveDssData( - __in PVOID Nth, - __in ULONG NdpSignature, - __in PVOID Datagram, - __in ULONG DatagramLength, - __in ULONG SessionIdentifier, - __in PVOID Context - ) -{ - PMBB_NDIS_RECEIVE_CONTEXT Receive = (PMBB_NDIS_RECEIVE_CONTEXT)Context; - ULONG SessionId; - - UNREFERENCED_PARAMETER(SessionIdentifier); - - // Pass this to the Dss indication processing code - SessionId = NdpSignature >> NCM_NDP_SESSION_SHIFT; - - // Forward to the dss receive handler - MbbNdisDeviceServiceSessionReceive( - Receive->AdapterContext, - SessionId, - Datagram, - DatagramLength - ); - - return NDIS_STATUS_SUCCESS; -} - -// -// NDIS / Bus Callbacks -// - -VOID -MbbNdisReceiveCallback( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in MBB_RECEIVE_CONTEXT ReceiveContext, - __in PMDL Mdl - ) -{ - PUCHAR DataBuffer; - ULONG DataLength; - PVOID Nth; - BOOLEAN Referenced = FALSE; - BOOLEAN ReturnBuffer = TRUE; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; - PMBB_NDIS_RECEIVE_CONTEXT Receive = NULL; - PMBB_NDIS_RECEIVE_NDP_CONTEXT ReceiveNdpContext = NULL; - int ReceiveNdpIndex = 0; - int MaxReceiveNdpIndex = -1; - - do - { - if( ! (Referenced = DrainAddRef( &(Adapter->ReceiveQueue.QueueDrainObject) )) ) - { - break; - } - - if( (DataBuffer = MmGetSystemAddressForMdlSafe( Mdl, NormalPagePriority | MdlMappingNoExecute )) == NULL ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to get system address for Mdl=0x%p", Mdl ); - break; - } - DataLength = MmGetMdlByteCount( Mdl ); - - Nth = DataBuffer; - - if( MbbNtbValidate( - Nth, - DataLength, - Adapter->BusParams.CurrentMode32Bit - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to validate NTB" ); - - - MbbWriteEvent( - &RECEIVED_BAD_NTB, - NULL, - NULL, - 2 - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &DataLength, - sizeof(DataLength) - ); - - - - { - ULONG i; - ULONG j; - - PUCHAR Buffer=(PUCHAR)Nth; - - for (i=0; i= DataLength) - { - // - // past the end, just put spaces - // - NumString[j*3] =' '; - NumString[j*3+1]=' '; - NumString[j*3+2]=' '; - - } else - { - Value=Buffer[i+j]; - - NumString[j*3]= TranslateTable[ Value >> 4]; - NumString[j*3+1]= TranslateTable[ Value & 0xf]; - NumString[j*3+2]=' '; - - if ((Buffer[i+j] >= 32) && (Buffer[i+j] < 128)) - { - AsciiBuffer[j]=Value; - } - else - { - AsciiBuffer[j]='.'; - } - } - } - - TraceError( WMBCLASS_RECEIVE, "%08lx - %s %s", i, NumString, AsciiBuffer); - } - - } - - - - - break; - } - - if( (Receive = MbbRecvQQueueReceive( - &Adapter->ReceiveQueue, - Adapter, - ReceiveContext, - Mdl - )) == NULL ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to allocate receive context" ); - break; - } - Receive->NtbSequence = MBB_NTB_GET_SEQUENCE( Nth ); - - if( MbbNtbParse( - Nth, - DataLength, - MbbReceiveParseNdp, - Receive - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] FAILED to parse NTB" ); - break; - } - - // Preprocessing here to ensure that Receive Context is not cleaned up when - // MbbNdisMiniportReturnNetBufferLists is called for the last NDP NBL chain processed - - for(ReceiveNdpIndex = 0; ReceiveNdpIndex < ARRAYSIZE(Receive->ReceiveNdpContext); ReceiveNdpIndex++) - { - ReceiveNdpContext = &(Receive->ReceiveNdpContext[ReceiveNdpIndex]); - - if(!IsListEmpty( &ReceiveNdpContext->NblQueue ) ) - { - MaxReceiveNdpIndex = ReceiveNdpIndex; - } - } - - for(ReceiveNdpIndex = 0; ReceiveNdpIndex <= MaxReceiveNdpIndex && ReceiveNdpIndex < ARRAYSIZE(Receive->ReceiveNdpContext); ReceiveNdpIndex++) - { - ReceiveNdpContext = &(Receive->ReceiveNdpContext[ReceiveNdpIndex]); - - // If all the Ndps in this receive are Dss stuff, we - // wont have any NBLs to indicate - if( !IsListEmpty( &ReceiveNdpContext->NblQueue ) ) - { - ASSERT(ReceiveNdpContext->SessionIdPortNumberEntry.InUse); - - ReturnBuffer = FALSE; - - { - PNET_BUFFER_LIST CurrentNetBufferList; - PNET_BUFFER_LIST NextNetBufferList; - PNET_BUFFER NetBuffer; - - for( CurrentNetBufferList = ReceiveNdpContext->FirstNbl; - CurrentNetBufferList != NULL; - CurrentNetBufferList = NextNetBufferList ) - { - NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL( CurrentNetBufferList ); - - for( NetBuffer = NET_BUFFER_LIST_FIRST_NB( CurrentNetBufferList ); - NetBuffer != NULL; - NetBuffer = NET_BUFFER_NEXT_NB( NetBuffer ) ) - { - InterlockedAdd64(&Adapter->Stats.ifHCInOctets, NET_BUFFER_DATA_LENGTH(NetBuffer)); - InterlockedIncrement64(&Adapter->GenRcvFramesOk); - InterlockedIncrement64(&Adapter->Stats.ifHCInUcastPkts); - } - } - } - -#if DBG - MbbTestValidateNblChain(ReceiveNdpContext->FirstNbl ); -#endif - NdisMIndicateReceiveNetBufferLists( - Adapter->MiniportAdapterHandle, - ReceiveNdpContext->FirstNbl, - ReceiveNdpContext->SessionIdPortNumberEntry.PortNumber, - ReceiveNdpContext->NblCount, - 0 - ); - } - } - } - while( FALSE ); - - if( ReturnBuffer == TRUE ) - { - TraceError( WMBCLASS_RECEIVE, "[Recv] DROPPING received Mdl=0x%p", Mdl ); - InterlockedIncrement64( &Adapter->Stats.ifInDiscards ); - - if( Receive != NULL ) - { - MbbReceiveCleanupNbls( Receive ); - - MbbRecvQDequeueReceive( - &Adapter->ReceiveQueue, - Receive - ); - // - // Reference dropped by Dequeue - // - Referenced = FALSE; - } - else - { - MbbBusReturnReceiveBuffer( - Adapter->BusHandle, - ReceiveContext, - Mdl - ); - } - if( Referenced ) - DrainRelease( &(Adapter->ReceiveQueue.QueueDrainObject) ); - } -} - -VOID -MbbNdisMiniportReturnNetBufferLists( - __in NDIS_HANDLE MiniportAdapterContext, - __in PNET_BUFFER_LIST NetBufferLists, - __in ULONG ReturnFlags - ) -{ - PNET_BUFFER_LIST NetBufferList; - PNET_BUFFER_LIST NextNetBufferList; - PMBB_NBL_RECEIVE_CONTEXT NblContext; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - - if (MbbBusIsFastIO(Adapter->BusHandle)) - { - MbbBusReturnNetBufferLists(Adapter->BusHandle, NetBufferLists, ReturnFlags); - } - else - { - for (NetBufferList = NetBufferLists; - NetBufferList != NULL; - NetBufferList = NextNetBufferList) - { - NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(NetBufferList); - NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL; - NblContext = (PMBB_NBL_RECEIVE_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); - MbbReceiveRemoveNbl(NblContext->Receive, NetBufferList); - } - } -} - -#if DBG -VOID -MbbTestValidateNblChain( - __in PNET_BUFFER_LIST NblChain - ) -{ - PNET_BUFFER NetBuffer; - PNET_BUFFER_LIST NetBufferList; - - for( NetBufferList = NblChain; - NetBufferList != NULL; - NetBufferList = NET_BUFFER_LIST_NEXT_NBL( NetBufferList ) ) - { - NetBuffer = NET_BUFFER_LIST_FIRST_NB( NetBufferList ); - ASSERT( NET_BUFFER_CURRENT_MDL( NetBuffer ) != NULL ); - } -} -#endif diff --git a/network/wwan/cxwmbclass/receive.h b/network/wwan/cxwmbclass/receive.h deleted file mode 100644 index e686f9f88..000000000 --- a/network/wwan/cxwmbclass/receive.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -NDIS_STATUS -MbbRecvQInitialize( - __in PMBB_RECEIVE_QUEUE RecvQueue, - __in MBB_DRAIN_COMPLETE DrainCompleteCallback, - __in PVOID DrainCompleteContext, - __in NDIS_HANDLE MiniportHandle - ); - -VOID -MbbRecvQCleanup( - __in PMBB_RECEIVE_QUEUE RecvQueue - ); - -VOID -MbbRecvQCancel( - __in PMBB_RECEIVE_QUEUE RecvQueue, - __in NDIS_STATUS Status, - __in BOOLEAN WaitForCompletion - ); diff --git a/network/wwan/cxwmbclass/request.c b/network/wwan/cxwmbclass/request.c deleted file mode 100644 index 5fd6a64ea..000000000 --- a/network/wwan/cxwmbclass/request.c +++ /dev/null @@ -1,19728 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -//////////////////////////////////////////////////////////////////////////////// -// -// INCLUDES -// -//////////////////////////////////////////////////////////////////////////////// -#include "precomp.h" -#include "Request.tmh" -#include "WMBClassTelemetry.h" - -#pragma prefast(push) -// Disables oacr check for 26014(INCORRECT_VALIDATION) because we use many MBB struct carrying 1-element array for data buffer -// e.g. -// struct MBB_X { -// MBB_STRING str; // empty string -// UCHAR DataBuffer[ 1 ]; -// } -// The real size of payload could be "sizeof(MBB_X) - 1." -// To avoid noise, disable this specific validation in OACR as the implementation already validates the payload -#pragma prefast(disable: __WARNING_INCORRECT_VALIDATION) // allowed off-by-1 struct - -C_ASSERT(MbbCellularClassMaximum == 3 ); - -//////////////////////////////////////////////////////////////////////////////// -// -// DECLARATIONS -// -//////////////////////////////////////////////////////////////////////////////// -NDIS_STATUS -MbbNdisProcessSerializedOidRequest( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ); - -VOID -MbbNdisIndicateStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -// -// Get handlers -// - -NDIS_STATUS -MbbNdisGetVendorDriverVersion( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetVendorId( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetVendorDescription( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetReceiveBlockSize( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetReceiveBufferSpace( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetTransmitBlockSize( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetTransmitBufferSpace( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetMaximumTotalSize( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetInterruptModeration( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetCurrentLookahead( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetFramesReceived( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetFramesTransmitted( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetMediaSupported( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetDriverCaps( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetStatistics( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -// MAC -NDIS_STATUS -MbbNdisCreateMac( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetMbimVersion( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - - -#define MbbNdisGetDeviceCaps MbbUtilQueryAttribute - -#define MbbNdisGetReadyInfo MbbUtilQueryAttribute - -#define MbbNdisGetEmergencyMode MbbUtilQueryAttribute - -#define MbbNdisGetRadioState MbbUtilQueryAttribute - -#define MbbNdisGetPinInfo MbbUtilQueryAttribute - -#define MbbNdisGetPinList MbbUtilQueryAttribute - -#define MbbNdisGetHomeProvider MbbUtilQueryAttribute - -#define MbbNdisGetPreferredProviders MbbUtilQueryAttribute - -#define MbbNdisGetRegisterState MbbUtilQueryAttribute - -#define MbbNdisGetPacketService MbbUtilQueryAttribute - -#define MbbNdisGetSignalState MbbUtilQueryAttribute - -#define MbbNdisGetProvisionedContexts MbbUtilQueryAttribute - -NDIS_STATUS -MbbNdisGetProvisionedContextsV2( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - -#define MbbNdisGetMulticarrierProviders MbbUtilQueryAttribute - -#define MbbNdisGetSarConfig MbbUtilQueryAttribute - -#define MbbNdisGetSarTransmissionStatus MbbUtilQueryAttribute - -#define MbbNdisGetLteAttachConfig MbbUtilQueryAttribute - -#define MbbNdisGetLteAttachStatus MbbUtilQueryAttribute - -NDIS_STATUS -MbbNdisGetPcoStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - - -NDIS_STATUS -MbbNdisQueryPower( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -// SMS - -NDIS_STATUS -MbbNdisSmsRead( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - - -NDIS_STATUS -MbbNdisGetVisibleProviders( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetConnectState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbIpGetConfiguration( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - - -#define MbbNdisSmsGetConfiguration MbbUtilQueryAttribute - -#define MbbNdisSmsGetStatus MbbUtilQueryAttribute - -// Device Service - -NDIS_STATUS -MbbNdisEnumerateDeviceServices( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetDeviceServiceCommand( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisEnumerateDeviceServiceCommands( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -// EAP Authentication - -NDIS_STATUS -MbbNdisGetAuthChallenge( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -// Multi-carrier - -NDIS_STATUS -MbbNdisGetMultiCarrierDsCidList( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -// UICC -#define MbbNdisGetUiccAppList MbbUtilQueryAttribute - -NDIS_STATUS -MbbNdisGetUiccFileStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisUiccReadBinary( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisUiccReadRecord( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbNdisGetPinInfoEx( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - -// Device State and Configuration for MBIM 2.0 - -NDIS_STATUS -MbbNdisGetSysCapsInfo( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - -NDIS_STATUS -MbbNdisGetDeviceCapsEx( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - -#define MbbNdisGetSysSlotMappings MbbUtilQueryAttribute - -NDIS_STATUS -MbbNdisGetSlotInfoStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - -#define MbbNdisGetDeviceBindings MbbUtilQueryAttribute - -// Registration, Signal Strength, and NITZ for MBIM 2.0 - -#define MbbNdisGetRegisterStateEx MbbUtilQueryAttribute - -#define MbbNdisGetImsVoiceState MbbUtilQueryAttribute - -#define MbbNdisGetSignalStateEx MbbUtilQueryAttribute - -#define MbbNdisGetLocationState MbbUtilQueryAttribute - -#define MbbNdisGetNitzInfo MbbUtilQueryAttribute - -// Low-Level UICC Access - -NDIS_STATUS -MbbNdisGetAtr( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - -#define MbbNdisGetUiccTerminalCapability MbbUtilQueryAttribute - -NDIS_STATUS -MbbNdisGetUiccReset( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize, - _Out_writes_bytes_to_opt_(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - _Inout_ PULONG OutBufferSize -); - -// Base station information -NDIS_STATUS -MbbNdisGetBaseStationsInfo( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -); - - -// -// Set handlers -// - -NDIS_STATUS -MbbNdisSetInterruptModeration( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetCurrentLookahead( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetRadioState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetPinInfo( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetPinInfoEx2( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetPreferredProviders( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetRegisterState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetPacketService( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetPower( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetPmParameters( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetAddWolPattern( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetRemoveAddWolPattern( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - - -NDIS_STATUS -MbbNdisSetSignalState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - - -NDIS_STATUS -MbbNdisSetCurrentLookahead( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetConnectState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetProvisionedContexts( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetProvisionedContextsV2( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetServiceActivation( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetHomeProvider( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - - -NDIS_STATUS -MbbNdisSetMulticarrierProviders( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -// SMS - -NDIS_STATUS -MbbNdisSmsSetConfiguration( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSmsSend( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSmsDelete( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -// USSD - -NDIS_STATUS -MbbNdisSetUSSD( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - -); - -// DEVICE SERVICE - -NDIS_STATUS -MbbNdisSetDeviceServiceCommand( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSubscribeDeviceServiceEvents( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetDeviceServiceSession( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisDssWrite( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -// MAC ADDRESS - -NDIS_STATUS -MbbNdisDeleteMac( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -// UICC - -NDIS_STATUS -MbbNdisUiccUpdateBinary( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisUiccUpdateRecord( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - - -// Device State and Configuration for MBIM 2.0 - -NDIS_STATUS -MbbNdisSetSysSlotMappings( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -); - -NDIS_STATUS -MbbNdisSetDeviceBindings( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -); - -// Registration, Signal Strength, and NITZ for MBIM 2.0 - -NDIS_STATUS -MbbNdisSetRegisterStateEx( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -); - -NDIS_STATUS -MbbNdisSetImsVoiceState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -); - -NDIS_STATUS -MbbNdisSetSignalStateEx( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -); - -NDIS_STATUS -MbbNdisSetLocationState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -); - -// Vendor Specific - -NDIS_STATUS -MbbNdisSetVendorSpecific( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -// Network Idle Hint -NDIS_STATUS -MbbNdisSetNetworkIdleHint( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -// System Preshutdown -NDIS_STATUS -MbbNdisSetPreshutdown( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -// Low-Level UICC Access - -NDIS_STATUS -MbbNdisSetUiccOpenChannel( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetUiccCloseChannel( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetUiccApdu( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetUiccTerminalCapability( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetUiccReset( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetSarConfig( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetSarTransmissionStatus( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetLteAttachContexts( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetNetworkBlacklist( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSetDeviceReset( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize - ); - -// -// Status handlers -// - -NDIS_STATUS -MbbNdisDeviceCapsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisReadyInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisEmergencyModeStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisRadioStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisPinInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisPinListStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisHomeProviderStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisPreferredProviderStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisVisibleProviderStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisRegisterStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -VOID -MbbNdisIndicatePacketService( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); - - -NDIS_STATUS -MbbNdisPacketServiceStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSignalStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisConnectStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisProvisionedContextStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisProvisionedContextV2StatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisServiceActivationStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisMulticarrierProviderStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -// SMS - -NDIS_STATUS -MbbNdisSmsConfigurationStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSmsReadStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSmsSendStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSmsDeleteStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSmsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisGetStatsHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -// DEVICE SERVICE - -NDIS_STATUS -MbbNdisDeviceServiceListStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisDeviceServiceStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSubscribeDeviceServiceEventsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - - -// USSD - -NDIS_STATUS -MbbNdisUSSDStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - - -// EAP Authentication - -NDIS_STATUS -MbbNdisAuthAKAStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisAuthAKAPStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - - -NDIS_STATUS -MbbNdisAuthSIMStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - - -NDIS_STATUS -MbbNdisDssOpenStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - - -NDIS_STATUS -MbbNdisDssCloseStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisDssWriteCompleteStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -// Multi-carrier - -NDIS_STATUS -MbbNdisMultiCarrierDsCidListStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -// UICC - -NDIS_STATUS -MbbNdisUiccAppListStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisUiccFileStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisUiccAccessStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -// Device State and Configuration for MBIM 2.0 - -NDIS_STATUS -MbbNdisSysCapsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisDeviceCapsExStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisSysSlotMappingsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisSlotInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisDeviceBindingsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -// Registration, Signal Strength, and NITZ for MBIM 2.0 - -NDIS_STATUS -MbbNdisRegisterStateExStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisImsVoiceStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisSignalStateExStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisLocationStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisNitzStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -); - -// Vendor Specific - -NDIS_STATUS -MbbNdisVendorSpecificStatusHandler( -__in PMBB_REQUEST_CONTEXT Request, -__in NDIS_STATUS NdisStatus, -__in MBB_STATUS MbbStatus, -__in_bcount_opt(InBufferSize) PUCHAR InBuffer, -__in ULONG InBufferSize -); - -// System Preshutdown - -NDIS_STATUS -MbbNdisPreshutdownHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -// Low-Level UICC Access - -NDIS_STATUS -MbbNdisAtrInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisUiccOpenChannelInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisUiccCloseChannelInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisUiccApduInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisUiccTerminalCapabilityInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisUiccResetInfoStatusHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSarConfigHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisSarTransmissionStatusHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisLteAttachConfigHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisLteAttachStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisNetworkBlacklistHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -NDIS_STATUS -MbbNdisPcoStatusHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize -); - -NDIS_STATUS -MbbNdisDeviceResetStatusHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize - ); - -// Base station information - -NDIS_STATUS -MbbNdisBaseStationsInfoHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize -); - - -// -// Completion Handlers -// - -VOID -MbbNdisReadyInfoCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); - -VOID -MbbNdisPacketServiceStateCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); - -VOID -MbbNdisMultiCarrierDsCidListCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); -VOID -MbbNdisCreateMacCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); - -VOID -MbbNdisDeleteMacCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); - - -//////////////////////////////////////////////////////////////////////////////// -// -// GLOBALS -// -//////////////////////////////////////////////////////////////////////////////// -#define OID_INVALID (-1) - -#define MBIM_CID_VENDORSPECIFIC 1 - - -MBB_OID_HANDLER_ENTRY MbbSpecialOidHandlerTable[] = -{ - // - // Authentication Challenges - AKA, AKAP, and SIM - // - { - OID_WWAN_AUTH_CHALLENGE, // Oid - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_AUTH_CHALLENGE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_AUTH_CHALLENGE), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetAuthChallenge, // Query routine - sizeof(NDIS_WWAN_AUTH_CHALLENGE), // MinQueryInBufferSize - sizeof(NDIS_WWAN_AUTH_RESPONSE), // MinQueryOutBufferSize - - { MBB_UUID_AUTH_CONSTANT, MBB_AUTH_CID_AKA}, // ResponseCommand - sizeof(MBB_USSD), // ResponseBufferLength - MbbNdisAuthAKAStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_AUTH_CHALLENGE, // Oid - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_AUTH_CHALLENGE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_AUTH_CHALLENGE), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetAuthChallenge, // Query routine - sizeof(NDIS_WWAN_AUTH_CHALLENGE), // MinQueryInBufferSize - sizeof(NDIS_WWAN_AUTH_RESPONSE), // MinQueryOutBufferSize - - { MBB_UUID_AUTH_CONSTANT, MBB_AUTH_CID_AKAP}, // ResponseCommand - sizeof(MBB_USSD), // ResponseBufferLength - MbbNdisAuthAKAPStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_AUTH_CHALLENGE, // Oid - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_AUTH_CHALLENGE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_AUTH_CHALLENGE), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetAuthChallenge, // Query routine - sizeof(NDIS_WWAN_AUTH_CHALLENGE), // MinQueryInBufferSize - sizeof(NDIS_WWAN_AUTH_RESPONSE), // MinQueryOutBufferSize - - { MBB_UUID_AUTH_CONSTANT, MBB_AUTH_CID_SIM}, // ResponseCommand - sizeof(MBB_USSD), // ResponseBufferLength - MbbNdisAuthSIMStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // Device Service Sessions - Open & Close - // - { - OID_WWAN_DEVICE_SERVICE_SESSION, // Oid - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_REVISION_1, // NdisObjectHeaderRevision - SIZEOF_NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_1, // NdisObjectHeaderSize - - MbbNdisSetDeviceServiceSession, // Set routine - SIZEOF_NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_1, // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_DSS_CONSTANT, MBB_DSS_CID_CONNECT}, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisDssOpenStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, -#if 0 - { - OID_WWAN_DEVICE_SERVICE_SESSION, // Oid - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_REVISION_1, // NdisObjectHeaderRevision - SIZEOF_NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_1, // NdisObjectHeaderSize - - MbbNdisSetDeviceServiceSession, // Set routine - SIZEOF_NDIS_WWAN_SET_DEVICE_SERVICE_SESSION_1, // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_DSS_CONSTANT, MBB_DSS_CID_CONNECT}, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisDssCloseStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, -#endif - {0} // terminator -}; - -MBB_OID_HANDLER_ENTRY MbbOidHandlerTable[] = -{ - { - OID_GEN_MEDIA_SUPPORTED, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetMediaSupported, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_RCV_OK, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetFramesReceived, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONGLONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_XMIT_OK, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetFramesTransmitted, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONGLONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_STATISTICS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetStatistics, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_STATISTICS_INFO), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_STATISTICS }, // ResponseCommand - sizeof(MBB_PACKET_STATISTICS), // ResponseBufferLength - NULL, //MbbNdisGetStatsHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_INTERRUPT_MODERATION, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - MbbNdisSetInterruptModeration, // Set routine - sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS), // MinSetInBufferSize - - MbbNdisGetInterruptModeration, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_PNP_QUERY_POWER, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisQueryPower, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_PNP_SET_POWER, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - MbbNdisSetPower, // Set routine - sizeof(ULONG), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_INVALID, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_NETWORK_IDLE_HINT }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_INVALID, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_HOSTSHUTDOWN_CONSTANT, MBB_HOSTSHUTDOWN_CID_ONE }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_INVALID, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_FILTERS }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_PM_PARAMETERS, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - FALSE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - MbbNdisSetPmParameters, // Set routine - sizeof(NDIS_PM_PARAMETERS), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_FILTERS }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_PM_ADD_WOL_PATTERN, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - MbbNdisSetAddWolPattern, // Set routine - sizeof(NDIS_PM_WOL_PATTERN), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_PM_REMOVE_WOL_PATTERN, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - MbbNdisSetRemoveAddWolPattern, // Set routine - sizeof(ULONG), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_VENDOR_DRIVER_VERSION, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetVendorDriverVersion, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_VENDOR_ID, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetVendorId, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_VENDOR_DESCRIPTION, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetVendorDescription, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_CURRENT_LOOKAHEAD, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - MbbNdisSetCurrentLookahead, // Set routine - sizeof(ULONG), // MinSetInBufferSize - - MbbNdisGetCurrentLookahead, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_RECEIVE_BLOCK_SIZE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - sizeof(ULONG), // MinSetInBufferSize - - MbbNdisGetReceiveBlockSize, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_RECEIVE_BUFFER_SPACE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - sizeof(ULONG), // MinSetInBufferSize - - MbbNdisGetReceiveBufferSpace, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_TRANSMIT_BLOCK_SIZE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - sizeof(ULONG), // MinSetInBufferSize - - MbbNdisGetTransmitBlockSize, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_TRANSMIT_BUFFER_SPACE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - sizeof(ULONG), // MinSetInBufferSize - - MbbNdisGetTransmitBufferSpace, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_GEN_MAXIMUM_TOTAL_SIZE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - sizeof(ULONG), // MinSetInBufferSize - - MbbNdisGetMaximumTotalSize, // Query routine - 0, // MinQueryInBufferSize - sizeof(ULONG), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - // - // BASIC CONNECT - // - { - OID_WWAN_DRIVER_CAPS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetDriverCaps, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_DRIVER_CAPS), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_DEVICE_CAPS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetDeviceCaps, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_DEVICE_CAPS), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_DEVICE_CAPS }, // ResponseCommand - sizeof(MBB_DEVICE_CAPS), // ResponseBufferLength - MbbNdisDeviceCapsStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_READY_INFO, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetReadyInfo, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_READY_INFO), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_SUBSCRIBER_READY_INFO }, // ResponseCommand - sizeof(MBB_SUBSCRIBER_READY_INFO), // ResponseBufferLength - MbbNdisReadyInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_INVALID, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetEmergencyMode, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_EMERGENCY_MODE }, // ResponseCommand - sizeof(MBB_EMERGENCY_MODE), // ResponseBufferLength - MbbNdisEmergencyModeStatusHandler, // ResponseHandler - MbbNdisReadyInfoCompletionHandler // CompletionHandler - }, - { - OID_WWAN_RADIO_STATE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_RADIO_STATE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_RADIO_STATE), // NdisObjectHeaderSize - - MbbNdisSetRadioState, // Set routine - sizeof(NDIS_WWAN_SET_RADIO_STATE), // MinSetInBufferSize - - MbbNdisGetRadioState, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_RADIO_STATE), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_RADIO_STATE }, // ResponseCommand - sizeof(MBB_QUERY_RADIO_STATE), // ResponseBufferLength - MbbNdisRadioStateStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - - { - OID_WWAN_PIN_EX, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_PIN_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_PIN), // NdisObjectHeaderSize - - MbbNdisSetPinInfo, // Set routine - sizeof(NDIS_WWAN_SET_PIN), // MinSetInBufferSize - - MbbNdisGetPinInfo, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_PIN_INFO), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PIN_INFO }, // ResponseCommand - sizeof(MBB_PIN_INFO), // ResponseBufferLength - MbbNdisPinInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_PIN_LIST, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetPinList, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_PIN_LIST), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PIN_LIST }, // ResponseCommand - sizeof(MBB_PIN_LIST), // ResponseBufferLength - MbbNdisPinListStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_HOME_PROVIDER, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_HOME_PROVIDER_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_HOME_PROVIDER), // NdisObjectHeaderSize - - MbbNdisSetHomeProvider, // Set routine - sizeof(NDIS_WWAN_SET_HOME_PROVIDER), // MinSetInBufferSize - - MbbNdisGetHomeProvider, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_HOME_PROVIDER2), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_HOME_PROVIDER },// ResponseCommand - sizeof(MBB_PROVIDER), // ResponseBufferLength - MbbNdisHomeProviderStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_PREFERRED_PROVIDERS, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_PREFERRED_PROVIDERS_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_PREFERRED_PROVIDERS), // NdisObjectHeaderSize - - MbbNdisSetPreferredProviders, // Set routine - sizeof(NDIS_WWAN_SET_PREFERRED_PROVIDERS), // MinSetInBufferSize - - MbbNdisGetPreferredProviders, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_PREFERRED_PROVIDERS), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PREFERRED_PROVIDERS }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisPreferredProviderStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_VISIBLE_PROVIDERS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetVisibleProviders, // Query routine - sizeof(NDIS_WWAN_GET_VISIBLE_PROVIDERS), // MinQueryInBufferSize - sizeof(NDIS_WWAN_VISIBLE_PROVIDERS), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_VISIBLE_PROVIDERS }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisVisibleProviderStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_REGISTER_STATE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_REGISTER_STATE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_REGISTER_STATE), // NdisObjectHeaderSize - - MbbNdisSetRegisterState, // Set routine - sizeof(NDIS_WWAN_SET_REGISTER_STATE), // MinSetInBufferSize - - MbbNdisGetRegisterState, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_REGISTRATION_STATE), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_REGISTER_STATE }, // ResponseCommand - sizeof(MBB_REGISTRATION_STATE), // ResponseBufferLength - MbbNdisRegisterStateStatusHandler, // ResponseHandler - MbbNdisPacketServiceStateCompletionHandler // CompletionHandler, intentional PacketServiceHandler - }, - { - OID_WWAN_PACKET_SERVICE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_PACKET_SERVICE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_PACKET_SERVICE), // NdisObjectHeaderSize - - MbbNdisSetPacketService, // Set routine - sizeof(NDIS_WWAN_SET_PACKET_SERVICE), // MinSetInBufferSize - - MbbNdisGetPacketService, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_PACKET_SERVICE_STATE), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PACKET_SERVICE }, // ResponseCommand - sizeof(MBB_PACKET_SERVICE), // ResponseBufferLength - MbbNdisPacketServiceStatusHandler, // ResponseHandler - MbbNdisPacketServiceStateCompletionHandler // CompletionHandler - }, - { - OID_WWAN_SIGNAL_STATE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_SIGNAL_INDICATION_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION), // NdisObjectHeaderSize - - MbbNdisSetSignalState, // Set routine - sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION), // MinSetInBufferSize - - MbbNdisGetSignalState, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_SIGNAL_STATE), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_SIGNAL_STATE }, // ResponseCommand - sizeof(MBB_SIGNAL_STATE), // ResponseBufferLength - MbbNdisSignalStateStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_CONNECT, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_CONTEXT_STATE_REVISION_2, // NdisObjectHeaderRevision - SIZEOF_NDIS_WWAN_SET_CONTEXT_STATE_REVISION_2, // NdisObjectHeaderSize - - MbbNdisSetConnectState, // Set routine - SIZEOF_NDIS_WWAN_SET_CONTEXT_STATE_REVISION_2, // MinSetInBufferSize - - MbbNdisGetConnectState, // Query routine - 0, // MinQueryInBufferSize - SIZEOF_NDIS_WWAN_CONTEXT_STATE_REVISION_2, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_CONNECT }, // ResponseCommand - sizeof(MBB_CONTEXT_STATE), // ResponseBufferLength - MbbNdisConnectStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_INVALID, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - FALSE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbIpGetConfiguration, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_IP_ADDRESS_INFO }, // ResponseCommand - sizeof(MBB_CONTEXT_STATE), // ResponseBufferLength - MbbIpAddressStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_PROVISIONED_CONTEXTS, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_PROVISIONED_CONTEXT_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT), // NdisObjectHeaderSize - - MbbNdisSetProvisionedContexts, // Set routine - sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT), // MinSetInBufferSize - - MbbNdisGetProvisionedContexts, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_PROVISIONED_CONTEXTS }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisProvisionedContextStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_PROVISIONED_CONTEXTS, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_PROVISIONED_CONTEXT_REVISION_2, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT_V2), // NdisObjectHeaderSize - - MbbNdisSetProvisionedContextsV2, // Set routine - sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT_V2), // MinSetInBufferSize - - MbbNdisGetProvisionedContextsV2, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_PROVISIONED_CONTEXT_V2 }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisProvisionedContextV2StatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SERVICE_ACTIVATION, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SERVICE_ACTIVATION_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SERVICE_ACTIVATION), // NdisObjectHeaderSize - - MbbNdisSetServiceActivation, // Set routine - sizeof(NDIS_WWAN_SERVICE_ACTIVATION), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_SERVICE_ACTIVATION }, // ResponseCommand - sizeof(MBB_SERVICE_ACTIVATION_STATUS), // ResponseBufferLength - MbbNdisServiceActivationStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // SMS - // - { - OID_WWAN_SMS_CONFIGURATION, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_SMS_CONFIGURATION_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_SMS_CONFIGURATION), // NdisObjectHeaderSize - - MbbNdisSmsSetConfiguration, // Set routine - sizeof(NDIS_WWAN_SET_SMS_CONFIGURATION), // MinSetInBufferSize - - MbbNdisSmsGetConfiguration, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_SMS_CONFIGURATION), // MinQueryOutBufferSize - - { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_CONFIGURATION }, // ResponseCommand - sizeof(MBB_SMS_CONFIGURATION), // ResponseBufferLength - MbbNdisSmsConfigurationStatusHandler, // ResponseHandler - MbbNdisReadyInfoCompletionHandler // CompletionHandler - }, - { - OID_WWAN_SMS_READ, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisSmsRead, // Query routine - sizeof(NDIS_WWAN_SMS_READ), // MinQueryInBufferSize - sizeof(NDIS_WWAN_SMS_RECEIVE), // MinQueryOutBufferSize - - { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_READ }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisSmsReadStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SMS_SEND, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SMS_SEND_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SMS_SEND), // NdisObjectHeaderSize - - MbbNdisSmsSend, // Set routine - sizeof(NDIS_WWAN_SMS_SEND), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_SEND }, // ResponseCommand - sizeof(MBB_SMS_SEND_STATUS), // ResponseBufferLength - MbbNdisSmsSendStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SMS_DELETE, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SMS_DELETE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SMS_DELETE), // NdisObjectHeaderSize - - MbbNdisSmsDelete, // Set routine - sizeof(NDIS_WWAN_SMS_DELETE), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_DELETE }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisSmsDeleteStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SMS_STATUS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisSmsGetStatus, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_SMS_STATUS), // MinQueryOutBufferSize - - { MBB_UUID_SMS_CONSTANT, MBB_SMS_CID_STATUS }, // ResponseCommand - sizeof(MBB_SMS_STATUS), // ResponseBufferLength - MbbNdisSmsStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // USSD - // - { - OID_WWAN_USSD, // Oid - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_USSD_REQUEST_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_USSD_REQUEST), // NdisObjectHeaderSize - - MbbNdisSetUSSD, // Set routine - sizeof(NDIS_WWAN_USSD_REQUEST), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_USSD_CONSTANT, MBB_USSD_CID_USSD }, // ResponseCommand - sizeof(MBB_USSD), // ResponseBufferLength - MbbNdisUSSDStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // DEVICE SERVICES - // - { - OID_WWAN_ENUMERATE_DEVICE_SERVICES, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisEnumerateDeviceServices, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_DEVICE_SERVICES }, // ResponseCommand - sizeof(MBB_DEVICE_SERVICES_HEADER), // ResponseBufferLength - MbbNdisDeviceServiceListStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_DEVICE_SERVICE_COMMAND, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_DEVICE_SERVICE_COMMAND_REVISION_1, // NdisObjectHeaderRevision - SIZEOF_NDIS_WWAN_DEVICE_SERVICE_COMMAND_1, // NdisObjectHeaderSize - - MbbNdisSetDeviceServiceCommand, // Set routine - sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND), // MinSetInBufferSize - - MbbNdisGetDeviceServiceCommand, // Query routine - sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND), // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisDeviceServiceStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS_REVISION_1, // NdisObjectHeaderRevision - SIZEOF_NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS_1, // NdisObjectHeaderSize - - MbbNdisSubscribeDeviceServiceEvents, // Set routine - sizeof(NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisSubscribeDeviceServiceEventsStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS_REVISION_1, // NdisObjectHeaderRevision - SIZEOF_NDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS_1, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisEnumerateDeviceServiceCommands, // Query routine - sizeof(NDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS), // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_MAXIMUM }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_DEVICE_SERVICE_SESSION_WRITE, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - FALSE, // IsSerialized - TRUE, // IsIndicationRequired = Indicate will complete - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_REVISION_1, // NdisObjectHeaderRevision - SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_1, // NdisObjectHeaderSize - - MbbNdisDssWrite, // Set routine - sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisDssWriteCompleteStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_PREFERRED_MULTICARRIER_PROVIDERS, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS), // NdisObjectHeaderSize - - MbbNdisSetMulticarrierProviders, // Set routine - sizeof(NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS), // MinSetInBufferSize - - MbbNdisGetMulticarrierProviders, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_MULTICARRIER_PROVIDERS }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisMulticarrierProviderStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // CREATE/DELETE MAC - // - { - OID_WWAN_CREATE_MAC, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_MAC_PARAMETERS_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_MAC_PARAMETERS), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisCreateMac, // Query routine - SIZEOF_NDIS_WWAN_MAC_PARAMETERS_1, // MinQueryInBufferSize - sizeof(NDIS_WWAN_MAC_INFO), // MinQueryOutBufferSize - - {MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - MbbNdisCreateMacCompletionHandler // CompletionHandler - }, - { - OID_WWAN_DELETE_MAC, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_MAC_PARAMETERS_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_MAC_PARAMETERS), // NdisObjectHeaderSize - - MbbNdisDeleteMac, // Set routine - sizeof(NDIS_WWAN_MAC_INFO), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - MbbNdisDeleteMacCompletionHandler // CompletionHandler - }, - // - // MULTI-CARRIER - // - { - OID_INVALID, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetMultiCarrierDsCidList, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_MULTICARRIER_CONSTANT, MBB_MULTICARRIER_CID_CURRENT_CID_LIST }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisMultiCarrierDsCidListStatusHandler, // ResponseHandler - MbbNdisMultiCarrierDsCidListCompletionHandler // CompletionHandler - }, - // - // UICC - // - { - OID_WWAN_UICC_APP_LIST, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_UICC_APP_LIST_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_UICC_APP_LIST), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetUiccAppList, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_UICC_APP_LIST), // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_APP_LIST }, // ResponseCommand - sizeof(MBB_UICC_APP_LIST), // ResponseBufferLength - MbbNdisUiccAppListStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_UICC_FILE_STATUS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_UICC_FILE_PATH_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_UICC_FILE_PATH), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetUiccFileStatus, // Query routine - sizeof(NDIS_WWAN_UICC_FILE_PATH), // MinQueryInBufferSize - sizeof(NDIS_WWAN_UICC_FILE_STATUS), // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_FILE_STATUS }, // ResponseCommand - sizeof(MBB_UICC_FILE_STATUS), // ResponseBufferLength - MbbNdisUiccFileStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_UICC_ACCESS_BINARY, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_UICC_ACCESS_BINARY_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_UICC_ACCESS_BINARY), // NdisObjectHeaderSize - - MbbNdisUiccUpdateBinary, // Set routine - sizeof(NDIS_WWAN_UICC_ACCESS_BINARY), // MinSetInBufferSize - - MbbNdisUiccReadBinary, // Query routine - sizeof(NDIS_WWAN_UICC_ACCESS_BINARY), // MinQueryInBufferSize - sizeof(NDIS_WWAN_UICC_RESPONSE), // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_ACCESS_BINARY }, // ResponseCommand - sizeof(MBB_UICC_RESPONSE), // ResponseBufferLength - MbbNdisUiccAccessStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_UICC_ACCESS_RECORD, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_UICC_ACCESS_RECORD_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_UICC_ACCESS_RECORD), // NdisObjectHeaderSize - - MbbNdisUiccUpdateRecord, // Set routine - sizeof(NDIS_WWAN_UICC_ACCESS_RECORD), // MinSetInBufferSize - - MbbNdisUiccReadRecord, // Query routine - sizeof(NDIS_WWAN_UICC_ACCESS_RECORD), // MinQueryInBufferSize - sizeof(NDIS_WWAN_UICC_RESPONSE), // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_ACCESS_RECORD }, // ResponseCommand - sizeof(MBB_UICC_RESPONSE), // ResponseBufferLength - MbbNdisUiccAccessStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // UICC Security in MBIM 2.0 - // - { - OID_WWAN_PIN_EX2, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_PIN_REVISION_3, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_PIN_EX2), // NdisObjectHeaderSize - - MbbNdisSetPinInfoEx2, // Set routine - sizeof(NDIS_WWAN_SET_PIN_EX2), // MinSetInBufferSize - - MbbNdisGetPinInfoEx, // Query routine - sizeof(NDIS_WWAN_PIN_APP), // MinQueryInBufferSize - sizeof(NDIS_WWAN_PIN_INFO), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_PIN_INFO_EX2 }, // ResponseCommand - sizeof(MBB_PIN_INFO), // ResponseBufferLength - MbbNdisPinInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // MBIM-VERSION - // - { - OID_WWAN_MBIM_VERSION, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_MBIM_VERSION_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_MBIM_VERSION), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetMbimVersion, // Query routine - 0, // MinQueryInBufferSize - sizeof(USHORT), // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - // - // Device State and Configuration for MBIM 2.0 - // - { - OID_WWAN_SYS_CAPS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetSysCapsInfo, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_SYS_CAPS_INFO), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_SYS_CAPS }, // ResponseCommand - sizeof(MBB_MS_SYS_CAPS_INFO), // ResponseBufferLength - MbbNdisSysCapsStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_DEVICE_CAPS_EX, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetDeviceCapsEx, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_DEVICE_CAPS_EX), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_DEVICE_CAPS_V2 }, // ResponseCommand - sizeof(MBB_MS_DEVICE_CAPS_INFO_V2), // ResponseBufferLength - MbbNdisDeviceCapsExStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SYS_SLOTMAPPINGS, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO), // NdisObjectHeaderSize - - MbbNdisSetSysSlotMappings, // Set routine - sizeof(NDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO), // MinSetInBufferSize - - MbbNdisGetSysSlotMappings, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_DEVICE_SLOT_MAPPINGS }, // ResponseCommand - sizeof(MBB_MS_DEVICE_SLOT_MAPPING_INFO), // ResponseBufferLength - MbbNdisSysSlotMappingsStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SLOT_INFO_STATUS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetSlotInfoStatus, // Query routine - sizeof(NDIS_WWAN_GET_SLOT_INFO), // MinQueryInBufferSize - sizeof(NDIS_WWAN_SLOT_INFO), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_SLOT_INFO_STATUS }, // ResponseCommand - sizeof(MBB_MS_SLOT_INFO), // ResponseBufferLength - MbbNdisSlotInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_DEVICE_BINDINGS, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_DEVICE_BINDINGS_INFO_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_DEVICE_BINDINGS_INFO), // NdisObjectHeaderSize - - MbbNdisSetDeviceBindings, // Set routine - sizeof(NDIS_WWAN_SET_DEVICE_BINDINGS_INFO), // MinSetInBufferSize - - MbbNdisGetDeviceBindings, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO), // MinQueryOutBufferSize - - { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_DEVICE_BINDINGS }, // ResponseCommand - sizeof(MBB_DEVICE_BINDINGS_INFO), // ResponseBufferLength - MbbNdisDeviceBindingsStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // Registration, Signal Strength, and NITZ for MBIM 2.0 - // - { - OID_WWAN_REGISTER_STATE_EX, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_REGISTER_STATE_REVISION_2, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_REGISTER_STATE_EX), // NdisObjectHeaderSize - - MbbNdisSetRegisterState, // Set routine - sizeof(NDIS_WWAN_SET_REGISTER_STATE_EX), // MinSetInBufferSize - - MbbNdisGetRegisterStateEx, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX), // MinQueryOutBufferSize - - { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_REGISTER_STATE_V2 }, // ResponseCommand - sizeof(MBB_REGISTRATION_STATE_INFOS_V2), // ResponseBufferLength - MbbNdisRegisterStateExStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_IMS_VOICE_STATE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_IMS_VOICE_STATE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_IMS_VOICE_STATE), // NdisObjectHeaderSize - - MbbNdisSetImsVoiceState, // Set routine - sizeof(NDIS_WWAN_SET_IMS_VOICE_STATE), // MinSetInBufferSize - - MbbNdisGetImsVoiceState, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_IMS_VOICE_STATE), // MinQueryOutBufferSize - - { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_IMS_VOICE_STATE }, // ResponseCommand - sizeof(MBB_IMS_VOICE_STATE), // ResponseBufferLength - MbbNdisImsVoiceStateStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SIGNAL_STATE_EX, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_SIGNAL_INDICATION_REVISION_2, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION_EX), // NdisObjectHeaderSize - - MbbNdisSetSignalStateEx, // Set routine - sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION_EX), // MinSetInBufferSize - - MbbNdisGetSignalStateEx, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX), // MinQueryOutBufferSize - - { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_SIGNAL_STATE_V2 }, // ResponseCommand - sizeof(MBB_SIGNAL_STATE_INFOS_V2), // ResponseBufferLength - MbbNdisSignalStateExStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_LOCATION_STATE, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_LOCATION_TRIGGER_MODE_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_LOCATION_TRIGGER_MODE), // NdisObjectHeaderSize - - MbbNdisSetLocationState, // Set routine - sizeof(NDIS_WWAN_LOCATION_TRIGGER_MODE), // MinSetInBufferSize - - MbbNdisGetLocationState, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_LOCATION_STATE_INFO), // MinQueryOutBufferSize - - { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_LOCATION_STATE }, // ResponseCommand - sizeof(MBB_LOCATION_STATE_INFO), // ResponseBufferLength - MbbNdisLocationStateStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_NITZ, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetNitzInfo, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_NITZ_INFO), // MinQueryOutBufferSize - - { MBB_UUID_VOICEEXTENSIONS_CONSTANT, MBB_VOICEEXTENSIONS_CID_NITZ }, // ResponseCommand - sizeof(MBB_NITZ_INFO), // ResponseBufferLength - MbbNdisNitzStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // For MBIM vendor specific - // - { - OID_WWAN_VENDOR_SPECIFIC, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_VENDOR_SPECIFIC_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_VENDOR_SPECIFIC), // NdisObjectHeaderSize - - MbbNdisSetVendorSpecific, // Set routine - sizeof(NDIS_WWAN_VENDOR_SPECIFIC), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_MS_VENDOR_EXTENSION_CONSTANT, MBIM_CID_VENDORSPECIFIC }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisVendorSpecificStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // Network Idle Hint - // - { - OID_WWAN_NETWORK_IDLE_HINT, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - FALSE, // IsSerialized - FALSE, // IsIndicationRequired - FALSE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_NETWORK_IDLE_HINT_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_NETWORK_IDLE_HINT), // NdisObjectHeaderSize - - MbbNdisSetNetworkIdleHint, // Set routine - sizeof(NDIS_WWAN_NETWORK_IDLE_HINT), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_INVALID_CONSTANT, 0 }, // ResponseCommand - 0, // ResponseBufferLength - NULL, // ResponseHandler - NULL // CompletionHandler - }, - // - // System Preshutdown - // - { - OID_WWAN_PRESHUTDOWN, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_PRESHUTDOWN_STATE_REVISION_1, // NdisObjectHeaderRevision - SIZEOF_NDIS_WWAN_SET_PRESHUTDOWN_STATE_1, // NdisObjectHeaderSize - - MbbNdisSetPreshutdown, // Set routine - SIZEOF_NDIS_WWAN_SET_PRESHUTDOWN_STATE_1, // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_HOSTSHUTDOWN_CONSTANT, MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN }, // ResponseCommand - SIZEOF_NDIS_WWAN_PRESHUTDOWN_STATE_1, // ResponseBufferLength - MbbNdisPreshutdownHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // Low-Level UICC Access - // - { - OID_WWAN_UICC_ATR, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetAtr, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_ATR_INFO), // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_ATR }, // ResponseCommand - sizeof(MBB_ATR_INFO), // ResponseBufferLength - MbbNdisAtrInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_UICC_OPEN_CHANNEL, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_UICC_OPEN_CHANNEL_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_UICC_OPEN_CHANNEL), // NdisObjectHeaderSize - - MbbNdisSetUiccOpenChannel, // Set routine - sizeof(NDIS_WWAN_SET_UICC_OPEN_CHANNEL), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_OPEN_CHANNEL }, // ResponseCommand - sizeof(MBB_UICC_OPEN_CHANNEL_INFO), // ResponseBufferLength - MbbNdisUiccOpenChannelInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_UICC_CLOSE_CHANNEL, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_UICC_CLOSE_CHANNEL_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_UICC_CLOSE_CHANNEL), // NdisObjectHeaderSize - - MbbNdisSetUiccCloseChannel, // Set routine - sizeof(NDIS_WWAN_SET_UICC_CLOSE_CHANNEL), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_CLOSE_CHANNEL }, // ResponseCommand - sizeof(MBB_UICC_CLOSE_CHANNEL_INFO), // ResponseBufferLength - MbbNdisUiccCloseChannelInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_UICC_APDU, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_UICC_APDU_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_UICC_APDU), // NdisObjectHeaderSize - - MbbNdisSetUiccApdu, // Set routine - sizeof(NDIS_WWAN_SET_UICC_APDU), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_APDU },// ResponseCommand - sizeof(MBB_UICC_APDU_INFO), // ResponseBufferLength - MbbNdisUiccApduInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_UICC_TERMINAL_CAPABILITY, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY), // NdisObjectHeaderSize - - MbbNdisSetUiccTerminalCapability, // Set routine - sizeof(NDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY), // MinSetInBufferSize - - MbbNdisGetUiccTerminalCapability, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO), // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_TERMINAL_CAPABILITY }, // ResponseCommand - sizeof(MBB_UICC_TERMINAL_CAPABILITY_INFO), // ResponseBufferLength - MbbNdisUiccTerminalCapabilityInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - // - // SAR backoff - // - { - OID_WWAN_SAR_CONFIG, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_SAR_CONFIG_REVISON_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_SAR_CONFIG), // NdisObjectHeaderSize - - MbbNdisSetSarConfig, // Set routine - sizeof(NDIS_WWAN_SET_SAR_CONFIG), // MinSetInBufferSize - - MbbNdisGetSarConfig, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_SAR_CONFIG_INFO), // MinQueryOutBufferSize - - { MBB_UUID_SARCONTROL_CONSTANT, MBB_SAR_CID_CONFIG }, // ResponseCommand - sizeof(MBB_SAR_CONFIG_INFO), // ResponseBufferLength - MbbNdisSarConfigHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_SAR_TRANSMISSION_STATUS, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_SAR_TRANSMISSION_STATUS_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_SAR_TRANSMISSION_STATUS), // NdisObjectHeaderSize - - MbbNdisSetSarTransmissionStatus, // Set routine - sizeof(NDIS_WWAN_SET_SAR_TRANSMISSION_STATUS), // MinSetInBufferSize - - MbbNdisGetSarTransmissionStatus, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO), // MinQueryOutBufferSize - - { MBB_UUID_SARCONTROL_CONSTANT, MBB_SAR_CID_TRANSMISSION_STATUS }, // ResponseCommand - sizeof(MBB_SAR_TRANSMISSION_STATUS_INFO), // ResponseBufferLength - MbbNdisSarTransmissionStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_LTE_ATTACH_CONFIG, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_LTE_ATTACH_CONTEXT_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_LTE_ATTACH_CONTEXT), // NdisObjectHeaderSize - - MbbNdisSetLteAttachContexts, // Set routine - sizeof(NDIS_WWAN_SET_LTE_ATTACH_CONTEXT), // MinSetInBufferSize - - MbbNdisGetLteAttachConfig, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_LTE_ATTACH_CONTEXTS), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_LTE_ATTACH_CONFIG }, // ResponseCommand - sizeof(MBB_MS_LTE_ATTACH_CONFIG_INFO), // ResponseBufferLength - MbbNdisLteAttachConfigHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_LTE_ATTACH_STATUS, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - 0, // NdisObjectHeaderType - 0, // NdisObjectHeaderRevision - 0, // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetLteAttachStatus, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_SYS_CAPS_INFO), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_LTE_ATTACH_STATUS }, // ResponseCommand - sizeof(MBB_MS_LTE_ATTACH_STATUS), // ResponseBufferLength - MbbNdisLteAttachStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_NETWORK_BLACKLIST, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_NETWORK_BLACKLIST_REVISON_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_NETWORK_BLACKLIST), // NdisObjectHeaderSize - - MbbNdisSetNetworkBlacklist, // Set routine - sizeof(NDIS_WWAN_SET_NETWORK_BLACKLIST), // MinSetInBufferSize - - MbbUtilQueryAttribute, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_NETWORK_BLACKLIST), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_NETWORK_BLACKLIST }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisNetworkBlacklistHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_PCO, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_PCO_STATUS_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_PCO_STATUS), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetPcoStatus, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_PCO_STATUS), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_PCO }, // ResponseCommand - sizeof(MBB_MS_PCO_VALUE), // ResponseBufferLength - MbbNdisPcoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_UICC_RESET, // Oid - - TRUE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_UICC_RESET_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_UICC_RESET), // NdisObjectHeaderSize - - MbbNdisSetUiccReset, // Set routine - sizeof(NDIS_WWAN_SET_UICC_RESET), // MinSetInBufferSize - - MbbNdisGetUiccReset, // Query routine - 0, // MinQueryInBufferSize - sizeof(NDIS_WWAN_UICC_RESET_INFO), // MinQueryOutBufferSize - - { MBB_UUID_UICC_LOW_LEVEL_CONSTANT, MBB_UICC_CID_RESET }, // ResponseCommand - sizeof(MBB_UICC_RESET_INFO), // ResponseBufferLength - MbbNdisUiccResetInfoStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_DEVICE_RESET, // Oid - - TRUE, // IsSettable - FALSE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_SET_DEVICE_RESET_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_SET_DEVICE_RESET), // NdisObjectHeaderSize - - MbbNdisSetDeviceReset, // Set routine - sizeof(NDIS_WWAN_SET_DEVICE_RESET), // MinSetInBufferSize - - NULL, // Query routine - 0, // MinQueryInBufferSize - 0, // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_DEVICE_RESET }, // ResponseCommand - 0, // ResponseBufferLength - MbbNdisDeviceResetStatusHandler, // ResponseHandler - NULL // CompletionHandler - }, - { - OID_WWAN_BASE_STATIONS_INFO, // Oid - - FALSE, // IsSettable - TRUE, // IsQueryable - TRUE, // IsSerialized - TRUE, // IsIndicationRequired - TRUE, // CompleteRequestOnSendComplete - - NDIS_OBJECT_TYPE_DEFAULT, // NdisObjectHeaderType - NDIS_WWAN_BASE_STATIONS_INFO_REQ_REVISION_1, // NdisObjectHeaderRevision - sizeof(NDIS_WWAN_BASE_STATIONS_INFO_REQ), // NdisObjectHeaderSize - - NULL, // Set routine - 0, // MinSetInBufferSize - - MbbNdisGetBaseStationsInfo, // Query routine - sizeof(NDIS_WWAN_BASE_STATIONS_INFO_REQ), // MinQueryInBufferSize - FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData), // MinQueryOutBufferSize - - { MBB_UUID_BASIC_CONNECT_EXT_CONSTANT, MBB_BASICCONNECTEXT_CID_BASE_STATIONS_INFO }, // ResponseCommand - FIELD_OFFSET(MBB_MS_BASE_STATIONS_INFO, DataBuffer), // ResponseBufferLength - MbbNdisBaseStationsInfoHandler, // ResponseHandler - NULL // CompletionHandler - }, - - { 0 } // terminator -}; - - -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINITIONS -// -//////////////////////////////////////////////////////////////////////////////// - - -NDIS_STATUS -MbbNdisAdapterWriteBoolParameter( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN Value, - __in PNDIS_STRING RegNameString - ) -{ - NDIS_CONFIGURATION_OBJECT ConfigObject; - NDIS_HANDLE RegistryConfigurationHandle = NULL; - NDIS_CONFIGURATION_PARAMETER Parameter; - NDIS_STATUS NdisStatus; - - ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT; - ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1; - ConfigObject.Header.Size = sizeof( NDIS_CONFIGURATION_OBJECT ); - ConfigObject.NdisHandle = Adapter->MiniportAdapterHandle; - ConfigObject.Flags = 0; - - NdisStatus = NdisOpenConfigurationEx( - &ConfigObject, - &RegistryConfigurationHandle - ); - - if ((NdisStatus == NDIS_STATUS_SUCCESS) && (RegistryConfigurationHandle != NULL)) - { - NdisZeroMemory(&Parameter, sizeof(NDIS_CONFIGURATION_PARAMETER)); - - Parameter.ParameterData.IntegerData = (Value ? 1 : 0); - Parameter.ParameterType = NdisParameterInteger; - - NdisWriteConfiguration( - &NdisStatus, - RegistryConfigurationHandle, - RegNameString, - &Parameter - ); - } - else - { - TraceError( WMBCLASS_OID, "[MbbAdapter] FAILED to open configuration, status=%!STATUS!", NdisStatus ); - } - - // - // Close the handle to the registry - // - if (RegistryConfigurationHandle) - { - NdisCloseConfiguration(RegistryConfigurationHandle); - } - - return NdisStatus; -} - -MBB_BUS_HANDLE -MbbNdisGetBusHandle( - __in MBB_PROTOCOL_HANDLE AdapterHandle - ) -{ - return ((PMINIPORT_ADAPTER_CONTEXT)AdapterHandle)->BusHandle; -} - -NDIS_OID -MbbNdisGetOid( - __in PNDIS_OID_REQUEST OidRequest - ) -{ - switch( OidRequest->RequestType ) - { - case NdisRequestQueryInformation: - case NdisRequestQueryStatistics: - { - return OidRequest->DATA.QUERY_INFORMATION.Oid; - } - break; - - case NdisRequestSetInformation: - { - return OidRequest->DATA.SET_INFORMATION.Oid; - } - break; - - case NdisRequestMethod: - { - return OidRequest->DATA.METHOD_INFORMATION.Oid; - } - break; - } - - return (NDIS_OID)0; -} - -PMBB_OID_HANDLER_ENTRY -MbbNdisFetchOidHandler( - __in NDIS_OID Oid, - __in PNDIS_OID_REQUEST OidRequest - ) -{ - ULONG OidTableIndex; - PMBB_OID_HANDLER_ENTRY OidHandlerEntry = NULL; - PNDIS_WWAN_AUTH_CHALLENGE ndisWwanAuthChallenge; - ULONG CmdId = 0; - - - // - // Crack open the OID request - // - switch (Oid){ - case OID_WWAN_AUTH_CHALLENGE: - { - if (OidRequest->RequestType == NdisRequestQueryInformation){ - - if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < sizeof(*ndisWwanAuthChallenge)) - { - return NULL; - } - - ndisWwanAuthChallenge = (PNDIS_WWAN_AUTH_CHALLENGE)OidRequest->DATA.QUERY_INFORMATION.InformationBuffer; - if (ndisWwanAuthChallenge->AuthChallenge.AuthMethod == WwanAuthAka){ - CmdId = MBB_AUTH_CID_AKA; - } - else if (ndisWwanAuthChallenge->AuthChallenge.AuthMethod == WwanAuthAkaPrime){ - CmdId = MBB_AUTH_CID_AKAP; - } - else if (ndisWwanAuthChallenge->AuthChallenge.AuthMethod == WwanAuthSim){ - CmdId = MBB_AUTH_CID_SIM; - } - } - } - break; - case OID_WWAN_DEVICE_SERVICE_SESSION: - { - if (OidRequest->RequestType == NdisRequestSetInformation){ - - CmdId = MBB_DSS_CID_CONNECT; - } - - } - break; - - } - - - for( OidTableIndex = 0; - MbbSpecialOidHandlerTable[OidTableIndex].Oid != 0; - OidTableIndex++ ) - { - if( MbbSpecialOidHandlerTable[OidTableIndex].Oid == Oid ) - { - OidHandlerEntry = &MbbSpecialOidHandlerTable[OidTableIndex]; - if (CmdId == OidHandlerEntry->ResponseCommand.CommandId){ - return OidHandlerEntry; - } - } - } - - return NULL; -} - -PMBB_OID_HANDLER_ENTRY -MbbNdisFetchOidHandlerWithRev( - __in NDIS_OID Oid, - __in PNDIS_OID_REQUEST OidRequest -) -{ - ULONG OidTableIndex; - PMBB_OID_HANDLER_ENTRY OidHandlerEntry = NULL; - PNDIS_OBJECT_HEADER ndisHeader = NULL; - - // - // Crack open the OID request - // - switch (Oid) { - case OID_WWAN_PROVISIONED_CONTEXTS: - { - if (OidRequest->RequestType == NdisRequestQueryInformation) - { - ndisHeader = (PNDIS_OBJECT_HEADER)OidRequest->DATA.QUERY_INFORMATION.InformationBuffer; - } - else if (OidRequest->RequestType == NdisRequestSetInformation) - { - ndisHeader = (PNDIS_OBJECT_HEADER)OidRequest->DATA.SET_INFORMATION.InformationBuffer; - } - } - break; - - } - - if (ndisHeader) - { - for (OidTableIndex = 0; - MbbOidHandlerTable[OidTableIndex].Oid != 0; - OidTableIndex++) - { - if (MbbOidHandlerTable[OidTableIndex].Oid == Oid && - ndisHeader->Revision == MbbOidHandlerTable[OidTableIndex].NdisObjectHeaderRevision) - { - OidHandlerEntry = &MbbOidHandlerTable[OidTableIndex]; - break; - } - } - } - - return OidHandlerEntry; -} - -PMBB_OID_HANDLER_ENTRY -MbbNdisGetOidHandler( - __in NDIS_OID Oid - ) -{ - ULONG OidTableIndex; - PMBB_OID_HANDLER_ENTRY OidHandlerEntry = NULL; - - for( OidTableIndex = 0; - MbbOidHandlerTable[OidTableIndex].Oid != 0; - OidTableIndex++ ) - { - if( MbbOidHandlerTable[OidTableIndex].Oid == Oid ) - { - OidHandlerEntry = &MbbOidHandlerTable[OidTableIndex]; - break; - } - } - return OidHandlerEntry; -} - -PMBB_OID_HANDLER_ENTRY -MbbNdisGetOidHandlerByCommand( - __in PMBB_COMMAND Command - ) -{ - ULONG OidTableIndex; - ULONG TableNumber; - PMBB_OID_HANDLER_ENTRY Table; - PMBB_OID_HANDLER_ENTRY OidHandlerEntry = NULL; - - if( Command->CommandId == 0 && - memcmp( - &MBB_UUID_INVALID, - &(Command->ServiceId), - sizeof(GUID) - ) == 0 ) - { - return NULL; - } - - for( TableNumber = 0; - TableNumber < 2; - TableNumber ++ ) - { - if( TableNumber == 0 ) - Table = MbbOidHandlerTable; - else - Table = MbbSpecialOidHandlerTable; - - for( OidTableIndex = 0; - Table[OidTableIndex].Oid != 0; - OidTableIndex++ ) - { - if( Command->CommandId == Table[OidTableIndex].ResponseCommand.CommandId - && - memcmp( - &(Table[OidTableIndex].ResponseCommand.ServiceId), - &(Command->ServiceId), - sizeof(GUID) - ) == 0 ) - { - OidHandlerEntry = &Table[OidTableIndex]; - break; - } - } - } - - return OidHandlerEntry; -} - -__inline -VOID -MbbNdisMiniportIndicateRequestStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in PNDIS_STATUS_INDICATION StatusIndication - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=Request->RequestManager->AdapterContext; - - MbbUtilNdisMiniportIndicateStatusEx(Adapter, StatusIndication); -} - -VOID -MbbNdisMiniportOidRequestCompletion( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - NDIS_STATUS LocalNdisStatus; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(AdapterHandle); - PCSTR OidName=NULL; - ULONG OidNameLength=0; - BOOLEAN CompleteNdisRequest=TRUE; - BOOLEAN IndicationSentInHandler=FALSE; - - if (NdisStatus == MBB_STATUS_INDICATION_ALREADY_SENT) - { - // - // the request handler has indicated the response already, fix up the status - // and remember that we don't need to hold the request for a response that is not coming. - // - IndicationSentInHandler=TRUE; - NdisStatus = NDIS_STATUS_SUCCESS; - } - - if( NdisStatus == NDIS_STATUS_SUCCESS && - Request->OidHandler->IsIndicationRequired == TRUE ) - { - NdisStatus = NDIS_STATUS_INDICATION_REQUIRED; - - if (!Request->OidHandler->CompleteRequestOnSendComplete) - { - // - // We don't want to complete the request back to ndis at this point. - // We will complete the request when the response comes back from the device. - // - CompleteNdisRequest=FALSE; - } - - } - - if ((NdisStatus == NDIS_STATUS_PENDING)) - { - // - // We don't want to complete with status pending - // - CompleteNdisRequest=FALSE; - } - - // - // Complete the request to NDIS - // - if( CompleteNdisRequest ) - { - PNDIS_OID_REQUEST NdisRequest=NULL; - - NdisRequest=InterlockedExchangePointer(&Request->OidContext.OidRequest,(PNDIS_OID_REQUEST)-1); - - if (NdisRequest != (PNDIS_OID_REQUEST)-1) - { - MBB_NDIS_OID_STATE OldOidState; - - Request->OidContext.OidStatus = NdisStatus; - // - // Do not complete the OID request if the Oid handler is still running. - // Defer the OID completion to the Oid handler - // - OldOidState = MbbReqMgrGetSetOidState( - Request, - MbbNdisOidStateComplete - ); - if( OldOidState == MbbNdisOidStatePending || - OldOidState == MbbNdisOidStateDispatched ) - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Completing OID request in %!MbbOidState! to NDIS with status=%!status!", - Request->RequestId, OldOidState, NdisStatus - ); - - OidName=GetOidName(NdisRequest->DATA.QUERY_INFORMATION.Oid); - OidNameLength=strlen(OidName)+1; - - MbbWriteEvent( - &REQUEST_COMPLETE_EVENT, - NULL, - NULL, - 10, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &NdisRequest, - sizeof(NdisRequest), - &NdisRequest->DATA.QUERY_INFORMATION.Oid, - sizeof(NdisRequest->DATA.QUERY_INFORMATION.Oid), - (PVOID)OidName, - OidNameLength, - &NdisRequest->RequestId, - sizeof(NdisRequest->RequestId), - &NdisRequest->RequestHandle, - sizeof(NdisRequest->RequestHandle), - &NdisRequest->RequestType, - sizeof(NdisRequest->RequestType), - &NdisRequest->DATA.QUERY_INFORMATION.BytesWritten, - sizeof(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten), - &NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded, - sizeof(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded), - &NdisStatus, - sizeof(NdisStatus) - ); - - - NdisMOidRequestComplete( - Adapter->MiniportAdapterHandle, - NdisRequest, - NdisStatus - ); - - NdisRequest=NULL; - } - else - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Deferring oid completion in %!MbbOidState!", - Request->RequestId, OldOidState - ); - } - } - else - { - TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Oid already completed", - Request->RequestId - ); - } - } - - if( Request->OidHandler->CompletionHandler != NULL ) - { - Request->OidHandler->CompletionHandler( - Request, - NdisStatus - ); - } - - if( Request->HandlerContext.DataToFreeOnCompletion != NULL ) - FREE_POOL( Request->HandlerContext.DataToFreeOnCompletion ); - // - // If the request does not wait for a NDIS INDICATTION - // then free the request else move the request FSM - // to the next state. - // - if( IndicationSentInHandler || - ( NdisStatus != NDIS_STATUS_PENDING && - NdisStatus != NDIS_STATUS_INDICATION_REQUIRED )) - { - if ( Request->HandlerContext.DataToFreeOnResponse != NULL ) - FREE_POOL( Request->HandlerContext.DataToFreeOnResponse ); - - KeSetEvent( - &Request->WaitEvent, - IO_NO_INCREMENT, - FALSE - ); - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - - if (NdisStatus == NDIS_STATUS_FAILURE) - { - PMBB_SEND_QUEUE SendQueue = &Adapter->SendQueue; - switch (Request->OidHandler->Oid) - { - case OID_WWAN_RADIO_STATE: - TraceLoggingWrite( - g_hLoggingProvider, - "RadioStateSendFailure", - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); - TryQueueStallState(SendQueue); - break; - } - } -} - -NDIS_STATUS -MbbNdisMiniportOidRequest( - __in NDIS_HANDLE MiniportAdapter, - __in PNDIS_OID_REQUEST OidRequest - ) -{ - NDIS_OID Oid; - ULONG ResponseBufferLength; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - PMBB_OID_HANDLER_ENTRY OidHandler; - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapter; - NDIS_STATUS Status=NDIS_STATUS_NOT_SUPPORTED; - PCSTR OidName=NULL; - ULONG OidNameLength=0; - - do - { - OidName=GetOidName(OidRequest->DATA.QUERY_INFORMATION.Oid); - OidNameLength=strlen(OidName)+1; - - MbbWriteEvent( - &REQUEST_EVENT, - NULL, - NULL, - 8, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &OidRequest, - sizeof(OidRequest), - &OidRequest->DATA.QUERY_INFORMATION.Oid, - sizeof(OidRequest->DATA.QUERY_INFORMATION.Oid), - (PVOID)OidName, - OidNameLength, - &OidRequest->RequestId, - sizeof(OidRequest->RequestId), - &OidRequest->RequestHandle, - sizeof(OidRequest->RequestHandle), - &OidRequest->RequestType, - sizeof(OidRequest->RequestType), - &OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength, - sizeof(OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength) - ); - - if( (Oid = MbbNdisGetOid( OidRequest )) == 0 ) - { - TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to get Oid value" ); - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - // - // Find it in the Oid table. But first check if it is a special OID that needs to handled differently. - // If its not in the OID table then its not supported. - // - if ((OID_WWAN_AUTH_CHALLENGE == Oid ) || - (OID_WWAN_DEVICE_SERVICE_SESSION == Oid)) { - OidHandler = MbbNdisFetchOidHandler(Oid, OidRequest); - if (NULL == OidHandler) { - TraceError( WMBCLASS_OID, "[MbbNdis] UNSUPPORTED Oid=0x%x", Oid ); - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - } - else if (OID_WWAN_PROVISIONED_CONTEXTS == Oid) - { - OidHandler = MbbNdisFetchOidHandlerWithRev(Oid, OidRequest); - if (NULL == OidHandler) { - TraceError(WMBCLASS_OID, "[MbbNdis] UNSUPPORTED Oid=0x%x", Oid); - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - } - else if( (OidHandler = MbbNdisGetOidHandler( Oid )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis] UNSUPPORTED Oid=0x%x", Oid ); - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - // - // Allocate the internal MBB request context. - // - if( OidHandler->IsIndicationRequired == TRUE ) - { - ResponseBufferLength = OidHandler->ResponseBufferLength; - } - else - { - ResponseBufferLength = 0; - } - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to reference RequestManager for Oid=0x%x", Oid); - break; - } - - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - OidRequest, - ResponseBufferLength, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to allocate RequestContext for Oid=0x%x", Oid ); - break; - } - Request->OidHandler = OidHandler; - // - // Perform buffer validation - // - switch( OidRequest->RequestType ) - { - case NdisRequestQueryInformation: - case NdisRequestQueryStatistics: - { - if( OidHandler->IsQueryable == FALSE ) - { - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - // - // Minimum buffer size for query is NOT required for - // requests that are completed via status indications. - // - if( OidHandler->IsIndicationRequired != TRUE && - OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < OidHandler->MinQueryOutBufferSize ) - { - OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = OidHandler->MinQueryOutBufferSize; - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - } - break; - - case NdisRequestSetInformation: - { - if( OidHandler->IsSettable == FALSE ) - { - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - if( OidRequest->DATA.SET_INFORMATION.InformationBufferLength < OidHandler->MinSetInBufferSize ) - { - OidRequest->DATA.SET_INFORMATION.BytesNeeded = OidHandler->MinSetInBufferSize; - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - } - break; - - case NdisRequestMethod: - { - if( OidHandler->IsQueryable == FALSE ) - { - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - if( OidRequest->DATA.METHOD_INFORMATION.InputBufferLength < OidHandler->MinQueryInBufferSize || - OidRequest->DATA.METHOD_INFORMATION.OutputBufferLength < OidHandler->MinQueryOutBufferSize ) - { - OidRequest->DATA.METHOD_INFORMATION.BytesNeeded = MAX( OidHandler->MinQueryInBufferSize, OidHandler->MinQueryOutBufferSize ); - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - } - break; - - default: - { - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - } - break; - } - // - // If buffer validation failed or the OID Handler failed, bail out. - // - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - break; - } - // - // Dispatch the request to the queue for processing. - // If the request completes synchronously cleanup - // the request context. Else the completion routine - // will be called at a later time. - // - MbbReqMgrGetSetOidState( - Request, - MbbNdisOidStatePending - ); - NdisStatus = MbbReqMgrDispatchRequest( - Request, - (OidHandler->IsSerialized == 1), - MbbNdisProcessSerializedOidRequest, - MbbNdisMiniportOidRequestCompletion, - MbbNdisIndicateStatus - ); - } while( FALSE ); - - if( NdisStatus != NDIS_STATUS_PENDING && - NdisStatus != NDIS_STATUS_INDICATION_REQUIRED ) - { - if( Request != NULL ) - { - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - } - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - - if( NdisStatus != NDIS_STATUS_PENDING ) - { - MbbWriteEvent( - &REQUEST_NOT_PENDING_EXIT_EVENT, - NULL, - NULL, - 10, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &OidRequest, - sizeof(OidRequest), - &OidRequest->DATA.QUERY_INFORMATION.Oid, - sizeof(OidRequest->DATA.QUERY_INFORMATION.Oid), - (PVOID)OidName, - OidNameLength, - &OidRequest->RequestId, - sizeof(OidRequest->RequestId), - &OidRequest->RequestHandle, - sizeof(OidRequest->RequestHandle), - &OidRequest->RequestType, - sizeof(OidRequest->RequestType), - &OidRequest->DATA.QUERY_INFORMATION.BytesWritten, - sizeof(OidRequest->DATA.QUERY_INFORMATION.BytesWritten), - &OidRequest->DATA.QUERY_INFORMATION.BytesNeeded, - sizeof(OidRequest->DATA.QUERY_INFORMATION.BytesNeeded), - &NdisStatus, - sizeof(NdisStatus) - ); - - - } - else - { - MbbWriteEvent( - &REQUEST_PENDING_EXIT_EVENT, - NULL, - NULL, - 3, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &OidRequest, - sizeof(OidRequest), - &NdisStatus, - sizeof(NdisStatus) - ); - - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisProcessSerializedOidRequest( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -/*++ - Description - This is the internal serialized routine that calls OID handlers. - Only one instance of this routine will run at any time. - If an OID is associated with this request, NDIS is called to - notify about the OID completion via NdisMOidRequestComplete( ). - - Parameters - __in PMBB_REQUEST_CONTEXT Request - The request to process. This is the internal request representation. - The request - - Return Value - NDIS_STATUS_SUCCESS - The request was successfully processed and the OID, if any, - was successfully completed to NDIS. - - NDIS_STATUS_NOT_SUPPORTED - The request is an invalid request and could not be processed. - - NDIS_STATUS_PENDING - Request completion is deferred by the OID handler. - The OID handler will call NdisMOidRequestComplete( ). ---*/ -{ - NDIS_STATUS NdisStatus = STATUS_SUCCESS; - NDIS_OID Oid = MbbNdisGetOid( Request->OidContext.OidRequest ); - MBB_NDIS_OID_STATE OidState; - PMBB_OID_HANDLER_ENTRY OidHandlerEntry = Request->OidHandler; - PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)AdapterHandle; - - TraceInfo(WMBCLASS_OID, "Entered OID=%08lx ", Oid ); - - MbbReqMgrGetSetOidState( - Request, - MbbNdisOidStateDispatching - ); - // - // Buffers have already been validated. Call the handler. - // - switch( OidRequest->RequestType ) - { - case NdisRequestQueryInformation: - case NdisRequestQueryStatistics: - { - OidRequest->DATA.QUERY_INFORMATION.BytesWritten = OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength; - // - // Ideally, Query requests do not contain an InBuffer. - // SMS_READ,VISIBLE_PROVIDERS and DEVICE_SERVICE_COMMAND overloads - // the OutBuffer as an InBuffer. - // The correct approach would have been to use Method - // request instead of Query but deal with it anyways. - // - switch(Oid) - { - case OID_WWAN_SMS_READ: - case OID_WWAN_DEVICE_SERVICE_COMMAND: - case OID_WWAN_VISIBLE_PROVIDERS: - case OID_WWAN_AUTH_CHALLENGE: - case OID_WWAN_SLOT_INFO_STATUS: - case OID_WWAN_BASE_STATIONS_INFO: - - if( OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < OidHandlerEntry->MinQueryInBufferSize ) - { - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - - - NdisStatus = OidHandlerEntry->QueryHandler( - Request, - OidRequest->DATA.QUERY_INFORMATION.InformationBuffer, - &OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength, - OidRequest->DATA.QUERY_INFORMATION.InformationBuffer, - &OidRequest->DATA.QUERY_INFORMATION.BytesWritten - ); - - break; - - default: - NdisStatus = OidHandlerEntry->QueryHandler( - Request, - NULL, - NULL, - OidRequest->DATA.QUERY_INFORMATION.InformationBuffer, - &OidRequest->DATA.QUERY_INFORMATION.BytesWritten - ); - - break; - } - } - break; - - case NdisRequestSetInformation: - { - OidRequest->DATA.SET_INFORMATION.BytesRead = OidRequest->DATA.SET_INFORMATION.InformationBufferLength; - - NdisStatus = OidHandlerEntry->SetHandler( - Request, - OidRequest->DATA.SET_INFORMATION.InformationBuffer, - &OidRequest->DATA.SET_INFORMATION.BytesRead - ); - } - break; - - case NdisRequestMethod: - { - OidRequest->DATA.METHOD_INFORMATION.BytesRead = OidRequest->DATA.METHOD_INFORMATION.InputBufferLength; - OidRequest->DATA.METHOD_INFORMATION.BytesWritten = OidRequest->DATA.METHOD_INFORMATION.OutputBufferLength; - - NdisStatus = OidHandlerEntry->QueryHandler( - Request, - OidRequest->DATA.METHOD_INFORMATION.InformationBuffer, - &OidRequest->DATA.METHOD_INFORMATION.BytesRead, - OidRequest->DATA.METHOD_INFORMATION.InformationBuffer, - &OidRequest->DATA.METHOD_INFORMATION.BytesWritten - ); - } - break; - - default: - { - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - } - break; - } - // - // Complete the OID request if the Oid completion happened before this point. - // - OidState = MbbReqMgrGetSetOidState( - Request, - MbbNdisOidStateDispatched - ); - if( OidState == MbbNdisOidStateComplete ) - { - PCSTR OidName=NULL; - ULONG OidNameLength=0; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Delay completing OID request to NDIS with status=%!status!", - Request->RequestId, Request->OidContext.OidStatus - ); - - OidName = GetOidName(OidRequest->DATA.QUERY_INFORMATION.Oid); - OidNameLength = strlen(OidName)+1; - - MbbWriteEvent( - &REQUEST_COMPLETE_EVENT, - NULL, - NULL, - 10, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &OidRequest, - sizeof(OidRequest), - &OidRequest->DATA.QUERY_INFORMATION.Oid, - sizeof(OidRequest->DATA.QUERY_INFORMATION.Oid), - (PVOID)OidName, - OidNameLength, - &OidRequest->RequestId, - sizeof(OidRequest->RequestId), - &OidRequest->RequestHandle, - sizeof(OidRequest->RequestHandle), - &OidRequest->RequestType, - sizeof(OidRequest->RequestType), - &OidRequest->DATA.QUERY_INFORMATION.BytesWritten, - sizeof(OidRequest->DATA.QUERY_INFORMATION.BytesWritten), - &OidRequest->DATA.QUERY_INFORMATION.BytesNeeded, - sizeof(OidRequest->DATA.QUERY_INFORMATION.BytesNeeded), - &Request->OidContext.OidStatus, - sizeof(Request->OidContext.OidStatus) - ); - - NdisMOidRequestComplete( - Adapter->MiniportAdapterHandle, - OidRequest, - Request->OidContext.OidStatus - ); - } - - return NdisStatus; -} - -VOID -MbbNdisMiniportCancelOidRequest( - __in NDIS_HANDLE MiniportAdapter, - __in PVOID RequestId // PVOID is of actual type PNDIS_OID_REQUEST - ) - -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapter; - PMBB_REQUEST_MANAGER RequestManager = NULL; - PMBB_REQUEST_CONTEXT Request; - - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis] FAILED to reference RequestManager to cancel OID RequestId=0x%p", RequestId ); - return; - } - - if( (Request = MbbReqMgrGetRequestByOidRequestId( RequestManager, RequestId )) != NULL ) - { - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Received cancel for OID RequestId=0x%p. Submitting cancel to FSM.", Request->RequestId, RequestId ); - - MbbReqMgrQueueEvent( - RequestManager, - Request, - MbbRequestEventCancel, - NULL, - 0 - ); - MbbReqMgrDerefRequest( Request ); - } - else - { - TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to find request with OID RequestId=0x%p for cancellation", RequestId ); - } - MbbReqMgrDeref( RequestManager ); -} - -// -// RESPONSE HANDLING -// - -/*++ - RequestManager->FragmentBuffer is a shared buffer used - to retrieve response fragments. Even if there are multiple - interrupts on the interrupt pipe there will be only one - request active doing a GET_ENCAPSULATED_RESPONSE. - Hence access to the buffer is synchronized. - The synchronisation is guaranteed by MbbReqMgrCompleteRequest( ) - since it queues the SendComplete for the current active - request first before queuing the Start for the next request. - - MbbNdisGetResponseFragment( ) uses the same buffer for reading - each fragment. - - MbbNdisParseCommandResponse( ) reassembles the fragments in - per request response buffer. If the per request pre-allocated - response buffer is not sufficient, re-allocation is attempted. - - MbbNdisParseIndicateStatus( ) reassembles the fragments in - the shared RequestManager->ResponseBuffer. ---*/ - - -VOID -MbbNdisIndicateStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - PMBB_OID_HANDLER_ENTRY OidHandler; - - // - // If the request already has a Oid handler use that. - // Else if this request is doing a status indication it will not have a OidHandler. - // In status indication case - // - if( (OidHandler = Request->OidHandler) == NULL && - (OidHandler = MbbNdisGetOidHandlerByCommand( &(Request->HandlerContext.Response.Command) )) == NULL ) - { - if( !MbbUtilIsNativeMbnService( &Request->HandlerContext.Response.Command.ServiceId ) ) - { - OidHandler = MbbNdisGetOidHandler( OID_WWAN_DEVICE_SERVICE_COMMAND ); - } - } - if( OidHandler == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to find response Handler for ServiceId=%!GUID! Cid=%02d", - Request->RequestId, - &Request->HandlerContext.Response.Command.ServiceId, - Request->HandlerContext.Response.Command.CommandId - ); - NdisStatus = NDIS_STATUS_FAILURE; - } - // - // No NDIS specific work needed. - // Call the common handler to do cleanup. - // - MbbUtilCommonCIDResponse( - Request, - NdisStatus, - MbbStatus, - InBuffer, - InBufferSize, - OidHandler - ); -} - - -NDIS_STATUS -MbbNdisReassembleResponseFragment( - __in_bcount(FragmentLength) PUCHAR FragmentBuffer, - __in ULONG FragmentLength, - __in PMBB_REASSEMBLE_CONTEXT ReassembleContext, - __in BOOLEAN DoReassemble, - __in PMBB_REQUEST_MANAGER RequestManager, - __in GUID ActivityId - ) -/*++ - Return Value - STATUS_SUCCESS - All fragments of the message was successfully reassembled. - STATUS_PENDING - This fragment was successfully reassembled but there are more. - Other - The fragment could not be reassembled. ---*/ -{ - ULONG TransactionId; - ULONG PayloadLength; - ULONG PayloadOffset = 0; - PCHAR ReassembleBuffer = NULL; - ULONG ReassembleBufferOffset = 0; - ULONG ReassembleDataLength = 0; - ULONG FragmentCount; - ULONG CurrentFragment; - NTSTATUS NtStatus = STATUS_SUCCESS; - MBB_COMMAND Command = {0}; - MBB_STATUS MbbStatus = {0}; - PMBB_INDICATE_STATUS_HEADER IndicateStatusHeader; - PMBB_COMMAND_DONE_HEADER CommandDoneHeader; - PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader = (PMBB_COMMAND_FRAGMENT_HEADER)FragmentBuffer; - - - PayloadLength = MessageFragmentHeader->MessageHeader.MessageLength; - TransactionId = MessageFragmentHeader->MessageHeader.MessageTransactionId; - FragmentCount = MessageFragmentHeader->FragmentHeader.TotalFragments; - CurrentFragment = MessageFragmentHeader->FragmentHeader.CurrentFragment; - - do - { - // - // Get extra information from the first fragment - // - if( CurrentFragment == 0 ) - { - if( MessageFragmentHeader->MessageHeader.MessageType == MBB_MESSAGE_TYPE_COMMAND_DONE ) - { - if( FragmentLength < sizeof(MBB_COMMAND_DONE_HEADER) ) - { - return STATUS_NDIS_INVALID_LENGTH; - } - CommandDoneHeader = (PMBB_COMMAND_DONE_HEADER)FragmentBuffer; - - Command.CommandId = CommandDoneHeader->Command.CommandId; - MBB_UUID_TO_HOST( - &Command.ServiceId, - &CommandDoneHeader->Command.ServiceId - ); - MbbStatus = CommandDoneHeader->MbbStatus; - PayloadOffset = sizeof(MBB_COMMAND_DONE_HEADER); - ReassembleDataLength = CommandDoneHeader->InformationBufferLength; - } - else if( MessageFragmentHeader->MessageHeader.MessageType == MBB_MESSAGE_TYPE_INDICATE_STATUS ) - { - if( FragmentLength < sizeof(MBB_INDICATE_STATUS_HEADER) ) - { - return STATUS_NDIS_INVALID_LENGTH; - } - IndicateStatusHeader = (PMBB_INDICATE_STATUS_HEADER)FragmentBuffer; - - Command.CommandId = IndicateStatusHeader->Command.CommandId; - MBB_UUID_TO_HOST( - &Command.ServiceId, - &IndicateStatusHeader->Command.ServiceId - ); - MbbStatus = MBB_STATUS_SUCCESS; - PayloadOffset = sizeof(MBB_INDICATE_STATUS_HEADER); - ReassembleDataLength = IndicateStatusHeader->InformationBufferLength; - } - else - { - NtStatus = STATUS_NDIS_INVALID_DATA; - } - - if( ReassembleDataLength > ReassembleContext->BufferLength ) - { - NtStatus = STATUS_BUFFER_OVERFLOW; - break; - } - // - // Cache the info in the reassemble context for later use. - // - if( DoReassemble ) - { - ReassembleBuffer = ReassembleContext->Buffer; - ReassembleBufferOffset = 0; - } - ReassembleContext->MbbStatus = MbbStatus; - ReassembleContext->DataLength = ReassembleDataLength; - } - // - // For subsequent fragments read savved state from the reassemble context - // - else - { - Command = ReassembleContext->Command; - PayloadOffset = sizeof(MBB_COMMAND_FRAGMENT_HEADER); - - if( DoReassemble ) - { - ReassembleBuffer = ReassembleContext->Buffer; - ReassembleDataLength = ReassembleContext->DataLength; - ReassembleBufferOffset = ReassembleContext->BufferOffset; - } - } - - if( PayloadLength > FragmentLength || - PayloadLength < PayloadOffset ) - { - TraceError( WMBCLASS_OID, - "[MbbNdis][TID=0x%08x] INVALID MessageLength[Receieved=0x%08x < Expected=0x%08x] in Fragment=%02d/%02d", - TransactionId, - FragmentLength, - PayloadLength, - CurrentFragment, - FragmentCount - ); - MbbUtilSendMbimError( - TransactionId, - MBB_ERROR_LENGTH_MISMATCH, - RequestManager->AdapterContext, - ActivityId, - &Command - ); - NtStatus = STATUS_BUFFER_OVERFLOW; - break; - } - - if( DoReassemble ) - { - PayloadLength -= PayloadOffset; - - if( ( PayloadLength + ReassembleBufferOffset ) > ReassembleDataLength ) - { - TraceError( WMBCLASS_OID, - "[MbbNdis][TID=0x%08x] INVALID PayloadLength=0x%08x in Fragment=%02d/%02d. TRUNCATING Response.", - TransactionId, PayloadLength, CurrentFragment, FragmentCount - ); - } - TraceInfo( WMBCLASS_OID, - "[MbbNdis][TID=0x%08x] Received Fragment=%02d/%02d", - TransactionId, CurrentFragment, FragmentCount - ); - RtlCopyMemory( - ReassembleBuffer + ReassembleBufferOffset, - FragmentBuffer + PayloadOffset, - MIN( PayloadLength, (ReassembleDataLength-ReassembleBufferOffset) ) - ); - ReassembleBufferOffset += MIN( PayloadLength, (ReassembleDataLength-ReassembleBufferOffset) ); - - ReassembleContext->BufferOffset = ReassembleBufferOffset; - } - } - while( FALSE ); - - if( NtStatus == STATUS_SUCCESS ) - { - if( (CurrentFragment + 1) < FragmentCount ) - { - NtStatus = STATUS_PENDING; - } - } - // - // If there are more fragments to come arm the inter-fragment timer. - // Else set the final status in the reassemble context. - // - if( NtStatus != STATUS_PENDING ) - { - ReassembleContext->NdisStatus = NtStatus; - } - else - { - MbbReqMgrTimerArm( - RequestManager, - MbbTimerTypeFragment, - 0, - 0, - 0, - FALSE - ); - } - - return NtStatus; -} - -NDIS_STATUS -MbbNdisParseCommandResponse( - __in ULONG TransactionId, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - ULONG MessageFragmentLength; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PMBB_REQUEST_CONTEXT OriginalRequest = NULL; - PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; - PMBB_REASSEMBLE_CONTEXT ReassembleContext = NULL; - PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader; - - do - { - MessageFragmentLength = Request->HandlerContext.Response.FragmentLength; - MessageFragmentHeader = (PMBB_COMMAND_FRAGMENT_HEADER)(Request->HandlerContext.Response.FragmentBuffer); - // - // If the context cannot be acquired that means that another transaction - // is using the context. Indicate an out of order fragment to the device - // and hope it sends the right fragment soon. If not the inter-fragment - // timeout will clean things up. - // - // If fragment is in order but there isnt a request reassemble the - // fragment and then drop it. Reassembly is done to detect errors. - // - if( (ReassembleContext = MbbReqMgrAcquireSharedReassembleContext( - RequestManager, - MessageFragmentHeader, - MessageFragmentLength, - Request->ActivityId - )) != NULL ) - { - GUID ActivityId = {0}; - - OriginalRequest = MbbReqMgrGetRequestByTransactionId( - RequestManager, - TransactionId - ); - - // if there is an OriginalRequest corresponding to this response received - // then we should use the original request activity id so that the original - // request and its response can be traced end to end. If there is no - // OriginalRequest then we will use the activity Id of the current request - - ActivityId = (OriginalRequest) ? OriginalRequest->ActivityId : Request->ActivityId; - - NdisStatus = MbbNdisReassembleResponseFragment( - (PUCHAR)MessageFragmentHeader, - MessageFragmentLength, - ReassembleContext, - OriginalRequest? TRUE: FALSE, // Reassemble - RequestManager, - ActivityId - ); - } - else - { - NdisStatus = NDIS_STATUS_INVALID_DATA; - } - } - while( FALSE ); - - if( NdisStatus != NDIS_STATUS_PENDING ) - { - if( OriginalRequest != NULL ) - { - // - // Copy the common reassemble context used by the request manager - // in to the per request reassemble context. - // - OriginalRequest->HandlerContext.Response = *ReassembleContext; - - MbbReqMgrQueueEvent( - RequestManager, - OriginalRequest, - MbbRequestEventResponseReceived, - OriginalRequest->HandlerContext.Response.Buffer, - OriginalRequest->HandlerContext.Response.DataLength - ); - } - - if( ReassembleContext != NULL ) - { - MbbReqMgrReleaseSharedReassembleContext( RequestManager ); - } - } - - if( OriginalRequest ) - { - MbbReqMgrDerefRequest( OriginalRequest ); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisParseStatusIndication( - __in ULONG TransactionId, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - ULONG MessageFragmentLength; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - MBB_COMMAND Command; - PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; - PMBB_REASSEMBLE_CONTEXT ReassembleContext; - PMBB_COMMAND_FRAGMENT_HEADER MessageFragmentHeader; - - do - { - MessageFragmentLength = Request->HandlerContext.Response.FragmentLength; - MessageFragmentHeader = (PMBB_COMMAND_FRAGMENT_HEADER)(Request->HandlerContext.Response.FragmentBuffer); - // - // If the context cannot be acquired that means that another transaction - // is using the context. Indicate an out of order fragment to the device - // and hope it sends the right fragment soon. If not the inter-fragment - // timeout will clean things up. - // - if( (ReassembleContext = MbbReqMgrAcquireSharedReassembleContext( - RequestManager, - MessageFragmentHeader, - MessageFragmentLength, - Request->ActivityId - )) != NULL ) - { - NdisStatus = MbbNdisReassembleResponseFragment( - (PUCHAR)MessageFragmentHeader, - MessageFragmentLength, - ReassembleContext, - TRUE, // Reassemble - RequestManager, - Request->ActivityId - ); - } - else - { - NdisStatus = NDIS_STATUS_INVALID_DATA; - } - } - while( FALSE ); - - if( NdisStatus == NDIS_STATUS_SUCCESS ) - { - // - // Copy the common reassemble context used by the request manager - // in to the per request reassemble context. - // - Request->HandlerContext.Response = RequestManager->Fragmentation.Reassemble; - // - // Track that this is an indication and not a response. - // - MbbReqMgrSetUnsolicitedIndication( Request ); - - MbbReqMgrQueueEvent( - RequestManager, - Request, - MbbRequestEventResponseReceived, - Request->HandlerContext.Response.Buffer, - Request->HandlerContext.Response.DataLength - ); - } - - if( NdisStatus != NDIS_STATUS_PENDING ) - { - if( ReassembleContext != NULL ) - { - MbbReqMgrReleaseSharedReassembleContext( RequestManager ); - } - } - - // - // Tell the caller whether to keep or destroy the request - // - if( NdisStatus == NDIS_STATUS_SUCCESS ) - NdisStatus = NDIS_STATUS_PENDING; - else if( NdisStatus == NDIS_STATUS_PENDING ) - NdisStatus = NDIS_STATUS_SUCCESS; - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisParseFunctionError( - __in ULONG TransactionId, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - PMBB_ERROR_MESSAGE ErrorMessage = (PMBB_ERROR_MESSAGE)(Request->HandlerContext.Response.FragmentBuffer); -// ULONG ErrorMessageLength = Request->HandlerContext.Response.FragmentLength; - PMBB_REQUEST_CONTEXT OriginalRequest = NULL; - MBB_COMMAND Command = {0}; - PCHAR CommandName; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ); - - do - { - if( (OriginalRequest = MbbReqMgrGetRequestByTransactionId( - Request->RequestManager, - TransactionId - )) != NULL ) - { - TraceError( WMBCLASS_OID, "[MBIM_ERR][ReqID=0x%04x][TID=0x%08x] Received %!MbbError!. Cancelling request.", - OriginalRequest->RequestId, - TransactionId, - ErrorMessage->ErrorCode - ); - // - // MBB_UUID_TO_HOST( ) is not needed here since - // the command is being copied from the original - // request where it is already in the host format. - // - RtlCopyMemory( - &Command, - &OriginalRequest->HandlerContext.Command.Command, - sizeof(MBB_COMMAND) - ); - MbbReqMgrQueueEvent( - OriginalRequest->RequestManager, - OriginalRequest, - MbbRequestEventCancel, - (PVOID)(NDIS_STATUS_REQUEST_ABORTED), - 0 - ); - MbbReqMgrDerefRequest( OriginalRequest ); - } - else - { - TraceError( WMBCLASS_OID, "[MBIM_ERR][ReqID=0x%04x][TID=0x%08x] Received %!MbbError! for non-existing request", - Request->RequestId, - TransactionId, - ErrorMessage->ErrorCode - ); - } - - CommandName = MbbUtilGetCommandString( &Command ); - - MbbWriteEvent( - &MBIM_FUNCTION_ERROR_EVENT, - OriginalRequest ? &(OriginalRequest->ActivityId) : NULL, - NULL, - 6, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &ErrorMessage->ErrorCode, - sizeof(MBB_ERROR), - &ErrorMessage->MessageHeader.MessageTransactionId, - sizeof(ULONG), - &Command.ServiceId, - sizeof(GUID), - &Command.CommandId, - sizeof(ULONG), - CommandName, - strlen(CommandName) + 1 - ); - } - while( FALSE ); - - return NDIS_STATUS_SUCCESS; -} - -VOID -MbbNdisParseResponseFragment( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - ULONG RequestId = Request->RequestId; - BOOLEAN DestroyRequest = TRUE; - PVOID MessageBuffer; - ULONG MessageLength; - PMBB_MESSAGE_HEADER MessageHeader; - - do - { - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] GetEncapsulatedResponse FAILED, NdisStatus=%!STATUS!", - RequestId, - NdisStatus - ); - break; - } - - MessageBuffer = Request->HandlerContext.Response.FragmentBuffer; - MessageLength = Request->HandlerContext.Response.FragmentLength; - MessageHeader = (PMBB_MESSAGE_HEADER)MessageBuffer; - - if( MessageLength < sizeof(MBB_MESSAGE_HEADER) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT MessageBuffer Expected=%d > Received=%d", - RequestId, - sizeof(MBB_MESSAGE_HEADER), - MessageLength - ); - break; - } - - switch( MessageHeader->MessageType ) - { - case MBB_MESSAGE_TYPE_COMMAND_DONE: - { - if( MessageLength >= sizeof(MBB_COMMAND_FRAGMENT_HEADER) ) - { - MbbNdisParseCommandResponse( MessageHeader->MessageTransactionId, Request ); - } - else - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x][TID=0x%08x] INSUFFICIENT MessageBuffer for %!MbbMsgType! Expected=%d > Received=%d", - RequestId, - MessageHeader->MessageTransactionId, - MessageHeader->MessageType, - sizeof(MBB_COMMAND_FRAGMENT_HEADER), - MessageLength - ); - } - } - break; - - case MBB_MESSAGE_TYPE_INDICATE_STATUS: - { - if( MessageLength >= sizeof(MBB_COMMAND_FRAGMENT_HEADER) ) - { - if( MbbNdisParseStatusIndication( MessageHeader->MessageTransactionId, Request ) == NDIS_STATUS_PENDING ) - { - DestroyRequest = FALSE; - } - } - else - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x][TID=0x%08x] INSUFFICIENT MessageBuffer for %!MbbMsgType! Expected=%d > Received=%d", - RequestId, - MessageHeader->MessageTransactionId, - MessageHeader->MessageType, - sizeof(MBB_COMMAND_FRAGMENT_HEADER), - MessageLength - ); - } - } - break; - - case MBB_MESSAGE_TYPE_FUNCTION_ERROR: - { - if( MessageLength >= sizeof(MBB_ERROR_MESSAGE) && MessageHeader->MessageTransactionId > 0) - { - if( MbbNdisParseFunctionError( MessageHeader->MessageTransactionId, Request ) == NDIS_STATUS_PENDING ) - { - DestroyRequest = FALSE; - } - } - else if(MessageLength < sizeof(MBB_ERROR_MESSAGE)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x][TID=0x%08x] INSUFFICIENT MessageBuffer for %!MbbMsgType! Expected=%d > Received=%d", - RequestId, - MessageHeader->MessageTransactionId, - MessageHeader->MessageType, - sizeof(MBB_ERROR_MESSAGE), - MessageLength - ); - break; - } - else - { - TraceWarn(WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x][TID=0x%08x] MessageTransactionId is 0 for %!MbbMsgType! and ErrorCode %!MbbError!", - RequestId, - MessageHeader->MessageTransactionId, - MessageHeader->MessageType, - ((PMBB_ERROR_MESSAGE)MessageHeader)->ErrorCode - ); - break; - } - } - break; - - case MBB_MESSAGE_TYPE_OPEN_DONE: __fallthrough; - case MBB_MESSAGE_TYPE_CLOSE_DONE: __fallthrough; - default: - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x][TID=0x%08x] UNEXPECTED MessageType=%!MbbMsgType!", - RequestId, - MessageHeader->MessageTransactionId, - MessageHeader->MessageType - ); - } - break; - } - } - while( FALSE ); - - if( DestroyRequest == TRUE ) - { - MbbReqMgrDestroyRequest( Request->RequestManager, Request ); - } -} - -VOID -MbbNdisProcessResponseFragementWorker( - __in PVOID Context1, - __in PVOID Context2, - __in PVOID Context3, - __in PVOID Context4 - ) -{ - PMBB_REQUEST_CONTEXT Request = (PMBB_REQUEST_CONTEXT)Context1; - PMBB_REQUEST_MANAGER RequestManager = Request->RequestManager; - - MbbReqMgrQueueEvent( - RequestManager, - Request, - MbbRequestEventSendComplete, - (PVOID)(Request->HandlerContext.Response.NdisStatus), - 0 - ); - MbbReqMgrDerefRequest( Request ); -} - -VOID -MbbNdisGetResponseFragementComplete( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in MBB_REQUEST_HANDLE RequestHandle, - __in NTSTATUS Status, - __in ULONG_PTR ReceivedLength - ) -{ - NDIS_STATUS NdisStatus; - PMBB_REQUEST_CONTEXT Request; - PMBB_REQUEST_MANAGER RequestManager; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; - - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[MbbNdis][ReqId=0x%04x] FAILED to reference RequestManager to process request fragment", (ULONG)RequestHandle ); - return; - } - if( (Request = MbbReqMgrGetRequestById( RequestManager, (ULONG)RequestHandle )) != NULL ) - { - Request->HandlerContext.Response.NdisStatus = Status; - Request->HandlerContext.Response.FragmentLength = (ULONG)ReceivedLength; - // - // Queue a work item so that the processing happens at PASSIVE_LEVEL. - // On the response receive path string routines are called which require PASSIVE_LEVEL. - // - if( (NdisStatus = MbbWorkMgrQueueWorkItem( - RequestManager->WorkItemManagerHandle, - Request, - NULL, - NULL, - NULL, - MbbNdisProcessResponseFragementWorker - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[MbbNdis][ReqId=0x%04x] FAILED to queue work item to process request", Request->RequestId ); - } - } - else - { - TraceError( WMBCLASS_REQUEST_MANAGER, "[MbbNdis] UNABLE to find request, dropping fragment. Handle=%p", RequestHandle ); - } - MbbReqMgrDeref( RequestManager ); -} - -NDIS_STATUS -MbbNdisGetResponseFragment( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - ULONG RequestId; - NTSTATUS NtStatus; - NDIS_STATUS NdisStatus; - - RequestId = Request->RequestId; - - NtStatus = MbbBusReceiveMessageFragment( - MbbNdisGetBusHandle( MbbReqMgrGetAdapterHandle( Request ) ), - (MBB_REQUEST_HANDLE)RequestId, - Request->HandlerContext.Response.FragmentBuffer, - Request->HandlerContext.Response.FragmentBufferLength, - &(Request->ActivityId), - MbbNdisGetResponseFragementComplete - ); - if( NtStatus == STATUS_PENDING ) - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Waiting to retrieve response fragment", RequestId ); - return NDIS_STATUS_PENDING; - } - else - { - ASSERT( NtStatus != STATUS_SUCCESS ); - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to retrieve response fragment with status=%!status!", RequestId, NtStatus ); - return NDIS_STATUS_FAILURE; - } -} - -VOID -MbbNdisResponseFragmentAvailable( - __in MBB_PROTOCOL_HANDLE ProtocolHandle - ) -{ - ULONG RequestId; - NDIS_STATUS NdisStatus; - NTSTATUS NtStatus; - PMBB_REQUEST_CONTEXT Request; - PMBB_REQUEST_MANAGER RequestManager = NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to reference RequestManager for GetResponse" ); - break; - } - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis] FAILED to allocate RequestContext for GetResponse" ); - break; - } - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Created request to retrieve response.", Request->RequestId ); - - Request->HandlerContext.Response.FragmentBuffer = Request->RequestManager->Fragmentation.Reassemble.FragmentBuffer; - Request->HandlerContext.Response.FragmentBufferLength = Request->RequestManager->Fragmentation.Reassemble.FragmentBufferLength; - - // Get an activity id to associate with this request - NtStatus = MbbEventActivityIdCtl(&(Request->ActivityId)); - - if(!NT_SUCCESS(NtStatus)) - { - // Clear out the activity Id of the request - NdisZeroMemory(&(Request->ActivityId),sizeof(GUID)); - TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Failed to create an activity Id for request to retrieve response.NtStatus = %d.", Request->RequestId, NtStatus ); - } - else - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Created an activity id %!GUID! for the request",Request->RequestId, &(Request->ActivityId)); - } - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, - MbbNdisGetResponseFragment, - MbbNdisParseResponseFragment, - MbbNdisIndicateStatus - ); - if( NdisStatus != NDIS_STATUS_PENDING ) - { - MbbReqMgrDestroyRequest( - RequestManager, - Request - ); - } - } - while( FALSE ); - - if( RequestManager != NULL ) - MbbReqMgrDeref( RequestManager ); -} - - -// -// Get Handlers -// - - -NDIS_STATUS -MbbNdisGetMediaSupported( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PULONG MediaSupported = (PULONG)OutBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - - *MediaSupported = NdisMediumWirelessWan; - *OutBufferSize = sizeof(ULONG); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetInterruptModeration( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PNDIS_INTERRUPT_MODERATION_PARAMETERS InterruptModeration = (PNDIS_INTERRUPT_MODERATION_PARAMETERS)OutBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS) ); - - InterruptModeration->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - InterruptModeration->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1; - InterruptModeration->Header.Size = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); - InterruptModeration->Flags = NDIS_INTERRUPT_MODERATION_CHANGE_NEEDS_RESET; - InterruptModeration->InterruptModeration= NdisInterruptModerationNotSupported; - - *OutBufferSize = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetVendorDriverVersion( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PULONG DriverVersion = (PULONG)OutBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - - *DriverVersion = (WWAN_MAJOR_VERSION << 16) | (WWAN_MINOR_VERSION & 0xffff); - *OutBufferSize = sizeof(ULONG); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetVendorId( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PULONG VendorId = (PULONG)OutBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - - // - // no mac address - // - *VendorId = 0xFFFFFF; - *OutBufferSize = sizeof(ULONG); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetVendorDescription( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; - NDIS_STATUS Status; - ULONG SourceLength=0; - - Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - // - // make sure the buffer is big enough to hold the string and a null since the counted string - // might not have null - // - SourceLength=(ULONG)Adapter->FriendlyName.Length + 1; - - if (*OutBufferSize >= SourceLength ) - { - RtlZeroMemory(OutBuffer, SourceLength); - RtlCopyMemory(OutBuffer, Adapter->FriendlyName.Buffer, Adapter->FriendlyName.Length); - - Status = NDIS_STATUS_SUCCESS; - } - else - { - Status = NDIS_STATUS_BUFFER_TOO_SHORT; - } - - *OutBufferSize = SourceLength; - - return Status; -} - -NDIS_STATUS -MbbNdisGetCurrentLookahead( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PULONG Lookahead = (PULONG)OutBuffer; - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - // - // Todo: Return a value. - // - *Lookahead = 0; - *OutBufferSize = sizeof(ULONG); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetReceiveBlockSize( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; - PULONG BlockSize=(PULONG)OutBuffer; - - Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - - if (Adapter->BusParams.IsErrataDevice) - { - *BlockSize=Adapter->BusParams.MTU; - } else { - *BlockSize=Adapter->BusParams.MaxSegmentSize; - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetReceiveBufferSpace( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; - PULONG BufferSpace=(PULONG)OutBuffer; - - Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - - *BufferSpace=Adapter->BusParams.MaxOutNtb; - - return NDIS_STATUS_SUCCESS; - -} - -NDIS_STATUS -MbbNdisGetTransmitBlockSize( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; - PULONG BlockSize=(PULONG)OutBuffer; - - Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - - if (Adapter->BusParams.IsErrataDevice) - { - *BlockSize=Adapter->BusParams.MTU; - } else { - *BlockSize=Adapter->BusParams.MaxSegmentSize; - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetTransmitBufferSpace( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; - PULONG BufferSpace=(PULONG)OutBuffer; - - Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - - *BufferSpace=Adapter->BusParams.MaxOutNtb; - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetMaximumTotalSize( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=NULL; - PULONG BlockSize=(PULONG)OutBuffer; - - Adapter=(PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONG) ); - - if (Adapter->BusParams.IsErrataDevice) - { - *BlockSize=Adapter->BusParams.MTU; - } else { - *BlockSize=Adapter->BusParams.MaxSegmentSize; - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetFramesReceived( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PULONGLONG ReceivedFrames = (PULONGLONG)(OutBuffer); - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONGLONG) ); - - *ReceivedFrames = Adapter->GenRcvFramesOk; - *OutBufferSize = sizeof(ULONGLONG); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetFramesTransmitted( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PULONGLONG TransmittedFrames = (PULONGLONG)(OutBuffer); - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(ULONGLONG) ); - - *TransmittedFrames = Adapter->GenXmitFramesOk; - *OutBufferSize = sizeof(ULONGLONG); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetDriverCaps( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); - - PNDIS_WWAN_DRIVER_CAPS DriverCaps = (PNDIS_WWAN_DRIVER_CAPS)OutBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(NDIS_WWAN_DRIVER_CAPS) ); - - DriverCaps->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - DriverCaps->Header.Revision = NDIS_WWAN_DRIVER_CAPS_REVISION_1 ; - DriverCaps->Header.Size = sizeof(NDIS_WWAN_DRIVER_CAPS); - DriverCaps->DriverCaps.ulMajorVersion = WWAN_MAJOR_VERSION; - DriverCaps->DriverCaps.ulMinorVersion = WWAN_MINOR_VERSION; - DriverCaps->DriverCaps.ulDriverCaps = WWAN_DRIVER_CAPS_NONE; - - if (MbbBusIsUde(Adapter->BusHandle)) - { - DriverCaps->DriverCaps.ulDriverCaps = WWAN_DRIVER_CAPS_UDE; - } - *OutBufferSize = sizeof(NDIS_WWAN_DRIVER_CAPS); - return NDIS_STATUS_SUCCESS; -} - - -NDIS_STATUS -MbbNdisGetConnectState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); - PMBB_CONTEXT_STATE MbbGetContextState = NULL; - PMBB_PORT Port = NULL; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - UNREFERENCED_PARAMETER(InBuffer); - UNREFERENCED_PARAMETER(InBufferSize); - - if( (MbbGetContextState = (PMBB_CONTEXT_STATE) ALLOCATE_NONPAGED_POOL( sizeof(MBB_CONTEXT_STATE) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbGetContextState; - - Port = MbbWwanTranslatePortNumberToPort( - Adapter, - Request->OidContext.OidRequest->PortNumber); - - if(Port!= NULL) - { - ULONG MaxActivatedContexts = 0; - ULONG SessionId = MBB_INVALID_SESSION_ID; - - MbbAdapterPortsLock(Adapter); - MaxActivatedContexts = Adapter->MaxActivatedContexts; - MbbAdapterPortsUnlock(Adapter); - - RtlZeroMemory(MbbGetContextState, sizeof(MBB_CONTEXT_STATE)); - - SessionId = MbbWwanGetPortSessionId(Port); - - if(SessionId < MaxActivatedContexts) - { - MbbGetContextState->SessionId = SessionId; - - Status = MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR) MbbGetContextState, - sizeof(MBB_CONTEXT_STATE) - ); - } - else - { - // Fail this OID request because we cannot query the device with an invalid session ID. - // If we want to send a context deactivated indication instead of failure, we need to do it outside the - // context of this OID request because it may lead to deadlocks. Currently returning a failure here - // because it is equivalent and less complicated. Note that Wwansvc is not sending OID_WWAN_CONNECT - // query for disconnected additional PDP contexts. The only case when this OID request may come is for - // a disconnected Port 0 context, which is not an issue because we are setting session ID as 0 for Port 0 - // always and will never end up here. - - Status = NDIS_STATUS_FAILURE; - - ASSERT(IS_ALLOCATED_PORT_NUMBER(Request->OidContext.OidRequest->PortNumber)); - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbNdisGetConnectState failed for a Port: [%lu]. Requested sessionId: [%lu] Status=%!status!", - Request->RequestId, - Request->OidContext.OidRequest->PortNumber, - SessionId, - Status - ); - } - - // Remove the reference added during find - Dereference(Port); - } - else - { - Status = NDIS_STATUS_INVALID_PORT; - } - - return Status; -} - -NDIS_STATUS -MbbIpGetConfiguration( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMBB_IP_ADDRESS_INFO MbbGetIpAddressInfo = NULL; - - UNREFERENCED_PARAMETER(InBuffer); - UNREFERENCED_PARAMETER(InBufferSize); - - if( (MbbGetIpAddressInfo = (PMBB_IP_ADDRESS_INFO) ALLOCATE_NONPAGED_POOL( sizeof(MBB_IP_ADDRESS_INFO) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbGetIpAddressInfo; - - RtlZeroMemory(MbbGetIpAddressInfo, sizeof(MBB_IP_ADDRESS_INFO)); - - MbbGetIpAddressInfo->SessionId = Request->HandlerContext.Parameters.IpAddress.SessionId; - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR) MbbGetIpAddressInfo, - sizeof(MBB_IP_ADDRESS_INFO) - ); -} - -NDIS_STATUS -MbbNdisGetVisibleProviders( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PNDIS_WWAN_GET_VISIBLE_PROVIDERS NdisGetVisibleProviders = (PNDIS_WWAN_GET_VISIBLE_PROVIDERS)InBuffer; - PMBB_GET_VISIBLE_PROVIDERS MbbGetVisible; - NDIS_STATUS NdisStatus; - - if( (MbbGetVisible = (PMBB_GET_VISIBLE_PROVIDERS) ALLOCATE_NONPAGED_POOL( sizeof(MBB_GET_VISIBLE_PROVIDERS) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbGetVisible; - - NdisStatus = MbbUtilWwanToMbbGetVisible( - &NdisGetVisibleProviders->VisibleProviders, - MbbGetVisible - ); - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to convert GET_VISIBLE_PROVIDER with status=%!status!", - Request->RequestId, - NdisStatus - ); - return NdisStatus; - } - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR) MbbGetVisible, - sizeof(MBB_GET_VISIBLE_PROVIDERS) - ); -} - - -NDIS_STATUS -MbbNdisSmsRead( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PNDIS_WWAN_SMS_READ NdisSmsRead = (PNDIS_WWAN_SMS_READ)InBuffer; - PMBB_SMS_READ MbbSmsRead; - - if( (MbbSmsRead = (PMBB_SMS_READ) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SMS_READ) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSmsRead; - - MbbUtilWwanToMbbSmsRead( - &NdisSmsRead->SmsRead, - MbbSmsRead - ); - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR) MbbSmsRead, - sizeof(MBB_SMS_READ) - ); -} - - -NDIS_STATUS -MbbNdisEnumerateDeviceServices( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG DeviceElementCount = 0; - ULONG NdisDeviceServicesInfoSize; - PNDIS_WWAN_SUPPORTED_DEVICE_SERVICES NdisDeviceServicesInfo = NULL; - PWWAN_DEVICE_SERVICE_ENTRY NdisDeviceServiceEntry = NULL; - ULONG devIndex = 0; - ULONG oidIndex = 0; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - NDIS_STATUS_INDICATION StatusIndication; - - // Return the device services list from the cached state - do - { - // - // For OID queries, get the device service list from the cache - // - Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )); - - // We start with allocating memory for all entries. We would only report the non-native list to the OS - DeviceElementCount = Adapter->DeviceServiceState.ServicesCount; - NdisDeviceServicesInfoSize = sizeof(NDIS_WWAN_SUPPORTED_DEVICE_SERVICES) + ( DeviceElementCount * sizeof(WWAN_DEVICE_SERVICE_ENTRY) ); - - if( (NdisDeviceServicesInfo = ALLOCATE_NONPAGED_POOL(NdisDeviceServicesInfoSize)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES, Source Service Count=%d", - Request->RequestId, - NdisDeviceServicesInfoSize, - DeviceElementCount - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - // Start populating the indication - NdisDeviceServicesInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceServicesInfo->Header.Size = SIZEOF_NDIS_WWAN_SUPPORTED_DEVICE_SERVICES_1; - NdisDeviceServicesInfo->Header.Revision = NDIS_WWAN_SUPPORTED_DEVICE_SERVICES_REVISION_1; - - // Always reporting success - NdisDeviceServicesInfo->uStatus = WWAN_STATUS_SUCCESS; - - NdisDeviceServicesInfo->DeviceServices.uMaxCommandDataSize = Adapter->BusParams.FragmentSize; - NdisDeviceServicesInfo->DeviceServices.uMaxSessionDataSize = MBB_FRAGMENATION_BULK_BUFFER_LENGTH; - NdisDeviceServicesInfo->DeviceServices.uMaxSessionCount = Adapter->DeviceServiceState.MaxDSSSessions; - - NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementType = WwanStructDeviceServiceEntry; - NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementCount = 0; - - // Populate the device service entries - NdisDeviceServiceEntry = (PWWAN_DEVICE_SERVICE_ENTRY)(((PUCHAR)NdisDeviceServicesInfo) - + sizeof(NDIS_WWAN_SUPPORTED_DEVICE_SERVICES)); - for (devIndex = 0; devIndex < DeviceElementCount; devIndex++) - { - if (!MbbUtilIsNativeMbnService(&(NdisDeviceServiceEntry[devIndex].DeviceServiceGuid))) - { - // Cache is already in host format - RtlCopyMemory(&(NdisDeviceServiceEntry[oidIndex].DeviceServiceGuid), - &(Adapter->DeviceServiceState.ServicesList[devIndex].DeviceServiceId), - sizeof(GUID) - ); - - NdisDeviceServiceEntry[oidIndex].SessionCapability = - Adapter->DeviceServiceState.ServicesList[devIndex].DSSCapability; - NdisDeviceServiceEntry[oidIndex].uMaxSessionInstances = - Adapter->DeviceServiceState.ServicesList[devIndex].MaxDSSInstances; - - NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementCount++; - oidIndex++; - } - } - - // - // Indicate ndis status - // - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES - ); - - StatusIndication.StatusBuffer = NdisDeviceServicesInfo; - // Use the actual size for - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SUPPORTED_DEVICE_SERVICES) + - ( NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementCount * sizeof(WWAN_DEVICE_SERVICE_ENTRY) ); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES with %d entries", - Request->RequestId, - NdisDeviceServicesInfo->DeviceServices.ListHeader.ElementCount - ); - - // - // a special status that the oid completion handler will fix-up and complete the request instead of waiting - // a response from the device that is not coming. - // - NdisStatus=MBB_STATUS_INDICATION_ALREADY_SENT ; - - NdisMIndicateStatusEx( - ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ))->MiniportAdapterHandle, - &StatusIndication - ); - - } - while( FALSE ); - - // - // Local Cleanup - // - if( NdisDeviceServicesInfo != NULL ) - { - FREE_POOL( NdisDeviceServicesInfo ); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisGetDeviceServiceCommand( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - return MbbUtilDeviceServiceCommand( - Request, - InBuffer, - InBufferSize - ); -} - - -NDIS_STATUS -MbbNdisEnumerateDeviceServiceCommands( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - // The input data comes in as OutBuffer - PNDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS pRequestBuffer = (PNDIS_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS )OutBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - NDIS_STATUS_INDICATION StatusIndication; - PMBB_DS deviceServiceEntry = NULL; - ULONG NdisCommandsInfoSize; - PNDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS NdisCommandsInfo = NULL; - - do - { - // - // For CID list queries, use the info from the cache - // - Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )); - - // Find the device service for this GUID - deviceServiceEntry = MbbUtilFindDeviceService(Adapter, - &pRequestBuffer->DeviceServiceGuid - ); - if (deviceServiceEntry == NULL) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Enumerate COMMANDs request for invalid device service ID", - Request->RequestId - ); - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - // Allocate the buffer for the indication - NdisCommandsInfoSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS) + - + ( deviceServiceEntry->CIDCount * sizeof(ULONG) ); - - if( (NdisCommandsInfo = ALLOCATE_NONPAGED_POOL(NdisCommandsInfoSize)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS, Source Service Count=%d", - Request->RequestId, - NdisCommandsInfoSize, - deviceServiceEntry->CIDCount - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - // Start populating the indication - NdisCommandsInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisCommandsInfo->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS_1; - NdisCommandsInfo->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS_REVISION_1; - - // Always reporting success - NdisCommandsInfo->uStatus = WWAN_STATUS_SUCCESS; - - RtlCopyMemory(&NdisCommandsInfo->SupportedCommands.DeviceServiceGuid, - &pRequestBuffer->DeviceServiceGuid, - sizeof(GUID) - ); - - NdisCommandsInfo->SupportedCommands.ListHeader.ElementCount = deviceServiceEntry->CIDCount; - NdisCommandsInfo->SupportedCommands.ListHeader.ElementType = WwanStructDeviceServiceCommandId; - - // Populate the command list - RtlCopyMemory(((PUCHAR)NdisCommandsInfo) + sizeof(NDIS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS), - deviceServiceEntry->CIDList, - deviceServiceEntry->CIDCount * sizeof(ULONG) - ); - - // - // Indicate ndis status - // - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS - ); - - StatusIndication.StatusBuffer = NdisCommandsInfo; - StatusIndication.StatusBufferSize = NdisCommandsInfoSize; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS with %d entries", - Request->RequestId, - NdisCommandsInfo->SupportedCommands.ListHeader.ElementCount - ); - - // - // a special status that the oid completion handler will fix-up and complete the request instead of waiting - // a response from the device that is not coming. - // - NdisStatus=MBB_STATUS_INDICATION_ALREADY_SENT ; - - NdisMIndicateStatusEx( - ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ))->MiniportAdapterHandle, - &StatusIndication - ); - - } - while( FALSE ); - - // - // Local Cleanup - // - if( NdisCommandsInfo != NULL ) - { - FREE_POOL( NdisCommandsInfo ); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisGetMultiCarrierDsCidList( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -/*++ - HACK - The input parameter is passed in the Request instead of the above parameters. - The hack is necessary since there is no good way to pass parameters to handlers from - an internal request. ---*/ -{ - MBB_COMMAND Command; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - - UNREFERENCED_PARAMETER(InBuffer); - UNREFERENCED_PARAMETER(InBufferSize); - UNREFERENCED_PARAMETER(OutBuffer); - UNREFERENCED_PARAMETER(OutBufferSize); - - do - { - Command = Request->OidHandler->ResponseCommand; - - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Command, - MBB_COMMAND_TYPE_QUERY, - (PUCHAR)&Request->HandlerContext.Parameters.DeviceCaps.CurrentQueriedDeviceService, - sizeof(UUID) - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to setup command message for MbbNdisGetMultiCarrierDsCidList with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to send message fragments for MbbNdisGetMultiCarrierDsCidList with status=%!status!", - Request->RequestId, NdisStatus ); - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisGetUiccFileStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PNDIS_WWAN_UICC_FILE_PATH NdisUiccFilePath = (PNDIS_WWAN_UICC_FILE_PATH)InBuffer; - PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; - NDIS_STATUS NdisStatus; - ULONG BufferSize = 0; - - NdisStatus = MbbUtilWwanToMbbUiccFilePath( - &NdisUiccFilePath->UiccFilePath, - &MbbUiccFilePath, - &BufferSize - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbUiccFilePath; - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR) MbbUiccFilePath, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisUiccReadBinary( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - return MbbUtilUiccAccessBinary( - Request, - InBuffer, - InBufferSize - ); -} - -NDIS_STATUS -MbbNdisUiccReadRecord( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - return MbbUtilUiccAccessRecord( - Request, - InBuffer, - InBufferSize - ); -} - -NDIS_STATUS -MbbNdisGetPinInfoEx( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - PNDIS_WWAN_PIN_APP NdisPinApp = (PNDIS_WWAN_PIN_APP)InBuffer; - PMBB_PIN_APP MbbPinApp = NULL; - NDIS_STATUS NdisStatus; - ULONG BufferSize = 0; - - NdisStatus = MbbUtilWwanToMbbPinApp( - &NdisPinApp->PinApp, - &MbbPinApp, - &BufferSize - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbPinApp; - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR)MbbPinApp, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisGetMbimVersion( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - - PNDIS_WWAN_MBIM_VERSION MbbMbimVersion = (PNDIS_WWAN_MBIM_VERSION)OutBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *OutBufferSize >= sizeof(NDIS_WWAN_MBIM_VERSION) ); - - MbbMbimVersion->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - MbbMbimVersion->Header.Revision = NDIS_WWAN_MBIM_VERSION_REVISION_1 ; - MbbMbimVersion->Header.Size = SIZEOF_NDIS_WWAN_MBIM_VERSION_1; - - Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request)); - - MbbMbimVersion->MbimVersion.MbimVersion = Adapter->BusParams.MbimVersion; - - *OutBufferSize = sizeof(NDIS_WWAN_MBIM_VERSION); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetSlotInfoStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - PNDIS_WWAN_GET_SLOT_INFO NdisGetSlotInfo = (PNDIS_WWAN_GET_SLOT_INFO)InBuffer; - PMBB_MS_SLOT_INFO_REQ MbbSlotInfoReq = NULL; - - MbbSlotInfoReq = (PMBB_MS_SLOT_INFO_REQ)(ALLOCATE_NONPAGED_POOL(sizeof(MBB_MS_SLOT_INFO_REQ))); - if (NULL == MbbSlotInfoReq) - { - return NDIS_STATUS_RESOURCES; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSlotInfoReq; - - RtlZeroMemory(MbbSlotInfoReq, sizeof(MBB_MS_SLOT_INFO_REQ)); - - MbbSlotInfoReq->SlotIndex = NdisGetSlotInfo->GetSlotInfo.SlotIndex; - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR)MbbSlotInfoReq, - sizeof(MBB_MS_SLOT_INFO_REQ) - ); -} - -NDIS_STATUS -MbbNdisGetAtr( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterLock(Adapter); - BOOL IsUiccLowLevelCapable = Adapter->AdapterFlags.IsUiccLowLevelCapable; - MbbAdapterUnlock(Adapter); - - if (!IsUiccLowLevelCapable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support UICC low level operations (GET_ATR)"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - return MbbUtilQueryAttributeWithParameter( - Request, - NULL, - 0 - ); -} - -NDIS_STATUS -MbbNdisGetUiccReset( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize, - _Out_writes_bytes_to_opt_(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - _Inout_ PULONG OutBufferSize -) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterLock(Adapter); - BOOL IsUiccLowLevelCapable = Adapter->AdapterFlags.IsUiccLowLevelCapable; - MbbAdapterUnlock(Adapter); - - if (!IsUiccLowLevelCapable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support UICC low level operations (GET_UICC_RESET)"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - return MbbUtilQueryAttributeWithParameter( - Request, - NULL, - 0 - ); -} - -NDIS_STATUS -MbbNdisGetProvisionedContextsV2( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterLock(Adapter); - BOOL IsProvisionedContextV2Capable = Adapter->AdapterFlags.IsProvisionedContextV2Capable; - MbbAdapterUnlock(Adapter); - - if (!IsProvisionedContextV2Capable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support ProvisionedContextsV2"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - return MbbUtilQueryAttributeWithParameter( - Request, - NULL, - 0 - ); -} - -NDIS_STATUS -MbbNdisGetPcoStatus( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - UNREFERENCED_PARAMETER(InBuffer); - UNREFERENCED_PARAMETER(InBufferSize); - - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - PMBB_PORT Port = NULL; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - MBB_MS_PCO_VALUE MbbPcoValue = { 0 }; - - MbbAdapterLock(Adapter); - BOOL IsPcoCapable = Adapter->AdapterFlags.IsPcoCapable; - MbbAdapterUnlock(Adapter); - - if (!IsPcoCapable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support PCO"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - Port = MbbWwanTranslatePortNumberToPort( - Adapter, - Request->OidContext.OidRequest->PortNumber); - - if (Port != NULL) - { - ULONG MaxActivatedContexts = 0; - ULONG SessionId = MBB_INVALID_SESSION_ID; - - MbbAdapterPortsLock(Adapter); - MaxActivatedContexts = Adapter->MaxActivatedContexts; - MbbAdapterPortsUnlock(Adapter); - - SessionId = MbbWwanGetPortSessionId(Port); - - if (SessionId < MaxActivatedContexts) - { - MbbPcoValue.SessionId = SessionId; - - Status = MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR)&MbbPcoValue, - sizeof(MBB_MS_PCO_VALUE) - ); - } - else - { - // Fail this OID request because we cannot query the device with an invalid session ID. - - Status = NDIS_STATUS_FAILURE; - - ASSERT(IS_ALLOCATED_PORT_NUMBER(Request->OidContext.OidRequest->PortNumber)); - - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbNdisGetPcoStatus failed for a Port: [%lu]. Requested sessionId: [%lu] Status=%!status!", - Request->RequestId, - Request->OidContext.OidRequest->PortNumber, - SessionId, - Status - ); - } - - // Remove the reference added during find - Dereference(Port); - } - else - { - Status = NDIS_STATUS_INVALID_PORT; - } - - return Status; -} - -NDIS_STATUS -MbbNdisGetSysCapsInfo( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterLock(Adapter); - BOOL IsMultiSIMCapable = Adapter->AdapterFlags.IsMultiSIMCapable; - MbbAdapterUnlock(Adapter); - - if (!IsMultiSIMCapable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support system caps"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - return MbbUtilQueryAttributeWithParameter( - Request, - NULL, - 0 - ); -} - -NDIS_STATUS -MbbNdisGetDeviceCapsEx( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterLock(Adapter); - BOOL IsDeviceCapsV2Capable = Adapter->AdapterFlags.IsDeviceCapsV2Capable; - MbbAdapterUnlock(Adapter); - - if (!IsDeviceCapsV2Capable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support system caps, so assume it doesn't support device caps extention either"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - return MbbUtilQueryAttributeWithParameter( - Request, - NULL, - 0 - ); -} - -NDIS_STATUS -MbbNdisGetBaseStationsInfo( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize, *OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize -) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterLock(Adapter); - BOOL IsBaseStationsInfoCapable = Adapter->AdapterFlags.IsBaseStationsInfoCapable; - MbbAdapterUnlock(Adapter); - - if (!IsBaseStationsInfoCapable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support base station information"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - PNDIS_WWAN_BASE_STATIONS_INFO_REQ NdisGetBaseStationsInfoRequest = (PNDIS_WWAN_BASE_STATIONS_INFO_REQ)InBuffer; - PWWAN_BASE_STATIONS_INFO_REQ WwanBaseStationsInfoRequest = &(NdisGetBaseStationsInfoRequest->BaseStationsInfoRequest); - PMBB_MS_BASE_STATIONS_INFO_REQ MbbBaseStationsInfoReq = NULL; - - MbbBaseStationsInfoReq = (PMBB_MS_BASE_STATIONS_INFO_REQ)(ALLOCATE_NONPAGED_POOL(sizeof(MBB_MS_BASE_STATIONS_INFO_REQ))); - - Request->HandlerContext.DataToFreeOnCompletion = MbbBaseStationsInfoReq; - - RtlZeroMemory(MbbBaseStationsInfoReq, sizeof(MBB_MS_BASE_STATIONS_INFO_REQ)); - - MbbBaseStationsInfoReq->MaxGSMCount = WwanBaseStationsInfoRequest->MaxGSMCount; - MbbBaseStationsInfoReq->MaxUMTSCount = WwanBaseStationsInfoRequest->MaxUMTSCount; - MbbBaseStationsInfoReq->MaxTDSCDMACount = WwanBaseStationsInfoRequest->MaxTDSCDMACount; - MbbBaseStationsInfoReq->MaxLTECount = WwanBaseStationsInfoRequest->MaxLTECount; - MbbBaseStationsInfoReq->MaxCDMACount = WwanBaseStationsInfoRequest->MaxCDMACount; - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR)MbbBaseStationsInfoReq, - sizeof(MBB_MS_BASE_STATIONS_INFO_REQ) - ); -} - -// -// Set Handlers -// - - -NDIS_STATUS -MbbNdisSetCurrentLookahead( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(ULONG) ); - // - // Todo: Record this value. - // - *InBufferSize = sizeof(ULONG); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSetInterruptModeration( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS) ); - - *InBufferSize = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSetRadioState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - MBB_RADIO_STATE* MbbRadioState; - PNDIS_WWAN_SET_RADIO_STATE NdisRadioState = (PNDIS_WWAN_SET_RADIO_STATE)InBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_RADIO_STATE) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_RADIO_STATE); - - if( (MbbRadioState = (MBB_RADIO_STATE*) ALLOCATE_NONPAGED_POOL( sizeof(MBB_RADIO_STATE) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbRadioState; - - // Save the setting so that when the request completes we know what - // action was performed - Request->HandlerContext.Parameters.RadioState.SetAction = NdisRadioState->RadioAction; - - MbbUtilWwanToMbbRadioState( - &NdisRadioState->RadioAction, - MbbRadioState - ); - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbRadioState, - sizeof(MBB_RADIO_STATE) - ); -} - -NDIS_STATUS -MbbNdisSetPinInfo( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMBB_PIN_ACTION MbbPinAction=NULL; - PNDIS_WWAN_SET_PIN NdisSetPin = (PNDIS_WWAN_SET_PIN)InBuffer; - NTSTATUS Status; - ULONG BufferSize=0; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PIN) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_PIN); - - - - Status=MbbUtilWwanToMbbPinAction( - &NdisSetPin->PinAction, - &MbbPinAction, - &BufferSize - ); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbPinAction; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbPinAction, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetPinInfoEx2( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMBB_PIN_ACTION_EX2 MbbPinAction=NULL; - PNDIS_WWAN_SET_PIN_EX2 NdisSetPin = (PNDIS_WWAN_SET_PIN_EX2)InBuffer; - NTSTATUS Status; - ULONG BufferSize=0; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PIN_EX2) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_PIN_EX2); - - - - Status=MbbUtilWwanToMbbPinActionEx2( - &NdisSetPin->PinAction, - &MbbPinAction, - &BufferSize - ); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbPinAction; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbPinAction, - BufferSize - ); -} - - -NDIS_STATUS -MbbNdisSetPreferredProviders( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - ULONG ElementIndex; - ULONG ElementCount; - ULONG ValidDataSize; - ULONGLONG MbbPreferredProvidersSize; - ULONGLONG NdisSetPreferredProvidersSize; - PWWAN_PROVIDER2 WwanProvider; - NDIS_STATUS NdisStatus; - PMBB_PROVIDER_LIST MbbPreferredProviders = NULL; - MBB_CELLULAR_CLASS MbbCellularClass; - PNDIS_WWAN_SET_PREFERRED_PROVIDERS NdisSetPreferredProviders = (PNDIS_WWAN_SET_PREFERRED_PROVIDERS)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); - BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PREFERRED_PROVIDERS) ); - do - { - // - // Verify input buffer - // - if( NdisSetPreferredProviders->PreferredListHeader.ElementType != WwanStructProvider2 ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] INVALID WWAN_LIST Expecting=%d Received=%d", - Request->RequestId, - WwanStructProvider2, - NdisSetPreferredProviders->PreferredListHeader.ElementType - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - ElementCount = NdisSetPreferredProviders->PreferredListHeader.ElementCount; - - NdisSetPreferredProvidersSize = sizeof(NDIS_WWAN_SET_PREFERRED_PROVIDERS) ; - - NdisSetPreferredProvidersSize += ((ULONGLONG)ElementCount) * sizeof(WWAN_PROVIDER2); - - if( *InBufferSize < NdisSetPreferredProvidersSize ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] INSUFFICIENT buffer size for NDIS_WWAN_SET_PREFERRED_PROVIDERS, Expecting=%d Received=%d, ProviderCount=%d", - Request->RequestId, - (ULONG)NdisSetPreferredProvidersSize, - *InBufferSize, - ElementCount - ); - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - // - // Query for the required size - // - WwanProvider = (PWWAN_PROVIDER2)(((PCHAR)NdisSetPreferredProviders) + RTL_SIZEOF_THROUGH_FIELD( NDIS_WWAN_SET_PREFERRED_PROVIDERS, PreferredListHeader )); - - MbbPreferredProvidersSize = FIELD_OFFSET(MBB_PROVIDER_LIST, Providers); - MbbPreferredProvidersSize += (ULONGLONG)ElementCount * sizeof(MBB_ARRAY_ELEMENT); - - for( ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex ++ ) - { - SIZE_T StringCbLength; - - MbbPreferredProvidersSize = ROUND_UP_COUNT( MbbPreferredProvidersSize, ALIGN_DWORD ); - MbbPreferredProvidersSize += sizeof(MBB_PROVIDER); - - if( (NdisStatus = RtlStringCbLengthW( - WwanProvider->Provider.ProviderId, - sizeof(WwanProvider->Provider.ProviderId), - &StringCbLength - )) != STATUS_SUCCESS ) - { - StringCbLength = sizeof(WwanProvider->Provider.ProviderId); - } - MbbPreferredProvidersSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); - - if( (NdisStatus = RtlStringCbLengthW( - WwanProvider->Provider.ProviderName, - sizeof(WwanProvider->Provider.ProviderName), - &StringCbLength - )) != STATUS_SUCCESS ) - { - StringCbLength = sizeof(WwanProvider->Provider.ProviderName); - } - MbbPreferredProvidersSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); - WwanProvider++; - } - // - // Allocate & setup Mbb buffer - // - if( MbbPreferredProvidersSize > ULONG_MAX || - (MbbPreferredProviders = ALLOCATE_NONPAGED_POOL( (ULONG)MbbPreferredProvidersSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate MBB_PROVIDER_LIST of Size=%d for ProviderCount=%d", - Request->RequestId, - (ULONG)MbbPreferredProvidersSize, - ElementCount - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbPreferredProviders; - // - // Convert from WWAN to MBB - // - if( IsMultiCarrierCapable == TRUE ) - MbbCellularClass = MbbCellularClassInvalid; - else - MbbCellularClass = MbbAdapterGetSupportedCellularClass( Adapter ); - - ValidDataSize = (ULONG)MbbPreferredProvidersSize; - - if( (NdisStatus = MbbUtilWwanToMbbProviderList( - &NdisSetPreferredProviders->PreferredListHeader, - IsMultiCarrierCapable, - MbbCellularClass, - MbbPreferredProviders, - &ValidDataSize - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to convert WWAN_PROVIDER_LIST to MBB_PROVIDER_LIST ", Request->RequestId ); - break; - } - // - // Send the data - // - NdisStatus = MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbPreferredProviders, - ValidDataSize - ); - if( NdisStatus == NDIS_STATUS_SUCCESS || - NdisStatus == NDIS_STATUS_PENDING ) - { - *InBufferSize = (ULONG)NdisSetPreferredProvidersSize; - } - } - while( FALSE ); - - return NdisStatus; -} - - -NDIS_STATUS -MbbNdisSetRegisterState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMBB_SET_REGISTER_STATE MbbSetRegisterState; - PNDIS_WWAN_SET_REGISTER_STATE NdisSetRegisterState = (PNDIS_WWAN_SET_REGISTER_STATE)InBuffer; - ULONG BufferSize=0; - NDIS_STATUS Status; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_REGISTER_STATE) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_REGISTER_STATE); - - - Status=MbbUtilWwanToMbbSetRegisterState( - &NdisSetRegisterState->SetRegisterState, - &MbbSetRegisterState, - &BufferSize - ); - - if (!NT_SUCCESS(Status)) - { - - return Status; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetRegisterState; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSetRegisterState, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetPacketService( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS NdisStatus; - PMBB_SET_PACKET_SERVICE MbbSetPacketService; - PNDIS_WWAN_SET_PACKET_SERVICE NdisSetPacketService = (PNDIS_WWAN_SET_PACKET_SERVICE)InBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PACKET_SERVICE) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_PACKET_SERVICE); - - if( (MbbSetPacketService = (PMBB_SET_PACKET_SERVICE) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SET_PACKET_SERVICE) )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate MBB_SET_PACKET_SERVICE", Request->RequestId ); - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSetPacketService; - - NdisStatus = MbbUtilWwanToMbbSetPacketService( - NdisSetPacketService->PacketServiceAction, - MbbSetPacketService - ); - if( NT_ERROR( NdisStatus ) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to convert WWAN_PACKET_SERVICE_ACTION, NdisStatus=%!STATUS!", Request->RequestId, NdisStatus ); - return NdisStatus; - } - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSetPacketService, - sizeof(MBB_SET_PACKET_SERVICE) - ); -} - -NDIS_STATUS -MbbNdisSetSignalState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMBB_SET_SIGNAL_INDICATION MbbSetSignalStateIndication; - PNDIS_WWAN_SET_SIGNAL_INDICATION NdisSetSignalStateIndication = (PNDIS_WWAN_SET_SIGNAL_INDICATION)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_SIGNAL_INDICATION); - - if( (MbbSetSignalStateIndication = (PMBB_SET_SIGNAL_INDICATION) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SET_SIGNAL_INDICATION) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSetSignalStateIndication; - - // - // Adjust signal state configuration if needed - // - Adapter = MbbReqMgrGetAdapterHandle( Request ); - - MbbUtilAdjustSignalStateConfigurationForDevice( - Adapter, - &NdisSetSignalStateIndication->SignalIndication - ); - - // - // Map to MBB values - // - MbbUtilWwanToMbbSetSignalStateIndication( - &NdisSetSignalStateIndication->SignalIndication, - MbbSetSignalStateIndication - ); - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSetSignalStateIndication, - sizeof(MBB_SET_SIGNAL_INDICATION) - ); -} - -NDIS_STATUS -MbbNdisSetConnectState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS NdisStatus; - PNDIS_WWAN_SET_CONTEXT_STATE NdisSetContextState = (PNDIS_WWAN_SET_CONTEXT_STATE)InBuffer; - PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); - NDIS_PORT_NUMBER PortNumber = OidRequest->PortNumber; - PMBB_PORT Port = NULL; - ULONG SessionId; - BOOLEAN PortSessionIdSet = FALSE; - - // Find the port corresponding to the port number - Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); - - if(!Port) - { - return NDIS_STATUS_INVALID_PORT; - } - - do - { - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_CONTEXT_STATE) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_CONTEXT_STATE); - // - // Cache values for later use - // - Adapter = MbbReqMgrGetAdapterHandle( Request ); - - if( NdisSetContextState->SetContextState.ActivationCommand == WwanActivationCommandActivate ) - { - // Set a session ID - NdisStatus = MbbWwanSetPortSessionId(Port); - - if(NdisStatus != NDIS_STATUS_SUCCESS) - { - PortSessionIdSet = FALSE; - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to obtain a session id for the connection", Request->RequestId); - break; - } - else - { - PortSessionIdSet = TRUE; - } - - Request->HandlerContext.Parameters.Connect.Activate = TRUE; - // - // Henceforth any context_state indication \ reponse coming from the device - // will be reported using this ConnectionId. The ConnectionId is valid till - // the time the context is not de-activated or the activation fails. - // - MbbWwanSetPortConnectionId( - Port, - NdisSetContextState->SetContextState.ConnectionId - ); - - } - else - if( NdisSetContextState->SetContextState.ActivationCommand == WwanActivationCommandDeactivate ) - { - ULONG ConnectionId = MbbWwanGetPortConnectionId(Port); - - // - // If the ConnectionId isnt activated then fail the request. - // - if( ConnectionId != NdisSetContextState->SetContextState.ConnectionId ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to de-activate invalid ConnectionId[Received=%d, Expected=%d]", - Request->RequestId, - NdisSetContextState->SetContextState.ConnectionId, - ConnectionId - ); - NdisStatus = WWAN_STATUS_CONTEXT_NOT_ACTIVATED; - break; - } - - // always assume that the session id is set for a valid deactivate context request - PortSessionIdSet = TRUE; - } - else - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] bad Command = %d", - Request->RequestId, - NdisSetContextState->SetContextState.ActivationCommand - ); - - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - SessionId = MbbWwanGetPortSessionId(Port); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] Processing set context request = %d for port number = %d with session id = %d", - Request->RequestId, - NdisSetContextState->SetContextState.ActivationCommand, - PortNumber, - SessionId - ); - - Request->HandlerContext.Parameters.Connect.SessionId = SessionId; - - NdisStatus = MbbUtilProcessSetConnectState(Request, &(NdisSetContextState->SetContextState), SessionId); - - if(NdisStatus != NDIS_STATUS_SUCCESS - && NdisStatus != NDIS_STATUS_PENDING) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbProcessSetConnectState failed with status=%!STATUS!",Request->RequestId, NdisStatus); - break; - } - } - while( FALSE ); - // - // If the ACTIVATION request was not successful then wipe out the connectionid. - // - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING && - NdisSetContextState->SetContextState.ActivationCommand == WwanActivationCommandActivate ) - { - MbbWwanSetPortConnectionId( - Port, - 0 - ); - - // Return the session id to the pool only when it was actually set for the port - MbbWwanResetPortSessionId( - Port, - PortSessionIdSet - ); - } - - //Remove the reference added during find - Dereference(Port); - - return NdisStatus; -} - - -NDIS_STATUS -MbbNdisGetStatistics( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - - PNDIS_STATISTICS_INFO Stats=(PNDIS_STATISTICS_INFO)OutBuffer; - - __analysis_assume( *OutBufferSize >= sizeof(NDIS_STATISTICS_INFO) ); - - *OutBufferSize = sizeof(*Stats); - - RtlCopyMemory(Stats, &Adapter->Stats, sizeof(*Stats)); - - Stats->Header.Type=NDIS_OBJECT_TYPE_DEFAULT; - Stats->Header.Revision=NDIS_STATISTICS_INFO_REVISION_1; - Stats->Header.Size=NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; - - Stats->SupportedStatistics = NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV | - NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | - NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV; - - - return STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisCreateMac( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; - PNDIS_OID_REQUEST oidRequest = Request->OidContext.OidRequest; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); - - UNREFERENCED_PARAMETER(InBuffer); - UNREFERENCED_PARAMETER(InBufferSize); - - OutBuffer = oidRequest->DATA.METHOD_INFORMATION.InformationBuffer; - - do - { - oidRequest->DATA.METHOD_INFORMATION.BytesWritten = 0; - oidRequest->DATA.METHOD_INFORMATION.BytesRead = 0; - oidRequest->DATA.METHOD_INFORMATION.BytesNeeded = 0; - - if (oidRequest->RequestType != NdisRequestMethod) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] Invalid request type %d for OID_WWAN_CREATE_MAC\n", - Request->RequestId, - oidRequest->RequestType - ); - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - ASSERT(oidRequest->DATA.METHOD_INFORMATION.OutputBufferLength >= sizeof(NDIS_WWAN_MAC_INFO)); - - // - // Since OID calls are serialized, we do not expect the NumberOfPorts to change - // while we are checking the following until this OID is completed. So we do not need - // to protect the NumberOfPorts in any way - // - if (Adapter->NumberOfPorts >= Adapter->MaxActivatedContexts) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] Number of existing ports exceed max supported. Failing new port creation\n", - Request->RequestId); - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - ndisStatus = MbbUtilWwanCreateMac(Request); - - if (ndisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbUtilWwanCreateMac failed. Status = 0x%08x\n", - Request->RequestId,ndisStatus); - break; - } - } while (FALSE); - - - *OutBufferSize = oidRequest->DATA.METHOD_INFORMATION.BytesWritten; - - return ndisStatus; -} - - - -NDIS_STATUS -MbbNdisSetPower( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) - -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - NDIS_STATUS Status; - PSTATE_CHANGE_EVENT StateChange=NULL; - - PULONG PowerState=(PULONG)InBuffer; - - TraceInfo( WMBCLASS_POWER, "SetPower D%d", *PowerState - NetDeviceStateD0); - - *InBufferSize=sizeof(*PowerState); - - - StateChange=AllocateStateChangeEvent(&Adapter->AdapterState); - - if (StateChange != NULL) - { - StateChange->EventType=STATE_CHANGE_TYPE_POWER; - StateChange->Context1=Adapter; - StateChange->Power.Request=Request; - StateChange->Power.NewPower=*PowerState; - - QueueStateChangeEvent(&Adapter->AdapterState,StateChange); - - return STATUS_PENDING; - - } - - return STATUS_INSUFFICIENT_RESOURCES; - -} - -NDIS_STATUS -MbbNdisSetHomeProvider( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - ULONG ValidDataSize; - ULONGLONG MbbHomeProviderSize; - ULONG NdisSetHomeProvidersSize; - NDIS_STATUS NdisStatus; - PMBB_PROVIDER MbbHomeProvider = NULL; - WWAN_PROVIDER2 HomeProvider; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); - BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); - PNDIS_WWAN_SET_HOME_PROVIDER NdisSetHomeProvider = (PNDIS_WWAN_SET_HOME_PROVIDER)InBuffer; - SIZE_T StringCbLength= 0; - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_HOME_PROVIDER) ); - do - { - // - // Verify input buffer - // - if( !IsMultiCarrierCapable) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] SetHome unsupported for non-Multicarrier", - Request->RequestId - ); - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - NdisSetHomeProvidersSize = sizeof(NDIS_WWAN_SET_HOME_PROVIDER); - - if( *InBufferSize < NdisSetHomeProvidersSize ) - { - TraceError( WMBCLASS_OID, - "[MbbNdis][ReqID=0x%04x] INSUFFICIENT buffer size for NDIS_WWAN_SET_HOME_PROVIDER, Expecting=%d Received=%d", - Request->RequestId, - (ULONG)NdisSetHomeProvidersSize, - *InBufferSize - ); - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - // - // Query for the required size - // - HomeProvider = NdisSetHomeProvider->HomeProvider; - - MbbHomeProviderSize = sizeof(MBB_PROVIDER); - - if( (NdisStatus = RtlStringCbLengthW( - HomeProvider.Provider.ProviderId, - sizeof(HomeProvider.Provider.ProviderId), - &StringCbLength - )) != STATUS_SUCCESS ) - { - StringCbLength = sizeof(HomeProvider.Provider.ProviderId); - } - - MbbHomeProviderSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); - - if( (NdisStatus = RtlStringCbLengthW( - HomeProvider.Provider.ProviderName, - sizeof(HomeProvider.Provider.ProviderName), - &StringCbLength - )) != STATUS_SUCCESS ) - { - StringCbLength = sizeof(HomeProvider.Provider.ProviderName); - } - MbbHomeProviderSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); - - // - // Allocate & setup Mbb buffer - // - if( MbbHomeProviderSize > ULONG_MAX || - (MbbHomeProvider = ALLOCATE_NONPAGED_POOL( (ULONG)MbbHomeProviderSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate MBB_PROVIDER_LIST of Size=%d", - Request->RequestId, - (ULONG)MbbHomeProviderSize - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbHomeProvider; - - - // - // Convert from WWAN to MBB - // - if( (MbbHomeProviderSize = MbbUtilWwanToMbbProvider2( - &HomeProvider, - (ULONG)MbbHomeProviderSize, - MbbHomeProvider - )) == 0 ) - { - TraceError( WMBCLASS_OID, "[Util] FAILED to convert WWAN_PROVIDER2 to MBB_PROVIDER"); - break; - } - - // - // Send the data - // - NdisStatus = MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbHomeProvider, - (ULONG)MbbHomeProviderSize - ); - if( NdisStatus == NDIS_STATUS_SUCCESS || - NdisStatus == NDIS_STATUS_PENDING ) - { - *InBufferSize = (ULONG)NdisSetHomeProvidersSize; - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisSetMulticarrierProviders( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - ULONG ElementIndex; - ULONG ElementCount; - ULONG ValidDataSize; - ULONGLONG MbbPreferredProvidersSize; - ULONGLONG NdisSetPreferredProvidersSize; - PWWAN_PROVIDER2 WwanProvider; - NDIS_STATUS NdisStatus; - PMBB_PROVIDER_LIST MbbPreferredProviders = NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); - BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); - - PNDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS NdisSetPreferredProviders = (PNDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS)InBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS) ); - do - { - // - // Verify input buffer - // - if( NdisSetPreferredProviders->PreferredListHeader.ElementType != WwanStructProvider2 ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] INVALID WWAN_LIST Expecting=%d Received=%d", - Request->RequestId, - WwanStructProvider2, - NdisSetPreferredProviders->PreferredListHeader.ElementType - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - ElementCount = NdisSetPreferredProviders->PreferredListHeader.ElementCount; - NdisSetPreferredProvidersSize = sizeof(NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS) + (((ULONGLONG)ElementCount) * sizeof(WWAN_PROVIDER2)); - - if( *InBufferSize < NdisSetPreferredProvidersSize ) - { - TraceError( WMBCLASS_OID, - "[MbbNdis][ReqID=0x%04x] INSUFFICIENT buffer size for NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS, Expecting=%d Received=%d, ProviderCount=%d", - Request->RequestId, - (ULONG)NdisSetPreferredProvidersSize, - *InBufferSize, - ElementCount - ); - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - // - // Query for the required size - // - WwanProvider = (PWWAN_PROVIDER2)(((PCHAR)NdisSetPreferredProviders) + - RTL_SIZEOF_THROUGH_FIELD( NDIS_WWAN_SET_PREFERRED_MULTICARRIER_PROVIDERS, PreferredListHeader )); - - MbbPreferredProvidersSize = FIELD_OFFSET(MBB_PROVIDER_LIST, Providers); - MbbPreferredProvidersSize += (ULONGLONG)ElementCount * sizeof(MBB_ARRAY_ELEMENT); - - for( ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex ++ ) - { - SIZE_T StringCbLength; - - MbbPreferredProvidersSize = ROUND_UP_COUNT( MbbPreferredProvidersSize, ALIGN_DWORD ); - MbbPreferredProvidersSize += sizeof(MBB_PROVIDER); - - if( (NdisStatus = RtlStringCbLengthW( - WwanProvider->Provider.ProviderId, - sizeof(WwanProvider->Provider.ProviderId), - &StringCbLength - )) != STATUS_SUCCESS ) - { - StringCbLength = sizeof(WwanProvider->Provider.ProviderId); - } - MbbPreferredProvidersSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); - - if( (NdisStatus = RtlStringCbLengthW( - WwanProvider->Provider.ProviderName, - sizeof(WwanProvider->Provider.ProviderName), - &StringCbLength - )) != STATUS_SUCCESS ) - { - StringCbLength = sizeof(WwanProvider->Provider.ProviderName); - } - MbbPreferredProvidersSize += ROUND_UP_COUNT( (ULONG)StringCbLength, ALIGN_DWORD ); - WwanProvider++; - } - // - // Allocate & setup Mbb buffer - // - if( MbbPreferredProvidersSize > ULONG_MAX || - (MbbPreferredProviders = (PMBB_PROVIDER_LIST)ALLOCATE_NONPAGED_POOL( (ULONG)MbbPreferredProvidersSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate MBB_PROVIDER_LIST of Size=%d for ProviderCount=%d", - Request->RequestId, - (ULONG)MbbPreferredProvidersSize, - ElementCount - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbPreferredProviders; - // - // Convert from WWAN to MBB - // - ValidDataSize = (ULONG)MbbPreferredProvidersSize; - - if( (NdisStatus = MbbUtilWwanToMbbProviderList( - &NdisSetPreferredProviders->PreferredListHeader, - IsMultiCarrierCapable, - MbbCellularClassInvalid, - MbbPreferredProviders, - &ValidDataSize - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to convert WWAN_PROVIDER_LIST to MBB_PROVIDER_LIST ", Request->RequestId ); - break; - } - // - // Send the data - // - NdisStatus = MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbPreferredProviders, - ValidDataSize - ); - if( NdisStatus == NDIS_STATUS_SUCCESS || - NdisStatus == NDIS_STATUS_PENDING ) - { - *InBufferSize = (ULONG)NdisSetPreferredProvidersSize; - } - } - while( FALSE ); - - return NdisStatus; -} - - -NDIS_STATUS -MbbNdisSetPmParameters( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) - -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - PMBB_PACKET_FILTERS MbbPacketFilters=NULL; - ULONG BufferSize=0; - NDIS_STATUS Status=STATUS_SUCCESS; - PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; - NDIS_PORT_NUMBER PortNumber = OidRequest->PortNumber; - PMBB_PORT Port = NULL; - ULONG SessionId = MBB_INVALID_SESSION_ID; - PNDIS_PM_PARAMETERS PmParameters=(PNDIS_PM_PARAMETERS)InBuffer; - - *InBufferSize=sizeof(*PmParameters); - - //Only honor this request when its received on port number 0. This is because - // this OID is sent by NDIS only during low power transitions <=D2. This should be seen - // by the miniport only during low power transitions as NDIS absorbs it in other cases. - // As per the current design, the WWAN virtual miniports are also going to send OID_PM_PARAMETERS - // to the filter driver, after every OID_PM_ADD/REMOVE_WOL_PATTERN OID request. In this case also - // OID_PM_PARAMETERS will be absorbed by NDIS and sent to the physical miniport on port 0. - - if(IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - ASSERT(FALSE); - TraceError( WMBCLASS_POWER, "Unexpected: OID_PM_PARAMETERS received on port number %lu instead of port number 0. Not handling and returning success", PortNumber); - return NDIS_STATUS_SUCCESS; - } - - if ((PmParameters->WakeUpFlags & NDIS_PM_SELECTIVE_SUSPEND_ENABLED) != 0) - { - TraceInfo( WMBCLASS_POWER, "Set PM Params: enable SS"); - } - else - { - TraceInfo( WMBCLASS_POWER, "Set PM Params: enabling wake: events= %08lx, enabled patterns=%d", - PmParameters->MediaSpecificWakeUpEvents, - (PmParameters->EnabledWoLPacketPatterns & NDIS_PM_WOL_BITMAP_PATTERN_ENABLED) != 0 - ); - - Status = MbbAdapterConfigurePacketFilters(Adapter,((PmParameters->EnabledWoLPacketPatterns & NDIS_PM_WOL_BITMAP_PATTERN_ENABLED) != 0)); - - if (!NT_SUCCESS(Status)) - { - TraceError( WMBCLASS_POWER, "Could not arm patterns"); - - return Status; - } - - Status=MbbAdapterConfigureDeviceServiceSubscription(Adapter, FALSE, PmParameters->MediaSpecificWakeUpEvents, PmParameters->WakeUpFlags); - - if (!NT_SUCCESS(Status)) - { - TraceError( WMBCLASS_POWER, "Could not enabled wake events"); - return Status; - } - // - // tell the device we expect to not be sending traffic for awhile - // - Status = MbbAdapterSendNetworkIdleHint(Adapter); - } - - return Status; -} - -NDIS_STATUS -MbbNdisSetAddWolPattern( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - NDIS_STATUS Status; - ULONGLONG BufferEnd; - PNDIS_PM_WOL_PATTERN Pattern=(PNDIS_PM_WOL_PATTERN)InBuffer; - NDIS_PORT_NUMBER PortNumber = Request->OidContext.OidRequest->PortNumber; - - TraceInfo( WMBCLASS_POWER, "Entered MbbNdisSetAddWolPattern for NDIS port number %lu", PortNumber); - - if (Pattern->WoLPacketType != NdisPMWoLPacketBitmapPattern) - { - TraceError( WMBCLASS_POWER, "Unsupported packet type"); - - return NDIS_STATUS_NOT_SUPPORTED; - } - - BufferEnd = (ULONGLONG)Pattern->WoLPattern.WoLBitMapPattern.MaskOffset + Pattern->WoLPattern.WoLBitMapPattern.MaskSize; - - if (BufferEnd > *InBufferSize) - { - TraceError( WMBCLASS_POWER, "buffer overflow in mask"); - - return NDIS_STATUS_INVALID_PARAMETER; - } - - BufferEnd = (ULONGLONG)Pattern->WoLPattern.WoLBitMapPattern.PatternOffset + Pattern->WoLPattern.WoLBitMapPattern.PatternSize; - - if (BufferEnd > *InBufferSize) - { - TraceError( WMBCLASS_POWER, "buffer overflow in pattern"); - - return NDIS_STATUS_INVALID_PARAMETER; - } - - // - // Each bit in the ndis mask represents a byte of data. For NCM each byte of mask is a bit filter for the pattern - // - if (Pattern->WoLPattern.WoLBitMapPattern.MaskSize * 8 > Adapter->BusParams.MaxPowerFilterSize) - { - TraceError( WMBCLASS_POWER, "Mask size is larger than supported by the device"); - - return NDIS_STATUS_INVALID_PARAMETER; - } - - // This request can arrive on disconnected connections too. Hence we just add the WOL - // pattern to the adapter power filter table without looking at the connection state of the port. - // During low power transition, only WOL patterns corresponding to connected ports will be - // plumbed to the device. - - Status = MbbUtilSetPowerFilterPattern( - Adapter, - PortNumber, - Pattern->PatternId, - InBuffer + Pattern->WoLPattern.WoLBitMapPattern.MaskOffset, - Pattern->WoLPattern.WoLBitMapPattern.MaskSize, - InBuffer + Pattern->WoLPattern.WoLBitMapPattern.PatternOffset, - Pattern->WoLPattern.WoLBitMapPattern.PatternSize - ); - - return Status; -} - -NDIS_STATUS -MbbNdisSetRemoveAddWolPattern( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - ULONG PatternId=*(PULONG)InBuffer; - NDIS_STATUS Status; - NDIS_PORT_NUMBER PortNumber = Request->OidContext.OidRequest->PortNumber; - - TraceInfo( WMBCLASS_POWER, "Entered MbbNdisSetRemoveAddWolPattern for PatternId=%d and NDIS port number %lu", PatternId, PortNumber ); - - Status = MbbUtilSetPowerFilterPattern( - Adapter, - PortNumber, - PatternId, - 0, - 0, - 0, - 0 - ); - - return Status; -} - - -NDIS_STATUS -MbbNdisQueryPower( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) - -{ - PULONG PowerState=(PULONG)OutBuffer; - - TraceInfo( WMBCLASS_POWER, "Query power D%d", *PowerState - NetDeviceStateD0); - - __analysis_assume( *OutBufferSize >= sizeof(*PowerState) ); - - *OutBufferSize=sizeof(*PowerState); - - return NDIS_STATUS_SUCCESS; - -} - -NDIS_STATUS -MbbNdisSetLteAttachContexts( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG MbbSetLteAttachContext = NULL; - PNDIS_WWAN_SET_LTE_ATTACH_CONTEXT NdisSetLteAttachContext= (PNDIS_WWAN_SET_LTE_ATTACH_CONTEXT)InBuffer; - ULONG BufferSize=0; - NDIS_STATUS Status; - PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; - - MbbAdapterLock(Adapter); - BOOL IsLteAttachCapable = Adapter->AdapterFlags.IsLTEAttachConfigCapable; - MbbAdapterUnlock(Adapter); - - if (!IsLteAttachCapable) - { - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support set LTE Attach configurations"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_LTE_ATTACH_CONTEXT) ); - - // LTE attach scenario - Status=MbbUtilWwanToMbbSetLteAttachContext( - &NdisSetLteAttachContext->SetLteAttachContext, - &MbbSetLteAttachContext, - &BufferSize - ); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetLteAttachContext; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSetLteAttachContext, - BufferSize - ); - -} - -NDIS_STATUS -MbbNdisSetProvisionedContexts( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMBB_SET_CONTEXT MbbSetContext=NULL; - PNDIS_WWAN_SET_PROVISIONED_CONTEXT NdisSetProvisionedContext= (PNDIS_WWAN_SET_PROVISIONED_CONTEXT)InBuffer; - ULONG BufferSize=0; - NDIS_STATUS Status; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT) ); - - *InBufferSize = sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT); - - Status=MbbUtilWwanToMbbSetContext( - &NdisSetProvisionedContext->ProvisionedContext, - &MbbSetContext, - &BufferSize - ); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetContext; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSetContext, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetProvisionedContextsV2( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 MbbSetContext = NULL; - PNDIS_WWAN_SET_PROVISIONED_CONTEXT_V2 NdisSetProvisionedContext = (PNDIS_WWAN_SET_PROVISIONED_CONTEXT_V2)InBuffer; - ULONG BufferSize = 0; - NDIS_STATUS Status; - PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; - - MbbAdapterLock(Adapter); - BOOL IsProvisionedContextV2Capable = Adapter->AdapterFlags.IsProvisionedContextV2Capable; - MbbAdapterUnlock(Adapter); - - if (!IsProvisionedContextV2Capable) - { - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support ProvisionedContextV2"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT_V2)); - - *InBufferSize = sizeof(NDIS_WWAN_SET_PROVISIONED_CONTEXT_V2); - - Status = MbbUtilWwanToMbbSetContextV2( - &NdisSetProvisionedContext->ProvisionedContext, - &MbbSetContext, - &BufferSize - ); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetContext; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbSetContext, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetServiceActivation( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG MbbServiceActivationSize; - PMBB_SERVICE_ACTIVATION MbbServiceActivation = NULL; - PNDIS_WWAN_SERVICE_ACTIVATION NdisServiceActivation = (PNDIS_WWAN_SERVICE_ACTIVATION)InBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SERVICE_ACTIVATION) ); - *InBufferSize = sizeof(NDIS_WWAN_SERVICE_ACTIVATION); - - do - { - MbbServiceActivationSize = NdisServiceActivation->ServiceActivation.uVendorSpecificBufferSize; - - if (MbbServiceActivationSize > MBB_MAX_SERVICE_ACTIVATION_BUFFER) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] actrivation buffer too big %d", Request->RequestId, MbbServiceActivationSize ); - - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - - if (MbbServiceActivationSize + RTL_SIZEOF_THROUGH_FIELD( NDIS_WWAN_SERVICE_ACTIVATION, ServiceActivation.uVendorSpecificBufferSize ) > *InBufferSize) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] activation buffer larger than Input Buffer %d", Request->RequestId, MbbServiceActivationSize ); - - NdisStatus = NDIS_STATUS_BUFFER_TOO_SHORT; - break; - } - - - if( (MbbServiceActivation = ALLOCATE_NONPAGED_POOL( MbbServiceActivationSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate SERVICE_ACTIVATION buffer", Request->RequestId ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbServiceActivation; - - RtlCopyMemory( - MbbServiceActivation->VendorSpecificBuffer, - NdisServiceActivation + 1, - MbbServiceActivationSize - ); - - NdisStatus = MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)(MbbServiceActivation), - MbbServiceActivationSize - ); - } - while( FALSE ); - - return NdisStatus; -} - -// SMS - -NDIS_STATUS -MbbNdisSmsSetConfiguration( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - ULONG MbbBufferSize; - SIZE_T ScAddressSize; - NTSTATUS NtStatus; - PMBB_SET_SMS_CONFIGURATION MbbSetSmsConfiguration; - PNDIS_WWAN_SET_SMS_CONFIGURATION NdisSmsSetConfiguration = (PNDIS_WWAN_SET_SMS_CONFIGURATION)InBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_SMS_CONFIGURATION) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_SMS_CONFIGURATION); - - NtStatus = RtlStringCbLengthA( - NdisSmsSetConfiguration->SetSmsConfiguration.ScAddress, - WWAN_SMS_ADDRESS_MAX_LEN, - &ScAddressSize - ); - - if ( NtStatus != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] INVALID ScAddress OID_WWAN_SMS_CONFIGURATION SET, status=%!STATUS!", - Request->RequestId, - NtStatus - ); - - return NtStatus; - } - - NtStatus=MbbUtilWwanToMbbSmsSetConfiguration( - &NdisSmsSetConfiguration->SetSmsConfiguration, - (ULONG)ScAddressSize, - &MbbSetSmsConfiguration, - &MbbBufferSize - ); - - if ( NtStatus != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] could not convert SMS config to MBB, status=%!STATUS!", - Request->RequestId, - NtStatus - ); - - return NtStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetSmsConfiguration; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSetSmsConfiguration, - MbbBufferSize - ); -} - -NDIS_STATUS -MbbNdisSmsSend( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - ULONG MbbSmsSendSize; - NDIS_STATUS NdisStatus; - PMBB_SMS_SEND MbbSmsSend; - PNDIS_WWAN_SMS_SEND NdisSmsSend = (PNDIS_WWAN_SMS_SEND)InBuffer; - MBB_CELLULAR_CLASS CellularClass = MbbAdapterGetCurrentCellularClass( MbbReqMgrGetAdapterHandle( Request ) ); - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SMS_SEND) ); - *InBufferSize = sizeof(NDIS_WWAN_SMS_SEND); - - if (MbbAdapterIsMultimodeCapable(MbbReqMgrGetAdapterHandle( Request ))) - { - // - // multimode device always use GSM PDU's - // - CellularClass = MbbCellularClassGsm; - } - - - if( NdisSmsSend->SmsSend.SmsFormat == WwanSmsFormatPdu ) - { - - NdisStatus=MbbUtilWwanToMbbSmsSendPdu( - &NdisSmsSend->SmsSend.u.Pdu, - CellularClass, - &MbbSmsSend, - &MbbSmsSendSize - ); - - } - else - { - - NdisStatus=MbbUtilWwanToMbbSmsSendCdma( - &NdisSmsSend->SmsSend.u.Cdma, - &MbbSmsSend, - &MbbSmsSendSize - ); - - - } - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to convert data for OID_WWAN_SMS_SEND, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - return NdisStatus; - - } - - MbbSmsSend->SmsFormat = MbbUtilWwanToMbbSmsFormat( NdisSmsSend->SmsSend.SmsFormat ); - Request->HandlerContext.DataToFreeOnCompletion = MbbSmsSend; - - // - // Send CID - // - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSmsSend, - MbbSmsSendSize - ); -} - -NDIS_STATUS -MbbNdisSmsDelete( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMBB_SMS_DELETE MbbSmsDelete; - PNDIS_WWAN_SMS_DELETE NdisSmsDelete = (PNDIS_WWAN_SMS_DELETE)InBuffer; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SMS_DELETE) ); - *InBufferSize = sizeof(NDIS_WWAN_SMS_DELETE); - // - // TODO: If WWAN_SMS_FILTER and MBB_SMS_DELETE are of the same layout. - // avoid unneccesary data copy and use the passed in - // NDIS format and do not convert to MBB format. - // - if( (MbbSmsDelete = (PMBB_SMS_DELETE) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SMS_DELETE) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSmsDelete; - - MbbUtilWwanToMbbSmsDelete( - &NdisSmsDelete->SmsFilter, - MbbSmsDelete - ); - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSmsDelete, - sizeof(MBB_SMS_DELETE) - ); -} - -// DEVICE SERVICE - -NDIS_STATUS -MbbNdisSubscribeDeviceServiceEvents( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG OidSubscribeListSize = 0; - PMBB_SUBSCRIBE_EVENT_LIST OidSubscribeList = NULL; - PNDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS NdisSubscribeEvents = (PNDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS)InBuffer; - GUID* NdisSubscribeGuid = NULL; - PMBB_SUBSCRIBE_EVENT_LIST MbbSubscribeList = NULL; - ULONG MbbSubscribeListSize = 0; - ULONGLONG RequiredInputSize = 0; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - - - do - { - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS) ); - - // - // First, for the specified device services, generate the list - // of device service + CIDs that we want to subscribe to - // - RequiredInputSize = sizeof(NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS) + - (ULONGLONG)NdisSubscribeEvents->DeviceServiceListHeader.ElementCount * sizeof(GUID); - - if (*InBufferSize < RequiredInputSize) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS, BufferSize[Received=%d Expected=%I64d]", - Request->RequestId, - *InBufferSize, - RequiredInputSize - ); - - if (RequiredInputSize > ULONG_MAX) - { - *InBufferSize = ULONG_MAX; - } - else - { - *InBufferSize = (ULONG)RequiredInputSize; - } - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - - Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )); - - if (NdisSubscribeEvents->DeviceServiceListHeader.ElementCount != 0) - { - // Get the specified GUIDs - NdisSubscribeGuid = (GUID *)((PUCHAR)InBuffer + - sizeof(NDIS_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS)); - - // Generate the Mbb structure for this request - NdisStatus = MbbUtilWwanToMbbSubscribeEvents(Adapter, - NdisSubscribeGuid, - NdisSubscribeEvents->DeviceServiceListHeader.ElementCount, - TRUE, // External request, so validate - NULL, - 0, // No padding - &OidSubscribeList, - &OidSubscribeListSize - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to convert OID subscribe list to MBB subscribe list", - Request->RequestId - ); - break; - } - } - else - { - OidSubscribeList = NULL; - OidSubscribeListSize = 0; - } - - // Save this as the OID configured subscribe list till we finish the - // transaction. If the transaction succeeds, we will persist this list - Request->HandlerContext.Parameters.EventSubscribe.ExtList = OidSubscribeList; - Request->HandlerContext.Parameters.EventSubscribe.ExtSize = OidSubscribeListSize; - - // Save the pointer to the buffer so that it gets freed automatically on failure paths - Request->HandlerContext.DataToFreeOnResponse = OidSubscribeList; - - // - // Now, merge this with the internally generated list - // that we want to subscribe to - // - NdisStatus = MbbUtilGenerateSubscribeEventList( - (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext), - TRUE, // Awake - 0, - 0, - OidSubscribeList, - OidSubscribeListSize, - &MbbSubscribeList, - &MbbSubscribeListSize - ); - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to generate merged MBB_SUBSCRIBE_EVENT_LIST, status=%!STATUS!", - Request->RequestId, NdisStatus - ); - break; - } - - // The buffer we are using for the request is saved for freeing on completion - Request->HandlerContext.DataToFreeOnCompletion = MbbSubscribeList; - - NdisStatus = MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSubscribeList, - MbbSubscribeListSize - ); - if ((NdisStatus != NDIS_STATUS_SUCCESS) && - (NdisStatus != NDIS_STATUS_PENDING)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to submit merged MBB_SUBSCRIBE_EVENT_LIST, status=%!STATUS!", - Request->RequestId, NdisStatus - ); - break; - } - - - } while (FALSE); - - if ((NdisStatus != NDIS_STATUS_SUCCESS) && - (NdisStatus != NDIS_STATUS_PENDING)) - { - if (Request->HandlerContext.DataToFreeOnCompletion) - FREE_POOL(Request->HandlerContext.DataToFreeOnCompletion); - - if (Request->HandlerContext.DataToFreeOnResponse) - FREE_POOL(Request->HandlerContext.DataToFreeOnResponse); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisSetDeviceServiceCommand( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - return MbbUtilDeviceServiceCommand( - Request, - InBuffer, - InBufferSize - ); -} - -NDIS_STATUS -MbbNdisSetVendorSpecific( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS NdisStatus; - MBB_COMMAND MbbCommand; - PNDIS_WWAN_VENDOR_SPECIFIC NdisVendorSpecific; - - do - { - if( *InBufferSize < sizeof(NDIS_WWAN_VENDOR_SPECIFIC) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INSUFFICIENT InputBufferSize=%d Bytes for VENDOR_SPECIFIC, Expected=%d Bytes", - Request->RequestId, *InBufferSize, sizeof(NDIS_WWAN_VENDOR_SPECIFIC) ); - - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - *InBufferSize = sizeof(NDIS_WWAN_VENDOR_SPECIFIC); - break; - } - - NdisVendorSpecific = (PNDIS_WWAN_VENDOR_SPECIFIC) InBuffer; - - - if( NdisVendorSpecific->Header.Type != NDIS_OBJECT_TYPE_DEFAULT || - NdisVendorSpecific->Header.Size < sizeof(NDIS_WWAN_VENDOR_SPECIFIC) || - NdisVendorSpecific->Header.Revision < NDIS_WWAN_VENDOR_SPECIFIC_REVISION_1 ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INVALID ndis header for VENDOR_SPECIFIC, Type=0x%x Size=%d Revision=%d", - Request->RequestId, - NdisVendorSpecific->Header.Type, - NdisVendorSpecific->Header.Size, - NdisVendorSpecific->Header.Revision - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - if (NdisVendorSpecific->VendorSpecificData.uVendorSpecificBufferSize + - RTL_SIZEOF_THROUGH_FIELD(NDIS_WWAN_VENDOR_SPECIFIC,VendorSpecificData.uVendorSpecificBufferSize) > *InBufferSize ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INSUFFICIENT InputBufferSize=%d Bytes for VENDOR_SPECIFIC, Expected=%d Bytes", - Request->RequestId, *InBufferSize, sizeof(NDIS_WWAN_VENDOR_SPECIFIC) ); - - *InBufferSize = NdisVendorSpecific->VendorSpecificData.uVendorSpecificBufferSize + - RTL_SIZEOF_THROUGH_FIELD(NDIS_WWAN_VENDOR_SPECIFIC,VendorSpecificData.uVendorSpecificBufferSize); - - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - - RtlCopyMemory( - &MbbCommand.ServiceId, - &MBB_UUID_MS_VENDOR_EXTENSION, - sizeof(GUID) - ); - - MbbCommand.CommandId = MBIM_CID_VENDORSPECIFIC; - // - // Call the wrapper routine to allocate - // and format the message buffers. - // - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &MbbCommand, - MbbReqMgrIsSetOid( Request )? MBB_COMMAND_TYPE_SET: MBB_COMMAND_TYPE_QUERY, - (PUCHAR)(NdisVendorSpecific + 1), - NdisVendorSpecific->VendorSpecificData.uVendorSpecificBufferSize - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to setup command message for VENDOR_SPECIFIC with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to send message fragments for VENDOR_SPECIFIC with status=%!status!", - Request->RequestId, NdisStatus ); - } - - } while( FALSE ); - - return NdisStatus; -} - - -NDIS_STATUS -MbbNdisSetDeviceServiceSession( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - MBB_SET_DSS_CONNECT MbbDssConnect; - - PNDIS_WWAN_SET_DEVICE_SERVICE_SESSION NdisDssRequest = (PNDIS_WWAN_SET_DEVICE_SERVICE_SESSION)InBuffer; - NDIS_STATUS Status; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_SET_DEVICE_SERVICE_SESSION) ); - *InBufferSize = sizeof(NDIS_WWAN_SET_DEVICE_SERVICE_SESSION); - - if (MbbUtilIsNativeMbnService(&(NdisDssRequest->Session.DeviceServiceGuid))) - { - // Native device services cannot be used using this path - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED because of request for native device service %!GUID!", - Request->RequestId, - &(NdisDssRequest->Session.DeviceServiceGuid) - ); - - return NDIS_STATUS_INVALID_DATA; - } - - // - // Save stuff about the request in the set so that we can send the relevant - // info in the indication - // - RtlCopyMemory( - &Request->HandlerContext.Parameters.DssSession.DeviceServiceGuid, - &(NdisDssRequest->Session.DeviceServiceGuid), - sizeof(GUID) - ); - Request->HandlerContext.Parameters.DssSession.SessionId = NdisDssRequest->Session.uSessionID; - - - if ((NdisDssRequest->Session.State == WwanDeviceServiceSessionOpen) - || - (NdisDssRequest->Session.State == WwanDeviceServiceSessionClosed)) - { - - // Send the Open Request - - // Copy the device service in device format - MBB_UUID_TO_NET(&MbbDssConnect.DeviceServiceId, - &(NdisDssRequest->Session.DeviceServiceGuid) - ); - - MbbDssConnect.DssSessionId = NdisDssRequest->Session.uSessionID; - - MbbDssConnect.DssLinkState = (NdisDssRequest->Session.State == WwanDeviceServiceSessionOpen) ? MbbDssLinkActivate : MbbDssLinkDeactivate; - - Request->HandlerContext.Parameters.DssSession.LinkState = MbbDssConnect.DssLinkState; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)(&MbbDssConnect), - sizeof(MbbDssConnect) - ); - } - else - { - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Device Service Session state specified is invalid, %d", - Request->RequestId, - NdisDssRequest->Session.State); - - return NDIS_STATUS_INVALID_PARAMETER; - } -} - -NDIS_STATUS -MbbNdisDssWrite( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS NdisStatus; - MBB_COMMAND MbbCommand; - PNDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE NdisDssWriteRequest; - - // The session write gets pushed through the send path to the device - do - { - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE) ); - *InBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE); - - NdisDssWriteRequest = (PNDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE) InBuffer; - - if (NdisDssWriteRequest->WriteData.uDataSize == 0) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Invalid size for device service session write", - Request->RequestId); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - // Ref this request so that we can pass a reference to it to send path. When - // the send path completes the request, we will release the ref - MbbReqMgrRefRequest(Request); - - NdisStatus = MbbSendDeviceServiceSessionData( - ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )), - Request, - Request->RequestId, - NdisDssWriteRequest->WriteData.uSessionID, - NdisDssWriteRequest->WriteData.uDataSize, - (PUCHAR)(NdisDssWriteRequest + 1) - ); - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - MbbReqMgrDerefRequest(Request); - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to write device service data with status=%!status!", - Request->RequestId, NdisStatus ); - } - - } while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisDeleteMac( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; - PNDIS_WWAN_MAC_INFO ndisWwanMacInfo = NULL; - PNDIS_OID_REQUEST oidRequest = Request->OidContext.OidRequest; - - UNREFERENCED_PARAMETER(InBuffer); - UNREFERENCED_PARAMETER(InBufferSize); - - do - { - oidRequest->DATA.SET_INFORMATION.BytesRead = 0; - oidRequest->DATA.SET_INFORMATION.BytesNeeded = 0; - - if (oidRequest->RequestType != NdisRequestSetInformation) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] Invalid request type %d for OID_WWAN_DELETE_MAC\n", - Request->RequestId, - oidRequest->RequestType - ); - ndisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - ASSERT(oidRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof(NDIS_WWAN_MAC_INFO)); - - ndisWwanMacInfo = (PNDIS_WWAN_MAC_INFO)oidRequest->DATA.SET_INFORMATION.InformationBuffer; - - if (!IS_ALLOCATED_PORT_NUMBER(ndisWwanMacInfo->uNdisPortNumber)) - { - TraceError (WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] The port number (%d) being passed in is invalid", - Request->RequestId, - ndisWwanMacInfo->uNdisPortNumber); - - ndisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - ndisStatus = MbbUtilWwanDeleteMac(Request); - - if (ndisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID,"MbbNdis][ReqID=0x%04x] MbbUtilWwanDeleteMac failed. Status = 0x%08x\n", - Request->RequestId,ndisStatus); - break; - } - }while (FALSE); - - return ndisStatus; -} - -NDIS_STATUS -MbbNdisUiccUpdateBinary( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - return MbbUtilUiccAccessBinary( - Request, - InBuffer, - InBufferSize - ); -} - -NDIS_STATUS -MbbNdisUiccUpdateRecord( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - return MbbUtilUiccAccessRecord( - Request, - InBuffer, - InBufferSize - ); -} - -NDIS_STATUS -MbbNdisSetSysSlotMappings( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PNDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO NdisSetDeviceSlotMappingInfo = (PNDIS_WWAN_SET_DEVICE_SLOT_MAPPING_INFO)InBuffer; - PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbSetDeviceSlotMappingInfo = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG BufferSize = 0; - - NdisStatus = MbbUtilWwanToMbbSetDeviceSlotMappingInfo( - &(NdisSetDeviceSlotMappingInfo->SetDeviceSlotMappingInfo), - &MbbSetDeviceSlotMappingInfo, - &BufferSize); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetDeviceSlotMappingInfo; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbSetDeviceSlotMappingInfo, - BufferSize); -} - -NDIS_STATUS -MbbNdisSetDeviceBindings( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PNDIS_WWAN_SET_DEVICE_BINDINGS_INFO NdisSetDeviceBindingsInfo = (PNDIS_WWAN_SET_DEVICE_BINDINGS_INFO)InBuffer; - PMBB_DEVICE_BINDINGS_INFO MbbSetDeviceBindingsInfo = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG BufferSize = 0; - - NdisStatus = MbbUtilWwanToMbbSetDeviceBindingsInfo( - &(NdisSetDeviceBindingsInfo->SetDeviceBindingsInfo), - &MbbSetDeviceBindingsInfo, - &BufferSize); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetDeviceBindingsInfo; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbSetDeviceBindingsInfo, - BufferSize); -} - -NDIS_STATUS -MbbNdisSetRegisterStateEx( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PNDIS_WWAN_SET_REGISTER_STATE_EX NdisSetRegisterStateEx = (PNDIS_WWAN_SET_REGISTER_STATE_EX)InBuffer; - PMBB_SET_REGISTER_STATE_V2 MbbSetRegisterStateV2 = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG BufferSize = 0; - - NdisStatus = MbbUtilWwanToMbbSetRegisterStateEx( - &(NdisSetRegisterStateEx->SetRegisterState), - &MbbSetRegisterStateV2, - &BufferSize); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetRegisterStateV2; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbSetRegisterStateV2, - BufferSize); -} - -NDIS_STATUS -MbbNdisSetImsVoiceState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PNDIS_WWAN_SET_IMS_VOICE_STATE NdisSetImsVoiceState = (PNDIS_WWAN_SET_IMS_VOICE_STATE)InBuffer; - PMBB_SET_IMS_VOICE_STATE MbbSetImsVoiceState = NULL; - ULONG BufferSize = sizeof(MBB_SET_IMS_VOICE_STATE); - - MbbSetImsVoiceState = ALLOCATE_NONPAGED_POOL(BufferSize); - if (NULL == MbbSetImsVoiceState) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSetImsVoiceState; - - RtlZeroMemory(MbbSetImsVoiceState, BufferSize); - - MbbSetImsVoiceState->ImsVoiceStatus = (MBB_IMS_VOICE_STATUS)(NdisSetImsVoiceState->SetImsVoiceState.ImsVoiceStatus); - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR)MbbSetImsVoiceState, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetSignalStateEx( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PNDIS_WWAN_SET_SIGNAL_INDICATION_EX NdisSetSignalIndicationEx = (PNDIS_WWAN_SET_SIGNAL_INDICATION_EX)InBuffer; - PMBB_SET_SIGNAL_INDICATION_V2 MbbSetSignalIndicationV2 = NULL; - ULONG BufferSize = sizeof(MBB_SET_SIGNAL_INDICATION_V2); - - MbbSetSignalIndicationV2 = ALLOCATE_NONPAGED_POOL(BufferSize); - if (NULL == MbbSetSignalIndicationV2) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSetSignalIndicationV2; - - RtlZeroMemory(MbbSetSignalIndicationV2, BufferSize); - - RtlCopyMemory(MbbSetSignalIndicationV2, &(NdisSetSignalIndicationEx->SignalIndication), BufferSize); - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR)MbbSetSignalIndicationV2, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetLocationState( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PNDIS_WWAN_LOCATION_TRIGGER_MODE NdisLocationTriggerMode = (PNDIS_WWAN_LOCATION_TRIGGER_MODE)InBuffer; - PMBB_SET_LOCATION_STATE MbbSetLocationState = NULL; - ULONG BufferSize = sizeof(MBB_SET_LOCATION_STATE); - - MbbSetLocationState = ALLOCATE_NONPAGED_POOL(BufferSize); - if (NULL == MbbSetLocationState) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSetLocationState; - - RtlZeroMemory(MbbSetLocationState, BufferSize); - - MbbSetLocationState->Trigger = (MBB_LOCATION_TRIGGER_MODE)(NdisLocationTriggerMode->SetLocationState.Trigger); - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR)MbbSetLocationState, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetNetworkIdleHint( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PNDIS_WWAN_NETWORK_IDLE_HINT NdisNetworkIdleHint = (PNDIS_WWAN_NETWORK_IDLE_HINT)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; - NDIS_PORT_NUMBER PortNumber = OidRequest->PortNumber; - NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; - - // Honor this OID Request only if we get the request on the Physical Miniport which is on Port 0 - - do - { - if (IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] OID_WWAN_NETWORK_IDLE_HINT received on port number %lu instead of port number 0. Not handling and returning success\n", - Request->RequestId, - PortNumber - ); - ndisStatus = NDIS_STATUS_SUCCESS; - break; - } - - // if we are getting a call from above to put the device into Network Idle mode, then do so - if (NdisNetworkIdleHint->IdleHint.IsEnabled) - { - ndisStatus = MbbAdapterSendNetworkIdleHint(Adapter); - } - - } while (FALSE); - - return ndisStatus; -} - -NDIS_STATUS -MbbNdisSetPreshutdown( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - PNDIS_WWAN_PRESHUTDOWN_STATE NdisPreshutdownState = (PNDIS_WWAN_PRESHUTDOWN_STATE)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; - NDIS_PORT_NUMBER PortNumber = OidRequest->PortNumber; - BOOLEAN IsPreshutdownCapable = FALSE; - - do - { - // Honor this OID Request only if we get the request on the Physical Miniport (i.e. Port 0) - if (IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] OID_WWAN_PRESHUTDOWN received on port number %lu instead of port number 0. Not handling and returning success\n", - Request->RequestId, - PortNumber - ); - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - // Check for device support and bail if not supported - MbbAdapterLock(Adapter); - IsPreshutdownCapable = (TRUE == Adapter->AdapterFlags.IsPreshutdownCapable); - MbbAdapterUnlock(Adapter); - - if (!IsPreshutdownCapable) - { - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] OID_WWAN_PRESHUTDOWN - Device does not support preshutdown)", - Request->RequestId - ); - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - NdisStatus = MbbUtilSetAttributeWithParameter( - Request, - NULL, - 0); - if ((NdisStatus != NDIS_STATUS_SUCCESS) && - (NdisStatus != NDIS_STATUS_PENDING)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] OID_WWAN_PRESHUTDOWN Device SET failed", - Request->RequestId - ); - break; - } - - TraceLoggingWrite( - g_hLoggingProvider, - "OID_Wwan_Preshutdown_Request", - TraceLoggingUInt64(Request->RequestId, "RequestID"), - TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); - - } while (FALSE); - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisSetUiccOpenChannel( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PNDIS_WWAN_SET_UICC_OPEN_CHANNEL NdisSetUiccOpenChannel = (PNDIS_WWAN_SET_UICC_OPEN_CHANNEL)InBuffer; - PMBB_SET_UICC_OPEN_CHANNEL MbbSetUiccOpenChannel = NULL; - NDIS_STATUS NdisStatus; - ULONG BufferSize = 0; - - __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_OPEN_CHANNEL)); - - NdisStatus = MbbUtilWwanToMbbSetUiccOpenChannel( - &NdisSetUiccOpenChannel->SetUiccOpenChannel, - &MbbSetUiccOpenChannel, - &BufferSize - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccOpenChannel; - - return MbbUtilSetAttributeWithParameter( - Request, - (PUCHAR) MbbSetUiccOpenChannel, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetUiccCloseChannel( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PNDIS_WWAN_SET_UICC_CLOSE_CHANNEL NdisSetUiccCloseChannel = (PNDIS_WWAN_SET_UICC_CLOSE_CHANNEL)InBuffer; - PMBB_SET_UICC_CLOSE_CHANNEL MbbSetUiccCloseChannel = NULL; - - __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_CLOSE_CHANNEL)); - - if( (MbbSetUiccCloseChannel = (PMBB_SET_UICC_CLOSE_CHANNEL) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SET_UICC_CLOSE_CHANNEL) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - MbbUtilWwanToMbbSetUiccCloseChannel( - &NdisSetUiccCloseChannel->SetUiccCloseChannel, - MbbSetUiccCloseChannel - ); - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccCloseChannel; - - return MbbUtilSetAttributeWithParameter( - Request, - (PUCHAR) MbbSetUiccCloseChannel, - sizeof(MBB_SET_UICC_CLOSE_CHANNEL) - ); -} - -NDIS_STATUS -MbbNdisSetUiccApdu( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PNDIS_WWAN_SET_UICC_APDU NdisSetUiccApdu = (PNDIS_WWAN_SET_UICC_APDU)InBuffer; - PMBB_SET_UICC_APDU MbbSetUiccApdu = NULL; - NDIS_STATUS NdisStatus; - ULONG BufferSize = 0; - - __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_APDU)); - - NdisStatus = MbbUtilWwanToMbbSetUiccApdu( - &NdisSetUiccApdu->SetUiccApdu, - &MbbSetUiccApdu, - &BufferSize - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccApdu; - - return MbbUtilSetAttributeWithParameter( - Request, - (PUCHAR) MbbSetUiccApdu, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetUiccTerminalCapability( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PNDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY NdisSetUiccTerminalCapability = (PNDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY)InBuffer; - PMBB_SET_UICC_TERMINAL_CAPABILITY MbbSetUiccTerminalCapability = NULL; - NDIS_STATUS NdisStatus; - ULONG BufferSize = 0; - - __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_TERMINAL_CAPABILITY)); - - NdisStatus = MbbUtilWwanToMbbSetUiccTerminalCapability( - &NdisSetUiccTerminalCapability->SetUiccTerminalCapability.CapabilityListHeader, - &MbbSetUiccTerminalCapability, - &BufferSize - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccTerminalCapability; - - return MbbUtilSetAttributeWithParameter( - Request, - (PUCHAR) MbbSetUiccTerminalCapability, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetUiccReset( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize - ) -{ - PNDIS_WWAN_SET_UICC_RESET NdisSetUiccReset = (PNDIS_WWAN_SET_UICC_RESET)InBuffer; - PMBB_SET_UICC_RESET MbbSetUiccReset = NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterLock(Adapter); - BOOL IsUiccLowLevelCapable = Adapter->AdapterFlags.IsUiccLowLevelCapable; - MbbAdapterUnlock(Adapter); - - if (!IsUiccLowLevelCapable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support UICC low level operations (SET_UICC_RESET)"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_UICC_RESET)); - - if( (MbbSetUiccReset = (PMBB_SET_UICC_RESET) ALLOCATE_NONPAGED_POOL( sizeof(MBB_SET_UICC_RESET) )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - MbbSetUiccReset->PassThroughAction = (MBB_UICC_PASSTHROUGH_ACTION)NdisSetUiccReset->SetUiccReset.PassThroughAction; - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetUiccReset; - - return MbbUtilSetAttributeWithParameter( - Request, - (PUCHAR) MbbSetUiccReset, - sizeof(MBB_SET_UICC_RESET) - ); -} - -// SAR backoff set -NDIS_STATUS -MbbNdisSetSarConfig( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize - ) -{ - PMBB_SET_SAR_CONFIG MbbSetSarConfig = NULL; - PNDIS_WWAN_SET_SAR_CONFIG NdisSetSarConfig = (PNDIS_WWAN_SET_SAR_CONFIG)InBuffer; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG BufferSize = 0; - PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; - - MbbAdapterLock(Adapter); - BOOL IsSARCapable = Adapter->AdapterFlags.IsSARCapable; - MbbAdapterUnlock(Adapter); - - if (!IsSARCapable) - { - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support SAR control service"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - NdisStatus = MbbUtilWwanToMbbSetSarConfig( - &(NdisSetSarConfig->SetSarConfig), - &MbbSetSarConfig, - &BufferSize); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetSarConfig; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbSetSarConfig, - BufferSize); -} - -NDIS_STATUS -MbbNdisSetSarTransmissionStatus( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize - ) -{ - PMBB_SET_SAR_TRANSMISSION_STATUS MbbSetSarTransmissionStatus = NULL; - PNDIS_WWAN_SET_SAR_TRANSMISSION_STATUS NdisSetSarTransmissionStatus = (PNDIS_WWAN_SET_SAR_TRANSMISSION_STATUS)InBuffer; - ULONG BufferSize = sizeof(MBB_SET_SAR_TRANSMISSION_STATUS); - - MbbSetSarTransmissionStatus = ALLOCATE_NONPAGED_POOL(BufferSize); - if (NULL == MbbSetSarTransmissionStatus) - { - return NDIS_STATUS_RESOURCES; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbSetSarTransmissionStatus; - - RtlZeroMemory(MbbSetSarTransmissionStatus, BufferSize); - - MbbSetSarTransmissionStatus->ChannelNotification = - (MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE)(NdisSetSarTransmissionStatus->SetTransmissionStatus.ChannelNotification); - MbbSetSarTransmissionStatus->HysteresisTimer = NdisSetSarTransmissionStatus->SetTransmissionStatus.HysteresisTimer; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbSetSarTransmissionStatus, - BufferSize); -} - -NDIS_STATUS -MbbNdisSetNetworkBlacklist( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize -) -{ - PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist = NULL; - PNDIS_WWAN_SET_NETWORK_BLACKLIST NdisSetNetworkBlacklist = (PNDIS_WWAN_SET_NETWORK_BLACKLIST)InBuffer; - ULONG BufferSize = 0; - NDIS_STATUS Status; - PMINIPORT_ADAPTER_CONTEXT Adapter = Request->RequestManager->AdapterContext; - - MbbAdapterLock(Adapter); - BOOL IsNetworkBlacklistCapable = Adapter->AdapterFlags.IsNetworkBlacklistCapable; - MbbAdapterUnlock(Adapter); - - if (!IsNetworkBlacklistCapable) - { - TraceInfo(WMBCLASS_INIT, "[MbbAdapter] device does not support network blacklist"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_NETWORK_BLACKLIST)); - - *InBufferSize = sizeof(NDIS_WWAN_SET_NETWORK_BLACKLIST); - - Status = MbbUtilWwanToMbbSetNetworkBlacklist( - &NdisSetNetworkBlacklist->SetNetworkBlacklist, - &MbbNetworkBlacklist, - &BufferSize - ); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbNetworkBlacklist; - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbNetworkBlacklist, - BufferSize - ); -} - -NDIS_STATUS -MbbNdisSetDeviceReset( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_reads_bytes_opt_(*InBufferSize) PUCHAR InBuffer, - _In_ PULONG InBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle(Request); - - UNREFERENCED_PARAMETER(InBuffer); - - MbbAdapterLock(Adapter); - BOOL IsDeviceResetCapable = Adapter->AdapterFlags.IsDeviceResetCapable; - MbbAdapterUnlock(Adapter); - - if (!IsDeviceResetCapable) - { - TraceInfo(WMBCLASS_OID, "[MbbAdapter] device does not support device reset"); - return NDIS_STATUS_NOT_SUPPORTED; - } - - __analysis_assume(*InBufferSize >= sizeof(NDIS_WWAN_SET_DEVICE_RESET)); - - return MbbUtilSetAttributeWithParameter( - Request, - NULL, - 0 - ); -} - - -// -// Status Handlers -// - -/*++ -General handling of responses \ indications: - If the response \ indication couldnt be retrieved at all i.e. - NdisStatus != NDIS_STATUS_SUCCESS then bail out immediately. - - If the operational status is unsuccessful i.e. MbbStatus != - MBB_STATUS_SUCCESS the device may or may not have returned - additional data. In case it has propagate that data to svc. - If not then preserve the device returned failure code. - -Parameters - NdisStatus - Conveys whether the response was successfully retrieved. - - MbbStatus - The MBIM specification based operational status that the device returned. ---*/ - -VOID -MbbNdisIndicateDeviceCaps( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - BOOLEAN IndicateFailure = TRUE; - ULONG NdisDeviceCapsSize = Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCapsSize; - PMINIPORT_ADAPTER_CONTEXT Adapter; - PNDIS_WWAN_DEVICE_CAPS NdisDeviceCaps = Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCaps; - NDIS_WWAN_DEVICE_CAPS LocalNdisDeviceCaps; - NDIS_STATUS_INDICATION StatusIndication; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_CAPS - ); - - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ); - // - // If the CID response wasnt receieved then bail out. - // - if( NDIS_STATUS_SUCCESS != NdisStatus || - NULL == NdisDeviceCaps ) - { - break; - } - // - // Translate device services to caps. - // - if( Request->HandlerContext.Parameters.DeviceCaps.IsUssdCapsValid == 0 || - Request->HandlerContext.Parameters.DeviceCaps.IsAuthCapsValid == 0 ) - { - NdisStatus = MbbAdapterFWDeviceServicesToCapabilities( - Adapter, - Request - ); - if( NDIS_STATUS_PENDING == NdisStatus ) - { - // - // The status handler will take care of the rest. - // - NdisDeviceCaps = NULL; - IndicateFailure = FALSE; - break; - } - else if( NDIS_STATUS_SUCCESS != NdisStatus ) - { - break; - } - } - // - // All information is available. Indicate status. - // - NdisDeviceCaps->DeviceCaps.WwanAuthAlgoCaps = WWAN_AUTH_ALGO_CAPS_NONE; - if( Adapter->AdapterFlags.IsUssdCapable == TRUE ) - NdisDeviceCaps->DeviceCaps.WwanControlCaps |= WWAN_CTRL_CAPS_USSD; - if( Adapter->AdapterFlags.IsAkaAuthCapable == TRUE ) - NdisDeviceCaps->DeviceCaps.WwanAuthAlgoCaps |= WWAN_AUTH_ALGO_CAPS_AKA; - if( Adapter->AdapterFlags.IsAkapAuthCapable == TRUE ) - NdisDeviceCaps->DeviceCaps.WwanAuthAlgoCaps |= WWAN_AUTH_ALGO_CAPS_AKAPRIME; - if( Adapter->AdapterFlags.IsSimAuthCapable == TRUE ) - NdisDeviceCaps->DeviceCaps.WwanAuthAlgoCaps |= WWAN_AUTH_ALGO_CAPS_SIM; - // - // By default set this flag. When ready info comes later, - // MBCD will send a ReadyInfoFlag indication clearing the flag - // if its not set. The flag is set by default for buggy apps that - // may be caching the device caps. To prevent buggy apps from - // violating ProtectId laws this conservative approach is taken. - // - if( Adapter->AdapterFlags.IsShowIMSI == FALSE ) - NdisDeviceCaps->DeviceCaps.WwanControlCaps |= WWAN_CTRL_CAPS_PROTECT_UNIQUEID; - - NdisDeviceCaps->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceCaps->Header.Size = (USHORT)NdisDeviceCapsSize; - NdisDeviceCaps->Header.Revision = NDIS_WWAN_DEVICE_CAPS_REVISION_2; - NdisDeviceCaps->uStatus = WWAN_STATUS_SUCCESS; - - StatusIndication.StatusBuffer = NdisDeviceCaps; - StatusIndication.StatusBufferSize = NdisDeviceCapsSize; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_CAPS size=%d", Request->RequestId, NdisDeviceCapsSize ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - IndicateFailure = FALSE; - } - while( FALSE ); - - if( IndicateFailure ) - { - RtlZeroMemory( &LocalNdisDeviceCaps, sizeof(LocalNdisDeviceCaps) ); - - LocalNdisDeviceCaps.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisDeviceCaps.Header.Size = sizeof(LocalNdisDeviceCaps); - LocalNdisDeviceCaps.Header.Revision = NDIS_WWAN_DEVICE_CAPS_REVISION_2; - LocalNdisDeviceCaps.uStatus = NdisStatus; - - StatusIndication.StatusBuffer = &LocalNdisDeviceCaps; - StatusIndication.StatusBufferSize = sizeof(LocalNdisDeviceCaps); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to indicate NDIS_STATUS_WWAN_DEVICE_CAPS WwanStatus=%!WwanStatus!", Request->RequestId, NdisStatus ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - } - - if( NdisDeviceCaps != NULL ) - { - FREE_POOL( NdisDeviceCaps ); - } -} - -NDIS_STATUS -MbbNdisDeviceCapsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - PMBB_DEVICE_CAPS MbbDeviceCaps = (PMBB_DEVICE_CAPS)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - ULONG i = 0; - NDIS_WWAN_DEVICE_CAPS LocalNdisDeviceCaps; - PNDIS_WWAN_DEVICE_CAPS NdisDeviceCaps = NULL; - USHORT NdisDeviceCapsSize = (USHORT)sizeof(NDIS_WWAN_DEVICE_CAPS); - BOOL fMultimode = FALSE; - - do - { - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterResetCapabilities( Adapter ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_CAPS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!STATUS!", - Request->RequestId, - WwanStatus - ); - - break; - } - - - if( MbbDeviceCaps == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_DEVICE_CAPS, DataBuffer) ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_DEVICE_CAPS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - (ULONG)FIELD_OFFSET(MBB_DEVICE_CAPS, DataBuffer) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbDeviceCaps->CustomDataClass.Offset, - MbbDeviceCaps->CustomDataClass.Size, - MBB_MAXIMUM_DATA_CLASS_NAME_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] Bad custom data field, Offset=%d, Size=%d", - Request->RequestId, - MbbDeviceCaps->CustomDataClass.Offset, - MbbDeviceCaps->CustomDataClass.Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbDeviceCaps->DeviceIdString.Offset, - MbbDeviceCaps->DeviceIdString.Size, - MBB_MAXIMUM_DEVICE_ID_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] DeviceId data field, Offset=%d, Size=%d", - Request->RequestId, - MbbDeviceCaps->DeviceIdString.Offset, - MbbDeviceCaps->DeviceIdString.Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbDeviceCaps->FirmwareInfo.Offset, - MbbDeviceCaps->FirmwareInfo.Size, - MBB_MAXIMUM_FIRMWARE_INFO_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FirmwareInfo data field, Offset=%d, Size=%d", - Request->RequestId, - MbbDeviceCaps->FirmwareInfo.Offset, - MbbDeviceCaps->FirmwareInfo.Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - MbbAdapterSetSupportedCellularClass( Adapter, MbbDeviceCaps->CellularClass ); - MbbAdapterSetMaxActivatedContexts(Adapter,MbbDeviceCaps->dwMaxSessions); - fMultimode = MbbAdapterIsMultimodeCapable( Adapter ); - - // - // Remember whether this adapter is multi-carrier capable and also the data class. - // This information is used in reporting home and preferred and visible provider. - // - if( MbbDeviceCaps->ControlCaps & MbbControlCapsMultiCarrier ) - MbbAdapterSetMultiCarrierCapable( Adapter, TRUE ); - - MbbAdapterSetDataClass( Adapter, MbbDeviceCaps->DataClass ); - - if(!fMultimode) - { - MbbAdapterSetCurrentCellularClass( Adapter, MbbDeviceCaps->CellularClass ); - } - - // - // If this is an internal request then cache the device id and exit out. - // Internal query is generated from the miniport initialize path to query - // the device id. - // - if( MbbReqMgrIsInternalRequest( Request ) ) - { - MbbUtilPopulateStaticString( - Request->HandlerContext.Parameters.DeviceCaps.DeviceId, - MbbDeviceCaps, - DeviceIdString - ); - // - // If this is a test device the DeviceId may be absent. - // In this case fabricate an IMEI for GSM or ESN for CDMA. - // - if( Request->HandlerContext.Parameters.DeviceCaps.DeviceId[0] == 0 ) - { - if( fMultimode || - MbbDeviceCaps->CellularClass == MbbCellularClassGsm ) - { - RtlStringCbCopyW( - Request->HandlerContext.Parameters.DeviceCaps.DeviceId, - sizeof(Request->HandlerContext.Parameters.DeviceCaps.DeviceId), - MBB_PSEUDO_IMEI - ); - } - else - if( MbbDeviceCaps->CellularClass == MbbCellularClassCdma ) - { - RtlStringCbCopyW( - Request->HandlerContext.Parameters.DeviceCaps.DeviceId, - sizeof(Request->HandlerContext.Parameters.DeviceCaps.DeviceId), - MBB_PSEUDO_ESN - ); - } - else - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to get DeviceId, invalid CellularClass=%!MbbCellularClass!", - Request->RequestId, - MbbDeviceCaps->CellularClass - ); - return NDIS_STATUS_FAILURE; - } - } - return NDIS_STATUS_SUCCESS; - } - - //calculate variable buffer size for multimode devices - if(fMultimode) - { - //for now we support only GSM and CDMA so keep it simple - NdisDeviceCapsSize+= sizeof(WWAN_CELLULAR_CLASS) * (MbbCellularClassMaximum - 1); - } - - if( (NdisDeviceCaps = ALLOCATE_NONPAGED_POOL(NdisDeviceCapsSize)) == NULL ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_WWAN_DEVICE_CAPS", - Request->RequestId, - NdisDeviceCapsSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanDeviceCaps( - MbbDeviceCaps, - Adapter->BusParams.Manufacturer, - MAX_PARAMETER_STRING, - Adapter->BusParams.Model, - MAX_PARAMETER_STRING, - &NdisDeviceCaps->DeviceCaps, - fMultimode - ); - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCaps = NdisDeviceCaps; - Request->HandlerContext.Parameters.DeviceCaps.NdisDeviceCapsSize = NdisDeviceCapsSize; - - MbbNdisIndicateDeviceCaps( - Request, - WwanStatus - ); - - return NDIS_STATUS_SUCCESS; -} - -VOID -MbbNdisIndicateReadyInfoFailure( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_READY_INFO LocalNdisReadyInfo; - PMINIPORT_ADAPTER_CONTEXT Adapter; - - - Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle( Request ); - Adapter->AdapterFlags.IsShowIMSI = FALSE; - - RtlZeroMemory( - &LocalNdisReadyInfo, - sizeof(LocalNdisReadyInfo) - ); - - LocalNdisReadyInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisReadyInfo.Header.Size = sizeof(NDIS_WWAN_READY_INFO); - LocalNdisReadyInfo.Header.Revision = NDIS_WWAN_READY_INFO_REVISION_1; - LocalNdisReadyInfo.ReadyInfo.ReadyState = WwanReadyStateFailure; - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_READY_INFO - ); - - StatusIndication.StatusBuffer = &LocalNdisReadyInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_READY_INFO); - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] READY_STATE_FAILURE", Request->RequestId ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); -} - -VOID -MbbNdisIndicateReadyInfo( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - BOOLEAN IndicateReadyInfoFailure = TRUE; - ULONG NdisReadyInfoSize = Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfoSize; - PNDIS_WWAN_READY_INFO NdisReadyInfo = Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo; - - do - { - MBB_COMMAND NewCommand; - PMBB_REQUEST_CONTEXT NewRequest; - - // - // Track whether this is a indication or a response to a query. - // If this is a response to a query readyinfo then ndis indication needs to - // happen on any failure. In case of indications ignore failures. - // - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsFirstCid == 0 ) - { - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsFirstCid = 1; - - if( memcmp( - &Request->HandlerContext.Response.Command.ServiceId, - &MBB_UUID_BASIC_CONNECT, - sizeof(GUID) - ) == 0 - && - Request->HandlerContext.Response.Command.CommandId == MBB_BASIC_CID_SUBSCRIBER_READY_INFO - && - MbbReqMgrIsUnsolicitedIndication( Request ) == FALSE ) - { - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsQueryReadyInfo = 1; - } - } - // - // If the CID response wasnt receieved then bail out. - // - if( NdisStatus != NDIS_STATUS_SUCCESS ) - break; - // - // When switching FW in multi-carrier scenario the device - // indicates readystateoff and then re-enumerates. - // Thus the class driver will fail to query for emergencymode - // and smsconfiguration in this scenario and hence fail to - // indicate readystateoff. To forward the readystateoff - // indication to service fill in defaults on ReadyStateOff. - // - if( NdisReadyInfo != NULL && - WwanReadyStateOff == NdisReadyInfo->ReadyInfo.ReadyState ) - { - if( 0 == Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid ) - { - Request->HandlerContext.Parameters.SubscriberReadyInfo.WwanEmergencyMode = WwanEmergencyModeOff; - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid = 1; - } - - if( 0 == Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid ) - { - Request->HandlerContext.Parameters.SubscriberReadyInfo.CdmaShortMsgSize = WWAN_CDMA_SHORT_MSG_SIZE_UNKNOWN; - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid = 1; - } - } - // - // If we have all the information then indicate ready_info. - // - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo != NULL && - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid != 0 && - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid != 0 ) - { - ULONG ReadyInfoFlags; - PMINIPORT_ADAPTER_CONTEXT Adapter; - NDIS_STATUS_INDICATION StatusIndication; - - // - // Indicate NDIS_STATUS_WWAN_READY_INFO_FLAGS first. - // This is always a status indication. - // - Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle( Request ); - - if( 0 == Adapter->AdapterFlags.IsShowIMSI ) - ReadyInfoFlags = WWAN_CTRL_CAPS_PROTECT_UNIQUEID; - else - ReadyInfoFlags = 0; - - MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION( - &StatusIndication, - Adapter->MiniportAdapterHandle, - NDIS_STATUS_WWAN_RESERVED_2 - ); - StatusIndication.DestinationHandle = NULL; - StatusIndication.RequestId = 0; - StatusIndication.StatusBuffer = &ReadyInfoFlags; - StatusIndication.StatusBufferSize = sizeof(ULONG); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_READY_INFO_FLAGS", Request->RequestId ); - - NdisMIndicateStatusEx( - Adapter->MiniportAdapterHandle, - &StatusIndication - ); - // - // Now indicate NDIS_STATUS_WWAN_READY_INFO - // - NdisReadyInfo->ReadyInfo.EmergencyMode = Request->HandlerContext.Parameters.SubscriberReadyInfo.WwanEmergencyMode; - NdisReadyInfo->ReadyInfo.CdmaShortMsgSize = Request->HandlerContext.Parameters.SubscriberReadyInfo.CdmaShortMsgSize; - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_READY_INFO - ); - - StatusIndication.StatusBuffer = NdisReadyInfo; - StatusIndication.StatusBufferSize = NdisReadyInfoSize; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_READY_INFO size=%d", Request->RequestId, NdisReadyInfoSize ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - IndicateReadyInfoFailure = FALSE; - break; - } - // - // If we dont have any info then only indicate failure if this was a ready_info oid query. - // Fail the request in this case. - // - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo == NULL && - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid == 0 && - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid == 0 ) - { - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsQueryReadyInfo != 1 ) - { - IndicateReadyInfoFailure = FALSE; - } - break; - } - // - // We have something, get the other information. - // Select the next command to query - // - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo == NULL ) - { - NewCommand.ServiceId = MBB_UUID_BASIC_CONNECT; - NewCommand.CommandId = MBB_BASIC_CID_SUBSCRIBER_READY_INFO; - } else - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid == 0 ) - { - NewCommand.ServiceId = MBB_UUID_BASIC_CONNECT; - NewCommand.CommandId = MBB_BASIC_CID_EMERGENCY_MODE; - } else - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid == 0 ) - { - NewCommand.ServiceId = MBB_UUID_SMS; - NewCommand.CommandId = MBB_SMS_CID_CONFIGURATION; - } - - if( (NewRequest = MbbReqMgrCreateRequest( - Request->RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate Request for retrieving %s", - Request->RequestId, - MbbUtilGetCommandString( &NewCommand ) - ); - break; - } - NewRequest->OidHandler = MbbNdisGetOidHandlerByCommand( &NewCommand ); - // - // Cache the context from the previous request since it will be destroyed - // - NewRequest->OidContext.OidRequestId = Request->OidContext.OidRequestId; - NewRequest->OidContext.OidRequestHandle = Request->OidContext.OidRequestHandle; - NewRequest->HandlerContext.Parameters.SubscriberReadyInfo = Request->HandlerContext.Parameters.SubscriberReadyInfo; - // - // Dispatch the new CID request - // - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Dispatching Request[ReqId=0x%04x] for %s", - Request->RequestId, - NewRequest->RequestId, - MbbUtilGetCommandString( &NewCommand ) - ); - NdisStatus = MbbReqMgrDispatchRequest( - NewRequest, - (NewRequest->OidHandler->IsSerialized == 1), - MbbUtilInternalCIDQuery, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If dispatch failed, then indicate ReadyInfoFailure - // - if( NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to dispatch %s, NdisStatus=%!STATUS!", - NewRequest->RequestId, - MbbUtilGetCommandString( &NewCommand ), - NdisStatus - ); - MbbReqMgrDestroyRequest( - NewRequest->RequestManager, - NewRequest - ); - break; - } - // - // The status handler will take care of the rest. - // - NdisReadyInfo = NULL; - IndicateReadyInfoFailure = FALSE; - } - while( FALSE ); - - if( IndicateReadyInfoFailure && - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsQueryReadyInfo == 1 ) - { - MbbNdisIndicateReadyInfoFailure( Request ); - } - - if( NdisReadyInfo != NULL ) - FREE_POOL( NdisReadyInfo ); -} - -NDIS_STATUS -MbbNdisReadyInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - ULONG ElementIndex; - ULONG ElementCount; - ULONGLONG NdisReadyInfoSize = 0; - ULONGLONG MbbReadyInfoSize; - PNDIS_WWAN_READY_INFO NdisReadyInfo = NULL; - PMBB_SUBSCRIBER_READY_INFO MbbReadyInfo = (PMBB_SUBSCRIBER_READY_INFO)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter; - - // - // Extract partial ready_info from the response / indication buffer - // - do - { - Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle( Request ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_READY_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, WwanStatus=%!WwanStatus!. MbbStatus=%!MbbStatus!", - Request->RequestId, - WwanStatus, - MbbStatus - ); - - NdisStatus=WwanStatus; - - break; - } - - - if( MbbReadyInfo == NULL || - InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBER_READY_INFO, TelephoneNumberCount) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_READY_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBER_READY_INFO, TelephoneNumberCount) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - - ElementCount = MbbReadyInfo->TelephoneNumberCount; - - if (ElementCount > MBB_MAX_READY_INFO_PHONE_NUMBERS) - { - TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Too many phone numbers NDIS_STATUS_WWAN_READY_INFO, %d Truncating", - Request->RequestId, - ElementCount - ); - - ElementCount = MBB_MAX_READY_INFO_PHONE_NUMBERS; - } - - - MbbReadyInfoSize = FIELD_OFFSET(MBB_SUBSCRIBER_READY_INFO, TelephoneNumbers) + ((ULONGLONG)ElementCount * sizeof(MBB_STRING)); - NdisReadyInfoSize = sizeof(NDIS_WWAN_READY_INFO) + ((ULONGLONG)ElementCount * WWAN_TN_LEN * sizeof(WCHAR)); - - if( InBufferSize < MbbReadyInfoSize ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_READY_INFO, BufferSize[Received=%d Expected=%I64u] TNCount=%d", - Request->RequestId, - InBufferSize, - MbbReadyInfoSize, - MbbReadyInfo->TelephoneNumberCount - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - -#ifndef MBIM081d - if (MbbReadyInfo->SubscriberId.Size > (MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH) * sizeof(WCHAR)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] truncating SubScriberSize from %d to %d", Request->RequestId, MbbReadyInfo->SubscriberId.Size, (MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH) * sizeof(WCHAR)); - - MbbReadyInfo->SubscriberId.Size=(MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH) * sizeof(WCHAR); - } -#endif - - if( MbbIsVariableFieldValid( - InBufferSize, - MbbReadyInfo->SubscriberId.Offset, - MbbReadyInfo->SubscriberId.Size, - MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH, - sizeof(WCHAR) - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID MBB_SUBSCRIBER_READY_INFO.SubscriberId Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - Request->RequestId, - MbbReadyInfo->SubscriberId.Offset, - InBufferSize, - MbbReadyInfo->SubscriberId.Size, - MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH * sizeof(WCHAR) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - -#ifndef MBIM081d - if (MbbReadyInfo->SimIccId.Size > (MBB_MAXIMUM_SIM_ICC_ID_LENGTH) * sizeof(WCHAR)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] truncating SimIcci from %d to %d", Request->RequestId, MbbReadyInfo->SimIccId.Size, (MBB_MAXIMUM_SIM_ICC_ID_LENGTH) * sizeof(WCHAR)); - - MbbReadyInfo->SimIccId.Size=(MBB_MAXIMUM_SIM_ICC_ID_LENGTH) * sizeof(WCHAR); - } -#endif - - if( MbbIsVariableFieldValid( - InBufferSize, - MbbReadyInfo->SimIccId.Offset, - MbbReadyInfo->SimIccId.Size, - MBB_MAXIMUM_SIM_ICC_ID_LENGTH, - sizeof(WCHAR) - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID MBB_SUBSCRIBER_READY_INFO.SimIccId Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - Request->RequestId, - MbbReadyInfo->SimIccId.Offset, - InBufferSize, - MbbReadyInfo->SimIccId.Size, - MBB_MAXIMUM_SIM_ICC_ID_LENGTH * sizeof(WCHAR) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - for( ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex ++ ) - { - ULONG TelNumLen = Adapter->BusParams.IsErrataDevice ? MBB_MAXIMUM_TELEPHONE_NUMBER_ERRATA_LENGTH : MBB_MAXIMUM_TELEPHONE_NUMBER_LENGTH; - - if( MbbIsVariableFieldValid( - InBufferSize, - MbbReadyInfo->TelephoneNumbers[ElementIndex].Offset, - MbbReadyInfo->TelephoneNumbers[ElementIndex].Size, - TelNumLen, - sizeof(WCHAR) - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID MBB_SUBSCRIBER_READY_INFO.TelephoneNumber[%d] Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - Request->RequestId, - ElementIndex, - MbbReadyInfo->TelephoneNumbers[ElementIndex].Offset, - InBufferSize, - MbbReadyInfo->TelephoneNumbers[ElementIndex].Size, - TelNumLen * sizeof(WCHAR) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - } - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - break; - } - - if( (NdisReadyInfo = ALLOCATE_NONPAGED_POOL( (SIZE_T)NdisReadyInfoSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %I64u bytes for NDIS_STATUS_WWAN_READY_INFO, TNCount=%d", - Request->RequestId, - NdisReadyInfoSize, - MbbReadyInfo->TelephoneNumberCount - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - NdisReadyInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisReadyInfo->Header.Size = sizeof(NDIS_WWAN_READY_INFO); - NdisReadyInfo->Header.Revision = NDIS_WWAN_READY_INFO_REVISION_1; - - Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfoSize = (ULONG)NdisReadyInfoSize; - Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo = NdisReadyInfo; - - MbbUtilMbbToWwanReadyInfo( - MbbReadyInfo, - &NdisReadyInfo->ReadyInfo - ); - - if( ( - MbbReadyInfo->ReadyState == MbbReadyStateInitialized || - MbbReadyInfo->ReadyState == MbbReadyStateNotActivated || - MbbReadyInfo->ReadyState == MbbReadyStateDeviceLocked - ) && - ! ( MbbReadyInfo->ReadyInfoFlags & MbbReadyInfoFlagsUniqueId ) ) - { - Adapter->AdapterFlags.IsShowIMSI = TRUE; - } - else - { - Adapter->AdapterFlags.IsShowIMSI = FALSE; - } - } - while( FALSE ); - - MbbNdisIndicateReadyInfo( - Request, - NdisStatus - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisEmergencyModeStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -/*++ - Description: - This routine does not do a NDIS indication for a CID indication - because there is no EMERGENCY_MODE ndis indication. EmergencyMode - is indicated via ReadyInfo. This routine instead does a ReadyInfo - indication. To do so this routine will query ReadyInfo and SmsConfiguration. ---*/ -{ - MBB_EMERGENCY_MODE* MbbEmergencyMode = (MBB_EMERGENCY_MODE*)InBuffer; - - do - { - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for MBB_BASIC_CID_EMERGENCY_MODE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - if( MbbStatus != MBB_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for MBB_BASIC_CID_EMERGENCY_MODE, status=%!MbbStatus!", - Request->RequestId, - MbbStatus - ); - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - - if( MbbEmergencyMode == NULL || - InBufferSize < sizeof(MBB_EMERGENCY_MODE) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_BASIC_CID_EMERGENCY_MODE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_EMERGENCY_MODE) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] EMERGENCY_MODE=%d indication received", - Request->RequestId, - *MbbEmergencyMode - ); - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid = 1; - Request->HandlerContext.Parameters.SubscriberReadyInfo.WwanEmergencyMode = (WWAN_EMERGENCY_MODE)*MbbEmergencyMode; - } - while( FALSE ); - // - // Internal requests are created for indicating ready info. - // Do not fail ready info if emergency mode cannot be queried. - // - if( MbbReqMgrIsInternalRequest( Request ) == TRUE || - NdisStatus != NDIS_STATUS_SUCCESS ) - { - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsWwanEmergencyModeValid = 1; - Request->HandlerContext.Parameters.SubscriberReadyInfo.WwanEmergencyMode = WwanEmergencyModeOff; - NdisStatus = NDIS_STATUS_SUCCESS; - } - - MbbNdisIndicateReadyInfo( - Request, - NdisStatus - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisRadioStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS HandlerNdisStatus = NDIS_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_RADIO_STATE NdisRadioState; - PMBB_QUERY_RADIO_STATE MbbRadioState = (PMBB_QUERY_RADIO_STATE)InBuffer; - NDIS_STRING RadioOffRegString = RTL_CONSTANT_STRING(MBB_REGVAL_RADIO_OFF); - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - - do - { - RtlZeroMemory(&NdisRadioState, sizeof(NdisRadioState)); - - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_RADIO_STATE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!STATUS!", - Request->RequestId, - WwanStatus - ); - - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - - if( MbbRadioState == NULL || - InBufferSize < sizeof(MBB_QUERY_RADIO_STATE) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_RADIO_STATE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_QUERY_RADIO_STATE) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MBIM radio state hw=%d, sw=%d", - Request->RequestId, - MbbRadioState->HwRadioState, - MbbRadioState->SwRadioState - ); - - - // - // We will be sending the radio state notification up. - // If this is a set requested by the OS and the request - // succeeded, persist the radio state in registry and locally - // - if ((Request->OidContext.OidRequestId != 0) && - (MbbReqMgrIsSetOid( Request )) && - (WwanStatus == WWAN_STATUS_SUCCESS) ) - { - // - // OS initiated SET request that succeeded. The set action - // was saved in the Parameters portion of the request. - // Persist it - // - if (Request->HandlerContext.Parameters.RadioState.SetAction == WwanRadioOff) - { - // Radio OFF was requested & has successfully completed - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Persisting RadioState OFF", - Request->RequestId - ); - Request->RequestManager->AdapterContext->RadioOff = TRUE; - } - else - { - // Radio ON was requested & has successfully completed - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Persisting RadioState ON", - Request->RequestId - ); - Request->RequestManager->AdapterContext->RadioOff = FALSE; - } - - HandlerNdisStatus = MbbNdisAdapterWriteBoolParameter( - Adapter, - Adapter->RadioOff, - &RadioOffRegString - ); - if (HandlerNdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Failed to persist Radio state in registry, status=%!STATUS!", - Request->RequestId, - HandlerNdisStatus - ); - // We still indicate the current radio state to the OS - } - - } - - MbbUtilMbbToWwanRadioState( - &MbbRadioState->HwRadioState, - &NdisRadioState.RadioState.HwRadioState - ); - - MbbUtilMbbToWwanRadioState( - &MbbRadioState->SwRadioState, - &NdisRadioState.RadioState.SwRadioState - ); - } - while( FALSE ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceLoggingWrite( - g_hLoggingProvider, - "RadioStateFailure", - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); - PMBB_SEND_QUEUE SendQueue = &((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request))->SendQueue; - TryQueueStallState(SendQueue); - } - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if( MbbReqMgrIsInternalRequest( Request ) == FALSE || - ( - MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE && - NdisStatus == NDIS_STATUS_SUCCESS - ) ) - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_RADIO_STATE - ); - - NdisRadioState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisRadioState.Header.Size = sizeof(NDIS_WWAN_RADIO_STATE); - NdisRadioState.Header.Revision = NDIS_WWAN_RADIO_STATE_REVISION_1; - NdisRadioState.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisRadioState; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_RADIO_STATE); - - if ((Request->RequestManager->AdapterContext->RadioOff && (NdisRadioState.RadioState.SwRadioState != WwanRadioOff)) - || - (!Request->RequestManager->AdapterContext->RadioOff && (NdisRadioState.RadioState.SwRadioState != WwanRadioOn))) - { - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] reported radio state does not match it was configured to. config=%!BOOLEAN!, reported=%d", - Request->RequestId, - Request->RequestManager->AdapterContext->RadioOff, - NdisRadioState.RadioState.SwRadioState - ); - } - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_RADIO_STATE SwState=%u with status=%!WwanStatus!", - Request->RequestId, - NdisRadioState.RadioState.SwRadioState, - WwanStatus - ); - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - } - // - // If this request was submitted internally during adapter init - // then check if the radio state is set correctly. - // NOTE: Assumption that only adapter init path submits internal radio state request. - // - if( MbbReqMgrIsInternalRequest( Request ) == TRUE && - NdisStatus == NDIS_STATUS_SUCCESS ) - { - // Check if we are in the right state now - if (Adapter->RadioOff) - { - // We configured Software Radio OFF - if (MbbRadioState->SwRadioState != MbbRadioStateOff) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] Invalid radio state after ConfigureRadioState, Received ON Expected OFF"); - HandlerNdisStatus = NDIS_STATUS_INVALID_STATE; - } - } - else - { - // We configured Software Radio ON - if (MbbRadioState->SwRadioState != MbbRadioStateOn) - { - TraceError( WMBCLASS_INIT, "[MbbAdapter] Invalid radio state after ConfigureRadioState, Received OFF Expected ON"); - HandlerNdisStatus = NDIS_STATUS_INVALID_STATE; - } - } - } - - return HandlerNdisStatus; -} - -NDIS_STATUS -MbbNdisPinInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_PIN_INFO NdisPinInfo; - PMBB_PIN_INFO MbbPinInfo = (PMBB_PIN_INFO)InBuffer; - - do - { - RtlZeroMemory(&NdisPinInfo, sizeof(NdisPinInfo)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PIN_INFO - ); - - NdisPinInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisPinInfo.Header.Size = sizeof(NDIS_WWAN_PIN_INFO); - NdisPinInfo.Header.Revision = NDIS_WWAN_PIN_INFO_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PIN_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - - if( MbbPinInfo == NULL || - InBufferSize < sizeof(MBB_PIN_INFO) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PIN_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_PIN_INFO) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanPinInfo( - MbbPinInfo, - &NdisPinInfo.PinInfo - ); - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisPinInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisPinInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PIN_INFO); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PIN_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisPinListStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_PIN_LIST NdisPinList; - PMBB_PIN_LIST MbbPinList = (PMBB_PIN_LIST)InBuffer; - - do - { - RtlZeroMemory(&NdisPinList, sizeof(NdisPinList)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PIN_LIST - ); - - NdisPinList.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisPinList.Header.Size = sizeof(NDIS_WWAN_PIN_LIST); - NdisPinList.Header.Revision = NDIS_WWAN_PIN_LIST_REVISION_1; - NdisPinList.uStatus = NdisStatus; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PIN_LIST, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!STATUS!", - Request->RequestId, - WwanStatus - ); - - break; - } - - - if( MbbPinList == NULL || - InBufferSize < sizeof(MBB_PIN_LIST) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PIN_LIST, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_PIN_DESCRIPTION) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanPinList( - MbbPinList, - &NdisPinList.PinList - ); - } while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisPinList.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisPinList; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PIN_LIST); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PIN_LIST with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisHomeProviderStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_WWAN_HOME_PROVIDER2 NdisHomeProvider2; - NDIS_STATUS_INDICATION StatusIndication; - PMBB_PROVIDER MbbProvider = (PMBB_PROVIDER)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); - BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); - ULONG AdapterDataClass; - - do - { - RtlZeroMemory(&NdisHomeProvider2, sizeof(NdisHomeProvider2)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - MbbReqMgrIsSetOid( Request )? NDIS_STATUS_WWAN_SET_HOME_PROVIDER_COMPLETE : NDIS_STATUS_WWAN_HOME_PROVIDER - ); - - NdisHomeProvider2.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisHomeProvider2.Header.Size = sizeof(NDIS_WWAN_HOME_PROVIDER2); - NdisHomeProvider2.Header.Revision = NDIS_WWAN_HOME_PROVIDER_REVISION_2; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_HOME_PROVIDER, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!STATUS!", - Request->RequestId, - WwanStatus - ); - break; - } - - if( MbbUtilValidateMbbProvider( - InBufferSize, - MbbProvider - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to validate data for NDIS_STATUS_WWAN_HOME_PROVIDER", - Request->RequestId - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbAdapterGetDataClass( Adapter, &AdapterDataClass ); - - MbbUtilMbbToWwanProvider2( - MbbProvider, - AdapterDataClass, - &NdisHomeProvider2.Provider - ); - } - while( FALSE); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisHomeProvider2.uStatus = WwanStatus; - StatusIndication.StatusBuffer = &NdisHomeProvider2; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_HOME_PROVIDER2); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_HOME_PROVIDER for %s-carrier with status=%!WwanStatus!", - Request->RequestId, - IsMultiCarrierCapable? "Multi": "Single", - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisPreferredProviderStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - ULONG AdapterDataClass; - PMBB_PROVIDER_LIST MbbPreferredProviders = (PMBB_PROVIDER_LIST)InBuffer; - NDIS_STATUS_INDICATION StatusIndication; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); - BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); - ULONGLONG NdisPreferredProvidersSize = 0; - PNDIS_WWAN_PREFERRED_PROVIDERS NdisPreferredProviders = NULL; - NDIS_WWAN_PREFERRED_PROVIDERS LocalNdisPreferredProviders; - ULONG MulTemp = 0; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - RtlZeroMemory(&LocalNdisPreferredProviders, sizeof(LocalNdisPreferredProviders)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PREFERRED_PROVIDERS - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PREFERRED_PROVIDERS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - // - // On error there is no data buffer. - // - if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - break; - } - // - // On set requests the MB Driver Model requires that the preferred provider list is empty. - // - if( MbbReqMgrIsSetOid( Request ) == TRUE ) - { - break; - } - // - // Validate the received data and every provider structure in the list. - // - if( MbbUtilValidateMbbProviderList( - InBufferSize, - MbbPreferredProviders - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to validate MBB_PROVIDER_LIST", - Request->RequestId - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - // - // Convert the provider_list to the WWAN format. - // - if (MbbPreferredProviders->ProviderCount > MBB_MAX_PROVIDER_LIST_SIZE) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Provider count exceeds max, MbbPreferredProviders->ProviderCount=%d", - Request->RequestId, - MbbPreferredProviders->ProviderCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - - NtStatus = RtlULongMult( - MbbPreferredProviders->ProviderCount, - sizeof(WWAN_PROVIDER2), - &MulTemp - ); - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbPreferredProviders->ProviderCount=%d WWAN_PROVIDER2 size=%d", - Request->RequestId, - MbbPreferredProviders->ProviderCount, - sizeof(WWAN_PROVIDER2) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisPreferredProvidersSize = sizeof(NDIS_WWAN_PREFERRED_PROVIDERS); - NdisPreferredProvidersSize += MulTemp; - - if( NdisPreferredProvidersSize > ULONG_MAX || - (NdisPreferredProviders = (PNDIS_WWAN_PREFERRED_PROVIDERS)ALLOCATE_NONPAGED_POOL( (ULONG)NdisPreferredProvidersSize ) ) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_PREFERRED_PROVIDERS, ProviderCount=%d", - Request->RequestId, - (ULONG)NdisPreferredProvidersSize, - MbbPreferredProviders->ProviderCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisPreferredProviders->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisPreferredProviders->Header.Size = sizeof(NDIS_WWAN_PREFERRED_PROVIDERS); - NdisPreferredProviders->Header.Revision = NDIS_WWAN_PREFERRED_PROVIDERS_REVISION_1; - - MbbAdapterGetDataClass( Adapter, &AdapterDataClass ); - - MbbUtilMbbToWwanProviderList( - MbbPreferredProviders, - AdapterDataClass, - IsMultiCarrierCapable, - &NdisPreferredProviders->PreferredListHeader - ); - } - while( FALSE ); - - if( NdisPreferredProviders == NULL ) - { - LocalNdisPreferredProviders.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisPreferredProviders.Header.Size = sizeof(NDIS_WWAN_PREFERRED_PROVIDERS); - LocalNdisPreferredProviders.Header.Revision = NDIS_WWAN_PREFERRED_PROVIDERS_REVISION_1; - - LocalNdisPreferredProviders.PreferredListHeader.ElementCount = 0; - LocalNdisPreferredProviders.PreferredListHeader.ElementType = WwanStructProvider2; - - StatusIndication.StatusBuffer = &LocalNdisPreferredProviders; - StatusIndication.StatusBufferSize = sizeof(LocalNdisPreferredProviders); - } - else - { - StatusIndication.StatusBuffer = NdisPreferredProviders; - StatusIndication.StatusBufferSize = (ULONG)NdisPreferredProvidersSize; - } - ((PNDIS_WWAN_PREFERRED_PROVIDERS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PREFERRED_PROVIDERS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if( NdisPreferredProviders != NULL ) - FREE_POOL( NdisPreferredProviders ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisVisibleProviderStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - ULONG AdapterDataClass; - PMBB_PROVIDER_LIST MbbVisibleProviders = (PMBB_PROVIDER_LIST)InBuffer; - NDIS_STATUS_INDICATION StatusIndication; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); - BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); - ULONGLONG NdisVisibleProvidersSize = 0; - PNDIS_WWAN_VISIBLE_PROVIDERS NdisVisibleProviders = NULL; - NDIS_WWAN_VISIBLE_PROVIDERS LocalNdisVisibleProviders; - ULONG MulTemp = 0; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - RtlZeroMemory(&LocalNdisVisibleProviders, sizeof(LocalNdisVisibleProviders)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_VISIBLE_PROVIDERS - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_VISIBLE_PROVIDERS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - // - // On error there is no data buffer. - // - if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - break; - } - // - // Validate the received data and every provider structure in the list. - // - if( MbbUtilValidateMbbProviderList( - InBufferSize, - MbbVisibleProviders - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to validate MBB_PROVIDER_LIST", - Request->RequestId - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // - // Convert the provider_list to the WWAN format. - // - if (MbbVisibleProviders->ProviderCount > MBB_MAX_PROVIDER_LIST_SIZE) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Provider count exceeds max, MbbPreferredProviders->ProviderCount=%d", - Request->RequestId, - MbbVisibleProviders->ProviderCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - - // - // Convert the provider_list to the WWAN format. - // - NtStatus = RtlULongMult( - MbbVisibleProviders->ProviderCount, - sizeof(WWAN_PROVIDER2), - &MulTemp - ); - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbVisibleProviders->ProviderCount=%d WWAN_PROVIDER2 size=%d", - Request->RequestId, - MbbVisibleProviders->ProviderCount, - sizeof(WWAN_PROVIDER2) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisVisibleProvidersSize = sizeof(NDIS_WWAN_VISIBLE_PROVIDERS); - NdisVisibleProvidersSize += MulTemp; - - if( NdisVisibleProvidersSize > ULONG_MAX || - (NdisVisibleProviders = (PNDIS_WWAN_VISIBLE_PROVIDERS)ALLOCATE_NONPAGED_POOL( (ULONG)NdisVisibleProvidersSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_VISIBLE_PROVIDERS, ProviderCount=%d", - Request->RequestId, - (ULONG)NdisVisibleProvidersSize, - MbbVisibleProviders->ProviderCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisVisibleProviders->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisVisibleProviders->Header.Size = sizeof(NDIS_WWAN_VISIBLE_PROVIDERS); - NdisVisibleProviders->Header.Revision = NDIS_WWAN_VISIBLE_PROVIDERS_REVISION_1; - - MbbAdapterGetDataClass( Adapter, &AdapterDataClass ); - - MbbUtilMbbToWwanProviderList( - MbbVisibleProviders, - AdapterDataClass, - IsMultiCarrierCapable, - &NdisVisibleProviders->VisibleListHeader - ); - } - while( FALSE ); - - if( NdisVisibleProviders == NULL ) - { - LocalNdisVisibleProviders.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisVisibleProviders.Header.Size = sizeof(NDIS_WWAN_VISIBLE_PROVIDERS); - LocalNdisVisibleProviders.Header.Revision = NDIS_WWAN_VISIBLE_PROVIDERS_REVISION_1; - - LocalNdisVisibleProviders.VisibleListHeader.ElementCount = 0; - LocalNdisVisibleProviders.VisibleListHeader.ElementType = WwanStructProvider2; - - StatusIndication.StatusBuffer = &LocalNdisVisibleProviders; - StatusIndication.StatusBufferSize = sizeof(LocalNdisVisibleProviders); - } - else - { - StatusIndication.StatusBuffer = NdisVisibleProviders; - StatusIndication.StatusBufferSize = (ULONG)NdisVisibleProvidersSize; - } - ((PNDIS_WWAN_VISIBLE_PROVIDERS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_VISIBLE_PROVIDERS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if( NdisVisibleProviders != NULL ) - FREE_POOL( NdisVisibleProviders ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisRegisterStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_REGISTRATION_STATE NdisRegistrationState; - PMBB_REGISTRATION_STATE MbbRegistrationState = (PMBB_REGISTRATION_STATE)InBuffer; - - do - { - RtlZeroMemory(&NdisRegistrationState,sizeof(NdisRegistrationState)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_REGISTER_STATE - ); - - NdisRegistrationState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisRegistrationState.Header.Size = sizeof(NDIS_WWAN_REGISTRATION_STATE); - NdisRegistrationState.Header.Revision = NDIS_WWAN_REGISTRATION_STATE_REVISION_2; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_REGISTER_STATE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - - if( MbbRegistrationState == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_REGISTRATION_STATE, DataBuffer) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_REGISTER_STATE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_REGISTRATION_STATE) - ); - WwanStatus = WWAN_STATUS_FAILURE; - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - // - // pick this up now so we can return it in the case of an error - // - NdisRegistrationState.RegistrationState.uNwError=MbbRegistrationState->NetworkError; - - if ( WwanStatus != WWAN_STATUS_SUCCESS ) - { - NdisStatus = NDIS_STATUS_FAILURE; - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad status for NDIS_STATUS_WWAN_REGISTER_STATE, mbbstatus=%!MbbStatus!", - Request->RequestId, - MbbStatus - ); - - break; - } - - - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbRegistrationState->ProviderId.Offset, - MbbRegistrationState->ProviderId.Size, - MBB_MAXIMUM_PROVIDER_ID_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad provider id field, Offset=%d, Size=%d", - Request->RequestId, - MbbRegistrationState->ProviderId.Offset, - MbbRegistrationState->ProviderId.Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - - } - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbRegistrationState->ProviderName.Offset, - MbbRegistrationState->ProviderName.Size, - MBB_MAXIMUM_PROVIDER_NAME_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad provider Name field, Offset=%d, Size=%d", - Request->RequestId, - MbbRegistrationState->ProviderName.Offset, - MbbRegistrationState->ProviderName.Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - - } - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbRegistrationState->RoamingText.Offset, - MbbRegistrationState->RoamingText.Size, - MBB_MAXIMUM_ROAMING_TEXT_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad provider roaming text, Offset=%d, Size=%d", - Request->RequestId, - MbbRegistrationState->RoamingText.Offset, - MbbRegistrationState->RoamingText.Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - - } - - if( ( - MBB_IS_DEVICE_REGISTERED( MbbRegistrationState->RegisterState ) && - MbbRegistrationState->CurrentCellularClass == MbbCellularClassInvalid - ) || - MbbRegistrationState->CurrentCellularClass >= MbbCellularClassMaximum ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID CurrentCellularClass=0x%x", - Request->RequestId, - MbbRegistrationState->CurrentCellularClass - ); - WwanStatus = WWAN_STATUS_FAILURE; - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - MbbUtilMbbToWwanRegistrationState( - MbbRegistrationState, - &NdisRegistrationState.RegistrationState - ); - - Adapter->AvailableDataClassValid=TRUE; - Adapter->AvailableDataClass=MbbRegistrationState->AvailableDataClasses; - - MbbAdapterSetCurrentCellularClass(Adapter, MbbRegistrationState->CurrentCellularClass); - } - while( FALSE ); - - // - // When to do SMS Configuration indication - - // - This is a response to a OID query - // - This is an unsolicited indication - // When to do Ready Info indication - - // - This is a response to an internal query - // - This is an unsolicited indication - // - - - - if (!MbbReqMgrIsInternalRequest( Request ) || MbbReqMgrIsUnsolicitedIndication( Request )) - { - - // - // Not an internal request, external reaponse or indication - // - if (!MbbReqMgrIsUnsolicitedIndication( Request ) || (NdisStatus == NDIS_STATUS_SUCCESS)) - { - - // - // response or it is an unsolicited indication the was processed without error, - // don't propagate indication that don't parse - // - - NdisRegistrationState.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisRegistrationState; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_REGISTRATION_STATE); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_REGISTER_STATE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - } - } - - if( MbbReqMgrIsInternalRequest( Request ) || - ( - ( NdisStatus == NDIS_STATUS_SUCCESS ) && - MBB_IS_DEVICE_REGISTERED( MbbRegistrationState->RegisterState ) - ) ) - { - // - // it is an internal request which needs to be complete regardless, or it external or unsolictied indication that succeeded - // and is in a registered state. - // run the packet service locic to send a packet service with updated data classes. - // - - Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid = 1; - Request->HandlerContext.Parameters.PacketServiceState.AvailableDataClass = WWAN_DATA_CLASS_NONE; - - if( NdisStatus == NDIS_STATUS_SUCCESS ) - { - Request->HandlerContext.Parameters.PacketServiceState.AvailableDataClass = MbbRegistrationState->AvailableDataClasses; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Saving AvailableDataClass %08lx for Packet Service in registerstate=%d", - Request->RequestId, - MbbRegistrationState->AvailableDataClasses, - MbbRegistrationState->RegisterState - ); - - - } - - - MbbNdisIndicatePacketService( - Request, - NdisStatus - ); - - } - - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisMulticarrierProviderStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - ULONG AdapterDataClass; - PMBB_PROVIDER_LIST MbbPreferredProviders = (PMBB_PROVIDER_LIST)InBuffer; - NDIS_STATUS_INDICATION StatusIndication; - PMINIPORT_ADAPTER_CONTEXT Adapter = MbbReqMgrGetAdapterHandle( Request ); - BOOLEAN IsMultiCarrierCapable = MbbAdapterIsMultiCarrierCapable( Adapter ); - ULONGLONG NdisPreferredProvidersSize = 0; - - PNDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS NdisPreferredProviders = NULL; - NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS LocalNdisPreferredProviders; - - do - { - RtlZeroMemory(&LocalNdisPreferredProviders, sizeof(LocalNdisPreferredProviders)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, - "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - // - // On error there is no data buffer. - // - if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) - { - break; - } - // - // On set requests the MB Driver Model requires that the preferred provider list is empty. - // - if( MbbReqMgrIsSetOid( Request ) == TRUE ) - { - break; - } - - if(!IsMultiCarrierCapable) - { - break; - } - - // - // Validate the received data and every provider structure in the list. - // - if( MbbUtilValidateMbbProviderList( - InBufferSize, - MbbPreferredProviders - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to validate MBB_PROVIDER_LIST", - Request->RequestId - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // - // Convert the provider_list to the WWAN format. - // - if (MbbPreferredProviders->ProviderCount > MBB_MAX_PROVIDER_LIST_SIZE) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Provider count exceeds max, MbbPreferredProviders->ProviderCount=%d", - Request->RequestId, - MbbPreferredProviders->ProviderCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - // - // Convert the provider_list to the WWAN format. - // - NdisPreferredProvidersSize = sizeof(NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS); - NdisPreferredProvidersSize += ( (ULONGLONG)MbbPreferredProviders->ProviderCount * sizeof(WWAN_PROVIDER2) ); - - if( NdisPreferredProvidersSize > ULONG_MAX || - (NdisPreferredProviders = (PNDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS)ALLOCATE_NONPAGED_POOL( (ULONG)NdisPreferredProvidersSize ) ) == NULL ) - { - TraceError( WMBCLASS_OID, - "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS, ProviderCount=%d", - Request->RequestId, - (ULONG)NdisPreferredProvidersSize, - MbbPreferredProviders->ProviderCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisPreferredProviders->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisPreferredProviders->Header.Size = sizeof(NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS); - NdisPreferredProviders->Header.Revision = NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS_REVISION_1; - - MbbAdapterGetDataClass( Adapter, &AdapterDataClass ); - - MbbUtilMbbToWwanProviderList( - MbbPreferredProviders, - AdapterDataClass, - TRUE, - &NdisPreferredProviders->PreferredListHeader - ); - } - while( FALSE ); - - if( NdisPreferredProviders == NULL ) - { - LocalNdisPreferredProviders.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisPreferredProviders.Header.Size = sizeof(NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS); - LocalNdisPreferredProviders.Header.Revision = NDIS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS_REVISION_1; - - LocalNdisPreferredProviders.PreferredListHeader.ElementCount = 0; - LocalNdisPreferredProviders.PreferredListHeader.ElementType = WwanStructProvider2; - - StatusIndication.StatusBuffer = &LocalNdisPreferredProviders; - StatusIndication.StatusBufferSize = sizeof(LocalNdisPreferredProviders); - } - else - { - StatusIndication.StatusBuffer = NdisPreferredProviders; - StatusIndication.StatusBufferSize = (ULONG)NdisPreferredProvidersSize; - } - ((PNDIS_WWAN_PREFERRED_PROVIDERS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PREFERRED_MULTICARRIER_PROVIDERS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if( NdisPreferredProviders != NULL ) - FREE_POOL( NdisPreferredProviders ); - - return NDIS_STATUS_SUCCESS; -} - -VOID -MbbNdisIndicatePacketServiceFailure( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS Status - ) -{ - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_PACKET_SERVICE_STATE LocalNdisPacketService; - - RtlZeroMemory( - &LocalNdisPacketService, - sizeof(LocalNdisPacketService) - ); - - LocalNdisPacketService.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisPacketService.Header.Size = sizeof(NDIS_WWAN_PACKET_SERVICE_STATE); - LocalNdisPacketService.Header.Revision = NDIS_WWAN_PACKET_SERVICE_STATE_REVISION_1; - - LocalNdisPacketService.uStatus=Status; - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PACKET_SERVICE - ); - - StatusIndication.StatusBuffer = &LocalNdisPacketService; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PACKET_SERVICE_STATE); - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] PACKET_SERVICE_FAILURE", Request->RequestId ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); -} - -VOID -MbbNdisIndicatePacketService( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - - BOOLEAN IndicateFailure = TRUE; - ULONG NdisPacketServiceStateSize = Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceStateSize; - PNDIS_WWAN_PACKET_SERVICE_STATE NdisPacketServiceState = Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState; - - do - { - MBB_COMMAND NewCommand; - PMBB_REQUEST_CONTEXT NewRequest; - - // - // Track whether this is a indication or a response to a query. - // If this is a response to a query readyinfo then ndis indication needs to - // happen on any failure. In case of indications ignore failures. - // - if( Request->HandlerContext.Parameters.PacketServiceState.IsFirstCid == 0 ) - { - Request->HandlerContext.Parameters.PacketServiceState.IsFirstCid = 1; - - if( memcmp( - &Request->HandlerContext.Response.Command.ServiceId, - &MBB_UUID_BASIC_CONNECT, - sizeof(GUID) - ) == 0 - && - Request->HandlerContext.Response.Command.CommandId == MBB_BASIC_CID_PACKET_SERVICE - && - !MbbReqMgrIsUnsolicitedIndication( Request ) ) - { - Request->HandlerContext.Parameters.PacketServiceState.IsQuery = 1; - } - } - - // - // If the CID response wasnt receieved then bail out. - // - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - break; - } - - // - // If we have all the information then indicate ready_info. - // - if( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState != NULL && - Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid != 0 ) - { - NDIS_STATUS_INDICATION StatusIndication; - - NdisPacketServiceState->PacketService.AvailableDataClass = Request->HandlerContext.Parameters.PacketServiceState.AvailableDataClass; - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PACKET_SERVICE - ); - - StatusIndication.StatusBuffer = NdisPacketServiceState; - StatusIndication.StatusBufferSize = NdisPacketServiceStateSize; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PACKET_SERVICE size=%d", Request->RequestId, NdisPacketServiceStateSize ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - IndicateFailure = FALSE; - break; - } - // - // If we dont have any info then only indicate failure if this was a ready_info oid query. - // Fail the request in this case. - // - if( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState == NULL && - Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid == 0 ) - { - if( Request->HandlerContext.Parameters.PacketServiceState.IsQuery != 1 ) - { - IndicateFailure = FALSE; - } - break; - } - // - // We have something, get the other information. - // Select the next command to query - // - if( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState == NULL ) - { - NewCommand.ServiceId = MBB_UUID_BASIC_CONNECT; - NewCommand.CommandId = MBB_BASIC_CID_PACKET_SERVICE; - } else - if( Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid == 0 ) - { - NewCommand.ServiceId = MBB_UUID_BASIC_CONNECT; - NewCommand.CommandId = MBB_BASIC_CID_REGISTER_STATE; - } - - if( (NewRequest = MbbReqMgrCreateRequest( - Request->RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate Request for retrieving %s", - Request->RequestId, - MbbUtilGetCommandString( &NewCommand ) - ); - break; - } - NewRequest->OidHandler = MbbNdisGetOidHandlerByCommand( &NewCommand ); - // - // Cache the context from the previous request since it will be destroyed - // - if (Request->HandlerContext.Parameters.PacketServiceState.IsQuery) - { - // - // if this is the packet service query, save this since the context will be destroyed - // - NewRequest->OidContext.OidRequestId = Request->OidContext.OidRequestId; - NewRequest->OidContext.OidRequestHandle = Request->OidContext.OidRequestHandle; - } - - NewRequest->HandlerContext.Parameters.PacketServiceState = Request->HandlerContext.Parameters.PacketServiceState; - // - // Dispatch the new CID request - // - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Dispatching Request[ReqId=0x%04x] for %s", - Request->RequestId, - NewRequest->RequestId, - MbbUtilGetCommandString( &NewCommand ) - ); - - NdisStatus = MbbReqMgrDispatchRequest( - NewRequest, - (NewRequest->OidHandler->IsSerialized == 1), - MbbUtilInternalCIDQuery, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - // - // If dispatch failed, then indicate ReadyInfoFailure - // - if( NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to dispatch %s, NdisStatus=%!STATUS!", - NewRequest->RequestId, - MbbUtilGetCommandString( &NewCommand ), - NdisStatus - ); - MbbReqMgrDestroyRequest( - NewRequest->RequestManager, - NewRequest - ); - break; - } - // - // The status handler will take care of the rest. - // - NdisPacketServiceState = NULL; - IndicateFailure = FALSE; - } - while( FALSE ); - - if( IndicateFailure && - Request->HandlerContext.Parameters.PacketServiceState.IsQuery == 1 ) - { - MbbNdisIndicatePacketServiceFailure( Request , NdisStatus); - } - - if( NdisPacketServiceState != NULL ) - { - FREE_POOL( NdisPacketServiceState ); - } -} - -NDIS_STATUS -MbbNdisPacketServiceStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - PNDIS_WWAN_PACKET_SERVICE_STATE NdisPacketServiceState=NULL; - PMBB_PACKET_SERVICE MbbPacketService = (PMBB_PACKET_SERVICE)InBuffer; - - - do - { - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PACKET_SERVICE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - if( MbbPacketService == NULL || (InBufferSize < sizeof(MBB_PACKET_SERVICE) ) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PACKET_SERVICE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_PACKET_SERVICE) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - NdisPacketServiceState =(PNDIS_WWAN_PACKET_SERVICE_STATE) ALLOCATE_NONPAGED_POOL(sizeof(*NdisPacketServiceState)); - - if (NdisPacketServiceState == NULL) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate ndis structure", - Request->RequestId - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - RtlZeroMemory(NdisPacketServiceState, sizeof(*NdisPacketServiceState)); - - NdisPacketServiceState->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisPacketServiceState->Header.Size = sizeof(NDIS_WWAN_PACKET_SERVICE_STATE); - NdisPacketServiceState->Header.Revision = NDIS_WWAN_PACKET_SERVICE_STATE_REVISION_1; - - Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceStateSize=sizeof(*NdisPacketServiceState); - Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState=NdisPacketServiceState; - - - NdisPacketServiceState->PacketService.uNwError = MbbPacketService->NetworkError; - - NdisPacketServiceState->uStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if ( MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - break; - } - - MbbUtilMbbToWwanPacketService( - MbbPacketService, - &NdisPacketServiceState->PacketService - ); - - Adapter->UplinkSpeed = MbbPacketService->UplinkSpeed; - Adapter->DownlinkSpeed = MbbPacketService->DownlinkSpeed; - - if (Adapter->AvailableDataClassValid) - { - // - // if we have a current data class fill it in. - // - Request->HandlerContext.Parameters.PacketServiceState.IsWwanAvailableDataClassValid = 1; - Request->HandlerContext.Parameters.PacketServiceState.AvailableDataClass=Adapter->AvailableDataClass; - } - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( NdisStatus != NDIS_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - NdisStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PACKET_SERVICE with status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - - MbbNdisIndicatePacketService( - Request, - NdisStatus - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSignalStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_SIGNAL_STATE NdisSignalState; - PMBB_SIGNAL_STATE MbbSignalState = (PMBB_SIGNAL_STATE)InBuffer; - - do - { - RtlZeroMemory(&NdisSignalState, sizeof(NdisSignalState)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SIGNAL_STATE - ); - - NdisSignalState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSignalState.Header.Size = sizeof(NDIS_WWAN_SIGNAL_STATE); - NdisSignalState.Header.Revision = NDIS_WWAN_SIGNAL_STATE_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SIGNAL_STATE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - - if( MbbSignalState == NULL || - InBufferSize < sizeof(MBB_SIGNAL_STATE) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SIGNAL_STATE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_SIGNAL_STATE) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanSignalState( - MbbSignalState, - &NdisSignalState.SignalState - ); - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisSignalState.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisSignalState; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SIGNAL_STATE); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SIGNAL_STATE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - - -NDIS_STATUS -MbbNdisConnectStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_CONTEXT_STATE NdisContextState; - PMBB_CONTEXT_STATE MbbContextState = (PMBB_CONTEXT_STATE)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ); - PMBB_PORT Port = NULL; - NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; - BOOLEAN ResetPort = FALSE; - - do - { - RtlZeroMemory(&NdisContextState, sizeof(NdisContextState)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_CONTEXT_STATE - ); - - NdisContextState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisContextState.Header.Size = SIZEOF_NDIS_WWAN_CONTEXT_STATE_REVISION_2; - NdisContextState.Header.Revision = NDIS_WWAN_CONTEXT_STATE_REVISION_2; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_CONTEXT_STATE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - // - // A MBB_CONTEXT_STATE structure may follow even when MBB_STATUS - // is not successful. It is required, for example, to communicate - // the Network specific error. - // - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if ((WwanStatus != WWAN_STATUS_SUCCESS) && ((InBufferSize < sizeof(MBB_CONTEXT_STATE) || (MbbContextState == NULL)))) - { - // - // if the request failed and the buffer returned is too small, break out now and return the error. - // In the case of an error with a valid buffer, continue to try to get the uNwError to return - // - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus not successful, WwanStatus=%!WwanStatus!, MbbStatus=%!MbbStatus!", - Request->RequestId, - WwanStatus, - MbbStatus - ); - break; - } - - if( MbbContextState == NULL || InBufferSize < sizeof(MBB_CONTEXT_STATE) ) - { - // - // because of the check above, this is only hit for the success case. - // - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_CONTEXT_STATE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_CONTEXT_STATE) - ); - // - // only change the error if the current status is success - // - if (WwanStatus == WWAN_STATUS_SUCCESS) - { - WwanStatus = WWAN_STATUS_FAILURE; - } - break; - } - - // Get the port. Always rely on the session id returned by the device as this - // responsehandler may be triggered due to an OID request from above - // or some MB device specific notification from below. Session Id is set in both cases. - Port = MbbWwanTranslateSessionIdToPort(Adapter, MbbContextState->SessionId); - - if( Port == NULL ) - { - // invalid port context - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Received invalid port context in MbbNdisConnectStatusHandler", Request->RequestId); - - if( MbbContextState->ActivationState == MbbActivationStateDeactivated ) - { - // Handling the case when port ( virtual interface) may have been brought down before context deactivation. In that - // case the port will not be found but the session Id is still valid. Hence return the session id here. It will be returned - // successfully if its a valid session Id. Else this will be a no-op. - MbbWwanReturnSessionId(Adapter, MbbContextState->SessionId); - - TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Returned session id for CONTEXT DEACTIVATION response for session Id[%lu] for an invalid port context in MbbNdisConnectStatusHandler", - Request->RequestId, - MbbContextState->SessionId); - } - else - { - // This means that we have the port removed while the context activation was queued. - TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Not returning session id for context request: [%d] response for session Id[%lu] for an invalid port context in MbbNdisConnectStatusHandler", - Request->RequestId, - (int)MbbContextState->ActivationState, - MbbContextState->SessionId); - } - - if (WwanStatus == WWAN_STATUS_SUCCESS) - { - WwanStatus = WWAN_STATUS_FAILURE; - } - - break; - } - - // Get the port number - MBB_ACQUIRE_PORT_LOCK(Port); - PortNumber = Port->PortNumber; - MBB_RELEASE_PORT_LOCK(Port); - - MbbUtilMbbToWwanContextState( - MbbContextState, - MbbWwanGetPortConnectionId(Port), - &NdisContextState.ContextState - ); - } - while( FALSE ); - - if( (MbbContextState == NULL || InBufferSize < sizeof(MBB_CONTEXT_STATE)) && - (MbbReqMgrIsInternalRequest( Request ) == FALSE) && - (MbbReqMgrIsUnsolicitedIndication( Request ) == FALSE) - ) - { - // - // We cannot get the SessionId from the MbbContextState because it is invalid. - // Since this is a transactional response, we do a best-effort to send the response up - // on the default port. - // NOTE: Unsolicited indications with invalid context state are dropped. - // - - MBB_CONTEXT_STATE DummyMbbContextState = {0}; - - PortNumber = NDIS_DEFAULT_PORT_NUMBER; - Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); - - if (Port != NULL) - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbContextState is invalid. Using NDIS_DEFAULT_PORT_NUMBER (%lu) to indicate response", - Request->RequestId, - PortNumber - ); - - MbbUtilMbbToWwanContextState( - &DummyMbbContextState, - MbbWwanGetPortConnectionId(Port), - &NdisContextState.ContextState - ); - } - else - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbContextState is invalid AND we failed to retrieve the default port info", - Request->RequestId); - } - } - - // - // If this is an ACTIVATION failure reset the port - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbReqMgrIsSetOid( Request ) == TRUE && - Request->HandlerContext.Parameters.Connect.Activate == TRUE && - Port != NULL - ) - { - ResetPort = TRUE; - } - - if(Port != NULL) - { - // Indicate status indication on the correct port. If port is not found - // we dont know which port number to indicate the status on. - - NdisContextState.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisContextState; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_CONTEXT_STATE); - StatusIndication.PortNumber = PortNumber; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_CONTEXT_STATE with status=%!WwanStatus! for Port number=%lu", - Request->RequestId, - WwanStatus, - PortNumber - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - } - else - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Not indicating OID_WWAN_CONNECT completion as the port context is invalid.", Request->RequestId); - } - - // - // TODO: Get the speed information from the adpater. - // The adpater caches the information received from packet_service. - // - if( MbbContextState != NULL && - Port != NULL && - NdisStatus == NDIS_STATUS_SUCCESS && - WwanStatus == WWAN_STATUS_SUCCESS - ) - { - if( MbbContextState->ActivationState == MbbActivationStateActivated ) - { - MBB_CONNECTION_STATE ConnectionState; - - // - // Verify that the device is reporting the correct SessionId. - // There isnt much to do apart from logging. - // - ASSERT(MbbContextState->SessionId == MbbWwanGetPortSessionId(Port)); - - if(MbbContextState->SessionId != MbbWwanGetPortSessionId(Port)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID SessionId[Receieved=%d Expected=%d] on Connect", - Request->RequestId, - MbbContextState->SessionId, - MbbWwanGetPortSessionId(Port) - ); - } - - ConnectionState.ConnectionUp = TRUE; - ConnectionState.UpStreamBitRate = Adapter->UplinkSpeed; - ConnectionState.DownStreamBitRate = Adapter->DownlinkSpeed; - - MbbAdapterConnectionChange( - MbbReqMgrGetAdapterHandle( Request ), - &ConnectionState, - PortNumber - ); - } - else if( MbbContextState->ActivationState == MbbActivationStateDeactivated ) - { - MBB_CONNECTION_STATE ConnectionState; - - ConnectionState.ConnectionUp = FALSE; - ConnectionState.UpStreamBitRate = 0; - ConnectionState.DownStreamBitRate = 0; - - MbbAdapterConnectionChange( - MbbReqMgrGetAdapterHandle( Request ), - &ConnectionState, - PortNumber - ); - - // this is a successful deactivation. Reset the port - ResetPort = (MbbReqMgrIsUnsolicitedIndication( Request ) /*Unsolicited deactivate context*/ - || MbbReqMgrIsSetOid( Request )); /*Solicited deactivate context*/ - - } - } - - if(Port) - { - if(ResetPort) - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Resetting port with port number= %d", - Request->RequestId, - PortNumber); - - MbbWwanSetPortConnectionId( - Port, - 0 - ); - - MbbWwanResetPortSessionId( - Port, - TRUE // session id should be returned to the session pool - ); - - MBB_ACQUIRE_PORT_LOCK(Port); - - if(Port->IpAddressInfo != NULL) - { - FREE_POOL(Port->IpAddressInfo); - Port->IpAddressInfo = NULL; - } - - MBB_RELEASE_PORT_LOCK(Port); - } - - // Remove the reference added during find - Dereference(Port); - } - - // Return the session id to the adapter session id pool if- - // - // a) This was a context activation request - // b) Current state of the request is "MbbRequestStateCancelled" - // c) Last state of the request < MbbRequestStateResponseReceived. - // - // This will ensure that we are processing the request for whom the response hasnt been received as yet. - // - // If the response is received for these cancelled requests, that will be a no-op. - // - // Requests whose responses have already been received will be ( or are being ) processed by their - // respective response handlers and the upper layers are responsible for further actions. - // - - if(Adapter - && Request->HandlerContext.Parameters.Connect.Activate == TRUE) - { - // return session id to the session id pool of the adapter - // for the cancelled request. Otherwise this session id - // will leak. - - MBB_REQUEST_STATE CurrentRequestState = MbbRequestStateInvalid; - MBB_REQUEST_STATE LastRequestState = MbbRequestStateInvalid; - ULONG SessionId = MBB_INVALID_SESSION_ID; - - MbbReqMgrGetState( - Request, - &CurrentRequestState, - &LastRequestState - ); - - if(CurrentRequestState == MbbRequestStateCancelled) - { - if(LastRequestState < MbbRequestStateResponseReceived) - { - SessionId = Request->HandlerContext.Parameters.Connect.SessionId; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Attempting to return the session id of the cancelled context activation request to adapter session id pool.Session Id = %d, Current request state = %!MbbRequestState!, Last request state = %!MbbRequestState!", - Request->RequestId, - SessionId, - CurrentRequestState, - LastRequestState - ); - - MbbWwanReturnSessionId(Adapter, SessionId); - } - else - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Not attempting to return the session id of the cancelled context activation request to adapter session id pool. Session Id = %d, Current request state = %!MbbRequestState!, Last request state = %!MbbRequestState!", - Request->RequestId, - SessionId, - CurrentRequestState, - LastRequestState - ); - } - } - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisLteAttachConfigHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - ULONG NdisLteAttachContextSize = sizeof(NDIS_WWAN_LTE_ATTACH_CONTEXTS); - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication; - PNDIS_WWAN_LTE_ATTACH_CONTEXTS NdisLteAttachContext = NULL; - PMBB_MS_LTE_ATTACH_CONFIG_INFO MbbLteAttchConfigInfo = (PMBB_MS_LTE_ATTACH_CONFIG_INFO)InBuffer; - PMBB_MS_LTE_ATTACH_CONTEXT MbbContext=NULL; - ULONGLONG TempSize=0; - ULONG MulTempSize=0; - ULONG i; - - NdisLteAttachContext = ALLOCATE_NONPAGED_POOL( NdisLteAttachContextSize ); - - if ( NdisLteAttachContext == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_WWAN_LTE_ATTACH_CONTEXTS, ContextCount=%d", - Request->RequestId, - NdisLteAttachContextSize, - MbbLteAttchConfigInfo->ElementCount - ); - return NDIS_STATUS_RESOURCES; - } - RtlZeroMemory(NdisLteAttachContext, NdisLteAttachContextSize); - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_LTE_ATTACH_CONFIG - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_LTE_ATTACH_CONFIG, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - TempSize = RTL_SIZEOF_THROUGH_FIELD(MBB_MS_LTE_ATTACH_CONFIG_INFO, Contexts); - - if( MbbLteAttchConfigInfo == NULL || - InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_MS_LTE_ATTACH_CONFIG_INFO, Contexts) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_LTE_ATTACH_CONFIG, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_MS_LTE_ATTACH_CONFIG_INFO, Contexts) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbLteAttchConfigInfo->ElementCount != TotalRoamingConditions) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] wrong size element count returned, MbbLteAttchConfigInfo->ContextCount=%d, exepcting=%d", - Request->RequestId, - MbbLteAttchConfigInfo->ElementCount, - TotalRoamingConditions - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - // - // make sure it is big enough for the array of elements - // - NdisStatus = RtlULongMult( - MbbLteAttchConfigInfo->ElementCount, - sizeof(MBB_ARRAY_ELEMENT), - &MulTempSize - ); - - if ( NT_ERROR(NdisStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbLteAttchConfigInfo->ContextCount=%d MBB_ARRAY_ELEMENT size=%d", - Request->RequestId, - MbbLteAttchConfigInfo->ElementCount, - sizeof(MBB_ARRAY_ELEMENT) - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - TempSize += MulTempSize; - - if( InBufferSize < TempSize ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_LTE_ATTACH_CONFIG, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - (ULONG)TempSize - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // validation of the data buffer - for (i = 0; i < MbbLteAttchConfigInfo->ElementCount; i++) - { - // The max buffer size couldn't be larger than the maximum string length defined in WWAN struct - // otherwise, the conversion from MBB to WWAN could fail - ULONG maxContextSize = - (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer) + - WWAN_ACCESSSTRING_LEN + - WWAN_USERNAME_LEN + - WWAN_PASSWORD_LEN; - - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbLteAttchConfigInfo->Contexts[i].Offset, - MbbLteAttchConfigInfo->Contexts[i].Size, - maxContextSize, - sizeof(UCHAR) - ); - - if (!NT_SUCCESS(NdisStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad array element in MBB_MS_LTE_ATTACH_CONFIG_INFO", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbLteAttchConfigInfo->Contexts[i].Size < (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_CONTEXT, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - MbbLteAttchConfigInfo->Contexts[i].Size, - (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer) - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbContext = (PMBB_MS_LTE_ATTACH_CONTEXT)(InBuffer + MbbLteAttchConfigInfo->Contexts[i].Offset); - ULONG MbbContextSize = (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer); - - NdisStatus = MbbIsVariableFieldValid( - MbbLteAttchConfigInfo->Contexts[i].Size, - MbbContext->AccessString.Offset, - MbbContext->AccessString.Size, - MBB_MAXIMUM_ACCESS_STRING_LENGTH, - sizeof(WCHAR) - ); - - if (!NT_SUCCESS(NdisStatus)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - MbbContextSize += ROUND_UP_COUNT(MbbContext->AccessString.Size, ALIGN_DWORD); - - NdisStatus = MbbIsVariableFieldValid( - MbbLteAttchConfigInfo->Contexts[i].Size, - MbbContext->UserName.Offset, - MbbContext->UserName.Size, - MBB_MAXIMUM_USERNAME_LENGTH, - sizeof(WCHAR) - ); - - if ( !NT_SUCCESS(NdisStatus)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - MbbContextSize += ROUND_UP_COUNT(MbbContext->UserName.Size, ALIGN_DWORD); - - NdisStatus = MbbIsVariableFieldValid( - MbbLteAttchConfigInfo->Contexts[i].Size, - MbbContext->Password.Offset, - MbbContext->Password.Size, - MBB_MAXIMUM_PASSWORD_LENGTH, - sizeof(WCHAR) - ); - - if ( !NT_SUCCESS(NdisStatus)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - MbbContextSize += ROUND_UP_COUNT(MbbContext->Password.Size, ALIGN_DWORD); - - if (MbbLteAttchConfigInfo->Contexts[i].Size != MbbContextSize) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Incorrect BufferSize for MBB_MS_LTE_ATTACH_CONTEXT, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - MbbLteAttchConfigInfo->Contexts[i].Size, - MbbContextSize - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - } - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - NdisLteAttachContext->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisLteAttachContext->Header.Size = sizeof(NDIS_WWAN_LTE_ATTACH_CONTEXTS); - NdisLteAttachContext->Header.Revision = NDIS_WWAN_LTE_ATTACH_CONTEXT_REVISION_1; - NdisLteAttachContext->LteAttachContext.ElementCount = MbbLteAttchConfigInfo->ElementCount; - - MbbUtilMbbToWwanLteAttachConfigInfo( - MbbLteAttchConfigInfo, - &NdisLteAttachContext->LteAttachContext - ); - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - StatusIndication.StatusBuffer = NdisLteAttachContext; - StatusIndication.StatusBufferSize = NdisLteAttachContextSize; - ((PNDIS_WWAN_LTE_ATTACH_CONTEXTS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - FREE_POOL( NdisLteAttachContext ); - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisLteAttachStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - ULONG NdisLteAttachStatusSize = sizeof(NDIS_WWAN_LTE_ATTACH_STATUS); - PNDIS_WWAN_LTE_ATTACH_STATUS NdisLteAttachStatus = NULL; - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication; - PMBB_MS_LTE_ATTACH_STATUS MbbLteAttchStatus = (PMBB_MS_LTE_ATTACH_STATUS)InBuffer; - ULONGLONG TempSize=0; - - NdisLteAttachStatus = ALLOCATE_NONPAGED_POOL(NdisLteAttachStatusSize); - - if ( NdisLteAttachStatus == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_WWAN_LTE_ATTACH_STATUS", - Request->RequestId, - NdisLteAttachStatusSize - ); - return NDIS_STATUS_RESOURCES; - } - - RtlZeroMemory(NdisLteAttachStatus, NdisLteAttachStatusSize); - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_LTE_ATTACH_STATUS - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_LTE_ATTACH_STATUS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - if( MbbReqMgrIsSetOid( Request ) == TRUE ) - { - break; - } - - TempSize = (ULONG)FIELD_OFFSET(MBB_MS_LTE_ATTACH_STATUS, DataBuffer); - - if( MbbLteAttchStatus == NULL || - InBufferSize < TempSize ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_LTE_ATTACH_STATUS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - (ULONG)TempSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbLteAttchStatus->AccessString.Offset, - MbbLteAttchStatus->AccessString.Size, - MBB_MAXIMUM_ACCESS_STRING_LENGTH, - sizeof(WCHAR) - ); - - if ( !NT_SUCCESS(NdisStatus)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbLteAttchStatus->UserName.Offset, - MbbLteAttchStatus->UserName.Size, - MBB_MAXIMUM_USERNAME_LENGTH, - sizeof(WCHAR) - ); - - if ( !NT_SUCCESS(NdisStatus)) - { - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbLteAttchStatus->Password.Offset, - MbbLteAttchStatus->Password.Size, - MBB_MAXIMUM_PASSWORD_LENGTH, - sizeof(WCHAR) - ); - - if ( !NT_SUCCESS(NdisStatus)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_LTE_ATTACH_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - NdisLteAttachStatus->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisLteAttachStatus->Header.Size = sizeof(NDIS_WWAN_LTE_ATTACH_STATUS); - NdisLteAttachStatus->Header.Revision = NDIS_WWAN_LTE_ATTACH_STATUS_REVISION_1; - - MbbUtilMbbToWwanLteAttachStatus( - MbbLteAttchStatus, - &NdisLteAttachStatus->LteAttachStatus - ); - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - StatusIndication.StatusBuffer = NdisLteAttachStatus; - StatusIndication.StatusBufferSize = NdisLteAttachStatusSize; - - ((PNDIS_WWAN_LTE_ATTACH_STATUS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - FREE_POOL( NdisLteAttachStatus ); - return NdisStatus; -} - -NDIS_STATUS -MbbNdisProvisionedContextStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - ULONG NdisProvisionedContextSize = 0; - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - PNDIS_WWAN_PROVISIONED_CONTEXTS NdisProvisionedContext = NULL; - NDIS_WWAN_PROVISIONED_CONTEXTS LocalNdisProvisionedContext; - PMBB_CONTEXT_LIST MbbContextList = (PMBB_CONTEXT_LIST)InBuffer; - PMBB_CONTEXT MbbContext=NULL; - ULONGLONG TempSize=0; - ULONG MulTempSize=0; - ULONG i; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - RtlZeroMemory(&LocalNdisProvisionedContext, sizeof(LocalNdisProvisionedContext)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - - if( MbbReqMgrIsSetOid( Request ) == TRUE ) - { - break; - } - - TempSize = RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount); - - if( MbbContextList == NULL || - InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbContextList->ContextCount > MBB_MAX_PROVISIONED_CONTEXTS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Too many contexts returned, MbbContextList->ContextCount=%d", - Request->RequestId, - MbbContextList->ContextCount - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - // - // make sure it is big enough for the array of elements - // - NtStatus = RtlULongMult( - MbbContextList->ContextCount, - sizeof(MBB_ARRAY_ELEMENT), - &MulTempSize - ); - - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbContextList->ContextCount=%d MBB_ARRAY_ELEMENT size=%d", - Request->RequestId, - MbbContextList->ContextCount, - sizeof(MBB_ARRAY_ELEMENT) - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - TempSize += MulTempSize; - - if( InBufferSize < TempSize ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - (ULONG)TempSize - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - for (i=0; i < MbbContextList->ContextCount; i++) - { - - NtStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbContextList->Contexts[i].Offset, - MbbContextList->Contexts[i].Size, - 2048, // some reasonable upper limit - sizeof(UCHAR) - ); - - if ( !NT_SUCCESS(NtStatus)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad array element in MBB_CONTEXT_LIST", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbContextList->Contexts[i].Size < (ULONG)FIELD_OFFSET(MBB_CONTEXT, DataBuffer)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_CONTEXT, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - MbbContextList->Contexts[i].Size, - (ULONG)FIELD_OFFSET(MBB_CONTEXT, DataBuffer) - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - - - } - - MbbContext=(PMBB_CONTEXT)(InBuffer+MbbContextList->Contexts[i].Offset); - - NtStatus = MbbIsVariableFieldValid( - MbbContextList->Contexts[i].Size, - MbbContext->AccessString.Offset, - MbbContext->AccessString.Size, - MBB_MAXIMUM_ACCESS_STRING_LENGTH, - sizeof(WCHAR) - ); - - if ( !NT_SUCCESS(NtStatus)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - - NtStatus = MbbIsVariableFieldValid( - MbbContextList->Contexts[i].Size, - MbbContext->UserName.Offset, - MbbContext->UserName.Size, - MBB_MAXIMUM_USERNAME_LENGTH, - sizeof(WCHAR) - ); - - if ( !NT_SUCCESS(NtStatus)) - { - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - - NtStatus = MbbIsVariableFieldValid( - MbbContextList->Contexts[i].Size, - MbbContext->Password.Offset, - MbbContext->Password.Size, - MBB_MAXIMUM_PASSWORD_LENGTH, - sizeof(WCHAR) - ); - - if ( !NT_SUCCESS(NtStatus)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_CONTEXT", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - } - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - NtStatus = RtlULongMult( - MbbContextList->ContextCount, - sizeof(WWAN_CONTEXT), - &NdisProvisionedContextSize - ); - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbContextList->ContextCount=%d WWAN_CONTEXT size=%d", - Request->RequestId, - MbbContextList->ContextCount, - sizeof(WWAN_CONTEXT) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NtStatus = RtlULongAdd( - NdisProvisionedContextSize, - sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS), - &NdisProvisionedContextSize - ); - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, NdisProvisionedContextSize=%d NDIS_WWAN_PROVISIONED_CONTEXTS size=%d", - Request->RequestId, - NdisProvisionedContextSize, - sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisProvisionedContext = ALLOCATE_NONPAGED_POOL( NdisProvisionedContextSize ); - - if ( NdisProvisionedContext == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, ContextCount=%d", - Request->RequestId, - NdisProvisionedContextSize, - MbbContextList->ContextCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisProvisionedContext, NdisProvisionedContextSize); - - NdisProvisionedContext->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisProvisionedContext->Header.Size = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); - NdisProvisionedContext->Header.Revision = NDIS_WWAN_PROVISIONED_CONTEXTS_REVISION_1; - - MbbUtilMbbToWwanContextList( - MbbContextList, - &NdisProvisionedContext->ContextListHeader - ); - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if( NdisProvisionedContext == NULL ) - { - LocalNdisProvisionedContext.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisProvisionedContext.Header.Size = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); - LocalNdisProvisionedContext.Header.Revision = NDIS_WWAN_PROVISIONED_CONTEXTS_REVISION_1; - - LocalNdisProvisionedContext.ContextListHeader.ElementType = WwanStructContext; - LocalNdisProvisionedContext.ContextListHeader.ElementCount = 0; - - StatusIndication.StatusBuffer = &LocalNdisProvisionedContext; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); - } - else - { - StatusIndication.StatusBuffer = NdisProvisionedContext; - StatusIndication.StatusBufferSize = NdisProvisionedContextSize; - } - - ((PNDIS_WWAN_PROVISIONED_CONTEXTS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if( NdisProvisionedContext != NULL ) - { - FREE_POOL( NdisProvisionedContext ); - } - return NDIS_STATUS_SUCCESS; -} - - -NDIS_STATUS -MbbNdisProvisionedContextV2StatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -) -{ - ULONG NdisProvisionedContextSize = 0; - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - PNDIS_WWAN_PROVISIONED_CONTEXTS NdisProvisionedContext = NULL; - NDIS_WWAN_PROVISIONED_CONTEXTS LocalNdisProvisionedContext; - PMBB_CONTEXT_LIST MbbContextList = (PMBB_CONTEXT_LIST)InBuffer; - PMBB_MS_CONTEXT_V2 MbbContext = NULL; - ULONGLONG TempSize = 0; - ULONG MulTempSize = 0; - ULONG i; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - RtlZeroMemory(&LocalNdisProvisionedContext, sizeof(LocalNdisProvisionedContext)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - - if (MbbReqMgrIsSetOid(Request) == TRUE) - { - break; - } - - TempSize = RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount); - - if (MbbContextList == NULL || - InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_CONTEXT_LIST, ContextCount) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbContextList->ContextCount > MBB_MAX_PROVISIONED_CONTEXTS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Too many contexts returned, MbbContextList->ContextCount=%d", - Request->RequestId, - MbbContextList->ContextCount - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - // - // make sure it is big enough for the array of elements - // - NtStatus = RtlULongMult( - MbbContextList->ContextCount, - sizeof(MBB_ARRAY_ELEMENT), - &MulTempSize - ); - - if (NT_ERROR(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbContextList->ContextCount=%d MBB_ARRAY_ELEMENT size=%d", - Request->RequestId, - MbbContextList->ContextCount, - sizeof(MBB_ARRAY_ELEMENT) - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - TempSize += MulTempSize; - - if (InBufferSize < TempSize) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - (ULONG)TempSize - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - for (i = 0; i < MbbContextList->ContextCount; i++) - { - - NtStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbContextList->Contexts[i].Offset, - MbbContextList->Contexts[i].Size, - 2048, // some reasonable upper limit - sizeof(UCHAR) - ); - - if (!NT_SUCCESS(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad array element in MBB_CONTEXT_LIST", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbContextList->Contexts[i].Size < (ULONG)FIELD_OFFSET(MBB_MS_CONTEXT_V2, DataBuffer)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_MS_CONTEXT_V2, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - MbbContextList->Contexts[i].Size, - (ULONG)FIELD_OFFSET(MBB_MS_CONTEXT_V2, DataBuffer) - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - - - } - - MbbContext = (PMBB_MS_CONTEXT_V2)(InBuffer + MbbContextList->Contexts[i].Offset); - - NtStatus = MbbIsVariableFieldValid( - MbbContextList->Contexts[i].Size, - MbbContext->AccessString.Offset, - MbbContext->AccessString.Size, - MBB_MAXIMUM_ACCESS_STRING_LENGTH, - sizeof(WCHAR) - ); - - if (!NT_SUCCESS(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_CONTEXT_V2", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - - NtStatus = MbbIsVariableFieldValid( - MbbContextList->Contexts[i].Size, - MbbContext->UserName.Offset, - MbbContext->UserName.Size, - MBB_MAXIMUM_USERNAME_LENGTH, - sizeof(WCHAR) - ); - - if (!NT_SUCCESS(NtStatus)) - { - - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_CONTEXT_V2", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - - NtStatus = MbbIsVariableFieldValid( - MbbContextList->Contexts[i].Size, - MbbContext->Password.Offset, - MbbContext->Password.Size, - MBB_MAXIMUM_PASSWORD_LENGTH, - sizeof(WCHAR) - ); - - if (!NT_SUCCESS(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Invalid access string for MBB_MS_CONTEXT_V2", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - } - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - NtStatus = RtlULongMult( - MbbContextList->ContextCount, - sizeof(WWAN_CONTEXT_V2), - &NdisProvisionedContextSize - ); - if (NT_ERROR(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbContextList->ContextCount=%d MBB_MS_CONTEXT_V2 size=%d", - Request->RequestId, - MbbContextList->ContextCount, - sizeof(WWAN_CONTEXT_V2) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NtStatus = RtlULongAdd( - NdisProvisionedContextSize, - sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS), - &NdisProvisionedContextSize - ); - if (NT_ERROR(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, NdisProvisionedContextSize=%d NDIS_WWAN_PROVISIONED_CONTEXTS size=%d", - Request->RequestId, - NdisProvisionedContextSize, - sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisProvisionedContext = ALLOCATE_NONPAGED_POOL(NdisProvisionedContextSize); - - if (NdisProvisionedContext == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, ContextCount=%d", - Request->RequestId, - NdisProvisionedContextSize, - MbbContextList->ContextCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisProvisionedContext, NdisProvisionedContextSize); - - NdisProvisionedContext->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisProvisionedContext->Header.Size = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); - NdisProvisionedContext->Header.Revision = NDIS_WWAN_PROVISIONED_CONTEXTS_REVISION_2; - - MbbUtilMbbToWwanContextV2List( - MbbContextList, - &NdisProvisionedContext->ContextListHeader - ); - } while (FALSE); - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - if (NdisProvisionedContext == NULL) - { - LocalNdisProvisionedContext.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisProvisionedContext.Header.Size = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); - LocalNdisProvisionedContext.Header.Revision = NDIS_WWAN_PROVISIONED_CONTEXTS_REVISION_2; - - LocalNdisProvisionedContext.ContextListHeader.ElementType = WwanStructContextV2; - LocalNdisProvisionedContext.ContextListHeader.ElementCount = 0; - - StatusIndication.StatusBuffer = &LocalNdisProvisionedContext; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PROVISIONED_CONTEXTS); - } - else - { - StatusIndication.StatusBuffer = NdisProvisionedContext; - StatusIndication.StatusBufferSize = NdisProvisionedContextSize; - } - - ((PNDIS_WWAN_PROVISIONED_CONTEXTS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisProvisionedContext != NULL) - { - FREE_POOL(NdisProvisionedContext); - } - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisServiceActivationStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - ULONG VendorSpecificBufferSize; - ULONG NdisServiceActivationStatusSize = 0; - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - PNDIS_WWAN_SERVICE_ACTIVATION_STATUS NdisServiceActivationStatus = NULL; - NDIS_WWAN_SERVICE_ACTIVATION_STATUS LocalNdisServiceActivationStatus; - PMBB_SERVICE_ACTIVATION_STATUS MbbServiceActivationStatus = (PMBB_SERVICE_ACTIVATION_STATUS)InBuffer; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - RtlZeroMemory(&LocalNdisServiceActivationStatus, sizeof(LocalNdisServiceActivationStatus)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SERVICE_ACTIVATION - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SERVICE_ACTIVATION, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( MbbServiceActivationStatus == NULL || - InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SERVICE_ACTIVATION_STATUS, NetworkError) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SERVICE_ACTIVATION, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_SERVICE_ACTIVATION_STATUS, NetworkError) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - VendorSpecificBufferSize = InBufferSize - RTL_SIZEOF_THROUGH_FIELD(MBB_SERVICE_ACTIVATION_STATUS, NetworkError); - - NtStatus = RtlULongAdd( - VendorSpecificBufferSize, - sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS), - &NdisServiceActivationStatusSize - ); - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, VendorSpecificBufferSize=%d NDIS_WWAN_SERVICE_ACTIVATION_STATUS size=%d", - Request->RequestId, - VendorSpecificBufferSize, - sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( (NdisServiceActivationStatus = ALLOCATE_NONPAGED_POOL( NdisServiceActivationStatusSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_SERVICE_ACTIVATION", - Request->RequestId, - NdisServiceActivationStatusSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisServiceActivationStatus->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisServiceActivationStatus->Header.Size = sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS); - NdisServiceActivationStatus->Header.Revision = NDIS_WWAN_SERVICE_ACTIVATION_STATUS_REVISION_1; - - MbbUtilMbbToWwanServiceActivationStatus( - MbbServiceActivationStatus, - VendorSpecificBufferSize, - &NdisServiceActivationStatus->ServiceActivationStatus - ); - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if( NdisServiceActivationStatus == NULL ) - { - LocalNdisServiceActivationStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisServiceActivationStatus.Header.Size = sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS); - LocalNdisServiceActivationStatus.Header.Revision = NDIS_WWAN_SERVICE_ACTIVATION_STATUS_REVISION_1; - - LocalNdisServiceActivationStatus.ServiceActivationStatus.uNwError = 0; - LocalNdisServiceActivationStatus.ServiceActivationStatus.uVendorSpecificBufferSize = 0; - - StatusIndication.StatusBuffer = &LocalNdisServiceActivationStatus; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SERVICE_ACTIVATION_STATUS); - } - else - { - StatusIndication.StatusBuffer = NdisServiceActivationStatus; - StatusIndication.StatusBufferSize = NdisServiceActivationStatusSize; - } - - ((PNDIS_WWAN_SERVICE_ACTIVATION_STATUS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SERVICE_ACTIVATION with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if( NdisServiceActivationStatus != NULL ) - { - FREE_POOL( NdisServiceActivationStatus ); - } - return NDIS_STATUS_SUCCESS; -} - -// SMS - -NDIS_STATUS -MbbNdisSmsConfigurationStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_SMS_CONFIGURATION NdisSmsConfiguration; - PMBB_SMS_CONFIGURATION MbbSmsConfiguration = (PMBB_SMS_CONFIGURATION)InBuffer; - - do - { - RtlZeroMemory(&NdisSmsConfiguration, sizeof(NdisSmsConfiguration)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SMS_CONFIGURATION - ); - - NdisSmsConfiguration.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSmsConfiguration.Header.Size = sizeof(NDIS_WWAN_SMS_CONFIGURATION); - NdisSmsConfiguration.Header.Revision = NDIS_WWAN_SMS_CONFIGURATION_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_CONFIGURATION, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) - { - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - - if( MbbSmsConfiguration == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_SMS_CONFIGURATION, DataBuffer) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SMS_CONFIGURATION, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_SMS_CONFIGURATION, ScAddress) - ); - WwanStatus = WWAN_STATUS_FAILURE; - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - - - // - // If the SMS store is not initialized then other fields are not valid. - // - if( MbbSmsConfiguration->SmsStorageState != MbbSmsStorageInitialized ) - { - NdisStatus = NDIS_STATUS_FAILURE; - WwanStatus = WWAN_STATUS_BUSY; - break; - } - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbSmsConfiguration->ScAddress.Offset, - MbbSmsConfiguration->ScAddress.Size, - MBB_MAXIMUM_SMS_ADDRESS_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] ScAddress data field, Offset=%d, Size=%d", - Request->RequestId, - MbbSmsConfiguration->ScAddress.Offset, - MbbSmsConfiguration->ScAddress.Size - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - MbbUtilMbbToWwanSmsConfiguration( - MbbSmsConfiguration, - &NdisSmsConfiguration.SmsConfiguration - ); - } - while( FALSE ); - // - // When to do SMS Configuration indication - - // - This is a response to a OID query - // - This is an unsolicited indication - // When to do Ready Info indication - - // - This is a response to an internal query - // - This is an unsolicited indication - // - if( MbbReqMgrIsInternalRequest( Request ) == FALSE || - ( - MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE && - NdisStatus == NDIS_STATUS_SUCCESS - ) ) - { - NdisSmsConfiguration.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisSmsConfiguration; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_CONFIGURATION); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_CONFIGURATION with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - } - - if( MbbReqMgrIsInternalRequest( Request ) == TRUE || - ( - MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE && - NdisStatus == NDIS_STATUS_SUCCESS - ) ) - { - Request->HandlerContext.Parameters.SubscriberReadyInfo.IsCdmaShortMsgSizeValid = 1; - Request->HandlerContext.Parameters.SubscriberReadyInfo.CdmaShortMsgSize = WWAN_CDMA_SHORT_MSG_SIZE_UNKNOWN; - - if( NdisStatus == NDIS_STATUS_SUCCESS ) - Request->HandlerContext.Parameters.SubscriberReadyInfo.CdmaShortMsgSize = (UCHAR)MbbSmsConfiguration->CdmaShortMessageSize; - // - // Ignore SMS Configuration failures and return UNKNOWN CdmaShrotMessageSize - // when SMS_CONFIGURATION was queried internally for a READY_INFO. - // - MbbNdisIndicateReadyInfo( - Request, - NDIS_STATUS_SUCCESS - ); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSmsReadStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - ULONG WwanMessageSize; - ULONG NdisSmsReceiveSize = 0; - ULONG MessageBufferSize = 0; - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_SMS_RECEIVE LocalNdisSmsReceive; - PNDIS_WWAN_SMS_RECEIVE NdisSmsReceive = NULL; - PMBB_SMS_RECEIVE MbbSmsReceive = (PMBB_SMS_RECEIVE)InBuffer; - NTSTATUS Status; - MBB_CELLULAR_CLASS CellularClass; - - CellularClass = MbbAdapterGetCurrentCellularClass( MbbReqMgrGetAdapterHandle( Request ) ); - - if (MbbAdapterIsMultimodeCapable(MbbReqMgrGetAdapterHandle( Request ))) - { - // - // multimode device always use GSM PDU's - // - CellularClass = MbbCellularClassGsm; - } - - do - { - RtlZeroMemory(&LocalNdisSmsReceive, sizeof(LocalNdisSmsReceive)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SMS_RECEIVE - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_RECEIVE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - - // - // Validate received buffer - // - if( MbbUtilValidateMbbSmsReceive( - CellularClass, - InBufferSize, - MbbSmsReceive - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to validate data for MBB_SMS_RECEIVE", Request->RequestId ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbSmsReceive->SmsFormat == MbbSmsFormatPdu ) - WwanMessageSize = sizeof(WWAN_SMS_PDU_RECORD); - else - WwanMessageSize = sizeof(WWAN_SMS_CDMA_RECORD); - - - Status=RtlULongMult(MbbSmsReceive->MessageCount, WwanMessageSize, &MessageBufferSize); - - if (!NT_SUCCESS(Status)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] overflow Count=%d, Size=%d", Request->RequestId, MbbSmsReceive->MessageCount, WwanMessageSize ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - Status=RtlULongAdd( sizeof(NDIS_WWAN_SMS_RECEIVE), MessageBufferSize, &NdisSmsReceiveSize); - - if (!NT_SUCCESS(Status)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] overflow fixed=%d, MessageSize=%d", Request->RequestId, sizeof(NDIS_WWAN_SMS_RECEIVE), MessageBufferSize ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisSmsReceive = (PNDIS_WWAN_SMS_RECEIVE)ALLOCATE_NONPAGED_POOL( (ULONG)NdisSmsReceiveSize ); - - if( NdisSmsReceive == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to allocate %u bytes for NDIS_STATUS_WWAN_SMS_RECEIVE, MessageCount=%d", - Request->RequestId, - NdisSmsReceiveSize, - MbbSmsReceive->MessageCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisSmsReceive->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSmsReceive->Header.Size = sizeof(NDIS_WWAN_SMS_RECEIVE); - NdisSmsReceive->Header.Revision = NDIS_WWAN_SMS_RECEIVE_REVISION_1; - - if( (NdisStatus = MbbUtilMbbToWwanSmsReceive( - MbbSmsReceive, - InBufferSize, - CellularClass, - &NdisSmsReceive->SmsListHeader - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to convert data for NDIS_STATUS_WWAN_SMS_RECEIVE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if( WwanStatus != WWAN_STATUS_SUCCESS && - WwanStatus != WWAN_STATUS_SMS_MORE_DATA ) - { - StatusIndication.StatusBuffer = &LocalNdisSmsReceive; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_RECEIVE); - - LocalNdisSmsReceive.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisSmsReceive.Header.Size = sizeof(NDIS_WWAN_SMS_RECEIVE); - LocalNdisSmsReceive.Header.Revision = NDIS_WWAN_SMS_RECEIVE_REVISION_1; - - LocalNdisSmsReceive.SmsListHeader.ElementType = WwanStructSmsPdu; - LocalNdisSmsReceive.SmsListHeader.ElementCount = 0; - } - else - { - StatusIndication.StatusBuffer = NdisSmsReceive; - StatusIndication.StatusBufferSize = (ULONG)NdisSmsReceiveSize; - } - - ((PNDIS_WWAN_SMS_RECEIVE)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_RECEIVE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if( NdisSmsReceive != NULL ) - FREE_POOL( NdisSmsReceive ); - - if( WwanStatus == WWAN_STATUS_SMS_MORE_DATA ) - return NDIS_STATUS_PENDING; - else - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSmsSendStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_SMS_SEND_STATUS NdisSmsSendStatus; - PMBB_SMS_SEND_STATUS MbbSmsSendStatus = (PMBB_SMS_SEND_STATUS)InBuffer; - - do - { - RtlZeroMemory(&NdisSmsSendStatus, sizeof(NdisSmsSendStatus)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SMS_SEND - ); - - NdisSmsSendStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSmsSendStatus.Header.Size = sizeof(NDIS_WWAN_SMS_SEND_STATUS); - NdisSmsSendStatus.Header.Revision = NDIS_WWAN_SMS_SEND_STATUS_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_SEND, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - if( MbbSmsSendStatus == NULL || - InBufferSize < sizeof(MBB_SMS_SEND_STATUS) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SMS_SEND, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_SMS_SEND_STATUS) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisSmsSendStatus.MessageReference = MbbSmsSendStatus->MessageReference; - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisSmsSendStatus.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisSmsSendStatus; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_SEND_STATUS); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_SEND with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSmsDeleteStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_SMS_DELETE_STATUS NdisSmsDeleteStatus; - - do - { - RtlZeroMemory(&NdisSmsDeleteStatus, sizeof(NdisSmsDeleteStatus)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SMS_DELETE - ); - - NdisSmsDeleteStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSmsDeleteStatus.Header.Size = sizeof(NDIS_WWAN_SMS_DELETE_STATUS); - NdisSmsDeleteStatus.Header.Revision = NDIS_WWAN_SMS_DELETE_STATUS_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_DELETE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - while( FALSE ); - - NdisSmsDeleteStatus.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisSmsDeleteStatus; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_DELETE_STATUS); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_DELETE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSmsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_SMS_STATUS NdisSmsStatus; - PMBB_SMS_STATUS MbbSmsStatus = (PMBB_SMS_STATUS)InBuffer; - - do - { - RtlZeroMemory(&NdisSmsStatus, sizeof(NdisSmsStatus)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SMS_STATUS - ); - - NdisSmsStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSmsStatus.Header.Size = sizeof(NDIS_WWAN_SMS_STATUS); - NdisSmsStatus.Header.Revision = NDIS_WWAN_SMS_STATUS_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SMS_STATUS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - if( MbbSmsStatus == NULL || - InBufferSize < sizeof(MBB_SMS_STATUS) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SMS_STATUS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_SMS_STATUS) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanSmsStatus( MbbSmsStatus, &NdisSmsStatus.SmsStatus ); - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisSmsStatus.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisSmsStatus; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SMS_STATUS); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][Sms][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SMS_STATUS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -#if 0 -NDIS_STATUS -MbbNdisGetStatsHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) - -{ - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)(Request->RequestManager->AdapterContext); - PNDIS_STATISTICS_INFO Stats=NULL; - PMBB_PACKET_STATISTICS MbbStats=NULL; - PCSTR OidName=NULL; - ULONG OidNameLength=0; - - PNDIS_OID_REQUEST NdisRequest=NULL; - - if ((NdisStatus != NDIS_STATUS_SUCCESS) || (MbbStatus != MBB_STATUS_SUCCESS) || (InBufferSize < sizeof(*MbbStats))) - { - TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Device failed OID_GEN_STATISTICS", - Request->RequestId - ); - - } - - NdisRequest=InterlockedExchangePointer(&Request->OidContext.OidRequest,(PNDIS_OID_REQUEST)-1); - - if (NdisRequest !=(PNDIS_OID_REQUEST)-1) - { - MBB_NDIS_OID_STATE OldOidState; - - // - // The oid has not been competed - // - - Stats=(PNDIS_STATISTICS_INFO)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer; - - if (NdisStatus == NDIS_STATUS_SUCCESS) - { - - RtlZeroMemory(Stats, sizeof(*Stats)); - - Stats->Header.Type=NDIS_OBJECT_TYPE_DEFAULT; - Stats->Header.Revision=NDIS_STATISTICS_INFO_REVISION_1; - Stats->Header.Size=NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; - - Stats->SupportedStatistics = NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV | - NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS | - NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR | - NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV | - NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | - NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS | - NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT; - - - if (InBufferSize >= sizeof(*MbbStats)) - { - - MbbStats=(PMBB_PACKET_STATISTICS)InBuffer; - - Stats->ifHCInOctets = MbbStats->InOctets; - Stats->ifInDiscards = MbbStats->InDiscards; - Stats->ifInErrors = MbbStats->InErrors; - Stats->ifHCInUcastPkts = MbbStats->InPackets; - - Stats->ifHCOutOctets = MbbStats->OutOctets; - Stats->ifOutDiscards = MbbStats->OutDiscards; - Stats->ifOutErrors = MbbStats->OutErrors; - Stats->ifHCOutUcastPkts = MbbStats->OutPackets; - - NdisRequest->DATA.QUERY_INFORMATION.BytesWritten=sizeof(*Stats); - } - else - { - NdisStatus=NDIS_STATUS_FAILURE; - } - } - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Completing OID request to NDIS with status=%!status!", - Request->RequestId, NdisStatus - ); - - - RtlCopyMemory(Stats, &Adapter->Stats, sizeof(*Stats)); - - Stats->Header.Type=NDIS_OBJECT_TYPE_DEFAULT; - Stats->Header.Revision=NDIS_STATISTICS_INFO_REVISION_1; - Stats->Header.Size=NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; - - Stats->SupportedStatistics = NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV | - NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | - NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV; - - - NdisRequest->DATA.QUERY_INFORMATION.BytesWritten=sizeof(*Stats); - - NdisStatus = NDIS_STATUS_SUCCESS; - - } - - Request->OidContext.OidStatus = NdisStatus; - // - // Do not complete the OID request if the Oid handler is still running. - // Defer the OID completion to the Oid handler - // - OldOidState = MbbReqMgrGetSetOidState( - Request, - MbbNdisOidStateComplete - ); - if( OldOidState == MbbNdisOidStatePending || - OldOidState == MbbNdisOidStateDispatched ) - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Completing OID request in %!MbbOidState! to NDIS with status=%!status!", - Request->RequestId, OldOidState, NdisStatus - ); - OidName=GetOidName(NdisRequest->DATA.QUERY_INFORMATION.Oid); - OidNameLength=strlen(OidName)+1; - - MbbWriteEvent( - &REQUEST_COMPLETE_EVENT, - NULL, - NULL, - 10, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &NdisRequest, - sizeof(NdisRequest), - &NdisRequest->DATA.QUERY_INFORMATION.Oid, - sizeof(NdisRequest->DATA.QUERY_INFORMATION.Oid), - (PVOID)OidName, - OidNameLength, - &NdisRequest->RequestId, - sizeof(NdisRequest->RequestId), - &NdisRequest->RequestHandle, - sizeof(NdisRequest->RequestHandle), - &NdisRequest->RequestType, - sizeof(NdisRequest->RequestType), - &NdisRequest->DATA.QUERY_INFORMATION.BytesWritten, - sizeof(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten), - &NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded, - sizeof(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded), - &NdisStatus, - sizeof(NdisStatus) - ); - NdisMOidRequestComplete( - Adapter->MiniportAdapterHandle, - NdisRequest, - NdisStatus - ); - NdisRequest=NULL; - } - else - { - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Deferring oid completion in %!MbbOidState!", - Request->RequestId, OldOidState - ); - } - } - else - { - TraceWarn( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Oid already completed", - Request->RequestId - ); - - - } - - - return NDIS_STATUS_SUCCESS; - -} -#endif - - -// Device Services -#pragma warning(disable:6014) -NDIS_STATUS -MbbNdisDeviceServiceListStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - ULONG ElementCount = 0; - ULONG RequiredLength = 0; - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - PMBB_DEVICE_SERVICES_HEADER MbbDeviceServicesInfo = (PMBB_DEVICE_SERVICES_HEADER)InBuffer; - PMBB_DEVICE_SERVICE_ELEMENT MbbDeviceServiceElement = NULL; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - PMBB_DS CachedDSInfo = NULL; - ULONG i; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - // - // This function should only be called once when we initialize for caching - // the supported device list. From that point on, we should only be using - // the cached list (from MbbNdisEnumerateDeviceServices) - // - if( (MbbReqMgrIsInternalRequest( Request ) == FALSE) || - (MbbReqMgrIsUnsolicitedIndication( Request ) == TRUE) ) - { - // Ignore unsolicited indications or stuff not due to internal requests - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] UNEXPECTED DEVICE_SERVICES list notification", - Request->RequestId - ); - NdisStatus = NDIS_STATUS_NOT_ACCEPTED; - break; - } - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - // - // There is no device service list on failure. - // - if( (WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus )) != WWAN_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED DeviceServices request MbbStatus=%!MbbStatus!", - Request->RequestId, - MbbStatus - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - if( MbbDeviceServicesInfo == NULL || - InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_DEVICE_SERVICES_HEADER, MaxDSSSessions) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_DEVICE_SERVICES_HEADER, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_DEVICE_SERVICES_HEADER, MaxDSSSessions) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - // - // Cache everything in the device services state - // - Adapter = ((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request )); - - ElementCount = MbbDeviceServicesInfo->DeviceServicesCount; - - if (ElementCount == 0) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Zero device services supported", - Request->RequestId - ); - - Adapter->DeviceServiceState.ServicesList = NULL; - Adapter->DeviceServiceState.ServicesCount = 0; - Adapter->DeviceServiceState.MaxDSSSessions = 0; - ASSERT(FALSE); - - NdisStatus = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - // Not worrying about the CIDs yet. Those will be checked in a bit - NtStatus = RtlULongMult( - ElementCount, - sizeof(MBB_DEVICE_SERVICE_ELEMENT), - &RequiredLength - ); - - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, ElementCount=%d MBB_DEVICE_SERVICE_ELEMENT size=%d", - Request->RequestId, - ElementCount, - sizeof(MBB_DEVICE_SERVICE_ELEMENT) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - NtStatus = RtlULongAdd( - RequiredLength, - FIELD_OFFSET(MBB_DEVICE_SERVICES_HEADER, ArrayElement), - &RequiredLength - ); - - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, RequiredLength=%d FIELD_OFFSET=%d", - Request->RequestId, - RequiredLength, - FIELD_OFFSET(MBB_DEVICE_SERVICES_HEADER, ArrayElement) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - if( InBufferSize < RequiredLength ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_DEVICE_SERVICES_HEADER, BufferSize[Received=%d Expected=%d] ServiceCount=%d", - Request->RequestId, - InBufferSize, - RequiredLength, - ElementCount - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - CachedDSInfo = ALLOCATE_NONPAGED_POOL(ElementCount * sizeof(MBB_DS)); - - if ( CachedDSInfo == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for MBB_DS list, ServiceCount=%d", - Request->RequestId, - ElementCount * sizeof(MBB_DS), - ElementCount - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - RtlZeroMemory(CachedDSInfo, ElementCount * sizeof(MBB_DS)); - - // Presaved so that we can cleanup easier - Adapter->DeviceServiceState.ServicesList = CachedDSInfo; - Adapter->DeviceServiceState.ServicesCount = 0; // Will be incremented as we add stuff in - Adapter->DeviceServiceState.MaxDSSSessions = MbbDeviceServicesInfo->MaxDSSSessions; - - - for (i = 0; i < ElementCount; i++) - { - - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbDeviceServicesInfo->ArrayElement[i].Offset, - MbbDeviceServicesInfo->ArrayElement[i].Size, - 512, - sizeof(ULONG) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Array element %d is not valid", Request->RequestId, i); - break; - } - - MbbDeviceServiceElement = (PMBB_DEVICE_SERVICE_ELEMENT)(((PUCHAR)MbbDeviceServicesInfo) + - MbbDeviceServicesInfo->ArrayElement[i].Offset); - - RequiredLength = FIELD_OFFSET(MBB_DEVICE_SERVICE_ELEMENT, CIDList) + - MbbDeviceServiceElement->CIDCount * sizeof(ULONG); - - if ( InBufferSize < RequiredLength + MbbDeviceServicesInfo->ArrayElement[i].Offset) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT remaining size for MBB_DEVICE_SERVICE_HEADER, BufferSize[Received=%d Expected=%d] ServiceIndex=%d", - Request->RequestId, - InBufferSize, - RequiredLength, - i - ); - - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - - // - // Copy it while swapping order - // - MBB_UUID_TO_HOST(&(CachedDSInfo[i].DeviceServiceId), - &MbbDeviceServiceElement->DeviceServiceId - ); - - // - // This is a direct mapping - // - CachedDSInfo[i].DSSCapability = MbbDeviceServiceElement->DSSPayload; - - CachedDSInfo[i].MaxDSSInstances = MbbDeviceServiceElement->MaxDSSInstances; - - if (MbbDeviceServiceElement->CIDCount != 0) - { - CachedDSInfo[i].CIDList = ALLOCATE_NONPAGED_POOL(MbbDeviceServiceElement->CIDCount * sizeof(ULONG)); - - if( CachedDSInfo[i].CIDList == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for CID list, ServiceIndex=%d", - Request->RequestId, - MbbDeviceServiceElement->CIDCount * sizeof(ULONG), - i - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - // - // Copy the CID list - // - CachedDSInfo[i].CIDCount = MbbDeviceServiceElement->CIDCount; - - RtlCopyMemory(CachedDSInfo[i].CIDList, - MbbDeviceServiceElement->CIDList, - MbbDeviceServiceElement->CIDCount * sizeof(ULONG) - ); - } - - // - // One more entry added - // - Adapter->DeviceServiceState.ServicesCount++; - - } - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - break; - } - } - while( FALSE ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - if (Adapter != NULL) - { - // Free anything that we have ended up allocating - FreeDeviceServiceState(&(Adapter->DeviceServiceState)); - } - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisDeviceServiceResponseStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - ULONG NdisDeviceServiceResponseSize = 0; - NDIS_WWAN_DEVICE_SERVICE_RESPONSE LocalNdisDeviceServiceResponse; - PNDIS_WWAN_DEVICE_SERVICE_RESPONSE NdisDeviceServiceResponse = NULL; - - do - { - RtlZeroMemory(&LocalNdisDeviceServiceResponse, sizeof(LocalNdisDeviceServiceResponse)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS ) - { - break; - } - - - if (InBufferSize > (ULONG_MAX - sizeof(NDIS_WWAN_DEVICE_SERVICE_RESPONSE))) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Device service response too big for NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE, VendorDataSize=%dBytes", - Request->RequestId, - InBufferSize - - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisDeviceServiceResponseSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_RESPONSE) + InBufferSize; - - if( (NdisDeviceServiceResponse = (PNDIS_WWAN_DEVICE_SERVICE_RESPONSE) ALLOCATE_NONPAGED_POOL(NdisDeviceServiceResponseSize)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to allocate memory for NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE, VendorDataSize=%dBytes", - Request->RequestId, - InBufferSize - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisDeviceServiceResponse->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceServiceResponse->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_RESPONSE_1; - NdisDeviceServiceResponse->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_RESPONSE_REVISION_1; - - NdisDeviceServiceResponse->Response.DeviceServiceGuid = Request->HandlerContext.Response.Command.ServiceId; - NdisDeviceServiceResponse->Response.ResponseID = Request->HandlerContext.Response.Command.CommandId; - NdisDeviceServiceResponse->Response.uDataSize = InBufferSize; - - // No fragmentation support - - if( InBufferSize != 0 ) - { - RtlCopyMemory( - NdisDeviceServiceResponse + 1, - InBuffer, - InBufferSize - ); - } - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if( NdisDeviceServiceResponse != NULL ) - { - StatusIndication.StatusBuffer = NdisDeviceServiceResponse; - StatusIndication.StatusBufferSize = NdisDeviceServiceResponseSize; - } - else - { - LocalNdisDeviceServiceResponse.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisDeviceServiceResponse.Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_RESPONSE_1; - LocalNdisDeviceServiceResponse.Header.Revision = NDIS_WWAN_DEVICE_SERVICE_RESPONSE_REVISION_1; - - LocalNdisDeviceServiceResponse.Response.DeviceServiceGuid = Request->HandlerContext.Response.Command.ServiceId; - LocalNdisDeviceServiceResponse.Response.ResponseID = Request->HandlerContext.Response.Command.CommandId; - LocalNdisDeviceServiceResponse.Response.uDataSize = 0; - - StatusIndication.StatusBuffer = &LocalNdisDeviceServiceResponse; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_RESPONSE); - } - ((PNDIS_WWAN_DEVICE_SERVICE_RESPONSE)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if( NdisDeviceServiceResponse != NULL ) - { - FREE_POOL( NdisDeviceServiceResponse ); - } - return (WwanStatus == WWAN_STATUS_SMS_MORE_DATA)? NDIS_STATUS_PENDING: NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisDeviceServiceEventStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - ULONG NdisDeviceServiceEventSize; - PNDIS_WWAN_DEVICE_SERVICE_EVENT NdisDeviceServiceEvent = NULL; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - NtStatus = RtlULongAdd( - InBufferSize, - sizeof(NDIS_WWAN_DEVICE_SERVICE_EVENT), - &NdisDeviceServiceEventSize - ); - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Addition overflow occured, InBufferSize=%d NDIS_WWAN_DEVICE_SERVICE_EVENT size=%d", - Request->RequestId, - InBufferSize, - sizeof(NDIS_WWAN_DEVICE_SERVICE_EVENT) - ); - break; - } - - if( (NdisDeviceServiceEvent = (PNDIS_WWAN_DEVICE_SERVICE_EVENT) ALLOCATE_NONPAGED_POOL(NdisDeviceServiceEventSize)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to allocate memory for NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT, VendorDataSize=%dBytes", - Request->RequestId, - InBufferSize - ); - break; - } - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - NdisDeviceServiceEvent->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceServiceEvent->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_EVENT_1; - NdisDeviceServiceEvent->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_EVENT_REVISION_1; - - NdisDeviceServiceEvent->Event.DeviceServiceGuid = Request->HandlerContext.Response.Command.ServiceId; - NdisDeviceServiceEvent->Event.EventID = Request->HandlerContext.Response.Command.CommandId; - NdisDeviceServiceEvent->Event.uDataSize = InBufferSize; - - if( InBufferSize != 0 ) - { - RtlCopyMemory( - NdisDeviceServiceEvent + 1, - InBuffer, - InBufferSize - ); - } - - StatusIndication.StatusBuffer = NdisDeviceServiceEvent; - StatusIndication.StatusBufferSize = NdisDeviceServiceEventSize; - - TraceInfo( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT", - Request->RequestId - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - } - while( FALSE ); - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - - if( NdisDeviceServiceEvent != NULL ) - { - FREE_POOL( NdisDeviceServiceEvent ); - } - return (WwanStatus == WWAN_STATUS_SMS_MORE_DATA)? NDIS_STATUS_PENDING: NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisDeviceServiceStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - if (!MbbUtilIsValidDeviceService(&(Request->HandlerContext.Response.Command.ServiceId))) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Dropping indication with invalid device service %!GUID!", - Request->RequestId, - &(Request->HandlerContext.Response.Command.ServiceId) - ); - return NDIS_STATUS_INVALID_DATA; - } - - if (MbbReqMgrIsUnsolicitedIndication(Request)) - { - // This is an event - return MbbNdisDeviceServiceEventStatusHandler(Request, - NdisStatus, - MbbStatus, - InBuffer, - InBufferSize - ); - } - else - { - // This is a response - return MbbNdisDeviceServiceResponseStatusHandler(Request, - NdisStatus, - MbbStatus, - InBuffer, - InBufferSize - ); - } -} - -NDIS_STATUS -MbbNdisVendorSpecificStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - ULONG NdisVendorSpecificResponseSize = 0; - NDIS_WWAN_VENDOR_SPECIFIC LocalNdisVendorSpecific; - PNDIS_WWAN_VENDOR_SPECIFIC NdisVendorSpecific = NULL; - - do - { - RtlZeroMemory(&LocalNdisVendorSpecific, sizeof(LocalNdisVendorSpecific)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_VENDOR_SPECIFIC - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_VENDOR_SPECIFIC, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if( WwanStatus != WWAN_STATUS_SUCCESS ) - { - break; - } - - - if (InBufferSize > (ULONG_MAX - sizeof(NDIS_WWAN_VENDOR_SPECIFIC))) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Vendor specific response too big for NDIS_STATUS_WWAN_VENDOR_SPECIFIC, VendorDataSize=%dBytes", - Request->RequestId, - InBufferSize - - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisVendorSpecificResponseSize = sizeof(NDIS_WWAN_VENDOR_SPECIFIC) + InBufferSize; - - if( (NdisVendorSpecific = (PNDIS_WWAN_VENDOR_SPECIFIC) ALLOCATE_NONPAGED_POOL(NdisVendorSpecificResponseSize)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to allocate memory for NDIS_STATUS_WWAN_VENDOR_SPECIFIC, VendorDataSize=%dBytes", - Request->RequestId, - InBufferSize - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisVendorSpecific->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisVendorSpecific->Header.Size = sizeof(NDIS_WWAN_VENDOR_SPECIFIC); - NdisVendorSpecific->Header.Revision = NDIS_WWAN_VENDOR_SPECIFIC_REVISION_1; - - NdisVendorSpecific->VendorSpecificData.uVendorSpecificBufferSize = InBufferSize; - - if( InBufferSize != 0 ) - { - RtlCopyMemory( - NdisVendorSpecific + 1, - InBuffer, - InBufferSize - ); - } - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if( NdisVendorSpecific != NULL ) - { - StatusIndication.StatusBuffer = NdisVendorSpecific; - StatusIndication.StatusBufferSize = NdisVendorSpecificResponseSize; - } - else - { - LocalNdisVendorSpecific.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisVendorSpecific.Header.Size = sizeof(NDIS_WWAN_VENDOR_SPECIFIC); - LocalNdisVendorSpecific.Header.Revision = NDIS_WWAN_VENDOR_SPECIFIC_REVISION_1; - - LocalNdisVendorSpecific.VendorSpecificData.uVendorSpecificBufferSize = 0; - - StatusIndication.StatusBuffer = &LocalNdisVendorSpecific; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_VENDOR_SPECIFIC); - } - - // WwanStatus is only used for trace purpose. NDIS_WWAN_VENDOR_SPECIFIC doesn't have uStaus field. - TraceInfo( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_VENDOR_SPECIFIC with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if( NdisVendorSpecific != NULL ) - { - FREE_POOL( NdisVendorSpecific ); - } - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSubscribeDeviceServiceEventsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_DEVICE_SERVICE_SUBSCRIPTION NdisDeviceServiceSubscription; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - - do - { - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - // - // We will be sending the notification up. - // If this is a set requested by the OS and the request - // succeeded, persist the radio state in registry and locally - // - if ((Request->OidContext.OidRequestId != 0) && - (MbbReqMgrIsSetOid( Request )) && - (WwanStatus == WWAN_STATUS_SUCCESS) ) - { - // - // OS initiated SET request that succeeded. The subscription - // list from the OS has been persisted in DataToFreeOnResponse - // Save it - // - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - MbbAdapterLock(Adapter); - if (Adapter->DeviceServiceState.ExtSubscribeList != NULL) - FREE_POOL( Adapter->DeviceServiceState.ExtSubscribeList ); - - Adapter->DeviceServiceState.ExtSubscribeList = - Request->HandlerContext.Parameters.EventSubscribe.ExtList; - Adapter->DeviceServiceState.ExtSubscribeListBufferSize = - Request->HandlerContext.Parameters.EventSubscribe.ExtSize; - - MbbAdapterUnlock(Adapter); - - // We have taken ownership of the pointer - Request->HandlerContext.DataToFreeOnResponse = NULL; - } - - } - while (FALSE); - - // - // If this is for an OS request, send the notification up - // - if( (MbbReqMgrIsInternalRequest( Request ) == FALSE)) - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION - ); - - NdisDeviceServiceSubscription.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceServiceSubscription.Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SUBSCRIPTION_1; - NdisDeviceServiceSubscription.Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SUBSCRIPTION_REVISION_1; - - NdisDeviceServiceSubscription.DeviceServiceListHeader.ElementType = WwanStructDeviceServiceGuid; - NdisDeviceServiceSubscription.DeviceServiceListHeader.ElementCount = 0; - - - NdisDeviceServiceSubscription.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisDeviceServiceSubscription; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SUBSCRIPTION); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - } - - return NdisStatus; -} - - -NDIS_STATUS -MbbNdisSetUSSD( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PMBB_SET_USSD MbbSetUSSD; - PNDIS_WWAN_USSD_REQUEST NdisUSSDRequest = (PNDIS_WWAN_USSD_REQUEST)InBuffer; - NDIS_STATUS Status; - ULONG MbbSetUSSDSize; - ULONG UssdStringLengthRounded; - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_USSD_REQUEST) ); - *InBufferSize = sizeof(NDIS_WWAN_USSD_REQUEST); - UssdStringLengthRounded = NdisUSSDRequest->UssdRequest.UssdString.StringLength; - UssdStringLengthRounded = ROUND_UP_COUNT( UssdStringLengthRounded, ALIGN_DWORD ); - // - // Both lengths are checked to detect overflow. - // - if( NdisUSSDRequest->UssdRequest.UssdString.StringLength > MBB_USSD_STRING_LEN_MAX || - UssdStringLengthRounded > MBB_USSD_STRING_LEN_MAX ) - { - TraceError( WMBCLASS_OID, "[MbbNdis] USSD string too long: 0x%x", - NdisUSSDRequest->UssdRequest.UssdString.StringLength - ); - Status = NDIS_STATUS_INVALID_LENGTH; - return Status; - } - - //determine length of buffer - MbbSetUSSDSize = FIELD_OFFSET(MBB_SET_USSD, DataBuffer); - MbbSetUSSDSize = ROUND_UP_COUNT( MbbSetUSSDSize, ALIGN_DWORD ); - MbbSetUSSDSize += UssdStringLengthRounded; - - if( (MbbSetUSSD = (PMBB_SET_USSD) ALLOCATE_NONPAGED_POOL( MbbSetUSSDSize )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSetUSSD; - - RtlZeroMemory( MbbSetUSSD, MbbSetUSSDSize ); - - Status = MbbUtilWwanToMbbSetUSSD( - MbbSetUSSD, - &NdisUSSDRequest->UssdRequest - ); - if (Status != NDIS_STATUS_SUCCESS){ - return Status; - } - - - return MbbUtilSetAttributeWithParameter( - Request, - (PCHAR)MbbSetUSSD, - MbbSetUSSDSize - ); -} - - - -NDIS_STATUS -MbbNdisUSSDStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_USSD_EVENT NdisWWanUSSDEvt; - PMBB_USSD MbbUSSDResponse = (PMBB_USSD)InBuffer; - NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; - - do - { - - RtlZeroMemory(&NdisWWanUSSDEvt, sizeof(NdisWWanUSSDEvt)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_USSD - ); - - NdisWWanUSSDEvt.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisWWanUSSDEvt.Header.Size = sizeof(NDIS_WWAN_USSD_EVENT); - NdisWWanUSSDEvt.Header.Revision = NDIS_WWAN_USSD_EVENT_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_USSD, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - // - // If the device returned MBIM error status and didnt provide any data - // propagate the error code to the service. Sometimes data can be sent - // by the device even if the device reports error. - // - if ( (WwanStatus != WWAN_STATUS_SUCCESS) && - InBufferSize < (ULONG)FIELD_OFFSET(MBB_USSD,DataBuffer) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Device FAILED USSD request, status=%!MbbStatus!", - Request->RequestId, - MbbStatus - ); - break; - } - - // - // the request succeeded, or if failed and returned a minimal valid buffer - // - - // - // Check for min or max data size from device - // - if( MbbUSSDResponse == NULL - || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_USSD,DataBuffer) - - ) - { - - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Insufficient BufferSize for NDIS_STATUS_WWAN_USSD, BufferSize[Received=%d Min Expected=%d", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_USSD,DataBuffer) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisStatus=MbbIsVariableFieldValid( - InBufferSize, - MbbUSSDResponse->USSDPayload.Offset, - MbbUSSDResponse->USSDPayload.Size, - MBB_USSD_STRING_LEN_MAX, - sizeof(UCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Incorrect BufferSize for NDIS_STATUS_WWAN_USSD, BufferSize[Received=%d Min Expected=%d payload=%d", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_USSD,DataBuffer), - MbbUSSDResponse->USSDPayload.Size - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - - } - - - LocalNdisStatus = MbbUtilMbbToWwanUSSDEvent( - MbbUSSDResponse, - &NdisWWanUSSDEvt.UssdEvent - ); - - if( LocalNdisStatus != NDIS_STATUS_SUCCESS ) - { - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - } - while( FALSE ); - - NdisWWanUSSDEvt.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisWWanUSSDEvt; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_USSD_EVENT); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_USSD with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisGetAuthChallenge( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - MBB_SIM_AUTH_CHALLENGE MbbSimAuthChallenge; - MBB_AKA_AUTH_CHALLENGE MbbAKAAuthChallenge; - PMBB_AKAP_AUTH_CHALLENGE MbbAKAPAuthChallenge; - - PNDIS_WWAN_AUTH_CHALLENGE NdisAuthRequest = (PNDIS_WWAN_AUTH_CHALLENGE)InBuffer; - NDIS_STATUS Status; - - // - // Size is already verified in MbbNdisMiniportOidRequest( ) - // - __analysis_assume( *InBufferSize >= sizeof(NDIS_WWAN_AUTH_CHALLENGE) ); - *InBufferSize = sizeof(NDIS_WWAN_AUTH_CHALLENGE); - - if(NdisAuthRequest->AuthChallenge.AuthMethod == WwanAuthAka){ - RtlCopyMemory( &MbbAKAAuthChallenge, - &NdisAuthRequest->AuthChallenge.u.AuthAka, - sizeof(MbbAKAAuthChallenge) ); - - return MbbUtilQueryAttributeWithParameter( - Request, - (PCHAR)(&MbbAKAAuthChallenge), - sizeof(MbbAKAAuthChallenge) - ); - } - else if (NdisAuthRequest->AuthChallenge.AuthMethod == WwanAuthAkaPrime) - { - ULONG MbbSize; - ULONG UTF16ByteCount; - // - // Calculate required length - // - if (NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkNameLength > WWAN_AUTH_NETWORK_NAME_MAX_LEN) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] NetworkNameLength invalid, %d", - Request->RequestId, - NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkNameLength - ); - - return NDIS_STATUS_INVALID_PARAMETER; - } - - Status = RtlUTF8ToUnicodeN( - NULL, - 0, - &UTF16ByteCount, - (PCCH)(NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkName), - NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkNameLength - ); - if( STATUS_SUCCESS != Status ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED RtlUTF8ToUnicodeN(%s)=%!STATUS!, ignoring=%!BOOLEAN!", - Request->RequestId, - NdisAuthRequest->AuthChallenge.u.AuthAkap.NetworkName, - Status, - (STATUS_SOME_NOT_MAPPED == Status) - ); - if( STATUS_SOME_NOT_MAPPED != Status ) - return Status; - else - Status = STATUS_SUCCESS; - } - - MbbSize = ROUND_UP_COUNT( FIELD_OFFSET( MBB_AKAP_AUTH_CHALLENGE, DataBuffer ), ALIGN_DWORD ); - MbbSize += ROUND_UP_COUNT( UTF16ByteCount, ALIGN_DWORD ); - - // - // Allocate the buffer and convert - // - if( (MbbAKAPAuthChallenge = (PMBB_AKAP_AUTH_CHALLENGE) ALLOCATE_NONPAGED_POOL( MbbSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to allocate AuthAkapChallenge for %dbytes", - Request->RequestId, - MbbSize - ); - return NDIS_STATUS_RESOURCES; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbAKAPAuthChallenge; - - if( (Status = MbbUtilWwanToMbbAkapAuthChallenge( - &NdisAuthRequest->AuthChallenge.u.AuthAkap, - UTF16ByteCount, - MbbSize, - MbbAKAPAuthChallenge - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to convert AuthAkapChallenge, NtStatus=%!STATUS!", - Request->RequestId, - Status - ); - return Status; - } - return MbbUtilQueryAttributeWithParameter( - Request, - (PCHAR)MbbAKAPAuthChallenge, - MbbSize - ); - } - else if (NdisAuthRequest->AuthChallenge.AuthMethod == WwanAuthSim){ - RtlCopyMemory( &MbbSimAuthChallenge, - &NdisAuthRequest->AuthChallenge.u.AuthSim, - sizeof(MbbSimAuthChallenge) ); - - return MbbUtilQueryAttributeWithParameter( - Request, - (PCHAR)(&MbbSimAuthChallenge), - sizeof(MbbSimAuthChallenge) - ); - } - else{ - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] AUTH CHALLENGE specified is invalid, %d", - Request->RequestId, - NdisAuthRequest->AuthChallenge.AuthMethod); - return NDIS_STATUS_INVALID_PARAMETER; - } -} - -NDIS_STATUS -MbbNdisAuthAKAStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_AUTH_RESPONSE NdisWWanAuthRes; - PMBB_AKA_AUTH_RESPONSE MbbAuthResponse = (PMBB_AKA_AUTH_RESPONSE)InBuffer; - NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; - - do - { - RtlZeroMemory(&NdisWWanAuthRes, sizeof(NdisWWanAuthRes)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_AUTH_RESPONSE - ); - - NdisWWanAuthRes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisWWanAuthRes.Header.Size = sizeof(NDIS_WWAN_AUTH_RESPONSE); - NdisWWanAuthRes.Header.Revision = NDIS_WWAN_AUTH_CHALLENGE_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_AUTH_RESPONSE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - // - // On certain error statuses there might be valid data - // - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - if( WwanStatus != WWAN_STATUS_SUCCESS && - WwanStatus != WWAN_STATUS_AUTH_SYNC_FAILURE ) - { - break; - } - - if( MbbAuthResponse == NULL || - InBufferSize < sizeof(*MbbAuthResponse) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_WWAN_AUTH_RESPONSE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(*MbbAuthResponse) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // - // Convert from MBB to WWAN messages. - // - RtlCopyMemory( &NdisWWanAuthRes.AuthResponse.u.AuthAka, - MbbAuthResponse, - sizeof(*MbbAuthResponse) ); - - - } - while( FALSE ); - // - // On internal error do not restore the device returned operational status - // since the service may be expecting certain data on certain status. - // - NdisWWanAuthRes.uStatus = WwanStatus; - NdisWWanAuthRes.AuthResponse.AuthMethod = WwanAuthAka; - - StatusIndication.StatusBuffer = &NdisWWanAuthRes; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_AUTH_RESPONSE); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_WWAN_AUTH_RESPONSE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - - -NDIS_STATUS -MbbNdisAuthAKAPStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_AUTH_RESPONSE NdisWWanAuthRes; - PMBB_AKAP_AUTH_RESPONSE MbbAuthResponse = (PMBB_AKAP_AUTH_RESPONSE)InBuffer; - NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; - - do - { - RtlZeroMemory(&NdisWWanAuthRes, sizeof(NdisWWanAuthRes)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_AUTH_RESPONSE - ); - - NdisWWanAuthRes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisWWanAuthRes.Header.Size = sizeof(NDIS_WWAN_AUTH_RESPONSE); - NdisWWanAuthRes.Header.Revision = NDIS_WWAN_AUTH_CHALLENGE_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_AUTH_RESPONSE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - // - // On certain error statuses there might be valid data - // - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - if( WwanStatus != WWAN_STATUS_SUCCESS && - WwanStatus != WWAN_STATUS_AUTH_SYNC_FAILURE ) - { - break; - } - - if( MbbAuthResponse == NULL || - InBufferSize < sizeof(*MbbAuthResponse) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_WWAN_AUTH_RESPONSE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(*MbbAuthResponse) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // - // Convert from MBB to WWAN messages. - // - RtlCopyMemory( &NdisWWanAuthRes.AuthResponse.u.AuthAkap, - MbbAuthResponse, - sizeof(*MbbAuthResponse) ); - - - } - while( FALSE ); - // - // On internal error do not restore the device returned operational status - // since the service may be expecting certain data on certain status. - // - NdisWWanAuthRes.uStatus = WwanStatus; - NdisWWanAuthRes.AuthResponse.AuthMethod = WwanAuthAkaPrime; - - StatusIndication.StatusBuffer = &NdisWWanAuthRes; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_AUTH_RESPONSE); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_WWAN_AUTH_RESPONSE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - - -NDIS_STATUS -MbbNdisAuthSIMStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_AUTH_RESPONSE NdisWWanAuthRes; - PMBB_SIM_AUTH_RESPONSE MbbAuthResponse = (PMBB_SIM_AUTH_RESPONSE)InBuffer; - NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; - - do - { - RtlZeroMemory(&NdisWWanAuthRes, sizeof(NdisWWanAuthRes)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_AUTH_RESPONSE - ); - - NdisWWanAuthRes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisWWanAuthRes.Header.Size = sizeof(NDIS_WWAN_AUTH_RESPONSE); - NdisWWanAuthRes.Header.Revision = NDIS_WWAN_AUTH_CHALLENGE_REVISION_1; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_AUTH_RESPONSE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - if (WwanStatus != WWAN_STATUS_SUCCESS){ - break; - } - - if( MbbAuthResponse == NULL || - InBufferSize < sizeof(*MbbAuthResponse) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_WWAN_AUTH_RESPONSE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(*MbbAuthResponse) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // - // Convert from MBB to WWAN messages. - // - RtlCopyMemory( &NdisWWanAuthRes.AuthResponse.u.AuthSim, - MbbAuthResponse, - sizeof(*MbbAuthResponse) ); - - - } - while( FALSE ); - - NdisWWanAuthRes.uStatus = WwanStatus; - NdisWWanAuthRes.AuthResponse.AuthMethod = WwanAuthSim; - - StatusIndication.StatusBuffer = &NdisWWanAuthRes; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_AUTH_RESPONSE); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_WWAN_AUTH_RESPONSE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - - - -NDIS_STATUS -MbbNdisDssStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize, - __in WWAN_DEVICE_SERVICE_SESSION_STATE NewState - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_DEVICE_SERVICE_SESSION_INFO NdisWWanSessionInfo; - NDIS_STATUS LocalNdisStatus = NDIS_STATUS_SUCCESS; - - if (MbbReqMgrIsUnsolicitedIndication(Request)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Dropping unsolicited Device Service Session state notification", - Request->RequestId - ); - return NDIS_STATUS_NOT_ACCEPTED; - } - - do - { - - RtlZeroMemory(&NdisWWanSessionInfo, sizeof(NdisWWanSessionInfo)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION - ); - - NdisWWanSessionInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisWWanSessionInfo.Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_INFO_1; - NdisWWanSessionInfo.Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SESSION_INFO_REVISION_1; - - // - // Populate the saved info for the request - // - NdisWWanSessionInfo.Session.State = Request->HandlerContext.Parameters.DssSession.LinkState == MbbDssLinkActivate ? - WwanDeviceServiceSessionOpen : WwanDeviceServiceSessionClosed; - - RtlCopyMemory( - &NdisWWanSessionInfo.Session.DeviceServiceGuid, - &Request->HandlerContext.Parameters.DssSession.DeviceServiceGuid, - sizeof(GUID) - ); - - NdisWWanSessionInfo.Session.uSessionID = Request->HandlerContext.Parameters.DssSession.SessionId; - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - if (WwanStatus != WWAN_STATUS_SUCCESS){ - break; - } - - } - while( FALSE ); - - NdisWWanSessionInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisWWanSessionInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_INFO); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - - - -NDIS_STATUS -MbbNdisDssOpenStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - // Forward to the generic handler - return MbbNdisDssStateStatusHandler( - Request, - NdisStatus, - MbbStatus, - InBuffer, - InBufferSize, - WwanDeviceServiceSessionOpen - ); -} - - -NDIS_STATUS -MbbNdisDssCloseStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - // Forward to the generic handler - return MbbNdisDssStateStatusHandler( - Request, - NdisStatus, - MbbStatus, - InBuffer, - InBufferSize, - WwanDeviceServiceSessionClosed - ); - -} - - -NDIS_STATUS -MbbNdisDssWriteCompleteStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE NdisDssWriteComplete; - - do - { - - RtlZeroMemory(&NdisDssWriteComplete, sizeof(NdisDssWriteComplete)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE - ); - - NdisDssWriteComplete.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDssWriteComplete.Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE_1; - NdisDssWriteComplete.Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE_REVISION_1; - - WwanStatus = MbbUtilNdisToWwanStatus( NdisStatus ); - if (WwanStatus != WWAN_STATUS_SUCCESS) - break; - - } - while( FALSE ); - - NdisDssWriteComplete.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisDssWriteComplete; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - // Derefence the request - MbbReqMgrDerefRequest(Request); - - return NDIS_STATUS_SUCCESS; -} - - -VOID -MbbNdisDeviceServiceSessionSendComplete( - __in MBB_REQUEST_HANDLE RequestHandle, - __in NDIS_STATUS NdisStatus - ) -{ - PMBB_OID_HANDLER_ENTRY OidHandler; - - OidHandler = MbbNdisGetOidHandler(OID_WWAN_DEVICE_SERVICE_SESSION_WRITE); - - if (OidHandler) - { - // Call the common handler to handle the indication - MbbUtilCommonCIDResponse( - (PMBB_REQUEST_CONTEXT)RequestHandle, - NdisStatus, - WWAN_STATUS_SUCCESS, - NULL, - 0, - OidHandler - ); - } -} - -NDIS_STATUS -MbbNdisDeviceServiceSessionReceive( - __in PMINIPORT_ADAPTER_CONTEXT AdapterContext, - __in ULONG SessionId, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - NDIS_STATUS_INDICATION StatusIndication; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ NdisWwanDssRead = NULL; - ULONG TotalNdisWwanSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_SESSION_READ) + InBufferSize; - - do - { - // Allocate memory for the output buffer - if( (NdisWwanDssRead = (PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ) ALLOCATE_NONPAGED_POOL( TotalNdisWwanSize )) == NULL ) - { - TraceError( WMBCLASS_RECEIVE, "[Receive][DSS Read] FAILED to allocate for PNDIS_WWAN_DEVICE_SERVICE_SESSION_READ %d bytes", - TotalNdisWwanSize - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - NdisWwanDssRead->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisWwanDssRead->Header.Size = SIZEOF_NDIS_WWAN_DEVICE_SERVICE_SESSION_READ_1; - NdisWwanDssRead->Header.Revision = NDIS_WWAN_DEVICE_SERVICE_SESSION_READ_REVISION_1; - - NdisWwanDssRead->ReadData.uDataSize = InBufferSize; - NdisWwanDssRead->ReadData.uSessionID = SessionId; - - // Copy the data. We cannot use the original buffer because it doesnt - // have space for the session Id, etc - RtlCopyMemory( - (PUCHAR)(NdisWwanDssRead + 1), - InBuffer, - InBufferSize - ); - - // Create the status indication - MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION( - &StatusIndication, - AdapterContext->MiniportAdapterHandle, - NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ - ); - - StatusIndication.StatusBuffer = NdisWwanDssRead; - StatusIndication.StatusBufferSize = TotalNdisWwanSize; - - TraceInfo( WMBCLASS_RECEIVE, "[Receive][DSS Read] Indicating NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ"); - - MbbUtilNdisMiniportIndicateStatusEx( - AdapterContext, - &StatusIndication - ); - - } - while( FALSE ); - - if (NdisWwanDssRead) - { - FREE_POOL(NdisWwanDssRead); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisMultiCarrierDsCidListStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - GUID DsServiceId; - ULONG CidIndex; - ULONG ExpectedSize; - WWAN_STATUS WwanStatus; - PMINIPORT_ADAPTER_CONTEXT Adapter; - PMBB_MULTICARRIER_CURRENT_CID_LIST MbbMulticarrierCidList; - - do - { - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle( Request ); - // - // If we couldnt retrieve the data then bail out. - // - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to get data for MBB_MULTICARRIER_CID_CURRENT_CID_LIST, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - if( WWAN_STATUS_SUCCESS != WwanStatus ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] FAILED to get data for MBB_MULTICARRIER_CID_CURRENT_CID_LIST, status=%!STATUS!", - Request->RequestId, - WwanStatus - ); - break; - } - // - // Verify the received data - // - MbbMulticarrierCidList = (PMBB_MULTICARRIER_CURRENT_CID_LIST)InBuffer; - ExpectedSize = RTL_SIZEOF_THROUGH_FIELD(MBB_MULTICARRIER_CURRENT_CID_LIST, CIDCount); - - if( MbbMulticarrierCidList == NULL || - InBufferSize < ExpectedSize ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_MULTICARRIER_CID_CURRENT_CID_LIST, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - ExpectedSize - ); - break; - } - - NdisStatus = RtlULongMult( - sizeof(ULONG), - MbbMulticarrierCidList->CIDCount, - &ExpectedSize - ); - if( NT_ERROR( NdisStatus ) ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INTEGER OVERFLOW : 0x%x * 0x%x = 0x%I64x", - Request->RequestId, - MbbMulticarrierCidList->CIDCount, - sizeof(ULONG), - ((ULONGLONG)(MbbMulticarrierCidList->CIDCount)) * sizeof(ULONG) - ); - break; - } - - NdisStatus = RtlULongAdd( - ExpectedSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_MULTICARRIER_CURRENT_CID_LIST, CIDCount), - &ExpectedSize - ); - if( NT_ERROR( NdisStatus ) ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INTEGER OVERFLOW : 0x%x + 0x%x = 0x%I64x", - Request->RequestId, - ExpectedSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_MULTICARRIER_CURRENT_CID_LIST, CIDCount), - ((ULONGLONG)ExpectedSize) + RTL_SIZEOF_THROUGH_FIELD(MBB_MULTICARRIER_CURRENT_CID_LIST, CIDCount) - ); - break; - } - - if( InBufferSize < ExpectedSize ) - { - TraceError( WMBCLASS_INIT, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for MBB_MULTICARRIER_CID_CURRENT_CID_LIST, CidCount=%d BufferSize[Received=%d Expected=%d]", - Request->RequestId, - MbbMulticarrierCidList->CIDCount, - InBufferSize, - ExpectedSize - ); - break; - } - // - // There is valid data, convert the CIDList to capabilities - // - MBB_UUID_TO_NET( - &DsServiceId, - &Request->HandlerContext.Parameters.DeviceCaps.CurrentQueriedDeviceService - ); - if( RtlCompareMemory( - &DsServiceId, - &MBB_UUID_USSD, - sizeof(GUID) - ) == sizeof(GUID) ) - { - if( MbbMulticarrierCidList->CIDCount > 0 ) - { - MbbAdapterLock( Adapter ); - Adapter->AdapterFlags.IsUssdCapable = TRUE; - MbbAdapterUnlock( Adapter ); - } - Request->HandlerContext.Parameters.DeviceCaps.IsUssdCapsValid = 1; - } else if( RtlCompareMemory( - &DsServiceId, - &MBB_UUID_AUTH, - sizeof(GUID) - ) == sizeof(GUID) ) - { - MbbAdapterLock( Adapter ); - for(CidIndex = 0; - CidIndex < MbbMulticarrierCidList->CIDCount; - CidIndex++ ) - { - switch( MbbMulticarrierCidList->CIDList[CidIndex] ) - { - case MBB_AUTH_CID_AKA: - { - Adapter->AdapterFlags.IsAkaAuthCapable = TRUE; - } - break; - - case MBB_AUTH_CID_AKAP: - { - Adapter->AdapterFlags.IsAkapAuthCapable = TRUE; - } - break; - - case MBB_AUTH_CID_SIM: - { - Adapter->AdapterFlags.IsSimAuthCapable = TRUE; - } - break; - } - } - MbbAdapterUnlock( Adapter ); - Request->HandlerContext.Parameters.DeviceCaps.IsAuthCapsValid = 1; - } - } - while( FALSE ); - - MbbNdisIndicateDeviceCaps( - Request, - NdisStatus - ); - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisUiccAppListStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -) -{ - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_UICC_APP_LIST NdisUiccAppList; - PMBB_UICC_APP_LIST MbbUiccAppList = (PMBB_UICC_APP_LIST)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_UICC_APP_LIST - ); - - RtlZeroMemory(&NdisUiccAppList, sizeof(NdisUiccAppList)); - - NdisUiccAppList.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisUiccAppList.Header.Size = sizeof(NDIS_WWAN_UICC_APP_LIST); - NdisUiccAppList.Header.Revision = NDIS_WWAN_UICC_APP_LIST_REVISION_1; - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_APP_LIST, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbUiccAppList == NULL || - InBufferSize < sizeof(MBB_UICC_APP_LIST)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_APP_LIST, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_UICC_APP_LIST) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanUiccAppList( - MbbUiccAppList, - &NdisUiccAppList.UiccAppList - ); - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisUiccAppList.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisUiccAppList; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_APP_LIST); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_APP_LIST with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisUiccFileStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_UICC_FILE_STATUS NdisUiccFileStatus; - PMBB_UICC_FILE_STATUS MbbUiccFileStatus = (PMBB_UICC_FILE_STATUS)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_UICC_FILE_STATUS - ); - - RtlZeroMemory(&NdisUiccFileStatus, sizeof(NdisUiccFileStatus)); - - NdisUiccFileStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisUiccFileStatus.Header.Size = sizeof(NDIS_WWAN_UICC_FILE_STATUS); - NdisUiccFileStatus.Header.Revision = NDIS_WWAN_UICC_FILE_STATUS_REVISION_1; - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_FILE_STATUS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbUiccFileStatus == NULL || - InBufferSize < sizeof(MBB_UICC_FILE_STATUS) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_FILE_STATUS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_UICC_FILE_STATUS) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanUiccFileStatus( - MbbUiccFileStatus, - &NdisUiccFileStatus.UiccFileStatus - ); - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisUiccFileStatus.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisUiccFileStatus; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_FILE_STATUS); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_FILE_STATUS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisUiccAccessStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - ULONG NdisUiccResponseSize = 0; - PNDIS_WWAN_UICC_RESPONSE NdisUiccResponse = NULL; - NDIS_WWAN_UICC_RESPONSE LocalNdisUiccResponse; - PMBB_UICC_RESPONSE MbbUiccResponse = (PMBB_UICC_RESPONSE)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_UICC_RESPONSE - ); - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_RESPONSE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbUiccResponse == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_UICC_RESPONSE, DataBuffer)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_RESPONSE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_UICC_RESPONSE, DataBuffer) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisUiccResponseSize = FIELD_OFFSET(NDIS_WWAN_UICC_RESPONSE, UiccResponse.ResponseData); - NdisUiccResponseSize += MbbUiccResponse->ResponseData.Size; - - NdisUiccResponse = (PNDIS_WWAN_UICC_RESPONSE)ALLOCATE_NONPAGED_POOL( NdisUiccResponseSize ); - - if( NdisUiccResponse == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_UICC_RESPONSE", - Request->RequestId, - NdisUiccResponseSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisUiccResponse, NdisUiccResponseSize); - - NdisUiccResponse->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisUiccResponse->Header.Size = sizeof(NDIS_WWAN_UICC_RESPONSE); - NdisUiccResponse->Header.Revision = NDIS_WWAN_UICC_RESPONSE_REVISION_1; - - MbbUtilMbbToWwanUiccResponse( - MbbUiccResponse, - &NdisUiccResponse->UiccResponse - ); - IndicationFailure = FALSE; - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if (!IndicationFailure) - { - NdisUiccResponse->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisUiccResponse; - StatusIndication.StatusBufferSize = NdisUiccResponseSize; - } - else - { - RtlZeroMemory(&LocalNdisUiccResponse, sizeof(NDIS_WWAN_UICC_RESPONSE)); - - LocalNdisUiccResponse.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisUiccResponse.Header.Size = sizeof(NDIS_WWAN_UICC_RESPONSE); - LocalNdisUiccResponse.Header.Revision = NDIS_WWAN_UICC_RESPONSE_REVISION_1; - LocalNdisUiccResponse.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisUiccResponse; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_RESPONSE); - } - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_RESPONSE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisUiccResponse != NULL) - { - FREE_POOL(NdisUiccResponse); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSysCapsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - NDIS_WWAN_SYS_CAPS_INFO NdisSysCapsInfo = { 0 }; - PMBB_MS_SYS_CAPS_INFO MbbSysCapsInfo = (PMBB_MS_SYS_CAPS_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SYS_CAPS_INFO - ); - - RtlZeroMemory(&NdisSysCapsInfo, sizeof(NDIS_WWAN_SYS_CAPS_INFO)); - - NdisSysCapsInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSysCapsInfo.Header.Size = sizeof(NDIS_WWAN_SYS_CAPS_INFO); - NdisSysCapsInfo.Header.Revision = NDIS_WWAN_SYS_CAPS_INFO_REVISION_1; - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SYS_CAPS_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbSysCapsInfo == NULL || - InBufferSize < sizeof(MBB_MS_SYS_CAPS_INFO)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SYS_CAPS_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_MS_SYS_CAPS_INFO) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanSysCapsInfo( - MbbSysCapsInfo, - &(NdisSysCapsInfo.SysCapsInfo) - ); - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisSysCapsInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisSysCapsInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SYS_CAPS_INFO); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SYS_CAPS_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisDeviceCapsExStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - BOOLEAN IsMultiMode = FALSE; - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - ULONG NdisDeviceCapsExSize = 0; - PNDIS_WWAN_DEVICE_CAPS_EX NdisDeviceCapsEx = NULL; - NDIS_WWAN_DEVICE_CAPS_EX LocalNdisDeviceCapsEx = { 0 }; - PMBB_MS_DEVICE_CAPS_INFO_V2 MbbDeviceCapsEx2 = (PMBB_MS_DEVICE_CAPS_INFO_V2)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = NULL; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_CAPS_EX - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_CAPS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbDeviceCapsEx2 == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_MS_DEVICE_CAPS_INFO_V2, DataBuffer)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_DEVICE_CAPS_EX, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_MS_DEVICE_CAPS_INFO_V2, DataBuffer) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbDeviceCapsEx2->CustomDataClass.Offset, - MbbDeviceCapsEx2->CustomDataClass.Size, - MBB_MAXIMUM_DATA_CLASS_NAME_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad custom data field, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - MbbDeviceCapsEx2->CustomDataClass.Offset, - MbbDeviceCapsEx2->CustomDataClass.Size, - InBufferSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbDeviceCapsEx2->DeviceIdString.Offset, - MbbDeviceCapsEx2->DeviceIdString.Size, - MBB_MAXIMUM_DEVICE_ID_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] DeviceId data field, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - MbbDeviceCapsEx2->DeviceIdString.Offset, - MbbDeviceCapsEx2->DeviceIdString.Size, - InBufferSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbDeviceCapsEx2->FirmwareInfo.Offset, - MbbDeviceCapsEx2->FirmwareInfo.Size, - MBB_MAXIMUM_FIRMWARE_INFO_LENGTH, - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FirmwareInfo data field, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - MbbDeviceCapsEx2->FirmwareInfo.Offset, - MbbDeviceCapsEx2->FirmwareInfo.Size, - InBufferSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisDeviceCapsExSize = sizeof(NDIS_WWAN_DEVICE_CAPS_EX); - // If only a single bit is set in CellularClass then the following expression should be zero. - // Otherwise the following expression should be non-zero. - IsMultiMode = (((MbbDeviceCapsEx2->CellularClass) & (MbbDeviceCapsEx2->CellularClass - 1)) != 0); - if (IsMultiMode) - { - NdisDeviceCapsExSize += sizeof(WWAN_CELLULAR_CLASS) * (MbbCellularClassMaximum - 1); - } - - NdisDeviceCapsEx = (PNDIS_WWAN_DEVICE_CAPS_EX)ALLOCATE_NONPAGED_POOL(NdisDeviceCapsExSize); - - if (NdisDeviceCapsEx == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_DEVICE_CAPS", - Request->RequestId, - NdisDeviceCapsExSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisDeviceCapsEx, NdisDeviceCapsExSize); - - NdisDeviceCapsEx->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceCapsEx->Header.Size = sizeof(NDIS_WWAN_DEVICE_CAPS_EX); - NdisDeviceCapsEx->Header.Revision = NDIS_WWAN_DEVICE_CAPS_EX_REVISION_1; - - // We need the Adapter to retrieve the Manufacturer and Model which are absent in MBB_MS_DEVICE_CAPS_INFO_V2. - Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - - MbbUtilMbbToWwanDeviceCapsV2( - MbbDeviceCapsEx2, - Adapter->BusParams.Manufacturer, - MAX_PARAMETER_STRING, - Adapter->BusParams.Model, - MAX_PARAMETER_STRING, - &(NdisDeviceCapsEx->DeviceCaps), - IsMultiMode - ); - - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps = WWAN_OPTIONAL_SERVICE_CAPS_NONE; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsProvisionedContextV2Capable ? WWAN_OPTIONAL_SERVICE_CAPS_PROVISIONED_CONTEXT_MGMT : 0; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsNetworkBlacklistCapable ? WWAN_OPTIONAL_SERVICE_CAPS_NETWORK_BLACKLIST : 0; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsLTEAttachConfigCapable ? WWAN_OPTIONAL_SERVICE_CAPS_LTE_ATTACH : 0; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsMultiSIMCapable ? WWAN_OPTIONAL_SERVICE_CAPS_MULTI_SIM : 0; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsSARCapable ? WWAN_OPTIONAL_SERVICE_CAPS_SAR : 0; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsPcoCapable ? WWAN_OPTIONAL_SERVICE_CAPS_PCO : 0; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsUiccLowLevelCapable ? WWAN_OPTIONAL_SERVICE_CAPS_UICC_RESET : 0; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsDeviceResetCapable ? WWAN_OPTIONAL_SERVICE_CAPS_DEVICE_RESET : 0; - NdisDeviceCapsEx->DeviceCaps.WwanOptionalServiceCaps |= - Adapter->AdapterFlags.IsBaseStationsInfoCapable ? WWAN_OPTIONAL_SERVICE_CAPS_BASE_STATIONS_INFO : 0; - - IndicationFailure = FALSE; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - if (!IndicationFailure) - { - NdisDeviceCapsEx->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisDeviceCapsEx; - StatusIndication.StatusBufferSize = NdisDeviceCapsExSize; - } - else - { - RtlZeroMemory(&LocalNdisDeviceCapsEx, sizeof(NDIS_WWAN_DEVICE_CAPS_EX)); - - LocalNdisDeviceCapsEx.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisDeviceCapsEx.Header.Size = sizeof(NDIS_WWAN_DEVICE_CAPS_EX); - LocalNdisDeviceCapsEx.Header.Revision = NDIS_WWAN_DEVICE_CAPS_EX_REVISION_1; - LocalNdisDeviceCapsEx.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisDeviceCapsEx; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_CAPS_EX); - } - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_CAPS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisDeviceCapsEx != NULL) - { - FREE_POOL(NdisDeviceCapsEx); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSysSlotMappingsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - ULONG NdisDeviceSlotMappingInfoSize = 0; - PNDIS_WWAN_DEVICE_SLOT_MAPPING_INFO NdisDeviceSlotMappingInfo = NULL; - NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO LocalNdisDeviceSlotMappingInfo = { 0 }; - PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbDeviceSlotMappingInfo = (PMBB_MS_DEVICE_SLOT_MAPPING_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbDeviceSlotMappingInfo == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_MS_DEVICE_SLOT_MAPPING_INFO, SlotMapList)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_MS_DEVICE_SLOT_MAPPING_INFO, SlotMapList) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisStatus = MbbIsArrayFieldValid( - InBufferSize, - MbbDeviceSlotMappingInfo->SlotMapList[0].Offset, - MbbDeviceSlotMappingInfo->MapCount, - sizeof(ULONG) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad slot map list, Offset=%d, ElementCount=%d, ElementSize=%d, ReceivedSize=%d", - Request->RequestId, - MbbDeviceSlotMappingInfo->SlotMapList[0].Offset, - MbbDeviceSlotMappingInfo->MapCount, - sizeof(ULONG), - InBufferSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisDeviceSlotMappingInfoSize = sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO); - NdisDeviceSlotMappingInfoSize += sizeof(ULONG) * (MbbDeviceSlotMappingInfo->MapCount); - - NdisDeviceSlotMappingInfo = (PNDIS_WWAN_DEVICE_SLOT_MAPPING_INFO)ALLOCATE_NONPAGED_POOL(NdisDeviceSlotMappingInfoSize); - - if (NdisDeviceSlotMappingInfo == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO", - Request->RequestId, - NdisDeviceSlotMappingInfoSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisDeviceSlotMappingInfo, NdisDeviceSlotMappingInfoSize); - - NdisDeviceSlotMappingInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceSlotMappingInfo->Header.Size = sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO); - NdisDeviceSlotMappingInfo->Header.Revision = NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO_REVISION_1; - - MbbUtilMbbToWwanDeviceSlotMappingInfo( - MbbDeviceSlotMappingInfo, - &(NdisDeviceSlotMappingInfo->DeviceSlotMappingInfo) - ); - IndicationFailure = FALSE; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - if (!IndicationFailure) - { - NdisDeviceSlotMappingInfo->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisDeviceSlotMappingInfo; - StatusIndication.StatusBufferSize = NdisDeviceSlotMappingInfoSize; - } - else - { - RtlZeroMemory(&LocalNdisDeviceSlotMappingInfo, sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO)); - - LocalNdisDeviceSlotMappingInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisDeviceSlotMappingInfo.Header.Size = sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO); - LocalNdisDeviceSlotMappingInfo.Header.Revision = NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO_REVISION_1; - LocalNdisDeviceSlotMappingInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisDeviceSlotMappingInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_SLOT_MAPPING_INFO); - } - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisDeviceSlotMappingInfo != NULL) - { - FREE_POOL(NdisDeviceSlotMappingInfo); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSlotInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - NDIS_WWAN_SLOT_INFO NdisSlotInfo = { 0 }; - PMBB_MS_SLOT_INFO MbbSlotInfo = (PMBB_MS_SLOT_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SLOT_INFO - ); - - RtlZeroMemory(&NdisSlotInfo, sizeof(NDIS_WWAN_SLOT_INFO)); - - NdisSlotInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSlotInfo.Header.Size = sizeof(NDIS_WWAN_SLOT_INFO); - NdisSlotInfo.Header.Revision = NDIS_WWAN_SLOT_INFO_REVISION_1; - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SLOT_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbSlotInfo == NULL || - InBufferSize < sizeof(MBB_MS_SLOT_INFO)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SLOT_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_MS_SLOT_INFO) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanSlotInfo( - MbbSlotInfo, - &(NdisSlotInfo.SlotInfo) - ); - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisSlotInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisSlotInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SLOT_INFO); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SLOT_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisDeviceBindingsStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - ULONG NdisDeviceBindingsInfoSize = 0; - PNDIS_WWAN_DEVICE_BINDINGS_INFO NdisDeviceBindingsInfo = NULL; - NDIS_WWAN_DEVICE_BINDINGS_INFO LocalNdisDeviceBindingsInfo = { 0 }; - PMBB_DEVICE_BINDINGS_INFO MbbDeviceBindingsInfo = (PMBB_DEVICE_BINDINGS_INFO)InBuffer; - ULONG AppCount = 0; - ULONG AppIndex = 0; - PMBB_ARRAY_ELEMENT AppId = NULL; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbDeviceBindingsInfo == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_DEVICE_BINDINGS_INFO, ApplicationList)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_DEVICE_BINDINGS_INFO, ApplicationList) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - AppCount = MbbDeviceBindingsInfo->ApplicationCount; - for (AppIndex = 0; AppIndex < AppCount; AppIndex++) - { - // Check whether the struct MBB_UICC_FILE_PATH is valid. - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbDeviceBindingsInfo->ApplicationList[AppIndex].Offset, - MbbDeviceBindingsInfo->ApplicationList[AppIndex].Size, - FIELD_OFFSET(MBB_UICC_FILE_PATH, DataBuffer) + sizeof(BYTE) * WWAN_UICC_APP_ID_MAX_LEN + sizeof(USHORT) * WWAN_UICC_FILE_PATH_MAX_LEN, - sizeof(BYTE) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad MBB_UICC_FILE_PATH for app %d, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - AppIndex, - MbbDeviceBindingsInfo->ApplicationList[AppIndex].Offset, - MbbDeviceBindingsInfo->ApplicationList[AppIndex].Size, - InBufferSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // Check whether the AppId in the struct MBB_UICC_FILE_PATH is valid. Note that the FilePath in the struct MBB_UICC_FILE_PATH is not used. - AppId = &(((PMBB_UICC_FILE_PATH)((PUCHAR)MbbDeviceBindingsInfo + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Offset))->AppId); - NdisStatus = MbbIsVariableFieldValid( - MbbDeviceBindingsInfo->ApplicationList[AppIndex].Size, - AppId->Offset, - AppId->Size, - WWAN_UICC_APP_ID_MAX_LEN, - sizeof(BYTE) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad AppId for app %d, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - AppIndex, - AppId->Offset, - AppId->Size, - MbbDeviceBindingsInfo->ApplicationList[AppIndex].Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - } - - NdisDeviceBindingsInfoSize = sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO); - NdisDeviceBindingsInfoSize += sizeof(WWAN_UICC_FILE_PATH) * AppCount; - - NdisDeviceBindingsInfo = (PNDIS_WWAN_DEVICE_BINDINGS_INFO)ALLOCATE_NONPAGED_POOL(NdisDeviceBindingsInfoSize); - - if (NdisDeviceBindingsInfo == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO", - Request->RequestId, - NdisDeviceBindingsInfoSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisDeviceBindingsInfo, NdisDeviceBindingsInfoSize); - - NdisDeviceBindingsInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceBindingsInfo->Header.Size = sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO); - NdisDeviceBindingsInfo->Header.Revision = NDIS_WWAN_DEVICE_BINDINGS_INFO_REVISION_1; - - MbbUtilMbbToWwanDeviceBindingsInfo( - MbbDeviceBindingsInfo, - &(NdisDeviceBindingsInfo->DeviceBindingsInfo) - ); - IndicationFailure = FALSE; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - if (!IndicationFailure) - { - NdisDeviceBindingsInfo->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisDeviceBindingsInfo; - StatusIndication.StatusBufferSize = NdisDeviceBindingsInfoSize; - } - else - { - RtlZeroMemory(&LocalNdisDeviceBindingsInfo, sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO)); - - LocalNdisDeviceBindingsInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisDeviceBindingsInfo.Header.Size = sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO); - LocalNdisDeviceBindingsInfo.Header.Revision = NDIS_WWAN_DEVICE_BINDINGS_INFO_REVISION_1; - LocalNdisDeviceBindingsInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisDeviceBindingsInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_BINDINGS_INFO); - } - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_BINDINGS_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisDeviceBindingsInfo != NULL) - { - FREE_POOL(NdisDeviceBindingsInfo); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisRegisterStateExStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - ULONG NdisRegistrationStateInfosExSize = 0; - PNDIS_WWAN_REGISTRATION_STATE_INFOS_EX NdisRegistrationStateInfosEx = NULL; - NDIS_WWAN_REGISTRATION_STATE_INFOS_EX LocalNdisRegistrationStateInfosEx = { 0 }; - PMBB_REGISTRATION_STATE_INFOS_V2 MbbRegistrationStateInfosV2 = (PMBB_REGISTRATION_STATE_INFOS_V2)InBuffer; - ULONG RegistrationStateCount = 0; - ULONG RegistrationStateIndex = 0; - PMBB_REGISTRATION_STATE_V2 RegistrationState = NULL; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_REGISTER_STATE - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_REGISTER_STATE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbRegistrationStateInfosV2 == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_REGISTRATION_STATE_INFOS_V2, RegistrationStateList)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_REGISTER_STATE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_REGISTRATION_STATE_INFOS_V2, RegistrationStateList) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RegistrationStateCount = MbbRegistrationStateInfosV2->ElementCount; - for (RegistrationStateIndex = 0; RegistrationStateIndex < RegistrationStateCount; RegistrationStateIndex++) - { - // Check whether the struct MBB_REGISTRATION_STATE_V2 is valid. - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Offset, - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, - FIELD_OFFSET(MBB_REGISTRATION_STATE_V2, DataBuffer) + sizeof(WCHAR) * (WWAN_PROVIDERID_LEN + WWAN_PROVIDERNAME_LEN + WWAN_ROAMTEXT_LEN - 3), // Minus 3 null terminators. - sizeof(BYTE) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad MBB_REGISTRATION_STATE_V2 for RegistrationState %d, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - RegistrationStateIndex, - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Offset, - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, - InBufferSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // Check whether the ProviderId in the struct MBB_REGISTRATION_STATE_V2 is valid. - RegistrationState = (PMBB_REGISTRATION_STATE_V2)((PUCHAR)MbbRegistrationStateInfosV2 + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Offset); - NdisStatus = MbbIsVariableFieldValid( - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, - RegistrationState->ProviderId.Offset, - RegistrationState->ProviderId.Size, - WWAN_PROVIDERID_LEN - 1, // Minus the null terminator. - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad ProviderId for RegistrationState %d, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - RegistrationStateIndex, - RegistrationState->ProviderId.Offset, - RegistrationState->ProviderId.Size, - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // Check whether the ProviderName in the struct MBB_REGISTRATION_STATE_V2 is valid. - NdisStatus = MbbIsVariableFieldValid( - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, - RegistrationState->ProviderName.Offset, - RegistrationState->ProviderName.Size, - WWAN_PROVIDERNAME_LEN - 1, // Minus the null terminator. - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad ProviderName for RegistrationState %d, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - RegistrationStateIndex, - RegistrationState->ProviderName.Offset, - RegistrationState->ProviderName.Size, - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // Check whether the RoamingText in the struct MBB_REGISTRATION_STATE_V2 is valid. - NdisStatus = MbbIsVariableFieldValid( - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size, - RegistrationState->RoamingText.Offset, - RegistrationState->RoamingText.Size, - WWAN_ROAMTEXT_LEN - 1, // Minus the null terminator. - sizeof(WCHAR) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad RoamingText for RegistrationState %d, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - RegistrationStateIndex, - RegistrationState->RoamingText.Offset, - RegistrationState->RoamingText.Size, - MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Size - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - } - - NdisRegistrationStateInfosExSize = sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX); - NdisRegistrationStateInfosExSize += sizeof(WWAN_REGISTRATION_STATE_EX) * RegistrationStateCount; - - NdisRegistrationStateInfosEx = (PNDIS_WWAN_REGISTRATION_STATE_INFOS_EX)ALLOCATE_NONPAGED_POOL(NdisRegistrationStateInfosExSize); - - if (NdisRegistrationStateInfosEx == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_REGISTER_STATE", - Request->RequestId, - NdisRegistrationStateInfosExSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisRegistrationStateInfosEx, NdisRegistrationStateInfosExSize); - - NdisRegistrationStateInfosEx->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisRegistrationStateInfosEx->Header.Size = sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX); - NdisRegistrationStateInfosEx->Header.Revision = NDIS_WWAN_REGISTRATION_STATE_REVISION_2; - - MbbUtilMbbToWwanRegistrationStateInfoV2( - MbbRegistrationStateInfosV2, - &(NdisRegistrationStateInfosEx->RegistrationStateInfos) - ); - IndicationFailure = FALSE; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - if (!IndicationFailure) - { - NdisRegistrationStateInfosEx->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisRegistrationStateInfosEx; - StatusIndication.StatusBufferSize = NdisRegistrationStateInfosExSize; - } - else - { - RtlZeroMemory(&LocalNdisRegistrationStateInfosEx, sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX)); - - LocalNdisRegistrationStateInfosEx.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisRegistrationStateInfosEx.Header.Size = sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX); - LocalNdisRegistrationStateInfosEx.Header.Revision = NDIS_WWAN_REGISTRATION_STATE_REVISION_2; - LocalNdisRegistrationStateInfosEx.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisRegistrationStateInfosEx; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_REGISTRATION_STATE_INFOS_EX); - } - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_REGISTER_STATE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisRegistrationStateInfosEx != NULL) - { - FREE_POOL(NdisRegistrationStateInfosEx); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisImsVoiceStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - NDIS_WWAN_IMS_VOICE_STATE NdisImsVoiceStatus = { 0 }; - PMBB_IMS_VOICE_STATE MbbImsVoiceStatus = (PMBB_IMS_VOICE_STATE)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_IMS_VOICE_STATE - ); - - RtlZeroMemory(&NdisImsVoiceStatus, sizeof(NdisImsVoiceStatus)); - - NdisImsVoiceStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisImsVoiceStatus.Header.Size = sizeof(NDIS_WWAN_IMS_VOICE_STATE); - NdisImsVoiceStatus.Header.Revision = NDIS_WWAN_IMS_VOICE_STATE_REVISION_1; - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_IMS_VOICE_STATE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbImsVoiceStatus == NULL || - InBufferSize < sizeof(MBB_IMS_VOICE_STATE)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_IMS_VOICE_STATE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_IMS_VOICE_STATE) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisImsVoiceStatus.ImsVoiceState.ImsVoiceStatus = (WWAN_IMS_VOICE_STATUS)(MbbImsVoiceStatus->ImsVoiceStatus); - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisImsVoiceStatus.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisImsVoiceStatus; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_IMS_VOICE_STATE); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_IMS_VOICE_STATE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSignalStateExStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - ULONG NdisSignalStateInfosExSize = 0; - PNDIS_WWAN_SIGNAL_STATE_INFOS_EX NdisSignalStateInfosEx = NULL; - NDIS_WWAN_SIGNAL_STATE_INFOS_EX LocalNdisSignalStateInfosEx = { 0 }; - PMBB_SIGNAL_STATE_INFOS_V2 MbbSignalStateInfosV2 = (PMBB_SIGNAL_STATE_INFOS_V2)InBuffer; - ULONG SignalStateCount = 0; - ULONG SignalStateIndex = 0; - PMBB_SIGNAL_STATE_V2 SignalState = NULL; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SIGNAL_STATE - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SIGNAL_STATE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbSignalStateInfosV2 == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_SIGNAL_STATE_INFOS_V2, SignalStateList)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SIGNAL_STATE, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_SIGNAL_STATE_INFOS_V2, SignalStateList) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - SignalStateCount = MbbSignalStateInfosV2->ElementCount; - for (SignalStateIndex = 0; SignalStateIndex < SignalStateCount; SignalStateIndex++) - { - // Check whether the struct MBB_SIGNAL_STATE_V2 is valid. - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Offset, - MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Size, - 1, - sizeof(MBB_SIGNAL_STATE_V2) - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Bad MBB_SIGNAL_STATE_V2 for SignalStateIndex %d, Offset=%d, Size=%d, ReceivedSize=%d", - Request->RequestId, - SignalStateIndex, - MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Offset, - MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Size, - InBufferSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - } - - NdisSignalStateInfosExSize = sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX); - NdisSignalStateInfosExSize += sizeof(WWAN_SIGNAL_STATE_EX) * SignalStateCount; - - NdisSignalStateInfosEx = (PNDIS_WWAN_SIGNAL_STATE_INFOS_EX)ALLOCATE_NONPAGED_POOL(NdisSignalStateInfosExSize); - - if (NdisSignalStateInfosEx == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_SIGNAL_STATE", - Request->RequestId, - NdisSignalStateInfosExSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisSignalStateInfosEx, NdisSignalStateInfosExSize); - - NdisSignalStateInfosEx->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSignalStateInfosEx->Header.Size = sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX); - NdisSignalStateInfosEx->Header.Revision = NDIS_WWAN_SIGNAL_STATE_REVISION_2; - - MbbUtilMbbToWwanSignalStateInfoV2( - MbbSignalStateInfosV2, - &(NdisSignalStateInfosEx->SignalStateInfos) - ); - IndicationFailure = FALSE; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - if (!IndicationFailure) - { - NdisSignalStateInfosEx->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisSignalStateInfosEx; - StatusIndication.StatusBufferSize = NdisSignalStateInfosExSize; - } - else - { - RtlZeroMemory(&LocalNdisSignalStateInfosEx, sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX)); - - LocalNdisSignalStateInfosEx.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisSignalStateInfosEx.Header.Size = sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX); - LocalNdisSignalStateInfosEx.Header.Revision = NDIS_WWAN_SIGNAL_STATE_REVISION_2; - LocalNdisSignalStateInfosEx.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisSignalStateInfosEx; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SIGNAL_STATE_INFOS_EX); - } - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SIGNAL_STATE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisSignalStateInfosEx != NULL) - { - FREE_POOL(NdisSignalStateInfosEx); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisLocationStateStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - NDIS_WWAN_LOCATION_STATE_INFO NdisLocationStateInfo = { 0 }; - PMBB_LOCATION_STATE_INFO MbbLocationStateInfo = (PMBB_LOCATION_STATE_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_LOCATION_STATE_INFO - ); - - RtlZeroMemory(&NdisLocationStateInfo, sizeof(NdisLocationStateInfo)); - - NdisLocationStateInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisLocationStateInfo.Header.Size = sizeof(NDIS_WWAN_LOCATION_STATE_INFO); - NdisLocationStateInfo.Header.Revision = NDIS_WWAN_LOCATION_STATE_INFO_REVISION_1; - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_LOCATION_STATE_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbLocationStateInfo == NULL || - InBufferSize < sizeof(MBB_LOCATION_STATE_INFO)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_LOCATION_STATE_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_LOCATION_STATE_INFO) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisLocationStateInfo.LocationStateInfo.Trigger = (WWAN_LOCATION_TRIGGER_MODE)(MbbLocationStateInfo->Trigger); - NdisLocationStateInfo.LocationStateInfo.DataClass = MbbLocationStateInfo->DataClass; - NdisLocationStateInfo.LocationStateInfo.AreaCode = MbbLocationStateInfo->AreaCode; - NdisLocationStateInfo.LocationStateInfo.CellId = MbbLocationStateInfo->CellId; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisLocationStateInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisLocationStateInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_LOCATION_STATE_INFO); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_LOCATION_STATE_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisNitzStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - NDIS_WWAN_NITZ_INFO NdisNitzInfo = { 0 }; - PMBB_NITZ_INFO MbbNitzInfo = (PMBB_NITZ_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_NITZ_INFO - ); - - RtlZeroMemory(&NdisNitzInfo, sizeof(NdisNitzInfo)); - - NdisNitzInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisNitzInfo.Header.Size = sizeof(NDIS_WWAN_NITZ_INFO); - NdisNitzInfo.Header.Revision = NDIS_WWAN_NITZ_INFO_REVISION_1; - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_NITZ_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbNitzInfo == NULL || - InBufferSize < sizeof(MBB_NITZ_INFO)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_NITZ_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_NITZ_INFO) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisNitzInfo.NitzInfo.Year = MbbNitzInfo->Year; - NdisNitzInfo.NitzInfo.Month = MbbNitzInfo->Month; - NdisNitzInfo.NitzInfo.Day = MbbNitzInfo->Day; - NdisNitzInfo.NitzInfo.Hour = MbbNitzInfo->Hour; - NdisNitzInfo.NitzInfo.Minute = MbbNitzInfo->Minute; - NdisNitzInfo.NitzInfo.Second = MbbNitzInfo->Second; - NdisNitzInfo.NitzInfo.TimeZoneOffsetMinutes = MbbNitzInfo->TimeZoneOffsetMinutes; - NdisNitzInfo.NitzInfo.DaylightSavingTimeOffsetMinutes = MbbNitzInfo->DaylightSavingTimeOffsetMinutes; - NdisNitzInfo.NitzInfo.DataClasses = MbbNitzInfo->DataClasses; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisNitzInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisNitzInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_NITZ_INFO); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_NITZ_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisPreshutdownHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_SUCCESS; - NDIS_STATUS_INDICATION StatusIndication = { 0 }; - NDIS_WWAN_PRESHUTDOWN_STATE NdisPreshutdownState = { 0 }; - - UNREFERENCED_PARAMETER(InBuffer); - UNREFERENCED_PARAMETER(InBufferSize); - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PRESHUTDOWN_STATE - ); - - RtlZeroMemory(&NdisPreshutdownState, sizeof(NdisPreshutdownState)); - - NdisPreshutdownState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisPreshutdownState.Header.Size = SIZEOF_NDIS_WWAN_PRESHUTDOWN_STATE_1; - NdisPreshutdownState.Header.Revision = NDIS_WWAN_PRESHUTDOWN_STATE_REVISION_1; - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PRESHUTDOWN_STATE, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisPreshutdownState.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisPreshutdownState; - StatusIndication.StatusBufferSize = sizeof(NdisPreshutdownState); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PRESHUTDOWN_STATE with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - TraceLoggingWrite( - g_hLoggingProvider, - "OID_Wwan_Preshutdown_Response", - TraceLoggingUInt64(Request->RequestId, "RequestID"), - TraceLoggingUInt64(WwanStatus, "WwanStatus"), - TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisAtrInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_ATR_INFO NdisAtrInfo; - PMBB_ATR_INFO MbbAtrInfo = (PMBB_ATR_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_ATR_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_ATR_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbAtrInfo == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_ATR_INFO, DataBuffer)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_ATR_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_ATR_INFO, DataBuffer) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(&NdisAtrInfo, sizeof(NdisAtrInfo)); - - NdisAtrInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisAtrInfo.Header.Size = sizeof(NDIS_WWAN_ATR_INFO); - NdisAtrInfo.Header.Revision = NDIS_WWAN_ATR_INFO_REVISION_1; - - MbbUtilMbbToWwanAtrInfo( - MbbAtrInfo, - &NdisAtrInfo.AtrInfo - ); - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisAtrInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisAtrInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_ATR_INFO); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_ATR_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisUiccOpenChannelInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - ULONG NdisUiccOpenChannelInfoSize = 0; - PNDIS_WWAN_UICC_OPEN_CHANNEL_INFO NdisUiccOpenChannelInfo = NULL; - NDIS_WWAN_UICC_OPEN_CHANNEL_INFO LocalNdisUiccOpenChannelInfo; - PMBB_UICC_OPEN_CHANNEL_INFO MbbUiccOpenChannelInfo = (PMBB_UICC_OPEN_CHANNEL_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbUiccOpenChannelInfo == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_UICC_OPEN_CHANNEL_INFO, DataBuffer)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_UICC_OPEN_CHANNEL_INFO, DataBuffer) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisUiccOpenChannelInfoSize = FIELD_OFFSET(NDIS_WWAN_UICC_OPEN_CHANNEL_INFO, UiccOpenChannelInfo.Response); - NdisUiccOpenChannelInfoSize += MbbUiccOpenChannelInfo->Response.Size; - - NdisUiccOpenChannelInfo = (PNDIS_WWAN_UICC_OPEN_CHANNEL_INFO)ALLOCATE_NONPAGED_POOL( NdisUiccOpenChannelInfoSize ); - - if( NdisUiccOpenChannelInfo == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO", - Request->RequestId, - NdisUiccOpenChannelInfoSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisUiccOpenChannelInfo, NdisUiccOpenChannelInfoSize); - - // Open channel can have a response payload even when the command fails - NdisUiccOpenChannelInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisUiccOpenChannelInfo->Header.Size = (USHORT)NdisUiccOpenChannelInfoSize; - NdisUiccOpenChannelInfo->Header.Revision = NDIS_WWAN_UICC_OPEN_CHANNEL_INFO_REVISION_1; - NdisUiccOpenChannelInfo->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisUiccOpenChannelInfo; - StatusIndication.StatusBufferSize = NdisUiccOpenChannelInfoSize; - - MbbUtilMbbToWwanUiccOpenChannelInfo( - MbbUiccOpenChannelInfo, - &NdisUiccOpenChannelInfo->UiccOpenChannelInfo - ); - IndicationFailure = FALSE; - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if (IndicationFailure) - { - RtlZeroMemory(&LocalNdisUiccOpenChannelInfo, sizeof(NDIS_WWAN_UICC_OPEN_CHANNEL_INFO)); - - LocalNdisUiccOpenChannelInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisUiccOpenChannelInfo.Header.Size = sizeof(NDIS_WWAN_UICC_OPEN_CHANNEL_INFO); - LocalNdisUiccOpenChannelInfo.Header.Revision = NDIS_WWAN_UICC_OPEN_CHANNEL_INFO_REVISION_1; - LocalNdisUiccOpenChannelInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisUiccOpenChannelInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_OPEN_CHANNEL_INFO); - } - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_OPEN_CHANNEL_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisUiccOpenChannelInfo != NULL) - { - FREE_POOL(NdisUiccOpenChannelInfo); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisUiccCloseChannelInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_UICC_CLOSE_CHANNEL_INFO NdisUiccCloseChannelInfo; - PMBB_UICC_CLOSE_CHANNEL_INFO MbbUiccCloseChannelInfo = (PMBB_UICC_CLOSE_CHANNEL_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_UICC_CLOSE_CHANNEL_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_CLOSE_CHANNEL_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbUiccCloseChannelInfo == NULL || - InBufferSize < sizeof(MBB_UICC_CLOSE_CHANNEL_INFO) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_CLOSE_CHANNEL_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_UICC_CLOSE_CHANNEL_INFO) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(&NdisUiccCloseChannelInfo, sizeof(NdisUiccCloseChannelInfo)); - - NdisUiccCloseChannelInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisUiccCloseChannelInfo.Header.Size = sizeof(NDIS_WWAN_UICC_CLOSE_CHANNEL_INFO); - NdisUiccCloseChannelInfo.Header.Revision = NDIS_WWAN_UICC_CLOSE_CHANNEL_INFO_REVISION_1; - - MbbUtilMbbToWwanUiccCloseChannelInfo( - MbbUiccCloseChannelInfo, - &NdisUiccCloseChannelInfo.UiccCloseChannelInfo - ); - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisUiccCloseChannelInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisUiccCloseChannelInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_CLOSE_CHANNEL_INFO); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_CLOSE_CHANNEL_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisUiccApduInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - ULONG NdisUiccApduInfoSize = 0; - PNDIS_WWAN_UICC_APDU_INFO NdisUiccApduInfo = NULL; - NDIS_WWAN_UICC_APDU_INFO LocalNdisUiccApduInfo; - PMBB_UICC_APDU_INFO MbbUiccApduInfo = (PMBB_UICC_APDU_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_UICC_APDU_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_APDU_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbUiccApduInfo == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_UICC_APDU_INFO, DataBuffer)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_APDU_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_UICC_APDU_INFO, DataBuffer) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisUiccApduInfoSize = FIELD_OFFSET(NDIS_WWAN_UICC_APDU_INFO, UiccApduInfo.Response); - NdisUiccApduInfoSize += MbbUiccApduInfo->Response.Size; - - NdisUiccApduInfo = (PNDIS_WWAN_UICC_APDU_INFO)ALLOCATE_NONPAGED_POOL( NdisUiccApduInfoSize ); - - if( NdisUiccApduInfo == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_UICC_APDU_INFO", - Request->RequestId, - NdisUiccApduInfoSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisUiccApduInfo, NdisUiccApduInfoSize); - - NdisUiccApduInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisUiccApduInfo->Header.Size = (USHORT)NdisUiccApduInfoSize; - NdisUiccApduInfo->Header.Revision = NDIS_WWAN_UICC_OPEN_CHANNEL_INFO_REVISION_1; - NdisUiccApduInfo->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisUiccApduInfo; - StatusIndication.StatusBufferSize = NdisUiccApduInfoSize; - - MbbUtilMbbToWwanUiccApduInfo( - MbbUiccApduInfo, - &NdisUiccApduInfo->UiccApduInfo - ); - IndicationFailure = FALSE; - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if (IndicationFailure) - { - RtlZeroMemory(&LocalNdisUiccApduInfo, sizeof(NDIS_WWAN_UICC_APDU_INFO)); - - LocalNdisUiccApduInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisUiccApduInfo.Header.Size = sizeof(NDIS_WWAN_UICC_APDU_INFO); - LocalNdisUiccApduInfo.Header.Revision = NDIS_WWAN_UICC_APDU_INFO_REVISION_1; - LocalNdisUiccApduInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisUiccApduInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_APDU_INFO); - } - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_APDU_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisUiccApduInfo != NULL) - { - FREE_POOL(NdisUiccApduInfo); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisUiccTerminalCapabilityInfoStatusHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - ULONG NdisUiccTerminalCapabilityInfoSize = 0; - PNDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO NdisUiccTerminalCapabilityInfo = NULL; - NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO LocalNdisUiccTerminalCapabilityInfo; - PMBB_UICC_TERMINAL_CAPABILITY_INFO MbbUiccTerminalCapabilityInfo = (PMBB_UICC_TERMINAL_CAPABILITY_INFO)InBuffer; - ULONG CapabilityCount = 0; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbUiccTerminalCapabilityInfo == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_UICC_TERMINAL_CAPABILITY_INFO, CapabilityList)) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_UICC_TERMINAL_CAPABILITY_INFO, CapabilityList) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - CapabilityCount = MbbUiccTerminalCapabilityInfo->ElementCount; - - NdisUiccTerminalCapabilityInfoSize = sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO); - NdisUiccTerminalCapabilityInfoSize += sizeof(WWAN_UICC_TERMINAL_CAPABILITY_TLV) * CapabilityCount; - - NdisUiccTerminalCapabilityInfo = (PNDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO)ALLOCATE_NONPAGED_POOL( NdisUiccTerminalCapabilityInfoSize ); - - if( NdisUiccTerminalCapabilityInfo == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO", - Request->RequestId, - NdisUiccTerminalCapabilityInfoSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisUiccTerminalCapabilityInfo, NdisUiccTerminalCapabilityInfoSize); - - NdisUiccTerminalCapabilityInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisUiccTerminalCapabilityInfo->Header.Size = (USHORT)NdisUiccTerminalCapabilityInfoSize; - NdisUiccTerminalCapabilityInfo->Header.Revision = NDIS_WWAN_UICC_OPEN_CHANNEL_INFO_REVISION_1; - NdisUiccTerminalCapabilityInfo->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisUiccTerminalCapabilityInfo; - StatusIndication.StatusBufferSize = NdisUiccTerminalCapabilityInfoSize; - - MbbUtilMbbToWwanUiccTerminalCapabilityInfo( - MbbUiccTerminalCapabilityInfo, - &NdisUiccTerminalCapabilityInfo->UiccCapabilityInfo.CapabilityListHeader - ); - IndicationFailure = FALSE; - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - if (IndicationFailure) - { - RtlZeroMemory(&LocalNdisUiccTerminalCapabilityInfo, sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO)); - - LocalNdisUiccTerminalCapabilityInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisUiccTerminalCapabilityInfo.Header.Size = sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO); - LocalNdisUiccTerminalCapabilityInfo.Header.Revision = NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO_REVISION_1; - LocalNdisUiccTerminalCapabilityInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisUiccTerminalCapabilityInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_TERMINAL_CAPABILITY_INFO); - } - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_TERMINAL_CAPABILITY_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisUiccTerminalCapabilityInfo != NULL) - { - FREE_POOL(NdisUiccTerminalCapabilityInfo); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisUiccResetInfoStatusHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_UICC_RESET_INFO NdisUiccResetInfo; - PMBB_UICC_RESET_INFO MbbUiccResetInfo = (PMBB_UICC_RESET_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_UICC_RESET_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_UICC_RESET_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if( MbbUiccResetInfo == NULL || - InBufferSize < sizeof(MBB_UICC_RESET_INFO) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_UICC_RESET_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_UICC_RESET_INFO) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(&NdisUiccResetInfo, sizeof(NdisUiccResetInfo)); - - NdisUiccResetInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisUiccResetInfo.Header.Size = sizeof(NDIS_WWAN_UICC_RESET_INFO); - NdisUiccResetInfo.Header.Revision = NDIS_WWAN_UICC_RESET_INFO_REVISION_1; - - NdisUiccResetInfo.UiccResetInfo.PassThroughStatus = (WWAN_UICC_PASSTHROUGH_STATUS)MbbUiccResetInfo->PassThroughStatus; - } - while( FALSE ); - - // - // Restore the device returned operational status, if any. - // - if( WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus( MbbStatus ) != WWAN_STATUS_SUCCESS ) - { - WwanStatus = MbbUtilMbbToWwanStatus( MbbStatus ); - } - - NdisUiccResetInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisUiccResetInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_UICC_RESET_INFO); - - TraceInfo( WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_UICC_RESET_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSarConfigHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize - ) -{ - BOOLEAN IndicateFailure = TRUE; - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - ULONG ElementIndex; - ULONG ElementCount; - ULONG NdisSarConfigSize = 0; - ULONG MbbSarConfigSize = 0; - NDIS_STATUS_INDICATION StatusIndication; - PNDIS_WWAN_SAR_CONFIG_INFO NdisSarConfigInfo = NULL; - NDIS_WWAN_SAR_CONFIG_INFO LocalNdisSarConfigInfo; - PMBB_SAR_CONFIG_INFO MbbSarConfigInfo = (PMBB_SAR_CONFIG_INFO)InBuffer; - - do - { - RtlZeroMemory(&LocalNdisSarConfigInfo, sizeof(LocalNdisSarConfigInfo)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SAR_CONFIG - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SAR_CONFIG, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, WwanStatus=%!WwanStatus!. MbbStatus=%!MbbStatus!", - Request->RequestId, - WwanStatus, - MbbStatus - ); - NdisStatus = WwanStatus; - break; - } - - if (MbbSarConfigInfo == NULL || - InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SAR_CONFIG_INFO, Configurations)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SAR_CONFIG, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_SAR_CONFIG_INFO, ElementCount) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - ElementCount = MbbSarConfigInfo->ElementCount; - MbbSarConfigSize = FIELD_OFFSET(MBB_SAR_CONFIG_INFO, Configurations) + (ULONG)ElementCount * sizeof(MBB_ARRAY_ELEMENT); - NdisSarConfigSize = sizeof(NDIS_WWAN_SAR_CONFIG_INFO) + (ULONG)ElementCount * sizeof(WWAN_SAR_CONFIG_INDICES); - - if (InBufferSize < MbbSarConfigSize) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SAR_CONFIG, BufferSize[Received=%d Expected=%I64u] ElementCount=%d", - Request->RequestId, - InBufferSize, - MbbSarConfigSize, - MbbSarConfigInfo->ElementCount - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - for (ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex++) - { - if (MbbIsVariableFieldValid( - InBufferSize, - MbbSarConfigInfo->Configurations[ElementIndex].Offset, - MbbSarConfigInfo->Configurations[ElementIndex].Size, - 2, // Expect two indices in a configuration - sizeof(ULONG) - ) != STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INVALID MBB_SAR_CONFIG_INFO.Configurations[%d] Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - Request->RequestId, - ElementIndex, - MbbSarConfigInfo->Configurations[ElementIndex].Offset, - InBufferSize, - MbbSarConfigInfo->Configurations[ElementIndex].Size, - 2 * sizeof(ULONG) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - } - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - break; - } - - if ((NdisSarConfigInfo = ALLOCATE_NONPAGED_POOL(NdisSarConfigSize)) == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %I64u bytes for NDIS_STATUS_WWAN_SAR_CONFIG, ElementCount=%d", - Request->RequestId, - NdisSarConfigSize, - MbbSarConfigInfo->ElementCount - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - NdisSarConfigInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisSarConfigInfo->Header.Size = sizeof(NDIS_WWAN_SAR_CONFIG_INFO); - NdisSarConfigInfo->Header.Revision = NDIS_WWAN_SAR_CONFIG_INFO_REVISION_1; - NdisSarConfigInfo->uStatus = WWAN_STATUS_SUCCESS; - - StatusIndication.StatusBuffer = NdisSarConfigInfo; - StatusIndication.StatusBufferSize = NdisSarConfigSize; - - MbbUtilMbbToWwanSarConfigInfo( - MbbSarConfigInfo, - &NdisSarConfigInfo->SarConfig - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - IndicateFailure = FALSE; - - } while (FALSE); - - if (IndicateFailure) - { - - LocalNdisSarConfigInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisSarConfigInfo.Header.Size = sizeof(LocalNdisSarConfigInfo); - LocalNdisSarConfigInfo.Header.Revision = NDIS_WWAN_SAR_CONFIG_INFO_REVISION_1; - LocalNdisSarConfigInfo.uStatus = NdisStatus; - - StatusIndication.StatusBuffer = &LocalNdisSarConfigInfo; - StatusIndication.StatusBufferSize = sizeof(LocalNdisSarConfigInfo); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to indicate NDIS_STATUS_WWAN_SAR_CONFIG WwanStatus=%!WwanStatus!", Request->RequestId, NdisStatus); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - } - - if (NdisSarConfigInfo != NULL) - { - FREE_POOL(NdisSarConfigInfo); - } - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisSarTransmissionStatusHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO NdisTransmissionStatusInfo; - PMBB_SAR_TRANSMISSION_STATUS_INFO MbbTransmissionStatusInfo = (PMBB_SAR_TRANSMISSION_STATUS_INFO)InBuffer; - - do - { - RtlZeroMemory(&NdisTransmissionStatusInfo, sizeof(NdisTransmissionStatusInfo)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_SAR_TRANSMISSION_STATUS - ); - - NdisTransmissionStatusInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisTransmissionStatusInfo.Header.Size = sizeof(NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO); - NdisTransmissionStatusInfo.Header.Revision = NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO_REVISION_1; - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_SAR_TRANSMISSION_STATUS_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, WwanStatus=%!WwanStatus!. MbbStatus=%!MbbStatus!", - Request->RequestId, - WwanStatus, - MbbStatus - ); - NdisStatus = WwanStatus; - break; - } - - if (MbbTransmissionStatusInfo == NULL || - InBufferSize < sizeof(MBB_SAR_TRANSMISSION_STATUS_INFO)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_SAR_TRANSMISSION_STATUS_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_SAR_TRANSMISSION_STATUS_INFO) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbUtilMbbToWwanTransmissionStatusInfo( - MbbTransmissionStatusInfo, - &NdisTransmissionStatusInfo.TransmissionStatus - ); - } while (FALSE); - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisTransmissionStatusInfo.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisTransmissionStatusInfo; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_SAR_TRANSMISSION_STATUS_INFO); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_SAR_TRANSMISSION_STATUS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - - -NDIS_STATUS -MbbNdisNetworkBlacklistHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize -) -{ - ULONG NdisNetworkBlacklistSize = 0; - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - PNDIS_WWAN_NETWORK_BLACKLIST NdisNetworkBlacklist = NULL; - NDIS_WWAN_NETWORK_BLACKLIST LocalNdisNetworkBlacklist; - PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist = (PMBB_MS_NETWORK_BLACKLIST_INFO)InBuffer; - PMBB_MS_NETWORK_BLACKLIST_PROVIDER MbbNetworkBlacklistProvider = NULL; - ULONGLONG TempSize = 0; - ULONG MulTempSize = 0; - ULONG i; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - RtlZeroMemory(&LocalNdisNetworkBlacklist, sizeof(LocalNdisNetworkBlacklist)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_NETWORK_BLACKLIST - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_NETWORK_BLACKLIST, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - - if (MbbReqMgrIsSetOid(Request) == TRUE) - { - break; - } - - TempSize = RTL_SIZEOF_THROUGH_FIELD(MBB_MS_NETWORK_BLACKLIST_INFO, ElementCount); - - if (MbbNetworkBlacklist == NULL || - InBufferSize < RTL_SIZEOF_THROUGH_FIELD(MBB_MS_NETWORK_BLACKLIST_INFO, ElementCount)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_NETWORK_BLACKLIST, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_MS_NETWORK_BLACKLIST_INFO, ElementCount) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // - // make sure it is big enough for the array of elements - // - NtStatus = RtlULongMult( - MbbNetworkBlacklist->ElementCount, - sizeof(MBB_ARRAY_ELEMENT), - &MulTempSize - ); - - if (NT_ERROR(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbNetworkBlacklist->ElementCount=%d MBB_ARRAY_ELEMENT size=%d", - Request->RequestId, - MbbNetworkBlacklist->ElementCount, - sizeof(MBB_ARRAY_ELEMENT) - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - TempSize += MulTempSize; - - if (InBufferSize < TempSize) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_NETWORK_BLACKLIST, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - (ULONG)TempSize - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - for (i = 0; i < MbbNetworkBlacklist->ElementCount; i++) - { - - NdisStatus = MbbIsVariableFieldValid( - InBufferSize, - MbbNetworkBlacklist->Contexts[i].Offset, - MbbNetworkBlacklist->Contexts[i].Size, - 2048, // some reasonable upper limit - sizeof(UCHAR) - ); - - if (!NT_SUCCESS(NdisStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] bad array element in MBB_MS_NETWORK_BLACKLIST_INFO", - Request->RequestId - ); - - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - MbbNetworkBlacklistProvider = (PMBB_MS_NETWORK_BLACKLIST_PROVIDER)(InBuffer + MbbNetworkBlacklist->Contexts[i].Offset); - } - - if (WwanStatus != WWAN_STATUS_SUCCESS) - { - break; - } - - NtStatus = RtlULongMult( - MbbNetworkBlacklist->ElementCount, - sizeof(MBB_MS_NETWORK_BLACKLIST_PROVIDER), - &NdisNetworkBlacklistSize - ); - if (NT_ERROR(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Multiplication overflow occured, MbbNetworkBlacklist->ElementCount=%d MBB_MS_NETWORK_BLACKLIST_PROVIDER size=%d", - Request->RequestId, - MbbNetworkBlacklist->ElementCount, - sizeof(WWAN_CONTEXT) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NtStatus = RtlULongAdd( - NdisNetworkBlacklistSize, - sizeof(NDIS_WWAN_NETWORK_BLACKLIST), - &NdisNetworkBlacklistSize - ); - if (NT_ERROR(NtStatus)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Addition overflow occured, NdisNetworkBlacklistSize=%d NDIS_WWAN_NETWORK_BLACKLIST size=%d", - Request->RequestId, - NdisNetworkBlacklistSize, - sizeof(NDIS_WWAN_NETWORK_BLACKLIST) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - NdisNetworkBlacklist = ALLOCATE_NONPAGED_POOL(NdisNetworkBlacklistSize); - - if (NdisNetworkBlacklist == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_NETWORK_BLACKLIST, ElementCount=%d", - Request->RequestId, - NdisNetworkBlacklistSize, - MbbNetworkBlacklist->ElementCount - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisNetworkBlacklist, NdisNetworkBlacklistSize); - - NdisNetworkBlacklist->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisNetworkBlacklist->Header.Size = sizeof(NDIS_WWAN_NETWORK_BLACKLIST); - NdisNetworkBlacklist->Header.Revision = NDIS_WWAN_NETWORK_BLACKLIST_REVISION_1; - - NdisNetworkBlacklist->NetworkBlacklistInfo.BlacklistState = MbbNetworkBlacklist->BlacklistState; - - MbbUtilMbbToWwanNetworkBlackList( - MbbNetworkBlacklist, - &NdisNetworkBlacklist->NetworkBlacklistInfo.BlacklistProviderList - ); - } while (FALSE); - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - if (NdisNetworkBlacklist == NULL) - { - LocalNdisNetworkBlacklist.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisNetworkBlacklist.Header.Size = sizeof(NDIS_WWAN_NETWORK_BLACKLIST); - LocalNdisNetworkBlacklist.Header.Revision = NDIS_WWAN_NETWORK_BLACKLIST_REVISION_1; - - LocalNdisNetworkBlacklist.NetworkBlacklistInfo.BlacklistProviderList.ElementType = WwanStructNetworkBlacklistProvider; - LocalNdisNetworkBlacklist.NetworkBlacklistInfo.BlacklistProviderList.ElementCount = 0; - - StatusIndication.StatusBuffer = &LocalNdisNetworkBlacklist; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_NETWORK_BLACKLIST); - } - else - { - StatusIndication.StatusBuffer = NdisNetworkBlacklist; - StatusIndication.StatusBufferSize = NdisNetworkBlacklistSize; - } - - ((PNDIS_WWAN_PROVISIONED_CONTEXTS)(StatusIndication.StatusBuffer))->uStatus = WwanStatus; - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_NETWORK_BLACKLIST with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisNetworkBlacklist != NULL) - { - FREE_POOL(NdisNetworkBlacklist); - } - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisPcoStatusHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize - ) -{ - WWAN_STATUS WwanStatus = WWAN_STATUS_FAILURE; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_PCO_STATUS NdisPcoStatus; - PMBB_MS_PCO_VALUE pMbbPcoValue = (PMBB_MS_PCO_VALUE)InBuffer; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request); - PMBB_PORT Port = NULL; - NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; - BOOLEAN ResetPort = FALSE; - - do - { - RtlZeroMemory(&NdisPcoStatus, sizeof(NdisPcoStatus)); - - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_PCO_STATUS - ); - - NdisPcoStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisPcoStatus.Header.Size = sizeof(NDIS_WWAN_PCO_STATUS); - NdisPcoStatus.Header.Revision = NDIS_WWAN_PCO_STATUS_REVISION_1; - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_PCO_STATUS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - - if ((WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus)) != WWAN_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] WwanStatus from device not success, WwanStatus=%!WwanStatus!. MbbStatus=%!MbbStatus!", - Request->RequestId, - WwanStatus, - MbbStatus - ); - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - - if (pMbbPcoValue == NULL || - InBufferSize < sizeof(MBB_MS_PCO_VALUE)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_PCO_STATUS, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - sizeof(MBB_MS_PCO_VALUE) - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // Get the port. Always rely on the session id returned by the device as this - // responsehandler may be triggered due to an OID request from above - // or some MB device specific notification from below. Session Id is set in both cases. - Port = MbbWwanTranslateSessionIdToPort(Adapter, pMbbPcoValue->SessionId); - - if (Port == NULL) - { - // invalid port context - NdisStatus = NDIS_STATUS_INVALID_PORT; - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // Get the port number - MBB_ACQUIRE_PORT_LOCK(Port); - PortNumber = Port->PortNumber; - MBB_RELEASE_PORT_LOCK(Port); - - // Copy PCO data from MBB payload to NDIS payload - NdisPcoStatus.PcoValue.Size = pMbbPcoValue->PcoDataSize; - NdisPcoStatus.PcoValue.Type = pMbbPcoValue->PcoDataType; - RtlCopyMemory( - (PBYTE)&NdisPcoStatus.PcoValue.PcoData[0], - (PBYTE)&pMbbPcoValue->PcoDataBuffer[0], - pMbbPcoValue->PcoDataSize); - - } while (FALSE); - - if ((NDIS_STATUS_INVALID_DATA == NdisStatus) && !MbbReqMgrIsUnsolicitedIndication(Request)) - { - // - // We cannot get the SessionId from the MbbContextState because it is invalid. - // Since this is a transactional response, we do a best-effort to send the response up - // on the port from OidRequest. - // NOTE: Unsolicited indications with invalid SessionId are dropped. - // - - PortNumber = Request->OidContext.OidRequest->PortNumber; - Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); - - if (Port != NULL) - { - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbPcoValue is invalid. Using NDIS_DEFAULT_PORT_NUMBER (%lu) to indicate response", - Request->RequestId, - PortNumber); - - NdisPcoStatus.PcoValue.Size = 0; - NdisPcoStatus.PcoValue.Type = WwanPcoTypeMax; - } - else - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] MbbPcoValue is invalid AND we failed to retrieve the default port info", - Request->RequestId); - } - } - - if (Port != NULL) - { - // Indicate status indication on the correct port. - - NdisPcoStatus.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisPcoStatus; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_PCO_STATUS); - StatusIndication.PortNumber = PortNumber; - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_PCO_STATUS with status=%!WwanStatus! for Port number=%lu", - Request->RequestId, - WwanStatus, - PortNumber); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication); - - Dereference(Port); - } - else - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Not indicating OID_WWAN_PCO completion as the port context is invalid.", - Request->RequestId); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbNdisDeviceResetStatusHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize -) -{ - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - NDIS_WWAN_DEVICE_RESET_STATUS NdisDeviceResetStatus; - - UNREFERENCED_PARAMETER(InBuffer); - UNREFERENCED_PARAMETER(InBufferSize); - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_DEVICE_RESET_STATUS - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_DEVICE_RESET_STATUS, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(&NdisDeviceResetStatus, sizeof(NdisDeviceResetStatus)); - - NdisDeviceResetStatus.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisDeviceResetStatus.Header.Size = sizeof(NDIS_WWAN_DEVICE_RESET_STATUS); - NdisDeviceResetStatus.Header.Revision = NDIS_WWAN_DEVICE_RESET_STATUS_REVISION_1; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - NdisDeviceResetStatus.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &NdisDeviceResetStatus; - StatusIndication.StatusBufferSize = sizeof(NDIS_WWAN_DEVICE_RESET_STATUS); - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_DEVICE_RESET_STATUS with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbNdisBaseStationsInfoHandler( - _In_ PMBB_REQUEST_CONTEXT Request, - _In_ NDIS_STATUS NdisStatus, - _In_ MBB_STATUS MbbStatus, - _In_reads_bytes_opt_(InBufferSize) PUCHAR InBuffer, - _In_ ULONG InBufferSize -) -{ - BOOLEAN IndicationFailure = TRUE; - WWAN_STATUS WwanStatus; - NDIS_STATUS_INDICATION StatusIndication; - ULONG NdisBaseStationsInfoSize = 0; - PNDIS_WWAN_BASE_STATIONS_INFO NdisBaseStationsInfoResponse = NULL; - PMBB_MS_BASE_STATIONS_INFO MbbBaseStationInfoResponse = (PMBB_MS_BASE_STATIONS_INFO)InBuffer; - - do - { - MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( - &StatusIndication, - Request, - NDIS_STATUS_WWAN_BASE_STATIONS_INFO - ); - - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to get data for NDIS_STATUS_WWAN_BASE_STATIONS_INFO, status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - if (MbbBaseStationInfoResponse == NULL || - InBufferSize < (ULONG)FIELD_OFFSET(MBB_MS_BASE_STATIONS_INFO, DataBuffer)) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] INSUFFICIENT BufferSize for NDIS_STATUS_WWAN_BASE_STATIONS_INFO, BufferSize[Received=%d Expected=%d]", - Request->RequestId, - InBufferSize, - FIELD_OFFSET(MBB_MS_BASE_STATIONS_INFO, DataBuffer) - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - // ---------------------------------------------------------- - // NDIS_WWAN_BASE_STATIONS_INFO - // |---- header - // |---- uStatus - // |---- BaseStationsInfo (WWAN_BASE_STATIONS_INFO) ------------+ - // | |---- SystemTypes (ULONG) | - // | |---- Offsets and sizes (ULONGs) + Same content - // | |---- BaseStationsData (ANYSIZE_ARRAY) | - // ------------------------------- | - // MBB_MS_BASE_STATIONS_INFO -----------------------------------+ - // |---- SystemType (MBB_DATA_CLASS_VALUE) - // |---- Offsets and sizes (MBB_ARRAY_ELEMENTs) - // |---- DataBuffer[1] - // ---------------------------------------------------------- - NdisBaseStationsInfoSize = FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData); - ULONG MbbBaseStationDataSize = - MbbBaseStationInfoResponse->GSMServingCell.Size + - MbbBaseStationInfoResponse->UMTSServingCell.Size + - MbbBaseStationInfoResponse->TDSCDMAServingCell.Size + - MbbBaseStationInfoResponse->LTEServingCell.Size + - MbbBaseStationInfoResponse->GSMNmr.Size + - MbbBaseStationInfoResponse->UMTSMrl.Size + - MbbBaseStationInfoResponse->TDSCDMAMrl.Size + - MbbBaseStationInfoResponse->LTEMrl.Size + - MbbBaseStationInfoResponse->CDMAMrl.Size; - NdisBaseStationsInfoSize += MbbBaseStationDataSize; - - NdisBaseStationsInfoResponse = (PNDIS_WWAN_BASE_STATIONS_INFO)ALLOCATE_NONPAGED_POOL(NdisBaseStationsInfoSize); - - if (NdisBaseStationsInfoResponse == NULL) - { - TraceError(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] FAILED to allocate %d bytes for NDIS_STATUS_WWAN_BASE_STATIONS_INFO", - Request->RequestId, - NdisBaseStationsInfoSize - ); - WwanStatus = WWAN_STATUS_FAILURE; - break; - } - - RtlZeroMemory(NdisBaseStationsInfoResponse, NdisBaseStationsInfoSize); - - NdisBaseStationsInfoResponse->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NdisBaseStationsInfoResponse->Header.Size = (USHORT)NdisBaseStationsInfoSize; - NdisBaseStationsInfoResponse->Header.Revision = NDIS_WWAN_BASE_STATIONS_INFO_REVISION_1; - - // Copy MBB_MS_BASE_STATIONS_INFO to WWAN_BASE_STATIONS_INFO - RtlCopyMemory( - &NdisBaseStationsInfoResponse->BaseStationsInfo, - MbbBaseStationInfoResponse, - FIELD_OFFSET(WWAN_BASE_STATIONS_INFO, BaseStationsData) + MbbBaseStationDataSize); - - IndicationFailure = FALSE; - } while (FALSE); - - // - // Restore the device returned operational status, if any. - // - if (WwanStatus != WWAN_STATUS_SUCCESS && - MbbUtilMbbToWwanStatus(MbbStatus) != WWAN_STATUS_SUCCESS) - { - WwanStatus = MbbUtilMbbToWwanStatus(MbbStatus); - } - - if (!IndicationFailure) - { - NdisBaseStationsInfoResponse->uStatus = WwanStatus; - - StatusIndication.StatusBuffer = NdisBaseStationsInfoResponse; - StatusIndication.StatusBufferSize = NdisBaseStationsInfoSize; - } - else - { - NDIS_WWAN_BASE_STATIONS_INFO LocalNdisBaseStationsInfoResponse; - RtlZeroMemory(&LocalNdisBaseStationsInfoResponse, FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData)); - - LocalNdisBaseStationsInfoResponse.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - LocalNdisBaseStationsInfoResponse.Header.Size = FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData); - LocalNdisBaseStationsInfoResponse.Header.Revision = NDIS_WWAN_BASE_STATIONS_INFO_REVISION_1; - LocalNdisBaseStationsInfoResponse.uStatus = WwanStatus; - - StatusIndication.StatusBuffer = &LocalNdisBaseStationsInfoResponse; - StatusIndication.StatusBufferSize = FIELD_OFFSET(NDIS_WWAN_BASE_STATIONS_INFO, BaseStationsInfo.BaseStationsData); - } - - TraceInfo(WMBCLASS_OID, "[MbbNdis][ReqId=0x%04x] Indicating NDIS_STATUS_WWAN_BASE_STATIONS_INFO with status=%!WwanStatus!", - Request->RequestId, - WwanStatus - ); - - MbbNdisMiniportIndicateRequestStatus( - Request, - &StatusIndication - ); - - if (NdisBaseStationsInfoResponse != NULL) - { - FREE_POOL(NdisBaseStationsInfoResponse); - } - - return NDIS_STATUS_SUCCESS; -} - -// -// Completion Handlers -// - -VOID -MbbNdisReadyInfoCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.IsQueryReadyInfo == 1 ) - MbbNdisIndicateReadyInfoFailure( Request ); - - if( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo != NULL ) - FREE_POOL( Request->HandlerContext.Parameters.SubscriberReadyInfo.NdisReadyInfo ); - } -} - - -VOID -MbbNdisPacketServiceStateCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -/*++ -Description: - This is the completion handler for both PacketService CIDs - and RegisterState CIDs. RegisterState CID is issued when a - packet service response or indication is received since some - fields in the PacketService OID (OID model) require data not - present in the PacketService CID but present in the - RegisterState CID. ---*/ -{ - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - if( Request->HandlerContext.Parameters.PacketServiceState.IsQuery == 1 ) - { - MbbNdisIndicatePacketServiceFailure( Request, NdisStatus ); - } - - if( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState != NULL ) - { - FREE_POOL( Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState ); - Request->HandlerContext.Parameters.PacketServiceState.NdisPacketServiceState=NULL; - } - } -} - -VOID -MbbNdisMultiCarrierDsCidListCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - MbbNdisIndicateDeviceCaps( - Request, - NdisStatus - ); - } -} - -VOID -MbbNdisCreateMacCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); - NDIS_PORT_NUMBER PortNumber = DEFAULT_NDIS_PORT_NUMBER; - PMBB_PORT Port = NULL; - BOOLEAN fInAdapterPortList = FALSE; - - Port = Request->HandlerContext.Parameters.NdisPortContext.Port; - - if(Port) - { - MBB_ACQUIRE_PORT_LOCK(Port); - PortNumber = Port->PortNumber; - MBB_RELEASE_PORT_LOCK(Port); - - if(IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - // We should never activate the default port - - // Check whether the port is in the adapter port list - PMBB_PORT PortToCheck = NULL; - - fInAdapterPortList = (PortToCheck = MbbWwanTranslatePortNumberToPort(Adapter,PortNumber))!= NULL; - - if(fInAdapterPortList) - { - // Remove the reference added for port find - Dereference(PortToCheck); - - Status = MbbUtilWwanCreateMacComplete( - Adapter, - Port, - NdisStatus); - } - } - - // Remove the reference added when port was added to handlercontext - Dereference(Port); - } - else - { - Status = NDIS_STATUS_INVALID_PORT; - } - - if(Status != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbNdisCreateMacCompletionHandler failed. Status = 0x%08x\n", - Request->RequestId,Status); - } - else - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbNdisCreateMacCompletionHandler completed successfully.\n", - Request->RequestId); - } -} - - -VOID -MbbNdisDeleteMacCompletionHandler( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PMINIPORT_ADAPTER_CONTEXT Adapter = (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); - NDIS_PORT_NUMBER PortNumber = DEFAULT_NDIS_PORT_NUMBER; - PMBB_PORT Port = Request->HandlerContext.Parameters.NdisPortContext.Port; - - if(Port) - { - MBB_ACQUIRE_PORT_LOCK(Port); - PortNumber = Port->PortNumber; - MBB_RELEASE_PORT_LOCK(Port); - - if(IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - Status = MbbUtilWwanDeleteMacComplete( - Adapter, - Port, - NdisStatus); - } - else - { - Status = NDIS_STATUS_INVALID_PORT; - } - - // Remove the reference added when the port context was - // passed on as the handlercontext - Dereference(Port); - } - - if(Status != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbNdisDeleteMacCompletionHandler failed. Status = 0x%08x\n", - Request->RequestId,Status); - } - else - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbNdisDeleteMacCompletionHandler completed successfully.\n", - Request->RequestId); - } -} - -#pragma prefast(pop) \ No newline at end of file diff --git a/network/wwan/cxwmbclass/rxqueue.cpp b/network/wwan/cxwmbclass/rxqueue.cpp new file mode 100644 index 000000000..947e020d0 --- /dev/null +++ b/network/wwan/cxwmbclass/rxqueue.cpp @@ -0,0 +1,609 @@ +//------------------------------------------------------------------------------- +// Net Adapter source file +// +// Copyright (c) Microsoft Corporation. All rights reserved. + +#include "precomp.h" + +#include "device.h" +#include "rxqueue.h" + +#define MBB_NTH_GET_FIRST_NDP_OFFSET(IS32BIT, NTH) \ + ((IS32BIT) ? MBB_NTH32_GET_FIRST_NDP_OFFSET((PNCM_NTH32)NTH) : MBB_NTH16_GET_FIRST_NDP_OFFSET((PNCM_NTH16)NTH)) + +void MbbNotifyRxReady(_In_ NETPACKETQUEUE RxQueue) +{ + PMBB_RXQUEUE_CONTEXT rxQueueContext = MbbGetRxQueueContext(RxQueue); + if (InterlockedExchange(&rxQueueContext->NotificationEnabled, FALSE) == TRUE) + { + NetRxQueueNotifyMoreReceivedPacketsAvailable(RxQueue); + } +} + +VOID MbbRecvCleanup(_In_ PMBB_NDIS_RECEIVE_CONTEXT Receive) +{ + MbbBusReturnReceiveBuffer(Receive->BusHandle, Receive->BusContext, Receive->Mdl); + + WdfObjectDelete(Receive->ReceiveLookasideBufferMemory); +} + +VOID MbbRecvReturnNdp(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext, _In_opt_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext) +{ + LONG newCompletedCount = InterlockedIncrement(&ReceiveContext->CompletedNdpCount); + if (newCompletedCount == ReceiveContext->TotalNdpCount) + { + MbbRecvCleanup(ReceiveContext); + } + if (ReceiveNdpContext != NULL) + { + WdfObjectDelete(ReceiveNdpContext->ReceiveNdpLookasideBufferMemory); + } +} + +_Use_decl_annotations_ VOID MbbRecvCancelNdps(PWMBCLASS_DEVICE_CONTEXT DeviceContext, ULONG SessionId) +{ + LIST_ENTRY tempList; + PLIST_ENTRY listEntry; + PLIST_ENTRY nextEntry; + PMBB_RECEIVE_NDP_CONTEXT receiveNdpContext = NULL; + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = DeviceContext->Sessions[SessionId].NetAdapterContext; + + InitializeListHead(&tempList); + + WdfSpinLockAcquire(DeviceContext->Sessions[SessionId].WdfRecvSpinLock); + InsertHeadList(&netAdapterContext->ReceiveNdpList, &tempList); + RemoveEntryList(&netAdapterContext->ReceiveNdpList); + InitializeListHead(&netAdapterContext->ReceiveNdpList); + // Cannot cache the received Ndps anymore + netAdapterContext->AllowRxTraffic = FALSE; + WdfSpinLockRelease(DeviceContext->Sessions[SessionId].WdfRecvSpinLock); + + for (listEntry = tempList.Flink; listEntry != &tempList; listEntry = nextEntry) + { + nextEntry = listEntry->Flink; + receiveNdpContext = CONTAINING_RECORD(listEntry, MBB_RECEIVE_NDP_CONTEXT, ReceiveNdpNode); + MbbRecvReturnNdp(receiveNdpContext->ReceiveContext, receiveNdpContext); + } +} + +void MbbReceiveDssData(__in PWMBCLASS_DEVICE_CONTEXT DeviceContext, __in ULONG SessionId, __in_bcount_opt(InBufferSize) PUCHAR InBuffer, __in ULONG InBufferSize) +{ + NTSTATUS status; + WDFMEMORY data; + + status = WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES, InBuffer, InBufferSize, &data); + + if (NT_SUCCESS(status)) + { + DeviceContext->DSSPacketsReceivedCount++; + + MbbDeviceReceiveDeviceServiceSessionData(DeviceContext->WdfDevice, SessionId, data); + WdfObjectDelete(data); + } +} + +NTSTATUS +MbbRecvNdpUnpackDss32(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext, _In_ PNCM_NTH32 Nth, _In_ PNCM_NDP32 Ndp) +{ + UNREFERENCED_PARAMETER(Nth); + NTSTATUS status = STATUS_SUCCESS; + ULONG datagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp); + ULONG sessionId = MBB_NDP32_GET_SESSIONID(Ndp); + for (ULONG index = 0; index < datagramCount; index++) + { + if (MBB_NTB32_IS_END_DATAGRAM(Nth, Ndp, index)) + break; + + // Forward to the dss receive handler + MbbReceiveDssData( + ReceiveContext->WmbDeviceContext, sessionId, (PUCHAR)MBB_NDP32_GET_DATAGRAM(Nth, Ndp, index), MBB_NDP32_GET_DATAGRAM_LENGTH(Ndp, index)); + } + + MbbRecvReturnNdp(ReceiveContext, NULL); + return status; +} + +NTSTATUS +MbbRecvNdpUnpackDss16(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext, _In_ PNCM_NTH16 Nth, _In_ PNCM_NDP16 Ndp) +{ + UNREFERENCED_PARAMETER(Nth); + NTSTATUS status = STATUS_SUCCESS; + ULONG datagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp); + ULONG sessionId = MBB_NDP16_GET_SESSIONID(Ndp); + for (ULONG index = 0; index < datagramCount; index++) + { + if (MBB_NTB16_IS_END_DATAGRAM(Nth, Ndp, index)) + break; + + // Forward to the dss receive handler + MbbReceiveDssData( + ReceiveContext->WmbDeviceContext, sessionId, (PUCHAR)MBB_NDP16_GET_DATAGRAM(Nth, Ndp, index), MBB_NDP16_GET_DATAGRAM_LENGTH(Ndp, index)); + } + MbbRecvReturnNdp(ReceiveContext, NULL); + return status; +} + +NTSTATUS +MbbRecvAddNdp(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext, _In_ PVOID Nth, _In_ PVOID Ndp, _In_ ULONG SessionId) +{ + NTSTATUS status = STATUS_SUCCESS; + PWMBCLASS_DEVICE_CONTEXT deviceContext = ReceiveContext->WmbDeviceContext; + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = NULL; + WDFMEMORY ndpContextMemory; + PMBB_RECEIVE_NDP_CONTEXT ndpContext = NULL; + size_t ndpContextSize; + BOOLEAN returnNdp = FALSE; + + WdfSpinLockAcquire(deviceContext->Sessions[SessionId].WdfRecvSpinLock); + do + { + netAdapterContext = deviceContext->Sessions[SessionId].NetAdapterContext; + if (netAdapterContext == NULL) + { + returnNdp = TRUE; + break; + } + + if (!NT_SUCCESS(status = WdfMemoryCreateFromLookaside(netAdapterContext->ReceiveNdpLookasideList, &ndpContextMemory))) + { + returnNdp = TRUE; + break; + } + + ndpContext = (PMBB_RECEIVE_NDP_CONTEXT)WdfMemoryGetBuffer(ndpContextMemory, &ndpContextSize); + RtlZeroMemory(ndpContext, ndpContextSize); + ndpContext->Nth = Nth; + ndpContext->Ndp = Ndp; + ndpContext->ReceiveContext = ReceiveContext; + ndpContext->ReceiveNdpLookasideBufferMemory = ndpContextMemory; + ndpContext->NetAdapterContext = netAdapterContext; + if (netAdapterContext->AllowRxTraffic) + { + InsertTailList(&netAdapterContext->ReceiveNdpList, &ndpContext->ReceiveNdpNode); + } + else + { + returnNdp = TRUE; + break; + } + + // If RxQueueCreate hasn't completed yet, we only queue the received Ndp and don't need notify RxReady + if (netAdapterContext->RxQueue) + { + MbbNotifyRxReady(netAdapterContext->RxQueue); + } + } while (FALSE); + WdfSpinLockRelease(deviceContext->Sessions[SessionId].WdfRecvSpinLock); + + if (returnNdp) + { + MbbRecvReturnNdp(ReceiveContext, ndpContext); + } + return status; +} + +VOID MbbRecvNtbParse(_In_ PMBB_NDIS_RECEIVE_CONTEXT ReceiveContext) +{ + NTSTATUS status = STATUS_SUCCESS; + PNCM_NTH32 nth32; + PNCM_NTH16 nth16; + PNCM_NDP32 ndp32; + PNCM_NDP16 ndp16; + PVOID nth = ReceiveContext->ReceiveNtbBuffer; + + if (MBB_NTB_IS_32BIT(nth)) + { + nth32 = (PNCM_NTH32)nth; + for (ndp32 = MBB_NTH32_GET_FIRST_NDP(nth32); ndp32 != NULL; ndp32 = MBB_NDP32_GET_NEXT_NDP(nth32, ndp32)) + { + if (MBB_NDP32_GET_SIGNATURE_TYPE(ndp32) == NCM_NDP32_VENDOR) + { + status = MbbRecvNdpUnpackDss32(ReceiveContext, nth32, ndp32); + if (!NT_SUCCESS(status)) + { + } + } + else if (MBB_NDP32_GET_SIGNATURE_TYPE(ndp32) == NCM_NDP32_IPS) + { + status = MbbRecvAddNdp(ReceiveContext, nth32, ndp32, MBB_NDP32_GET_SESSIONID(ndp32)); + if (!NT_SUCCESS(status)) + { + } + } + else + { + MbbRecvReturnNdp(ReceiveContext, NULL); + } + } + } + else if (MBB_NTB_IS_16BIT(nth)) + { + nth16 = (PNCM_NTH16)nth; + for (ndp16 = MBB_NTH16_GET_FIRST_NDP(nth16); ndp16 != NULL; ndp16 = MBB_NDP16_GET_NEXT_NDP(nth16, ndp16)) + { + if (MBB_NDP16_GET_SIGNATURE_TYPE(ndp16) == NCM_NDP16_VENDOR) + { + status = MbbRecvNdpUnpackDss16(ReceiveContext, nth16, ndp16); + if (!NT_SUCCESS(status)) + { + } + } + else if (MBB_NDP16_GET_SIGNATURE_TYPE(ndp16) == NCM_NDP16_IPS) + { + status = MbbRecvAddNdp(ReceiveContext, nth16, ndp16, MBB_NDP32_GET_SESSIONID(ndp16)); + if (!NT_SUCCESS(status)) + { + } + } + else + { + MbbRecvReturnNdp(ReceiveContext, NULL); + } + } + } +} + +NTSTATUS +MbbRecvNtbUnpackIpNdp32(_In_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext, _In_ PNCM_NTH32 Nth32, _In_ PNCM_NDP32 Ndp32, _Inout_ ULONG* IncompletedDatagramIndex, _In_ PMBB_RXQUEUE_CONTEXT RxQueueContext) +{ + PCHAR incompletedDatagram; + ULONG incompletedDatagramLength; + NET_PACKET* packet; + NET_FRAGMENT* fragment; + NET_FRAGMENT_RETURN_CONTEXT* returnContext; + NET_FRAGMENT_VIRTUAL_ADDRESS* virtualAddress; + NTSTATUS status = STATUS_SUCCESS; + ULONG datagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp32); + +// NET_RING_PACKET_ITERATOR pi = NetRingGetAllPackets(RxQueueContext->DatapathDescriptor); +// NET_RING_FRAGMENT_ITERATOR fi = NetRingGetAllFragments(RxQueueContext->DatapathDescriptor); + NET_RING * pr = NetRingCollectionGetPacketRing(RxQueueContext->DatapathDescriptor); + NET_RING * fr = NetRingCollectionGetFragmentRing(RxQueueContext->DatapathDescriptor); + + while ((incompletedDatagram = MBB_NDP32_GET_DATAGRAM(Nth32, Ndp32, *IncompletedDatagramIndex)) != NULL) + { + // If all packets have been unpacked, break to avoid inappropriate device which doesn't fully follow NCM protocol to have zero dwDatagramIndex and zero dwDatagramLength as a terminator. + // It will crash OS like bug https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/19970558 + if (*IncompletedDatagramIndex >= datagramCount) + { + break; + } + + if (fr->BeginIndex == fr->EndIndex) + { + status = STATUS_BUFFER_OVERFLOW; + break; + } + + incompletedDatagramLength = MBB_NDP32_GET_DATAGRAM_LENGTH(Ndp32, *IncompletedDatagramIndex); + + UINT32 const fragmentIndex = fr->BeginIndex; + fragment = NetRingGetFragmentAtIndex(fr, fragmentIndex); + fragment->Capacity = incompletedDatagramLength; + fragment->ValidLength = incompletedDatagramLength; + fragment->Offset = 0; + + returnContext = NetExtensionGetFragmentReturnContext(&RxQueueContext->ReturnContextExtension, fragmentIndex); + virtualAddress = + NetExtensionGetFragmentVirtualAddress(&RxQueueContext->VirtualAddressExtension, fragmentIndex); + + + returnContext->Handle = (NET_FRAGMENT_RETURN_CONTEXT_HANDLE)ReceiveNdpContext; + virtualAddress->VirtualAddress = incompletedDatagram; + + (ReceiveNdpContext->IndicatedPackets)++; + (*IncompletedDatagramIndex)++; + + UINT32 const packetIndex = pr->BeginIndex; + packet = NetRingGetPacketAtIndex(pr, packetIndex); + packet->FragmentIndex = fragmentIndex; + packet->FragmentCount = 1; + packet->Layout = {}; + + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + fr->BeginIndex = NetRingIncrementIndex(fr, fr->BeginIndex); + } + return status; +} + +NTSTATUS +MbbRecvNtbUnpackIpNdp16(_In_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext, _In_ PNCM_NTH16 Nth16, _In_ PNCM_NDP16 Ndp16, _Inout_ ULONG* IncompletedDatagramIndex, _In_ PMBB_RXQUEUE_CONTEXT RxQueueContext) +{ + PCHAR incompletedDatagram; + ULONG incompletedDatagramLength; + NET_PACKET* packet; + NET_FRAGMENT* fragment; + NET_FRAGMENT_RETURN_CONTEXT* returnContext; + NET_FRAGMENT_VIRTUAL_ADDRESS* virtualAddress; + NTSTATUS status = STATUS_SUCCESS; + ULONG datagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp16); + + NET_RING * pr = NetRingCollectionGetPacketRing(RxQueueContext->DatapathDescriptor); + NET_RING * fr = NetRingCollectionGetFragmentRing(RxQueueContext->DatapathDescriptor); + + while ((incompletedDatagram = MBB_NDP16_GET_DATAGRAM(Nth16, Ndp16, *IncompletedDatagramIndex)) != NULL) + { + // If all packets have been unpacked, break to avoid inappropriate device which doesn't fully follow NCM protocol to have zero dwDatagramIndex and zero dwDatagramLength as a terminator. + // It will crash OS like bug https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/19970558 + if (*IncompletedDatagramIndex >= datagramCount) + { + break; + } + + if (fr->BeginIndex == fr->EndIndex) + { + status = STATUS_BUFFER_OVERFLOW; + break; + } + + incompletedDatagramLength = MBB_NDP16_GET_DATAGRAM_LENGTH(Ndp16, *IncompletedDatagramIndex); + + UINT32 const fragmentIndex = fr->BeginIndex; + fragment = NetRingGetFragmentAtIndex(fr, fragmentIndex); + fragment->Capacity = incompletedDatagramLength; + fragment->ValidLength = incompletedDatagramLength; + fragment->Offset = 0; + + returnContext = NetExtensionGetFragmentReturnContext(&RxQueueContext->ReturnContextExtension, fragmentIndex); + virtualAddress = + NetExtensionGetFragmentVirtualAddress(&RxQueueContext->VirtualAddressExtension, fragmentIndex); + + returnContext->Handle = (NET_FRAGMENT_RETURN_CONTEXT_HANDLE)ReceiveNdpContext; + virtualAddress->VirtualAddress = incompletedDatagram; + + (ReceiveNdpContext->IndicatedPackets)++; + (*IncompletedDatagramIndex)++; + + UINT32 const packetIndex = pr->BeginIndex; + packet = NetRingGetPacketAtIndex(pr, packetIndex); + packet->FragmentIndex = fragmentIndex; + packet->FragmentCount = 1; + packet->Layout = {}; + + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + fr->BeginIndex = NetRingIncrementIndex(fr, fr->BeginIndex); + } + + return status; +} + +NTSTATUS +MbbRecvNdpUnpackIps(_In_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext, _In_ PMBB_RXQUEUE_CONTEXT RxQueueContext) +{ + NTSTATUS status = STATUS_SUCCESS; + PNCM_NTH32 nth32; + PNCM_NTH16 nth16; + PNCM_NDP32 ndp32; + PNCM_NDP16 ndp16; + PMBB_NDIS_RECEIVE_CONTEXT receiveContext = ReceiveNdpContext->ReceiveContext; + PVOID nth = receiveContext->ReceiveNtbBuffer; + + if (MBB_NTB_IS_32BIT(nth)) + { + nth32 = (PNCM_NTH32)nth; + ndp32 = (PNCM_NDP32)ReceiveNdpContext->Ndp; + status = MbbRecvNtbUnpackIpNdp32(ReceiveNdpContext, nth32, ndp32, &ReceiveNdpContext->CurrentDatagramIndex, RxQueueContext); + } + else if (MBB_NTB_IS_16BIT(nth)) + { + nth16 = (PNCM_NTH16)nth; + ndp16 = (PNCM_NDP16)ReceiveNdpContext->Ndp; + status = MbbRecvNtbUnpackIpNdp16(ReceiveNdpContext, nth16, ndp16, &ReceiveNdpContext->CurrentDatagramIndex, RxQueueContext); + } + + return status; +} + +PMBB_NDIS_RECEIVE_CONTEXT +MbbRecvQQueueReceive(_In_ PWMBCLASS_DEVICE_CONTEXT DeviceContext, _In_ MBB_RECEIVE_CONTEXT BusContext, _In_ PMDL Mdl, _In_reads_(sizeof(NCM_NTH32)) PUCHAR ReceiveNtbBuffer) +{ + PMBB_NDIS_RECEIVE_CONTEXT receiveContext = NULL; + WDFMEMORY receiveContextMemory; + size_t receiveContextSize; + NTSTATUS status = STATUS_SUCCESS; + + do + { + if (!NT_SUCCESS(status = WdfMemoryCreateFromLookaside(DeviceContext->ReceiveLookasideList, &receiveContextMemory))) + { + break; + } + + receiveContext = (PMBB_NDIS_RECEIVE_CONTEXT)WdfMemoryGetBuffer(receiveContextMemory, &receiveContextSize); + RtlZeroMemory(receiveContext, receiveContextSize); + + receiveContext->Mdl = Mdl; + receiveContext->WmbDeviceContext = DeviceContext; + receiveContext->BusHandle = DeviceContext->BusHandle; + receiveContext->BusContext = BusContext; + receiveContext->ReceiveLookasideList = DeviceContext->ReceiveLookasideList; + receiveContext->ReceiveLookasideBufferMemory = receiveContextMemory; + receiveContext->ReceiveNtbBuffer = ReceiveNtbBuffer; + receiveContext->NtbSequence = MBB_NTB_GET_SEQUENCE(ReceiveNtbBuffer); + } while (FALSE); + + return receiveContext; +} + +VOID MbbNdisReceiveCallback(_In_ MBB_PROTOCOL_HANDLE ProtocolHandle, _In_ MBB_RECEIVE_CONTEXT ReceiveContext, _In_ PMDL Mdl) +{ + PUCHAR dataBuffer; + ULONG dataLength; + PVOID nth; + BOOLEAN returnBuffer = TRUE; + PWMBCLASS_DEVICE_CONTEXT deviceContext = (PWMBCLASS_DEVICE_CONTEXT)ProtocolHandle; + PMBB_NDIS_RECEIVE_CONTEXT receive = NULL; + ULONG ndpCount = 1; + NTSTATUS status = STATUS_SUCCESS; + do + { + if ((dataBuffer = (PUCHAR)MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority | MdlMappingNoExecute)) == NULL) + { + status = STATUS_RESOURCE_DATA_NOT_FOUND; + break; + } + dataLength = MmGetMdlByteCount(Mdl); + + nth = dataBuffer; + + if (!NT_SUCCESS(status = MbbNtbValidate(nth, dataLength, deviceContext->BusParams.CurrentMode32Bit, &ndpCount))) + { + { + ULONG i; + ULONG j; + + PUCHAR buffer = (PUCHAR)nth; + + for (i = 0; i < dataLength; i += 16) + { + UCHAR numString[16 * 3 + 1]; + UCHAR asciiBuffer[40]; + UCHAR value = 0; + const char translateTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + RtlZeroMemory(numString, sizeof(numString)); + RtlZeroMemory(asciiBuffer, sizeof(asciiBuffer)); + + for (j = 0; j < 16; j++) + { + if (i + j >= dataLength) + { + // + // past the end, just put spaces + // + numString[j * 3] = ' '; + numString[j * 3 + 1] = ' '; + numString[j * 3 + 2] = ' '; + } + else + { + value = buffer[i + j]; + + numString[j * 3] = translateTable[value >> 4]; + numString[j * 3 + 1] = translateTable[value & 0xf]; + numString[j * 3 + 2] = ' '; + + if ((buffer[i + j] >= 32) && (buffer[i + j] < 128)) + { + asciiBuffer[j] = value; + } + else + { + asciiBuffer[j] = '.'; + } + } + } + } + } + break; + } + + if ((receive = MbbRecvQQueueReceive(deviceContext, ReceiveContext, Mdl, (PUCHAR)nth)) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + returnBuffer = FALSE; + receive->TotalNdpCount = ndpCount; + + // Receive DSS, IPs will be received in EvtRxQueueAdvance + MbbRecvNtbParse(receive); + } while (FALSE); + + if (returnBuffer) + { + if (receive != NULL) + { + MbbRecvCleanup(receive); + } + else + { + MbbBusReturnReceiveBuffer(deviceContext->BusHandle, ReceiveContext, Mdl); + } + } +} + +void EvtRxQueueDestroy(_In_ WDFOBJECT RxQueue) +{ + PMBB_RXQUEUE_CONTEXT rxQueueContext = MbbGetRxQueueContext(RxQueue); + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = rxQueueContext->NetAdapterContext; + netAdapterContext->RxQueue = NULL; +} + +VOID EvtRxQueueSetNotificationEnabled(_In_ NETPACKETQUEUE RxQueue, _In_ BOOLEAN NotificationEnabled) +{ + PMBB_RXQUEUE_CONTEXT txQueueContext = MbbGetRxQueueContext(RxQueue); + InterlockedExchange(&txQueueContext->NotificationEnabled, NotificationEnabled); +} + +void EvtRxQueueAdvance(_In_ NETPACKETQUEUE RxQueue) +{ + PMBB_RXQUEUE_CONTEXT rxQueueContext = MbbGetRxQueueContext(RxQueue); + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = rxQueueContext->NetAdapterContext; + WDFSPINLOCK wdfRecvSpinLock = netAdapterContext->WmbDeviceContext->Sessions[netAdapterContext->SessionId].WdfRecvSpinLock; + PMBB_RECEIVE_NDP_CONTEXT receiveNdpContext; + NTSTATUS status = STATUS_SUCCESS; + + WdfSpinLockAcquire(wdfRecvSpinLock); + while (!IsListEmpty(&netAdapterContext->ReceiveNdpList)) + { + receiveNdpContext = CONTAINING_RECORD(RemoveHeadList(&netAdapterContext->ReceiveNdpList), MBB_RECEIVE_NDP_CONTEXT, ReceiveNdpNode); + receiveNdpContext->ReceiveNdpNode.Flink = receiveNdpContext->ReceiveNdpNode.Blink = NULL; + WdfSpinLockRelease(wdfRecvSpinLock); + + status = MbbRecvNdpUnpackIps(receiveNdpContext, rxQueueContext); + if (status == STATUS_BUFFER_OVERFLOW) + { + WdfSpinLockAcquire(wdfRecvSpinLock); + InsertHeadList(&netAdapterContext->ReceiveNdpList, &receiveNdpContext->ReceiveNdpNode); + break; + } + else + { + if (!NT_SUCCESS(status)) + { + } + } + + WdfSpinLockAcquire(wdfRecvSpinLock); + } + WdfSpinLockRelease(wdfRecvSpinLock); +} + +void EvtRxQueueCancel(_In_ NETPACKETQUEUE RxQueue) +{ + PMBB_RXQUEUE_CONTEXT rxQueueContext = MbbGetRxQueueContext(RxQueue); + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = rxQueueContext->NetAdapterContext; + PWMBCLASS_DEVICE_CONTEXT deviceContext = netAdapterContext->WmbDeviceContext; + NET_RING_COLLECTION const* rings = rxQueueContext->DatapathDescriptor; + + NET_RING * pr = NetRingCollectionGetPacketRing(rings); + + while (pr->BeginIndex != pr->EndIndex) + { + NET_PACKET * packet = NetRingGetPacketAtIndex(pr, pr->BeginIndex); + packet->Ignore = 1; + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + } + + NET_RING * fr = NetRingCollectionGetFragmentRing(rings); + fr->BeginIndex = fr->EndIndex; + + // Cancel received Ndps which may be received after EvtRxQueueCancel started, these Ndps may never be processed by EvtRxQueueAdvance + MbbRecvCancelNdps(deviceContext, netAdapterContext->SessionId); +} + +VOID EvtAdapterReturnRxBuffer(_In_ NETADAPTER Adapter, _In_ NET_FRAGMENT_RETURN_CONTEXT_HANDLE RxBufferReturnContext) +{ + PMBB_RECEIVE_NDP_CONTEXT receiveNdpContext = (PMBB_RECEIVE_NDP_CONTEXT)RxBufferReturnContext; + UNREFERENCED_PARAMETER(Adapter); + NT_ASSERT(receiveNdpContext->IndicatedPackets); + + receiveNdpContext->IndicatedPackets--; + if ((receiveNdpContext->IndicatedPackets == 0) && (receiveNdpContext->ReceiveNdpNode.Blink == NULL) && + (receiveNdpContext->ReceiveNdpNode.Flink == NULL)) + { + MbbRecvReturnNdp(receiveNdpContext->ReceiveContext, receiveNdpContext); + } +} diff --git a/network/wwan/cxwmbclass/selsuspend.cpp b/network/wwan/cxwmbclass/selsuspend.cpp new file mode 100644 index 000000000..c2b2e2421 --- /dev/null +++ b/network/wwan/cxwmbclass/selsuspend.cpp @@ -0,0 +1,79 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +#include + +_Function_class_(IO_COMPLETION_ROUTINE) +NTSTATUS +MbbUsbBusIdleRequestCompletion(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID Context) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)Context; + + KeSetEvent(&BusObject->UsbSsIrpComplete, IO_NO_INCREMENT, FALSE); + + (*BusObject->IdleNotificationComplete)(BusObject->ProtocolHandle, Irp->IoStatus.Status); + + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +MbbBusIdleNotification(__in MBB_BUS_HANDLE BusHandle, __in BOOLEAN ForceIdle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status = STATUS_SUCCESS; + PIO_STACK_LOCATION IoSp = NULL; + + // + // This routine is invoked by NDIS when it has detected that the miniport + // is idle. The miniport must prepare to issue its selective suspend IRP + // to the USB stack. The driver can return NDIS_STATUS_BUSY if it is + // not ready to go to idle at this moment; NDIS will then retry later. + // Otherwise, the miniport should return NDIS_STATUS_PENDING. + // + + KeResetEvent(&BusObject->UsbSsIrpComplete); + + IoReuseIrp(BusObject->UsbSsIrp, STATUS_NOT_SUPPORTED); + + IoSp = IoGetNextIrpStackLocation(BusObject->UsbSsIrp); + + IoSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + + IoSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION; + IoSp->Parameters.DeviceIoControl.InputBufferLength = sizeof(BusObject->UsbSsCallback); + IoSp->Parameters.DeviceIoControl.Type3InputBuffer = &BusObject->UsbSsCallback; + + IoSetCompletionRoutine(BusObject->UsbSsIrp, MbbUsbBusIdleRequestCompletion, BusObject, TRUE, TRUE, TRUE); + + Status = IoCallDriver(BusObject->Fdo, BusObject->UsbSsIrp); + + if (!NT_SUCCESS(Status)) + { + KeSetEvent(&BusObject->UsbSsIrpComplete, IO_NO_INCREMENT, FALSE); + + return STATUS_UNSUCCESSFUL; + } + + return STATUS_PENDING; +} + +VOID MbbBusCancelIdleNotification(__in MBB_BUS_HANDLE BusHandle) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + + // This routine is called if NDIS needs to cancel an idle notification. + // All that is needed is to cancel the selective suspend IRP. + // + + IoCancelIrp(BusObject->UsbSsIrp); + + return; +} + +VOID MbbBusMiniportUsbIdle(PVOID Context) +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)Context; + + (*BusObject->IdleConfirmCallback)(BusObject->ProtocolHandle, PowerDeviceD2); + return; +} diff --git a/network/wwan/cxwmbclass/send.c b/network/wwan/cxwmbclass/send.c deleted file mode 100644 index 5f82e0aec..000000000 --- a/network/wwan/cxwmbclass/send.c +++ /dev/null @@ -1,2744 +0,0 @@ -/*************************************************************************** - -Copyright (c) 2010 Microsoft Corporation - -Module Name: - - send.c - -Abstract: - - This file contains - 1. Queuing of send NBLs - 2. Conversion of NBL to NTBs - 3. Completion of NBLs - -Environment: - - kernel mode only - -Notes: - - -Revision History: - - 3/20/2010 : TriRoy : Changed queuing to use NblContext, added conversion routines. - -Authors: - - BrianL - TriRoy - -****************************************************************************/ - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// INCLUDES -// -//////////////////////////////////////////////////////////////////////////////// -#include "precomp.h" -#include "send.tmh" -#include "WMBClassTelemetry.h" - - - -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// -#define MBB_NDP_DATAGRAM_INDEX_INVALID ((ULONG)-1) - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// TYPEDEFS -// -//////////////////////////////////////////////////////////////////////////////// -typedef enum -{ - MbbNdpTypeNoCrc = 0, - MbbNdpTypeCrc, - MbbNdpTypeIps, - MbbNdpTypeVendor_1, // Vendor with session id X (need not be 1) - MbbNdpTypeVendor_2, // Vendor with session id Y (need not be X + 1) - MbbNdpTypeVendor_3, - MbbNdpTypeVendor_Max, // Max 4 vendor sessions in one NTB - MbbNdpTypeMax - -} MBB_NDP_TYPE; - -typedef struct _MBB_NB_CONTEXT -{ - PMDL DataStartMdl; - PMDL DataEndMdl; - PMDL PaddingMdl; - PMDL ModifiedMdl; - MDL OriginalMdl; - PNPAGED_LOOKASIDE_LIST NbLookasideList; - -} MBB_NB_CONTEXT, -*PMBB_NB_CONTEXT; - -typedef -__callback VOID -(*MBB_NBL_CLEANUP_CALLBACK)( - __in PNET_BUFFER_LIST NetBufferList, - __in PVOID Context - ); - -typedef struct _MBB_NBL_CONTEXT -{ - // - // Protected by send queue lock - // - LIST_ENTRY NblQLink; - LIST_ENTRY DispatchQLink; - PNET_BUFFER_LIST NetBufferList; - PNET_BUFFER CurrentNb; - BOOLEAN Failed; - ULONG NbTotalCount; - ULONG NbDispatchCount; - ULONG SessionId; - // - // Protected by Interlock - // - ULONG NbCompleteCount; - - MBB_NBL_CLEANUP_CALLBACK CleanupCallback; - PVOID CleanupCallbackContext; - PNPAGED_LOOKASIDE_LIST NblLookasideList; - PNPAGED_LOOKASIDE_LIST NbLookasideList; - - // - // State for Dss data - // - MBB_REQUEST_HANDLE DssRequestHandle; - ULONG DssSessionId; - - -} MBB_NBL_CONTEXT, -*PMBB_NBL_CONTEXT; - -__inline -BOOLEAN -MbbNblContextIsDssData( - __in PMBB_NBL_CONTEXT NblContext - ) -{ - if( NblContext->DssSessionId != (ULONG)(-1)) - return TRUE; - else - return FALSE; -} - - -typedef struct _MBB_NDP_HEADER_ENTRY -{ - MBB_NDP_TYPE NdpType; - ULONG SessionId; - ULONG DatagramOffset; - ULONG DatagramLength; - ULONG NextEntryIndex; - PNET_BUFFER NetBuffer; - PNET_BUFFER_LIST NetBufferList; - -} MBB_NDP_HEADER_ENTRY, -*PMBB_NDP_HEADER_ENTRY; - -typedef struct _MBB_NTB_BUILD_CONTEXT -{ - LIST_ENTRY NtbQLink; - // - // Read-only values - // - BOOLEAN IsNtb32Bit; - ULONG NtbHeaderSize; - ULONG NdpHeaderFixedSize; - ULONG NdpDatagramEntrySize; - ULONG NtbOutMaxSize; - USHORT NtbOutMaxDatagrams; - USHORT NdpOutDivisor; - USHORT NdpOutPayloadRemainder; - USHORT NdpOutAlignment; - NDIS_HANDLE MiniportHandle; - PVOID PaddingBuffer; - PNPAGED_LOOKASIDE_LIST NtbLookasideList; - // - // Network Transfer Header(NTH) - // - union { - NCM_NTH16 Nth16; - NCM_NTH32 Nth32; - }; - PMDL NthMdl; - // - // NDP Header - // - PMDL NdpMdl; - ULONG NdpSize; - PVOID NdpBuffer; - // - // NDP Datagrams - // - ULONG DatagramCount; - ULONG DatagramLength; - PMDL DatagramLastMdl; - // - // NDP Headers. Varialble length array is limited - // to NdpMaxDatagrams. NdpFirstDatagramEntry of -1 - // is invalid. - // - ULONG NdpFirstDatagramEntry[MbbNdpTypeMax]; - MBB_NDP_HEADER_ENTRY NdpDatagramEntries[ANYSIZE_ARRAY]; - -} MBB_NTB_BUILD_CONTEXT, -*PMBB_NTB_BUILD_CONTEXT; - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// PROTOTYPES -// -//////////////////////////////////////////////////////////////////////////////// - -// -// NTB Context -// - -PMBB_NTB_BUILD_CONTEXT -MbbNtbAllocateContext( - __in NDIS_HANDLE MiniportHandle, - __in PNPAGED_LOOKASIDE_LIST NtbLookasideList, - __in PMBB_BUS_PARAMETERS BusParams, - __in PVOID PaddingBuffer, - __in ULONG NtbSequence - ); - -VOID -MbbNtbCleanupContext( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in NTSTATUS NtStatus - ); - -NDIS_STATUS -MbbNtbAddNdpHeaders( - __in PMBB_NTB_BUILD_CONTEXT NtbContext - ); - -ULONG -MbbNtbMapNdpTypeToSignature( - __in MBB_NDP_TYPE MbbNdpType, - __in BOOLEAN Is32Bit, - __in ULONG SessionId - ); - -VOID -MbbNtbFillNdp32Header( - __in PNCM_NDP32 Ndp, - __in MBB_NDP_TYPE NdpType, - __in PMBB_NTB_BUILD_CONTEXT NtbContext - ); - -VOID -MbbNtbFillNdp16Header( - __in PNCM_NDP16 Ndp, - __in MBB_NDP_TYPE NdpType, - __in PMBB_NTB_BUILD_CONTEXT NtbContext - ); - -FORCEINLINE -PMDL -MbbNtbGetMdlChainHead( - __in PMBB_NTB_BUILD_CONTEXT NtbContext - ); - -NDIS_STATUS -MbbNtbAddNbl( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in PNET_BUFFER_LIST NetBufferList - ); - -NDIS_STATUS -MbbNtbAddNb( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in PNPAGED_LOOKASIDE_LIST NbLookasideList, - __in PNET_BUFFER NetBuffer, - __in PNET_BUFFER_LIST NetBufferList, - __in MBB_NDP_TYPE CurrentNdpType, - __in ULONG SessionId - ); - -VOID -MbbNtbChainNb( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in PNET_BUFFER NetBuffer - ); - -// Test - -NDIS_STATUS -MbbNtbValidate( - __in PVOID Nth, - __in ULONG BufferLength, - __in BOOLEAN Is32Bit - ); - -#if DBG - -NDIS_STATUS -MbbTestValidateNtb( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in_bcount(ScratchLength) PCHAR ScratchBuffer, - __in ULONG ScratchLength - ); -#endif - -// -// NB Context -// - -PMBB_NB_CONTEXT -MbbNbAllocateContext( - __in PNET_BUFFER NetBuffer, - __in ULONG DatagramLength, - __in PVOID PaddingBuffer, - __in ULONG PaddingLength, - __in PNPAGED_LOOKASIDE_LIST NbLookasideList, - __in NDIS_HANDLE MiniportHandle - ); - -VOID -MbbNbCleanupContext( - __in PNET_BUFFER NetBuffer - ); - -FORCEINLINE -PMDL -MbbNbGetFirstMdl( - __in PNET_BUFFER NetBuffer - ); - -FORCEINLINE -PMDL -MbbNbGetLastMdl( - __in PNET_BUFFER NetBuffer - ); - -VOID -MbbNbSaveAndSetMdl( - __in PNET_BUFFER NetBuffer, - __in PMDL MdlToSave, - __in PMDL MdlToSet - ); - -VOID -MbbNbRestoreMdl( - __in PNET_BUFFER NetBuffer - ); - -// -// NBL Context -// - -PMBB_NBL_CONTEXT -MbbNblAllocateContext( - __in PNET_BUFFER_LIST NetBufferList, - __in PNPAGED_LOOKASIDE_LIST NblLookasideList, - __in PNPAGED_LOOKASIDE_LIST NbLookasideList, - __in MBB_NBL_CLEANUP_CALLBACK CleanupCallback, - __in PVOID CleanupCallbackContext - ); - -VOID -MbbNblFinalizeContext( - __in PNET_BUFFER_LIST NetBufferList, - __in ULONG NbCount, - __in NTSTATUS NtStatus - ); - -FORCEINLINE -PNET_BUFFER -MbbNblGetNextDispatchNb( - __in PNET_BUFFER_LIST NetBufferList - ); - -FORCEINLINE -PNET_BUFFER -MbbNblAdvanceDispatchNb( - __in PNET_BUFFER_LIST NetBufferList - ); - -// -// Send Queue -// - -_Acquires_lock_( SendQueue->Lock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, SendQueue ) -FORCEINLINE -VOID -MbbSendQLock( - __in PMBB_SEND_QUEUE SendQueue, - __in BOOLEAN DispatchLevel - ); - -_Releases_lock_( SendQueue->Lock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, SendQueue ) -FORCEINLINE -VOID -MbbSendQUnlock( - __in PMBB_SEND_QUEUE SendQueue, - __in BOOLEAN DispatchLevel - ); - -FORCEINLINE -VOID -MbbSendQResetNtbSequence( - __in PMBB_SEND_QUEUE SendQueue - ); - -FORCEINLINE -ULONG -MbbSendQGetNtbSequence( - __in PMBB_SEND_QUEUE SendQueue - ); - -VOID -MbbSendQProcess( - __in PMBB_SEND_QUEUE SendQueue, - __in BOOLEAN DispatchLevel - ); - -_Requires_lock_held_(SendQueue->Lock) -NDIS_STATUS -MbbSendQQueueNbl( - __in PMBB_SEND_QUEUE SendQueue, - __in PNET_BUFFER_LIST NetBufferList, - __in ULONG SessionId - ); - -VOID -MbbSendQDequeueNbl( - __in PNET_BUFFER_LIST NetBufferList, - __in PVOID Context - ); - -VOID -MbbSendQCompleteNtb( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in MBB_REQUEST_HANDLE RequestHandle, - __in NTSTATUS NtStatus, - __in PMDL Mdl - ); - -VOID -MbbSendQCancelRequests( - __in PMBB_SEND_QUEUE SendQueue, - __in NDIS_STATUS Status, - __in BOOLEAN WaitForCompletion, - __in BOOLEAN ExternalDataOnly - ); - -_Requires_lock_held_(SendQueue->Lock) -NDIS_STATUS -MbbSendQQueueDssData( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_SEND_QUEUE SendQueue, - __in MBB_REQUEST_HANDLE RequestHandle, - __in ULONG RequestId, - __in ULONG SessionId, - __in ULONG DataSize, - __in PVOID Data - ); - -VOID -MbbSendQDequeueDssData( - __in PNET_BUFFER_LIST NetBufferList, - __in PVOID Context - ); - -//////////////////////////////////////////////////////////////////////////////// -// -// IMPLEMENTATION -// -//////////////////////////////////////////////////////////////////////////////// -_Acquires_lock_( SendQueue->Lock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, SendQueue ) -FORCEINLINE -VOID -MbbSendQLock( - __in PMBB_SEND_QUEUE SendQueue, - __in BOOLEAN DispatchLevel - ) -{ - if( DispatchLevel == TRUE ) - { - NdisDprAcquireSpinLock( &SendQueue->Lock ); - } - else - { - NdisAcquireSpinLock( &SendQueue->Lock ); - } -} - -_Releases_lock_( SendQueue->Lock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, SendQueue ) -FORCEINLINE -VOID -MbbSendQUnlock( - __in PMBB_SEND_QUEUE SendQueue, - __in BOOLEAN DispatchLevel - ) -{ - if( DispatchLevel == TRUE ) - { - NdisDprReleaseSpinLock( &SendQueue->Lock ); - } - else - { - NdisReleaseSpinLock( &SendQueue->Lock ); - } -} - -NDIS_STATUS -MbbSendQInitialize( - __in PMBB_SEND_QUEUE SendQueue, - __in ULONG MaxConcurrentSends, - __in MBB_DRAIN_COMPLETE DrainCompleteCallback, - __in PVOID DrainCompleteCallbackContext, - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_BUS_HANDLE BusHandle, - __in NDIS_HANDLE MiniportHandle - ) -{ - ULONG PaddingLength; - ULONG NtbSize; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - NET_BUFFER_POOL_PARAMETERS NbPoolParameters; - NET_BUFFER_LIST_POOL_PARAMETERS NblPoolParameters; - - do - { - RtlZeroMemory( SendQueue, sizeof(MBB_SEND_QUEUE) ); - - NdisAllocateSpinLock( &SendQueue->Lock ); - InitializeListHead( &SendQueue->NtbQueue ); - InitializeListHead( &SendQueue->NblTrackList ); - InitializeListHead( &SendQueue->NblDispatchQueue ); - - KeInitializeEvent( - &SendQueue->NblQueueEmptyEvent, - NotificationEvent, - TRUE - ); - PaddingLength = MAX( Adapter->BusParams.NdpOutAlignment, Adapter->BusParams.NdpOutDivisor ); - if( (SendQueue->PaddingBuffer = ALLOCATE_NONPAGED_POOL( PaddingLength )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } -#if DBG - SendQueue->ScratchLength = Adapter->BusParams.MaxOutNtb; - if( (SendQueue->ScratchBuffer = (PCHAR)ALLOCATE_NONPAGED_POOL( SendQueue->ScratchLength )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } -#endif - - RtlZeroMemory( SendQueue->PaddingBuffer, PaddingLength ); - - SendQueue->NblPool = NULL; - - NblPoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NblPoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; - NblPoolParameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; - NblPoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; - NblPoolParameters.fAllocateNetBuffer = TRUE; - NblPoolParameters.ContextSize = 0; - NblPoolParameters.PoolTag = MbbPoolTagNblPool; - NblPoolParameters.DataSize = 0; - - if( (SendQueue->NblPool = NdisAllocateNetBufferListPool( - MiniportHandle, - &NblPoolParameters - )) == NULL ) - { - TraceError( WMBCLASS_SEND, "[Send] FAILED to allocate NetBufferListPool" ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - SendQueue->MaxConcurrentSends = MaxConcurrentSends; - SendQueue->AdapterContext = Adapter; - SendQueue->BusHandle = BusHandle; - - NtbSize = FIELD_OFFSET(MBB_NTB_BUILD_CONTEXT,NdpDatagramEntries); - NtbSize += (Adapter->BusParams.MaxOutDatagrams * sizeof(MBB_NDP_HEADER_ENTRY)); - NdisInitializeNPagedLookasideList( - &SendQueue->NtbLookasideList, - NULL, - NULL, - 0, // Flags - NtbSize, - MbbPoolTagNtbSend, - 0 // Depth - ); - NdisInitializeNPagedLookasideList( - &SendQueue->NblLookasideList, - NULL, - NULL, - 0, // Flags - sizeof(MBB_NBL_CONTEXT), - MbbPoolTagNblSend, - 0 // Depth - ); - NdisInitializeNPagedLookasideList( - &SendQueue->NbLookasideList, - NULL, - NULL, - 0, // Flags - sizeof(MBB_NB_CONTEXT), - MbbPoolTagNbSend, - 0 // Depth - ); - InitDrainObject( - &SendQueue->QueueDrainObject, - DrainCompleteCallback, - DrainCompleteCallbackContext - ); - TraceInfo( WMBCLASS_SEND, "[Send] Initialization complete" ); - } - while( FALSE ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - if( SendQueue->NblPool != NULL ) - { - NdisFreeNetBufferListPool( SendQueue->NblPool ); - SendQueue->NblPool = NULL; - } - - if( SendQueue->PaddingBuffer != NULL ) - FREE_POOL( SendQueue->PaddingBuffer ); - -#if DBG - if( SendQueue->ScratchBuffer != NULL ) - FREE_POOL( SendQueue->ScratchBuffer ); -#endif - - } - return NdisStatus; -} - -VOID -MbbSendQCleanup( - __in PMBB_SEND_QUEUE SendQueue - ) -/*++ - Description - Frees all resources allocated for the queue. - This is called from MiniportHalt so the queue should - already be empty. This routine does not call cancel - or wait for pending requests to complete since there - should not be any. ---*/ -{ - ASSERT( IsListEmpty( &SendQueue->NblTrackList ) == TRUE ); - - NdisDeleteNPagedLookasideList( &SendQueue->NtbLookasideList ); - NdisDeleteNPagedLookasideList( &SendQueue->NblLookasideList ); - NdisDeleteNPagedLookasideList( &SendQueue->NbLookasideList ); - - if( SendQueue->PaddingBuffer != NULL ) - FREE_POOL( SendQueue->PaddingBuffer ); - -#if DBG - if( SendQueue->ScratchBuffer != NULL ) - FREE_POOL( SendQueue->ScratchBuffer ); -#endif - - if( SendQueue->NblPool != NULL ) - { - NdisFreeNetBufferListPool( SendQueue->NblPool ); - SendQueue->NblPool = NULL; - } - - TraceInfo( WMBCLASS_SEND, "[Send] Cleanup complete" ); -} - -VOID -MbbSendQCancel( - __in PMBB_SEND_QUEUE SendQueue, - __in NDIS_STATUS Status, - __in BOOLEAN WaitForCompletion - ) -{ - StartDrain( &SendQueue->QueueDrainObject ); - - // - // NBLs - // - MbbSendQCancelRequests( - SendQueue, - Status, - WaitForCompletion, - FALSE - ); - - TraceInfo( WMBCLASS_SEND, "[Send] Cancel complete" ); -} - -VOID -MbbSendQCancelRequests( - __in PMBB_SEND_QUEUE SendQueue, - __in NDIS_STATUS Status, - __in BOOLEAN WaitForCompletion, - __in BOOLEAN ExternalDataOnly - ) -{ - PLIST_ENTRY ListEntry = NULL; - PLIST_ENTRY NextEntry = NULL; - LIST_ENTRY TempList; - PLIST_ENTRY QueueHead; - PKEVENT QueueEmptyEvent; - PMBB_NBL_CONTEXT NblContext; - PMBB_REQUEST_CONTEXT Request; - - TraceInfo( WMBCLASS_SEND, "[Send] Cancelling %s requests", (ExternalDataOnly? "External": "All") ); - - QueueHead = &SendQueue->NblDispatchQueue; - QueueEmptyEvent = &SendQueue->NblQueueEmptyEvent; - - InitializeListHead( &TempList ); - - MbbSendQLock( SendQueue, FALSE ); - for( ListEntry = QueueHead->Flink; - ListEntry != QueueHead; - ListEntry = NextEntry ) - { - NextEntry = ListEntry->Flink; - RemoveEntryList( ListEntry ); - InsertTailList( &TempList, ListEntry ); - } - MbbSendQUnlock( SendQueue, FALSE ); - - for( ListEntry = TempList.Flink; - ListEntry != &TempList; - ListEntry = NextEntry ) - { - NextEntry = ListEntry->Flink; - RemoveEntryList( ListEntry ); - NblContext = CONTAINING_RECORD( ListEntry, MBB_NBL_CONTEXT, DispatchQLink ); - MbbNblFinalizeContext( - NblContext->NetBufferList, - NblContext->NbTotalCount - NblContext->NbDispatchCount, - Status - ); - } - - if( WaitForCompletion ) - { - TraceInfo( WMBCLASS_SEND, "[Send] Cancel, waiting for %s requests to complete", (ExternalDataOnly? "External": "All") ); - - KeWaitForSingleObject( - QueueEmptyEvent, - Executive, - KernelMode, - FALSE, - NULL - ); - } -} - -VOID -MbbSendQProcess( - __in PMBB_SEND_QUEUE SendQueue, - __in BOOLEAN DispatchLevel - ) -{ - NTSTATUS NtStatus; - NDIS_STATUS NdisStatus; - BOOLEAN AbortDataQueue; - BOOLEAN CompleteNBs; - PMBB_NBL_CONTEXT NblContext; - PMBB_NTB_BUILD_CONTEXT NtbContext; - PMBB_REQUEST_CONTEXT Request; - - // - // Synchronize with other instances of this routine called from completion handlers. - // - MbbSendQLock( SendQueue, DispatchLevel ); - if( SendQueue->ProcessingQueue != FALSE ) - { - MbbSendQUnlock( SendQueue, DispatchLevel ); - return; - } - SendQueue->ProcessingQueue = TRUE; - - while( SendQueue->ConcurrentSends < SendQueue->MaxConcurrentSends && - ! IsListEmpty( &SendQueue->NblDispatchQueue )) - { - // - // Process the data queue - // Try to add as many NBLs as possible to the NTB - // - NtbContext = NULL; - NdisStatus = NDIS_STATUS_SUCCESS; - AbortDataQueue = FALSE; - - while( IsListEmpty(&SendQueue->NblDispatchQueue) == FALSE && - NdisStatus == NDIS_STATUS_SUCCESS ) - { - CompleteNBs = FALSE; - - if( NtbContext == NULL ) - { - if( (NtbContext = MbbNtbAllocateContext( - SendQueue->AdapterContext->MiniportAdapterHandle, - &SendQueue->NtbLookasideList, - &SendQueue->AdapterContext->BusParams, - SendQueue->PaddingBuffer, - MbbSendQGetNtbSequence( SendQueue ) - )) == NULL ) - { - TraceError( WMBCLASS_SEND, "[Send] FAILED to allocate NTB" ); - AbortDataQueue = TRUE; - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - InsertTailList( &SendQueue->NtbQueue, &NtbContext->NtbQLink ); - SendQueue->ConcurrentSends++; - } - NblContext = CONTAINING_RECORD( - RemoveHeadList( &SendQueue->NblDispatchQueue ), - MBB_NBL_CONTEXT, - DispatchQLink - ); - // - // Drop lock for send processing - // - MbbSendQUnlock( SendQueue, DispatchLevel ); - // - // Add NetBuffers from the NetBufferList to the NTB - // - if( (NdisStatus = MbbNtbAddNbl( - NtbContext, - NblContext->NetBufferList - )) == NDIS_STATUS_SUCCESS ) - { - // - // If all NBs in the current NBL can be - // added to the NTB, then try another NBL. - // - } - else if( NdisStatus == NDIS_STATUS_BUFFER_OVERFLOW ) - { - // - // If the NTB was empty and this NBL couldnt be added - // then fail the NBL to prevent retrying forever. - // If all NBs in the current NBL couldnt be - // added then requeue the NBL to the head of the queue. - // - if( NtbContext->DatagramCount == 0 ) - { - TraceError( WMBCLASS_SEND, "[Send][Seq=0x%04x][NBL=0x%p] FAILED to add NBL to empty NTB, status=%!STATUS!", - MBB_NTB_GET_SEQUENCE( &NtbContext->Nth32 ), - NblContext->NetBufferList, - NdisStatus - ); - CompleteNBs = TRUE; - } - else - { - MbbSendQLock( SendQueue, DispatchLevel ); - InsertHeadList( &SendQueue->NblDispatchQueue, &NblContext->DispatchQLink ); - MbbSendQUnlock( SendQueue, DispatchLevel ); - } - } - else - { - TraceError( WMBCLASS_SEND, "[Send][Seq=0x%04x][NBL=0x%p] FAILED to send NBL, status=%!STATUS!", - MBB_NTB_GET_SEQUENCE( &NtbContext->Nth32 ), - NblContext->NetBufferList, - NdisStatus - ); - CompleteNBs = TRUE; - } - // - // If the call failed for complete the remaining NBs with failure. - // - if( CompleteNBs ) - { - MbbNblFinalizeContext( - NblContext->NetBufferList, - NblContext->NbTotalCount - NblContext->NbDispatchCount, - NdisStatus - ); - } - // - // Reacquire lock for re-evaluating the send queue. - // - MbbSendQLock( SendQueue, DispatchLevel ); - } - MbbSendQUnlock( SendQueue, DispatchLevel ); - // - // Send this NTB to the bus and continue processing other requests. - // - if( NtbContext != NULL ) - { - if( NtbContext->DatagramCount > 0 ) - { - MbbNtbAddNdpHeaders( NtbContext ); -#if DBG - if( MbbTestValidateNtb( - NtbContext, - SendQueue->ScratchBuffer, - SendQueue->ScratchLength - ) != NDIS_STATUS_SUCCESS ) - { - ASSERT( FALSE ); - TraceError( WMBCLASS_SEND, "[Send][Seq=0x%04x] FAILED NTB validation, sending anyway", MBB_NTB_GET_SEQUENCE( &NtbContext->Nth32 ) ); - } -#endif - // - // Send the data. On failure, cleanup. - // - NtStatus = MbbBusWriteData( - SendQueue->BusHandle, - NtbContext, - MbbNtbGetMdlChainHead( NtbContext ), - MbbSendQCompleteNtb - ); - } - else - { - TraceError( WMBCLASS_SEND, "[Send][Seq=0x%04x] NTB has no datagrams", MBB_NTB_GET_SEQUENCE( &NtbContext->Nth32 ) ); - NtStatus = STATUS_UNSUCCESSFUL; - } - - if( ! NT_SUCCESS( NtStatus ) ) - { - MbbSendQCompleteNtb( - SendQueue->AdapterContext, - NtbContext, - NtStatus, - MbbNtbGetMdlChainHead( NtbContext ) - ); - } - } - if( AbortDataQueue == TRUE ) - { - MbbSendQCancel( SendQueue, NdisStatus, FALSE ); - } - // - // Reacquire lock for re-evaluating the send queue. - // - MbbSendQLock( SendQueue, DispatchLevel ); - } - // - // Processing complete - // - SendQueue->ProcessingQueue = FALSE; - MbbSendQUnlock( SendQueue, DispatchLevel ); -} - -_Requires_lock_held_(SendQueue->Lock) -NDIS_STATUS -MbbSendQQueueNbl( - __in PMBB_SEND_QUEUE SendQueue, - __in PNET_BUFFER_LIST NetBufferList, - __in ULONG SessionId - ) -{ - PMBB_NBL_CONTEXT NblContext; - - if( (NblContext = MbbNblAllocateContext( - NetBufferList, - &SendQueue->NblLookasideList, - &SendQueue->NbLookasideList, - MbbSendQDequeueNbl, - SendQueue - )) == NULL ) - { - TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] FAILED to allocated context", NetBufferList ); - return NDIS_STATUS_RESOURCES; - } - - // Set the session Id - NblContext->SessionId = SessionId; - - if( IsListEmpty( &SendQueue->NblTrackList ) ) - KeResetEvent( &SendQueue->NblQueueEmptyEvent ); - - InsertTailList( &SendQueue->NblTrackList, &NblContext->NblQLink ); - InsertTailList( &SendQueue->NblDispatchQueue, &NblContext->DispatchQLink ); - - MbbWriteEvent( - &NBL_QUEUED_EVENT, - NULL, - NULL, - 2, - &SendQueue->AdapterContext->TraceInstance, - sizeof(SendQueue->AdapterContext->TraceInstance), - &NetBufferList, - sizeof(NetBufferList) - ); - - return NDIS_STATUS_SUCCESS; -} - -VOID -MbbSendQDequeueNbl( - __in PNET_BUFFER_LIST NetBufferList, - __in PVOID Context - ) -{ - PMBB_SEND_QUEUE SendQueue = (PMBB_SEND_QUEUE)Context; - PMBB_NBL_CONTEXT NblContext = (PMBB_NBL_CONTEXT)NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; - - NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0] = NULL; - - if( NetBufferList->Status != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] Completed with failed NdisStatus=%!STATUS!", - NetBufferList, - NetBufferList->Status - ); - } - else - { - PNET_BUFFER NetBuffer; - for( NetBuffer = NET_BUFFER_LIST_FIRST_NB( NetBufferList ); - NetBuffer != NULL; - NetBuffer = NET_BUFFER_NEXT_NB( NetBuffer ) ) - { - InterlockedAdd64(&SendQueue->AdapterContext->Stats.ifHCOutOctets, NET_BUFFER_DATA_LENGTH(NetBuffer)); - InterlockedIncrement64(&SendQueue->AdapterContext->GenXmitFramesOk); - } - } - - NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0] = NULL; - NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[1] = NblContext; - - MbbWriteEvent( - &NBL_COMPLETED_EVENT, - NULL, - NULL, - 3, - &SendQueue->AdapterContext->TraceInstance, - sizeof(SendQueue->AdapterContext->TraceInstance), - &NetBufferList, - sizeof(NetBufferList), - &NetBufferList->Status, - sizeof(NetBufferList->Status) - ); - - NdisMSendNetBufferListsComplete( - SendQueue->AdapterContext->MiniportAdapterHandle, - NetBufferList, - 0 - ); - DrainRelease( &SendQueue->QueueDrainObject ); - - MbbSendQLock(SendQueue, FALSE); - if (RemoveEntryList(&NblContext->NblQLink)) - KeSetEvent(&SendQueue->NblQueueEmptyEvent, 0, FALSE); - MbbSendQUnlock(SendQueue, FALSE); -} - -VOID -MbbSendQCompleteNtb( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in MBB_REQUEST_HANDLE RequestHandle, - __in NTSTATUS NtStatus, - __in PMDL Mdl - ) -{ - PMBB_SEND_QUEUE SendQueue = &((PMINIPORT_ADAPTER_CONTEXT)ProtocolHandle)->SendQueue; - PMBB_NTB_BUILD_CONTEXT NtbContext = (PMBB_NTB_BUILD_CONTEXT)RequestHandle; - PSTATE_CHANGE_EVENT StateChange=NULL; - - UNREFERENCED_PARAMETER( Mdl ); - - if (!NT_SUCCESS(NtStatus)) - { - if (NtStatus == STATUS_NDIS_ADAPTER_NOT_READY) - { - TraceError(WMBCLASS_SEND, "%!FUNC!: MbbSendQCompleteNtb failed because the data pipes is being reset"); - } - else if (NtStatus == STATUS_CANCELLED) - { - TraceWarn(WMBCLASS_SEND, "%!FUNC!: MbbSendQCompleteNtb failed because the request is cancelled"); - } - else - { - if (InterlockedExchange((LONG*)&SendQueue->LastDataPathTelemetryStatus, MbbDataPathTelmetryStatusReportHang) != MbbDataPathTelmetryStatusReportHang) - { - TraceLoggingWrite( - g_hLoggingProvider, - "WmbclassTxDataPathStatus", - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), - TraceLoggingWideString(L"Hung", "Status") - ); - } - TraceError(WMBCLASS_SEND, "%!FUNC!: MbbSendQCompleteNtb failed with %!STATUS!, data pipe will restart", NtStatus); - TryQueueStallState(SendQueue); - } - } - else - { - if (InterlockedExchange((LONG*)&SendQueue->LastDataPathTelemetryStatus, MbbDataPathTelmetryStatusReportSuccess) != MbbDataPathTelmetryStatusReportSuccess) - { - TraceLoggingWrite( - g_hLoggingProvider, - "WmbclassTxDataPathStatus", - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), - TraceLoggingWideString(L"Success", "Status") - ); - } - } - - MbbSendQLock( SendQueue, FALSE ); - RemoveEntryList( &NtbContext->NtbQLink ); - SendQueue->ConcurrentSends--; - MbbSendQUnlock( SendQueue, FALSE ); - - MbbNtbCleanupContext( - NtbContext, - NtStatus - ); - MbbSendQProcess( SendQueue, FALSE ); -} - - -// -// TODO: Needs to be called from Adapter reset -// -FORCEINLINE -VOID -MbbSendQResetNtbSequence( - __in PMBB_SEND_QUEUE SendQueue - ) -{ - InterlockedExchange( &SendQueue->NtbSequence, 0 ); -} - -FORCEINLINE -ULONG -MbbSendQGetNtbSequence( - __in PMBB_SEND_QUEUE SendQueue - ) -{ - return InterlockedIncrement( &SendQueue->NtbSequence ); -} - -// -// NTB Context -// - -PMBB_NTB_BUILD_CONTEXT -MbbNtbAllocateContext( - __in NDIS_HANDLE MiniportHandle, - __in PNPAGED_LOOKASIDE_LIST NtbLookasideList, - __in PMBB_BUS_PARAMETERS BusParams, - __in PVOID PaddingBuffer, - __in ULONG NtbSequence - ) -{ - MBB_NDP_TYPE NdpType; - ULONG DatagramEntryIndex; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG NtbSize; - PMBB_NTB_BUILD_CONTEXT NtbContext; - - do - { - NtbSize = FIELD_OFFSET(MBB_NTB_BUILD_CONTEXT,NdpDatagramEntries); - NtbSize += (BusParams->MaxOutDatagrams * sizeof(MBB_NDP_HEADER_ENTRY)); -#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate ntb context from lookaside pool, released when send queue completes.") - if( (NtbContext = ALLOCATE_LOOKASIDE( NtbLookasideList )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - RtlZeroMemory( NtbContext, NtbSize ); - NtbContext->MiniportHandle = MiniportHandle; - NtbContext->PaddingBuffer = PaddingBuffer; - NtbContext->NtbLookasideList = NtbLookasideList; - // - // Initialize the NTH and the NTH MDL. - // - if( (NtbContext->IsNtb32Bit = BusParams->CurrentMode32Bit) == TRUE ) - { - if( (NtbContext->NthMdl = NdisAllocateMdl( - MiniportHandle, - &NtbContext->Nth32, - sizeof(NtbContext->Nth32) - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - NtbContext->Nth32.dwSignature = NCM_NTH32_SIG; - NtbContext->Nth32.wHeaderLength = sizeof(NCM_NTH32); - NtbContext->Nth32.wSequence = (USHORT)NtbSequence; - - NtbContext->NtbHeaderSize = sizeof(NCM_NTH32); - NtbContext->NdpHeaderFixedSize = sizeof(NCM_NDP32); - NtbContext->NdpDatagramEntrySize = sizeof(NCM_NDP32_DATAGRAM); - } - else - { - if( (NtbContext->NthMdl = NdisAllocateMdl( - MiniportHandle, - &NtbContext->Nth16, - sizeof(NtbContext->Nth16) - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - NtbContext->Nth16.dwSignature = NCM_NTH16_SIG; - NtbContext->Nth16.wHeaderLength = sizeof(NCM_NTH16); - NtbContext->Nth16.wSequence = (USHORT)NtbSequence; - - NtbContext->NtbHeaderSize = sizeof(NCM_NTH16); - NtbContext->NdpHeaderFixedSize = sizeof(NCM_NDP16); - NtbContext->NdpDatagramEntrySize = sizeof(NCM_NDP16_DATAGRAM); - } - // - // Initialize NextEntryIndex - // - for( NdpType = 0; - NdpType < MbbNdpTypeMax; - NdpType++ ) - { - NtbContext->NdpFirstDatagramEntry[NdpType] = MBB_NDP_DATAGRAM_INDEX_INVALID; - } - for( DatagramEntryIndex = 0; - DatagramEntryIndex < BusParams->MaxOutDatagrams; - DatagramEntryIndex ++ ) - { - NtbContext->NdpDatagramEntries[DatagramEntryIndex].NextEntryIndex = MBB_NDP_DATAGRAM_INDEX_INVALID; - } - - NtbContext->NtbOutMaxSize = BusParams->MaxOutNtb; - NtbContext->NtbOutMaxDatagrams = BusParams->MaxOutDatagrams; - NtbContext->NdpOutDivisor = BusParams->NdpOutDivisor; - NtbContext->NdpOutPayloadRemainder = BusParams->NdpOutRemainder; - NtbContext->NdpOutAlignment = BusParams->NdpOutAlignment; - } - while( FALSE ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - if( NtbContext != NULL ) - { - MbbNtbCleanupContext( NtbContext, NdisStatus ); - } - NtbContext = NULL; - } - return NtbContext; -} - -VOID -MbbNtbCleanupContext( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in NTSTATUS NtStatus - ) -{ - ULONG DatagramIndex; - PNET_BUFFER NetBuffer; - PNET_BUFFER_LIST NetBufferList; - - for( DatagramIndex = 0; - DatagramIndex < NtbContext->DatagramCount; - DatagramIndex ++ ) - { - NetBuffer = NtbContext->NdpDatagramEntries[DatagramIndex].NetBuffer; - NetBufferList = NtbContext->NdpDatagramEntries[DatagramIndex].NetBufferList; - - MbbNbCleanupContext( NetBuffer ); - MbbNblFinalizeContext( NetBufferList, 1, NtStatus ); - } - if( NtbContext->NdpMdl != NULL ) - { - NdisFreeMdl( NtbContext->NdpMdl ); - } - if( NtbContext->NthMdl != NULL ) - { - NdisFreeMdl( NtbContext->NthMdl ); - } - if( NtbContext->NdpBuffer != NULL ) - { - FREE_POOL( NtbContext->NdpBuffer ); - } - FREE_LOOKASIDE( NtbContext, NtbContext->NtbLookasideList ); -} - -NDIS_STATUS -MbbNtbAddNbl( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in PNET_BUFFER_LIST NetBufferList - ) -{ - ULONG NbIndex; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PNET_BUFFER NetBuffer; - MBB_NDP_TYPE CurrentNdpType; - PMBB_NBL_CONTEXT NblContext = NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList)[0]; - ULONG SessionId = MBB_DEFAULT_SESSION_ID; - do - { - // - // Pick the NDP type. NoCRC, CRC are not yet used. - // - if (MbbNblContextIsDssData(NblContext)) - { - SessionId = NblContext->DssSessionId; - - // Vendor NDP. Determine if we are already have a NDP for - // this session ID. If yes, add this datagram into that NDP. Else - // assign new NDP for this datagram - for( CurrentNdpType = MbbNdpTypeVendor_1; - CurrentNdpType <= MbbNdpTypeVendor_Max; - CurrentNdpType ++ ) - { - if( NtbContext->NdpFirstDatagramEntry[CurrentNdpType] != MBB_NDP_DATAGRAM_INDEX_INVALID ) - { - // Entry is used. Does it match the session ID I am using? - if (NtbContext->NdpDatagramEntries[NtbContext->NdpFirstDatagramEntry[CurrentNdpType]].SessionId - == SessionId) - { - // Matching session ID. We can use this type - break; - } - } - else - { - // Entry is not used. We will use it - break; - } - } - - if (CurrentNdpType > MbbNdpTypeVendor_Max) - { - // Didnt find an empty slot in this NTB - NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; - break; - } - } - else - { - CurrentNdpType = MbbNdpTypeIps; - - SessionId = NblContext->SessionId; - - ASSERT(NblContext->SessionId != MBB_INVALID_SESSION_ID); - - if( NtbContext->NdpFirstDatagramEntry[CurrentNdpType] != MBB_NDP_DATAGRAM_INDEX_INVALID ) - { - if(NtbContext->NdpDatagramEntries[NtbContext->NdpFirstDatagramEntry[CurrentNdpType]].SessionId - != SessionId) - { - NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; - break; - } - } - } - - // - // Add as many NBs as can fit. - // - for( NetBuffer = MbbNblGetNextDispatchNb( NetBufferList ); - NetBuffer != NULL; - NetBuffer = MbbNblAdvanceDispatchNb( NetBufferList ) ) - { - if( (NdisStatus = MbbNtbAddNb( - NtbContext, - NblContext->NbLookasideList, - NetBuffer, - NetBufferList, - CurrentNdpType, - SessionId - )) != NDIS_STATUS_SUCCESS ) - { - break; - } - } - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbNtbAddNb( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in PNPAGED_LOOKASIDE_LIST NbLookasideList, - __in PNET_BUFFER NetBuffer, - __in PNET_BUFFER_LIST NetBufferList, - __in MBB_NDP_TYPE CurrentNdpType, - __in ULONG SessionId - ) -{ - ULONG DatagramLength; - ULONG DatagramOffset; - ULONG PaddingLength; - ULONG NdpSize; - ULONG NdpIndex; - PMBB_NB_CONTEXT NbContext = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG TotalLength; - ULONG CurrentNdpLastEntryIndex = MBB_NDP_DATAGRAM_INDEX_INVALID; - - do - { - if( (NtbContext->DatagramCount + 1) > NtbContext->NtbOutMaxDatagrams ) - { - NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; - break; - } - - // - // Size of passed in NET_BUFFER, to be updated later in the NDP Context. - // - TotalLength = NtbContext->NtbHeaderSize + NtbContext->DatagramLength; - DatagramLength = NET_BUFFER_DATA_LENGTH( NetBuffer ); - PaddingLength = ALIGN_AT_OFFSET( - TotalLength, - NtbContext->NdpOutDivisor, - NtbContext->NdpOutPayloadRemainder - ) - TotalLength; - // - // Calculate the new NTB size based on the passed in NET_BUFFER - // - - // - // Fixed size NTH & DatagramSize along with Padding for all NDPs - // - DatagramOffset = TotalLength + PaddingLength; - TotalLength += DatagramLength + PaddingLength; - // - // Calculate NDP HeaderSize for all NDPs - // - NdpSize = TotalLength; - for( NdpIndex = 0; - NdpIndex < MbbNdpTypeMax; - NdpIndex ++ ) - { - ULONG NdpDatagramCount = ( NdpIndex == CurrentNdpType )? 1: 0; - ULONG NextEntryIndex = NtbContext->NdpFirstDatagramEntry[NdpIndex]; - - while( NextEntryIndex != MBB_NDP_DATAGRAM_INDEX_INVALID ) - { - if( NdpIndex == CurrentNdpType ) - CurrentNdpLastEntryIndex = NextEntryIndex; - - NdpDatagramCount++; - NextEntryIndex = NtbContext->NdpDatagramEntries[NextEntryIndex].NextEntryIndex; - } - - if( NdpDatagramCount != 0 ) - { - TotalLength = ALIGN( TotalLength, NtbContext->NdpOutAlignment ); - TotalLength += NtbContext->NdpHeaderFixedSize; - TotalLength += (NdpDatagramCount * NtbContext->NdpDatagramEntrySize); - } - } - NdpSize = TotalLength - NdpSize; - // - // Can everything fit? - // - if( TotalLength > NtbContext->NtbOutMaxSize ) - { - NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; - break; - } - if( (NbContext = MbbNbAllocateContext( - NetBuffer, - DatagramLength, - NtbContext->PaddingBuffer, - PaddingLength, - NbLookasideList, - NtbContext->MiniportHandle - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - // - // Update the NTB Context for the new NET_BUFFER. - // - NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].DatagramOffset = DatagramOffset; - NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].DatagramLength = DatagramLength; - NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NdpType = CurrentNdpType; - NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].SessionId = SessionId; - NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NetBuffer = NetBuffer; - NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NetBufferList = NetBufferList; - - if( CurrentNdpLastEntryIndex != MBB_NDP_DATAGRAM_INDEX_INVALID ) - NtbContext->NdpDatagramEntries[CurrentNdpLastEntryIndex].NextEntryIndex = NtbContext->DatagramCount; - - if( NtbContext->NdpFirstDatagramEntry[CurrentNdpType] == MBB_NDP_DATAGRAM_INDEX_INVALID ) - NtbContext->NdpFirstDatagramEntry[CurrentNdpType] = NtbContext->DatagramCount; - - NtbContext->NdpSize = NdpSize; - NtbContext->DatagramCount += 1; - NtbContext->DatagramLength += (DatagramLength + PaddingLength); - - MbbNtbChainNb( NtbContext, NetBuffer ); - } - while( FALSE ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - if( NbContext != NULL ) - MbbNbCleanupContext( NetBuffer ); - } - return NdisStatus; -} - -VOID -MbbNtbChainNb( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in PNET_BUFFER NetBuffer - ) -{ - PMDL MdlToChain; - - if( NtbContext->DatagramLastMdl != NULL ) - { - TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Chaining Mdl=0x%p -> Mdl=0x%p", - NetBuffer, NtbContext->DatagramLastMdl, MbbNbGetFirstMdl( NetBuffer ) - ); - NtbContext->DatagramLastMdl->Next = MbbNbGetFirstMdl( NetBuffer ); - } - else - { - TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Chaining Mdl=0x%p -> Mdl=0x%p", - NetBuffer, NtbContext->NthMdl, MbbNbGetFirstMdl( NetBuffer ) - ); - NtbContext->NthMdl->Next = MbbNbGetFirstMdl( NetBuffer ); - } - - NtbContext->DatagramLastMdl = MbbNbGetLastMdl( NetBuffer ); -} - -ULONG -MbbNtbMapNdpTypeToSignature( - __in MBB_NDP_TYPE MbbNdpType, - __in BOOLEAN Is32Bit, - __in ULONG SessionId - ) -{ - ULONG SessionMask = ( SessionId << NCM_NDP_SESSION_SHIFT ); - - switch( MbbNdpType ) - { - case MbbNdpTypeIps : return (( Is32Bit==TRUE )? NCM_NDP32_IPS | SessionMask - : NCM_NDP16_IPS | SessionMask); - default : - if ((MbbNdpType >= MbbNdpTypeVendor_1) && (MbbNdpType <= MbbNdpTypeVendor_Max)) - { - return (( Is32Bit==TRUE )? NCM_NDP32_VENDOR | SessionMask - : NCM_NDP16_VENDOR | SessionMask); - } - } - return 0; -} - -VOID -MbbNtbFillNdp32Header( - __in PNCM_NDP32 Ndp, - __in MBB_NDP_TYPE NdpType, - __in PMBB_NTB_BUILD_CONTEXT NtbContext - ) -{ - ULONG DatagramIndex; - ULONG NdpDatagramCount; - ULONG NdpDatagramIndex; - PNCM_NDP32_DATAGRAM NdpDatagramEntries; - - DatagramIndex = NtbContext->NdpFirstDatagramEntry[NdpType]; - - // Caller ensured we are OK here - ASSERT(DatagramIndex != MBB_NDP_DATAGRAM_INDEX_INVALID); - - Ndp->dwSignature = MbbNtbMapNdpTypeToSignature( - NdpType, - TRUE, - NtbContext->NdpDatagramEntries[DatagramIndex].SessionId - ); - Ndp->dwNextFpIndex = 0; - NdpDatagramEntries = Ndp->Datagram; - // - // Add datagram entries to the NDP Table - // - NdpDatagramIndex = 0; - NdpDatagramCount = 0; - - for( DatagramIndex = NtbContext->NdpFirstDatagramEntry[NdpType]; - DatagramIndex != MBB_NDP_DATAGRAM_INDEX_INVALID; - DatagramIndex = NtbContext->NdpDatagramEntries[DatagramIndex].NextEntryIndex ) - { - NdpDatagramEntries[NdpDatagramIndex].dwDatagramIndex = NtbContext->NdpDatagramEntries[DatagramIndex].DatagramOffset; - NdpDatagramEntries[NdpDatagramIndex].dwDatagramLength = NtbContext->NdpDatagramEntries[DatagramIndex].DatagramLength; - NdpDatagramIndex++; - NdpDatagramCount++; - } - // - // Terminating entry is taken in to account - // in the fixed size NDP Header. - // - NdpDatagramEntries[NdpDatagramIndex].dwDatagramIndex = 0; - NdpDatagramEntries[NdpDatagramIndex].dwDatagramLength = 0; - - Ndp->wLength = (USHORT)(NtbContext->NdpHeaderFixedSize + (NdpDatagramIndex * NtbContext->NdpDatagramEntrySize)); -} - -VOID -MbbNtbFillNdp16Header( - __in PNCM_NDP16 Ndp, - __in MBB_NDP_TYPE NdpType, - __in PMBB_NTB_BUILD_CONTEXT NtbContext - ) -{ - ULONG DatagramIndex; - ULONG NdpDatagramCount; - ULONG NdpDatagramIndex; - PNCM_NDP16_DATAGRAM NdpDatagramEntries; - - DatagramIndex = NtbContext->NdpFirstDatagramEntry[NdpType]; - - // Caller ensured we are OK here - ASSERT(DatagramIndex != MBB_NDP_DATAGRAM_INDEX_INVALID); - - Ndp->dwSignature = MbbNtbMapNdpTypeToSignature( - NdpType, - FALSE, - NtbContext->NdpDatagramEntries[DatagramIndex].SessionId - ); - - Ndp->wNextFpIndex = 0; - NdpDatagramEntries = Ndp->Datagram; - // - // Add datagram entries to the NDP Table - // - NdpDatagramIndex = 0; - NdpDatagramCount = 0; - - for( DatagramIndex = NtbContext->NdpFirstDatagramEntry[NdpType]; - DatagramIndex != MBB_NDP_DATAGRAM_INDEX_INVALID; - DatagramIndex = NtbContext->NdpDatagramEntries[DatagramIndex].NextEntryIndex ) - { - NdpDatagramEntries[NdpDatagramIndex].wDatagramIndex = (USHORT)NtbContext->NdpDatagramEntries[DatagramIndex].DatagramOffset; - NdpDatagramEntries[NdpDatagramIndex].wDatagramLength = (USHORT)NtbContext->NdpDatagramEntries[DatagramIndex].DatagramLength; - NdpDatagramIndex++; - NdpDatagramCount++; - } - // - // Terminating entry is taken in to account - // in the fixed size NDP Header. - // - NdpDatagramEntries[NdpDatagramIndex].wDatagramIndex = 0; - NdpDatagramEntries[NdpDatagramIndex].wDatagramLength = 0; - - Ndp->wLength = (USHORT)(NtbContext->NdpHeaderFixedSize + (NdpDatagramCount * NtbContext->NdpDatagramEntrySize)); -} - -NDIS_STATUS -MbbNtbAddNdpHeaders( - __in PMBB_NTB_BUILD_CONTEXT NtbContext - ) -{ - // Offset from the start of the NTB buffer to the start of NDP headers - ULONG NdpStartOffset; - // Offset from the start of the NTB Buffer to the current position. - ULONG NtbOffset; - PCHAR NdpBuffer; - MBB_NDP_TYPE NdpType; - PNCM_NDP16 Ndp16; - PNCM_NDP32 Ndp32; - PNCM_NDP16 PreviousNdp16 = NULL; - PNCM_NDP32 PreviousNdp32 = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - do - { - // - // Allocate buffer for all NDP headers. - // This includes padding for NDP Header alignment. - // - if( (NtbContext->NdpBuffer = ALLOCATE_NONPAGED_POOL( - NtbContext->NdpSize - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - NdpBuffer = (PCHAR)(NtbContext->NdpBuffer); - // - // Chain the NDP Header through its MDL to datagram MDL - // - if( (NtbContext->NdpMdl = NdisAllocateMdl( - NtbContext->MiniportHandle, - NtbContext->NdpBuffer, - NtbContext->NdpSize - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - NtbContext->DatagramLastMdl->Next = NtbContext->NdpMdl; - NdpStartOffset = NtbContext->NtbHeaderSize + NtbContext->DatagramLength; - - if( NtbContext->IsNtb32Bit ) - NtbContext->Nth32.dwFpIndex = ALIGN( NdpStartOffset, NtbContext->NdpOutAlignment ); - else - NtbContext->Nth16.wFpIndex = (USHORT)ALIGN( NdpStartOffset, NtbContext->NdpOutAlignment ); - - NtbOffset = NdpStartOffset; - - for( NdpType = 0; - NdpType < MbbNdpTypeMax; - NdpType ++ ) - { - if( NtbContext->NdpFirstDatagramEntry[NdpType] == MBB_NDP_DATAGRAM_INDEX_INVALID ) - continue; - - NtbOffset = ALIGN( NtbOffset, NtbContext->NdpOutAlignment ); - - if( NtbContext->IsNtb32Bit == TRUE ) - { - Ndp32 = (PNCM_NDP32)(NdpBuffer + (NtbOffset - NdpStartOffset)); - - MbbNtbFillNdp32Header( - Ndp32, - NdpType, - NtbContext - ); - - if( PreviousNdp32 != NULL ) - PreviousNdp32->dwNextFpIndex = NtbOffset; - - NtbOffset += Ndp32->wLength; - PreviousNdp32 = Ndp32; - } - else - { - Ndp16 = (PNCM_NDP16)(NdpBuffer + (NtbOffset - NdpStartOffset)); - - MbbNtbFillNdp16Header( - Ndp16, - NdpType, - NtbContext - ); - - if( PreviousNdp16 != NULL ) - PreviousNdp16->wNextFpIndex = (USHORT)NtbOffset; - - NtbOffset += Ndp16->wLength; - PreviousNdp16 = Ndp16; - } - } - - if( NtbContext->IsNtb32Bit == TRUE ) - { - NtbContext->Nth32.dwBlockLength = NtbContext->NtbHeaderSize; - NtbContext->Nth32.dwBlockLength += NtbContext->DatagramLength; - NtbContext->Nth32.dwBlockLength += NtbContext->NdpSize; - } - else - { - NtbContext->Nth16.wBlockLength = (USHORT)(NtbContext->NtbHeaderSize); - NtbContext->Nth16.wBlockLength += (USHORT)(NtbContext->DatagramLength); - NtbContext->Nth16.wBlockLength += (USHORT)(NtbContext->NdpSize); - } - } - while( FALSE ); - // - // No cleanup. Cleanup done by caller. - // - return NdisStatus; -} - -FORCEINLINE -PMDL -MbbNtbGetMdlChainHead( - __in PMBB_NTB_BUILD_CONTEXT NtbContext - ) -{ - return NtbContext->NthMdl; -} - -// Test -#if DBG -NDIS_STATUS -MbbTestValidateNtb( - __in PMBB_NTB_BUILD_CONTEXT NtbContext, - __in_bcount(ScratchLength) PCHAR ScratchBuffer, - __in ULONG ScratchLength - ) -{ - PMDL CurrentMdl; - ULONGLONG NtbLength; - ULONG MdlLength; - PVOID MdlVa; - PVOID Nth; - - Nth = ScratchBuffer; - NtbLength = 0; - - for( CurrentMdl = MbbNtbGetMdlChainHead( NtbContext ); - CurrentMdl != NULL; - CurrentMdl = CurrentMdl->Next ) - { - MdlLength = MmGetMdlByteCount( CurrentMdl ); - - if( (MdlVa = MmGetSystemAddressForMdlSafe( - CurrentMdl, - NormalPagePriority | MdlMappingNoExecute - )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - if( (NtbLength+MdlLength) > ScratchLength ) - { - return NDIS_STATUS_BUFFER_OVERFLOW; - } - - RtlCopyMemory( ScratchBuffer, MdlVa, MdlLength ); - - ScratchBuffer += MdlLength; - NtbLength += MdlLength; - } - - return MbbNtbValidate( - Nth, - (ULONG)NtbLength, - NtbContext->IsNtb32Bit - ); -} -#endif - -// -// NB Context -// - -PMBB_NB_CONTEXT -MbbNbAllocateContext( - __in PNET_BUFFER NetBuffer, - __in ULONG DatagramLength, - __in PVOID PaddingBuffer, - __in ULONG PaddingLength, - __in PNPAGED_LOOKASIDE_LIST NbLookasideList, - __in NDIS_HANDLE MiniportHandle - ) -{ - PMDL NbDataStartMdl = NET_BUFFER_CURRENT_MDL( NetBuffer ); - ULONG NbDataStartMdlDataOffset = NET_BUFFER_CURRENT_MDL_OFFSET( NetBuffer ); - ULONG NbDataStartMdlDataLength; - PCHAR NbDataStartBuffer; - PMDL NbDataEndMdl; - ULONG NbDataEndMdlDataLength; - PCHAR NbDataEndBuffer; - PMDL NbMdl; - ULONG NbMdlOffset; - ULONG NbMdlLength; - PMDL NbPenultimateMdl; - PMBB_NB_CONTEXT NbContext = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - do - { - // - // Allocate the NbContext - // - if( (NbContext = ALLOCATE_LOOKASIDE(NbLookasideList)) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - RtlZeroMemory( NbContext, sizeof(MBB_NB_CONTEXT) ); - NbContext->NbLookasideList = NbLookasideList; - - NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0] = NbContext; - - if( (NbDataStartBuffer = (PCHAR) MmGetSystemAddressForMdlSafe( - NbDataStartMdl, - NormalPagePriority | MdlMappingNoExecute - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - NbDataStartBuffer += NbDataStartMdlDataOffset; - // - // Create new DataStart and DataEnd Mdls - // to remove the unused data space. - // - NbDataStartMdlDataLength = MmGetMdlByteCount( NbDataStartMdl ); - NbDataStartMdlDataLength -= NbDataStartMdlDataOffset; - - if( (NbContext->DataStartMdl = NdisAllocateMdl( - MiniportHandle, - NbDataStartBuffer, - MIN( DatagramLength, NbDataStartMdlDataLength ) - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Creating DataStartMdl[OrigMdl=0x%p,NewMdl=0x%p]", NetBuffer, NbDataStartMdl, NbContext->DataStartMdl ); - NbContext->DataStartMdl->Next = NbDataStartMdl->Next; - // - // Find the end MDL and the amount of data in the end MDL - // - NbMdl = NbDataStartMdl; - NbMdlOffset = NbDataStartMdlDataOffset; - NbPenultimateMdl = NULL; - - for( NbDataEndMdlDataLength = DatagramLength; - NbDataEndMdlDataLength > (MmGetMdlByteCount( NbMdl ) - NbMdlOffset); - NbDataEndMdlDataLength -= NbMdlLength ) - { - NbPenultimateMdl = NbMdl; - NbMdlLength = MmGetMdlByteCount( NbMdl ) - NbMdlOffset; - NbMdlOffset = 0; - NbMdl = NbMdl->Next; - } - NbDataEndMdl = NbMdl; - // - // If the starting and ending MDLs are not the same - // then build another partial MDL removing any unused - // data space. - // - if( NbDataEndMdl != NbDataStartMdl ) - { - if( (NbDataEndBuffer = MmGetSystemAddressForMdlSafe( - NbDataEndMdl, - NormalPagePriority | MdlMappingNoExecute - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - if( (NbContext->DataEndMdl = NdisAllocateMdl( - MiniportHandle, - NbDataEndBuffer, - NbDataEndMdlDataLength - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Creating DataEndMdl[OrigMdl=0x%p,NewMdl=0x%p]", NetBuffer, NbDataEndMdl, NbContext->DataEndMdl ); - NbContext->DataEndMdl->Next = NULL; - - if( NbPenultimateMdl != NbDataStartMdl ) - { - MDL TempMdl = *NbPenultimateMdl; - TempMdl.Next = NbContext->DataEndMdl; - - MbbNbSaveAndSetMdl( - NetBuffer, - NbPenultimateMdl, - &TempMdl - ); - } - - if( NbContext->DataStartMdl->Next == NbDataEndMdl ) - { - NbContext->DataStartMdl->Next = NbContext->DataEndMdl; - } - } - // - // Allocate padding, if needed. The padding buffer is a share buffer. - // Every padding MDL points to this same buffer. The buffer contains - // all 0s. - // - if( PaddingLength != 0 ) - { - if( (NbContext->PaddingMdl = NdisAllocateMdl( - MiniportHandle, - PaddingBuffer, - PaddingLength - )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Creating PaddingMdl=0x%p", NetBuffer, NbContext->PaddingMdl ); - NbContext->PaddingMdl->Next = NbContext->DataStartMdl; - } - } - while( FALSE ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - if( NbContext != NULL ) - { - MbbNbCleanupContext( NetBuffer ); - NbContext = NULL; - } - } - return NbContext; -} - -VOID -MbbNbCleanupContext( - __in PNET_BUFFER NetBuffer - ) -{ - PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; - - MbbNbRestoreMdl( NetBuffer ); - - if( NbContext->PaddingMdl != NULL ) - { - NdisFreeMdl( NbContext->PaddingMdl ); - } - if( NbContext->DataEndMdl != NULL ) - { - NdisFreeMdl( NbContext->DataEndMdl ); - } - if( NbContext->DataStartMdl != NULL ) - { - NdisFreeMdl( NbContext->DataStartMdl ); - } - NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0] = NULL; - NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[1] = NbContext; - - FREE_LOOKASIDE( NbContext, NbContext->NbLookasideList ); -} - -FORCEINLINE -PMDL -MbbNbGetFirstMdl( - __in PNET_BUFFER NetBuffer - ) -{ - PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; - - if( NbContext->PaddingMdl != NULL ) - return NbContext->PaddingMdl; - else - return NbContext->DataStartMdl; -} - -FORCEINLINE -PMDL -MbbNbGetLastMdl( - __in PNET_BUFFER NetBuffer - ) -{ - PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; - - if( NbContext->DataEndMdl != NULL ) - return NbContext->DataEndMdl; - else - return NbContext->DataStartMdl; -} - -VOID -MbbNbSaveAndSetMdl( - __in PNET_BUFFER NetBuffer, - __in PMDL MdlToSave, - __in PMDL MdlToSet - ) -{ - PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; - - if( NbContext->ModifiedMdl == NULL ) - { - NbContext->ModifiedMdl = MdlToSave; - NbContext->OriginalMdl = *MdlToSave; - TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Saving Mdl=0x%p", NetBuffer, NbContext->ModifiedMdl ); - } - *MdlToSave = *MdlToSet; -} - -VOID -MbbNbRestoreMdl( - __in PNET_BUFFER NetBuffer - ) -{ - PMBB_NB_CONTEXT NbContext = (PMBB_NB_CONTEXT)NET_BUFFER_MINIPORT_RESERVED( NetBuffer )[0]; - - if( NbContext->ModifiedMdl != NULL ) - { - TraceVerbose( WMBCLASS_SEND, "[Send][NB=0x%p] Restoring Mdl=0x%p", NetBuffer, NbContext->ModifiedMdl ); - *NbContext->ModifiedMdl = NbContext->OriginalMdl; - NbContext->ModifiedMdl = NULL; - } -} - -// -// NBL Context -// - -PMBB_NBL_CONTEXT -MbbNblAllocateContext( - __in PNET_BUFFER_LIST NetBufferList, - __in PNPAGED_LOOKASIDE_LIST NblLookasideList, - __in PNPAGED_LOOKASIDE_LIST NbLookasideList, - __in MBB_NBL_CLEANUP_CALLBACK CleanupCallback, - __in PVOID CleanupCallbackContext - ) -{ - PMBB_NBL_CONTEXT NblContext = NULL; - PNET_BUFFER NetBuffer; - ULONG NbCount; - - do - { - if( (NblContext = ALLOCATE_LOOKASIDE(NblLookasideList)) == NULL ) - { - break; - } - - InitializeListHead( &NblContext->NblQLink ); - InitializeListHead( &NblContext->DispatchQLink ); - - NblContext->NetBufferList = NetBufferList; - NblContext->NblLookasideList = NblLookasideList; - NblContext->NbLookasideList = NbLookasideList; - - NbCount = 0; - for( NetBuffer = NET_BUFFER_LIST_FIRST_NB( NetBufferList ); - NetBuffer != NULL; - NetBuffer = NET_BUFFER_NEXT_NB( NetBuffer ) ) - { - NbCount++; - } - NblContext->Failed = FALSE; - NblContext->NbTotalCount = NbCount; - NblContext->NbDispatchCount = 0; - NblContext->NbCompleteCount = 0; - NblContext->CleanupCallback = CleanupCallback; - NblContext->CleanupCallbackContext = CleanupCallbackContext; - NblContext->CurrentNb = NET_BUFFER_LIST_FIRST_NB( NetBufferList ); - NblContext->DssRequestHandle = NULL; - NblContext->DssSessionId = (ULONG)(-1); - NblContext->SessionId = MBB_INVALID_SESSION_ID; - - NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList)[0] = NblContext; - } - while( FALSE ); - - return NblContext; -} - -VOID -MbbNblFinalizeContext( - __in PNET_BUFFER_LIST NetBufferList, - __in ULONG NbCount, - __in NTSTATUS NtStatus - ) -{ - PMBB_NBL_CONTEXT NblContext = (PMBB_NBL_CONTEXT)NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; - ULONG OriginalCount; - ULONG NewCount; - - OriginalCount = NblContext->NbCompleteCount; - NewCount = OriginalCount + NbCount; - - while( InterlockedCompareExchange( - &NblContext->NbCompleteCount, - NewCount, - OriginalCount - ) != OriginalCount ) - { - OriginalCount = NblContext->NbCompleteCount; - NewCount = OriginalCount + NbCount; - } - - if( NtStatus != STATUS_SUCCESS ) - { - NblContext->Failed = TRUE; - } - - if( NewCount == NblContext->NbTotalCount ) - { - ASSERT( NblContext->NbCompleteCount == NblContext->NbTotalCount ); - - if( NblContext->Failed == TRUE ) - NetBufferList->Status = NDIS_STATUS_FAILURE; - else - NetBufferList->Status = NDIS_STATUS_SUCCESS; - - NblContext->CleanupCallback( - NetBufferList, - NblContext->CleanupCallbackContext - ); - // - // To catch double completions - // - NblContext->CleanupCallback = MBB_BAD_POINTER; - NblContext->CleanupCallbackContext = MBB_BAD_POINTER; - FREE_LOOKASIDE( NblContext, NblContext->NblLookasideList ); - } -} - -FORCEINLINE -PNET_BUFFER -MbbNblGetNextDispatchNb( - __in PNET_BUFFER_LIST NetBufferList - ) -{ - PMBB_NBL_CONTEXT NblContext = NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; - return NblContext->CurrentNb; -} - -FORCEINLINE -PNET_BUFFER -MbbNblAdvanceDispatchNb( - __in PNET_BUFFER_LIST NetBufferList - ) -{ - PMBB_NBL_CONTEXT NblContext = NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; - - if( NblContext->CurrentNb != NULL ) - { - NblContext->NbDispatchCount++; - NblContext->CurrentNb = NET_BUFFER_NEXT_NB( NblContext->CurrentNb ); - } - return NblContext->CurrentNb; -} - -// -// Miniport handlers -// - -VOID -MbbNdisMiniportSendNetBufferLists( - __in NDIS_HANDLE MiniportAdapterContext, - __in PNET_BUFFER_LIST NetBufferList, - __in NDIS_PORT_NUMBER PortNumber, - __in ULONG SendFlags - ) -{ - NDIS_STATUS NdisStatus; - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - PMBB_SEND_QUEUE SendQueue=&Adapter->SendQueue; - PNET_BUFFER_LIST NextNetBufferList=NULL; - PNET_BUFFER_LIST CurrentNetBufferList; - BOOLEAN DispatchLevel= (SendFlags & NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL) == NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL; - BOOLEAN CompleteNow=FALSE; - ULONG SessionId = MBB_INVALID_SESSION_ID; - PMBB_PORT Port = NULL; - BOOLEAN IsConnected = FALSE; - BOOLEAN CompleteNBLsOnFailure = FALSE; - - - // Get the session id for the corresponding portnumber - Port = MbbWwanTranslatePortNumberToPort( - Adapter, - PortNumber); - - if(!Port) - { - TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] DROPPING all. Received on invalid port %lu", NetBufferList,PortNumber); - CompleteNBLsOnFailure = TRUE; - } - else - { - // Get the connection status and session id for the port. - MBB_ACQUIRE_PORT_LOCK(Port); - - IsConnected = Port->ConnectionState.ConnectionUp; - SessionId = Port->SessionId; - - MBB_RELEASE_PORT_LOCK(Port); - - if(!IsConnected - || SessionId == MBB_INVALID_SESSION_ID ) - { - TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] DROPPING all. Received on disconnected port %lu", NetBufferList, PortNumber); - CompleteNBLsOnFailure = TRUE; - } - } - - if (MbbBusIsFastIO(Adapter->BusHandle) && CompleteNBLsOnFailure == FALSE) - { - USHORT NblContextSize = ALIGN(sizeof(MBB_NBL_TYPE), MEMORY_ALLOCATION_ALIGNMENT); - MBB_NBL_TYPE* NblContext; - for (CurrentNetBufferList = NetBufferList; - CurrentNetBufferList != NULL; - CurrentNetBufferList = NextNetBufferList) - { - if (NdisAllocateNetBufferListContext( - NetBufferList, - NblContextSize, - 0, - MbbPoolTagNblFastIOContext) != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_RECEIVE, "[FastIOSend][DSS NBL=0x%p] FAILED to allocate NetBufferListContext", NetBufferList); - CompleteNBLsOnFailure = TRUE; - break; - } - NblContext = (MBB_NBL_TYPE*)NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); - *NblContext = MBB_NBL_TYPE_IP; - } - } - - if(CompleteNBLsOnFailure) - { - for (CurrentNetBufferList = NetBufferList; - CurrentNetBufferList != NULL; - CurrentNetBufferList = NextNetBufferList) - { - // fail all NBLs - NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(CurrentNetBufferList); - NET_BUFFER_LIST_STATUS(CurrentNetBufferList) = NDIS_STATUS_FAILURE; - - InterlockedIncrement64(&Adapter->Stats.ifOutDiscards); - } - - NdisMSendNetBufferListsComplete( - Adapter->MiniportAdapterHandle, - NetBufferList, - DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0 - ); - } - else if (MbbBusIsFastIO(Adapter->BusHandle)) - { - MbbBusSendNetBufferLists(Adapter->BusHandle, NetBufferList, SessionId, SendFlags); - } - else - { - MbbSendQLock( SendQueue, DispatchLevel ); - - - for( CurrentNetBufferList = NetBufferList; - CurrentNetBufferList != NULL; - CurrentNetBufferList = NextNetBufferList ) - { - NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL( CurrentNetBufferList ); - NET_BUFFER_LIST_NEXT_NBL(CurrentNetBufferList) = NULL; - - CompleteNow = !DrainAddRef( &SendQueue->QueueDrainObject ); - - if( CompleteNow ) - { - CurrentNetBufferList->Status = NDIS_STATUS_PAUSED; - TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] DROPPING", CurrentNetBufferList ); - - MbbSendQUnlock( SendQueue, DispatchLevel ); - - NdisMSendNetBufferListsComplete( - Adapter->MiniportAdapterHandle, - CurrentNetBufferList, - DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0 - ); - - CurrentNetBufferList=NULL; - - InterlockedIncrement64( &Adapter->Stats.ifOutDiscards ); - - MbbSendQLock( SendQueue, DispatchLevel ); - - } - else - { - - if( (NdisStatus = MbbSendQQueueNbl( - SendQueue, - CurrentNetBufferList, - SessionId - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] DROPPING, queuing failed", CurrentNetBufferList ); - CurrentNetBufferList->Status = NdisStatus; - - MbbSendQUnlock( SendQueue, DispatchLevel ); - - NdisMSendNetBufferListsComplete( - Adapter->MiniportAdapterHandle, - CurrentNetBufferList, - DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0 - ); - - // - // a ref was added for this nbl, removed it - // - DrainRelease( &SendQueue->QueueDrainObject ); - - InterlockedIncrement64( &Adapter->Stats.ifOutDiscards ); - MbbSendQLock( SendQueue, DispatchLevel ); - } - CurrentNetBufferList=NULL; - } - } - - MbbSendQUnlock( SendQueue, DispatchLevel ); - - MbbSendQProcess( SendQueue, DispatchLevel ); - - } - - if(Port) - { - //Remove the reference added during find - Dereference(Port); - } - - return; -} - -VOID -MbbNdisMiniportCancelSend( - __in NDIS_HANDLE MiniportAdapterContext, - __in PVOID CancelId - ) -{ - PMINIPORT_ADAPTER_CONTEXT Adapter=(PMINIPORT_ADAPTER_CONTEXT)MiniportAdapterContext; - PMBB_SEND_QUEUE SendQueue=&Adapter->SendQueue; - PLIST_ENTRY ListEntry; - PLIST_ENTRY NextEntry; - LIST_ENTRY TempList; - PMBB_NBL_CONTEXT NblContext = NULL; - - if (MbbBusIsFastIO(Adapter->BusHandle)) - { - MbbBusCancelSendHandler(Adapter->BusHandle, CancelId); - return; - } - - InitializeListHead( &TempList ); - - MbbSendQLock( SendQueue, FALSE ); - for( ListEntry = SendQueue->NblDispatchQueue.Flink; - ListEntry != &SendQueue->NblDispatchQueue; - ListEntry = NextEntry ) - { - NextEntry = ListEntry->Flink; - NblContext = CONTAINING_RECORD( ListEntry, MBB_NBL_CONTEXT, DispatchQLink ); - if( NDIS_GET_NET_BUFFER_LIST_CANCEL_ID( NblContext->NetBufferList ) == CancelId ) - { - RemoveEntryList( ListEntry ); - InsertHeadList( &TempList, ListEntry ); - } - } - MbbSendQUnlock( SendQueue, FALSE ); - - for( ListEntry = TempList.Flink; - ListEntry != &TempList; - ListEntry = NextEntry ) - { - NextEntry = ListEntry->Flink; - RemoveEntryList( ListEntry ); - NblContext = CONTAINING_RECORD( ListEntry, MBB_NBL_CONTEXT, DispatchQLink ); - - TraceInfo( WMBCLASS_SEND, "[Send][NBL=0x%p] Cancelling for CancelId=0x%p", NblContext->NetBufferList, CancelId ); - - MbbNblFinalizeContext( - NblContext->NetBufferList, - NblContext->NbTotalCount - NblContext->NbDispatchCount, - NDIS_STATUS_SEND_ABORTED - ); - } -} - -PNET_BUFFER_LIST -MbbAllocateDssNbl( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_SEND_QUEUE SendQueue, - __in ULONG RequestId, - __in ULONG DataSize, - __in PVOID Data - ) -{ - PMDL Mdl = NULL; - PNET_BUFFER_LIST Nbl = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PVOID CopiedData = NULL; - - do - { - // Make a copy of the data. We need to do this - // since the OID may already be freed -#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate memory for data copy, released when data dequeued from send queue.") - if( (CopiedData = ALLOCATE_NONPAGED_POOL(DataSize)) == NULL) - { - TraceError( WMBCLASS_SEND, "[Send][DSS Write %d] FAILED to create copy of data", RequestId ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - RtlCopyMemory(CopiedData, Data, DataSize); - - if( (Mdl = NdisAllocateMdl( - Adapter->MiniportAdapterHandle, - CopiedData, - DataSize - )) == NULL ) - { - TraceError( WMBCLASS_SEND, "[Send][DSS Write %d] FAILED to allocated Mdl", RequestId ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - if( (Nbl = NdisAllocateNetBufferAndNetBufferList( - SendQueue->NblPool, - 0, - 0, - Mdl, - 0, - DataSize - )) == NULL ) - { - TraceError( WMBCLASS_SEND, "[Send][DSS Write %d] FAILED to allocated Nbl & Nb", RequestId ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - // Log the converted values - TraceInfo( WMBCLASS_SEND, "[Send][Dss Write %d] mapped to [NBL=0x%p] and [NB=0x%p]", - RequestId, Nbl, NET_BUFFER_LIST_FIRST_NB(Nbl)); - - } - while( FALSE ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - if (Nbl) - { - NdisFreeNetBufferList( Nbl ); - Nbl = NULL; - } - - if (Mdl) - { - NdisFreeMdl( Mdl ); - Mdl = NULL; - } - - if (CopiedData) - { - FREE_POOL(CopiedData); - } - } - return Nbl; -} - -VOID -MbbCleanupDssNbl( - _In_ PMBB_SEND_QUEUE SendQueue, - _In_ PNET_BUFFER_LIST NetBufferList - ) -{ - PMDL Mdl = NULL; - PVOID CopiedData = NULL; - ULONG Length; - - Mdl = NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(NetBufferList)); - NdisQueryMdl (Mdl, &CopiedData, &Length, NormalPagePriority | MdlMappingNoExecute); - if (CopiedData) - FREE_POOL(CopiedData); - - // The MDL is self allocated - NdisFreeMdl( Mdl ); - NdisFreeNetBufferList( NetBufferList ); -} - -_Requires_lock_held_(SendQueue->Lock) -NDIS_STATUS -MbbSendQQueueDssData( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_SEND_QUEUE SendQueue, - __in MBB_REQUEST_HANDLE RequestHandle, - __in ULONG RequestId, - __in ULONG SessionId, - __in ULONG DataSize, - __in PVOID Data - ) -{ - PMBB_NBL_CONTEXT NblContext; - PNET_BUFFER_LIST NetBufferList = NULL; - - if( (NetBufferList = MbbAllocateDssNbl( - Adapter, - SendQueue, - RequestId, - DataSize, - Data - )) == NULL ) - { - TraceError( WMBCLASS_SEND, "[Send][DSS Write %d] FAILED to allocated Nbl", RequestId ); - return NDIS_STATUS_RESOURCES; - } - - if( (NblContext = MbbNblAllocateContext( - NetBufferList, - &SendQueue->NblLookasideList, - &SendQueue->NbLookasideList, - MbbSendQDequeueDssData, - SendQueue - )) == NULL ) - { - TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] FAILED to allocated context", NetBufferList ); - MbbCleanupDssNbl(SendQueue, NetBufferList); - return NDIS_STATUS_RESOURCES; - } - - // Save the DSS specific information for completion - NblContext->DssSessionId = SessionId; - NblContext->DssRequestHandle = RequestHandle; - - if( IsListEmpty( &SendQueue->NblTrackList ) ) - KeResetEvent( &SendQueue->NblQueueEmptyEvent ); - - InsertTailList( &SendQueue->NblTrackList, &NblContext->NblQLink ); - InsertTailList( &SendQueue->NblDispatchQueue, &NblContext->DispatchQLink ); - - return NDIS_STATUS_SUCCESS; -} - -VOID -MbbSendQDequeueDssData( - __in PNET_BUFFER_LIST NetBufferList, - __in PVOID Context - ) -{ - PMBB_SEND_QUEUE SendQueue = (PMBB_SEND_QUEUE)Context; - PMBB_NBL_CONTEXT NblContext = (PMBB_NBL_CONTEXT)NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0]; - - NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0] = NULL; - - if( NetBufferList->Status != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_SEND, "[Send][NBL=0x%p] Completed with failed NdisStatus=%!STATUS!", - NetBufferList, - NetBufferList->Status - ); - } - - NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[0] = NULL; - NET_BUFFER_LIST_MINIPORT_RESERVED( NetBufferList )[1] = NblContext; - - // Call the completion handler - MbbNdisDeviceServiceSessionSendComplete( - NblContext->DssRequestHandle, - NetBufferList->Status - ); - - // Free the Nbl & stuff associate with the request - MbbCleanupDssNbl(SendQueue, NetBufferList); - - DrainRelease( &SendQueue->QueueDrainObject ); - - MbbSendQLock(SendQueue, FALSE); - if (RemoveEntryList(&NblContext->NblQLink)) - KeSetEvent(&SendQueue->NblQueueEmptyEvent, 0, FALSE); - MbbSendQUnlock(SendQueue, FALSE); -} - -// -// Miniport handlers -// - -NDIS_STATUS -MbbSendDeviceServiceSessionData( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_REQUEST_HANDLE RequestHandle, - __in ULONG RequestId, - __in ULONG SessionId, - __in ULONG DataSize, - __in PVOID Data - ) -{ - NDIS_STATUS NdisStatus; - PMBB_SEND_QUEUE SendQueue=&Adapter->SendQueue; - if (MbbBusIsFastIO(Adapter->BusHandle)) - { - PNET_BUFFER_LIST NetBufferList = NULL; - PVOID NblContext = NULL; - USHORT NblContextSize = ALIGN(sizeof(MBB_NBL_TYPE), MEMORY_ALLOCATION_ALIGNMENT); - MBB_NBL_TYPE NblType; - - if ((NetBufferList = MbbAllocateDssNbl( - Adapter, - SendQueue, - RequestId, - DataSize, - Data)) == NULL) - { - TraceError(WMBCLASS_SEND, "[FastIOSend][DSS Write %d] FAILED to allocate Nbl", RequestId); - return NDIS_STATUS_RESOURCES; - } - -#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate NetBufferList from SendQueue->NblPool, released when FastIOSendNetBufferListsComplete.") - if (NdisAllocateNetBufferListContext( - NetBufferList, - NblContextSize, - 0, - MbbPoolTagNblFastIOContext) != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_RECEIVE, "[FastIOSend][DSS NBL=0x%p] FAILED to allocate NetBufferListContext", NetBufferList); - MbbCleanupDssNbl(SendQueue, NetBufferList); - return NDIS_STATUS_RESOURCES; - } - - NblContext = NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); - *((MBB_NBL_TYPE*)NblContext) = MBB_NBL_TYPE_DSS; - - NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList)[0] = RequestHandle; - - MbbBusSendNetBufferLists(Adapter->BusHandle, NetBufferList, SessionId, 0); - } - else { - MbbSendQLock(SendQueue, FALSE); - - if (!DrainAddRef(&SendQueue->QueueDrainObject)) - { - TraceError(WMBCLASS_SEND, "[Send][DSS Write %d] DROPPING", RequestId); - MbbSendQUnlock(SendQueue, FALSE); - return NDIS_STATUS_ADAPTER_NOT_READY; - } - - if ((NdisStatus = MbbSendQQueueDssData( - Adapter, - SendQueue, - RequestHandle, - RequestId, - SessionId, - DataSize, - Data - )) != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_SEND, "[Send][DSS Write %d] DROPPING, queuing failed", RequestId); - - MbbSendQUnlock(SendQueue, FALSE); - - // - // a ref was added for this DSS data, removed it - // - DrainRelease(&SendQueue->QueueDrainObject); - return NdisStatus; - } - MbbSendQUnlock(SendQueue, FALSE); - - MbbSendQProcess(SendQueue, FALSE); - } - return NDIS_STATUS_SUCCESS; -} - diff --git a/network/wwan/cxwmbclass/send.h b/network/wwan/cxwmbclass/send.h deleted file mode 100644 index 36fa6e096..000000000 --- a/network/wwan/cxwmbclass/send.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -NDIS_STATUS -MbbSendQInitialize( - __in PMBB_SEND_QUEUE SendQueue, - __in ULONG MaxConcurrentSends, - __in MBB_DRAIN_COMPLETE DrainCompleteCallback, - __in PVOID DrainCompleteContext, - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_BUS_HANDLE BusHandle, - __in NDIS_HANDLE MiniportHandle - ); - -VOID -MbbSendQCleanup( - __in PMBB_SEND_QUEUE SendQueue - ); - -VOID -MbbSendQCancel( - __in PMBB_SEND_QUEUE SendQueue, - __in NDIS_STATUS Status, - __in BOOLEAN WaitForCompletion - ); - - -NDIS_STATUS -MbbSendDeviceServiceSessionData( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in MBB_REQUEST_HANDLE RequestHandle, - __in ULONG RequestId, - __in ULONG SessionId, - __in ULONG DataSize, - __in PVOID Data - ); - -VOID -MbbCleanupDssNbl( - _In_ PMBB_SEND_QUEUE SendQueue, - _In_ PNET_BUFFER_LIST NetBufferList -); diff --git a/network/wwan/cxwmbclass/sources.inc b/network/wwan/cxwmbclass/sources.inc new file mode 100644 index 000000000..7b1e526c9 --- /dev/null +++ b/network/wwan/cxwmbclass/sources.inc @@ -0,0 +1,12 @@ +MBBCX_MAJOR_VERSION=1 +MBBCX_MINOR_VERSION=0 + +MBBCX_VERSION=$(MBBCX_MAJOR_VERSION).$(MBBCX_MINOR_VERSION) + +MBBCX_DDK_INC_PATH=$(ONECORE_EXTERNAL_DDK_INC_PATH)\mbbcx\$(MBBCX_VERSION) +MBBCX_DDK_LIB_PATH=$(ONECORE_EXTERNAL_DDK_LIB_PATH)\mbbcx\$(MBBCX_VERSION) + +KMDF_VERSION_MAJOR=1 +KMDF_VERSION_MINOR=31 +KMDF_VERSION=$(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR) +KMDF_DDK_INC_PATH=$(ONECORE_INTERNAL_DDK_INC_PATH)\wdf\kmdf\$(KMDF_VERSION); diff --git a/network/wwan/cxwmbclass/tmpMbbMessages.h b/network/wwan/cxwmbclass/tmpMbbMessages.h deleted file mode 100644 index 3d73b4df2..000000000 --- a/network/wwan/cxwmbclass/tmpMbbMessages.h +++ /dev/null @@ -1,3306 +0,0 @@ - - -/* this ALWAYS GENERATED file contains the definitions for the interfaces */ - -/* File created by MIDL compiler version 8.01.0625 */ -/* at Mon Jan 18 19:14:07 2038 - */ -/* @@MIDL_FILE_HEADING( ) */ - -/* verify that the version is high enough to compile this file*/ -#ifndef __REQUIRED_RPCNDR_H_VERSION__ -#define __REQUIRED_RPCNDR_H_VERSION__ 500 -#endif - -/* verify that the version is high enough to compile this file*/ -#ifndef __REQUIRED_RPCSAL_H_VERSION__ -#define __REQUIRED_RPCSAL_H_VERSION__ 100 -#endif - -#include "rpc.h" -#include "rpcndr.h" - -#ifndef __RPCNDR_H_VERSION__ -#error this stub requires an updated version of -#endif /* __RPCNDR_H_VERSION__ */ - -#ifndef __MbbMessages_h__ -#define __MbbMessages_h__ - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -#pragma once -#endif - -#ifndef DECLSPEC_XFGVIRT -#if _CONTROL_FLOW_GUARD_XFG -#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func)) -#else -#define DECLSPEC_XFGVIRT(base, func) -#endif -#endif - -/* Forward Declarations */ - -/* header files for imported files */ -// #include "wtypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* interface __MIDL_itf_MbbMessages_0000_0000 */ -/* [local] */ - -// -// Copyright (C) Microsoft. All rights reserved. -// -#include -// -// Service Ids -// -// Invald GUID -// 00000000-0000-0000-0000-000000000000 -DEFINE_GUID(MBB_UUID_INVALID, 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -#define MBB_UUID_INVALID_CONSTANT \ - { \ - 0x00000000, 0x0000, 0x0000, \ - { \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ - } \ - } -// Basic IP Connectivity -// a289cc33-bcbb-8b4f-b6b0-133ec2aae6df -DEFINE_GUID(MBB_UUID_BASIC_CONNECT, 0xa289cc33, 0xbcbb, 0x8b4f, 0xb6, 0xb0, 0x13, 0x3e, 0xc2, 0xaa, 0xe6, 0xdf); -#define MBB_UUID_BASIC_CONNECT_CONSTANT \ - { \ - 0xa289cc33, 0xbcbb, 0x8b4f, \ - { \ - 0xb6, 0xb0, 0x13, 0x3e, 0xc2, 0xaa, 0xe6, 0xdf \ - } \ - } -// SMS -// 533fbeeb-14fe-4467-9f90-33a223e56c3f -DEFINE_GUID(MBB_UUID_SMS, 0x533fbeeb, 0x14fe, 0x4467, 0x9f, 0x90, 0x33, 0xa2, 0x23, 0xe5, 0x6c, 0x3f); -#define MBB_UUID_SMS_CONSTANT \ - { \ - 0x533fbeeb, 0x14fe, 0x4467, \ - { \ - 0x9f, 0x90, 0x33, 0xa2, 0x23, 0xe5, 0x6c, 0x3f \ - } \ - } -// USSD -// e550a0c8-5e82-479e-82f7-10abf4c3351f -DEFINE_GUID(MBB_UUID_USSD, 0xe550a0c8, 0x5e82, 0x479e, 0x82, 0xf7, 0x10, 0xab, 0xf4, 0xc3, 0x35, 0x1f); -#define MBB_UUID_USSD_CONSTANT \ - { \ - 0xe550a0c8, 0x5e82, 0x479e, \ - { \ - 0x82, 0xf7, 0x10, 0xab, 0xf4, 0xc3, 0x35, 0x1f \ - } \ - } -// Phonebook -// 4bf38476-1e6a-41db-b1d8-bed289c25bdb -DEFINE_GUID(MBB_UUID_PHONEBOOK, 0x4bf38476, 0x1e6a, 0x41db, 0xb1, 0xd8, 0xbe, 0xd2, 0x89, 0xc2, 0x5b, 0xdb); -#define MBB_UUID_PHONEBOOK_CONSTANT \ - { \ - 0x4bf38476, 0x1e6a, 0x41db, \ - { \ - 0xb1, 0xd8, 0xbe, 0xd2, 0x89, 0xc2, 0x5b, 0xdb \ - } \ - } -// SIM Application Toolkit -// d8f20131-fcb5-4e17-8602-d6ed3816164c -DEFINE_GUID(MBB_UUID_SAT, 0xd8f20131, 0xfcb5, 0x4e17, 0x86, 0x02, 0xd6, 0xed, 0x38, 0x16, 0x16, 0x4c); -#define MBB_UUID_SAT_CONSTANT \ - { \ - 0xd8f20131, 0xfcb5, 0x4e17, \ - { \ - 0x86, 0x02, 0xd6, 0xed, 0x38, 0x16, 0x16, 0x4c \ - } \ - } -// Windows 7 Vendor Extension -// b492e7e2-adba-499d-8401-7794bb913c1c -DEFINE_GUID(MBB_UUID_MS_VENDOR_EXTENSION, 0xb492e7e2, 0xadba, 0x499d, 0x84, 0x01, 0x77, 0x94, 0xbb, 0x91, 0x3c, 0x1c); -#define MBB_UUID_MS_VENDOR_EXTENSION_CONSTANT \ - { \ - 0xb492e7e2, 0xadba, 0x499d, \ - { \ - 0x84, 0x01, 0x77, 0x94, 0xbb, 0x91, 0x3c, 0x1c \ - } \ - } -// Authentication -// 1d2b5ff7-0aa1-48b2-aa52-50f15767174e -DEFINE_GUID(MBB_UUID_AUTH, 0x1d2b5ff7, 0x0aa1, 0x48b2, 0xaa, 0x52, 0x50, 0xf1, 0x57, 0x67, 0x17, 0x4e); -#define MBB_UUID_AUTH_CONSTANT \ - { \ - 0x1d2b5ff7, 0x0aa1, 0x48b2, \ - { \ - 0xaa, 0x52, 0x50, 0xf1, 0x57, 0x67, 0x17, 0x4e \ - } \ - } -// Device Service Stream -// c08a26dd-7718-4382-8482-6e0d583c4d0e -DEFINE_GUID(MBB_UUID_DSS, 0xc08a26dd, 0x7718, 0x4382, 0x84, 0x82, 0x6e, 0x0d, 0x58, 0x3c, 0x4d, 0x0e); -#define MBB_UUID_DSS_CONSTANT \ - { \ - 0xc08a26dd, 0x7718, 0x4382, \ - { \ - 0x84, 0x82, 0x6e, 0x0d, 0x58, 0x3c, 0x4d, 0x0e \ - } \ - } -// Multi-carrier device service -// 8b569648-628d-4653-9b9f-1025404424e1 -DEFINE_GUID(MBB_UUID_MULTICARRIER, 0x8b569648, 0x628d, 0x4653, 0x9b, 0x9f, 0x10, 0x25, 0x40, 0x44, 0x24, 0xe1); -#define MBB_UUID_MULTICARRIER_CONSTANT \ - { \ - 0x8b569648, 0x628d, 0x4653, \ - { \ - 0x9b, 0x9f, 0x10, 0x25, 0x40, 0x44, 0x24, 0xe1 \ - } \ - } -// Host Shutdown device service -// 883b7c26-985f-43fa-9804-27d7fb80959c -DEFINE_GUID(MBB_UUID_HOSTSHUTDOWN, 0x883b7c26, 0x985f, 0x43fa, 0x98, 0x04, 0x27, 0xd7, 0xfb, 0x80, 0x95, 0x9c); -#define MBB_UUID_HOSTSHUTDOWN_CONSTANT \ - { \ - 0x883b7c26, 0x985f, 0x43fa, \ - { \ - 0x98, 0x04, 0x27, 0xd7, 0xfb, 0x80, 0x95, 0x9c \ - } \ - } -// MBIM 2.0 voice extensions -// 8d8b9eba-37be-449b-8f1e-61cb034a702e -DEFINE_GUID(MBB_UUID_VOICEEXTENSIONS, 0x8d8b9eba, 0x37be, 0x449b, 0x8f, 0x1e, 0x61, 0xcb, 0x03, 0x4a, 0x70, 0x2e); -#define MBB_UUID_VOICEEXTENSIONS_CONSTANT \ - { \ - 0x8d8b9eba, 0x37be, 0x449b, \ - { \ - 0x8f, 0x1e, 0x61, 0xcb, 0x03, 0x4a, 0x70, 0x2e \ - } \ - } -// Low-Level UICC Access -// c2f6588e-f037-4bc9-8665-f4d44bd09367 -DEFINE_GUID(MBB_UUID_UICC_LOW_LEVEL, 0xc2f6588e, 0xf037, 0x4bc9, 0x86, 0x65, 0xf4, 0xd4, 0x4b, 0xd0, 0x93, 0x67); -#define MBB_UUID_UICC_LOW_LEVEL_CONSTANT \ - { \ - 0xc2f6588e, 0xf037, 0x4bc9, \ - { \ - 0x86, 0x65, 0xf4, 0xd4, 0x4b, 0xd0, 0x93, 0x67 \ - } \ - } -// Selective Absorption Rate (SAR) control -// 68223d04-9f6c-4e0f-822d-28441fb72340 -DEFINE_GUID(MBB_UUID_SARCONTROL, 0x68223d04, 0x9f6c, 0x4e0f, 0x82, 0x2d, 0x28, 0x44, 0x1f, 0xb7, 0x23, 0x40); -#define MBB_UUID_SARCONTROL_CONSTANT \ - { \ - 0x68223d04, 0x9f6c, 0x4e0f, \ - { \ - 0x82, 0x2d, 0x28, 0x44, 0x1f, 0xb7, 0x23, 0x40 \ - } \ - } -// Basic IP Connectivity Extensions (a private Microsoft service not approved by MBIM USB forum as of 2016/11/09) -// 3d01dcc5-fef5-4d05-0d3a-bef7058e9aaf -DEFINE_GUID(MBB_UUID_BASIC_CONNECT_EXTENSIONS, 0x3d01dcc5, 0xfef5, 0x4d05, 0x0d, 0x3a, 0xbe, 0xf7, 0x05, 0x8e, 0x9a, 0xaf); -#define MBB_UUID_BASIC_CONNECT_EXT_CONSTANT \ - { \ - 0x3d01dcc5, 0xfef5, 0x4d05, \ - { \ - 0x0d, 0x3a, 0xbe, 0xf7, 0x05, 0x8e, 0x9a, 0xaf \ - } \ - } -// DeviceService GUID for Modem Log Transfer (parameter for DSS connect/disconnect request to open/close DSS data channel) -// 0ebb1ceb-af2d-484d-8df3-53bc51fd162c -DEFINE_GUID(MBB_UUID_MODEM_LOG_TRANSFER, 0x0ebb1ceb, 0xaf2d, 0x484d, 0x8d, 0xf3, 0x53, 0xbc, 0x51, 0xfd, 0x16, 0x2c); -#define MBB_UUID_MODEM_LOG_TRANSFER_CONSTANT \ - { \ - 0x0ebb1ceb, 0xaf2d, 0x484d, \ - { \ - 0x8d, 0xf3, 0x53, 0xbc, 0x51, 0xfd, 0x16, 0x2c \ - } \ - } -// -// Context Type GUIDs -// -// MBIMContextTypeNone -// B43F758C-A560-4B46-B35E-C5869641FB54 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_NONE, 0xB43F758C, 0xA560, 0x4B46, 0xB3, 0x5E, 0xC5, 0x86, 0x96, 0x41, 0xFB, 0x54); -// MBIMContextTypeInternet -// 7E5E2A7E-4E6F-7272-736B-656E7E5E2A7E -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_INTERNET, 0x7E5E2A7E, 0x4E6F, 0x7272, 0x73, 0x6B, 0x65, 0x6E, 0x7E, 0x5E, 0x2A, 0x7E); -// MBIMContextTypeVpn -// 9B9F7BBE-8952-44B7-83AC-CA41318DF7A0 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_VPN, 0x9B9F7BBE, 0x8952, 0x44B7, 0x83, 0xAC, 0xCA, 0x41, 0x31, 0x8D, 0xF7, 0xA0); -// MBIMContextTypeVoice -// 88918294-0EF4-4396-8CCA-A8588FBC02B2 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_VOICE, 0x88918294, 0x0EF4, 0x4396, 0x8C, 0xCA, 0xA8, 0x58, 0x8F, 0xBC, 0x02, 0xB2); -// MBIMContextTypeVideoShare -// 05A2A716-7C34-4B4D-9A91-C5EF0C7AAACC -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_VIDEO_SHARE, 0x05A2A716, 0x7C34, 0x4B4D, 0x9A, 0x91, 0xC5, 0xEF, 0x0C, 0x7A, 0xAA, 0xCC); -// MBIMContextTypePurchase -// B3272496-AC6C-422B-A8C0-ACF687A27217 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_PURCHASE, 0xB3272496, 0xAC6C, 0x422B, 0xA8, 0xC0, 0xAC, 0xF6, 0x87, 0xA2, 0x72, 0x17); -// MBIMContextTypeIMS -// 21610D01-3074-4BCE-9425-B53A07D697D6 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_IMS, 0x21610D01, 0x3074, 0x4BCE, 0x94, 0x25, 0xB5, 0x3A, 0x07, 0xD6, 0x97, 0xD6); -// MBIMContextTypeMMS -// 46726664-7269-6BC6-9624-D1D35389ACA9 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MMS, 0x46726664, 0x7269, 0x6BC6, 0x96, 0x24, 0xD1, 0xD3, 0x53, 0x89, 0xAC, 0xA9); -// MBIMContextTypeLocal -// A57A9AFC-B09F-45D7-BB40-033C39F60DB9 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_LOCAL, 0xA57A9AFC, 0xB09F, 0x45D7, 0xBB, 0x40, 0x03, 0x3C, 0x39, 0xF6, 0x0D, 0xB9); -// MBIMMsContextTypeAdmin -// 5f7e4c2e-e80b-40a9-a239-f0abcfd11f4b -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_ADMIN, 0x5f7e4c2e, 0xe80b, 0x40a9, 0xa2, 0x39, 0xf0, 0xab, 0xcf, 0xd1, 0x1f, 0x4b); -// MBIMMSContextTypeApp -// 74d88a3d-dfbd-4799-9a8c-7310a37bb2ee -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_APP, 0x74d88a3d, 0xdfbd, 0x4799, 0x9a, 0x8c, 0x73, 0x10, 0xa3, 0x7b, 0xb2, 0xee); -// MBIMMsContextTypeXcap -// 50d378a7-baa5-4a50-b872-3fe5bb463411 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_XCAP, 0x50d378a7, 0xbaa5, 0x4a50, 0xb8, 0x72, 0x3f, 0xe5, 0xbb, 0x46, 0x34, 0x11); -// MBIMMsContextTypeTethering -// 5e4e0601-48dc-4e2b-acb8-08b4016bbaac -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_TETHERING, 0x5e4e0601, 0x48dc, 0x4e2b, 0xac, 0xb8, 0x08, 0xb4, 0x01, 0x6b, 0xba, 0xac); -// MBIMMsContextTypeEmergencyCalling -// 5f41adb8-204e-4d31-9da8-b3c970e360f2 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_MS_EMERGENCYCALL, 0x5f41adb8, 0x204e, 0x4d31, 0x9d, 0xa8, 0xb3, 0xc9, 0x70, 0xe3, 0x60, 0xf2); -// 9C494542-A43B-4EA5-B8B7-53310E71DF10 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_CUSTOM, 0x9C494542, 0xA43B, 0x4EA5, 0xB8, 0xB7, 0x53, 0x31, 0x0E, 0x71, 0xDF, 0x10); -// 64F65862-6954-4FB3-B6E1-807461ABEBA0 -DEFINE_GUID(MBB_UUID_CONTEXT_TYPE_SUPL, 0x64F65862, 0x6954, 0x4FB3, 0xB6, 0xE1, 0x80, 0x74, 0x61, 0xAB, 0xEB, 0xA0); -// 146FED19-EB71-42A7-B3EB-3875DEA61D92 -DEFINE_GUID(GUID_USB_CAPABILITY_DEVICE_TYPE, 0x146FED19, 0xEB71, 0x42A7, 0xB3, 0xEB, 0x38, 0x75, 0xDE, 0xA6, 0x1D, 0x92); - -#define MBB_STATUS_SUCCESS(STATUS) (((STATUS) == MBB_STATUS_SUCCESS) || ((STATUS) == MBB_STATUS_SMS_MORE_DATA)) -#define MBB_STATUS_IS_BASIC(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_BASIC_START) && ((MBBSTATUS) < MBB_STATUS_BASIC_END)) -#define MBB_STATUS_BASIC_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_BASIC_START) -#define MBB_STATUS_BASIC_COUNT() (MBB_STATUS_BASIC_END - MBB_STATUS_BASIC_START) -#define MBB_STATUS_IS_SMS(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_SMS_START) && ((MBBSTATUS) < MBB_STATUS_SMS_END)) -#define MBB_STATUS_SMS_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_SMS_START) -#define MBB_STATUS_SMS_COUNT() (MBB_STATUS_SMS_END - MBB_STATUS_SMS_START) -#define MBB_STATUS_IS_UICC(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_UICC_START) && ((MBBSTATUS) < MBB_STATUS_UICC_END)) -#define MBB_STATUS_UICC_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_UICC_START) -#define MBB_STATUS_UICC_COUNT() (MBB_STATUS_UICC_END - MBB_STATUS_UICC_START) -#define MBB_STATUS_IS_4_0(MBBSTATUS) (((MBBSTATUS) >= MBB_STATUS_4_0_START) && ((MBBSTATUS) < MBB_STATUS_4_0_END)) -#define MBB_STATUS_4_0_INDEX(MBBSTATUS) ((MBBSTATUS)-MBB_STATUS_4_0_START) -#define MBB_STATUS_4_0_COUNT() (MBB_STATUS_4_0_END - MBB_STATUS_4_0_START) -#define MBB_UUID_TO_NET(_dest, _src) \ - { \ - (_dest)->Data1 = RtlUlongByteSwap((_src)->Data1); \ - (_dest)->Data2 = RtlUshortByteSwap((_src)->Data2); \ - (_dest)->Data3 = RtlUshortByteSwap((_src)->Data3); \ - RtlCopyMemory((_dest)->Data4, (_src)->Data4, sizeof((_src)->Data4)); \ - } -#define MBB_UUID_TO_HOST(_dest, _src) MBB_UUID_TO_NET(_dest, _src) -#define MBB_IS_DEVICE_REGISTERED(_State_) \ - (((_State_) == MbbRegisterStateHome) || ((_State_) == MbbRegisterStateRoaming) || ((_State_) == MbbRegisterStatePartner)) -#include -#define MBB_MAXIMUM_DATA_CLASS_NAME_LENGTH (11) - -#define MBB_MAXIMUM_DEVICE_ID_LENGTH (17) - -#define MBB_MAXIMUM_FIRMWARE_INFO_LENGTH (31) - -#define MBB_MAXIMUM_SUBSCRIBER_ID_LENGTH (15) - -#define MBB_MAXIMUM_SIM_ICC_ID_LENGTH (20) - -#define MBB_MAXIMUM_TELEPHONE_NUMBER_LENGTH (15) - -#define MBB_MAXIMUM_TELEPHONE_NUMBER_ERRATA_LENGTH (22) - -#define MBB_MAXIMUM_PIN_LENGTH (16) - -#define MBB_MAXIMUM_PROVIDER_ID_LENGTH (6) - -#define MBB_MAXIMUM_PROVIDER_NAME_LENGTH (20) - -#define MBB_MAXIMUM_ROAMING_TEXT_LENGTH (63) - -#define MBB_MAXIMUM_ACCESS_STRING_LENGTH (100) - -#define MBB_MAXIMUM_USERNAME_LENGTH (255) - -#define MBB_MAXIMUM_PASSWORD_LENGTH (255) - -#define MBB_MAXIMUM_SMS_ADDRESS_LENGTH (20) - -#define MBB_MAXIMUM_SMS_CDMA_ADDRESS_LENGTH (49) - -#define MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH (21) - -#define MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH (160) - -#define MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH (183) - -#define MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH (255) - -#define MBB_USSD_STRING_LEN_MAX (160) - -#define MBB_RSSI_DISABLE (0xffffffff) - -#define MBB_RSSI_DEFAULT (0) - -#define MBB_SET_CONTEXT_STATE_EX3_MIN_TLV_CNT (3) - -#define MBB_CONTEXT_STATE_EX3_MIN_TLV_CNT (1) - -#define MBIM_VERSION_1_0 (0x100) - -#define MBIM_MS_EXTENDED_VER_1_0 (0x100) - -#define MBIM_MS_EXTENDED_VER_2_0 (0x200) - -#define MBIM_MS_EXTENDED_VER_3_0 (0x300) - -#define MBIM_MS_EXTENDED_VER_4_0 (0x400) - -#define MBB_MS_DEVICE_CAPS_INFO_V3_MIN_TLV_CNT (6) - -#define MBB_TLV_TYPE_RESERVED (0) - -#define MBB_TLV_TYPE_UE_POLICIES (1) - -#define MBB_TLV_TYPE_SINGLE_NSSAI (2) - -#define MBB_TLV_TYPE_ALLOWED_NSSAI (3) - -#define MBB_TLV_TYPE_CFG_NSSAI (4) - -#define MBB_TLV_TYPE_DFLT_CFG_NSSAI (5) - -#define MBB_TLV_TYPE_PRECFG_DFLT_CFG_NSSAI (6) - -#define MBB_TLV_TYPE_REJ_NSSAI (7) - -#define MBB_TLV_TYPE_LADN (8) - -#define MBB_TLV_TYPE_TAI (9) - -#define MBB_TLV_TYPE_WCHAR_STR (10) - -#define MBB_TLV_TYPE_UINT16_TBL (11) - -#define MBB_TLV_TYPE_EAP_PACKET (12) - -#define MBB_TLV_TYPE_PCO (13) - -#define MBB_TLV_TYPE_ROUTE_SELECTION_DESCRIPTORS (14) - -#define MBB_TLV_TYPE_TRAFFIC_PARAMETERS (15) - -#define MBB_TLV_TYPE_WAKE_COMMAND (16) - -#define MBB_TLV_TYPE_WAKE_PACKET (17) - -#define MBB_TLV_TYPE_OSID (18) - -#define MBB_TLV_TYPE_3GPP_REL_VERSION (19) - -#define MBB_TLV_TYPE_URSP_RULES_TD_ONLY (20) - -#define MBB_TLV_TYPE_SESSION_ID (21) - -#define MBB_NW_PARAMS_INFO_CONFIG_TLV_CNT (6) - -#define MBB_NW_PARAMS_INFO_UE_POLICIES_TLV_CNT (1) - -typedef unsigned short MBB_TLV_TYPE; - -typedef struct _MBB_TLV_IE -{ - MBB_TLV_TYPE Type; - UCHAR Reserved; - UCHAR PaddingLength; - ULONG DataLength; -} MBB_TLV_IE; - -typedef struct _MBB_TLV_IE* PMBB_TLV_IE; - -typedef enum _USB_CAP_DEVICE_TYPE -{ - USB_CAP_DEVICE_TYPE_USB = 0, - USB_CAP_DEVICE_TYPE_UDE_MBIM = 1, - USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO = 2, - USB_CAP_DEVICE_TYPE_MAXIMUM = (USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO + 1) -} USB_CAP_DEVICE_TYPE; - -typedef struct _USB_CAP_DEVICE_INFO_HEADER -{ - USB_CAP_DEVICE_TYPE DeviceType; - UCHAR DeviceMinorVersion; - UCHAR DeviceMajorVersion; - ULONG Reserved; -} USB_CAP_DEVICE_INFO_HEADER; - -typedef struct _USB_CAP_DEVICE_INFO_HEADER* PUSB_CAP_DEVICE_INFO_HEADER; - -typedef struct _USB_CAP_DEVICE_INFO -{ - USB_CAP_DEVICE_INFO_HEADER DeviceInfoHeader; -} USB_CAP_DEVICE_INFO; - -typedef struct _USB_CAP_DEVICE_INFO* PUSB_CAP_DEVICE_INFO; - -typedef enum _MBB_NBL_TYPE -{ - MBB_NBL_TYPE_IP = 0, - MBB_NBL_TYPE_DSS = 1, - MBB_NBL_TYPE_MAXIMUM = (MBB_NBL_TYPE_DSS + 1) -} MBB_NBL_TYPE; - -typedef enum _MBB_STATUS -{ - MBB_STATUS_SUCCESS = 0, - MBB_STATUS_BASIC_START = 0, - MBB_STATUS_BUSY = 1, - MBB_STATUS_FAILURE = 2, - MBB_STATUS_SIM_NOT_INSERTED = 3, - MBB_STATUS_BAD_SIM = 4, - MBB_STATUS_PIN_REQUIRED = 5, - MBB_STATUS_PIN_DISABLED = 6, - MBB_STATUS_NOT_REGISTERED = 7, - MBB_STATUS_PROVIDERS_NOT_FOUND = 8, - MBB_STATUS_NO_DEVICE_SUPPORT = 9, - MBB_STATUS_PROVIDER_NOT_VISIBLE = 10, - MBB_STATUS_DATA_CLASS_NOT_AVAILABLE = 11, - MBB_STATUS_PACKET_SVC_DETACHED = 12, - MBB_STATUS_MAX_ACTIVATED_CONTEXTS = 13, - MBB_STATUS_NOT_INITIALIZED = 14, - MBB_STATUS_VOICE_CALL_IN_PROGRESS = 15, - MBB_STATUS_CONTEXT_NOT_ACTIVATED = 16, - MBB_STATUS_SERVICE_NOT_ACTIVATED = 17, - MBB_STATUS_INVALID_ACCESS_STRING = 18, - MBB_STATUS_INVALID_USER_NAME_PWD = 19, - MBB_STATUS_RADIO_POWER_OFF = 20, - MBB_STATUS_INVALID_PARAMETERS = 21, - MBB_STATUS_READ_FAILURE = 22, - MBB_STATUS_WRITE_FAILURE = 23, - MBB_STATUS_DENIED_POLICY = 24, - MBB_STATUS_NO_PHONEBOOK = 25, - MBB_STATUS_PARAMETER_TOO_LONG = 26, - MBB_STATUS_STK_BUSY = 27, - MBB_STATUS_OPERATION_NOT_ALLOWED = 28, - MBB_STATUS_MEMORY_FAILURE = 29, - MBB_STATUS_INVALID_MEMORY_INDEX = 30, - MBB_STATUS_MEMORY_FULL = 31, - MBB_STATUS_FILTER_NOT_SUPPORTED = 32, - MBB_STATUS_DSS_INSTANCE_LIMIT = 33, - MBB_STATUS_INVALID_DEVICE_SERVICE_OPERATION = 34, - MBB_STATUS_AUTH_INCORRECT_AUTN = 35, - MBB_STATUS_AUTH_SYNC_FAILURE = 36, - MBB_STATUS_AUTH_AMF_NOT_SET = 37, - MBB_STATUS_CONTEXT_NOT_SUPPORTED = 38, - MBB_STATUS_SHAREABILITY_CONDITION_ERROR = 39, - MBB_STATUS_PIN_FAILURE = 40, - MBB_STATUS_NO_LTE_ATTACH_CONFIG = 41, - MBB_STATUS_SESSION_ALREADY_EXISTS = 42, - MBB_STATUS_BASIC_END = (MBB_STATUS_SESSION_ALREADY_EXISTS + 1), - MBB_STATUS_SMS_UNKNOWN_SMSC_ADDRESS = 100, - MBB_STATUS_SMS_START = 100, - MBB_STATUS_SMS_NETWORK_TIMEOUT = 101, - MBB_STATUS_SMS_LANG_NOT_SUPPORTED = 102, - MBB_STATUS_SMS_ENCODING_NOT_SUPPORTED = 103, - MBB_STATUS_SMS_FORMAT_NOT_SUPPORTED = 104, - MBB_STATUS_SMS_MORE_DATA = 105, - MBB_STATUS_SMS_END = (MBB_STATUS_SMS_MORE_DATA + 1), - MBB_STATUS_4_0_START = 200, - MBB_STATUS_MATCHING_PDU_SESSION_FOUND = MBB_STATUS_4_0_START, - MBB_STATUS_DESSOCIATION_NEEDED_FOR_APPLICATION = 201, - MBB_STATUS_ERROR_INVALID_SLOT = 202, - MBB_STATUS_NO_MATCHING_URSP_RULE = 203, - MBB_STATUS_NO_DEFAULT_URSP_RULE = 204, - MBB_STATUS_4_0_END = (MBB_STATUS_NO_DEFAULT_URSP_RULE + 1), - MBB_STATUS_UICC_NO_LOGICAL_CHANNELS = 0x87430001, - MBB_STATUS_UICC_START = 0x87430001, - MBB_STATUS_UICC_SELECT_FAILED = 0x87430002, - MBB_STATUS_UICC_INVALID_LOGICAL_CHANNEL = 0x87430003, - MBB_STATUS_UICC_END = (MBB_STATUS_UICC_INVALID_LOGICAL_CHANNEL + 1) -} MBB_STATUS; - -typedef enum _MBB_ERROR -{ - MBB_ERROR_NONE = 0, - MBB_ERROR_TIMEOUT_FRAGMENT = 1, - MBB_ERROR_FRAGMENT_OUT_OF_SEQUENCE = 2, - MBB_ERROR_LENGTH_MISMATCH = 3, - MBB_ERROR_DUPLICATE_TID = 4, - MBB_ERROR_NOT_OPENED = 5, - MBB_ERROR_UNKNOWN = 6, - MBB_ERROR_CANCEL = 7, - MBB_ERROR_MAX_TRANSFER = 8 -} MBB_ERROR; - -typedef enum _MBB_MESSAGE_TYPE -{ - MBB_MESSAGE_TYPE_NONE = 0, - MBB_MESSAGE_TYPE_OPEN = 0x1, - MBB_MESSAGE_TYPE_CLOSE = 0x2, - MBB_MESSAGE_TYPE_COMMAND = 0x3, - MBB_MESSAGE_TYPE_HOST_ERROR = 0x4, - MBB_MESSAGE_TYPE_OPEN_DONE = 0x80000001, - MBB_MESSAGE_TYPE_CLOSE_DONE = 0x80000002, - MBB_MESSAGE_TYPE_COMMAND_DONE = 0x80000003, - MBB_MESSAGE_TYPE_FUNCTION_ERROR = 0x80000004, - MBB_MESSAGE_TYPE_INDICATE_STATUS = 0x80000007 -} MBB_MESSAGE_TYPE; - -typedef enum _MBB_COMMAND_TYPE -{ - MBB_COMMAND_TYPE_QUERY = 0, - MBB_COMMAND_TYPE_SET = 1 -} MBB_COMMAND_TYPE; - -typedef struct _MBB_MESSAGE_HEADER -{ - MBB_MESSAGE_TYPE MessageType; - ULONG MessageLength; - ULONG MessageTransactionId; -} MBB_MESSAGE_HEADER; - -typedef struct _MBB_MESSAGE_HEADER* PMBB_MESSAGE_HEADER; - -typedef struct _MBB_FRAGMENT_HEADER -{ - ULONG TotalFragments; - ULONG CurrentFragment; -} MBB_FRAGMENT_HEADER; - -typedef struct _MBB_FRAGMENT_HEADER* PMBB_FRAGMENT_HEADER; - -typedef struct _MBB_COMMAND -{ - GUID ServiceId; - ULONG CommandId; -} MBB_COMMAND; - -typedef struct _MBB_COMMAND* PMBB_COMMAND; - -typedef struct _MBB_COMMAND_HEADER -{ - MBB_MESSAGE_HEADER MessageHeader; - MBB_FRAGMENT_HEADER FragmentHeader; - MBB_COMMAND Command; - MBB_COMMAND_TYPE CommandType; - ULONG InformationBufferLength; -} MBB_COMMAND_HEADER; - -typedef struct _MBB_COMMAND_HEADER* PMBB_COMMAND_HEADER; - -typedef struct _MBB_COMMAND_FRAGMENT_HEADER -{ - MBB_MESSAGE_HEADER MessageHeader; - MBB_FRAGMENT_HEADER FragmentHeader; -} MBB_COMMAND_FRAGMENT_HEADER; - -typedef struct _MBB_COMMAND_FRAGMENT_HEADER* PMBB_COMMAND_FRAGMENT_HEADER; - -typedef struct _MBB_COMMAND_DONE_HEADER -{ - MBB_MESSAGE_HEADER MessageHeader; - MBB_FRAGMENT_HEADER FragmentHeader; - MBB_COMMAND Command; - MBB_STATUS MbbStatus; - ULONG InformationBufferLength; -} MBB_COMMAND_DONE_HEADER; - -typedef struct _MBB_COMMAND_DONE_HEADER* PMBB_COMMAND_DONE_HEADER; - -typedef struct _MBB_INDICATE_STATUS_HEADER -{ - MBB_MESSAGE_HEADER MessageHeader; - MBB_FRAGMENT_HEADER FragmentHeader; - MBB_COMMAND Command; - ULONG InformationBufferLength; -} MBB_INDICATE_STATUS_HEADER; - -typedef struct _MBB_INDICATE_STATUS_HEADER* PMBB_INDICATE_STATUS_HEADER; - -typedef struct _MBB_OPEN_MESSAGE -{ - MBB_MESSAGE_HEADER MessageHeader; - ULONG MaximumControlTransfer; -} MBB_OPEN_MESSAGE; - -typedef struct _MBB_OPEN_MESSAGE* PMBB_OPEN_MESSAGE; - -typedef struct _MBB_OPEN_MESSAGE_FASTIO -{ - MBB_MESSAGE_HEADER MessageHeader; - ULONG MaximumControlTransfer; - PVOID AdapterContext; - PVOID SendNetBufferListsCompleteHandler; - PVOID ReceiveNetBufferListsHandler; -} MBB_OPEN_MESSAGE_FASTIO; - -typedef struct _MBB_OPEN_MESSAGE_FASTIO* PMBB_OPEN_MESSAGE_FASTIO; - -typedef struct _MBB_CLOSE_MESSAGE -{ - MBB_MESSAGE_HEADER MessageHeader; -} MBB_CLOSE_MESSAGE; - -typedef struct _MBB_CLOSE_MESSAGE* PMBB_CLOSE_MESSAGE; - -typedef struct _MBB_OPEN_DONE -{ - MBB_MESSAGE_HEADER MessageHeader; - MBB_STATUS MbbStatus; -} MBB_OPEN_DONE; - -typedef struct _MBB_OPEN_DONE* PMBB_OPEN_DONE; - -typedef struct _MBB_OPEN_DONE_FASTIO -{ - MBB_MESSAGE_HEADER MessageHeader; - MBB_STATUS MbbStatus; - PVOID ModemContext; - PVOID SendNetBufferListsHandler; - PVOID ReturnNetBufferListsHandler; - PVOID CancelSendHandler; - PVOID HaltHandler; - PVOID PauseHandler; - PVOID ShutdownHandler; - PVOID ResetHandler; - PVOID RestartHandler; -} MBB_OPEN_DONE_FASTIO; - -typedef struct _MBB_OPEN_DONE_FASTIO* PMBB_OPEN_DONE_FASTIO; - -typedef struct _MBB_CLOSE_DONE -{ - MBB_MESSAGE_HEADER MessageHeader; - MBB_STATUS MbbStatus; -} MBB_CLOSE_DONE; - -typedef struct _MBB_CLOSE_DONE* PMBB_CLOSE_DONE; - -typedef struct _MBB_ERROR_MESSAGE -{ - MBB_MESSAGE_HEADER MessageHeader; - MBB_ERROR ErrorCode; -} MBB_ERROR_MESSAGE; - -typedef struct _MBB_ERROR_MESSAGE* PMBB_ERROR_MESSAGE; - -typedef enum _MBB_BASIC_CID -{ - MBB_BASIC_CID_DEVICE_CAPS = 1, - MBB_BASIC_CID_SUBSCRIBER_READY_INFO = 2, - MBB_BASIC_CID_RADIO_STATE = 3, - MBB_BASIC_CID_PIN_INFO = 4, - MBB_BASIC_CID_PIN_LIST = 5, - MBB_BASIC_CID_HOME_PROVIDER = 6, - MBB_BASIC_CID_PREFERRED_PROVIDERS = 7, - MBB_BASIC_CID_VISIBLE_PROVIDERS = 8, - MBB_BASIC_CID_REGISTER_STATE = 9, - MBB_BASIC_CID_PACKET_SERVICE = 10, - MBB_BASIC_CID_SIGNAL_STATE = 11, - MBB_BASIC_CID_CONNECT = 12, - MBB_BASIC_CID_PROVISIONED_CONTEXTS = 13, - MBB_BASIC_CID_SERVICE_ACTIVATION = 14, - MBB_BASIC_CID_IP_ADDRESS_INFO = 15, - MBB_BASIC_CID_DEVICE_SERVICES = 16, - MBB_BASIC_CID_NOTIFY_DEVICE_SERVICE_UPDATES = 19, - MBB_BASIC_CID_PACKET_STATISTICS = 20, - MBB_BASIC_CID_NETWORK_IDLE_HINT = 21, - MBB_BASIC_CID_EMERGENCY_MODE = 22, - MBB_BASIC_CID_PACKET_FILTERS = 23, - MBB_BASIC_CID_MULTICARRIER_PROVIDERS = 24, - MBB_BASIC_CID_MAXIMUM = (MBB_BASIC_CID_MULTICARRIER_PROVIDERS + 1) -} MBB_BASIC_CID; - -typedef enum _MBB_SMS_CID -{ - MBB_SMS_CID_CONFIGURATION = 1, - MBB_SMS_CID_READ = 2, - MBB_SMS_CID_SEND = 3, - MBB_SMS_CID_DELETE = 4, - MBB_SMS_CID_STATUS = 5, - MBB_SMS_CID_MAXIMUM = (MBB_SMS_CID_STATUS + 1) -} MBB_SMS_CID; - -typedef enum _MBB_VENDOR_CID -{ - MBB_VENDOR_CID_MS_VENDOR_SPECIFIC = 1, - MBB_VENDOR_CID_MAXIMUM = (MBB_VENDOR_CID_MS_VENDOR_SPECIFIC + 1) -} MBB_VENDOR_CID; - -typedef enum _MBB_USSD_CID -{ - MBB_USSD_CID_USSD = 1, - MBB_USSD_CID_MAXIMUM = (MBB_USSD_CID_USSD + 1) -} MBB_USSD_CID; - -typedef enum _MBB_PHONEBOOK_CID -{ - MBB_PHONEBOOK_CID_CONFIGURATION = 1, - MBB_PHONEBOOK_CID_READ = 2, - MBB_PHONEBOOK_CID_DELETE = 3, - MBB_PHONEBOOK_CID_SAVE = 4, - MBB_PHONEBOOK_CID_MAXIMUM = (MBB_PHONEBOOK_CID_SAVE + 1) -} MBB_PHONEBOOK_CID; - -typedef enum _MBB_SAT_CID -{ - MBB_SAT_CID_PAC = 1, - MBB_SAT_CID_TERMINAL_RESPONSE = 2, - MBB_SAT_CID_ENVELOPE = 3, - MBB_SAT_CID_MAXIMUM = (MBB_SAT_CID_ENVELOPE + 1) -} MBB_SAT_CID; - -typedef enum _MBB_AUTH_CID -{ - MBB_AUTH_CID_AKA = 1, - MBB_AUTH_CID_AKAP = 2, - MBB_AUTH_CID_SIM = 3, - MBB_AUTH_CID_MAXIUM = (MBB_AUTH_CID_SIM + 1) -} MBB_AUTH_CID; - -typedef enum _MBB_DSS_CID -{ - MBB_DSS_CID_CONNECT = 1, - MBB_DSS_CID_MAXIUM = (MBB_DSS_CID_CONNECT + 1) -} MBB_DSS_CID; - -typedef enum _MBB_MULTICARRIER_CID -{ - MBB_MULTICARRIER_CID_CAPABILITIES = 1, - MBB_MULTICARRIER_CID_LOCATION_INFO = 2, - MBB_MULTICARRIER_CID_CURRENT_CID_LIST = 3, - MBB_MULTICARRIER_CID_MAXIMUM = (MBB_MULTICARRIER_CID_CURRENT_CID_LIST + 1) -} MBB_MULTICARRIER_CID; - -typedef enum _MBB_HOSTSHUTDOWN_CID -{ - MBB_HOSTSHUTDOWN_CID_ONE = 1, - MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN = 2, - MBB_HOSTSHUTDOWN_CID_MAX = (MBB_HOSTSHUTDOWN_CID_PRESHUTDOWN + 1) -} MBB_HOSTSHUTDOWN_CID; - -typedef enum _MBB_VOICEEXTENSIONS_CID -{ - MBB_VOICEEXTENSIONS_CID_SYS_CAPS = 1, - MBB_VOICEEXTENSIONS_CID_DEVICE_CAPS_V2 = 2, - MBB_VOICEEXTENSIONS_CID_SYS_SLOTMAPPINGS = 3, - MBB_VOICEEXTENSIONS_CID_SLOT_INFO_STATUS = 4, - MBB_VOICEEXTENSIONS_CID_DEVICE_BINDINGS = 5, - MBB_VOICEEXTENSIONS_CID_REGISTER_STATE_V2 = 6, - MBB_VOICEEXTENSIONS_CID_IMS_VOICE_STATE = 7, - MBB_VOICEEXTENSIONS_CID_SIGNAL_STATE_V2 = 8, - MBB_VOICEEXTENSIONS_CID_LOCATION_STATE = 9, - MBB_VOICEEXTENSIONS_CID_NITZ = 10, - MBB_VOICEEXTENSIONS_CID_MAX = (MBB_VOICEEXTENSIONS_CID_NITZ + 1) -} MBB_VOICEEXTENSIONS_CID; - -typedef enum _MBB_UICC_CID -{ - MBB_UICC_CID_ATR = 1, - MBB_UICC_CID_OPEN_CHANNEL = 2, - MBB_UICC_CID_CLOSE_CHANNEL = 3, - MBB_UICC_CID_APDU = 4, - MBB_UICC_CID_TERMINAL_CAPABILITY = 5, - MBB_UICC_CID_RESET = 6, - MBB_UICC_CID_APP_LIST = 7, - MBB_UICC_CID_FILE_STATUS = 8, - MBB_UICC_CID_ACCESS_BINARY = 9, - MBB_UICC_CID_ACCESS_RECORD = 10, - MBB_UICC_CID_MAXIMUM = (MBB_UICC_CID_ACCESS_RECORD + 1) -} MBB_UICC_CID; - -typedef enum _MBB_SAR_CID -{ - MBB_SAR_CID_CONFIG = 1, - MBB_SAR_CID_TRANSMISSION_STATUS = 2, - MBB_SAR_CID_MAXIMUM = (MBB_SAR_CID_TRANSMISSION_STATUS + 1) -} MBB_SAR_CID; - -typedef enum _MBB_BASICCONNECTEXT_CID -{ - MBB_BASICCONNECTEXT_CID_PROVISIONED_CONTEXT_V2 = 1, - MBB_BASICCONNECTEXT_CID_NETWORK_BLACKLIST = 2, - MBB_BASICCONNECTEXT_CID_LTE_ATTACH_CONFIG = 3, - MBB_BASICCONNECTEXT_CID_LTE_ATTACH_STATUS = 4, - MBB_BASICCONNECTEXT_CID_SYS_CAPS = 5, - MBB_BASICCONNECTEXT_CID_DEVICE_CAPS_V2 = 6, - MBB_BASICCONNECTEXT_CID_DEVICE_SLOT_MAPPINGS = 7, - MBB_BASICCONNECTEXT_CID_SLOT_INFO_STATUS = 8, - MBB_BASICCONNECTEXT_CID_PCO = 9, - MBB_BASICCONNECTEXT_CID_DEVICE_RESET = 10, - MBB_BASICCONNECTEXT_CID_BASE_STATIONS_INFO = 11, - MBB_BASICCONNECTEXT_CID_LOCATION_INFO_STATUS = 12, - MBB_BASICCONNECTEXT_CID_MODEM_LOGGING_CONFIG = 13, - MBB_BASICCONNECTEXT_CID_PIN_INFO_EX2 = 14, - MBB_BASICCONNECTEXT_CID_VERSION = 15, - MBB_BASICCONNECTEXT_CID_MODEM_CONFIG = 16, - MBB_BASICCONNECTEXT_CID_REGISTRATION_PARAMS = 17, - MBB_BASICCONNECTEXT_CID_NETWORK_PARAMS = 18, - MBB_BASICCONNECTEXT_CID_WAKE_REASON = 19, - MBB_BASICCONNECTEXT_CID_UE_POLICY = 20, - MBB_BASICCONNECTEXT_CID_MAXIMUM = (MBB_BASICCONNECTEXT_CID_WAKE_REASON + 1) -} MBB_BASICCONNECTEXT_CID; - -typedef enum _MBB_DEVICE_TYPE -{ - MbbDeviceTypeUnknown = 0, - MbbDeviceTypeEmbedded = 1, - MbbDeviceTypeRemovable = 2, - MbbDeviceTypeRemote = 3, - MbbDeviceTypeMaximum = (MbbDeviceTypeRemote + 1) -} MBB_DEVICE_TYPE; - -typedef enum _MBB_CELLULAR_CLASS -{ - MbbCellularClassInvalid = 0, - MbbCellularClassGsm = 1, - MbbCellularClassCdma = 2, - MbbCellularClassMaximum = (MbbCellularClassCdma + 1) -} MBB_CELLULAR_CLASS; - -typedef enum _MBB_VOICE_CLASS -{ - MbbVoiceClassInvalid = 0, - MbbVoiceClassNoVoice = 1, - MbbVoiceClassSeparateVoiceData = 2, - MbbVoiceClassSimultaneousVoiceData = 3, - MbbVoiceClassMaximum = (MbbVoiceClassSimultaneousVoiceData + 1) -} MBB_VOICE_CLASS; - -typedef enum _MBB_SIM_CLASS -{ - MbbSimClassInvalid = 0, - MbbSimClassSimLogical = 1, - MbbSimClassSimRemovable = 2, - MbbSimClassMaximum = (MbbSimClassSimRemovable + 1) -} MBB_SIM_CLASS; - -typedef enum _MBB_DATA_CLASS_VALUE -{ - MbbDataClassNone = 0, - MbbDataClassGprs = 0x1, - MbbDataClassEdge = 0x2, - MbbDataClassUmts = 0x4, - MbbDataClassHsdpa = 0x8, - MbbDataClassHsupa = 0x10, - MbbDataClassLte = 0x20, - MbbDataClass5G = 0x40, - MbbDataClass_UNUSED = 0x80, - MbbDataClassTdScdma = 0x1000, - MbbDataClass1xRtt = 0x10000, - MbbDataClass1xEvdo = 0x20000, - MbbDataClass1xEvdoReva = 0x40000, - MbbDataClass1xEvdv = 0x80000, - MbbDataClass3xRtt = 0x100000, - MbbDataClass1xEvdoRevb = 0x200000, - MbbDataClassUmb = 0x400000, - MbbDataClassCustom = 0x80000000 -} MBB_DATA_CLASS_VALUE; - -typedef enum _MBB_DATA_SUBCLASS_VALUE -{ - MbbDataSubClassNone = 0, - MbbDataSubClass5GENDC = 0x1, - MbbDataSubClass5GNR = 0x2, - MbbDataSubClass5GNEDC = 0x4, - MbbDataSubClass5GELTE = 0x8, - MbbDataSubClassNGENDC = 0x10 -} MBB_DATA_SUBCLASS_VALUE; - -typedef enum _MBB_FREQUENCY_RANGE -{ - MbbFrequencyRangeUnknown = 0, - MbbFrequencyRange1 = 1, - MbbFrequencyRange2 = 2, - MbbFrequencyRange1AndRange2 = 3, - MbbFrequencyRangeMaximum = (MbbFrequencyRange1AndRange2 + 1) -} MBB_FREQUENCY_RANGE; - -typedef enum _MBB_BAND_CLASS_VALUE -{ - MbbBandClassUnknown = 0, - MbbBandClass0 = 0x1, - MbbBandClassI = 0x2, - MbbBandClassII = 0x4, - MbbBandClassIII = 0x8, - MbbBandClassIV = 0x10, - MbbBandClassV = 0x20, - MbbBandClassVI = 0x40, - MbbBandClassVII = 0x80, - MbbBandClassVIII = 0x100, - MbbBandClassIX = 0x200, - MbbBandClassX = 0x400, - MbbBandClassXI = 0x800, - MbbBandClassXII = 0x1000, - MbbBandClassXIII = 0x2000, - MbbBandClassXIV = 0x4000, - MbbBandClassXV = 0x8000, - MbbBandClassXVI = 0x10000, - MbbBandClassXVII = 0x20000, - MbbBandClassCustom = 0x80000000 -} MBB_BAND_CLASS_VALUE; - -typedef enum _MBB_SMS_CAPS_VALUE -{ - MbbSmsCapsNone = 0, - MbbSmsCapsPduReceive = 0x1, - MbbSmsCapsPduSend = 0x2, - MbbSmsCapsTextReceive = 0x4, - MbbSmsCapsTextSend = 0x8 -} MBB_SMS_CAPS_VALUE; - -typedef enum _MBB_CONTROL_CAPS_VALUE -{ - MbbControlCapsNone = 0, - MbbControlCapsRegManual = 0x1, - MbbControlCapsHwRadioSwitch = 0x2, - MbbControlCapsCdmaMobileIp = 0x4, - MbbControlCapsCdmaSimpleIp = 0x8, - MbbControlCapsMultiCarrier = 0x10, - MbbControlCapsESIM = 0x20, - MbbControlCapsUEPolicyRouteSelection = 0x40, - MbbControlCapsSIMHotSwapCapable = 0x80 -} MBB_CONTROL_CAPS_VALUE; - -typedef enum _MBB_READY_STATE -{ - MbbReadyStateOff = 0, - MbbReadyStateInitialized = 1, - MbbReadyStateSimNotInserted = 2, - MbbReadyStateBadSim = 3, - MbbReadyStateFailure = 4, - MbbReadyStateNotActivated = 5, - MbbReadyStateDeviceLocked = 6, - MbbReadyStateNoEsimProfile = 7, - MbbReadyStateMaximum = (MbbReadyStateNoEsimProfile + 1) -} MBB_READY_STATE; - -typedef enum _MBB_READY_INFO_FLAGS -{ - MbbReadyInfoFlagsNone = 0, - MbbReadyInfoFlagsUniqueId = 1 -} MBB_READY_INFO_FLAGS; - -typedef enum _MBB_EMERGENCY_MODE -{ - MbbEmergencyModeOff = 0, - MbbEmergencyModeOn = 1, - MbbEmergencyModeMaximum = (MbbEmergencyModeOn + 1) -} MBB_EMERGENCY_MODE; - -typedef enum _MBB_RADIO_STATE -{ - MbbRadioStateOff = 0, - MbbRadioStateOn = 1, - MbbRadioStateMaximum = (MbbRadioStateOn + 1) -} MBB_RADIO_STATE; - -typedef enum _MBB_PIN_TYPE -{ - MbbPinTypeNone = 0, - MbbPinTypeCustom = 1, - MbbPinTypePin1 = 2, - MbbPinTypePin2 = 3, - MbbPinTypeDeviceSimPin = 4, - MbbPinTypeDeviceFirstSimPin = 5, - MbbPinTypeNetworkPin = 6, - MbbPinTypeNetworkSubsetPin = 7, - MbbPinTypeSvcProviderPin = 8, - MbbPinTypeCorporatePin = 9, - MbbPinTypeSubsidyLock = 10, - MbbPinTypePuk1 = 11, - MbbPinTypePuk2 = 12, - MbbPinTypeDeviceFirstSimPuk = 13, - MbbPinTypeNetworkPuk = 14, - MbbPinTypeNetworkSubsetPuk = 15, - MbbPinTypeSvcProviderPuk = 16, - MbbPinTypeCorporatePuk = 17, - MbbPinTypeNev = 18, - MbbPinTypeAdm = 19, - MbbPinTypeMaximum = (MbbPinTypeAdm + 1) -} MBB_PIN_TYPE; - -typedef enum _MBB_PIN_STATE -{ - MbbPinStateUnlocked = 0, - MbbPinStateLocked = 1, - MbbPinStateMaximum = (MbbPinStateLocked + 1) -} MBB_PIN_STATE; - -typedef enum _MBB_PIN_OPERATION -{ - MbbPinOperationEnter = 0, - MbbPinOperationEnable = 1, - MbbPinOperationDisable = 2, - MbbPinOperationChange = 3, - MbbPinOperationMaximum = (MbbPinOperationChange + 1) -} MBB_PIN_OPERATION; - -typedef enum _MBB_PIN_MODE -{ - MbbPinModeNotSupported = 0, - MbbPinModeEnabled = 1, - MbbPinModeDisabled = 2, - MbbPinModeMaximum = (MbbPinModeDisabled + 1) -} MBB_PIN_MODE; - -typedef enum _MBB_PIN_FORMAT -{ - MbbPinFormatUnknown = 0, - MbbPinFormatNumeric = 1, - MbbPinFormatAlphaNumeric = 2, - MbbPinFormatMaximum = (MbbPinFormatAlphaNumeric + 1) -} MBB_PIN_FORMAT; - -typedef enum _MBB_PROVIDER_STATE_VALUE -{ - MbbProviderStateHome = 0x1, - MbbProviderStateForbidden = 0x2, - MbbProviderStatePreferred = 0x4, - MbbProviderStateVisible = 0x8, - MbbProviderStateRegistered = 0x10, - MbbProviderStatePreferredMulticarrier = 0x20 -} MBB_PROVIDER_STATE_VALUE; - -typedef enum _MBB_REGISTER_ACTION -{ - MbbRegisterActionAutomatic = 0, - MbbRegisterActionManual = 1, - MbbRegisterActionMaximum = (MbbRegisterActionManual + 1) -} MBB_REGISTER_ACTION; - -typedef enum _MBB_REGISTER_STATE -{ - MbbRegisterStateUnknown = 0, - MbbRegisterStateDeregistered = 1, - MbbRegisterStateSearching = 2, - MbbRegisterStateHome = 3, - MbbRegisterStateRoaming = 4, - MbbRegisterStatePartner = 5, - MbbRegisterStateDenied = 6, - MbbRegisterStateMaximum = (MbbRegisterStateDenied + 1) -} MBB_REGISTER_STATE; - -typedef enum _MBB_REGISTER_MODE -{ - MbbRegisterModeUnknown = 0, - MbbRegisterModeAutomatic = 1, - MbbRegisterModeManual = 2, - MbbRegisterModeMaximum = (MbbRegisterModeManual + 1) -} MBB_REGISTER_MODE; - -typedef enum _MBB_PACKET_SERVICE_ACTION -{ - MbbPacketServiceActionAttach = 0, - MbbPacketServiceActionDetach = 1, - MbbPacketServiceActionMaximum = (MbbPacketServiceActionDetach + 1) -} MBB_PACKET_SERVICE_ACTION; - -typedef enum _MBB_PACKET_SERVICE_STATE -{ - MbbPacketServiceStateUnknown = 0, - MbbPacketServiceStateAttaching = 1, - MbbPacketServiceStateAttached = 2, - MbbPacketServiceStateDetaching = 3, - MbbPacketServiceStateDetached = 4, - MbbPacketServiceStateMaximum = (MbbPacketServiceStateDetached + 1) -} MBB_PACKET_SERVICE_STATE; - -typedef enum _MBB_CONTEXT_IP_TYPE -{ - MbbContextIPTypeDefault = 0, - MbbContextIPTypeIPv4 = 1, - MbbContextIPTypeIPv6 = 2, - MbbContextIPTypeIPv4v6 = 3, - MbbContextIPTypeIPv4AndIPv6 = 4, - MbbContextIPTypeMaximum = (MbbContextIPTypeIPv4AndIPv6 + 1) -} MBB_CONTEXT_IP_TYPE; - -typedef enum _MBB_ACTIVATION_COMMAND -{ - MbbActivationCommandDeactivate = 0, - MbbActivationCommandActivate = 1, - MbbActivationCommandCancel = 2, - MbbActivationCommandMaximum = (MbbActivationCommandCancel + 1) -} MBB_ACTIVATION_COMMAND; - -typedef enum _MBB_COMPRESSION -{ - MbbCompressionNone = 0, - MbbCompressionEnable = 1, - MbbCompressionMaximum = (MbbCompressionEnable + 1) -} MBB_COMPRESSION; - -typedef enum _MBB_AUTH_PROTOCOL -{ - MbbAuthProtocolNone = 0, - MbbAuthProtocolPap = 1, - MbbAuthProtocolChap = 2, - MbbAuthProtocolMsChapV2 = 3, - MbbAuthProtocolMaximum = (MbbAuthProtocolMsChapV2 + 1) -} MBB_AUTH_PROTOCOL; - -typedef enum _MBB_ACTIVATION_STATE -{ - MbbActivationStateUnknown = 0, - MbbActivationStateActivated = 1, - MbbActivationStateActivating = 2, - MbbActivationStateDeactivated = 3, - MbbActivationStateDeactivating = 4, - MbbActivationStateMaximum = (MbbActivationStateDeactivating + 1) -} MBB_ACTIVATION_STATE; - -typedef enum _MBB_VOICE_CALL_STATE -{ - MbbVoiceCallStateNone = 0, - MbbVoiceCallStateInProgress = 1, - MbbVoiceCallStateHangUp = 2, - MbbVoiceCallStateMaximum = (MbbVoiceCallStateHangUp + 1) -} MBB_VOICE_CALL_STATE; - -typedef enum _MBB_SMS_FORMAT -{ - MbbSmsFormatPdu = 0, - MbbSmsFormatCdma = 1, - MbbSmsFormatMaximum = (MbbSmsFormatCdma + 1) -} MBB_SMS_FORMAT; - -typedef enum _MBB_SMS_FLAG -{ - MbbSmsFlagAll = 0, - MbbSmsFlagIndex = 1, - MbbSmsFlagNew = 2, - MbbSmsFlagOld = 3, - MbbSmsFlagSent = 4, - MbbSmsFlagDraft = 5, - MbbSmsFlagMaximum = (MbbSmsFlagDraft + 1) -} MBB_SMS_FLAG; - -typedef enum _MBB_SMS_CDMA_LANGUAGE -{ - MbbSmsCdmaLanguageUnknown = 0, - MbbSmsCdmaLanguageEnglish = 1, - MbbSmsCdmaLanguageFrench = 2, - MbbSmsCdmaLanguageSpanish = 3, - MbbSmsCdmaLanguageJapanese = 4, - MbbSmsCdmaLanguageKorean = 5, - MbbSmsCdmaLanguageChinese = 6, - MbbSmsCdmaLanguageHebrew = 7, - MbbSmsCdmaLanguageMaximum = (MbbSmsCdmaLanguageHebrew + 1) -} MBB_SMS_CDMA_LANGUAGE; - -typedef enum _MBB_SMS_CDMA_ENCODING -{ - MbbSmsCdmaEncodingOctet = 0, - MbbSmsCdmaEncodingEpm = 1, - MbbSmsCdmaEncoding7BitAscii = 2, - MbbSmsCdmaEncodingIa5 = 3, - MbbSmsCdmaEncodingUnicode = 4, - MbbSmsCdmaEncodingShiftJis = 5, - MbbSmsCdmaEncodingKorean = 6, - MbbSmsCdmaEncodingLatinHebrew = 7, - MbbSmsCdmaEncodingLatin = 8, - MbbSmsCdmaEncodingGsm7Bit = 9, - MbbSmsCdmaEncodingMaximum = (MbbSmsCdmaEncodingGsm7Bit + 1) -} MBB_SMS_CDMA_ENCODING; - -typedef enum _MBB_SMS_MESSAGE_STATUS -{ - MbbSmsMessageStatusNew = 0, - MbbSmsMessageStatusOld = 1, - MbbSmsMessageStatusDraft = 2, - MbbSmsMessageStatusSent = 3, - MbbSmsMessageStatusMaximum = (MbbSmsMessageStatusSent + 1) -} MBB_SMS_MESSAGE_STATUS; - -typedef enum _MBB_REG_FLAGS_VALUE -{ - MbbRegFlagsNone = 0, - MbbRegFlagsNoManualReg = 0x1, - MbbRegFlagsPSAutoAttach = 0x2 -} MBB_REG_FLAGS_VALUE; - -typedef enum _MBB_SMS_STATUS_FLAGS_VALUE -{ - MbbSmsFlagNone = 0, - MbbSmsFlagMessageStoreFull = 1, - MbbSmsFlagNewMessage = 2 -} MBB_SMS_STATUS_FLAGS_VALUE; - -typedef struct _MBB_STRING -{ - ULONG Offset; - ULONG Size; -} MBB_STRING; - -typedef struct _MBB_STRING* PMBB_STRING; - -typedef struct _MBB_ARRAY_ELEMENT -{ - ULONG Offset; - ULONG Size; -} MBB_ARRAY_ELEMENT; - -typedef struct _MBB_ARRAY_ELEMENT* PMBB_ARRAY_ELEMENT; - -typedef struct _MBB_ARRAY_ELEMENT2 -{ - ULONG Size; - ULONG Offset; -} MBB_ARRAY_ELEMENT2; - -typedef struct _MBB_ARRAY_ELEMENT2* PMBB_ARRAY_ELEMENT2; - -typedef enum _MBB_DSS_PAYLOAD_SUPPORT -{ - MbbDssPayloadNone = 0, - MbbDssPayloadHostToDevice = 0x1, - MbbDssPayloadDeviceToHost = 0x2 -} MBB_DSS_PAYLOAD_SUPPORT; - -typedef enum _MBB_DSS_LINK_STATE -{ - MbbDssLinkDeactivate = 0, - MbbDssLinkActivate = 0x1 -} MBB_DSS_LINK_STATE; - -typedef enum _MBB_IP_CONFIGURATION_FLAGS_VALUE -{ - MbbIpFlagsNone = 0, - MbbIpFlagsAddressAvailable = 0x1, - MbbIpFlagsGatewayAvailable = 0x2, - MbbIpFlagsDnsServerAvailable = 0x4, - MbbIpFlagsMTUAvailable = 0x8 -} MBB_IP_CONFIGURATION_FLAGS_VALUE; - -typedef enum _MBB_NETWORK_IDLE_HINT_STATE -{ - MbbNetworkIdleHintDisabled = 0, - MbbNetworkIdleHintEnabled = 1 -} MBB_NETWORK_IDLE_HINT_STATE; - -typedef enum _MBB_SAR_BACKOFF_STATE -{ - MbbSarBackoffStatusDisabled = 0, - MbbSarBackoffStatusEnabled = 1, - MbbSarBackoffStatusMaximum = (MbbSarBackoffStatusEnabled + 1) -} MBB_SAR_BACKOFF_STATE; - -typedef enum _MBB_SAR_CONTROL_MODE -{ - MbbSarControlModeDevice = 0, - MbbSarControlModeOS = 1, - MbbSarControlModeMaximum = (MbbSarControlModeOS + 1) -} MBB_SAR_CONTROL_MODE; - -typedef enum _MBB_SAR_WIFI_HARDWARE_INTEGRATION -{ - MbbSarWifiHardwareNotIntegrated = 0, - MbbSarWifiHardwareIntegrated = 1, - MbbSarWifiHardwareIntegrationMaximum = (MbbSarWifiHardwareIntegrated + 1) -} MBB_SAR_WIFI_HARDWARE_INTEGRATION; - -typedef enum _MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE -{ - MbbTransmissionNotificationDisabled = 0, - MbbTransmissionNotificationEnabled = 1, - MbbTransmissionNotificationMaximum = (MbbTransmissionNotificationEnabled + 1) -} MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE; - -typedef enum _MBB_SAR_TRANSMISSION_STATUS -{ - MbbTransmissionStateInactive = 0, - MbbTransmissionStateActive = 1, - MbbTransmissionStateMaximum = (MbbTransmissionStateActive + 1) -} MBB_SAR_TRANSMISSION_STATUS; - -typedef enum _MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL -{ - MbbMsContextRoamingControlHomeOnly = 0, - MbbMsContextRoamingControlPartnerOnly = 1, - MbbMsContextRoamingControlNonPartnerOnly = 2, - MbbMsContextRoamingControlHomeAndPartner = 3, - MbbMsContextRoamingControlHomeAndNonPartner = 4, - MbbMsContextRoamingControlPartnerAndNonPartner = 5, - MbbMsContextRoamingControlAllowAll = 6, - MbbMsContextRoamingControlMaximum = (MbbMsContextRoamingControlAllowAll + 1) -} MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL; - -typedef enum _MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE -{ - MbbMsContextMediaTypeCellularOnly = 0, - MbbMsContextMediaTypeWifiOnly = 1, - MbbMsContextMediaTypeAll = 2, - MbbMsContextMediaTypeMaximum = (MbbMsContextMediaTypeAll + 1) -} MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE; - -typedef enum _MBB_BASICCONNECTEXT_CONTEXT_ENABLE -{ - MbbMsContextDisabled = 0, - MbbMsContextEnabled = 1, - MbbMsContextEnableMaximum = (MbbMsContextEnabled + 1) -} MBB_BASICCONNECTEXT_CONTEXT_ENABLE; - -typedef enum _MBB_BASICCONNECTEXT_CONTEXT_SOURCE -{ - MbbMsContextSourceAdmin = 0, - MbbMsContextSourceUser = 1, - MbbMsContextSourceOperator = 2, - MbbMsContextSourceModem = 3, - MbbMsContextSourceDevice = 4, - MbbMsContextSourceMaximum = (MbbMsContextSourceDevice + 1) -} MBB_BASICCONNECTEXT_CONTEXT_SOURCE; - -typedef enum _MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS -{ - MbbMsContextOperationDefault = 0, - MbbMsContextOperationDelete = 1, - MbbMsContextOperationRestoreFactory = 2, - MbbMsContextOperationMaximum = (MbbMsContextOperationRestoreFactory + 1) -} MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS; - -typedef enum _MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE -{ - MbbMsNetworkBlacklistStateNotActuated = 0, - MbbMsNetworkBlacklistSIMProviderActuated = 1, - MbbMsNetworkBlacklistNetworkProviderActuated = 2, - MbbMsNetworkBlacklistStateMaximum = (MbbMsNetworkBlacklistNetworkProviderActuated + 1) -} MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE; - -typedef enum _MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE -{ - MbbMsNetworkBlacklistTypeSIM = 0, - MbbMsNetworkBlacklistTypeNetwork = 1, - MbbMsNetworkBlacklistTypeMaximum = (MbbMsNetworkBlacklistTypeNetwork + 1) -} MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE; - -typedef enum _MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL -{ - MbbMsLteAttachContextRoamingControlHome = 0, - MbbMsLteAttachContextRoamingControlPartner = 1, - MbbMsLteAttachContextRoamingControlNonPartner = 2, - MbbMsLteAttachContextRoamingControlMaximum = (MbbMsLteAttachContextRoamingControlNonPartner + 1) -} MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL; - -typedef enum _MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS -{ - MbbMsLteAttachContextOperationDefault = 0, - MbbMsLteAttachContextOperationRestoreFactory = 1, - MbbMsLteAttachContextOperationMaximum = (MbbMsLteAttachContextOperationRestoreFactory + 1) -} MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS; - -typedef enum _MBB_BASICCONNECTEXT_LTEATTACH_STATE -{ - MbbMsLteAttachStateDetached = 0, - MbbMsLteAttachStateAttached = 1, - MbbMsLteAttachStateMaximum = (MbbMsLteAttachStateAttached + 1) -} MBB_BASICCONNECTEXT_LTEATTACH_STATE; - -typedef enum _MBB_BASICCONNECTEXT_UICCSLOT_STATE -{ - MbbMsUiccSlotStateUnknown = 0, - MbbMsUiccSlotStateOffEmpty = 1, - MbbMsUiccSlotStateOff = 2, - MbbMsUiccSlotStateEmpty = 3, - MbbMsUiccSlotStateNotReady = 4, - MbbMsUiccSlotStateActive = 5, - MbbMsUiccSlotStateError = 6, - MbbMsUiccSlotStateActiveEsim = 7, - MbbMsUiccSlotStateActiveEsimNoProfiles = 8 -} MBB_BASICCONNECTEXT_UICCSLOT_STATE; - -typedef enum _MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG -{ - MbbMsModemLoggingLevelProd = 0, - MbbMsModemLoggingLevelLabVerbose = 1, - MbbMsModemLoggingLevelLabMedium = 2, - MbbMsModemLoggingLevelLabLow = 3, - MbbMsModemLoggingLevelOem = 4, - MbbMsModemLoggingLevelMaximum = (MbbMsModemLoggingLevelOem + 1) -} MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG; - -typedef enum _MBB_PCO_TYPE -{ - MbbPcoTypeComplete = 0, - MbbPcoTypePartial = 1, - MbbPcoTypeMaximum = (MbbPcoTypePartial + 1) -} MBB_PCO_TYPE; - -typedef struct _MBB_DEVICE_CAPS -{ - MBB_DEVICE_TYPE DeviceType; - MBB_CELLULAR_CLASS CellularClass; - MBB_VOICE_CLASS VoiceClass; - MBB_SIM_CLASS SimClass; - ULONG DataClass; - ULONG SmsCaps; - ULONG ControlCaps; - ULONG dwMaxSessions; - MBB_STRING CustomDataClass; - MBB_STRING DeviceIdString; - MBB_STRING FirmwareInfo; - MBB_STRING HardwareInfo; - UCHAR DataBuffer[1]; -} MBB_DEVICE_CAPS; - -typedef struct _MBB_DEVICE_CAPS* PMBB_DEVICE_CAPS; - -typedef struct _MBB_SUBSCRIBER_READY_INFO -{ - MBB_READY_STATE ReadyState; - MBB_STRING SubscriberId; - MBB_STRING SimIccId; - MBB_READY_INFO_FLAGS ReadyInfoFlags; - ULONG TelephoneNumberCount; - MBB_STRING TelephoneNumbers[1]; -} MBB_SUBSCRIBER_READY_INFO; - -typedef struct _MBB_SUBSCRIBER_READY_INFO* PMBB_SUBSCRIBER_READY_INFO; - -typedef enum _MBB_SUBSCRIBER_READY_STATUS_FLAGS -{ - MbbSubscriberReadyStatusFlagNone = 0, - MbbSubscriberReadyStatusFlagESim = 0x1, - MbbSubscriberReadyStatusFlagSIMRemovabilityKnown = 0x2, - MbbSubscriberReadyStatusFlagSIMRemovable = 0x4 -} MBB_SUBSCRIBER_READY_STATUS_FLAGS; - -typedef struct _MBB_SUBSCRIBER_READY_INFO_EX3 -{ - MBB_READY_STATE ReadyState; - MBB_SUBSCRIBER_READY_STATUS_FLAGS StatusFlags; - MBB_STRING SubscriberId; - MBB_STRING SimIccId; - MBB_READY_INFO_FLAGS ReadyInfoFlags; - ULONG TelephoneNumberCount; - MBB_STRING TelephoneNumbers[1]; -} MBB_SUBSCRIBER_READY_INFO_EX3; - -typedef struct _MBB_SUBSCRIBER_READY_INFO_EX3* PMBB_SUBSCRIBER_READY_INFO_EX3; - -typedef struct _MBB_QUERY_RADIO_STATE -{ - MBB_RADIO_STATE HwRadioState; - MBB_RADIO_STATE SwRadioState; -} MBB_QUERY_RADIO_STATE; - -typedef struct _MBB_QUERY_RADIO_STATE* PMBB_QUERY_RADIO_STATE; - -typedef struct _MBB_PIN_INFO -{ - MBB_PIN_TYPE PinType; - MBB_PIN_STATE PinState; - ULONG AttemptsRemaining; -} MBB_PIN_INFO; - -typedef struct _MBB_PIN_INFO* PMBB_PIN_INFO; - -typedef struct _MBB_PIN_ACTION -{ - MBB_PIN_TYPE PinType; - MBB_PIN_OPERATION PinOperation; - MBB_STRING Pin; - MBB_STRING NewPin; - UCHAR DataBuffer[1]; -} MBB_PIN_ACTION; - -typedef struct _MBB_PIN_ACTION* PMBB_PIN_ACTION; - -typedef struct _MBB_PIN_DESCRIPTION -{ - MBB_PIN_MODE PinMode; - MBB_PIN_FORMAT PinFormat; - ULONG PinLengthMin; - ULONG PinLengthMax; -} MBB_PIN_DESCRIPTION; - -typedef struct _MBB_PIN_DESCRIPTION* PMBB_PIN_DESCRIPTION; - -typedef struct _MBB_PIN_LIST -{ - MBB_PIN_DESCRIPTION PinDescPin1; - MBB_PIN_DESCRIPTION PinDescPin2; - MBB_PIN_DESCRIPTION PinDescDeviceSimPin; - MBB_PIN_DESCRIPTION PinDescDeviceFirstSimPin; - MBB_PIN_DESCRIPTION PinDescNetworkPin; - MBB_PIN_DESCRIPTION PinDescNetworkSubsetPin; - MBB_PIN_DESCRIPTION PinDescSvcProviderPin; - MBB_PIN_DESCRIPTION PinDescCorporatePin; - MBB_PIN_DESCRIPTION PinDescSubsidyLock; - MBB_PIN_DESCRIPTION PinDescCustom; -} MBB_PIN_LIST; - -typedef struct _MBB_PIN_LIST* PMBB_PIN_LIST; - -typedef struct _MBB_PROVIDER -{ - MBB_STRING ProviderId; - ULONG ProviderState; - MBB_STRING ProviderName; - MBB_CELLULAR_CLASS CellularClass; - ULONG Rssi; - ULONG ErrorRate; -} MBB_PROVIDER; - -typedef struct _MBB_PROVIDER* PMBB_PROVIDER; - -typedef struct _MBB_PROVIDER_LIST -{ - ULONG ProviderCount; - MBB_ARRAY_ELEMENT Providers[1]; -} MBB_PROVIDER_LIST; - -typedef struct _MBB_PROVIDER_LIST* PMBB_PROVIDER_LIST; - -typedef struct _MBB_REGISTRATION_STATE -{ - ULONG NetworkError; - MBB_REGISTER_STATE RegisterState; - MBB_REGISTER_MODE RegisterMode; - ULONG AvailableDataClasses; - MBB_CELLULAR_CLASS CurrentCellularClass; - MBB_STRING ProviderId; - MBB_STRING ProviderName; - MBB_STRING RoamingText; - ULONG RegFlags; - UCHAR DataBuffer[1]; -} MBB_REGISTRATION_STATE; - -typedef struct _MBB_REGISTRATION_STATE* PMBB_REGISTRATION_STATE; - -typedef struct _MBB_SET_REGISTER_STATE -{ - MBB_STRING ProviderId; - MBB_REGISTER_ACTION RegisterAction; - ULONG DataClass; - UCHAR DataBuffer[1]; -} MBB_SET_REGISTER_STATE; - -typedef struct _MBB_SET_REGISTER_STATE* PMBB_SET_REGISTER_STATE; - -typedef struct _MBB_SET_PACKET_SERVICE -{ - MBB_PACKET_SERVICE_ACTION PacketServiceAction; -} MBB_SET_PACKET_SERVICE; - -typedef struct _MBB_SET_PACKET_SERVICE* PMBB_SET_PACKET_SERVICE; - -typedef struct _MBB_PACKET_SERVICE -{ - ULONG NetworkError; - MBB_PACKET_SERVICE_STATE PacketServiceState; - ULONG HighestAvailableDataClass; - ULONGLONG UplinkSpeed; - ULONGLONG DownlinkSpeed; -} MBB_PACKET_SERVICE; - -typedef struct _MBB_PACKET_SERVICE* PMBB_PACKET_SERVICE; - -typedef struct _MBB_PACKET_SERVICE_INFO_V2 -{ - ULONG NetworkError; - MBB_PACKET_SERVICE_STATE PacketServiceState; - MBB_DATA_CLASS_VALUE CurrentDataClass; - ULONGLONG UplinkSpeed; - ULONGLONG DownlinkSpeed; - MBB_FREQUENCY_RANGE FrequencyRange; -} MBB_PACKET_SERVICE_INFO_V2; - -typedef struct _MBB_PACKET_SERVICE_INFO_V2* PMBB_PACKET_SERVICE_INFO_V2; - -typedef struct _MBB_PLMN -{ - USHORT Mcc; - USHORT Mnc; -} MBB_PLMN; - -typedef struct _MBB_PLMN* PMBB_PLMN; - -typedef struct _MBB_TAI -{ - MBB_PLMN Plmn; - ULONG Tac; -} MBB_TAI; - -typedef struct _MBB_TAI* PMBB_TAI; - -typedef struct _MBB_PACKET_SERVICE_INFO_V3 -{ - ULONG NetworkError; - MBB_PACKET_SERVICE_STATE PacketServiceState; - MBB_DATA_CLASS_VALUE CurrentDataClass; - ULONGLONG UplinkSpeed; - ULONGLONG DownlinkSpeed; - MBB_FREQUENCY_RANGE FrequencyRange; - MBB_DATA_SUBCLASS_VALUE CurrentDataSubClass; - MBB_TAI TrackingAreaId; -} MBB_PACKET_SERVICE_INFO_V3; - -typedef struct _MBB_PACKET_SERVICE_INFO_V3* PMBB_PACKET_SERVICE_INFO_V3; - -typedef struct _MBB_SET_SIGNAL_INDICATION -{ - ULONG RssiInterval; - ULONG RssiThreshold; - ULONG ErrorRateThreshold; -} MBB_SET_SIGNAL_INDICATION; - -typedef struct _MBB_SET_SIGNAL_INDICATION* PMBB_SET_SIGNAL_INDICATION; - -typedef struct _MBB_SIGNAL_STATE -{ - ULONG Rssi; - ULONG ErrorRate; - ULONG RssiInterval; - ULONG RssiThreshold; - ULONG ErrorRateThreshold; -} MBB_SIGNAL_STATE; - -typedef struct _MBB_SIGNAL_STATE* PMBB_SIGNAL_STATE; - -typedef struct _MBB_SET_CONTEXT_STATE -{ - ULONG SessionId; - MBB_ACTIVATION_COMMAND ActivationCommand; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - MBB_CONTEXT_IP_TYPE IPType; - GUID ContextType; - CHAR DataBuffer[1]; -} MBB_SET_CONTEXT_STATE; - -typedef struct _MBB_SET_CONTEXT_STATE* PMBB_SET_CONTEXT_STATE; - -typedef enum _MBB_ACCESS_MEDIA_PREF -{ - MbbAccessMediaPrefNone = 0, - MbbAccessMediaPref3GPP = 1, - MbbAccessMediaPref3GPPPreferred = 2, - MbbAccessMediaPrefMaximum = (MbbAccessMediaPref3GPPPreferred + 1) -} MBB_ACCESS_MEDIA_PREF; - -typedef struct _MBB_SET_CONTEXT_STATE_EX3 -{ - ULONG SessionId; - MBB_ACTIVATION_COMMAND ActivationCommand; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - MBB_CONTEXT_IP_TYPE IPType; - GUID ContextType; - MBB_ACCESS_MEDIA_PREF MediaPreference; -} MBB_SET_CONTEXT_STATE_EX3; - -typedef struct _MBB_SET_CONTEXT_STATE_EX3* PMBB_SET_CONTEXT_STATE_EX3; - -typedef struct _MBB_QUERY_CONTEXT_EX3 -{ - ULONG SessionId; -} MBB_QUERY_CONTEXT_EX3; - -typedef struct _MBB_QUERY_CONTEXT_EX3* PMBB_QUERY_CONTEXT_EX3; - -typedef struct _MBB_CONTEXT_STATE -{ - ULONG SessionId; - MBB_ACTIVATION_STATE ActivationState; - MBB_VOICE_CALL_STATE VoiceCallState; - MBB_CONTEXT_IP_TYPE IPType; - GUID ContextType; - ULONG NetworkError; -} MBB_CONTEXT_STATE; - -typedef struct _MBB_CONTEXT_STATE* PMBB_CONTEXT_STATE; - -typedef struct _MBB_CONTEXT_STATE_EX3 -{ - ULONG SessionId; - MBB_ACTIVATION_STATE ActivationState; - MBB_VOICE_CALL_STATE VoiceCallState; - MBB_CONTEXT_IP_TYPE IPType; - GUID ContextType; - ULONG NetworkError; - MBB_ACCESS_MEDIA_PREF MediaPreference; -} MBB_CONTEXT_STATE_EX3; - -typedef struct _MBB_CONTEXT_STATE_EX3* PMBB_CONTEXT_STATE_EX3; - -typedef struct _MBB_SET_CONTEXT -{ - ULONG ContextId; - GUID ContextType; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - MBB_STRING ProviderId; - UCHAR DataBuffer[1]; -} MBB_SET_CONTEXT; - -typedef struct _MBB_SET_CONTEXT* PMBB_SET_CONTEXT; - -typedef struct _MBB_CONTEXT -{ - ULONG ContextId; - GUID ContextType; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - UCHAR DataBuffer[1]; -} MBB_CONTEXT; - -typedef struct _MBB_CONTEXT* PMBB_CONTEXT; - -typedef struct _MBB_CONTEXT_LIST -{ - ULONG ContextCount; - MBB_ARRAY_ELEMENT Contexts[1]; -} MBB_CONTEXT_LIST; - -typedef struct _MBB_CONTEXT_LIST* PMBB_CONTEXT_LIST; - -typedef struct _MBB_SERVICE_ACTIVATION -{ - CHAR VendorSpecificBuffer[1]; -} MBB_SERVICE_ACTIVATION; - -typedef struct _MBB_SERVICE_ACTIVATION* PMBB_SERVICE_ACTIVATION; - -typedef struct _MBB_SERVICE_ACTIVATION_STATUS -{ - ULONG NetworkError; - CHAR VendorSpecificBuffer[1]; -} MBB_SERVICE_ACTIVATION_STATUS; - -typedef struct _MBB_SERVICE_ACTIVATION_STATUS* PMBB_SERVICE_ACTIVATION_STATUS; - -typedef struct _MBB_IPV4_ADDRESS -{ - ULONG OnLinkPrefixLength; - UCHAR IPV4Address[4]; -} MBB_IPV4_ADDRESS; - -typedef struct _MBB_IPV4_ADDRESS* PMBB_IPV4_ADDRESS; - -typedef struct _MBB_IPV6_ADDRESS -{ - ULONG OnLinkPrefixLength; - UCHAR IPV6Address[16]; -} MBB_IPV6_ADDRESS; - -typedef struct _MBB_IPV6_ADDRESS* PMBB_IPV6_ADDRESS; - -typedef struct _MBB_IP_ADDRESS_INFO -{ - ULONG SessionId; - ULONG IPv4Flags; - ULONG IPv6Flags; - ULONG IPv4AddressCount; - ULONG IPv4AddressOffset; - ULONG IPv6AddressCount; - ULONG IPv6AddressOffset; - ULONG IPv4GatewayOffset; - ULONG IPv6GatewayOffset; - ULONG IPv4DnsServerCount; - ULONG IPv4DnsServerOffset; - ULONG IPv6DnsServerCount; - ULONG IPv6DnsServerOffset; - ULONG IPv4MTU; - ULONG IPv6MTU; -} MBB_IP_ADDRESS_INFO; - -typedef struct _MBB_IP_ADDRESS_INFO* PMBB_IP_ADDRESS_INFO; - -typedef struct _MBB_PACKET_STATISTICS -{ - ULONG InDiscards; - ULONG InErrors; - ULONGLONG InOctets; - ULONGLONG InPackets; - ULONGLONG OutOctets; - ULONGLONG OutPackets; - ULONG OutErrors; - ULONG OutDiscards; -} MBB_PACKET_STATISTICS; - -typedef struct _MBB_PACKET_STATISTICS* PMBB_PACKET_STATISTICS; - -typedef enum _MBB_VISIBLE_PROVIDERS_ACTION_VALUE -{ - MbbVisibleProvidersActionFull = 0, - MbbVisibleProvidersActionMulticarrier = 0x1, - MbbVisibleProvidersActionMax = (MbbVisibleProvidersActionMulticarrier + 1) -} MBB_VISIBLE_PROVIDERS_ACTION_VALUE; - -typedef struct _MBB_GET_VISIBLE_PROVIDERS -{ - ULONG Action; -} MBB_GET_VISIBLE_PROVIDERS; - -typedef struct _MBB_GET_VISIBLE_PROVIDERS* PMBB_GET_VISIBLE_PROVIDERS; - -typedef enum _MBB_SMS_STORAGE_STATE -{ - MbbSmsStorageNotInitialized = 0, - MbbSmsStorageInitialized = 1 -} MBB_SMS_STORAGE_STATE; - -typedef struct _MBB_SET_SMS_CONFIGURATION -{ - MBB_SMS_FORMAT SmsFormat; - MBB_STRING ScAddress; - UCHAR DataBuffer[1]; -} MBB_SET_SMS_CONFIGURATION; - -typedef struct _MBB_SET_SMS_CONFIGURATION* PMBB_SET_SMS_CONFIGURATION; - -typedef struct _MBB_SMS_CONFIGURATION -{ - MBB_SMS_STORAGE_STATE SmsStorageState; - MBB_SMS_FORMAT SmsFormat; - ULONG MaxMessages; - ULONG CdmaShortMessageSize; - MBB_STRING ScAddress; - UCHAR DataBuffer[1]; -} MBB_SMS_CONFIGURATION; - -typedef struct _MBB_SMS_CONFIGURATION* PMBB_SMS_CONFIGURATION; - -typedef struct _MBB_SMS_READ -{ - MBB_SMS_FORMAT SmsFormat; - MBB_SMS_FLAG SmsFlag; - ULONG MessageIndex; -} MBB_SMS_READ; - -typedef struct _MBB_SMS_READ* PMBB_SMS_READ; - -typedef struct _MBB_SMS_CDMA_RECORD -{ - ULONG MessageIndex; - MBB_SMS_MESSAGE_STATUS MessageStatus; - MBB_STRING Address; - MBB_STRING TimeStamp; - MBB_SMS_CDMA_ENCODING EncodingId; - MBB_SMS_CDMA_LANGUAGE LanguageId; - MBB_ARRAY_ELEMENT EncodedMessage; - ULONG SizeInCharacters; - UCHAR DataBuffer[1]; -} MBB_SMS_CDMA_RECORD; - -typedef struct _MBB_SMS_CDMA_RECORD* PMBB_SMS_CDMA_RECORD; - -typedef struct _MBB_SMS_PDU_RECORD -{ - ULONG MessageIndex; - MBB_SMS_MESSAGE_STATUS MessageStatus; - MBB_ARRAY_ELEMENT PduData; - UCHAR DataBuffer[1]; -} MBB_SMS_PDU_RECORD; - -typedef struct _MBB_SMS_PDU_RECORD* PMBB_SMS_PDU_RECORD; - -typedef struct _MBB_SMS_RECEIVE -{ - MBB_SMS_FORMAT SmsFormat; - ULONG MessageCount; - MBB_ARRAY_ELEMENT MessageElement[1]; -} MBB_SMS_RECEIVE; - -typedef struct _MBB_SMS_RECEIVE* PMBB_SMS_RECEIVE; - -typedef struct _MBB_SMS_SEND_PDU -{ - MBB_ARRAY_ELEMENT PduData; - UCHAR DataBuffer[1]; -} MBB_SMS_SEND_PDU; - -typedef struct _MBB_SMS_SEND_PDU* PMBB_SMS_SEND_PDU; - -typedef struct _MBB_SMS_SEND_CDMA -{ - MBB_SMS_CDMA_ENCODING EncodingId; - MBB_SMS_CDMA_LANGUAGE LanguageId; - MBB_STRING Address; - MBB_ARRAY_ELEMENT EncodedMessage; - ULONG SizeInCharacters; - UCHAR DataBuffer[1]; -} MBB_SMS_SEND_CDMA; - -typedef struct _MBB_SMS_SEND_CDMA* PMBB_SMS_SEND_CDMA; - -typedef struct _MBB_SMS_SEND -{ - MBB_SMS_FORMAT SmsFormat; - /* [switch_is] */ /* [switch_type] */ union __MIDL___MIDL_itf_MbbMessages_0000_0000_0001 - { - /* [case()] */ MBB_SMS_SEND_PDU Pdu; - /* [case()] */ MBB_SMS_SEND_CDMA Cdma; - } u; -} MBB_SMS_SEND; - -typedef struct _MBB_SMS_SEND* PMBB_SMS_SEND; - -typedef struct _MBB_SMS_SEND_STATUS -{ - ULONG MessageReference; -} MBB_SMS_SEND_STATUS; - -typedef struct _MBB_SMS_SEND_STATUS* PMBB_SMS_SEND_STATUS; - -typedef struct _MBB_SMS_DELETE -{ - MBB_SMS_FLAG SmsFlags; - ULONG MessageIndex; -} MBB_SMS_DELETE; - -typedef struct _MBB_SMS_DELETE* PMBB_SMS_DELETE; - -typedef struct _MBB_SMS_STATUS -{ - ULONG StatusFlags; - ULONG MessageIndex; -} MBB_SMS_STATUS; - -typedef struct _MBB_SMS_STATUS* PMBB_SMS_STATUS; - -typedef enum _MBB_USSD_ACTION -{ - MbbUSSDInitiate = 0, - MbbUSSDContinue = 1, - MbbUSSDCancel = 2 -} MBB_USSD_ACTION; - -typedef enum _MBB_USSD_RESPONSE -{ - MbbUSSDNoActionRequired = 0, - MbbUSSDActionRequired = 1, - MbbUSSDTerminated = 2, - MbbUSSDOtherLocalClient = 3, - MbbUSSDOperationNotSupported = 4, - MbbUSSDNetworkTimeOut = 5 -} MBB_USSD_RESPONSE; - -typedef enum _MBB_USSD_SESSION_STATE -{ - MbbUSSDNewSession = 0, - MbbUSSDExistingSession = 1 -} MBB_USSD_SESSION_STATE; - -typedef struct _MBB_SET_USSD -{ - MBB_USSD_ACTION USSDAction; - ULONG USSDDataCodingScheme; - MBB_ARRAY_ELEMENT USSDPayload; - UCHAR DataBuffer[1]; -} MBB_SET_USSD; - -typedef struct _MBB_SET_USSD* PMBB_SET_USSD; - -typedef struct _MBB_USSD -{ - MBB_USSD_RESPONSE USSDResponse; - MBB_USSD_SESSION_STATE USSDSessionState; - ULONG USSDDataCodingScheme; - MBB_ARRAY_ELEMENT USSDPayload; - UCHAR DataBuffer[1]; -} MBB_USSD; - -typedef struct _MBB_USSD* PMBB_USSD; - -typedef struct _MBB_AKA_AUTH_CHALLENGE -{ - UCHAR Rand[16]; - UCHAR Autn[16]; -} MBB_AKA_AUTH_CHALLENGE; - -typedef struct _MBB_AKA_AUTH_CHALLENGE* PMBB_AKA_AUTH_CHALLENGE; - -typedef struct _MBB_AKA_AUTH_RESPONSE -{ - UCHAR Res[16]; - ULONG ResLength; - UCHAR IK[16]; - UCHAR CK[16]; - UCHAR Auts[14]; -} MBB_AKA_AUTH_RESPONSE; - -typedef struct _MBB_AKA_AUTH_RESPONSE* PMBB_AKA_AUTH_RESPONSE; - -typedef struct _MBB_AKAP_AUTH_CHALLENGE -{ - UCHAR Rand[16]; - UCHAR Autn[16]; - MBB_STRING NetworkName; - UCHAR DataBuffer[1]; -} MBB_AKAP_AUTH_CHALLENGE; - -typedef struct _MBB_AKAP_AUTH_CHALLENGE* PMBB_AKAP_AUTH_CHALLENGE; - -typedef struct _MBB_AKAP_AUTH_RESPONSE -{ - UCHAR Res[16]; - ULONG ResLength; - UCHAR IK[16]; - UCHAR CK[16]; - UCHAR Auts[14]; -} MBB_AKAP_AUTH_RESPONSE; - -typedef struct _MBB_AKAP_AUTH_RESPONSE* PMBB_AKAP_AUTH_RESPONSE; - -typedef struct _MBB_SIM_AUTH_CHALLENGE -{ - UCHAR Rand1[16]; - UCHAR Rand2[16]; - UCHAR Rand3[16]; - ULONG n; -} MBB_SIM_AUTH_CHALLENGE; - -typedef struct _MBB_SIM_AUTH_CHALLENGE* PMBB_SIM_AUTH_CHALLENGE; - -typedef struct _MBB_SIM_AUTH_RESPONSE -{ - UCHAR Sres1[4]; - UCHAR Kc1[8]; - UCHAR Sres2[4]; - UCHAR Kc2[8]; - UCHAR Sres3[4]; - UCHAR Kc3[8]; - ULONG n; -} MBB_SIM_AUTH_RESPONSE; - -typedef struct _MBB_SIM_AUTH_RESPONSE* PMBB_SIM_AUTH_RESPONSE; - -typedef struct _MBB_PACKET_FILTERS -{ - ULONG SessionId; - ULONG PacketFiltersCount; - MBB_ARRAY_ELEMENT ArrayElement[1]; -} MBB_PACKET_FILTERS; - -typedef struct _MBB_PACKET_FILTERS* PMBB_PACKET_FILTERS; - -typedef struct _MBB_SINGLE_PACKET_FILTER -{ - ULONG FilterSize; - ULONG PacketFilterOffset; - ULONG PacketMaskOffset; - UCHAR DataBuffer[1]; -} MBB_SINGLE_PACKET_FILTER; - -typedef struct _MBB_SINGLE_PACKET_FILTER* PMBB_SINGLE_PACKET_FILTER; - -typedef struct _MBB_SINGLE_PACKET_FILTER_V2 -{ - ULONG FilterSize; - ULONG PacketFilterOffset; - ULONG PacketMaskOffset; - ULONG FilterId; - UCHAR DataBuffer[1]; -} MBB_SINGLE_PACKET_FILTER_V2; - -typedef struct _MBB_SINGLE_PACKET_FILTER_V2* PMBB_SINGLE_PACKET_FILTER_V2; - -typedef struct _MBB_NETWORK_IDLE_HINT -{ - MBB_NETWORK_IDLE_HINT_STATE NetworkIdleHintState; -} MBB_NETWORK_IDLE_HINT; - -typedef struct _MBB_NETWORK_IDLE_HINT* PMBB_NETWORK_IDLE_HINT; - -typedef struct _MBB_DEVICE_SERVICE_ELEMENT -{ - GUID DeviceServiceId; - MBB_DSS_PAYLOAD_SUPPORT DSSPayload; - ULONG MaxDSSInstances; - ULONG CIDCount; - ULONG CIDList[1]; -} MBB_DEVICE_SERVICE_ELEMENT; - -typedef struct _MBB_DEVICE_SERVICE_ELEMENT* PMBB_DEVICE_SERVICE_ELEMENT; - -typedef struct _MBB_DEVICE_SERVICES_HEADER -{ - ULONG DeviceServicesCount; - ULONG MaxDSSSessions; - MBB_ARRAY_ELEMENT ArrayElement[1]; -} MBB_DEVICE_SERVICES_HEADER; - -typedef struct _MBB_DEVICE_SERVICES_HEADER* PMBB_DEVICE_SERVICES_HEADER; - -typedef struct _MBB_SUBSCRIBE_EVENT_ENTRY -{ - GUID DeviceServiceId; - ULONG CIDCount; - ULONG CIDList[1]; -} MBB_SUBSCRIBE_EVENT_ENTRY; - -typedef struct _MBB_SUBSCRIBE_EVENT_ENTRY* PMBB_SUBSCRIBE_EVENT_ENTRY; - -typedef struct _MBB_SUBSCRIBE_EVENT_LIST -{ - ULONG Count; - MBB_ARRAY_ELEMENT ArrayElement[1]; -} MBB_SUBSCRIBE_EVENT_LIST; - -typedef struct _MBB_SUBSCRIBE_EVENT_LIST* PMBB_SUBSCRIBE_EVENT_LIST; - -typedef struct _MBB_SET_DSS_CONNECT -{ - GUID DeviceServiceId; - ULONG DssSessionId; - MBB_DSS_LINK_STATE DssLinkState; -} MBB_SET_DSS_CONNECT; - -typedef struct _MBB_SET_DSS_CONNECT* PMBB_SET_DSS_CONNECT; - -typedef struct _MBB_SET_DSS_CLOSE -{ - ULONG DssSessionId; -} MBB_SET_DSS_CLOSE; - -typedef struct _MBB_SET_DSS_CLOSE* PMBB_SET_DSS_CLOSE; - -typedef struct _MBB_MULTICARRIER_CURRENT_CID_LIST -{ - ULONG CIDCount; - ULONG CIDList[1]; -} MBB_MULTICARRIER_CURRENT_CID_LIST; - -typedef struct _MBB_MULTICARRIER_CURRENT_CID_LIST* PMBB_MULTICARRIER_CURRENT_CID_LIST; - -typedef enum _MBB_UICC_APP_TYPE -{ - MbbUiccAppTypeUnknown = 0, - MbbUiccAppTypeMf = 1, - MbbUiccAppTypeMfSIM = 2, - MbbUiccAppTypeMfRUIM = 3, - MbbUiccAppTypeUSIM = 4, - MbbUiccAppTypeCSIM = 5, - MbbUiccAppTypeISIM = 6, - MbbUiccAppTypeMax = (MbbUiccAppTypeISIM + 1) -} MBB_UICC_APP_TYPE; - -typedef struct _MBB_UICC_APP_INFO -{ - MBB_UICC_APP_TYPE AppType; - MBB_ARRAY_ELEMENT AppId; - MBB_ARRAY_ELEMENT AppName; - ULONG NumPins; - MBB_ARRAY_ELEMENT PinRef; - UCHAR DataBuffer[1]; -} MBB_UICC_APP_INFO; - -typedef struct _MBB_UICC_APP_INFO* PMBB_UICC_APP_INFO; - -typedef struct _MBB_UICC_APP_LIST -{ - ULONG Version; - ULONG AppCount; - ULONG ActiveAppIndex; - ULONG AppListSize; - MBB_ARRAY_ELEMENT DataBuffer[1]; -} MBB_UICC_APP_LIST; - -typedef struct _MBB_UICC_APP_LIST* PMBB_UICC_APP_LIST; - -typedef enum _MBB_UICC_FILE_ACCESSIBILITY -{ - MbbUiccFileAccessibilityUnknown = 0, - MbbUiccFileAccessibilityNotShareable = 1, - MbbUiccFileAccessibilityShareable = 2, - MbbUiccFileAccessibilityMax = (MbbUiccFileAccessibilityShareable + 1) -} MBB_UICC_FILE_ACCESSIBILITY; - -typedef enum _MBB_UICC_FILE_TYPE -{ - MbbUiccFileTypeUnknown = 0, - MbbUiccFileTypeWorkingEf = 1, - MbbUiccFileTypeInternalEf = 2, - MbbUiccFileTypeDfOrAdf = 3, - MbbUiccFileTypeMax = (MbbUiccFileTypeDfOrAdf + 1) -} MBB_UICC_FILE_TYPE; - -typedef enum _MBB_UICC_FILE_STRUCTURE -{ - MbbUiccFileStructureUnknown = 0, - MbbUiccFileStructureTransparent = 1, - MbbUiccFileStructureCyclic = 2, - MbbUiccFileStructureLinear = 3, - MbbUiccFileStructureBertlv = 4, - MbbUiccFileStructureMax = (MbbUiccFileStructureBertlv + 1) -} MBB_UICC_FILE_STRUCTURE; - -typedef struct _MBB_UICC_FILE_PATH -{ - ULONG Version; - MBB_ARRAY_ELEMENT AppId; - MBB_ARRAY_ELEMENT FilePath; - UCHAR DataBuffer[1]; -} MBB_UICC_FILE_PATH; - -typedef struct _MBB_UICC_FILE_PATH* PMBB_UICC_FILE_PATH; - -typedef struct _MBB_UICC_FILE_STATUS -{ - ULONG Version; - ULONG StatusWord1; - ULONG StatusWord2; - MBB_UICC_FILE_ACCESSIBILITY FileAccessibility; - MBB_UICC_FILE_TYPE FileType; - MBB_UICC_FILE_STRUCTURE FileStructure; - ULONG ItemCount; - ULONG ItemSize; - MBB_PIN_TYPE FileLockStatus[4]; -} MBB_UICC_FILE_STATUS; - -typedef struct _MBB_UICC_FILE_STATUS* PMBB_UICC_FILE_STATUS; - -typedef struct _MBB_UICC_ACCESS_BINARY -{ - ULONG Version; - MBB_ARRAY_ELEMENT AppId; - MBB_ARRAY_ELEMENT UiccFilePath; - ULONG FileOffset; - ULONG NumberOfBytes; - MBB_ARRAY_ELEMENT LocalPin; - MBB_ARRAY_ELEMENT BinaryData; - UCHAR DataBuffer[1]; -} MBB_UICC_ACCESS_BINARY; - -typedef struct _MBB_UICC_ACCESS_BINARY* PMBB_UICC_ACCESS_BINARY; - -typedef struct _MBB_UICC_ACCESS_RECORD -{ - ULONG Version; - MBB_ARRAY_ELEMENT AppId; - MBB_ARRAY_ELEMENT UiccFilePath; - ULONG RecordNumber; - MBB_ARRAY_ELEMENT LocalPin; - MBB_ARRAY_ELEMENT RecordData; - UCHAR DataBuffer[1]; -} MBB_UICC_ACCESS_RECORD; - -typedef struct _MBB_UICC_ACCESS_RECORD* PMBB_UICC_ACCESS_RECORD; - -typedef struct _MBB_UICC_RESPONSE -{ - ULONG Version; - ULONG StatusWord1; - ULONG StatusWord2; - MBB_ARRAY_ELEMENT ResponseData; - UCHAR DataBuffer[1]; -} MBB_UICC_RESPONSE; - -typedef struct _MBB_UICC_RESPONSE* PMBB_UICC_RESPONSE; - -typedef struct _MBB_PIN_APP -{ - ULONG Version; - MBB_ARRAY_ELEMENT AppId; - UCHAR DataBuffer[1]; -} MBB_PIN_APP; - -typedef struct _MBB_PIN_APP* PMBB_PIN_APP; - -typedef struct _MBB_PIN_ACTION_EX2 -{ - MBB_PIN_TYPE PinType; - MBB_PIN_OPERATION PinOperation; - MBB_STRING Pin; - MBB_STRING NewPin; - MBB_ARRAY_ELEMENT AppId; - UCHAR DataBuffer[1]; -} MBB_PIN_ACTION_EX2; - -typedef struct _MBB_PIN_ACTION_EX2* PMBB_PIN_ACTION_EX2; - -typedef struct _MBB_SYS_CAPS_INFO -{ - ULONG NumberOfExecutors; - ULONG NumberOfSlots; - ULONG Concurrency; -} MBB_SYS_CAPS_INFO; - -typedef struct _MBB_SYS_CAPS_INFO* PMBB_SYS_CAPS_INFO; - -typedef struct _MBB_DEVICE_CAPS_V2 -{ - MBB_DEVICE_TYPE DeviceType; - MBB_CELLULAR_CLASS CellularClass; - MBB_VOICE_CLASS VoiceClass; - MBB_SIM_CLASS SimClass; - ULONG DataClass; - ULONG SmsCaps; - ULONG ControlCaps; - ULONG dwMaxSessions; - MBB_STRING CustomDataClass; - MBB_STRING DeviceIdString; - MBB_STRING FirmwareInfo; - MBB_STRING HardwareInfo; - ULONG DeviceIndex; - UCHAR DataBuffer[1]; -} MBB_DEVICE_CAPS_V2; - -typedef struct _MBB_DEVICE_CAPS_V2* PMBB_DEVICE_CAPS_V2; - -typedef struct _MBB_DEVICE_SLOT_MAPPING_INFO -{ - ULONG MapCount; - MBB_ARRAY_ELEMENT SlotMapList[1]; -} MBB_DEVICE_SLOT_MAPPING_INFO; - -typedef struct _MBB_DEVICE_SLOT_MAPPING_INFO* PMBB_DEVICE_SLOT_MAPPING_INFO; - -typedef enum _MBB_UICCSLOT_STATE -{ - MbbUiccSlotStateOffEmpty = 0, - MbbUiccSlotStateOff = 1, - MbbUiccSlotStateEmpty = 2, - MbbUiccSlotStateNotReady = 3, - MbbUiccSlotStateActive = 4, - MbbUiccSlotStateError = 5 -} MBB_UICCSLOT_STATE; - -typedef struct _MBB_SLOT_INFO_REQ -{ - ULONG SlotIndex; -} MBB_SLOT_INFO_REQ; - -typedef struct _MBB_SLOT_INFO_REQ* PMBB_SLOT_INFO_REQ; - -typedef struct _MBB_SLOT_INFO -{ - ULONG SlotIndex; - MBB_UICCSLOT_STATE State; -} MBB_SLOT_INFO; - -typedef struct _MBB_SLOT_INFO* PMBB_SLOT_INFO; - -typedef struct _MBB_DEVICE_BINDINGS_INFO -{ - ULONG ApplicationCount; - MBB_ARRAY_ELEMENT ApplicationList[1]; -} MBB_DEVICE_BINDINGS_INFO; - -typedef struct _MBB_DEVICE_BINDINGS_INFO* PMBB_DEVICE_BINDINGS_INFO; - -typedef enum _MBB_REGISTRATION_VOICE_CLASS -{ - MbbRegistrationVoiceClassVoiceCentric = 0, - MbbRegistrationVoiceClassDataCentric = 1 -} MBB_REGISTRATION_VOICE_CLASS; - -typedef enum _MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE -{ - MbbRegistrationVoiceDomainPreferenceCsOnly = 0, - MbbRegistrationVoiceDomainPreferenceCsPreferred = 1, - MbbRegistrationVoiceDomainPreferenceImsPreferred = 2, - MbbRegistrationVoiceDomainPreferenceImsOnly = 3 -} MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE; - -typedef enum _MBB_REGISTRATION_VOICE_SUPPORT -{ - MbbRegistrationVoiceSupportNone = 0, - MbbRegistrationVoiceSupportIms = 0x1, - MbbRegistrationVoiceSupportEmergencyAttach = 0x2, - MbbRegistrationVoiceSupportCs = 0x4, - MbbRegistrationVoiceSupportCsfb = 0x8, - MbbRegistrationVoiceSupport1xCsfb = 0x10, - MbbRegistrationVoiceSupportCsEmergency = 0x20 -} MBB_REGISTRATION_VOICE_SUPPORT; - -typedef enum _MBB_REGISTRATION_CDMA_ROAM_MODE -{ - MbbRegistrationCdmaRoamModeAutomatic = 0, - MbbRegistrationCdmaRoamModeHomeOnly = 1 -} MBB_REGISTRATION_CDMA_ROAM_MODE; - -typedef struct _MBB_SET_REGISTER_STATE_V2 -{ - MBB_STRING ProviderId; - MBB_REGISTER_ACTION RegisterAction; - ULONG DataClass; - MBB_REGISTRATION_VOICE_CLASS VoiceClass; - MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE VoiceDomain; - MBB_REGISTRATION_CDMA_ROAM_MODE CdmaRoamMode; - MBB_ARRAY_ELEMENT AcquisitionOrder[1]; -} MBB_SET_REGISTER_STATE_V2; - -typedef struct _MBB_SET_REGISTER_STATE_V2* PMBB_SET_REGISTER_STATE_V2; - -typedef struct _MBB_REGISTRATION_STATE_V2 -{ - ULONG NetworkError; - MBB_REGISTER_STATE RegisterState; - MBB_REGISTER_MODE RegisterMode; - ULONG AvailableDataClasses; - MBB_CELLULAR_CLASS CurrentCellularClass; - MBB_STRING ProviderId; - MBB_STRING ProviderName; - MBB_STRING RoamingText; - ULONG RegFlags; - MBB_REGISTRATION_VOICE_SUPPORT VoiceSupport; - ULONG CurrentRATClass; - UCHAR DataBuffer[1]; -} MBB_REGISTRATION_STATE_V2; - -typedef struct _MBB_REGISTRATION_STATE_V2* PMBB_REGISTRATION_STATE_V2; - -typedef struct _MBB_REGISTRATION_STATE_INFOS_V2 -{ - ULONG ElementCount; - MBB_ARRAY_ELEMENT RegistrationStateList[1]; -} MBB_REGISTRATION_STATE_INFOS_V2; - -typedef struct _MBB_REGISTRATION_STATE_INFOS_V2* PMBB_REGISTRATION_STATE_INFOS_V2; - -typedef struct _MBB_REGISTRATION_STATE_INFO_V2 -{ - ULONG NetworkError; - MBB_REGISTER_STATE RegisterState; - MBB_REGISTER_MODE RegisterMode; - ULONG AvailableDataClasses; - MBB_CELLULAR_CLASS CurrentCellularClass; - MBB_STRING ProviderId; - MBB_STRING ProviderName; - MBB_STRING RoamingText; - ULONG RegistrationFlag; - ULONG PreferredDataClasses; - UCHAR DataBuffer[1]; -} MBB_REGISTRATION_STATE_INFO_V2; - -typedef struct _MBB_REGISTRATION_STATE_INFO_V2* PMBB_REGISTRATION_STATE_INFO_V2; - -typedef enum _MBB_IMS_VOICE_STATUS -{ - MbbImsVoiceStatusUnknown = 0, - MbbImsVoiceStatusUnregistered = 1, - MbbImsVoiceStatusRegistered = 2 -} MBB_IMS_VOICE_STATUS; - -typedef struct _MBB_SET_IMS_VOICE_STATE -{ - MBB_IMS_VOICE_STATUS ImsVoiceStatus; -} MBB_SET_IMS_VOICE_STATE; - -typedef struct _MBB_SET_IMS_VOICE_STATE* PMBB_SET_IMS_VOICE_STATE; - -typedef struct _MBB_IMS_VOICE_STATE -{ - MBB_IMS_VOICE_STATUS ImsVoiceStatus; -} MBB_IMS_VOICE_STATE; - -typedef struct _MBB_IMS_VOICE_STATE* PMBB_IMS_VOICE_STATE; - -typedef struct _MBB_SET_SIGNAL_INDICATION_V2 -{ - ULONG RssiInterval; - ULONG RssiThreshold; - ULONG ErrorRateThreshold; - ULONG SnrThreshold; -} MBB_SET_SIGNAL_INDICATION_V2; - -typedef struct _MBB_SET_SIGNAL_INDICATION_V2* PMBB_SET_SIGNAL_INDICATION_V2; - -typedef struct _MBB_SIGNAL_STATE_V2 -{ - ULONG Rssi; - ULONG ErrorRate; - ULONG RssiInterval; - ULONG RssiThreshold; - ULONG ErrorRateThreshold; - ULONG Snr; - ULONG SnrThreshold; - ULONG DataClass; -} MBB_SIGNAL_STATE_V2; - -typedef struct _MBB_SIGNAL_STATE_V2* PMBB_SIGNAL_STATE_V2; - -typedef struct _MBB_RSRP_SNR_INFO -{ - ULONG RSRP; - ULONG SNR; - ULONG RSRPThreshold; - ULONG SNRThreshold; - MBB_DATA_CLASS_VALUE SystemType; -} MBB_RSRP_SNR_INFO; - -typedef struct _MBB_RSRP_SNR_INFO* PMBB_RSRP_SNR_INFO; - -typedef struct _MBB_RSRP_SNR -{ - ULONG ElementCount; - MBB_RSRP_SNR_INFO DataBuffer[1]; -} MBB_RSRP_SNR; - -typedef struct _MBB_RSRP_SNR* PMBB_RSRP_SNR; - -typedef struct _MBB_SIGNAL_STATE_INFO_V2 -{ - ULONG Rssi; - ULONG ErrorRate; - ULONG SignalStrengthInterval; - ULONG RssiThreshold; - ULONG ErrorRateThreshold; - ULONG RsrpSnrOffset; - ULONG RsrpSnrSize; - MBB_RSRP_SNR DataBuffer; -} MBB_SIGNAL_STATE_INFO_V2; - -typedef struct _MBB_SIGNAL_STATE_INFO_V2* PMBB_SIGNAL_STATE_INFO_V2; - -typedef struct _MBB_SIGNAL_STATE_INFOS_V2 -{ - ULONG ElementCount; - MBB_ARRAY_ELEMENT SignalStateList[1]; -} MBB_SIGNAL_STATE_INFOS_V2; - -typedef struct _MBB_SIGNAL_STATE_INFOS_V2* PMBB_SIGNAL_STATE_INFOS_V2; - -typedef enum _MBB_LOCATION_TRIGGER_MODE -{ - MbbLocationTriggerNone = 0, - MbbLocationTriggerAreaCode = 1, - MbbLocationTriggerAreaCellId = 2 -} MBB_LOCATION_TRIGGER_MODE; - -typedef struct _MBB_SET_LOCATION_STATE -{ - MBB_LOCATION_TRIGGER_MODE Trigger; -} MBB_SET_LOCATION_STATE; - -typedef struct _MBB_SET_LOCATION_STATE* PMBB_SET_LOCATION_STATE; - -typedef struct _MBB_LOCATION_STATE_INFO -{ - MBB_LOCATION_TRIGGER_MODE Trigger; - ULONG DataClass; - ULONG AreaCode; - ULONG CellId; -} MBB_LOCATION_STATE_INFO; - -typedef struct _MBB_LOCATION_STATE_INFO* PMBB_LOCATION_STATE_INFO; - -typedef struct _MBB_NITZ_INFO -{ - ULONG Year; - ULONG Month; - ULONG Day; - ULONG Hour; - ULONG Minute; - ULONG Second; - ULONG TimeZoneOffsetMinutes; - ULONG DaylightSavingTimeOffsetMinutes; - ULONG DataClasses; -} MBB_NITZ_INFO; - -typedef struct _MBB_NITZ_INFO* PMBB_NITZ_INFO; - -typedef struct _MBB_ATR_INFO -{ - MBB_ARRAY_ELEMENT2 Atr; - UCHAR DataBuffer[1]; -} MBB_ATR_INFO; - -typedef struct _MBB_ATR_INFO* PMBB_ATR_INFO; - -typedef struct _MBB_SET_UICC_OPEN_CHANNEL -{ - MBB_ARRAY_ELEMENT2 AppId; - ULONG SelectP2Arg; - ULONG ChannelGroup; - UCHAR DataBuffer[1]; -} MBB_SET_UICC_OPEN_CHANNEL; - -typedef struct _MBB_SET_UICC_OPEN_CHANNEL* PMBB_SET_UICC_OPEN_CHANNEL; - -typedef struct _MBB_UICC_OPEN_CHANNEL_INFO -{ - UCHAR Status[4]; - ULONG Channel; - MBB_ARRAY_ELEMENT2 Response; - UCHAR DataBuffer[1]; -} MBB_UICC_OPEN_CHANNEL_INFO; - -typedef struct _MBB_UICC_OPEN_CHANNEL_INFO* PMBB_UICC_OPEN_CHANNEL_INFO; - -typedef struct _MBB_SET_UICC_CLOSE_CHANNEL -{ - ULONG Channel; - ULONG ChannelGroup; - ULONG SelectP2Arg; -} MBB_SET_UICC_CLOSE_CHANNEL; - -typedef struct _MBB_SET_UICC_CLOSE_CHANNEL* PMBB_SET_UICC_CLOSE_CHANNEL; - -typedef struct _MBB_UICC_CLOSE_CHANNEL_INFO -{ - UCHAR Status[4]; -} MBB_UICC_CLOSE_CHANNEL_INFO; - -typedef struct _MBB_UICC_CLOSE_CHANNEL_INFO* PMBB_UICC_CLOSE_CHANNEL_INFO; - -typedef enum _MBB_UICC_SECURE_MESSAGING -{ - MbbUiccSecureMessagingNone = 0, - MbbUiccSecureMessagingNoHdrAuth = 1 -} MBB_UICC_SECURE_MESSAGING; - -typedef enum _MBB_UICC_CLASS_BYTE_TYPE -{ - MbbUiccClassByteTypeInterindustry = 0, - MbbUiccClassByteTypeExtended = 1 -} MBB_UICC_CLASS_BYTE_TYPE; - -typedef struct _MBB_SET_UICC_APDU -{ - ULONG Channel; - MBB_UICC_SECURE_MESSAGING SecureMessaging; - MBB_UICC_CLASS_BYTE_TYPE Type; - MBB_ARRAY_ELEMENT2 Command; - UCHAR DataBuffer[1]; -} MBB_SET_UICC_APDU; - -typedef struct _MBB_SET_UICC_APDU* PMBB_SET_UICC_APDU; - -typedef struct _MBB_UICC_APDU_INFO -{ - UCHAR Status[4]; - MBB_ARRAY_ELEMENT2 Response; - UCHAR DataBuffer[1]; -} MBB_UICC_APDU_INFO; - -typedef struct _MBB_UICC_APDU_INFO* PMBB_UICC_APDU_INFO; - -typedef struct _MBB_UICC_TERMINAL_CAPABILITY_TLV -{ - UCHAR Data[3]; -} MBB_UICC_TERMINAL_CAPABILITY_TLV; - -typedef struct _MBB_UICC_TERMINAL_CAPABILITY_TLV* PMBB_UICC_TERMINAL_CAPABILITY_TLV; - -typedef struct _MBB_SET_UICC_TERMINAL_CAPABILITY -{ - ULONG ElementCount; - MBB_ARRAY_ELEMENT CapabilityList[1]; -} MBB_SET_UICC_TERMINAL_CAPABILITY; - -typedef struct _MBB_SET_UICC_TERMINAL_CAPABILITY* PMBB_SET_UICC_TERMINAL_CAPABILITY; - -typedef struct _MBB_UICC_TERMINAL_CAPABILITY_INFO -{ - ULONG ElementCount; - MBB_ARRAY_ELEMENT CapabilityList[1]; -} MBB_UICC_TERMINAL_CAPABILITY_INFO; - -typedef struct _MBB_UICC_TERMINAL_CAPABILITY_INFO* PMBB_UICC_TERMINAL_CAPABILITY_INFO; - -typedef enum _MBB_UICC_PASSTHROUGH_ACTION -{ - MbbUiccPassThroughDisable = 0, - MbbUiccPassThroughEnable = 1 -} MBB_UICC_PASSTHROUGH_ACTION; - -typedef enum _MBB_UICC_PASSTHROUGH_STATUS -{ - MbbUiccPassThroughDisabled = 0, - MbbUiccPassThroughEnabled = 1 -} MBB_UICC_PASSTHROUGH_STATUS; - -typedef struct _MBB_SET_UICC_RESET -{ - MBB_UICC_PASSTHROUGH_ACTION PassThroughAction; -} MBB_SET_UICC_RESET; - -typedef struct _MBB_SET_UICC_RESET* PMBB_SET_UICC_RESET; - -typedef struct _MBB_UICC_RESET_INFO -{ - MBB_UICC_PASSTHROUGH_STATUS PassThroughStatus; -} MBB_UICC_RESET_INFO; - -typedef struct _MBB_UICC_RESET_INFO* PMBB_UICC_RESET_INFO; - -typedef struct _MBB_SAR_CONFIG_INDICES -{ - ULONG SarAntennaIndex; - ULONG SarBackoffIndex; -} MBB_SAR_CONFIG_INDICES; - -typedef struct _MBB_SAR_CONFIG_INDICES* PMBB_SAR_CONFIG_INDICES; - -typedef struct _MBB_SAR_CONFIG_INFO -{ - MBB_SAR_CONTROL_MODE SarMode; - MBB_SAR_BACKOFF_STATE SarBackoffStatus; - MBB_SAR_WIFI_HARDWARE_INTEGRATION SarWifiIntegration; - ULONG ElementCount; - MBB_ARRAY_ELEMENT Configurations[1]; -} MBB_SAR_CONFIG_INFO; - -typedef struct _MBB_SAR_CONFIG_INFO* PMBB_SAR_CONFIG_INFO; - -typedef struct _MBB_SET_SAR_CONFIG -{ - MBB_SAR_CONTROL_MODE SarMode; - MBB_SAR_BACKOFF_STATE SarBackoffStatus; - ULONG ElementCount; - MBB_ARRAY_ELEMENT Configurations[1]; -} MBB_SET_SAR_CONFIG; - -typedef struct _MBB_SET_SAR_CONFIG* PMBB_SET_SAR_CONFIG; - -typedef struct _MBB_SAR_TRANSMISSION_STATUS_INFO -{ - MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE ChannelNotification; - MBB_SAR_TRANSMISSION_STATUS TransmissionStatus; - ULONG HysteresisTimer; -} MBB_SAR_TRANSMISSION_STATUS_INFO; - -typedef struct _MBB_SAR_TRANSMISSION_STATUS_INFO* PMBB_SAR_TRANSMISSION_STATUS_INFO; - -typedef struct _MBB_SET_SAR_TRANSMISSION_STATUS -{ - MBB_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE ChannelNotification; - ULONG HysteresisTimer; -} MBB_SET_SAR_TRANSMISSION_STATUS; - -typedef struct _MBB_SET_SAR_TRANSMISSION_STATUS* PMBB_SET_SAR_TRANSMISSION_STATUS; - -typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 -{ - MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS Operation; - GUID ContextType; - MBB_CONTEXT_IP_TYPE IPType; - MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; - MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; - MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; - MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - UCHAR DataBuffer[1]; -} MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2; - -typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2* PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2; - -typedef struct _MBB_MS_CONTEXT_V2 -{ - ULONG ContextId; - GUID ContextType; - MBB_CONTEXT_IP_TYPE IPType; - MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; - MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; - MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; - MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - UCHAR DataBuffer[1]; -} MBB_MS_CONTEXT_V2; - -typedef struct _MBB_MS_CONTEXT_V2* PMBB_MS_CONTEXT_V2; - -typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2_EX4 -{ - MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS Operation; - GUID ContextType; - MBB_CONTEXT_IP_TYPE IPType; - MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; - MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; - MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; - MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - MBB_TLV_IE Snssai; - UCHAR DataBuffer[1]; -} MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2_EX4; - -typedef struct _MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2_EX4* PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2_EX4; - -typedef struct _MBB_MS_CONTEXT_V2_EX4 -{ - ULONG ContextId; - GUID ContextType; - MBB_CONTEXT_IP_TYPE IPType; - MBB_BASICCONNECTEXT_CONTEXT_ENABLE Enable; - MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL Roaming; - MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE MediaType; - MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - MBB_TLV_IE Snssai; - UCHAR DataBuffer[1]; -} MBB_MS_CONTEXT_V2_EX4; - -typedef struct _MBB_MS_CONTEXT_V2_EX4* PMBB_MS_CONTEXT_V2_EX4; - -typedef struct _MBB_MS_NETWORK_BLACKLIST_PROVIDER -{ - ULONG MCC; - ULONG MNC; - MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_TYPE NetworkBlacklistType; -} MBB_MS_NETWORK_BLACKLIST_PROVIDER; - -typedef struct _MBB_MS_NETWORK_BLACKLIST_PROVIDER* PMBB_MS_NETWORK_BLACKLIST_PROVIDER; - -typedef struct _MBB_MS_NETWORK_BLACKLIST_INFO -{ - MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE BlacklistState; - ULONG ElementCount; - MBB_ARRAY_ELEMENT Contexts[1]; -} MBB_MS_NETWORK_BLACKLIST_INFO; - -typedef struct _MBB_MS_NETWORK_BLACKLIST_INFO* PMBB_MS_NETWORK_BLACKLIST_INFO; - -typedef struct _MBB_MS_VERSION_INFO -{ - USHORT bcdMBIMVersion; - USHORT bcdMBIMExtendedVersion; -} MBB_MS_VERSION_INFO; - -typedef struct _MBB_MS_VERSION_INFO* PMBB_MS_VERSION_INFO; - -typedef struct _MBB_MS_LTE_ATTACH_CONTEXT -{ - MBB_CONTEXT_IP_TYPE IPType; - MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL Roaming; - MBB_BASICCONNECTEXT_CONTEXT_SOURCE Source; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - UCHAR DataBuffer[1]; -} MBB_MS_LTE_ATTACH_CONTEXT; - -typedef struct _MBB_MS_LTE_ATTACH_CONTEXT* PMBB_MS_LTE_ATTACH_CONTEXT; - -typedef struct _MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG -{ - MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS Operation; - ULONG ElementCount; - MBB_ARRAY_ELEMENT Contexts[1]; -} MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG; - -typedef struct _MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG* PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG; - -typedef struct _MBB_MS_LTE_ATTACH_CONFIG_INFO -{ - ULONG ElementCount; - MBB_ARRAY_ELEMENT Contexts[1]; -} MBB_MS_LTE_ATTACH_CONFIG_INFO; - -typedef struct _MBB_MS_LTE_ATTACH_CONFIG_INFO* PMBB_MS_LTE_ATTACH_CONFIG_INFO; - -typedef struct _MBB_MS_LTE_ATTACH_STATUS -{ - MBB_BASICCONNECTEXT_LTEATTACH_STATE LteAttachState; - MBB_CONTEXT_IP_TYPE IPType; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - UCHAR DataBuffer[1]; -} MBB_MS_LTE_ATTACH_STATUS; - -typedef struct _MBB_MS_LTE_ATTACH_STATUS* PMBB_MS_LTE_ATTACH_STATUS; - -typedef struct _MBB_MS_LTE_ATTACH_STATUS_V2 -{ - MBB_BASICCONNECTEXT_LTEATTACH_STATE LteAttachState; - ULONG NetworkError; - MBB_CONTEXT_IP_TYPE IPType; - MBB_STRING AccessString; - MBB_STRING UserName; - MBB_STRING Password; - MBB_COMPRESSION Compression; - MBB_AUTH_PROTOCOL AuthProtocol; - UCHAR DataBuffer[1]; -} MBB_MS_LTE_ATTACH_STATUS_V2; - -typedef struct _MBB_MS_LTE_ATTACH_STATUS_V2* PMBB_MS_LTE_ATTACH_STATUS_V2; - -typedef struct _MBB_MS_SYS_CAPS_INFO -{ - ULONG NumberOfExecutors; - ULONG NumberOfSlots; - ULONG Concurrency; - ULONG64 ModemId; -} MBB_MS_SYS_CAPS_INFO; - -typedef struct _MBB_MS_SYS_CAPS_INFO* PMBB_MS_SYS_CAPS_INFO; - -typedef struct _MBB_MS_DEVICE_CAPS_INFO_V2 -{ - MBB_DEVICE_TYPE DeviceType; - MBB_CELLULAR_CLASS CellularClass; - MBB_VOICE_CLASS VoiceClass; - MBB_SIM_CLASS SimClass; - ULONG DataClass; - ULONG SmsCaps; - ULONG ControlCaps; - ULONG dwMaxSessions; - MBB_STRING CustomDataClass; - MBB_STRING DeviceIdString; - MBB_STRING FirmwareInfo; - MBB_STRING HardwareInfo; - ULONG ExecutorIndex; - UCHAR DataBuffer[1]; -} MBB_MS_DEVICE_CAPS_INFO_V2; - -typedef struct _MBB_MS_DEVICE_CAPS_INFO_V2* PMBB_MS_DEVICE_CAPS_INFO_V2; - -typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3_OBS -{ - MBB_DEVICE_TYPE DeviceType; - MBB_CELLULAR_CLASS CellularClass; - MBB_VOICE_CLASS VoiceClass; - ULONG SimClassBitMasks; - ULONG DataClass; - ULONG SmsCaps; - ULONG ControlCaps; - ULONGLONG MiscCaps; - ULONG dwMaxSessions; - ULONG ExecutorIndex; - ULONG WcdmaBandClass; -} MBB_MS_DEVICE_CAPS_INFO_V3_OBS; - -typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3_OBS* PMBB_MS_DEVICE_CAPS_INFO_V3_OBS; - -typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3 -{ - MBB_DEVICE_TYPE DeviceType; - MBB_CELLULAR_CLASS CellularClass; - MBB_VOICE_CLASS VoiceClass; - ULONG SimClassBitMasks; - ULONG DataClass; - ULONG SmsCaps; - ULONG ControlCaps; - ULONGLONG DataSubClass; - ULONG dwMaxSessions; - ULONG ExecutorIndex; - ULONG WcdmaBandClass; -} MBB_MS_DEVICE_CAPS_INFO_V3; - -typedef struct _MBB_MS_DEVICE_CAPS_INFO_V3* PMBB_MS_DEVICE_CAPS_INFO_V3; - -typedef struct _MBB_MS_DEVICE_SLOT_MAPPING_INFO -{ - ULONG MapCount; - MBB_ARRAY_ELEMENT SlotMapList[1]; -} MBB_MS_DEVICE_SLOT_MAPPING_INFO; - -typedef struct _MBB_MS_DEVICE_SLOT_MAPPING_INFO* PMBB_MS_DEVICE_SLOT_MAPPING_INFO; - -typedef struct _MBB_MS_SLOT_INFO_REQ -{ - ULONG SlotIndex; -} MBB_MS_SLOT_INFO_REQ; - -typedef struct _MBB_MS_SLOT_INFO_REQ* PMBB_MS_SLOT_INFO_REQ; - -typedef struct _MBB_MS_SLOT_INFO -{ - ULONG SlotIndex; - MBB_BASICCONNECTEXT_UICCSLOT_STATE State; -} MBB_MS_SLOT_INFO; - -typedef struct _MBB_MS_SLOT_INFO* PMBB_MS_SLOT_INFO; - -typedef struct _MBB_MS_PCO_VALUE -{ - ULONG SessionId; - ULONG PcoDataSize; - MBB_PCO_TYPE PcoDataType; - UCHAR PcoDataBuffer[1]; -} MBB_MS_PCO_VALUE; - -typedef struct _MBB_MS_PCO_VALUE* PMBB_MS_PCO_VALUE; - -typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ -{ - ULONG MaxGSMCount; - ULONG MaxUMTSCount; - ULONG MaxTDSCDMACount; - ULONG MaxLTECount; - ULONG MaxCDMACount; -} MBB_MS_BASE_STATIONS_INFO_REQ; - -typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ* PMBB_MS_BASE_STATIONS_INFO_REQ; - -typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ_V2 -{ - ULONG MaxGSMCount; - ULONG MaxUMTSCount; - ULONG MaxTDSCDMACount; - ULONG MaxLTECount; - ULONG MaxCDMACount; - ULONG MaxNRCount; -} MBB_MS_BASE_STATIONS_INFO_REQ_V2; - -typedef struct _MBB_MS_BASE_STATIONS_INFO_REQ_V2* PMBB_MS_BASE_STATIONS_INFO_REQ_V2; - -typedef struct _MBB_MS_BASE_STATIONS_INFO -{ - MBB_DATA_CLASS_VALUE SystemType; - MBB_ARRAY_ELEMENT GSMServingCell; - MBB_ARRAY_ELEMENT UMTSServingCell; - MBB_ARRAY_ELEMENT TDSCDMAServingCell; - MBB_ARRAY_ELEMENT LTEServingCell; - MBB_ARRAY_ELEMENT GSMNmr; - MBB_ARRAY_ELEMENT UMTSMrl; - MBB_ARRAY_ELEMENT TDSCDMAMrl; - MBB_ARRAY_ELEMENT LTEMrl; - MBB_ARRAY_ELEMENT CDMAMrl; - UCHAR DataBuffer[1]; -} MBB_MS_BASE_STATIONS_INFO; - -typedef struct _MBB_MS_BASE_STATIONS_INFO* PMBB_MS_BASE_STATIONS_INFO; - -typedef struct _MBB_MS_BASE_STATIONS_INFO_V2 -{ - MBB_DATA_CLASS_VALUE SystemType; - MBB_DATA_SUBCLASS_VALUE SystemSubType; - MBB_ARRAY_ELEMENT GSMServingCell; - MBB_ARRAY_ELEMENT UMTSServingCell; - MBB_ARRAY_ELEMENT TDSCDMAServingCell; - MBB_ARRAY_ELEMENT LTEServingCell; - MBB_ARRAY_ELEMENT GSMNmr; - MBB_ARRAY_ELEMENT UMTSMrl; - MBB_ARRAY_ELEMENT TDSCDMAMrl; - MBB_ARRAY_ELEMENT LTEMrl; - MBB_ARRAY_ELEMENT CDMAMrl; - MBB_ARRAY_ELEMENT NRServingCells; - MBB_ARRAY_ELEMENT NRNeighborCells; - UCHAR DataBuffer[1]; -} MBB_MS_BASE_STATIONS_INFO_V2; - -typedef struct _MBB_MS_BASE_STATIONS_INFO_V2* PMBB_MS_BASE_STATIONS_INFO_V2; - -typedef struct _MBB_MODEM_LOGGING_CONFIG -{ - ULONG Version; - ULONG MaxSegmentSize; - ULONG MaxFlushTime; - MBB_BASICCONNECTEXT_MODEM_LOGGING_LEVEL_CONFIG LevelConfig; -} MBB_MODEM_LOGGING_CONFIG; - -typedef struct _MBB_MODEM_LOGGING_CONFIG* PMBB_MODEM_LOGGING_CONFIG; - -typedef enum _MBB_ACCESS_TYPE -{ - MbbAccessUnknown = 0, - MbbAccess3GPP = 1, - MbbAccessNon3GPP = 2, - MbbAccessMaximum = (MbbAccessNon3GPP + 1) -} MBB_ACCESS_TYPE; - -typedef struct _MBB_PRE_DFLT_NSSAI_INFO -{ - MBB_ACCESS_TYPE AccessType; - MBB_TLV_IE PreferredNSSAI; -} MBB_PRE_DFLT_NSSAI_INFO; - -typedef struct _MBB_PRE_DFLT_NSSAI_INFO* PMBB_PRE_DFLT_NSSAI_INFO; - -typedef struct _MBB_SNSSAI_INFO -{ - UCHAR SnssaiLength; - UCHAR Sst; -} MBB_SNSSAI_INFO; - -typedef struct _MBB_SNSSAI_INFO* PMBB_SNSSAI_INFO; - -typedef struct _MBB_TAI_LIST_SINGLE_PLMN -{ - MBB_PLMN Plmn; - UCHAR ElementCount; - ULONG TacList[1]; -} MBB_TAI_LIST_SINGLE_PLMN; - -typedef struct _MBB_TAI_LIST_SINGLE_PLMN* PMBB_TAI_LIST_SINGLE_PLMN; - -typedef struct _MBB_TAI_LIST_MULTI_PLMNS -{ - UCHAR ElementCount; - MBB_TAI TaiList[1]; -} MBB_TAI_LIST_MULTI_PLMNS; - -typedef struct _MBB_TAI_LIST_MULTI_PLMNS* PMBB_TAI_LIST_MULTI_PLMNS; - -typedef struct _MBB_TAI_LIST_INFO -{ - UCHAR ListType; - /* [switch_is] */ /* [switch_type] */ union __MIDL___MIDL_itf_MbbMessages_0000_0000_0002 - { - /* [case()] */ MBB_TAI_LIST_SINGLE_PLMN SinglePlmnTaiList; - /* [case()] */ MBB_TAI_LIST_MULTI_PLMNS MultiPlmnsTaiList; - } u; -} MBB_TAI_LIST_INFO; - -typedef struct _MBB_TAI_LIST_INFO* PMBB_TAI_LIST_INFO; - -typedef struct _MBB_DNN -{ - UCHAR DnnLength; -} MBB_DNN; - -typedef struct _MBB_DNN* PMBB_DNN; - -typedef struct _MBB_LADN -{ - MBB_DNN Dnn; -} MBB_LADN; - -typedef struct _MBB_LADN* PMBB_LADN; - -typedef enum _MBB_MODEM_CONFIG_STATUS -{ - ModemConfigStatusUnknown = 0, - ModemConfigStatusStarted = 1, - ModemConfigStatusCompleted = 2, - ModemConfigStatusMaximum = (ModemConfigStatusCompleted + 1) -} MBB_MODEM_CONFIG_STATUS; - -typedef struct _MBB_MODEM_CONFIG_INFO -{ - MBB_MODEM_CONFIG_STATUS ConfigStatus; - MBB_TLV_IE ConfigName; -} MBB_MODEM_CONFIG_INFO; - -typedef struct _MBB_MODEM_CONFIG_INFO* PMBB_MODEM_CONFIG_INFO; - -typedef enum _MBB_MICO_MODE -{ - MicoModeDisabled = 0, - MicoModeEnabled = 1, - MicoModeUnsupported = 2, - MBIMMicoModeDefault = 3, - MicoModeMaximum = (MBIMMicoModeDefault + 1) -} MBB_MICO_MODE; - -typedef enum _MBB_DRX_PARAMS -{ - DRXNotSpecified = 0, - MBIMDRXNotSupported = 1, - DRXCycle32 = 2, - DRXCycle64 = 3, - DRXCycle128 = 4, - DRXCycle256 = 5, - DRXCycleMaximum = (DRXCycle256 + 1) -} MBB_DRX_PARAMS; - -typedef enum _MBB_DEFAULT_PDU_HINT -{ - MBIMDefaultPDUSessionActivationUnlikely = 0, - MBIMDefaultPDUSessionActivationLikely = 1, - DefaultPDUMaximum = (MBIMDefaultPDUSessionActivationLikely + 1) -} MBB_DEFAULT_PDU_HINT; - -typedef enum _MBB_MS_LADN_IND -{ - LADNInfoNotNeeded = 0, - LADNInfoRequested = 1, - LADNInfoMaximum = (LADNInfoRequested + 1) -} MBB_MS_LADN_IND; - -typedef struct _MBB_REGISTRATION_PARAMS_INFO -{ - MBB_MICO_MODE MicoMode; - MBB_DRX_PARAMS DRXParams; - MBB_MS_LADN_IND LADNInfo; - MBB_DEFAULT_PDU_HINT DefaultPDUHint; - ULONG ReRegisterIfNeeded; -} MBB_REGISTRATION_PARAMS_INFO; - -typedef struct _MBB_REGISTRATION_PARAMS_INFO* PMBB_REGISTRATION_PARAMS_INFO; - -typedef enum _MBB_MICO_IND -{ - RaaiTypeRaNotAllocated = 0, - RaaiTypeRaAllocated = 1, - RaaiTypeNotAvailable = 0xffffffff -} MBB_MICO_IND; - -typedef struct _MBB_NW_PARAMS_QUERY_INFO -{ - USHORT AreConfigurationsNeeded; - USHORT AreUEPoliciesNeeded; -} MBB_NW_PARAMS_QUERY_INFO; - -typedef struct _MBB_NW_PARAMS_QUERY_INFO* PMBB_NW_PARAMS_QUERY_INFO; - -typedef struct _MBB_NW_PARAMS_INFO -{ - MBB_MICO_IND MicoInd; - MBB_DRX_PARAMS DRXParams; -} MBB_NW_PARAMS_INFO; - -typedef struct _MBB_NW_PARAMS_INFO* PMBB_NW_PARAMS_INFO; - -typedef enum _MBB_WAKE_TYPE -{ - WakeTypeCIDResponse = 0, - WakeTypeCIDIndication = 1, - WakeTypePacket = 2 -} MBB_WAKE_TYPE; - -typedef struct _MBB_WAKE_REASON -{ - MBB_WAKE_TYPE WakeType; - ULONG SessionId; -} MBB_WAKE_REASON; - -typedef struct _MBB_WAKE_REASON* PMBB_WAKE_REASON; - -typedef struct _MBB_WAKE_COMMAND -{ - MBB_COMMAND Command; - ULONG PayloadOffset; - ULONG PayloadSize; - UCHAR DataBuffer[1]; -} MBB_WAKE_COMMAND; - -typedef struct _MBB_WAKE_COMMAND* PMBB_WAKE_COMMAND; - -typedef struct _MBB_WAKE_PACKET -{ - ULONG FilterId; - ULONG OriginalPacketSize; - ULONG SavedPacketOffset; - ULONG SavedPacketSize; - UCHAR DataBuffer[1]; -} MBB_WAKE_PACKET; - -typedef struct _MBB_WAKE_PACKET* PMBB_WAKE_PACKET; - -#include - -extern RPC_IF_HANDLE __MIDL_itf_MbbMessages_0000_0000_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_MbbMessages_0000_0000_v0_0_s_ifspec; - -/* Additional Prototypes for ALL interfaces */ - -/* end of Additional Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/network/wwan/cxwmbclass/txqueue.cpp b/network/wwan/cxwmbclass/txqueue.cpp new file mode 100644 index 000000000..55fc5e7a9 --- /dev/null +++ b/network/wwan/cxwmbclass/txqueue.cpp @@ -0,0 +1,989 @@ +//------------------------------------------------------------------------------- +// Net Adapter source file +// +// Copyright (c) Microsoft Corporation. All rights reserved. + +#include "precomp.h" + +#include "device.h" +#include "txqueue.h" + +void MbbNotifyTxReady(_In_ NETPACKETQUEUE TxQueue) +{ + PMBB_TXQUEUE_CONTEXT txQueueContext = MbbGetTxQueueContext(TxQueue); + + if (InterlockedExchange(&txQueueContext->NotificationEnabled, FALSE) == TRUE) + { + NetTxQueueNotifyMoreCompletedPacketsAvailable(TxQueue); + } +} + +ULONG +MbbGetNetPacketDataLength(_In_ NET_PACKET* NetPacket, _In_ NET_RING_COLLECTION const* Rings) +{ + ULONG length = 0; + auto fr = NetRingCollectionGetFragmentRing(Rings); + for (UINT32 i = 0; i < NetPacket->FragmentCount; i++) + { + auto fragment = NetRingGetFragmentAtIndex(fr, (NetPacket->FragmentIndex + i) & fr->ElementIndexMask); + length += static_cast(fragment->ValidLength); + } + + return length; +} + +VOID MbbPacketRestoreMdl(_In_ PMBB_PACKET_CONTEXT PacketContext) +{ + if (PacketContext->ModifiedMdl != NULL) + { + *PacketContext->ModifiedMdl = PacketContext->OriginalMdl; + PacketContext->ModifiedMdl = NULL; + } +} + +VOID MbbPacketCleanupContext(_In_ PMBB_PACKET_CONTEXT PacketContext) +{ + MbbPacketRestoreMdl(PacketContext); + if (PacketContext->PaddingMdl != NULL) + { + IoFreeMdl(PacketContext->PaddingMdl); + PacketContext->PaddingMdl = NULL; + } + if (PacketContext->DataEndMdl != NULL) + { + IoFreeMdl(PacketContext->DataEndMdl); + PacketContext->DataEndMdl = NULL; + } + if (PacketContext->DataStartMdl != NULL) + { + IoFreeMdl(PacketContext->DataStartMdl); + PacketContext->DataStartMdl = NULL; + } +} + +FORCEINLINE +PMDL MbbPacketGetFirstMdl(_In_ PMBB_PACKET_CONTEXT PacketContext) +{ + if (PacketContext->PaddingMdl != NULL) + return PacketContext->PaddingMdl; + else + return PacketContext->DataStartMdl; +} + +FORCEINLINE +PMDL MbbPacketGetLastMdl(_In_ PMBB_PACKET_CONTEXT PacketContext) +{ + if (PacketContext->DataEndMdl != NULL) + return PacketContext->DataEndMdl; + else + return PacketContext->DataStartMdl; +} + +VOID MbbPacketSaveAndSetMdl(_In_ PMBB_PACKET_CONTEXT PacketContext, _In_ PMDL MdlToSave, _In_ PMDL MdlToSet) +{ + if (PacketContext->ModifiedMdl == NULL) + { + PacketContext->ModifiedMdl = MdlToSave; + PacketContext->OriginalMdl = *MdlToSave; + } + *MdlToSave = *MdlToSet; +} + +VOID MbbCleanupDssPacket(_In_ PDSS_PACKET Packet) +{ + if (Packet->Mdl != NULL) + { + IoFreeMdl(Packet->Mdl); + } + if (Packet != NULL) + { + FREE_POOL(Packet); + } +} + +VOID MbbNtbCleanupContext(_In_ PMBB_NTB_BUILD_CONTEXT NtbContext, _In_ NTSTATUS NtStatus) +{ + ULONG DatagramIndex; + BOOLEAN NeedReturnCompletedPackets = FALSE; + + for (DatagramIndex = 0; DatagramIndex < NtbContext->DatagramCount; DatagramIndex++) + { + MbbPacketCleanupContext(&NtbContext->NdpDatagramEntries[DatagramIndex].NetPacketContext); + if (NtbContext->NdpDatagramEntries[DatagramIndex].NdpType == MbbNdpTypeIps) + { + NtbContext->NdpDatagramEntries[DatagramIndex].NetPacket->Scratch = 1; + NeedReturnCompletedPackets = TRUE; + } + else if (NtbContext->NdpDatagramEntries[DatagramIndex].NdpType == MbbNdpTypeVendor_1) + { + MbbDeviceSendDeviceServiceSessionDataComplete(NtbContext->NdpDatagramEntries[DatagramIndex].DssPacket->Data, NtStatus); + + MbbCleanupDssPacket(NtbContext->NdpDatagramEntries[DatagramIndex].DssPacket); + } + } + if (NtbContext->NdpMdl != NULL) + { + IoFreeMdl(NtbContext->NdpMdl); + } + if (NtbContext->NthMdl != NULL) + { + IoFreeMdl(NtbContext->NthMdl); + } + if (NtbContext->NdpBufferMemory != NULL) + { + WdfObjectDelete(NtbContext->NdpBufferMemory); + } +#if DBG + if (NtbContext->ScratchBuffer != NULL) + { + FREE_POOL(NtbContext->ScratchBuffer); + } +#endif + if (NeedReturnCompletedPackets) + { + MbbNotifyTxReady(NtbContext->NetTxQueue); + } + WdfObjectDelete(NtbContext->NtbLookasideBufferMemory); +} + +FORCEINLINE +ULONG +MbbSendQGetNtbSequence(_In_ PWMBCLASS_DEVICE_CONTEXT DeviceContext) +{ + return InterlockedIncrement(&DeviceContext->NtbSequenceNumber); +} + +PMBB_NTB_BUILD_CONTEXT +MbbNtbAllocateContext(_In_ WDFLOOKASIDE NtbLookasideList, _In_ PMBB_BUS_PARAMETERS BusParams, _In_ PVOID PaddingBuffer, _In_ ULONG NtbSequence) +{ + NTSTATUS status = NDIS_STATUS_SUCCESS; + size_t ntbSize; + PMBB_NTB_BUILD_CONTEXT ntbContext = NULL; + WDFMEMORY ntbContextMemory; + + do + { +#pragma prefast(suppress \ + : __WARNING_MEMORY_LEAK, "By Design: Allocate ntb context from lookaside pool, released when send completes.") + if (!NT_SUCCESS(status = WdfMemoryCreateFromLookaside(NtbLookasideList, &ntbContextMemory))) + { + break; + } + + ntbContext = (PMBB_NTB_BUILD_CONTEXT)WdfMemoryGetBuffer(ntbContextMemory, &ntbSize); + RtlZeroMemory(ntbContext, ntbSize); + ntbContext->PaddingBuffer = PaddingBuffer; + ntbContext->NtbLookasideList = NtbLookasideList; + ntbContext->NtbLookasideBufferMemory = ntbContextMemory; + +#if DBG + ntbContext->ScratchLength = BusParams->MaxOutNtb; + if ((ntbContext->ScratchBuffer = (PCHAR)ALLOCATE_NONPAGED_POOL(ntbContext->ScratchLength)) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } +#endif + // + // Initialize the NTH and the NTH MDL. + // + if ((ntbContext->IsNtb32Bit = BusParams->CurrentMode32Bit) == TRUE) + { + if ((ntbContext->NthMdl = AllocateNonPagedMdl(&ntbContext->Nth32, sizeof(ntbContext->Nth32))) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + ntbContext->Nth32.dwSignature = NCM_NTH32_SIG; + ntbContext->Nth32.wHeaderLength = sizeof(NCM_NTH32); + ntbContext->Nth32.wSequence = (USHORT)NtbSequence; + + ntbContext->NtbHeaderSize = sizeof(NCM_NTH32); + ntbContext->NdpHeaderFixedSize = sizeof(NCM_NDP32); + ntbContext->NdpDatagramEntrySize = sizeof(NCM_NDP32_DATAGRAM); + } + else + { + if ((ntbContext->NthMdl = AllocateNonPagedMdl(&ntbContext->Nth16, sizeof(ntbContext->Nth16))) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + ntbContext->Nth16.dwSignature = NCM_NTH16_SIG; + ntbContext->Nth16.wHeaderLength = sizeof(NCM_NTH16); + ntbContext->Nth16.wSequence = (USHORT)NtbSequence; + + ntbContext->NtbHeaderSize = sizeof(NCM_NTH16); + ntbContext->NdpHeaderFixedSize = sizeof(NCM_NDP16); + ntbContext->NdpDatagramEntrySize = sizeof(NCM_NDP16_DATAGRAM); + } + + ntbContext->NtbOutMaxSize = BusParams->MaxOutNtb; + ntbContext->NtbOutMaxDatagrams = BusParams->MaxOutDatagrams; + ntbContext->NdpOutDivisor = BusParams->NdpOutDivisor; + ntbContext->NdpOutPayloadRemainder = BusParams->NdpOutRemainder; + ntbContext->NdpOutAlignment = BusParams->NdpOutAlignment; + } while (FALSE); + + if (!NT_SUCCESS(status)) + { + if (ntbContext != NULL) + { + MbbNtbCleanupContext(ntbContext, status); + } + ntbContext = NULL; + } + return ntbContext; +} + +NTSTATUS +MbbFillPacketContext( + _In_ PMBB_PACKET_CONTEXT PacketContext, + _In_ PMDL PacketDataStartMdl, + _In_ ULONG PacketDataStartMdlDataOffset, + _In_ ULONG DatagramLength, + _In_ PVOID PaddingBuffer, + _In_ ULONG PaddingLength) +{ + ULONG packetDataStartMdlDataLength; + PCHAR packetDataStartBuffer; + PMDL packetDataEndMdl; + ULONG packetDataEndMdlDataLength; + PCHAR packetDataEndBuffer; + PMDL packetMdl; + ULONG packetMdlOffset; + ULONG packetMdlLength; + PMDL packetPenultimateMdl; + NTSTATUS status = STATUS_SUCCESS; + + do + { + if ((packetDataStartBuffer = (PCHAR)MmGetSystemAddressForMdlSafe(PacketDataStartMdl, NormalPagePriority | MdlMappingNoExecute)) == NULL) + { + status = STATUS_RESOURCE_DATA_NOT_FOUND; + break; + } + packetDataStartBuffer += PacketDataStartMdlDataOffset; + // + // Create new DataStart and DataEnd Mdls + // to remove the unused data space. + // + packetDataStartMdlDataLength = MmGetMdlByteCount(PacketDataStartMdl); + packetDataStartMdlDataLength -= PacketDataStartMdlDataOffset; + + if ((PacketContext->DataStartMdl = + AllocateNonPagedMdl(packetDataStartBuffer, (ULONG)(MIN(DatagramLength, packetDataStartMdlDataLength)))) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + PacketContext->DataStartMdl->Next = PacketDataStartMdl->Next; + // + // Find the end MDL and the amount of data in the end MDL + // + packetMdl = PacketDataStartMdl; + packetMdlOffset = PacketDataStartMdlDataOffset; + packetPenultimateMdl = NULL; + + for (packetDataEndMdlDataLength = (ULONG)DatagramLength; packetDataEndMdlDataLength > (MmGetMdlByteCount(packetMdl) - packetMdlOffset); + packetDataEndMdlDataLength -= packetMdlLength) + { + packetPenultimateMdl = packetMdl; + packetMdlLength = MmGetMdlByteCount(packetMdl) - packetMdlOffset; + packetMdlOffset = 0; + packetMdl = packetMdl->Next; + } + packetDataEndMdl = packetMdl; + // + // If the starting and ending MDLs are not the same + // then build another partial MDL removing any unused + // data space. + // + if (packetDataEndMdl != PacketDataStartMdl) + { + if ((packetDataEndBuffer = (PCHAR)MmGetSystemAddressForMdlSafe(packetDataEndMdl, NormalPagePriority | MdlMappingNoExecute)) == NULL) + { + status = STATUS_RESOURCE_DATA_NOT_FOUND; + break; + } + + if ((PacketContext->DataEndMdl = AllocateNonPagedMdl(packetDataEndBuffer, packetDataEndMdlDataLength)) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + PacketContext->DataEndMdl->Next = NULL; + + if (packetPenultimateMdl != PacketDataStartMdl) + { + MDL TempMdl = *packetPenultimateMdl; + TempMdl.Next = PacketContext->DataEndMdl; + + MbbPacketSaveAndSetMdl(PacketContext, packetPenultimateMdl, &TempMdl); + } + + if (PacketContext->DataStartMdl->Next == packetDataEndMdl) + { + PacketContext->DataStartMdl->Next = PacketContext->DataEndMdl; + } + } + // + // Allocate padding, if needed. The padding buffer is a share buffer. + // Every padding MDL points to this same buffer. The buffer contains + // all 0s. + // + if (PaddingLength != 0) + { + if ((PacketContext->PaddingMdl = AllocateNonPagedMdl(PaddingBuffer, PaddingLength)) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + PacketContext->PaddingMdl->Next = PacketContext->DataStartMdl; + } + } while (FALSE); + + return status; +} + +VOID MbbNtbChainNb(_In_ PMBB_NTB_BUILD_CONTEXT NtbContext, _In_ PMBB_PACKET_CONTEXT PacketContext) +{ + if (NtbContext->DatagramLastMdl != NULL) + { + NtbContext->DatagramLastMdl->Next = MbbPacketGetFirstMdl(PacketContext); + } + else + { + NtbContext->NthMdl->Next = MbbPacketGetFirstMdl(PacketContext); + } + + NtbContext->DatagramLastMdl = MbbPacketGetLastMdl(PacketContext); +} + +NTSTATUS +MbbNtbAddPacket( + _In_ PMBB_NTB_BUILD_CONTEXT NtbContext, + _In_ PVOID PacketContext, + _In_ ULONG DatagramLength, + _In_ PMDL PacketDataStartMdl, + _In_ ULONG PacketDataStartMdlDataOffset, + _In_ MBB_NDP_TYPE CurrentNdpType, + _In_ ULONG SessionId) +{ + ULONG datagramOffset; + ULONG paddingLength; + ULONG ndpSize; + NTSTATUS status = STATUS_SUCCESS; + ULONG totalLength; + PMBB_PACKET_CONTEXT packetContext = NULL; + + do + { + if ((NtbContext->DatagramCount + 1) > NtbContext->NtbOutMaxDatagrams) + { + status = STATUS_BUFFER_OVERFLOW; + break; + } + + // + // Size of passed in NET_BUFFER, to be updated later in the NDP Context. + // + totalLength = NtbContext->NtbHeaderSize + NtbContext->DatagramLength; + paddingLength = ALIGN_AT_OFFSET(totalLength, NtbContext->NdpOutDivisor, NtbContext->NdpOutPayloadRemainder) - totalLength; + // + // Calculate the new NTB size based on the passed in MBB_PACKET + // + + // + // Fixed size NTH & DatagramSize along with Padding for all NDPs + // + datagramOffset = totalLength + paddingLength; + totalLength += DatagramLength + paddingLength; + + // + // Calculate NDP HeaderSize for all NDPs + // + ndpSize = totalLength; + totalLength = ALIGN(totalLength, NtbContext->NdpOutAlignment); + totalLength += NtbContext->NdpHeaderFixedSize; + totalLength += ((NtbContext->DatagramCount + 1) * NtbContext->NdpDatagramEntrySize); + ndpSize = totalLength - ndpSize; + // + // Can everything fit? + // + if (totalLength > NtbContext->NtbOutMaxSize) + { + status = STATUS_BUFFER_OVERFLOW; + break; + } + packetContext = &NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NetPacketContext; + if (!NT_SUCCESS( + status = MbbFillPacketContext( + packetContext, PacketDataStartMdl, PacketDataStartMdlDataOffset, DatagramLength, NtbContext->PaddingBuffer, paddingLength))) + { + break; + } + // + // Update the NTB Context for the new NET_BUFFER. + // + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].DatagramOffset = datagramOffset; + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].DatagramLength = DatagramLength; + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NdpType = CurrentNdpType; + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].SessionId = SessionId; + if (CurrentNdpType == MbbNdpTypeIps) + { + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].NetPacket = (NET_PACKET*)PacketContext; + } + else if (CurrentNdpType == MbbNdpTypeVendor_1) + { + NtbContext->NdpDatagramEntries[NtbContext->DatagramCount].DssPacket = (PDSS_PACKET)PacketContext; + } + + NtbContext->NdpSize = ndpSize; + NtbContext->DatagramCount += 1; + NtbContext->DatagramLength += (DatagramLength + paddingLength); + + MbbNtbChainNb(NtbContext, packetContext); + } while (FALSE); + + if (!NT_SUCCESS(status)) + { + if (packetContext != NULL) + { + MbbPacketCleanupContext(packetContext); + } + } + return status; +} + +FORCEINLINE +PMDL MbbNtbGetMdlChainHead(_In_ PMBB_NTB_BUILD_CONTEXT NtbContext) +{ + return NtbContext->NthMdl; +} + +VOID MbbSendQCompleteNtb(_In_ MBB_PROTOCOL_HANDLE ProtocolHandle, _In_ MBB_REQUEST_HANDLE RequestHandle, _In_ NTSTATUS NtStatus, _In_ PMDL Mdl) +{ + UNREFERENCED_PARAMETER(ProtocolHandle); + PMBB_NTB_BUILD_CONTEXT ntbContext = (PMBB_NTB_BUILD_CONTEXT)RequestHandle; + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetNetAdapterContext(ntbContext->NetAdapter)->WmbDeviceContext; + UNREFERENCED_PARAMETER(Mdl); + + if (!NT_SUCCESS(NtStatus)) + { + if (NtStatus == STATUS_NDIS_ADAPTER_NOT_READY) + { + } + else if (NtStatus == STATUS_CANCELLED) + { + } + else if (NtStatus == STATUS_NO_SUCH_DEVICE) + { + } + else + { + MbbBusResetDataPipes(deviceContext->BusHandle); + } + } + + MbbNtbCleanupContext(ntbContext, NtStatus); +} + +ULONG +MbbNtbMapNdpTypeToSignature(_In_ MBB_NDP_TYPE MbbNdpType, _In_ BOOLEAN Is32Bit, _In_ ULONG SessionId) +{ + ULONG SessionMask = (SessionId << NCM_NDP_SESSION_SHIFT); + + switch (MbbNdpType) + { + case MbbNdpTypeIps: return ((Is32Bit == TRUE) ? NCM_NDP32_IPS | SessionMask : NCM_NDP16_IPS | SessionMask); + default: + if ((MbbNdpType >= MbbNdpTypeVendor_1) && (MbbNdpType <= MbbNdpTypeVendor_Max)) + { + return ((Is32Bit == TRUE) ? NCM_NDP32_VENDOR | SessionMask : NCM_NDP16_VENDOR | SessionMask); + } + } + return 0; +} + +VOID MbbNtbFillNdp32Header(_In_ PNCM_NDP32 Ndp, _In_ MBB_NDP_TYPE NdpType, _In_ PMBB_NTB_BUILD_CONTEXT NtbContext) +{ + ULONG datagramIndex = 0; + ULONG ndpDatagramIndex = 0; + PNCM_NDP32_DATAGRAM ndpDatagramEntries; + + Ndp->dwSignature = MbbNtbMapNdpTypeToSignature(NdpType, TRUE, NtbContext->NdpDatagramEntries[datagramIndex].SessionId); + Ndp->dwNextFpIndex = 0; + ndpDatagramEntries = Ndp->Datagram; + // + // Add datagram entries to the NDP Table + // + + for (datagramIndex = 0; datagramIndex < NtbContext->DatagramCount; datagramIndex++) + { + ndpDatagramEntries[ndpDatagramIndex].dwDatagramIndex = NtbContext->NdpDatagramEntries[datagramIndex].DatagramOffset; + ndpDatagramEntries[ndpDatagramIndex].dwDatagramLength = NtbContext->NdpDatagramEntries[datagramIndex].DatagramLength; + ndpDatagramIndex++; + } + // + // Terminating entry is taken in to account + // in the fixed size NDP Header. + // + ndpDatagramEntries[ndpDatagramIndex].dwDatagramIndex = 0; + ndpDatagramEntries[ndpDatagramIndex].dwDatagramLength = 0; + + Ndp->wLength = (USHORT)(NtbContext->NdpHeaderFixedSize + (ndpDatagramIndex * NtbContext->NdpDatagramEntrySize)); +} + +VOID MbbNtbFillNdp16Header(__in PNCM_NDP16 Ndp, __in MBB_NDP_TYPE NdpType, __in PMBB_NTB_BUILD_CONTEXT NtbContext) +{ + ULONG datagramIndex = 0; + ULONG ndpDatagramIndex = 0; + PNCM_NDP16_DATAGRAM ndpDatagramEntries; + + Ndp->dwSignature = MbbNtbMapNdpTypeToSignature(NdpType, FALSE, NtbContext->NdpDatagramEntries[datagramIndex].SessionId); + + Ndp->wNextFpIndex = 0; + ndpDatagramEntries = Ndp->Datagram; + // + // Add datagram entries to the NDP Table + // + for (datagramIndex = 0; datagramIndex < NtbContext->DatagramCount; datagramIndex++) + { + ndpDatagramEntries[ndpDatagramIndex].wDatagramIndex = (USHORT)NtbContext->NdpDatagramEntries[datagramIndex].DatagramOffset; + ndpDatagramEntries[ndpDatagramIndex].wDatagramLength = (USHORT)NtbContext->NdpDatagramEntries[datagramIndex].DatagramLength; + ndpDatagramIndex++; + } + // + // Terminating entry is taken in to account + // in the fixed size NDP Header. + // + ndpDatagramEntries[ndpDatagramIndex].wDatagramIndex = 0; + ndpDatagramEntries[ndpDatagramIndex].wDatagramLength = 0; + + Ndp->wLength = (USHORT)(NtbContext->NdpHeaderFixedSize + (ndpDatagramIndex * NtbContext->NdpDatagramEntrySize)); +} + +NTSTATUS +MbbNtbAddNdpHeaders(_In_ PMBB_NTB_BUILD_CONTEXT NtbContext) +{ + // Offset from the start of the NTB buffer to the start of NDP headers + ULONG ndpStartOffset; + // Offset from the start of the NTB Buffer to the current position. + ULONG ntbOffset; + PCHAR ndpBuffer; + MBB_NDP_TYPE ndpType; + PNCM_NDP16 ndp16; + PNCM_NDP32 ndp32; + NTSTATUS status = STATUS_SUCCESS; + + do + { + // + // Allocate buffer for all NDP headers. + // This includes padding for NDP Header alignment. + // + status = CreateNonPagedWdfMemory( + NtbContext->NdpSize, + &NtbContext->NdpBufferMemory, + &NtbContext->NdpBuffer, + NtbContext->NetTxQueue == NULL ? (WDFOBJECT)NtbContext->NetAdapter : NtbContext->NetTxQueue, + MbbPoolTagNtbSend); + if (!NT_SUCCESS(status)) + { + break; + } + RtlZeroMemory(NtbContext->NdpBuffer, NtbContext->NdpSize); + ndpBuffer = (PCHAR)(NtbContext->NdpBuffer); + // + // Chain the NDP Header through its MDL to datagram MDL + // + if ((NtbContext->NdpMdl = AllocateNonPagedMdl(NtbContext->NdpBuffer, NtbContext->NdpSize)) == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + NtbContext->DatagramLastMdl->Next = NtbContext->NdpMdl; + ndpStartOffset = NtbContext->NtbHeaderSize + NtbContext->DatagramLength; + + if (NtbContext->IsNtb32Bit) + NtbContext->Nth32.dwFpIndex = ALIGN(ndpStartOffset, NtbContext->NdpOutAlignment); + else + NtbContext->Nth16.wFpIndex = (USHORT)ALIGN(ndpStartOffset, NtbContext->NdpOutAlignment); + + ntbOffset = ALIGN(ndpStartOffset, NtbContext->NdpOutAlignment); + ndpType = NtbContext->NdpDatagramEntries[0].NdpType; + + if (NtbContext->IsNtb32Bit == TRUE) + { + ndp32 = (PNCM_NDP32)(ndpBuffer + (ntbOffset - ndpStartOffset)); + + MbbNtbFillNdp32Header(ndp32, ndpType, NtbContext); + } + else + { + ndp16 = (PNCM_NDP16)(ndpBuffer + (ntbOffset - ndpStartOffset)); + + MbbNtbFillNdp16Header(ndp16, ndpType, NtbContext); + } + + if (NtbContext->IsNtb32Bit == TRUE) + { + NtbContext->Nth32.dwBlockLength = NtbContext->NtbHeaderSize; + NtbContext->Nth32.dwBlockLength += NtbContext->DatagramLength; + NtbContext->Nth32.dwBlockLength += NtbContext->NdpSize; + } + else + { + NtbContext->Nth16.wBlockLength = (USHORT)(NtbContext->NtbHeaderSize); + NtbContext->Nth16.wBlockLength += (USHORT)(NtbContext->DatagramLength); + NtbContext->Nth16.wBlockLength += (USHORT)(NtbContext->NdpSize); + } + } while (FALSE); + // + // No cleanup. Cleanup done by caller. + // + return status; +} + +NTSTATUS +MbbTestValidateNtb(_In_ PMBB_NTB_BUILD_CONTEXT NtbContext, _In_reads_bytes_(ScratchLength) PCHAR ScratchBuffer, _In_ ULONG ScratchLength) +{ + PMDL currentMdl; + ULONGLONG ntbLength; + ULONG mdlLength; + PVOID mdlVa; + PVOID nth; + + nth = ScratchBuffer; + ntbLength = 0; + + for (currentMdl = MbbNtbGetMdlChainHead(NtbContext); currentMdl != NULL; currentMdl = currentMdl->Next) + { + mdlLength = MmGetMdlByteCount(currentMdl); + + if ((mdlVa = MmGetSystemAddressForMdlSafe(currentMdl, NormalPagePriority | MdlMappingNoExecute)) == NULL) + { + return STATUS_RESOURCE_DATA_NOT_FOUND; + } + + if ((ntbLength + mdlLength) > ScratchLength) + { + return STATUS_BUFFER_OVERFLOW; + } + + RtlCopyMemory(ScratchBuffer, mdlVa, mdlLength); + + ScratchBuffer += mdlLength; + ntbLength += mdlLength; + } + + return MbbNtbValidate(nth, (ULONG)ntbLength, NtbContext->IsNtb32Bit, NULL); +} + +void EvtTxQueueDestroy(_In_ WDFOBJECT TxQueue) +{ + PMBB_TXQUEUE_CONTEXT txQueueContext = MbbGetTxQueueContext(TxQueue); + + txQueueContext->NetAdapterContext->TxQueue = NULL; +} + +VOID EvtTxQueueSetNotificationEnabled(_In_ NETPACKETQUEUE TxQueue, _In_ BOOLEAN NotificationEnabled) +{ + PMBB_TXQUEUE_CONTEXT txQueueContext = MbbGetTxQueueContext(TxQueue); + + InterlockedExchange(&txQueueContext->NotificationEnabled, NotificationEnabled); +} + +void EvtTxQueueCancel(_In_ NETPACKETQUEUE TxQueue) +{ + NET_RING_COLLECTION const* rings = MbbGetTxQueueContext(TxQueue)->DatapathDescriptor; + + NET_RING * pr = NetRingCollectionGetPacketRing(rings); + while (pr->BeginIndex != pr->EndIndex) + { + UINT32 const packetIndex = pr->BeginIndex; + NetRingGetPacketAtIndex(pr, packetIndex)->Scratch = 1; + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + } +} + +bool MbbEnableTxBatching(_In_ NET_RING_COLLECTION const* Rings) +{ + NET_RING * ring = Rings->Rings[NetRingTypeFragment]; + return ((ring->EndIndex - ring->BeginIndex) & ring->ElementIndexMask) > (NetRingCollectionGetPacketRing(Rings)->NumberOfElements / 2); +} + +inline +VOID +CompleteTxPacketsBatch( + _In_ NET_RING_COLLECTION const * Rings, + _In_ UINT32 BatchSize +) +{ + UINT32 packetCount = 0; + + NET_RING * pr = NetRingCollectionGetPacketRing(Rings); + + while (pr->BeginIndex != pr->EndIndex) + { + UINT32 const packetIndex = pr->BeginIndex; + auto packet = NetRingGetPacketAtIndex(pr, packetIndex); + + // this function uses Scratch field as the bit for testing completion + if (!packet->Scratch) + { + break; + } + + packetCount++; + + NET_RING * fr = NetRingCollectionGetFragmentRing(Rings); + fr->BeginIndex = fr->EndIndex; + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + + if (packetCount >= BatchSize) + { + Rings->Rings[NetRingTypeFragment]->BeginIndex = fr->BeginIndex; + } + } +} + +void EvtTxQueueAdvance(_In_ NETPACKETQUEUE TxQueue) +{ + NTSTATUS status = STATUS_SUCCESS; + PMBB_TXQUEUE_CONTEXT txQueueContext = MbbGetTxQueueContext(TxQueue); + NET_RING_COLLECTION const* rings = txQueueContext->DatapathDescriptor; + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = txQueueContext->NetAdapterContext; + PWMBCLASS_DEVICE_CONTEXT deviceContext = netAdapterContext->WmbDeviceContext; + PMBB_NTB_BUILD_CONTEXT ntbContext = NULL; + ULONG sessionId = netAdapterContext->SessionId; + ULONG batchSize = MbbEnableTxBatching(rings) ? txQueueContext->CompletionBatchSize : 1; + + NET_RING * pr = NetRingCollectionGetPacketRing(rings); + while (pr->BeginIndex != pr->EndIndex) + { + UINT32 const packetIndex = pr->BeginIndex; + auto packet = NetRingGetPacketAtIndex(pr, packetIndex); + if (packet->Ignore) + { + packet->Scratch = 1; + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + continue; + } + + ntbContext = MbbNtbAllocateContext( + netAdapterContext->NtbLookasideList, &deviceContext->BusParams, deviceContext->sharedPaddingBuffer, MbbSendQGetNtbSequence(deviceContext)); + + if (ntbContext == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + ntbContext->NetTxQueue = TxQueue; + ntbContext->NetAdapter = netAdapterContext->NetAdapter; + ntbContext->NetDatapathDescriptor = rings; + + auto fr = NetRingCollectionGetFragmentRing(rings); + while (NT_SUCCESS( + status = MbbNtbAddPacket( + ntbContext, + packet, + MbbGetNetPacketDataLength(packet, rings), + NetExtensionGetFragmentMdl(&txQueueContext->MdlExtension, packet->FragmentIndex)->Mdl, + NetRingGetFragmentAtIndex(fr, packet->FragmentIndex)->Offset, + MbbNdpTypeIps, + sessionId))) + { + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + + // the ring buffer has no more net packets to send, + // so packing is done. break now to make USB request + if (pr->BeginIndex == pr->EndIndex) + { + break; + } + + UINT32 const packetIndex = pr->BeginIndex; + packet = NetRingGetPacketAtIndex(pr, packetIndex); + } + + if (status == STATUS_BUFFER_OVERFLOW) + { + // + // If the NTB was empty and this packet couldnt be added + // then ignore this packet to prevent retrying forever. + // Or send this NTB to bus then start a new NTB + // + if (ntbContext->DatagramCount == 0) + { + packet->Scratch = 1; + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + } + } + else if (status != STATUS_SUCCESS) + { + // + // MbbNtbAddPacket failed, we should ignore this packet, or the loop may never complete + // + packet->Scratch = 1; + pr->BeginIndex = NetRingIncrementIndex(pr, pr->BeginIndex); + } + + if (ntbContext->DatagramCount > 0) + { + status = MbbNtbAddNdpHeaders(ntbContext); + if (!NT_SUCCESS(status)) + { + } + else + { +#if DBG + if (!NT_SUCCESS(MbbTestValidateNtb(ntbContext, ntbContext->ScratchBuffer, ntbContext->ScratchLength))) + { + ASSERT(FALSE); + } +#endif + // + // Send the data. On failure, cleanup. + // + status = MbbBusWriteData(deviceContext->BusHandle, ntbContext, MbbNtbGetMdlChainHead(ntbContext), MbbSendQCompleteNtb); + if (!NT_SUCCESS(status)) + { + } + } + } + else + { + status = STATUS_UNSUCCESSFUL; + } + + if (!NT_SUCCESS(status)) + { + MbbSendQCompleteNtb(netAdapterContext, ntbContext, status, MbbNtbGetMdlChainHead(ntbContext)); + } + } + + CompleteTxPacketsBatch(rings, batchSize); +} + +PDSS_PACKET MbbAllocateDssPacket(_In_ WDFMEMORY Data, _In_ PVOID DataBuffer, _In_ size_t DataSize) +{ + NTSTATUS status = STATUS_SUCCESS; + PDSS_PACKET packet = NULL; + do + { +// By Design: Allocate packet from NtbSend Pool, released in function MbbNtbCleanupContext called from MbbSendQCompleteNtb. +#pragma prefast(suppress : __WARNING_MEMORY_LEAK, "Released in function MbbNtbCleanupContext") + packet = (PDSS_PACKET)ALLOCATE_NONPAGED_POOL_WITH_TAG(sizeof(DSS_PACKET), MbbPoolTagNtbSend); + if (packet == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + RtlZeroMemory(packet, sizeof(DSS_PACKET)); + + packet->Data = Data; + packet->Mdl = AllocateNonPagedMdl(DataBuffer, (ULONG)DataSize); + + if (packet->Mdl == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + } while (FALSE); + + if (!NT_SUCCESS(status)) + { + if (packet != NULL) + { + MbbCleanupDssPacket(packet); + packet = NULL; + } + } + + return packet; +} + +_Use_decl_annotations_ VOID EvtMbbDeviceSendDeviceServiceSessionData(WDFDEVICE Device, DSS_SESSION_ID SessionId, WDFMEMORY Data) +{ + PWMBCLASS_DEVICE_CONTEXT deviceContext = WmbClassGetDeviceContext(Device); + NTSTATUS status = STATUS_SUCCESS; + + PWMBCLASS_NETADAPTER_CONTEXT netAdapterContext = deviceContext->Sessions[MBB_DEFAULT_SESSION_ID].NetAdapterContext; + + PMBB_NTB_BUILD_CONTEXT ntbContext = NULL; + PDSS_PACKET packet = NULL; + BOOLEAN completeNow = TRUE; + + do + { + ntbContext = MbbNtbAllocateContext( + netAdapterContext->NtbLookasideList, &deviceContext->BusParams, deviceContext->sharedPaddingBuffer, MbbSendQGetNtbSequence(deviceContext)); + + if (ntbContext == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + ntbContext->NetTxQueue = NULL; + ntbContext->NetAdapter = netAdapterContext->NetAdapter; + size_t bufferSize = 0; + PVOID buffer = WdfMemoryGetBuffer(Data, &bufferSize); + + packet = MbbAllocateDssPacket(Data, buffer, bufferSize); + if (packet == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + status = MbbNtbAddPacket(ntbContext, packet, (ULONG)bufferSize, packet->Mdl, 0, MbbNdpTypeVendor_1, SessionId); + if (!NT_SUCCESS(status)) + { + MbbCleanupDssPacket(packet); + break; + } + + completeNow = FALSE; + + status = MbbNtbAddNdpHeaders(ntbContext); + if (!NT_SUCCESS(status)) + { + break; + } + +#if DBG + if (!NT_SUCCESS(MbbTestValidateNtb(ntbContext, ntbContext->ScratchBuffer, ntbContext->ScratchLength))) + { + ASSERT(FALSE); + } +#endif + + // + // Send the data. On failure, cleanup. It will return STATUS_PENDING when success + // + status = MbbBusWriteData(deviceContext->BusHandle, ntbContext, MbbNtbGetMdlChainHead(ntbContext), MbbSendQCompleteNtb); + if (!NT_SUCCESS(status)) + { + break; + } + + deviceContext->DSSPacketsSentCount++; + } while (FALSE); + + if (!NT_SUCCESS(status)) + { + if (ntbContext != NULL) + { + MbbSendQCompleteNtb(deviceContext, ntbContext, status, MbbNtbGetMdlChainHead(ntbContext)); + } + if (completeNow) + { + MbbDeviceSendDeviceServiceSessionDataComplete(Data, status); + } + } +} diff --git a/network/wwan/cxwmbclass/util.c b/network/wwan/cxwmbclass/util.c deleted file mode 100644 index 6b3d9a5cb..000000000 --- a/network/wwan/cxwmbclass/util.c +++ /dev/null @@ -1,9090 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -//////////////////////////////////////////////////////////////////////////////// -// -// INCLUDES -// -//////////////////////////////////////////////////////////////////////////////// -#include "precomp.h" -#include "util.tmh" -#include -#include "WMBClassTelemetry.h" - - - -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// -#define WMBCLASS_MAX_EVENT_DATA_DESCRIPTORS (10) - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// TYPEDEFS -// -//////////////////////////////////////////////////////////////////////////////// -// this is for translating a code into an ASCII string -typedef struct Code2Ascii -{ - NDIS_OID Oid; - PCHAR OidName; -} Code2Ascii; - -typedef struct _MBB_ALLOC_MANAGER -{ - NPAGED_LOOKASIDE_LIST LookasideList; - NDIS_SPIN_LOCK Lock; - LIST_ENTRY AllocatedList; - LIST_ENTRY PreAllocatedFreeList; - MBB_ALLOC_FLAGS Flags; - -} MBB_ALLOC_MANAGER, -*PMBB_ALLOC_MANAGER; - -typedef struct _MBB_ALLOC_ENTRY -{ - LIST_ENTRY TrackLink; - LIST_ENTRY FreeLink; - BOOLEAN IsPreAllocated; - PMBB_ALLOC_MANAGER AllocMgr; - -} MBB_ALLOC_ENTRY, -*PMBB_ALLOC_ENTRY; - -typedef struct _MBB_BUFFER_MANAGER -{ - PVOID AllocMgrHandle; - ULONG BufferLength; - -} MBB_BUFFER_MANAGER, -*PMBB_BUFFER_MANAGER; - -typedef struct _MBB_BUFFER_CONTEXT -{ - PMBB_BUFFER_MANAGER BufferManager; - PVOID OwnerContext; - -} MBB_BUFFER_CONTEXT, -*PMBB_BUFFER_CONTEXT; - -typedef struct _MBB_WORKITEM_ENTRY -{ - LIST_ENTRY QueueLink; - PVOID Context1; - PVOID Context2; - PVOID Context3; - PVOID Context4; - MBB_WORKITEM_ROUTINE Routine; - -} MBB_WORKITEM_ENTRY, -*PMBB_WORKITEM_ENTRY; - -typedef struct _MBB_WORKITEM_MANAGER -{ - NDIS_SPIN_LOCK Lock; - PVOID AllocMgrHandle; - KEVENT ThreadExitEvent; - KEVENT WorkItemEvent; - LIST_ENTRY WorkItemQueue; - HANDLE ThreadHandle; - -} MBB_WORKITEM_MANAGER, -*PMBB_WORKITEM_MANAGER; - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// GLOBALS -// -//////////////////////////////////////////////////////////////////////////////// -const Code2Ascii OidList[] = -{ - OID_GEN_SUPPORTED_LIST, "OID_GEN_SUPPORTED_LIST", - OID_GEN_HARDWARE_STATUS, "OID_GEN_HARDWARE_STATUS", - OID_GEN_MEDIA_SUPPORTED, "OID_GEN_MEDIA_SUPPORTED", - OID_GEN_MEDIA_IN_USE, "OID_GEN_MEDIA_IN_USE", - OID_GEN_MAXIMUM_LOOKAHEAD, "OID_GEN_MAXIMUM_LOOKAHEAD", - OID_GEN_MAXIMUM_FRAME_SIZE, "OID_GEN_MAXIMUM_FRAME_SIZE", - OID_GEN_LINK_SPEED, "OID_GEN_LINK_SPEED", - OID_GEN_TRANSMIT_BUFFER_SPACE, "OID_GEN_TRANSMIT_BUFFER_SPACE", - OID_GEN_RECEIVE_BUFFER_SPACE, "OID_GEN_RECEIVE_BUFFER_SPACE", - OID_GEN_TRANSMIT_BLOCK_SIZE, "OID_GEN_TRANSMIT_BLOCK_SIZE", - OID_GEN_RECEIVE_BLOCK_SIZE, "OID_GEN_RECEIVE_BLOCK_SIZE", - OID_GEN_VENDOR_ID, "OID_GEN_VENDOR_ID", - OID_GEN_VENDOR_DESCRIPTION, "OID_GEN_VENDOR_DESCRIPTION", - OID_GEN_CURRENT_PACKET_FILTER, "OID_GEN_CURRENT_PACKET_FILTER", - OID_GEN_TRANSPORT_HEADER_OFFSET, "OID_GEN_TRANSPORT_HEADER_OFFSET", - OID_GEN_CURRENT_LOOKAHEAD, "OID_GEN_CURRENT_LOOKAHEAD", - OID_GEN_DRIVER_VERSION, "OID_GEN_DRIVER_VERSION", - OID_GEN_VENDOR_DRIVER_VERSION, "OID_GEN_VENDOR_DRIVER_VERSION", - OID_GEN_MAXIMUM_TOTAL_SIZE, "OID_GEN_MAXIMUM_TOTAL_SIZE", - OID_GEN_PROTOCOL_OPTIONS, "OID_GEN_PROTOCOL_OPTIONS", - OID_GEN_MAC_OPTIONS, "OID_GEN_MAC_OPTIONS", - OID_GEN_MEDIA_CONNECT_STATUS, "OID_GEN_MEDIA_CONNECT_STATUS", - OID_GEN_MAXIMUM_SEND_PACKETS, "OID_GEN_MAXIMUM_SEND_PACKETS", - OID_GEN_SUPPORTED_GUIDS, "OID_GEN_SUPPORTED_GUIDS", - OID_GEN_XMIT_OK, "OID_GEN_XMIT_OK", - OID_GEN_RCV_OK, "OID_GEN_RCV_OK", - OID_GEN_XMIT_ERROR, "OID_GEN_XMIT_ERROR", - OID_GEN_RCV_ERROR, "OID_GEN_RCV_ERROR", - OID_GEN_RCV_NO_BUFFER, "OID_GEN_RCV_NO_BUFFER", - OID_GEN_RCV_CRC_ERROR, "OID_GEN_RCV_CRC_ERROR", - OID_GEN_TRANSMIT_QUEUE_LENGTH, "OID_GEN_TRANSMIT_QUEUE_LENGTH", - OID_802_3_PERMANENT_ADDRESS, "OID_802_3_PERMANENT_ADDRESS", - OID_802_3_CURRENT_ADDRESS, "OID_802_3_CURRENT_ADDRESS", - OID_802_3_MULTICAST_LIST, "OID_802_3_MULTICAST_LIST", - OID_802_3_MAXIMUM_LIST_SIZE, "OID_802_3_MAXIMUM_LIST_SIZE", - OID_802_3_RCV_ERROR_ALIGNMENT, "OID_802_3_RCV_ERROR_ALIGNMENT", - OID_802_3_XMIT_ONE_COLLISION, "OID_802_3_XMIT_ONE_COLLISION", - OID_802_3_XMIT_MORE_COLLISIONS, "OID_802_3_XMIT_MORE_COLLISIONS", - OID_802_3_XMIT_DEFERRED, "OID_802_3_XMIT_DEFERRED", - OID_802_3_XMIT_MAX_COLLISIONS, "OID_802_3_XMIT_MAX_COLLISIONS", - OID_802_3_RCV_OVERRUN, "OID_802_3_RCV_OVERRUN", - OID_802_3_XMIT_UNDERRUN, "OID_802_3_XMIT_UNDERRUN", - OID_802_3_XMIT_HEARTBEAT_FAILURE, "OID_802_3_XMIT_HEARTBEAT_FAILURE", - OID_802_3_XMIT_TIMES_CRS_LOST, "OID_802_3_XMIT_TIMES_CRS_LOST", - OID_802_3_XMIT_LATE_COLLISIONS, "OID_802_3_XMIT_LATE_COLLISIONS", - OID_802_3_MAC_OPTIONS, "OID_802_3_MAC_OPTIONS", - OID_TCP_TASK_OFFLOAD, "OID_TCP_TASK_OFFLOAD", - OID_PNP_CAPABILITIES, "OID_PNP_CAPABILITIES", - OID_PNP_SET_POWER, "OID_PNP_SET_POWER", - OID_PNP_QUERY_POWER, "OID_PNP_QUERY_POWER", - OID_PNP_ADD_WAKE_UP_PATTERN, "OID_PNP_ADD_WAKE_UP_PATTERN", - OID_PNP_REMOVE_WAKE_UP_PATTERN, "OID_PNP_REMOVE_WAKE_UP_PATTERN", - OID_PNP_ENABLE_WAKE_UP, "OID_PNP_ENABLE_WAKE_UP", - OID_GEN_STATISTICS, "OID_GEN_STATISTICS", - OID_GEN_MEDIA_SUPPORTED, "OID_GEN_MEDIA_SUPPORTED", - OID_WWAN_DRIVER_CAPS, "OID_WWAN_DRIVER_CAPS", - OID_WWAN_DEVICE_CAPS, "OID_WWAN_DEVICE_CAPS", - OID_WWAN_READY_INFO, "OID_WWAN_READY_INFO", - OID_WWAN_RADIO_STATE, "OID_WWAN_RADIO_STATE", - OID_WWAN_PIN_EX, "OID_WWAN_PIN_EX", - OID_WWAN_PIN_LIST, "OID_WWAN_PIN_LIST", - OID_WWAN_HOME_PROVIDER, "OID_WWAN_HOME_PROVIDER", - OID_WWAN_PREFERRED_PROVIDERS, "OID_WWAN_PREFERRED_PROVIDERS", - OID_WWAN_VISIBLE_PROVIDERS, "OID_WWAN_VISIBLE_PROVIDERS", - OID_WWAN_REGISTER_STATE, "OID_WWAN_REGISTER_STATE", - OID_WWAN_PACKET_SERVICE, "OID_WWAN_PACKET_SERVICE", - OID_WWAN_SIGNAL_STATE, "OID_WWAN_SIGNAL_STATE", - OID_WWAN_CONNECT, "OID_WWAN_CONNECT", - OID_WWAN_PROVISIONED_CONTEXTS, "OID_WWAN_PROVISIONED_CONTEXTS", - OID_WWAN_SERVICE_ACTIVATION, "OID_WWAN_SERVICE_ACTIVATION", - OID_WWAN_ENUMERATE_DEVICE_SERVICES, "OID_WWAN_ENUMERATE_DEVICE_SERVICES", - OID_WWAN_DEVICE_SERVICE_COMMAND, "OID_WWAN_DEVICE_SERVICE_COMMAND", - OID_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS,"OID_WWAN_SUBSCRIBE_DEVICE_SERVICE_EVENTS", - OID_WWAN_SMS_CONFIGURATION, "OID_WWAN_SMS_CONFIGURATION", - OID_WWAN_SMS_READ, "OID_WWAN_SMS_READ", - OID_WWAN_SMS_SEND, "OID_WWAN_SMS_SEND", - OID_WWAN_SMS_DELETE, "OID_WWAN_SMS_DELETE", - OID_WWAN_SMS_STATUS, "OID_WWAN_SMS_STATUS", - OID_WWAN_VENDOR_SPECIFIC, "OID_WWAN_VENDOR_SPECIFIC", - OID_WWAN_USSD, "OID_WWAN_USSD", - OID_WWAN_AUTH_CHALLENGE, "OID_WWAN_AUTH_CHALLENGE", - OID_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS,"OID_WWAN_ENUMERATE_DEVICE_SERVICE_COMMANDS", - OID_WWAN_DEVICE_SERVICE_SESSION, "OID_WWAN_DEVICE_SERVICE_SESSION", - OID_WWAN_DEVICE_SERVICE_SESSION_WRITE, "OID_WWAN_DEVICE_SERVICE_SESSION_WRITE", - OID_WWAN_DEVICE_SERVICE_SESSION_WRITE, "OID_WWAN_DEVICE_SERVICE_SESSION_WRITE", - OID_WWAN_CREATE_MAC, "OID_WWAN_CREATE_MAC", - OID_WWAN_DELETE_MAC, "OID_WWAN_DELETE_MAC", - OID_WWAN_UICC_FILE_STATUS, "OID_WWAN_UICC_FILE_STATUS", - OID_WWAN_UICC_ACCESS_BINARY, "OID_WWAN_UICC_ACCESS_BINARY", - OID_WWAN_UICC_ACCESS_RECORD, "OID_WWAN_UICC_ACCESS_RECORD", - OID_WWAN_PIN_EX2, "OID_WWAN_PIN_EX2", - OID_WWAN_MBIM_VERSION, "OID_WWAN_MBIM_VERSION", - OID_WWAN_SYS_CAPS, "OID_WWAN_SYS_CAPS", - OID_WWAN_DEVICE_CAPS_EX, "OID_WWAN_DEVICE_CAPS_EX", - OID_WWAN_SYS_SLOTMAPPINGS, "OID_WWAN_SYS_SLOTMAPPINGS", - OID_WWAN_SLOT_INFO_STATUS, "OID_WWAN_SLOT_INFO_STATUS", - OID_WWAN_DEVICE_BINDINGS, "OID_WWAN_DEVICE_BINDINGS", - OID_WWAN_REGISTER_STATE_EX, "OID_WWAN_REGISTER_STATE_EX", - OID_WWAN_IMS_VOICE_STATE, "OID_WWAN_IMS_VOICE_STATE", - OID_WWAN_SIGNAL_STATE_EX, "OID_WWAN_SIGNAL_STATE_EX", - OID_WWAN_LOCATION_STATE, "OID_WWAN_LOCATION_STATE", - OID_WWAN_NITZ, "OID_WWAN_NITZ", - OID_WWAN_NETWORK_IDLE_HINT, "OID_WWAN_NETWORK_IDLE_HINT", - OID_WWAN_PRESHUTDOWN, "OID_WWAN_PRESHUTDOWN", - OID_WWAN_UICC_ATR, "OID_WWAN_UICC_ATR", - OID_WWAN_UICC_OPEN_CHANNEL, "OID_WWAN_UICC_OPEN_CHANNEL", - OID_WWAN_UICC_CLOSE_CHANNEL, "OID_WWAN_UICC_CLOSE_CHANNEL", - OID_WWAN_UICC_APDU, "OID_WWAN_UICC_APDU", - OID_WWAN_UICC_TERMINAL_CAPABILITY, "OID_WWAN_UICC_TERMINAL_CAPABILITY", - OID_WWAN_SAR_CONFIG, "OID_WWAN_SAR_CONFIG", - OID_WWAN_SAR_TRANSMISSION_STATUS, "OID_WWAN_SAR_TRANSMISSION_STATUS", - OID_WWAN_LTE_ATTACH_CONFIG, "OID_WWAN_LTE_ATTACH_CONFIG", - OID_WWAN_LTE_ATTACH_STATUS, "OID_WWAN_LTE_ATTACH_STATUS", - OID_WWAN_NETWORK_BLACKLIST, "OID_WWAN_NETWORK_BLACKLIST", - OID_WWAN_UICC_RESET, "OID_WWAN_UICC_RESET", - OID_WWAN_DEVICE_RESET, "OID_WWAN_DEVICE_RESET", - OID_WWAN_UICC_APP_LIST, "OID_WWAN_UICC_APP_LIST", -}; - -const UINT NumOid = sizeof(OidList) / sizeof(Code2Ascii); - -const Code2Ascii IndicationList[] = -{ - NDIS_STATUS_WWAN_DEVICE_CAPS, "NDIS_STATUS_WWAN_DEVICE_CAPS", - NDIS_STATUS_WWAN_READY_INFO, "NDIS_STATUS_WWAN_READY_INFO", - NDIS_STATUS_WWAN_RADIO_STATE, "NDIS_STATUS_WWAN_RADIO_STATE", - NDIS_STATUS_WWAN_PIN_INFO, "NDIS_STATUS_WWAN_PIN_INFO", - NDIS_STATUS_WWAN_PIN_LIST, "NDIS_STATUS_WWAN_PIN_LIST", - NDIS_STATUS_WWAN_HOME_PROVIDER, "NDIS_STATUS_WWAN_HOME_PROVIDER", - NDIS_STATUS_WWAN_PREFERRED_PROVIDERS, "NDIS_STATUS_WWAN_PREFERRED_PROVIDERS", - NDIS_STATUS_WWAN_VISIBLE_PROVIDERS, "NDIS_STATUS_WWAN_VISIBLE_PROVIDERS", - NDIS_STATUS_WWAN_REGISTER_STATE, "NDIS_STATUS_WWAN_REGISTER_STATE", - NDIS_STATUS_WWAN_PACKET_SERVICE, "NDIS_STATUS_WWAN_PACKET_SERVICE", - NDIS_STATUS_WWAN_SIGNAL_STATE, "NDIS_STATUS_WWAN_SIGNAL_STATE", - NDIS_STATUS_WWAN_CONTEXT_STATE, "NDIS_STATUS_WWAN_CONTEXT_STATE", - NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS, "NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS", - NDIS_STATUS_WWAN_SERVICE_ACTIVATION, "NDIS_STATUS_WWAN_SERVICE_ACTIVATION", - NDIS_STATUS_WWAN_SMS_CONFIGURATION, "NDIS_STATUS_WWAN_SMS_CONFIGURATION", - NDIS_STATUS_WWAN_SMS_RECEIVE, "NDIS_STATUS_WWAN_SMS_RECEIVE", - NDIS_STATUS_WWAN_SMS_SEND, "NDIS_STATUS_WWAN_SMS_SEND", - NDIS_STATUS_WWAN_SMS_DELETE, "NDIS_STATUS_WWAN_SMS_DELETE", - NDIS_STATUS_WWAN_SMS_STATUS, "NDIS_STATUS_WWAN_SMS_STATUS", - NDIS_STATUS_WWAN_DNS_ADDRESS, "NDIS_STATUS_WWAN_DNS_ADDRESS", - - NDIS_STATUS_WWAN_VENDOR_SPECIFIC, "NDIS_STATUS_WWAN_VENDOR_SPECIFIC", - - NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES, "NDIS_STATUS_WWAN_SUPPORTED_DEVICE_SERVICES", - NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SUBSCRIPTION", - NDIS_STATUS_WWAN_SET_HOME_PROVIDER_COMPLETE, "NDIS_STATUS_WWAN_SET_HOME_PROVIDER_COMPLETE", - NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE, "NDIS_STATUS_WWAN_DEVICE_SERVICE_RESPONSE", - NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT, "NDIS_STATUS_WWAN_DEVICE_SERVICE_EVENT", - NDIS_STATUS_WWAN_USSD, "NDIS_STATUS_WWAN_USSD", - NDIS_STATUS_WWAN_AUTH_RESPONSE, "NDIS_STATUS_WWAN_AUTH_RESPONSE", - NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SUPPORTED_COMMANDS", - NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION", - NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_WRITE_COMPLETE", - NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ, "NDIS_STATUS_WWAN_DEVICE_SERVICE_SESSION_READ", - NDIS_STATUS_WWAN_PRESHUTDOWN_STATE, "NDIS_STATUS_WWAN_PRESHUTDOWN_STATE", - NDIS_STATUS_WWAN_SYS_CAPS_INFO, "NDIS_STATUS_WWAN_SYS_CAPS_INFO", - NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO, "NDIS_STATUS_WWAN_DEVICE_SLOT_MAPPING_INFO", - NDIS_STATUS_WWAN_SLOT_INFO, "NDIS_STATUS_WWAN_SLOT_INFO", - NDIS_STATUS_WWAN_DEVICE_CAPS_EX, "NDIS_STATUS_WWAN_DEVICE_CAPS_EX", -}; - -const UINT NumIndications = sizeof(IndicationList) / sizeof(Code2Ascii); - -CHAR CommandStringTableBasic[MBB_BASIC_CID_MAXIMUM][48] = -{ - "BASIC_UNKNOWN_0", - "BASIC_DEVICE_CAPS", - "BASIC_SUBSCRIBER_READY_INFO", - "BASIC_RADIO_STATE", - "BASIC_PIN_INFO", - "BASIC_PIN_LIST", - "BASIC_HOME_PROVIDER", - "BASIC_PREFERRED_PROVIDERS", - "BASIC_VISIBLE_PROVIDERS", - "BASIC_REGISTER_STATE", - "BASIC_PACKET_SERVICE", - "BASIC_SIGNAL_STATE", - "BASIC_CONNECT", - "BASIC_PROVISIONED_CONTEXTS", - "BASIC_SERVICE_ACTIVATION", - "BASIC_IP_ADDRESS_INFO", - "BASIC_CID_DEVICE_SERVICES", - "BASIC_UNKNOWN_17", - "BASIC_UNKNOWN_18", - "BASIC_NOTIFY_DEVICE_SERVICE_UPDATES", - "BASIC_PACKET_STATISTICS", - "BASIC_NETWORK_IDLE_HINT", - "BASIC_EMERGENCY_MODE", - "BASIC_PACKET_FILTERS" -}; - -CHAR CommandStringTableSMS[MBB_SMS_CID_MAXIMUM][32] = -{ - "SMS_UNKNOWN", - "SMS_CONFIGURATION", - "SMS_READ", - "SMS_SEND", - "SMS_DELETE", - "SMS_STATUS" -}; - -CHAR CommandStringTableVendor[MBB_VENDOR_CID_MAXIMUM][32] = -{ - "VENDOR_UNKNOWN", - "VENDOR_MS_SPECIFIC", -}; - -CHAR CommandStringTableUSSD[MBB_USSD_CID_MAXIMUM][32] = -{ - "USSD_UNKNOWN", - "USSD_USSD" -}; - -CHAR CommandStringTablePhoneBook[MBB_PHONEBOOK_CID_MAXIMUM][32] = -{ - "PHONEBOOK_UNKNOWN", - "PHONEBOOK_CONFIGURATION", - "PHONEBOOK_READ", - "PHONEBOOK_DELETE", - "PHONEBOOK_SAVE" -}; - -CHAR CommandStringTableSAT[MBB_SAT_CID_MAXIMUM][32] = -{ - "SAT_UNKNOWN", - "SAT_PAC", - "SAT_TERMINAL_RESPONSE", - "SAT_ENVELOPE" -}; - - -CHAR CommandStringTableAuth[MBB_AUTH_CID_MAXIUM][32]= -{ - "AUTH_UNKNOWN", - "AUTH_AKA", - "AUTH_AKAP", - "AUTH_SIM" -}; - -CHAR CommandStringTableMulticarrier[MBB_MULTICARRIER_CID_MAXIMUM][32]= -{ - "MULTICARRIER_UNKNOWN", - "MULTICARRIER_CAPABILITIES", - "MULTICARRIER_LOCATION_INFO", - "MULTICARRIER_CURRENT_CID_LIST" -}; - -CHAR CommandStringTableDss[MBB_DSS_CID_MAXIUM][32]= -{ - "DSS_CID_UNKNOWN", - "DSS_CID_CONNECT" -}; - -CHAR CommandStringTableHostShutdown[MBB_HOSTSHUTDOWN_CID_MAX][32]= -{ - "HOSTSHUTDOWN_UNKNOWN", - "HOSTSHUTDOWN_CID_ONE", - "HOSTSHUTDOWN_CID_PRESHUTDOWN", -}; - -CHAR CommandStringTableUicc[MBB_UICC_CID_MAXIMUM][32] = -{ - "UICC_UNKNOWN", - "UICC_CID_ATR", - "UICC_CID_OPEN_CHANNEL", - "UICC_CID_CLOSE_CHANNEL", - "UICC_CID_APDU", - "UICC_CID_TERMINAL_CAPABILITY", - "UICC_CID_RESET" - "UICC_APP_LIST", - "UICC_FILE_STATUS", - "UICC_ACCESS_BINARY", - "UICC_ACCESS_RECORD", -}; - -CHAR CommandStringTableSar[MBB_SAR_CID_MAXIMUM][32] = -{ - "SAR_UNKNOWN", - "SAR_CONFIG", - "SAR_TRANSMISSION_STATUS" -}; - -CHAR CommandStringTableBasicExt[MBB_BASICCONNECTEXT_CID_MAXIMUM][32] = -{ - "BASICEXT_UNKNOWN", - "BASICEXT_PROVISIONED_CONTEXT_V2", - "BASICEXT_NETWORK_BLACKLIST", - "BASICEXT_LTE_ATTACH_CONFIG", - "BASICEXT_LTE_ATTACH_STATUS", - "BASICEXT_CID_SYS_CAPS", - "BASICEXT_CID_DEVICE_CAPS_V2", - "BASICEXT_CID_SLOT_MAPPINGS", - "BASICEXT_CID_SLOT_INFO_STATUS", - "BASICEXT_CID_PCO", - "BASICEXT_CID_DEVICE_RESET" -}; - - -//////////////////////////////////////////////////////////////////////////////// -// -// PROTOTYPES -// -//////////////////////////////////////////////////////////////////////////////// - -// -// FRAGMENT ROUTINES -// - -NTSTATUS -MbbUtilBusSendMessageFragment( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_HANDLE FragmentBufferHandle, - __in PVOID MessageFragment, - __in ULONG FragmentLength - ); - -VOID -MbbUtilSendMessageFragmentComplete( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in MBB_REQUEST_HANDLE RequestHandle, - __in NTSTATUS NtStatus - ); - -// -// WORK ITEM -// - -__drv_sameIRQL -__drv_functionClass(KSTART_ROUTINE) -VOID -MbbWorkMgrProcessWorkItem( - __in PVOID StartContext - ); - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// IMPLEMENTATION -// -//////////////////////////////////////////////////////////////////////////////// - -/****************************************************************************/ -/* GetOidName */ -/****************************************************************************/ -/* */ -/* Routine Description: */ -/* */ -/* Returns string with OID name */ -/* */ -/* Arguments: */ -/* */ -/* Oid - OID to find */ -/* */ -/* Return: */ -/* */ -/* PCHAR */ -/* */ -/****************************************************************************/ -PCSTR -GetOidName( - __in NDIS_OID Oid - ) -{ - UINT Index; - - // - // see if the matching Oid and string are in the list - // - for(Index = 0; Index < NumOid; Index++) - { - if(Oid == OidList[Index].Oid) - { - return OidList[Index].OidName; - } - } - -// TraceWarn(WMBCLASS_OID, " unknown OID %08lx", Oid); - - return "Unknown OID"; - -} // GetOidName - -BOOLEAN -IsSameGuid(GUID * pgGuid1, GUID *pgGuid2) -{ - ASSERT (pgGuid1); - ASSERT(pgGuid2); - - return (!memcmp(pgGuid1, pgGuid2, sizeof(GUID))); -} - -BOOLEAN -IsZeroGuid( - __in GUID* pGuid - ) -{ - GUID ZeroGuid = {0}; - return IsSameGuid(pGuid,&ZeroGuid);; -} - -PCSTR -MbbUtilGetWwanIndicationString( - __in NDIS_STATUS Indication - ) -{ - UINT Index; - - // - // see if the matching Oid and string are in the list - // - for(Index = 0; Index < NumOid; Index++) - { - if(Indication == IndicationList[Index].Oid) - { - return OidList[Index].OidName; - } - } - -// TraceWarn(WMBCLASS_OID, " unknown OID %08lx", Oid); - - return "Unknown Indication"; - -} // GetOidName - - - -/****************************************************************************/ -/* GetDeviceFriendlyName */ -/****************************************************************************/ -/* */ -/* Routine Description: */ -/* */ -/* Return the friendly name associated with the given Adapter. */ -/* */ -/* Arguments: */ -/* */ -/* MiniportAdapterHandle - NDIS context for the adapter */ -/* */ -/* Return: */ -/* */ -/* NTSTATUS */ -/* */ -/****************************************************************************/ -NDIS_STATUS -GetDeviceFriendlyName( - __in NDIS_HANDLE MiniportAdapterHandle, - __out PANSI_STRING AnsiName - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - NTSTATUS NtStatus; - UNICODE_STRING UnicodeString = {0, 0, NULL}; - ANSI_STRING AnsiString = {0, 0, NULL}; - USHORT AnsiMaxLength; - - - - do - { - RtlInitAnsiString(AnsiName,NULL); - - Status = NdisMQueryAdapterInstanceName(&UnicodeString, MiniportAdapterHandle); - - if (Status != NDIS_STATUS_SUCCESS) - { - break; - } - - // - // Allocate space for ANSI version. - // - AnsiMaxLength = UnicodeString.MaximumLength+sizeof(WCHAR) / sizeof(WCHAR); - - AnsiString.Buffer = ALLOCATE_NONPAGED_POOL( AnsiMaxLength ); - - if (AnsiString.Buffer == NULL) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - break; - } - - AnsiString.MaximumLength = AnsiMaxLength; - AnsiString.Length = 0; - RtlZeroMemory(AnsiString.Buffer, AnsiString.MaximumLength); - - NtStatus = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); - - if (!NT_SUCCESS(NtStatus)) - { - ASSERT(FALSE); - Status = NDIS_STATUS_FAILURE; - break; - } - - *AnsiName = AnsiString; - AnsiString.Buffer=NULL; - Status = NDIS_STATUS_SUCCESS; - - break; - } - while (FALSE); - - if (UnicodeString.Buffer != NULL) - { - NdisFreeMemory(UnicodeString.Buffer, 0, 0); - } - - if (AnsiString.Buffer != NULL) - { - FREE_POOL(AnsiString.Buffer); - } - - - return (Status); -} - - -VOID -FreeAdapterBlock( - _In_ __drv_freesMem(Mem) PMINIPORT_ADAPTER_CONTEXT Adapter - ) - -{ - ULONG i; - - if ( Adapter != NULL) - { - ShutdownAdapterStateObject(&Adapter->AdapterState); - - FreeDeviceServiceState(&Adapter->DeviceServiceState); - - if (Adapter->FriendlyName.Buffer != NULL) - { - FREE_POOL(Adapter->FriendlyName.Buffer); - Adapter->FriendlyName.Buffer=NULL; - } - - if (Adapter->BusHandle != NULL) - { - MbbBusCleanup(Adapter->BusHandle); - Adapter->BusHandle=NULL; - } - - if (Adapter->PowerFilterTable != NULL) - { - - for (i=0; iBusParams.PowerFiltersSupported; i++) - { - if (Adapter->PowerFilterTable[i].InUse) - { - // all the WOL patterns should have been removed by now - ASSERT(FALSE); - - FREE_POOL(Adapter->PowerFilterTable[i].Mask); - Adapter->PowerFilterTable[i].Mask=NULL; - FREE_POOL(Adapter->PowerFilterTable[i].Pattern); - Adapter->PowerFilterTable[i].Pattern=NULL; - } - } - - FREE_POOL(Adapter->PowerFilterTable); - Adapter->PowerFilterTable=NULL; - - } - - NdisFreeSpinLock(&Adapter->PortsLock); - - NdisFreeSpinLock(&Adapter->SessionIdPortTableLock); - - FREE_POOL(Adapter); - Adapter=NULL; - } - - return; -} - -PCHAR -MbbUtilGetCommandString( - __in PMBB_COMMAND Command - ) -{ - if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_BASIC_CONNECT, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_BASIC_CID_MAXIMUM ) - return CommandStringTableBasic[0]; - else - return CommandStringTableBasic[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_SMS, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_SMS_CID_MAXIMUM ) - return CommandStringTableSMS[0]; - else - return CommandStringTableSMS[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_USSD, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_USSD_CID_MAXIMUM ) - return CommandStringTableUSSD[0]; - else - return CommandStringTableUSSD[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_PHONEBOOK, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_PHONEBOOK_CID_MAXIMUM ) - return CommandStringTablePhoneBook[0]; - else - return CommandStringTablePhoneBook[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_SAT, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_SAT_CID_MAXIMUM ) - return CommandStringTableSAT[0]; - else - return CommandStringTableSAT[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_MS_VENDOR_EXTENSION, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_VENDOR_CID_MAXIMUM ) - return CommandStringTableVendor[0]; - else - return CommandStringTableVendor[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_AUTH, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_AUTH_CID_MAXIUM) - return CommandStringTableAuth[0]; - else - return CommandStringTableAuth[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_MULTICARRIER, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_MULTICARRIER_CID_MAXIMUM) - return CommandStringTableMulticarrier[0]; - else - return CommandStringTableMulticarrier[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_DSS, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_DSS_CID_MAXIUM) - return CommandStringTableDss[0]; - else - return CommandStringTableDss[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_HOSTSHUTDOWN, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_HOSTSHUTDOWN_CID_MAX) - return CommandStringTableHostShutdown[0]; - else - return CommandStringTableHostShutdown[Command->CommandId]; - } - else if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_UICC_LOW_LEVEL, sizeof(GUID) ) == sizeof(GUID) ) - { - if( Command->CommandId >= MBB_UICC_CID_MAXIMUM) - return CommandStringTableUicc[0]; - else - return CommandStringTableUicc[Command->CommandId]; - } - else if (RtlCompareMemory(&Command->ServiceId, &MBB_UUID_SARCONTROL, sizeof(GUID)) == sizeof(GUID)) - { - if (Command->CommandId >= MBB_SAR_CID_MAXIMUM) - return CommandStringTableSar[0]; - else - return CommandStringTableSar[Command->CommandId]; - } - else if (RtlCompareMemory(&Command->ServiceId, &MBB_UUID_BASIC_CONNECT_EXTENSIONS, sizeof(GUID)) == sizeof(GUID)) - { - if (Command->CommandId >= MBB_BASICCONNECTEXT_CID_MAXIMUM) - return CommandStringTableBasicExt[0]; - else - return CommandStringTableBasicExt[Command->CommandId]; - } - else - { - return "UNKNOWN"; - } -} - -BOOLEAN -MbbUtilIsBasicCommand( - __in PMBB_COMMAND Command - ) -{ - if( RtlCompareMemory( &Command->ServiceId, &MBB_UUID_BASIC_CONNECT, sizeof(GUID) ) == sizeof(GUID) ) - return TRUE; - else - return FALSE; -} - -BOOLEAN -MbbUtilIsValidDeviceService( - __in GUID* DeviceServiceGuid - ) -{ - // We could check list of supported services. However we only do one check - - if(RtlCompareMemory( &DeviceServiceGuid, &MBB_UUID_INVALID, sizeof(GUID) ) == sizeof(GUID) ) - { - return FALSE; - } - - return TRUE; -} - - -// -// ALLOCATOR -// - -__drv_allocatesMem(Mem) -__drv_aliasesMem -PVOID -MbbAllocMgrInitialize( - __in ULONG AllocationSize, - __in ULONG AllocationCount, - __in ULONG PoolTag, - __in MBB_ALLOC_FLAGS Flags - ) -{ - ULONG i; - PMBB_ALLOC_MANAGER AllocMgr; - PMBB_ALLOC_ENTRY AllocEntry; - - if( (AllocMgr = (PMBB_ALLOC_MANAGER) ALLOCATE_NONPAGED_POOL(sizeof(MBB_ALLOC_MANAGER))) == NULL ) - { - return NULL; - } - - NdisAllocateSpinLock( &AllocMgr->Lock ); - - NdisInitializeNPagedLookasideList( - &AllocMgr->LookasideList, - NULL, // allocate function - NULL, // free function - 0, // Flags - AllocationSize + sizeof(MBB_ALLOC_ENTRY), - PoolTag, - 0 // Depth - ); - - InitializeListHead( &AllocMgr->AllocatedList ); - InitializeListHead( &AllocMgr->PreAllocatedFreeList ); - - AllocMgr->Flags.Value = Flags.Value; - - for( i = 0; - i < AllocationCount; - i ++ ) - { - if( (AllocEntry = (PMBB_ALLOC_ENTRY) NdisAllocateFromNPagedLookasideList( &AllocMgr->LookasideList )) == NULL ) - { - break; - } - AllocEntry->AllocMgr = AllocMgr; - AllocEntry->IsPreAllocated = TRUE; - - InsertTailList( &AllocMgr->AllocatedList, &AllocEntry->TrackLink ); - InsertTailList( &AllocMgr->PreAllocatedFreeList, &AllocEntry->FreeLink ); - } - - if( i < AllocationCount ) - { - MbbAllocMgrCleanup( AllocMgr ); - AllocMgr = NULL; - } - - return AllocMgr; -} - -VOID -MbbAllocMgrCleanup( - __in __drv_freesMem(Mem) PVOID AllocMgrHandle - ) -/*++ - Description - The function assumes that all entries are already freed. ---*/ -{ - PLIST_ENTRY ListEntry; - PLIST_ENTRY NextEntry; - PMBB_ALLOC_MANAGER AllocMgr = (PMBB_ALLOC_MANAGER) AllocMgrHandle; - PMBB_ALLOC_ENTRY AllocEntry; - - NdisAcquireSpinLock( &AllocMgr->Lock ); - - for( ListEntry = AllocMgr->PreAllocatedFreeList.Flink; - ListEntry != &AllocMgr->PreAllocatedFreeList; - ListEntry = NextEntry ) - { - NextEntry = ListEntry->Flink; - AllocEntry = CONTAINING_RECORD( ListEntry, MBB_ALLOC_ENTRY, FreeLink ); - RemoveEntryList( &AllocEntry->FreeLink ); - RemoveEntryList( &AllocEntry->TrackLink ); - NdisFreeToNPagedLookasideList( &AllocMgr->LookasideList, AllocEntry ); - } - - ASSERT( IsListEmpty( &AllocMgr->AllocatedList ) ); - - NdisReleaseSpinLock( &AllocMgr->Lock ); - - NdisDeleteNPagedLookasideList( &AllocMgr->LookasideList ); - NdisFreeSpinLock( &AllocMgr->Lock ); - - FREE_POOL( AllocMgr ); -} - -PVOID -MbbAllocMgrAllocate( - __in PVOID AllocMgrHandle - ) -{ - PLIST_ENTRY ListEntry; - PVOID AllocHandle = NULL; - PMBB_ALLOC_MANAGER AllocMgr = (PMBB_ALLOC_MANAGER) AllocMgrHandle; - PMBB_ALLOC_ENTRY AllocEntry = NULL; - - NdisAcquireSpinLock( &AllocMgr->Lock ); - - // MbbAllocMgrFree puts the free entry to the head of the list, here we just allocate from the tail of the list - if( (ListEntry = RemoveTailList( &AllocMgr->PreAllocatedFreeList )) != &AllocMgr->PreAllocatedFreeList ) - { - AllocEntry = CONTAINING_RECORD( ListEntry, MBB_ALLOC_ENTRY, FreeLink ); - } - else if( AllocMgr->Flags.NoPostAllocation == 0 ) - { - if( (AllocEntry = (PMBB_ALLOC_ENTRY) NdisAllocateFromNPagedLookasideList( &AllocMgr->LookasideList )) != NULL ) - { - AllocEntry->AllocMgr = AllocMgr; - AllocEntry->IsPreAllocated = FALSE; - - InsertTailList( &AllocMgr->AllocatedList, &AllocEntry->TrackLink ); - } - } - - NdisReleaseSpinLock( &AllocMgr->Lock ); - - if( AllocEntry != NULL ) - AllocHandle = AllocEntry + 1; - - return AllocHandle; -} - -VOID -MbbAllocMgrFree( - __in PVOID AllocHandle - ) -{ - PLIST_ENTRY ListEntry; - PMBB_ALLOC_ENTRY AllocEntry = ((PMBB_ALLOC_ENTRY)AllocHandle) - 1; - #pragma prefast(suppress: 26001, "Accessing abstracted header.") - PMBB_ALLOC_MANAGER AllocMgr = AllocEntry->AllocMgr; - - NdisAcquireSpinLock( &AllocMgr->Lock ); - - if( AllocEntry->IsPreAllocated ) - { - InsertHeadList( &AllocMgr->PreAllocatedFreeList, &AllocEntry->FreeLink ); - } - else - { - RemoveEntryList( &AllocEntry->TrackLink ); - NdisFreeToNPagedLookasideList( &AllocMgr->LookasideList, AllocEntry ); - } - - NdisReleaseSpinLock( &AllocMgr->Lock ); -} - - -// -// BUFFER MANAGER -// - -__drv_allocatesMem(Mem) -__drv_aliasesMem -PVOID -MbbBufMgrInitialize( - __in ULONG BufferCount, - __in ULONG BufferLength - ) -{ - PMBB_BUFFER_MANAGER BufferManager; - MBB_ALLOC_FLAGS AllocFlags = { 0 }; - - if( (BufferManager = (PMBB_BUFFER_MANAGER) ALLOCATE_NONPAGED_POOL( sizeof(MBB_BUFFER_MANAGER) )) == NULL ) - { - return NULL; - } - BufferManager->BufferLength = BufferLength; - - AllocFlags.NoPostAllocation = 1; - - if( (BufferManager->AllocMgrHandle = MbbAllocMgrInitialize( - BufferLength + sizeof(MBB_BUFFER_CONTEXT), - BufferCount, - MbbPoolTagDefault, - AllocFlags - )) == NULL ) - { - TraceError( WMBCLASS_UTIL, "[BufMgr] FAILED to initialize allocation manager" ); - MbbBufMgrCleanup( BufferManager ); - BufferManager = NULL; - } - - return BufferManager; -} - -VOID -MbbBufMgrCleanup( - __in __drv_freesMem(Mem) PVOID ManagerHandle - ) -{ - PMBB_BUFFER_MANAGER BufferManager = (PMBB_BUFFER_MANAGER)ManagerHandle; - - if( BufferManager->AllocMgrHandle != NULL ) - MbbAllocMgrCleanup( BufferManager->AllocMgrHandle ); - - FREE_POOL( BufferManager ); -} - -PVOID -MbbBufMgrAllocateBuffer( - __in PVOID ManagerHandle - ) -{ - PVOID BufferHandle = NULL; - PMBB_BUFFER_MANAGER BufferManager = (PMBB_BUFFER_MANAGER)ManagerHandle; - PMBB_BUFFER_CONTEXT BufferEntry = NULL; - - if( (BufferEntry = (PMBB_BUFFER_CONTEXT) MbbAllocMgrAllocate( BufferManager->AllocMgrHandle )) != NULL ) - { - BufferEntry->BufferManager = BufferManager; - BufferHandle = BufferEntry + 1; - } - return BufferHandle; -} - -VOID -MbbBufMgrFreeBuffer( - __in PVOID BufferHandle - ) -{ - PMBB_BUFFER_CONTEXT BufferEntry = ((PMBB_BUFFER_CONTEXT)BufferHandle) - 1; - - MbbAllocMgrFree( BufferEntry ); -} - -FORCEINLINE -ULONG -MbbBufMgrGetBufferLength( - __in PVOID BufferHandle - ) -{ - PMBB_BUFFER_CONTEXT BufferEntry = ((PMBB_BUFFER_CONTEXT)BufferHandle) - 1; - - #pragma prefast(suppress: 26001, "Accessing abstracted header.") - return BufferEntry->BufferManager->BufferLength; -} - -FORCEINLINE -VOID -MbbBufMgrSetBufferContext( - __in PVOID BufferHandle, - __in PVOID Context - ) -{ - PMBB_BUFFER_CONTEXT BufferEntry = ((PMBB_BUFFER_CONTEXT)BufferHandle) - 1; - - #pragma prefast(suppress: 26001, "Accessing abstracted header.") - BufferEntry->OwnerContext = Context; -} - -FORCEINLINE -PVOID -MbbBufMgrGetBufferContext( - __in PVOID BufferHandle - ) -{ - PMBB_BUFFER_CONTEXT BufferEntry = ((PMBB_BUFFER_CONTEXT)BufferHandle) - 1; - - #pragma prefast(suppress: 26001, "Accessing abstracted header.") - return BufferEntry->OwnerContext; -} - - -// -// WORK ITEMS -// - -__drv_allocatesMem(Mem) -__drv_aliasesMem -PVOID -MbbWorkMgrInitialize( - __in ULONG InitialWorkItemCount - ) -{ - BOOLEAN Success = FALSE; - NTSTATUS NtStatus; - PMBB_WORKITEM_MANAGER WorkItemManager; - MBB_ALLOC_FLAGS AllocFlags = { 0 }; - - do - { - if( (WorkItemManager = (PMBB_WORKITEM_MANAGER) ALLOCATE_NONPAGED_POOL( sizeof(MBB_WORKITEM_MANAGER) )) == NULL ) - { - TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to allocate work item manager" ); - break; - } - - InitializeListHead( &WorkItemManager->WorkItemQueue ); - - NdisAllocateSpinLock( &WorkItemManager->Lock ); - - KeInitializeEvent( - &(WorkItemManager->WorkItemEvent), - NotificationEvent, - FALSE - ); - KeInitializeEvent( - &(WorkItemManager->ThreadExitEvent), - NotificationEvent, - FALSE - ); - WorkItemManager->ThreadHandle = NULL; - - if( (WorkItemManager->AllocMgrHandle = MbbAllocMgrInitialize( - sizeof(MBB_WORKITEM_ENTRY), - InitialWorkItemCount, - MbbPoolTagDefault, - AllocFlags - )) == NULL ) - { - TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to initialize allocation manager" ); - break; - } - - NtStatus = PsCreateSystemThread( - &(WorkItemManager->ThreadHandle), - STANDARD_RIGHTS_REQUIRED, - NULL, - NULL, - NULL, - MbbWorkMgrProcessWorkItem, - WorkItemManager - ); - if( ! NT_SUCCESS( NtStatus ) ) - { - TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to create worker thread, status=%!status!", NtStatus ); - break; - } - Success = TRUE; - } - while( FALSE ); - - if( !Success && WorkItemManager ) - { - MbbWorkMgrCleanup( WorkItemManager ); - WorkItemManager = NULL; - } - return WorkItemManager; -} - -VOID -MbbWorkMgrCleanup( - __in __drv_freesMem(Mem) PVOID WorkItemManagerHandle - ) -{ - NTSTATUS NtStatus; - PMBB_WORKITEM_MANAGER WorkItemManager = (PMBB_WORKITEM_MANAGER)WorkItemManagerHandle; - PVOID ThreadObject; - - // - // Ask the event thread to cleanup and exit. - // - NdisAcquireSpinLock( &WorkItemManager->Lock ); - KeSetEvent( &WorkItemManager->ThreadExitEvent, IO_NO_INCREMENT, FALSE ); - NdisReleaseSpinLock( &WorkItemManager->Lock ); - TraceInfo( WMBCLASS_UTIL, "[WorkMgr] Waiting for worker thread to exit" ); - // - // Wait for the worker thread to exit - // - if( WorkItemManager->ThreadHandle != NULL ) - { - NtStatus = ObReferenceObjectByHandle( - WorkItemManager->ThreadHandle, - STANDARD_RIGHTS_REQUIRED, - *PsThreadType, - KernelMode, - &ThreadObject, - NULL - ); - if( NT_SUCCESS( NtStatus ) ) - { - NtStatus = KeWaitForSingleObject( - ThreadObject, - Executive, - KernelMode, - TRUE, - NULL - ); - if( NtStatus != STATUS_WAIT_0 ) - { - TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to wait for worker thread with status=%!status!", NtStatus ); - } - ObDereferenceObject( ThreadObject ); - } - else - { - TraceError( WMBCLASS_UTIL, "[WorkMgr] FAILED to reference worker thread with status=%!status!", NtStatus ); - } - ZwClose( WorkItemManager->ThreadHandle ); - } - - ASSERT( IsListEmpty( &WorkItemManager->WorkItemQueue ) ); - - if( WorkItemManager->AllocMgrHandle != NULL ) - MbbAllocMgrCleanup( WorkItemManager->AllocMgrHandle ); - - NdisFreeSpinLock( &WorkItemManager->Lock ); - - FREE_POOL( WorkItemManager ); -} - -NDIS_STATUS -MbbWorkMgrQueueWorkItem( - __in PVOID WorkItemManagerHandle, - __in_opt PVOID Context1, - __in_opt PVOID Context2, - __in_opt PVOID Context3, - __in_opt PVOID Context4, - __in MBB_WORKITEM_ROUTINE Routine - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_RESOURCES; - PMBB_WORKITEM_ENTRY WorkItemEntry = NULL; - PMBB_WORKITEM_MANAGER WorkItemManager = (PMBB_WORKITEM_MANAGER)WorkItemManagerHandle; - - if( (WorkItemEntry = MbbAllocMgrAllocate( WorkItemManager->AllocMgrHandle )) != NULL ) - { - WorkItemEntry->Context1 = Context1; - WorkItemEntry->Context2 = Context2; - WorkItemEntry->Context3 = Context3; - WorkItemEntry->Context4 = Context4; - WorkItemEntry->Routine = Routine; - - NdisAcquireSpinLock( &WorkItemManager->Lock ); - InsertTailList( &WorkItemManager->WorkItemQueue, &WorkItemEntry->QueueLink ); - KeSetEvent( &WorkItemManager->WorkItemEvent, IO_NO_INCREMENT, FALSE ); - NdisReleaseSpinLock( &WorkItemManager->Lock ); - NdisStatus = NDIS_STATUS_SUCCESS; - } - - return NdisStatus; -} - -__drv_sameIRQL -__drv_functionClass(KSTART_ROUTINE) -KSTART_ROUTINE MbbWorkMgrProcessWorkItem; - -__drv_sameIRQL -__drv_functionClass(KSTART_ROUTINE) -VOID -MbbWorkMgrProcessWorkItem( - __in PVOID StartContext - ) -{ - NTSTATUS NtStatus; - PKEVENT EventArray[2]; - LIST_ENTRY ListHead; - PLIST_ENTRY ListEntry; - PMBB_WORKITEM_ENTRY WorkItemEntry; - PMBB_WORKITEM_MANAGER WorkItemManager = (PMBB_WORKITEM_MANAGER)StartContext; - - EventArray[0] = &(WorkItemManager->ThreadExitEvent); - EventArray[1] = &(WorkItemManager->WorkItemEvent); - - while( TRUE ) - { - NtStatus = KeWaitForMultipleObjects( - 2, - EventArray, - WaitAny, - Executive, - KernelMode, - TRUE, - NULL, - NULL - ); - if( NtStatus == STATUS_WAIT_0 ) - { - // - // Thread exit - // - break; - } - else if( NtStatus == STATUS_WAIT_1 ) - { - InitializeListHead( &ListHead ); - NdisAcquireSpinLock( &WorkItemManager->Lock ); - InsertTailList( &WorkItemManager->WorkItemQueue, &ListHead ); - RemoveEntryList( &WorkItemManager->WorkItemQueue ); - InitializeListHead( &WorkItemManager->WorkItemQueue ); - KeResetEvent( &WorkItemManager->WorkItemEvent ); - NdisReleaseSpinLock( &WorkItemManager->Lock ); - - for( ListEntry = RemoveHeadList( &ListHead ); - ListEntry != &ListHead; - ListEntry = RemoveHeadList( &ListHead ) ) - { - WorkItemEntry = CONTAINING_RECORD( ListEntry, MBB_WORKITEM_ENTRY, QueueLink ); - - WorkItemEntry->Routine( - WorkItemEntry->Context1, - WorkItemEntry->Context2, - WorkItemEntry->Context3, - WorkItemEntry->Context4 - ); - - MbbAllocMgrFree( WorkItemEntry ); - } - } - } - PsTerminateSystemThread( STATUS_SUCCESS ); -} - - -// -// CID MESSAGE FRAGMENTS -// - - -NDIS_STATUS -MbbUtilSetupCommandMessage( - __in PMBB_REQUEST_CONTEXT Request, - __in PMBB_COMMAND Command, - __in MBB_COMMAND_TYPE CommandType, - __in_bcount_opt(InputBufferLength) PUCHAR InputBuffer, - __in ULONG InputBufferLength - ) -{ - ULONG FragmentCount; - ULONG FragmentDataLength; - ULONG FragmentLength; - NTSTATUS NtStatus; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - do - { - // - // OS supported commands are sent over the control pipe. - // - FragmentLength = Request->RequestManager->Fragmentation.ControlFragmentLength; - FragmentDataLength = FragmentLength; - - // - // Query the amount of fragment buffers required for the command message. - // - FragmentCount = 0; - - if( (NtStatus = MbbLibFragmentBufferToCommandMessages( - Command, - CommandType, - InputBuffer, - InputBufferLength, - &Request->TransactionId, - 0, // StartingFragment - &FragmentCount, - &FragmentDataLength, - NULL // FragmentBuffers - )) != STATUS_SUCCESS ) - { - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - Request->HandlerContext.Command.Data = InputBuffer; - Request->HandlerContext.Command.DataLength = InputBufferLength; - Request->HandlerContext.Command.Command = *Command; - Request->HandlerContext.Command.CommandType = CommandType; - Request->HandlerContext.Command.FragmentCount = FragmentCount; - Request->HandlerContext.Command.FragmentLength = FragmentLength; - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilSendMessageFragmentsAndLog( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - PCHAR CommandName = MbbUtilGetCommandString(&(Request->HandlerContext.Command.Command)); - NTSTATUS Status = STATUS_SUCCESS; - LPGUID ActivityId = NULL; - MBB_MESSAGE_TYPE MessageType = MBB_MESSAGE_TYPE_COMMAND; - ULONG MessageLength = Request->HandlerContext.Command.DataLength + sizeof(MBB_COMMAND_HEADER); - DWORD TotalFragments = 1; - DWORD CurrentFragment = 0; - - // Create an activity Id to be associated with this message - // This activity Id will be associated with the USB IRP for sending - // this message so that we can associate USB traces with our traces. - // Also note that there is one activity Id for sending all the fragments - // of a message. - - Status = MbbEventActivityIdCtl(&(Request->ActivityId)); - - if(NT_SUCCESS(Status)) - { - ActivityId = &(Request->ActivityId); - } - - // Etw Trace send - MbbWriteEvent( - &CID_COMMAND_SEND, - ActivityId, - NULL, - 7, - &(Request->OidContext.OidRequestId), - sizeof(Request->OidContext.OidRequestId), - &(Request->RequestId), - sizeof(ULONG), - &(Request->HandlerContext.Command.Command.ServiceId), - sizeof(GUID), - CommandName, - strlen(CommandName) + 1, - &(Request->HandlerContext.Command.Command.CommandId), - sizeof(ULONG), - &(Request->HandlerContext.Command.DataLength), - sizeof(ULONG), - Request->HandlerContext.Command.Data, - Request->HandlerContext.Command.DataLength - ); - - // Etw Trace for MBB OPN. Log an event that renders the entire MBIM message - MbbWriteEventOpn( - &COMMAND_MSG, - ActivityId, - NULL, - 10, - &MessageType, - sizeof(MessageType), - &MessageLength, - sizeof(MessageLength), - &(Request->TransactionId), - sizeof(Request->TransactionId), - &TotalFragments, - sizeof(TotalFragments), - &CurrentFragment, - sizeof(CurrentFragment), - &(Request->HandlerContext.Command.Command.ServiceId), - sizeof(Request->HandlerContext.Command.Command.ServiceId), - &(Request->HandlerContext.Command.Command.CommandId), - sizeof(Request->HandlerContext.Command.Command.CommandId), - &(Request->HandlerContext.Command.CommandType), - sizeof(Request->HandlerContext.Command.CommandType), - &(Request->HandlerContext.Command.DataLength), - sizeof(Request->HandlerContext.Command.DataLength), - Request->HandlerContext.Command.Data, - Request->HandlerContext.Command.DataLength - ); - - return MbbUtilSendMessageFragments( Request ); -} - - -NDIS_STATUS -MbbUtilSendMessageFragments( - __in PMBB_REQUEST_CONTEXT Request - ) -/*++ - Synchronization: - Fields updated by the SendCompletion routine - and the Send routine are protected by the - RequestManager lock e.g. NextFrameIndex. - - Some fields are static and need no protection - e.g. FragmentCount. - - At any time only one instance of the Send - routine is processing fragments since the - routines are synchronized by the RequestManager lock. - - Return Value: - NDIS_STATUS_SUCCESS - Successfully sent all fragments, SendComplete event is queued to the request. - NDIS_STATUS_FAILURE - Failed to send all fragments, SendComplete event is queued to the request. - NDIS_STATUS_PENDING - SendComplete event will be queued later. ---*/ -{ - ULONG FragmentIndex; - ULONG FragmentLength; - ULONG FragmentCount; - ULONG FragmentSentCount; - ULONG FragmentBufferCount; - PVOID BufferManagerHandle; - PCHAR FragmentBuffer; - NTSTATUS NtStatus; - NDIS_STATUS NdisStatus; - PMBB_REQUEST_MANAGER RequestManager; - - // - // Cache values for easy access. - // - RequestManager = Request->RequestManager; - BufferManagerHandle = RequestManager->Fragmentation.BufferManager; - FragmentCount = Request->HandlerContext.Command.FragmentCount; - // - // Synchronize with other instances of the same routine - // invoked from completion handlers. - // - MbbReqMgrLockManager( RequestManager ); - if( Request->HandlerContext.Command.IsProcessing == TRUE ) - { - MbbReqMgrUnlockManager( RequestManager ); - return NDIS_STATUS_PENDING; - } - Request->HandlerContext.Command.IsProcessing = TRUE; - // - // If some fragments failed to be sent then no point - // sending more. Fail the request right away. - // - FragmentSentCount = 0; - NdisStatus = Request->HandlerContext.Command.SendStatus; - - for( FragmentIndex = Request->HandlerContext.Command.NextFragmentIndex; - FragmentIndex < FragmentCount && NdisStatus == NDIS_STATUS_SUCCESS; - FragmentIndex ++ ) - { - // - // Allocate fragment buffer. If there are no buffers then wait - // for the SendCompletion routine to return the buffers. - // - if( (FragmentBuffer= MbbBufMgrAllocateBuffer( BufferManagerHandle )) == NULL ) - { - // - // If the first fragment couldnt be sent then fail the send. - // This should never happen, this is an indication of a buffer leak. - // - if( FragmentIndex == 0 ) - { - ASSERT( FragmentBuffer != NULL ); - NdisStatus = NDIS_STATUS_RESOURCES; - } - break; - } - // - // Format fragments one at a time. - // - FragmentLength = Request->HandlerContext.Command.FragmentLength; - FragmentBufferCount = 1; - - ASSERT( FragmentLength <= MbbBufMgrGetBufferLength( FragmentBuffer ) ); - - NtStatus = MbbLibFragmentBufferToCommandMessages( - &Request->HandlerContext.Command.Command, - Request->HandlerContext.Command.CommandType, - Request->HandlerContext.Command.Data, - Request->HandlerContext.Command.DataLength, - &Request->TransactionId, - FragmentIndex, - &FragmentBufferCount, - &FragmentLength, - &FragmentBuffer - ); - if( NtStatus != STATUS_SUCCESS && - NtStatus != STATUS_MORE_PROCESSING_REQUIRED ) - { - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - // - // Ensure library formatted the data correctly - // - ASSERT( FragmentBufferCount == 1 ); - ASSERT( FragmentLength <= Request->HandlerContext.Command.FragmentLength ); - // - // Save context required by the completion handler. - // - MbbBufMgrSetBufferContext( FragmentBuffer, Request ); - // - // Call the wrapper that will sent the fragment over the control or bulk pipe. - // Drop the lock before calling in to the bus layer. - // - MbbReqMgrUnlockManager( RequestManager ); - - NtStatus = MbbUtilBusSendMessageFragment( - Request, - (MBB_REQUEST_HANDLE)FragmentBuffer, - FragmentBuffer, - FragmentLength - ); - if( NtStatus != STATUS_PENDING ) - { - MbbBufMgrFreeBuffer( FragmentBuffer ); - } - - if( NtStatus == STATUS_SUCCESS ) - { - TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x][TID=0x%08x] Sent Fragment %02d/%02d", - Request->RequestId, Request->TransactionId, FragmentIndex, FragmentCount - ); - FragmentSentCount++; - } - else if( NtStatus != STATUS_PENDING ) - { - TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x][TID=0x%08x] FAILED to send Fragment %02d/%02d status=%!status!", - Request->RequestId, Request->TransactionId, FragmentIndex, FragmentCount, NtStatus - ); - NdisStatus = NDIS_STATUS_FAILURE; - } - else - { - TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x][TID=0x%08x] Pending send Fragment %02d/%02d", - Request->RequestId, Request->TransactionId, FragmentIndex, FragmentCount - ); - } - // - // Reacquire lock for evaluating the queue - // - MbbReqMgrLockManager( RequestManager ); - } // for - - // - // On failure, update the status field. - // Dont send any more fragments, fake remaining fragments are sent. - // - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - Request->HandlerContext.Command.SendStatus = NdisStatus; - FragmentSentCount += FragmentCount - FragmentIndex; - } - // - // Update the Request fields - // Protected by RequestManager lock. - // - Request->HandlerContext.Command.NextFragmentIndex = FragmentIndex; - Request->HandlerContext.Command.FragmentSentCount += FragmentSentCount; - Request->HandlerContext.Command.IsProcessing = FALSE; - // - // If any fragments were completed synchronously then check if - // the request can move to SendComplete - // - if( FragmentSentCount > 0 ) - FragmentSentCount = Request->HandlerContext.Command.FragmentSentCount; - MbbReqMgrUnlockManager( RequestManager ); - // - // Queue SendComplete event if no fragments are pending - // - if( FragmentSentCount == FragmentCount ) - { - PCHAR CommandName = MbbUtilGetCommandString(&(Request->HandlerContext.Command.Command)); - - // Etw Trace send complete - MbbWriteEvent( - &CID_SEND_COMPLETE, - &(Request->ActivityId), - NULL, - 8, - &(Request->OidContext.OidRequestId), - sizeof(Request->OidContext.OidRequestId), - &(Request->RequestId), - sizeof(ULONG), - &(Request->HandlerContext.Command.Command.ServiceId), - sizeof(GUID), - CommandName, - strlen(CommandName) + 1, - &(Request->HandlerContext.Command.Command.CommandId), - sizeof(ULONG), - &(Request->HandlerContext.Command.DataLength), - sizeof(ULONG), - Request->HandlerContext.Command.Data, - Request->HandlerContext.Command.DataLength, - &NdisStatus, - sizeof(NDIS_STATUS) - ); - - MbbReqMgrQueueEvent( - Request->RequestManager, - Request, - MbbRequestEventSendComplete, - (PVOID)(NdisStatus), - 0 - ); - } - else - { - NdisStatus = NDIS_STATUS_PENDING; - } - - return NdisStatus; -} - -NTSTATUS -MbbUtilBusSendMessageFragment( - __in PMBB_REQUEST_CONTEXT Request, - __in MBB_REQUEST_HANDLE FragmentBuffer, - __in PVOID MessageFragment, - __in ULONG FragmentLength - ) -{ - PMDL Mdl; - NTSTATUS NtStatus; - MBB_BUS_HANDLE BusHandle = MbbNdisGetBusHandle( MbbReqMgrGetAdapterHandle( Request ) ); - - // - // OS supported commands are sent over the control pipe. - // Vendor device service commands are send also sent over the control pipe - // - NtStatus = MbbBusSendMessageFragment( - BusHandle, - FragmentBuffer, - MessageFragment, - FragmentLength, - !IsZeroGuid(&(Request->ActivityId)) ? &(Request->ActivityId) : NULL, - MbbUtilSendMessageFragmentComplete - ); - - return NtStatus; -} - -VOID -MbbUtilSendMessageFragmentComplete( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in MBB_REQUEST_HANDLE FragmentBuffer, - __in NTSTATUS NtStatus - ) -{ - ULONG FragmentCount; - ULONG FragmentSentCount; - NDIS_STATUS NdisStatus; - PMBB_REQUEST_CONTEXT Request; - PMBB_REQUEST_MANAGER RequestManager; - - if( NtStatus == STATUS_SUCCESS ) - NdisStatus = NDIS_STATUS_SUCCESS; - else - NdisStatus = NDIS_STATUS_FAILURE; - - Request = (PMBB_REQUEST_CONTEXT) MbbBufMgrGetBufferContext( FragmentBuffer ); - RequestManager = Request->RequestManager; - FragmentCount = Request->HandlerContext.Command.FragmentCount; - // - // Update fields that need synchronization. - // Note the buffer should be returned with RequestManager lock held. - // - MbbReqMgrLockManager( RequestManager ); - MbbBufMgrFreeBuffer( FragmentBuffer ); - FragmentSentCount = ++Request->HandlerContext.Command.FragmentSentCount; - if( NdisStatus != NDIS_STATUS_SUCCESS ) - Request->HandlerContext.Command.SendStatus = NdisStatus; - MbbReqMgrUnlockManager( RequestManager ); - - TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x][TID=0x%08x] %02d/%02d fragment completed with status=%!status!", - Request->RequestId, Request->TransactionId, FragmentSentCount, FragmentCount, NdisStatus - ); - // - // If all fragments have completed sending then complete the request. - // If not, then try to send more fragments. - // - if( FragmentSentCount == FragmentCount ) - { - PCHAR CommandName = MbbUtilGetCommandString(&(Request->HandlerContext.Command.Command)); - - // Etw Trace send complete - MbbWriteEvent( - &CID_SEND_COMPLETE, - &(Request->ActivityId), - NULL, - 8, - &(Request->OidContext.OidRequestId), - sizeof(Request->OidContext.OidRequestId), - &(Request->RequestId), - sizeof(ULONG), - &(Request->HandlerContext.Command.Command.ServiceId), - sizeof(GUID), - CommandName, - strlen(CommandName) + 1, - &(Request->HandlerContext.Command.Command.CommandId), - sizeof(ULONG), - &(Request->HandlerContext.Command.DataLength), - sizeof(ULONG), - Request->HandlerContext.Command.Data, - Request->HandlerContext.Command.DataLength, - &NdisStatus, - sizeof(NDIS_STATUS) - ); - - MbbReqMgrQueueEvent( - Request->RequestManager, - Request, - MbbRequestEventSendComplete, - (PVOID)(NdisStatus), - 0 - ); - - if (NtStatus == STATUS_IO_TIMEOUT && Request->OidHandler != NULL) - { - PMBB_SEND_QUEUE SendQueue = &((PMINIPORT_ADAPTER_CONTEXT)MbbReqMgrGetAdapterHandle(Request))->SendQueue; - switch (Request->OidHandler->Oid) - { - case OID_WWAN_CONNECT: - TraceLoggingWrite( - g_hLoggingProvider, - "ConnectSendTimeout", - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); - TryQueueStallState(SendQueue); - break; - // Remove OID_WWAN_PIN_EX since there is an observed case that the OID_WWAN_PIN_EX failed but data path is still working - // case OID_WWAN_PIN_EX: __fallthrough; - //case OID_WWAN_RADIO_STATE: - // TraceLoggingWrite( - // g_hLoggingProvider, - // "RadioStateSendTimeout", - // TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); - // TryQueueStallState(SendQueue); - // break; - } - } - } - else - { - // - // All fragments might be already send but some may be inflight. - // If all fragments are sent then below call will be a no-op. - // - MbbUtilSendMessageFragments( Request ); - } -} - -VOID -MbbUtilSendMbimErrorComplete( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in MBB_REQUEST_HANDLE SendBuffer, - __in NTSTATUS NtStatus - ) -{ - PMBB_ERROR_MESSAGE ErrorMessage = (PMBB_ERROR_MESSAGE)SendBuffer; - - if( ! NT_SUCCESS( NtStatus ) ) - { - TraceError( WMBCLASS_UTIL, "[Util][MBIM_ERR][TID=0x%08x] FAILED to send error message to device, Error=%!MbbError!", - ErrorMessage->MessageHeader.MessageTransactionId, - ErrorMessage->ErrorCode - ); - } - FREE_POOL( ErrorMessage ); -} - -VOID -MbbUtilSendMbimError( - __in ULONG TransactionId, - __in MBB_ERROR ErrorCode, - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in GUID ActivityId, - __in PMBB_COMMAND Command - ) -/*++ -Description - Helper routine to send a MBB error message to the MBIM device. - This also logs an ETW event in the event log. ---*/ -{ - NTSTATUS NtStatus; - PCHAR CommandName; - PMBB_ERROR_MESSAGE ErrorMessage; - -#pragma prefast(suppress: __WARNING_MEMORY_LEAK, "Released by MbbUtilSendMbimErrorComplete") - if( (ErrorMessage = (PMBB_ERROR_MESSAGE) ALLOCATE_NONPAGED_POOL( sizeof(MBB_ERROR_MESSAGE) )) == NULL ) - { - TraceError( WMBCLASS_UTIL, "[MBIM_ERR][TID=0x%08x] FAILED to allocate error message for, Error=%!MbbError!", - TransactionId, - ErrorCode - ); - return; - } - - ErrorMessage->MessageHeader.MessageType = MBB_MESSAGE_TYPE_HOST_ERROR; - ErrorMessage->MessageHeader.MessageLength = sizeof(*ErrorMessage); - ErrorMessage->MessageHeader.MessageTransactionId= TransactionId; - ErrorMessage->ErrorCode = ErrorCode; - - TraceError( WMBCLASS_UTIL, "[MBIM_ERR][TID=0x%08x] Sending MBIM error message for %!MbbError! to device", - TransactionId, - ErrorCode - ); - - NtStatus = MbbBusSendMessageFragment( - MbbNdisGetBusHandle( Adapter ), - ErrorMessage, - ErrorMessage, - sizeof(*ErrorMessage), - !IsZeroGuid(&ActivityId) ? &ActivityId : NULL, - MbbUtilSendMbimErrorComplete - ); - if( ! NT_SUCCESS( NtStatus ) ) - { - TraceError( WMBCLASS_UTIL, "[MBIM_ERR][TID=0x%08x] FAILED to send error message to bus layer, Error=%!MbbError!", - TransactionId, - ErrorCode - ); - } - - if( NtStatus != STATUS_PENDING ) - { - MbbUtilSendMbimErrorComplete( - NULL, - ErrorMessage, - NtStatus - ); - } - - CommandName = MbbUtilGetCommandString( Command ); - - MbbWriteEvent( - &MBIM_HOST_ERROR_EVENT, - NULL, - NULL, - 6, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &ErrorCode, - sizeof(MBB_ERROR), - &TransactionId, - sizeof(ULONG), - &Command->ServiceId, - sizeof(Command->ServiceId), - &Command->CommandId, - sizeof(Command->CommandId), - CommandName, - strlen(CommandName) + 1 - ); -} - - -// -// CID QUERY \ SET WRAPPER -// - - -NDIS_STATUS -MbbUtilInternalCIDQuery( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -/*++ - Description - This is the internal serialized routine that calls CID handlers. - Only one instance of this routine will run at any time. - This is different than MbbNdisProcessSerializeOidRequest( ) - in that it is not related to OIDs. Internal request submissions - that do not have a OID use this wrapper routine as their dispatch routine. - - Parameters - __in PMBB_REQUEST_CONTEXT Request - The request to process. This is the internal request representation. ---*/ -{ - TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x] Internal query dispatch for CID %s", - Request->RequestId, - MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ) - ); - - return Request->OidHandler->QueryHandler( - Request, - NULL, - NULL, - NULL, - NULL - ); -} - -VOID -MbbUtilInternalCIDCompletion( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ) -/*++ - Description: - This routine is used by internal CID requestors. This is the default - handler for SendCompletion that handles common cleanup work. ---*/ -{ - if( Request->OidHandler->CompletionHandler != NULL ) - { - Request->OidHandler->CompletionHandler( - Request, - NdisStatus - ); - } - - TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x] Internal SendComplete cleanup for CID %s. Status=%!status! DataToFree=0x%p", - Request->RequestId, - MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), - NdisStatus, - Request->HandlerContext.DataToFreeOnCompletion - ); - - if( Request->HandlerContext.DataToFreeOnCompletion != NULL ) - FREE_POOL( Request->HandlerContext.DataToFreeOnCompletion ); - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - if( Request->HandlerContext.DataToFreeOnResponse != NULL ) - FREE_POOL( Request->HandlerContext.DataToFreeOnResponse ); - - KeSetEvent( - &Request->WaitEvent, - IO_NO_INCREMENT, - FALSE - ); - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } -} - -VOID -MbbUtilCommonCIDResponse( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize, - __in_opt PMBB_OID_HANDLER_ENTRY OidHandler - ) -{ - NDIS_STATUS HandlerStatus = NDIS_STATUS_SUCCESS; - PCHAR ResponseType = (MbbReqMgrIsUnsolicitedIndication( Request )) ? "Unsolicited":"Solicited"; - PCHAR CommandName = NULL; - GUID ServiceId = MBB_UUID_INVALID_CONSTANT; - ULONG CommandId = 0; - MBB_MESSAGE_TYPE MessageType; - ULONG MessageLength; - DWORD TotalFragments = 1; - DWORD CurrentFragment = 0; - - if( OidHandler != NULL && - OidHandler->ResponseHandler != NULL ) - { - HandlerStatus = OidHandler->ResponseHandler( - Request, - NdisStatus, - MbbStatus, - InBuffer, - InBufferSize - ); - // - // Let the handler overwrite the status - // - NdisStatus = HandlerStatus; - - CommandName = MbbUtilGetCommandString(&OidHandler->ResponseCommand); - ServiceId = OidHandler->ResponseCommand.ServiceId; - CommandId = OidHandler->ResponseCommand.CommandId; - } - - // Etw trace response received - MbbWriteEvent( - &CID_RESPONSE_RECVD, - &(Request->ActivityId), - NULL, - 10, - ResponseType, - strlen(ResponseType) + 1, - &(Request->OidContext.OidRequestId), - sizeof(Request->OidContext.OidRequestId), - &(Request->RequestId), - sizeof(ULONG), - &ServiceId, - sizeof(GUID), - CommandName, - (CommandName == NULL) ? 0 : (strlen(CommandName) + 1), - &CommandId, - sizeof(ULONG), - &MbbStatus, - sizeof(MBB_STATUS), - &NdisStatus, - sizeof(NDIS_STATUS), - &InBufferSize, - sizeof(ULONG), - InBuffer, - InBufferSize - ); - - // Etw Trace for MBB OPN. Log an event that renders the entire MBIM message - if( MbbReqMgrIsUnsolicitedIndication( Request ) ) - { - MessageType = MBB_MESSAGE_TYPE_INDICATE_STATUS; - MessageLength = InBufferSize + sizeof(MBB_INDICATE_STATUS_HEADER); - MbbWriteEventOpn( - &INDICATE_STATUS_MSG, - &(Request->ActivityId), - NULL, - 9, - &MessageType, - sizeof(MessageType), - &MessageLength, - sizeof(MessageLength), - &(Request->TransactionId), - sizeof(Request->TransactionId), - &TotalFragments, - sizeof(TotalFragments), - &CurrentFragment, - sizeof(CurrentFragment), - &(ServiceId), - sizeof(ServiceId), - &(CommandId), - sizeof(CommandId), - &InBufferSize, - sizeof(InBufferSize), - InBuffer, - InBufferSize - ); - } - else - { - MessageType = MBB_MESSAGE_TYPE_COMMAND_DONE; - MessageLength = InBufferSize + sizeof(MBB_COMMAND_DONE_HEADER); - MbbWriteEventOpn( - &COMMAND_DONE_MSG, - &(Request->ActivityId), - NULL, - 10, - &MessageType, - sizeof(MessageType), - &MessageLength, - sizeof(MessageLength), - &(Request->TransactionId), - sizeof(Request->TransactionId), - &TotalFragments, - sizeof(TotalFragments), - &CurrentFragment, - sizeof(CurrentFragment), - &(ServiceId), - sizeof(ServiceId), - &(CommandId), - sizeof(CommandId), - &MbbStatus, - sizeof(MbbStatus), - &InBufferSize, - sizeof(InBufferSize), - InBuffer, - InBufferSize - ); - } - - // - // If the handler wants to keep the request around for MoreData - // then do not cleanup the request yet. - // - if( HandlerStatus == NDIS_STATUS_PENDING ) - { - TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x] Not cleaning CID %s", - Request->RequestId, - MbbUtilGetCommandString( &Request->HandlerContext.Response.Command ) - ); - } - else - { - TraceInfo( WMBCLASS_OID, "[Util][ReqId=0x%04x] ResponseReceived cleanup for CID %s. Status=%!status! DataToFree=0x%p", - Request->RequestId, - MbbUtilGetCommandString( &Request->HandlerContext.Response.Command ), - NdisStatus, - Request->HandlerContext.DataToFreeOnResponse - ); - Request->HandlerContext.Response.NdisStatus = NdisStatus; - - if( Request->HandlerContext.DataToFreeOnResponse != NULL ) - FREE_POOL( Request->HandlerContext.DataToFreeOnResponse ); - - KeSetEvent( - &Request->WaitEvent, - IO_NO_INCREMENT, - FALSE - ); - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } -} - -VOID -MbbUtilInternalCIDResponse( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ) -/*++ - Description: - This routine is used by internal CID requestors. This is the deafult - handler for ResposenReceivethat handles common cleanup work. - - Internal routine requires that there is an OID handler Which means - that status indidcations are not supported on the internal path. ---*/ -{ - MbbUtilCommonCIDResponse( - Request, - NdisStatus, - MbbStatus, - InBuffer, - InBufferSize, - Request->OidHandler - ); -} - -NDIS_STATUS -MbbUtilQueryAttribute( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ) -{ - return MbbUtilQueryAttributeWithParameter( - Request, - NULL, - 0 - ); -} - -NDIS_STATUS -MbbUtilQueryAttributeWithParameter( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(GetRequestParametersSize) PUCHAR GetRequestParameters, - __in ULONG GetRequestParametersSize - ) -{ - NDIS_STATUS NdisStatus; - - do - { - // - // Call the wrapper routine to allocate - // and format the message buffers. - // - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Request->OidHandler->ResponseCommand, - MBB_COMMAND_TYPE_QUERY, - GetRequestParameters, - GetRequestParametersSize - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x] FAILED to setup command message for %s with status=%!status!", - Request->RequestId, MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x] FAILED to send message fragments for %s with status=%!status!", - Request->RequestId, MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), NdisStatus ); - } - - } while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilSetAttributeWithParameter( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(SetParametersSize) PUCHAR SetParameters, - __in ULONG SetParametersSize - ) -{ - NDIS_STATUS NdisStatus; - - do - { - // - // Call the wrapper routine to allocate - // and format the message buffers. - // - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &Request->OidHandler->ResponseCommand, - MBB_COMMAND_TYPE_SET, - SetParameters, - SetParametersSize - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x] FAILED to setup command message for %s with status=%!status!", - Request->RequestId, MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), NdisStatus ); - break; - } - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_OID, "[Util][ReqId=0x%04x] FAILED to send message fragments for %s with status=%!status!", - Request->RequestId, MbbUtilGetCommandString( &(Request->OidHandler->ResponseCommand) ), NdisStatus ); - } - - } while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilDeviceServiceCommand( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - NDIS_STATUS NdisStatus; - MBB_COMMAND MbbCommand; - PNDIS_WWAN_DEVICE_SERVICE_COMMAND NdisDeviceServiceCommand; - - do - { - if( *InBufferSize < sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INSUFFICIENT InputBufferSize=%d Bytes for DEVICE_SERVICE_COMMAND, Expected=%d Bytes", - Request->RequestId, *InBufferSize, sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND) ); - - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - *InBufferSize = sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND); - break; - } - - NdisDeviceServiceCommand = (PNDIS_WWAN_DEVICE_SERVICE_COMMAND) InBuffer; - - - if( NdisDeviceServiceCommand->Header.Type != NDIS_OBJECT_TYPE_DEFAULT || - NdisDeviceServiceCommand->Header.Size < SIZEOF_NDIS_WWAN_DEVICE_SERVICE_COMMAND_1 || - NdisDeviceServiceCommand->Header.Revision < NDIS_WWAN_DEVICE_SERVICE_COMMAND_REVISION_1 ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INVALID ndis header for DEVICE_SERVICE_COMMAND, Type=0x%x Size=%d Revision=%d", - Request->RequestId, - NdisDeviceServiceCommand->Header.Type, - NdisDeviceServiceCommand->Header.Size, - NdisDeviceServiceCommand->Header.Revision - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - if (NdisDeviceServiceCommand->Command.uDataSize + RTL_SIZEOF_THROUGH_FIELD(NDIS_WWAN_DEVICE_SERVICE_COMMAND,Command.uDataSize) > *InBufferSize ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] INSUFFICIENT InputBufferSize=%d Bytes for DEVICE_SERVICE_COMMAND, Expected=%d Bytes", - Request->RequestId, *InBufferSize, sizeof(NDIS_WWAN_DEVICE_SERVICE_COMMAND) ); - - *InBufferSize = NdisDeviceServiceCommand->Command.uDataSize + RTL_SIZEOF_THROUGH_FIELD(NDIS_WWAN_DEVICE_SERVICE_COMMAND,Command.uDataSize); - - NdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - - RtlCopyMemory( - &MbbCommand.ServiceId, - &NdisDeviceServiceCommand->Command.DeviceServiceGuid, - sizeof(GUID) - ); - - MbbCommand.CommandId = NdisDeviceServiceCommand->Command.CommandID; - // - // Call the wrapper routine to allocate - // and format the message buffers. - // - if( (NdisStatus = MbbUtilSetupCommandMessage( - Request, - &MbbCommand, - MbbReqMgrIsSetOid( Request )? MBB_COMMAND_TYPE_SET: MBB_COMMAND_TYPE_QUERY, - (PUCHAR)(NdisDeviceServiceCommand + 1), - NdisDeviceServiceCommand->Command.uDataSize - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to setup command message for DEVICE_SERVICE_COMMAND with status=%!status!", - Request->RequestId, NdisStatus ); - break; - } - *InBufferSize += NdisDeviceServiceCommand->Command.uDataSize; - // - // Call the wrapper routine to send each fragment. - // The wrapper will cleanup fragments in case of - // success or failure. - // - NdisStatus = MbbUtilSendMessageFragmentsAndLog( Request ); - if( NdisStatus != NDIS_STATUS_SUCCESS && - NdisStatus != NDIS_STATUS_PENDING ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][Ven][ReqId=0x%04x] FAILED to send message fragments for DEVICE_SERVICE_COMMAND with status=%!status!", - Request->RequestId, NdisStatus ); - } - - } while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilUiccAccessBinary( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PNDIS_WWAN_UICC_ACCESS_BINARY NdisUiccAccessBinary = (PNDIS_WWAN_UICC_ACCESS_BINARY)InBuffer; - PMBB_UICC_ACCESS_BINARY MbbUiccAccessBinary = NULL; - NDIS_STATUS NdisStatus; - ULONG BufferSize = 0; - - NdisStatus = MbbUtilWwanToMbbUiccAccessBinary( - &NdisUiccAccessBinary->UiccAccessBinary, - &MbbUiccAccessBinary, - &BufferSize - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbUiccAccessBinary; - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR) MbbUiccAccessBinary, - BufferSize - ); -} - -NDIS_STATUS -MbbUtilUiccAccessRecord( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ) -{ - PNDIS_WWAN_UICC_ACCESS_RECORD NdisUiccAccessRecord = (PNDIS_WWAN_UICC_ACCESS_RECORD)InBuffer; - PMBB_UICC_ACCESS_RECORD MbbUiccAccessRecord = NULL; - NDIS_STATUS NdisStatus; - ULONG BufferSize = 0; - - NdisStatus = MbbUtilWwanToMbbUiccAccessRecord( - &NdisUiccAccessRecord->UiccAccessRecord, - &MbbUiccAccessRecord, - &BufferSize - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - return NdisStatus; - } - - Request->HandlerContext.DataToFreeOnCompletion = MbbUiccAccessRecord; - - return MbbUtilQueryAttributeWithParameter( - Request, - (PUCHAR) MbbUiccAccessRecord, - BufferSize - ); -} - -// -// Wwan to Mbb -// - - -VOID -MbbUtilWwanToMbbRadioState( - __in WWAN_RADIO* WwanRadio, - __out MBB_RADIO_STATE* MbbRadioState - ) -{ - *MbbRadioState = (MBB_RADIO_STATE)*WwanRadio; -} - -NTSTATUS -MbbUtilWwanToMbbPinAction( - __in PWWAN_PIN_ACTION WwanPinAction, - __out PMBB_PIN_ACTION * MbbPinActionOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_PIN_ACTION MbbPinAction=NULL; - NTSTATUS Status; - SIZE_T PinLength; - SIZE_T NewPinLength; - - *ReturnedBufferSize=0; - - BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_PIN_ACTION,DataBuffer), ALIGN_DWORD); - - CurrentOffset=BufferSize; - - Status=RtlStringCbLengthW(WwanPinAction->Pin, sizeof(WwanPinAction->Pin), &PinLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status=RtlStringCbLengthW(WwanPinAction->NewPin, sizeof(WwanPinAction->NewPin), &NewPinLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - BufferSize+=(ULONG)ROUND_UP_COUNT(PinLength, ALIGN_DWORD); - BufferSize+=(ULONG)ROUND_UP_COUNT(NewPinLength, ALIGN_DWORD); - - if( (MbbPinAction = ALLOCATE_NONPAGED_POOL( BufferSize )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer=(PUCHAR)MbbPinAction; - - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - &MbbPinAction->Pin, - (PUCHAR)WwanPinAction->Pin, - (ULONG)PinLength - ); - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - &MbbPinAction->NewPin, - (PUCHAR)WwanPinAction->NewPin, - (ULONG)NewPinLength - ); - - - MbbPinAction->PinType = (MBB_PIN_TYPE)WwanPinAction->PinType; - MbbPinAction->PinOperation = (MBB_PIN_OPERATION)WwanPinAction->PinOperation; - - - *MbbPinActionOut=MbbPinAction; - - *ReturnedBufferSize=BufferSize; - - return STATUS_SUCCESS; -} - -NTSTATUS -MbbUtilWwanToMbbPinActionEx2( - __in PWWAN_PIN_ACTION_EX2 WwanPinAction, - __out PMBB_PIN_ACTION_EX2 *MbbPinActionOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_PIN_ACTION_EX2 MbbPinAction=NULL; - NTSTATUS Status; - SIZE_T PinLength; - SIZE_T NewPinLength; - - *ReturnedBufferSize=0; - - BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_PIN_ACTION_EX2,DataBuffer), ALIGN_DWORD); - - CurrentOffset=BufferSize; - - Status=RtlStringCbLengthW(WwanPinAction->Pin, sizeof(WwanPinAction->Pin), &PinLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status=RtlStringCbLengthW(WwanPinAction->NewPin, sizeof(WwanPinAction->NewPin), &NewPinLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - BufferSize+=(ULONG)ROUND_UP_COUNT(PinLength, ALIGN_DWORD); - BufferSize+=(ULONG)ROUND_UP_COUNT(NewPinLength, ALIGN_DWORD); - BufferSize+=(ULONG)ROUND_UP_COUNT(WwanPinAction->AppIdLength, ALIGN_DWORD); - - if( (MbbPinAction = ALLOCATE_NONPAGED_POOL( BufferSize )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer=(PUCHAR)MbbPinAction; - - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - &MbbPinAction->Pin, - (PUCHAR)WwanPinAction->Pin, - (ULONG)PinLength - ); - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - &MbbPinAction->NewPin, - (PUCHAR)WwanPinAction->NewPin, - (ULONG)NewPinLength - ); - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbPinAction->AppId, - (PUCHAR)WwanPinAction->AppId, - (ULONG)WwanPinAction->AppIdLength - ); - - MbbPinAction->PinType = (MBB_PIN_TYPE)WwanPinAction->PinType; - MbbPinAction->PinOperation = (MBB_PIN_OPERATION)WwanPinAction->PinOperation; - - *MbbPinActionOut=MbbPinAction; - - *ReturnedBufferSize=BufferSize; - - return STATUS_SUCCESS; -} - -ULONG -MbbUtilWwanToMbbProvider( - __in PWWAN_PROVIDER WwanProvider, - __in MBB_CELLULAR_CLASS MbbCellularClass, - __in ULONG Rssi, - __in ULONG ErrorRate, - __in ULONG MbbProviderSize, - __out_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider - ) -{ - ULONG MbbProviderOffset; - SIZE_T StringCbLength; - NDIS_STATUS NdisStatus; - - do - { - if( sizeof(MBB_PROVIDER) > MbbProviderSize ) - { - TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER, Size=%d Expected=%d", - MbbProviderSize, - sizeof(MBB_PROVIDER) - ); - MbbProviderOffset = 0; - break; - } - MbbProvider->ProviderState = (ULONG)WwanProvider->ProviderState; - MbbProvider->Rssi = Rssi; - MbbProvider->ErrorRate = ErrorRate; - MbbProvider->CellularClass = MbbCellularClass; - - MBB_INIT_MBB_STRING( &MbbProvider->ProviderId ); - MBB_INIT_MBB_STRING( &MbbProvider->ProviderName ); - - MbbProviderOffset = sizeof(MBB_PROVIDER); - - if( (NdisStatus = RtlStringCbLengthW( - WwanProvider->ProviderId, - sizeof(WwanProvider->ProviderId), - &StringCbLength - )) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util] FAILED to get string length for WWAN_PROVIDER.ProviderId, NdisStatus=%!STATUS!", - NdisStatus - ); - MbbProviderOffset = 0; - break; - } - - if( MbbProviderOffset + StringCbLength > MbbProviderSize ) - { - TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER.ProviderId, Size=%d Expected=%d", - MbbProviderSize, - (ULONG)(MbbProviderOffset + StringCbLength) - ); - MbbProviderOffset = 0; - break; - } - - MbbProviderOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbProvider, - MbbProviderSize, - MbbProviderOffset, - &MbbProvider->ProviderId, - (PCUCHAR)(WwanProvider->ProviderId), - (ULONG)StringCbLength - ); - - if( (NdisStatus = RtlStringCbLengthW( - WwanProvider->ProviderName, - sizeof(WwanProvider->ProviderName), - &StringCbLength - )) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util] FAILED to get string length for WWAN_PROVIDER.ProviderName, NdisStatus=%!STATUS!", NdisStatus ); - MbbProviderOffset = 0; - break; - } - - if( MbbProviderOffset + StringCbLength > MbbProviderSize ) - { - TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER.ProviderName, Size=%d Expected=%d", - MbbProviderSize, - (ULONG)(MbbProviderOffset + StringCbLength) - ); - MbbProviderOffset = 0; - break; - } - - MbbProviderOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbProvider, - MbbProviderSize, - MbbProviderOffset, - &MbbProvider->ProviderName, - (PCUCHAR)(WwanProvider->ProviderName), - (ULONG)StringCbLength - ); - } - while( FALSE ); - - return MbbProviderOffset; -} - -ULONG -MbbUtilWwanToMbbProvider2( - __in PWWAN_PROVIDER2 WwanProvider2, - __in ULONG MbbProviderSize, - __out_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider - ) -{ - // - // There is no MBB mapping for WwanCellularClassWiMAX. - // Assume that the service will behave correctly and not send bad data. - // - return MbbUtilWwanToMbbProvider( - &WwanProvider2->Provider, - (MBB_CELLULAR_CLASS)(WwanProvider2->WwanCellularClass), - WwanProvider2->Rssi, - WwanProvider2->ErrorRate, - MbbProviderSize, - MbbProvider - ); -} - -NDIS_STATUS -MbbUtilWwanToMbbProviderList( - __in PWWAN_LIST_HEADER WwanProviderList, - __in BOOLEAN IsMultiCarrierCapable, - __in_opt MBB_CELLULAR_CLASS MbbCellularClass, - __out_bcount(*MbbProviderListSize) PMBB_PROVIDER_LIST MbbProviderList, - __inout PULONG MbbProviderListSize - ) -{ - ULONG ElementIndex; - ULONG ElementCount = WwanProviderList->ElementCount; - ULONG MbbProviderSize; - ULONG MbbProviderListOffset; - NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE; - PMBB_PROVIDER MbbProvider; - PWWAN_PROVIDER2 WwanProviders2 = (PWWAN_PROVIDER2)(WwanProviderList + 1); - PMBB_ARRAY_ELEMENT MbbProviderElement = (PMBB_ARRAY_ELEMENT)(MbbProviderList->Providers); - - MbbProviderListOffset = FIELD_OFFSET(MBB_PROVIDER_LIST, Providers); - MbbProviderListOffset += ElementCount * sizeof(MBB_ARRAY_ELEMENT); - - if( MbbProviderListOffset > *MbbProviderListSize ) - { - TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER_LIST, BufferSize=%d Expected=%d", - *MbbProviderListSize, - MbbProviderListOffset - ); - return NDIS_STATUS_BUFFER_OVERFLOW; - } - - for( ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex ++ ) - { - MbbProviderListOffset = ROUND_UP_COUNT( MbbProviderListOffset, ALIGN_DWORD ); - MbbProviderElement[ElementIndex].Offset = MbbProviderListOffset; - MbbProvider = (PMBB_PROVIDER)(((PCHAR)MbbProviderList)+MbbProviderListOffset); - - if( MbbProviderListOffset > *MbbProviderListSize ) - { - TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT buffer to convert WWAN_PROVIDER_LIST.Provider[%02d], BufferSize=%d Expected=%d", - *MbbProviderListSize, - MbbProviderListOffset, - ElementIndex - ); - NdisStatus = NDIS_STATUS_BUFFER_OVERFLOW; - break; - } - - if( (MbbProviderSize = MbbUtilWwanToMbbProvider2( - &WwanProviders2[ElementIndex], - *MbbProviderListSize - MbbProviderListOffset, - MbbProvider - )) == 0 ) - { - TraceError( WMBCLASS_OID, "[Util] FAILED to convert %02d# WWAN_PROVIDER2 to MBB_PROVIDER", ElementIndex ); - break; - } - - MbbProviderElement[ElementIndex].Size = MbbProviderSize; - MbbProviderListOffset += MbbProviderSize; - } - if( ElementIndex == ElementCount ) - { - MbbProviderList->ProviderCount = ElementCount; - NdisStatus = NDIS_STATUS_SUCCESS; - *MbbProviderListSize = MbbProviderListOffset; - } - return NdisStatus; -} - -NTSTATUS -MbbUtilWwanToMbbSetRegisterState( - __in PWWAN_SET_REGISTER_STATE WwanSetRegisterState, - __out PMBB_SET_REGISTER_STATE *MbbSetRegisterStateOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_SET_REGISTER_STATE MbbSetRegisterState=NULL; - NTSTATUS Status; - SIZE_T ProviderIdLength; - - *ReturnedBufferSize=0; - - BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_REGISTER_STATE,DataBuffer), ALIGN_DWORD); - - CurrentOffset=BufferSize; - - Status=RtlStringCbLengthW(WwanSetRegisterState->ProviderId, sizeof(WwanSetRegisterState->ProviderId), &ProviderIdLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - - BufferSize+=(ULONG)ROUND_UP_COUNT(ProviderIdLength, ALIGN_DWORD); - - if( (MbbSetRegisterState = ALLOCATE_NONPAGED_POOL( BufferSize )) == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer=(PUCHAR)MbbSetRegisterState; - - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - &MbbSetRegisterState->ProviderId, - (PUCHAR)WwanSetRegisterState->ProviderId, - (ULONG)ProviderIdLength - ); - - MbbSetRegisterState->DataClass = (MBB_DATA_CLASS_VALUE)WwanSetRegisterState->WwanDataClass; - MbbSetRegisterState->RegisterAction = (MBB_REGISTER_ACTION)WwanSetRegisterState->RegisterAction; - - - *MbbSetRegisterStateOut=MbbSetRegisterState; - - *ReturnedBufferSize=BufferSize; - - return STATUS_SUCCESS; - -} - -NDIS_STATUS -MbbUtilWwanToMbbSetPacketService( - __in WWAN_PACKET_SERVICE_ACTION PacketServiceAction, - __out PMBB_SET_PACKET_SERVICE MbbSetPacketService - ) -{ - switch( PacketServiceAction ) - { - case WwanPacketServiceActionAttach: - MbbSetPacketService->PacketServiceAction = MbbPacketServiceActionAttach; - return NDIS_STATUS_SUCCESS; - case WwanPacketServiceActionDetach: - MbbSetPacketService->PacketServiceAction = MbbPacketServiceActionDetach; - return NDIS_STATUS_SUCCESS; - default : - return NDIS_STATUS_INVALID_DATA; - } -} - -VOID -MbbUtilAdjustSignalStateConfigurationForDevice( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __inout PWWAN_SET_SIGNAL_INDICATION WwanSetSignalIndication - ) -/*++ -Description - The signal state interval and threshold values need to be adjusted - for Blue for efficient power management. This is done only for - devices that support MBIM 1.0 Errata and the configuration is adjusted - to (60, 1). The signal state configuration - for non-errata devices will continue to be the Win 8 WWAN values (30, -1). - The values are adjusted only if they were set to WWAN_RSSI_DEFAULT (-1). ---*/ -{ - // - // Check if device supports Errata - // - if ( Adapter->BusParams.IsErrataDevice ) - { - // - // Use new Blue values - // - if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiInterval ) - { - WwanSetSignalIndication->RssiInterval = WWAN_RSSI_INTERVAL_SECS_BLUE; - } - - if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiThreshold ) - { - WwanSetSignalIndication->RssiThreshold = WWAN_RSSI_THRESHOLD_CODED_UNIT_BLUE; - } - } - else - { - // - // Continue to use Win 8 values - // - if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiInterval ) - { - WwanSetSignalIndication->RssiInterval = WWAN_RSSI_INTERVAL_SECS_WIN8; - } - - if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiThreshold ) - { - WwanSetSignalIndication->RssiThreshold = WWAN_RSSI_THRESHOLD_CODED_UNIT_WIN8; - } - } -} - -VOID -MbbUtilWwanToMbbSetSignalStateIndication( - __in PWWAN_SET_SIGNAL_INDICATION WwanSetSignalIndication, - __out PMBB_SET_SIGNAL_INDICATION MbbSetSignalStateIndication - ) -/*++ -Description - MBB and WWAN default and disable values are inverted so - appropriate checks and translation is required. ---*/ -{ - if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiInterval ) - MbbSetSignalStateIndication->RssiInterval = MBB_RSSI_DEFAULT; - else if( WWAN_RSSI_DISABLE == WwanSetSignalIndication->RssiInterval ) - MbbSetSignalStateIndication->RssiInterval = MBB_RSSI_DISABLE; - else - MbbSetSignalStateIndication->RssiInterval = WwanSetSignalIndication->RssiInterval; - - if( WWAN_RSSI_DEFAULT == WwanSetSignalIndication->RssiThreshold ) - MbbSetSignalStateIndication->RssiThreshold = MBB_RSSI_DEFAULT; - else if( WWAN_RSSI_DISABLE == WwanSetSignalIndication->RssiThreshold ) - MbbSetSignalStateIndication->RssiThreshold = MBB_RSSI_DISABLE; - else - MbbSetSignalStateIndication->RssiThreshold = WwanSetSignalIndication->RssiThreshold; - - MbbSetSignalStateIndication->ErrorRateThreshold = MBB_RSSI_DISABLE; -} - -VOID -MbbUtilWwanToMbbContextType( - __in WWAN_CONTEXT_TYPE WwanContextType, - __out PGUID MbbContextType - ) -{ - GUID SrcGuid; - - switch( WwanContextType ) - { - case WwanContextTypeInternet: - SrcGuid = MBB_UUID_CONTEXT_TYPE_INTERNET; - break; - - case WwanContextTypeVpn: - SrcGuid = MBB_UUID_CONTEXT_TYPE_VPN; - break; - - case WwanContextTypeVoice: - SrcGuid = MBB_UUID_CONTEXT_TYPE_VOICE; - break; - - case WwanContextTypeVideoShare: - SrcGuid = MBB_UUID_CONTEXT_TYPE_VIDEO_SHARE; - break; - - case WwanContextTypePurchase: - SrcGuid = MBB_UUID_CONTEXT_TYPE_PURCHASE; - break; - - case WwanContextTypeCustom: - SrcGuid = MBB_UUID_CONTEXT_TYPE_CUSTOM; - break; - - case WwanContextTypeIms: - SrcGuid = MBB_UUID_CONTEXT_TYPE_IMS; - break; - - case WwanContextTypeAdmin: - SrcGuid = MBB_UUID_CONTEXT_TYPE_MS_ADMIN; - break; - - case WwanContextTypeApp: - SrcGuid = MBB_UUID_CONTEXT_TYPE_MS_APP; - break; - - case WwanContextTypeLteAttach: - SrcGuid = MBB_UUID_BASIC_CONNECT_EXTENSIONS; - break; - - case WwanContextTypeNone: - default: - SrcGuid = MBB_UUID_CONTEXT_TYPE_NONE; - - break; - } - MBB_UUID_TO_NET( MbbContextType, &SrcGuid ); -} - -VOID -MbbUtilWwanToMbbSetContextState( - __in PWWAN_SET_CONTEXT_STATE WwanSetContextState, - __in ULONG AccessStringCchLength, - __in ULONG UserNameCchLength, - __in ULONG PasswordCchLength, - __in ULONG MbbSetContextStateSize, - __in ULONG SessionId, - __out PMBB_SET_CONTEXT_STATE MbbSetContextState - ) -{ - ULONG CurrentOffset; - - MbbSetContextState->SessionId = SessionId; - MbbSetContextState->ActivationCommand = (MBB_ACTIVATION_COMMAND)WwanSetContextState->ActivationCommand; - MbbSetContextState->Compression = (MBB_COMPRESSION)WwanSetContextState->Compression; - MbbSetContextState->AuthProtocol = (MBB_AUTH_PROTOCOL)WwanSetContextState->AuthType; - MbbSetContextState->IPType = (MBB_CONTEXT_IP_TYPE)WwanSetContextState->IPType; - if (MbbSetContextState->IPType > MbbContextIPTypeIPv4v6) - { - TraceWarn(WMBCLASS_UTIL, "Invalid IPType from the OS. Resetting it to MbbContextIPTypeDefault"); - MbbSetContextState->IPType = MbbContextIPTypeDefault; - } - - MbbUtilWwanToMbbContextType( - WwanContextTypeInternet, - &MbbSetContextState->ContextType - ); - - CurrentOffset = FIELD_OFFSET( MBB_SET_CONTEXT_STATE, DataBuffer ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContextState, - MbbSetContextStateSize, - CurrentOffset, - &MbbSetContextState->AccessString, - (PCUCHAR)(WwanSetContextState->AccessString), - AccessStringCchLength * sizeof(WCHAR) - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContextState, - MbbSetContextStateSize, - CurrentOffset, - &MbbSetContextState->UserName, - (PCUCHAR)(WwanSetContextState->UserName), - UserNameCchLength * sizeof(WCHAR) - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContextState, - MbbSetContextStateSize, - CurrentOffset, - &MbbSetContextState->Password, - (PCUCHAR)(WwanSetContextState->Password), - PasswordCchLength * sizeof(WCHAR) - ); -} - -VOID -MbbUtilMbbToWwanLteAttachConfigInfo( - __in MBB_MS_LTE_ATTACH_CONFIG_INFO* MbbLteAttachContextList, - __out PWWAN_LTE_ATTACH_CONFIG WwanLteAttachContext - ) -{ - PMBB_MS_LTE_ATTACH_CONTEXT MbbLteAttachContext; - - for( ULONG ContextIndex = 0; - ContextIndex < MbbLteAttachContextList->ElementCount; - ContextIndex ++ ) - { - MbbLteAttachContext = (PMBB_MS_LTE_ATTACH_CONTEXT)((PUCHAR)MbbLteAttachContextList + MbbLteAttachContextList->Contexts[ContextIndex].Offset); - - MbbUtilMbbToWwanLteAttachContext( - MbbLteAttachContext, - &(WwanLteAttachContext->LteContextArray[ContextIndex]) - ); - } -} - -NTSTATUS -MbbUtilWwanToMbbSetLteAttachContext( - __in PWWAN_SET_LTE_ATTACH WwanSetContextBuffer, - __out PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG *ReturnedMbbSetContext, - __out ULONG *ReturnedBufferSize - ) -{ - NTSTATUS Status = STATUS_SUCCESS; - - PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG MbbSetContext = NULL; - ULONG SetBufferSize = 0; - ULONG SetBufferOffset = 0; - - PMBB_MS_LTE_ATTACH_CONTEXT MbbLteAttachContext = NULL; - ULONG BufferSize[TotalRoamingConditions] = {0}; - ULONG MbbLteAttachOffset = 0; - SIZE_T AccessStringLength[TotalRoamingConditions] = {0}; - SIZE_T UserNameLength[TotalRoamingConditions] = {0}; - SIZE_T PasswordLength[TotalRoamingConditions] = {0}; - - PWWAN_SET_CONTEXT_V2 WwanSetLteAttachContext = NULL; - *ReturnedBufferSize=0; - *ReturnedMbbSetContext=NULL; - - SetBufferSize = ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG, Contexts), ALIGN_DWORD); - SetBufferSize += ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * TotalRoamingConditions, ALIGN_DWORD); - - SetBufferOffset = SetBufferSize; - - for (ULONG i = 0; i < TotalRoamingConditions; i ++) - { - WwanSetLteAttachContext = &(WwanSetContextBuffer->SetContextArray[i]); - - BufferSize[i] = ROUND_UP_COUNT(FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer), ALIGN_DWORD); - - Status=RtlStringCbLengthW(WwanSetLteAttachContext->basicInfo.AccessString, sizeof(WwanSetLteAttachContext->basicInfo.AccessString), &(AccessStringLength[i])); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status=RtlStringCbLengthW(WwanSetLteAttachContext->basicInfo.UserName, sizeof(WwanSetLteAttachContext->basicInfo.UserName), &(UserNameLength[i])); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status=RtlStringCbLengthW(WwanSetLteAttachContext->basicInfo.Password, sizeof(WwanSetLteAttachContext->basicInfo.Password), &(PasswordLength[i])); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - BufferSize[i] += (ULONG)ROUND_UP_COUNT(AccessStringLength[i], ALIGN_DWORD); - BufferSize[i] += (ULONG)ROUND_UP_COUNT(UserNameLength[i], ALIGN_DWORD); - BufferSize[i] += (ULONG)ROUND_UP_COUNT(PasswordLength[i], ALIGN_DWORD); - - SetBufferSize += BufferSize[i]; - } - - MbbSetContext = ALLOCATE_NONPAGED_POOL( SetBufferSize ); - - if ( MbbSetContext == NULL ) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlZeroMemory(MbbSetContext, SetBufferSize); - - MbbSetContext->Operation = WwanLteAttachOperationsMapTable[WwanSetContextBuffer->SetContextArray[0].Operation]; - MbbSetContext->ElementCount = TotalRoamingConditions; - - for (ULONG i = 0; i < TotalRoamingConditions; i ++) - { - MbbSetContext->Contexts[i].Offset = SetBufferOffset; - MbbSetContext->Contexts[i].Size = BufferSize[i]; - - MbbLteAttachOffset = FIELD_OFFSET(MBB_MS_LTE_ATTACH_CONTEXT, DataBuffer); - MbbLteAttachContext = (PMBB_MS_LTE_ATTACH_CONTEXT)((PBYTE)MbbSetContext + SetBufferOffset); - WwanSetLteAttachContext = &(WwanSetContextBuffer->SetContextArray[i]); - - if (WwanSetLteAttachContext->IPType >= WwanIPTypeDefault && - WwanSetLteAttachContext->IPType <= WwanIPTypeIpv4v6) - { - MbbLteAttachContext->IPType = WwanIpTypesMapTable[WwanSetLteAttachContext->IPType]; - } - else - { - MbbLteAttachContext->IPType = MbbContextIPTypeMaximum; - } - - MbbLteAttachContext->Roaming = (MBB_BASICCONNECTEXT_LTEATTACH_ROAMING_CONTROL)WwanSetLteAttachContext->Roaming; - - if (WwanSetLteAttachContext->Source >= WwanUserProvisioned && - WwanSetLteAttachContext->Source < WwanMaxProvisionSource) - { - MbbLteAttachContext->Source = WwanSourcsMapTable[WwanSetLteAttachContext->Source]; - } - else - { - MbbLteAttachContext->Source = MbbMsContextSourceMaximum; - } - - MbbLteAttachOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbLteAttachContext, - BufferSize[i], - MbbLteAttachOffset, - &MbbLteAttachContext->AccessString, - (PCUCHAR)(WwanSetLteAttachContext->basicInfo.AccessString), - (ULONG)AccessStringLength[i] - ); - - MbbLteAttachOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbLteAttachContext, - BufferSize[i], - MbbLteAttachOffset, - &MbbLteAttachContext->UserName, - (PCUCHAR)(WwanSetLteAttachContext->basicInfo.UserName), - (ULONG)UserNameLength[i] - ); - - MbbLteAttachOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbLteAttachContext, - BufferSize[i], - MbbLteAttachOffset, - &MbbLteAttachContext->Password, - (PCUCHAR)(WwanSetLteAttachContext->basicInfo.Password), - (ULONG)PasswordLength[i] - ); - - MbbLteAttachContext->Compression = (MBB_COMPRESSION)WwanSetLteAttachContext->basicInfo.Compression; - MbbLteAttachContext->AuthProtocol = (MBB_AUTH_PROTOCOL)WwanSetLteAttachContext->basicInfo.AuthType; - - SetBufferOffset += BufferSize[i]; - } - - *ReturnedBufferSize=SetBufferSize; - *ReturnedMbbSetContext=MbbSetContext; - - return STATUS_SUCCESS; -} - - -NTSTATUS -MbbUtilWwanToMbbSetContext( - __in PWWAN_SET_CONTEXT WwanSetContext, - __out PMBB_SET_CONTEXT *ReturnedMbbSetContext, - __out ULONG *ReturnedBufferSize - ) -{ - - - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_SET_CONTEXT MbbSetContext=NULL; - NTSTATUS Status; - SIZE_T AccessStringLength; - SIZE_T UserNameLength; - SIZE_T PasswordLength; - SIZE_T ProviderIdLength; - - *ReturnedBufferSize=0; - *ReturnedMbbSetContext=NULL; - - BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_CONTEXT,DataBuffer), ALIGN_DWORD); - - Status=RtlStringCbLengthW(WwanSetContext->AccessString, sizeof(WwanSetContext->AccessString), &AccessStringLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status=RtlStringCbLengthW(WwanSetContext->UserName, sizeof(WwanSetContext->UserName), &UserNameLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status=RtlStringCbLengthW(WwanSetContext->Password, sizeof(WwanSetContext->Password), &PasswordLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status=RtlStringCbLengthW(WwanSetContext->ProviderId, sizeof(WwanSetContext->ProviderId), &ProviderIdLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - - - BufferSize+=(ULONG)ROUND_UP_COUNT(AccessStringLength, ALIGN_DWORD); - BufferSize+=(ULONG)ROUND_UP_COUNT(UserNameLength, ALIGN_DWORD); - BufferSize+=(ULONG)ROUND_UP_COUNT(PasswordLength, ALIGN_DWORD); - BufferSize+=(ULONG)ROUND_UP_COUNT(ProviderIdLength, ALIGN_DWORD); - - MbbSetContext = ALLOCATE_NONPAGED_POOL( BufferSize ); - - if ( MbbSetContext == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - CurrentOffset = FIELD_OFFSET( MBB_SET_CONTEXT_STATE, DataBuffer ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContext, - BufferSize, - CurrentOffset, - &MbbSetContext->AccessString, - (PCUCHAR)(WwanSetContext->AccessString), - (ULONG)AccessStringLength - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContext, - BufferSize, - CurrentOffset, - &MbbSetContext->UserName, - (PCUCHAR)(WwanSetContext->UserName), - (ULONG)UserNameLength - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContext, - BufferSize, - CurrentOffset, - &MbbSetContext->Password, - (PCUCHAR)(WwanSetContext->Password), - (ULONG)PasswordLength - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContext, - BufferSize, - CurrentOffset, - &MbbSetContext->ProviderId, - (PCUCHAR)(WwanSetContext->ProviderId), - (ULONG)ProviderIdLength - ); - - - MbbSetContext->ContextId = WwanSetContext->ContextId; - MbbSetContext->Compression = (MBB_COMPRESSION)WwanSetContext->Compression; - MbbSetContext->AuthProtocol = (MBB_AUTH_PROTOCOL)WwanSetContext->AuthType; - - MbbUtilWwanToMbbContextType( - WwanSetContext->ContextType, - &MbbSetContext->ContextType - ); - - *ReturnedBufferSize=BufferSize; - *ReturnedMbbSetContext=MbbSetContext; - - return STATUS_SUCCESS; - -} - -NTSTATUS -MbbUtilWwanToMbbSetContextV2( - __in PWWAN_SET_PROVISIONED_CONTEXT_V2 WwanSetContext, - __out PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 *ReturnedMbbSetContext, - __out ULONG *ReturnedBufferSize -) -{ - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 MbbSetContext = NULL; - NTSTATUS Status; - SIZE_T AccessStringLength; - SIZE_T UserNameLength; - SIZE_T PasswordLength; - SIZE_T ProviderIdLength; - - *ReturnedBufferSize = 0; - *ReturnedMbbSetContext = NULL; - - BufferSize = ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2, DataBuffer), ALIGN_DWORD); - - Status = RtlStringCbLengthW(WwanSetContext->basicInfo.AccessString, sizeof(WwanSetContext->basicInfo.AccessString), &AccessStringLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status = RtlStringCbLengthW(WwanSetContext->basicInfo.UserName, sizeof(WwanSetContext->basicInfo.UserName), &UserNameLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status = RtlStringCbLengthW(WwanSetContext->basicInfo.Password, sizeof(WwanSetContext->basicInfo.Password), &PasswordLength); - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - BufferSize += (ULONG)ROUND_UP_COUNT(AccessStringLength, ALIGN_DWORD); - BufferSize += (ULONG)ROUND_UP_COUNT(UserNameLength, ALIGN_DWORD); - BufferSize += (ULONG)ROUND_UP_COUNT(PasswordLength, ALIGN_DWORD); - - MbbSetContext = ALLOCATE_NONPAGED_POOL(BufferSize); - - if (MbbSetContext == NULL) - { - return NDIS_STATUS_RESOURCES; - } - - CurrentOffset = FIELD_OFFSET(MBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2, DataBuffer); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContext, - BufferSize, - CurrentOffset, - &MbbSetContext->AccessString, - (PCUCHAR)(WwanSetContext->basicInfo.AccessString), - (ULONG)AccessStringLength - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContext, - BufferSize, - CurrentOffset, - &MbbSetContext->UserName, - (PCUCHAR)(WwanSetContext->basicInfo.UserName), - (ULONG)UserNameLength - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetContext, - BufferSize, - CurrentOffset, - &MbbSetContext->Password, - (PCUCHAR)(WwanSetContext->basicInfo.Password), - (ULONG)PasswordLength - ); - - - MbbSetContext->Compression = (MBB_COMPRESSION)WwanSetContext->basicInfo.Compression; - MbbSetContext->AuthProtocol = (MBB_AUTH_PROTOCOL)WwanSetContext->basicInfo.AuthType; - - MbbUtilWwanToMbbContextType( - WwanSetContext->basicInfo.ContextType, - &MbbSetContext->ContextType - ); - - MbbSetContext->Operation = (MBB_BASICCONNECTEXT_CONTEXT_OPERATIONS)WwanSetContext->Operation; - MbbSetContext->IPType = WwanIpTypesMapTable[WwanSetContext->IPType]; - MbbSetContext->Enable = (MBB_BASICCONNECTEXT_CONTEXT_ENABLE)WwanSetContext->Enable; - MbbSetContext->Roaming = (MBB_BASICCONNECTEXT_CONTEXT_ROAMING_CONTROL)WwanSetContext->Roaming; - MbbSetContext->MediaType = (MBB_BASICCONNECTEXT_CONTEXT_MEDIA_TYPE)WwanSetContext->MediaType; - MbbSetContext->Source = WwanSourcsMapTable[WwanSetContext->Source]; - - *ReturnedBufferSize = BufferSize; - *ReturnedMbbSetContext = MbbSetContext; - - return STATUS_SUCCESS; -} - -// SMS - -MBB_SMS_FORMAT -MbbUtilWwanToMbbSmsFormat( - __in WWAN_SMS_FORMAT WwanSmsFormat - ) -{ - switch( WwanSmsFormat ) - { - case WwanSmsFormatPdu: - return MbbSmsFormatPdu; - case WwanSmsFormatCdma: - return MbbSmsFormatCdma; - default: - return MbbSmsFormatMaximum; - } -} - -NTSTATUS -MbbUtilWwanToMbbSmsSetConfiguration( - __in PWWAN_SET_SMS_CONFIGURATION WwanSmsSetConfiguration, - __in ULONG ScAddressSize, - __out PMBB_SET_SMS_CONFIGURATION *MbbSmsSetConfigurationReturn, - __out PULONG ReturnedBufferSize - ) -{ - NTSTATUS NtStatus; - ANSI_STRING AnsiString; - UNICODE_STRING UnicodeString; - WCHAR WideCharBuffer[WWAN_SMS_ADDRESS_MAX_LEN]; - PMBB_SET_SMS_CONFIGURATION MbbSmsSetConfiguration=NULL; - PBYTE Buffer=NULL; - ULONG BufferSize=0; - ULONG CurrentOffset=0; - - *MbbSmsSetConfigurationReturn=NULL; - *ReturnedBufferSize=0; - - - AnsiString.Buffer = WwanSmsSetConfiguration->ScAddress; - AnsiString.Length = (USHORT)ScAddressSize; - AnsiString.MaximumLength = WWAN_SMS_ADDRESS_MAX_LEN - 1; // No NULL - - UnicodeString.Buffer = &WideCharBuffer[0]; - UnicodeString.Length = 0; - UnicodeString.MaximumLength = sizeof(WideCharBuffer); - - - NtStatus = RtlAnsiStringToUnicodeString( - &UnicodeString, - &AnsiString, - FALSE // AllocateDestinationString - ); - - if ( NtStatus != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_UTIL, "[MbbNdis] FAILED to convert ScAddress Length=%dbytes, NtStatus=%!STATUS!", - AnsiString.Length, NtStatus - ); - ASSERT(0); - return NtStatus; - } - - BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_SMS_CONFIGURATION,DataBuffer), ALIGN_DWORD); - - CurrentOffset=BufferSize; - - - BufferSize+=(ULONG)ROUND_UP_COUNT(ScAddressSize * sizeof(WCHAR), ALIGN_DWORD); - - MbbSmsSetConfiguration = ALLOCATE_NONPAGED_POOL( BufferSize ); - - if (MbbSmsSetConfiguration == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer=(PUCHAR)MbbSmsSetConfiguration; - - MbbSmsSetConfiguration->SmsFormat = MbbUtilWwanToMbbSmsFormat( WwanSmsSetConfiguration->SmsFormat ); - - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - &MbbSmsSetConfiguration->ScAddress, - (PUCHAR)&WideCharBuffer[0], - (ULONG)ScAddressSize * sizeof(WCHAR) - ); - - *MbbSmsSetConfigurationReturn=MbbSmsSetConfiguration; - *ReturnedBufferSize=BufferSize; - - return STATUS_SUCCESS; - -} - -VOID -MbbUtilWwanToMbbSmsRead( - __in PWWAN_SMS_READ WwanSmsRead, - __out PMBB_SMS_READ MbbSmsRead - ) -{ - MbbSmsRead->SmsFormat = MbbUtilWwanToMbbSmsFormat( WwanSmsRead->SmsFormat ); - MbbSmsRead->SmsFlag = (MBB_SMS_FLAG)WwanSmsRead->ReadFilter.Flag; - MbbSmsRead->MessageIndex = WwanSmsRead->ReadFilter.MessageIndex; -} - -NDIS_STATUS -MbbUtilHexStringToUchar( - __in_ecount(2) PCHAR HexString, - __out PUCHAR Value - ) -/*++ - Description - On success Value is populated with the value of the hex string. - On failure, Value is undefined. ---*/ -{ - ULONG NibbleIndex; - UCHAR Nibbles[2]; - UCHAR NibbleAscii; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - for( NibbleIndex = 0; NibbleIndex < 2; NibbleIndex++ ) - { - NibbleAscii = HexString[NibbleIndex]; - - if( NibbleAscii >= 'a' && NibbleAscii <= 'f' ) - { - Nibbles[NibbleIndex] = 10 + NibbleAscii - 'a'; - } - else if( NibbleAscii >= 'A' && NibbleAscii <= 'F' ) - { - Nibbles[NibbleIndex] = 10 + NibbleAscii - 'A'; - } - else if( NibbleAscii >= '0' && NibbleAscii <= '9' ) - { - Nibbles[NibbleIndex] = NibbleAscii - '0'; - } - else - { - NdisStatus = NDIS_STATUS_FAILURE; - break; - } - } - - if( NdisStatus == NDIS_STATUS_SUCCESS ) - *Value = (Nibbles[0] * 16) + Nibbles[1]; - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilHexStringToByteStream( - __in_bcount_z(HexStringSize) PCHAR HexString, - __in ULONG HexStringSize, - __out_bcount(ByteStreamSize) PUCHAR ByteStream, - __in ULONG ByteStreamSize - ) -{ - ULONG i; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - for( i = 0; - i < ByteStreamSize && - ((i * 2) + 1) < HexStringSize; - i ++ ) - { - if( (NdisStatus = MbbUtilHexStringToUchar( - &HexString[i*2], - &ByteStream[i] - )) != NDIS_STATUS_SUCCESS ) - { - break; - } - } - return NdisStatus; -} - -VOID -MbbUtilByteStreamToHexString( - __in_bcount(ByteStreamSize) PUCHAR ByteStream, - __in ULONG ByteStreamSize, - __out_bcount_z(HexStringSize) PCHAR HexString, - __in ULONG HexStringSize - ) -{ - ULONG i; - UCHAR UpperNibble; - UCHAR LowerNibble; - CHAR AsciiTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - - for( i = 0; - i < ByteStreamSize && - ((i * 2) + 1) < HexStringSize; - i ++ ) - { - UpperNibble = ( ByteStream[i] >> 4 ) & 0x0F; - LowerNibble = ByteStream[i] & 0x0F; - - HexString[i*2] = AsciiTable[UpperNibble]; - HexString[(i*2)+1] = AsciiTable[LowerNibble]; - } - HexString[MIN( (i*2), (HexStringSize-1) )] = 0; -} - -NDIS_STATUS -MbbUtilWwanToMbbSmsSendPdu( - __in PWWAN_SMS_SEND_PDU WwanSmsSendPdu, - __in MBB_CELLULAR_CLASS CellularClass, - __out PMBB_SMS_SEND *ReturnedMbbSmsSend, - __out PULONG MbbSmsSendSize - ) -{ - UCHAR SmscAddressLength = 0; - SIZE_T PduDataCbLength; - ULONG PduDataLength; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PMBB_SMS_SEND_PDU MbbSmsSendPdu=NULL; - ULONG CurrentOffset=0; - ULONG BufferSize = 0; - PUCHAR Buffer = NULL; - - ULONG OuterBufferSize = 0; - PUCHAR OuterBuffer = NULL; - ULONG InitialOffset=0; - - do - { - // - // add some space at the beginning, for the contain struct - // - InitialOffset = FIELD_OFFSET( MBB_SMS_SEND, u.Pdu ); - - if( CellularClass == MbbCellularClassGsm ) - { - // - // the first two bytes are the hex encoded length of smsc address. - // - NdisStatus=MbbUtilHexStringToUchar( - WwanSmsSendPdu->PduData, - &SmscAddressLength - ); - - - if( NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID hexstring for SMSC Address Length=%1c%1c", - WwanSmsSendPdu->PduData[0], - WwanSmsSendPdu->PduData[1] - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - // - // The encoded size is for the raw data. - // Add one byte for the SmscAddressLength itself. - // - SmscAddressLength++; - PduDataLength = WwanSmsSendPdu->Size; - - // - // Validate the buffer given by the service - // - if( (NdisStatus = RtlStringCbLengthA( - WwanSmsSendPdu->PduData, - sizeof(WwanSmsSendPdu->PduData), - &PduDataCbLength - )) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] FAILED to get string length for WwanSmsSendPdu->PduData, NtStatus=%!STATUS!", NdisStatus ); - break; - } - - // - // PduDataCbLength is the length of the null terminated string of hex digits from the service. - // PduDataLength is the declarded length of the PDU data from service not including the smsc address - // - if( ((PduDataCbLength/2) - SmscAddressLength) != PduDataLength ) - { - TraceError( WMBCLASS_UTIL, "[Util][Sms] INVALID WwanSmsSendPdu->Size=%d != PduDataStringLength=%d - SmscAddressLength=%d", - PduDataLength, - (ULONG)(PduDataCbLength/2), - SmscAddressLength - ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - - - BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SMS_SEND_PDU, DataBuffer), ALIGN_DWORD); - - CurrentOffset=BufferSize; - - BufferSize+=(ULONG)ROUND_UP_COUNT(PduDataLength + SmscAddressLength, ALIGN_DWORD); - - // - // Outer buffer has storage for the containing structure as well - // - OuterBufferSize = InitialOffset + BufferSize; - - OuterBuffer = ALLOCATE_NONPAGED_POOL(OuterBufferSize); - - if (OuterBuffer == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer=OuterBuffer + InitialOffset; - - MbbSmsSendPdu=(PMBB_SMS_SEND_PDU)Buffer; - - - // - // PduSize in the mbb message is the whole message len+smsc+pdudata - // - MbbSmsSendPdu->PduData.Size = PduDataLength + SmscAddressLength; - MbbSmsSendPdu->PduData.Offset = ROUND_UP_COUNT(FIELD_OFFSET(MBB_SMS_SEND_PDU, DataBuffer), ALIGN_DWORD); - - // - // convert the hex encoded data to binary data - // - NdisStatus = MbbUtilHexStringToByteStream( - WwanSmsSendPdu->PduData, - (PduDataLength + SmscAddressLength) * 2, - ((PUCHAR)MbbSmsSendPdu) + MbbSmsSendPdu->PduData.Offset, - MbbSmsSendPdu->PduData.Size - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_UTIL, "[Util][Sms] FAILED to convert hexstring to bytestream NdisStatus=%!STATUS!", NdisStatus ); - break; - } - } - else - { - BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_SMS_SEND_PDU, DataBuffer), ALIGN_DWORD); - - CurrentOffset=BufferSize; - - BufferSize+=(ULONG)ROUND_UP_COUNT(WwanSmsSendPdu->Size, ALIGN_DWORD); - - // - // Outer buffer has storage for the containing structure as well - // - OuterBufferSize = InitialOffset + BufferSize; - - OuterBuffer = ALLOCATE_NONPAGED_POOL(OuterBufferSize); - - if (OuterBuffer == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer=OuterBuffer + InitialOffset; - - MbbSmsSendPdu=(PMBB_SMS_SEND_PDU)Buffer; - - MbbSmsSendPdu->PduData.Offset=CurrentOffset; - MbbSmsSendPdu->PduData.Size=WwanSmsSendPdu->Size; - - RtlCopyMemory( - ((PUCHAR)MbbSmsSendPdu) + MbbSmsSendPdu->PduData.Offset, - WwanSmsSendPdu->PduData, - WwanSmsSendPdu->Size - ); - - MbbSmsSendPdu->PduData.Size = WwanSmsSendPdu->Size; - } - - *MbbSmsSendSize = OuterBufferSize; - - *ReturnedMbbSmsSend = (PMBB_SMS_SEND)OuterBuffer; - - TraceInfo( WMBCLASS_UTIL, "[Util][Sms] Received PDU send record, CurrentCellularClass=%!MbbCellularClass! PduDataSize=0x%08x SmscAddressLength=0x%08x", - CellularClass, - WwanSmsSendPdu->Size, - SmscAddressLength - ); - TraceInfo( WMBCLASS_UTIL, "[Util][Sms] Converted to PDU record of size 0x%08x, PduDataSize=0x%08x", - *MbbSmsSendSize, - MbbSmsSendPdu->PduData.Size - ); - } - while( FALSE ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - if (OuterBuffer != NULL) - { - FREE_POOL(OuterBuffer); - *MbbSmsSendSize = 0; - *ReturnedMbbSmsSend = NULL; - } - } - return NdisStatus; -} - -NDIS_STATUS -MbbUtilWwanToMbbSmsSendCdma( - __in PWWAN_SMS_SEND_CDMA WwanSmsSendCdma, - __out PMBB_SMS_SEND *ReturnedMbbSmsSend, - __out PULONG MbbSmsSendSize - ) -{ - ULONG CurrentOffset; - SIZE_T StringCbLength; - ANSI_STRING AnsiString; - UNICODE_STRING UnicodeString; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - WCHAR TempWideString[WWAN_SMS_CDMA_ADDR_MAX_LEN]; - ULONG BufferSize = 0; - PUCHAR Buffer = NULL; - - ULONG OuterBufferSize = 0; - PUCHAR OuterBuffer = NULL; - ULONG InitialOffset=0; - - PMBB_SMS_SEND_CDMA MbbSmsSendCdma=NULL; - - *ReturnedMbbSmsSend=NULL; - *MbbSmsSendSize=0; - - do - { - // - // add some space at the beginning, for the contain struct - // - InitialOffset = FIELD_OFFSET( MBB_SMS_SEND, u.Cdma ); - - - BufferSize += ROUND_UP_COUNT( FIELD_OFFSET( MBB_SMS_SEND_CDMA, DataBuffer ), ALIGN_DWORD ); - - // - // Address - // - if( (NdisStatus = RtlStringCbLengthA( - WwanSmsSendCdma->Address, - WWAN_SMS_CDMA_ADDR_MAX_LEN, - &StringCbLength - )) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] FAILED to get string length for CDMA Address NtStatus=%!STATUS!", NdisStatus ); - return NdisStatus; - } - - BufferSize += ROUND_UP_COUNT( StringCbLength * sizeof(WCHAR), ALIGN_DWORD ); - - BufferSize += ROUND_UP_COUNT( WwanSmsSendCdma->SizeInBytes, ALIGN_DWORD ); - - // - // Outer buffer has storage for the containing structure as well - // - OuterBufferSize = InitialOffset + BufferSize; - -#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate to a outgoing reference ReturnedMbbSmsSend.") - OuterBuffer = ALLOCATE_NONPAGED_POOL(OuterBufferSize); - - if (OuterBuffer == NULL ) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer=OuterBuffer + InitialOffset; - - MbbSmsSendCdma=(PMBB_SMS_SEND_CDMA)Buffer; - - MbbSmsSendCdma->EncodingId = (MBB_SMS_CDMA_ENCODING)WwanSmsSendCdma->EncodingId; - MbbSmsSendCdma->LanguageId = (MBB_SMS_CDMA_LANGUAGE)WwanSmsSendCdma->LanguageId; - MbbSmsSendCdma->SizeInCharacters = WwanSmsSendCdma->SizeInCharacters; - - - - CurrentOffset = ROUND_UP_COUNT( FIELD_OFFSET( MBB_SMS_SEND_CDMA, DataBuffer ), ALIGN_DWORD ); - - TraceInfo( WMBCLASS_UTIL, "[Util][Sms] Received CDMA send record, EncodingId=0x%08x LanguageId=0x%08x Address[Sz=0x%08x] EncodedMessage[Sz=0x%08x SzCh=0x%08x]", - WwanSmsSendCdma->EncodingId, - WwanSmsSendCdma->LanguageId, - (ULONG)StringCbLength, - WwanSmsSendCdma->SizeInBytes, - WwanSmsSendCdma->SizeInCharacters - ); - - AnsiString.Buffer = WwanSmsSendCdma->Address; - AnsiString.Length = (USHORT)StringCbLength; - AnsiString.MaximumLength = WWAN_SMS_CDMA_ADDR_MAX_LEN; - - UnicodeString.Buffer = &TempWideString[0]; - UnicodeString.Length = 0; - UnicodeString.MaximumLength = sizeof(TempWideString); - - if( (NdisStatus = RtlAnsiStringToUnicodeString( - &UnicodeString, - &AnsiString, - FALSE // AllocateDestinationString - )) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_UTIL, "[Util][Sms] FAILED to convert WwanSmsSendCdma->Address Length=%dbytes, NtStatus=%!STATUS!", - AnsiString.Length, NdisStatus - ); - break; - } - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - &MbbSmsSendCdma->Address, - (PUCHAR)&TempWideString[0], - (ULONG)StringCbLength * sizeof(WCHAR) - ); - - CurrentOffset=MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbSmsSendCdma->EncodedMessage, - (PUCHAR)WwanSmsSendCdma->EncodedMsg, - WwanSmsSendCdma->SizeInBytes - ); - - // - // MessageSize - // - *MbbSmsSendSize = OuterBufferSize; - *ReturnedMbbSmsSend = (PMBB_SMS_SEND)OuterBuffer; - - TraceInfo( WMBCLASS_OID, "[Util][Sms] Converted to CDMA send record of size 0x%08x, Address[Off=0x%08x Sz=0x%08x] EncodedMessage[Off=0x%08x Sz=0x%08x SzCh=0x%08x]", - *MbbSmsSendSize, - MbbSmsSendCdma->Address.Offset, - MbbSmsSendCdma->Address.Size, - MbbSmsSendCdma->EncodedMessage.Offset, - MbbSmsSendCdma->EncodedMessage.Size, - MbbSmsSendCdma->SizeInCharacters - ); - } - while( FALSE ); - - return NdisStatus; -} - - -VOID -MbbUtilWwanToMbbSmsDelete( - __in PWWAN_SMS_FILTER WwanSmsFilter, - __out PMBB_SMS_DELETE MbbSmsDelete - ) -{ - MbbSmsDelete->SmsFlags = (MBB_SMS_FLAG)WwanSmsFilter->Flag; - MbbSmsDelete->MessageIndex = WwanSmsFilter->MessageIndex; -} - -NDIS_STATUS -MbbUtilWwanToMbbSubscribeEvents( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in_ecount(GuidCount) GUID* GuidList, - __in ULONG GuidCount, - __in BOOL ExternalRequest, - __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, - __in ULONG ExtSubscribeListSize, - __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, - __out PULONG OutputSubscribeBufferSize - ) -{ - ULONG i = 0; - PMBB_DS deviceServiceEntry = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG ResultSize = 0; - PMBB_SUBSCRIBE_EVENT_LIST MbbSubscribeList = NULL; - ULONG MbbSubscribeListSize = 0; - PMBB_SUBSCRIBE_EVENT_ENTRY EventEntry = NULL; - ULONG DeviceServiceCount = 0; - ULONG CurrentOffset; - - *OutputSubscribeList = NULL; - *OutputSubscribeBufferSize = 0; - - do - { - // - // Determine the size of the total list by going through all device services - // & combining that with the CID list length - // - MbbSubscribeListSize = FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement); - - for (i = 0; i < GuidCount; i++) - { - // If this is an external request, reject native services - // - if (ExternalRequest && MbbUtilIsNativeMbnService(&GuidList[i])) - { - // Native device services cannot be subscribed to using this path - TraceError( WMBCLASS_OID, "[Util] FAILED because of subscribe request for native device service %!GUID!", - &GuidList[i] - ); - - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - - // - // Find this device service so that we can get the CID list - // - deviceServiceEntry = MbbUtilFindDeviceService(Adapter, - &GuidList[i] - ); - if (deviceServiceEntry == NULL) - { - // Unsupported device service - if (ExternalRequest) - { - TraceError( WMBCLASS_OID, "[Util] FAILED because of subscribe request for unsupported device service %!GUID!", - &GuidList[i] - ); - - NdisStatus = NDIS_STATUS_INVALID_DATA; - break; - } - else - { - // Just move to the next for internal GUID lists - continue; - } - } - - MbbSubscribeListSize += sizeof(MBB_ARRAY_ELEMENT); - - // Space for this GUID & its CID list - MbbSubscribeListSize += (FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) + - deviceServiceEntry->CIDCount * sizeof(ULONG) - ); - - DeviceServiceCount++; - - } - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - // Failed due to bad device service in the list - break; - } - - if ((ExtSubscribeList != NULL) && (ExtSubscribeListSize > (ULONG)FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement))) - { - // - // we have another list to merge into this one - // - for (i=0; iCount; i++) - { - DeviceServiceCount++; - MbbSubscribeListSize += sizeof(MBB_ARRAY_ELEMENT); - MbbSubscribeListSize += ExtSubscribeList->ArrayElement[i].Size; - - } - } - - // - // Now allocate memory for the OID's device services subscription - // - MbbSubscribeList = ALLOCATE_NONPAGED_POOL( MbbSubscribeListSize); - - if ( MbbSubscribeList == NULL ) - { - TraceError( WMBCLASS_OID, "[Util] FAILED to allocate %d bytes for OID MBB_SUBSCRIBE_EVENT_LIST, ElementCount=%d", - MbbSubscribeListSize, - GuidCount - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - MbbSubscribeList->Count = DeviceServiceCount; - CurrentOffset=FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement) + (sizeof(MbbSubscribeList->ArrayElement[0]) * MbbSubscribeList->Count); - - // Start copying - - DeviceServiceCount=0; - - for (i = 0; i < GuidCount ; i++) - { - // Find the device service again (validation for the service is already done) - deviceServiceEntry = MbbUtilFindDeviceService(Adapter, - &GuidList[i] - ); - - if (deviceServiceEntry != NULL) - { - - EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)MbbSubscribeList+CurrentOffset); - - // OACR complains below that the size is small, but its really not because we - // checked before for the size - - // Copy the GUID (changing length) - MBB_UUID_TO_NET(&EventEntry->DeviceServiceId, - &GuidList[i] - ); - - // CID Count - EventEntry->CIDCount = deviceServiceEntry->CIDCount; - - // Copy the CIDs - RtlCopyMemory(EventEntry->CIDList, - deviceServiceEntry->CIDList, - sizeof(ULONG) * EventEntry->CIDCount - ); - - - MbbSubscribeList->ArrayElement[DeviceServiceCount].Offset=CurrentOffset; - MbbSubscribeList->ArrayElement[DeviceServiceCount].Size= FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) + deviceServiceEntry->CIDCount * sizeof(ULONG); - - CurrentOffset += FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) + deviceServiceEntry->CIDCount * sizeof(ULONG); - - DeviceServiceCount++; - - } - else - { - // Not supported by device, skip - } - - } - - if ((ExtSubscribeList != NULL) && (ExtSubscribeListSize > (ULONG)FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement))) - { - // - // we have another list to merge into this one - // - for (i=0; iCount; i++) - { - EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)MbbSubscribeList+CurrentOffset); - - MbbSubscribeList->ArrayElement[DeviceServiceCount].Offset=CurrentOffset; - MbbSubscribeList->ArrayElement[DeviceServiceCount].Size= ExtSubscribeList->ArrayElement[i].Size; - - RtlCopyMemory( - EventEntry, - ((PBYTE)ExtSubscribeList+ExtSubscribeList->ArrayElement[i].Offset), - ExtSubscribeList->ArrayElement[i].Size - ); - - CurrentOffset += ExtSubscribeList->ArrayElement[i].Size; - - DeviceServiceCount++; - } - } - - - *OutputSubscribeList = MbbSubscribeList; - *OutputSubscribeBufferSize = MbbSubscribeListSize; - - } while (FALSE); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - if (MbbSubscribeList) - { - FREE_POOL(MbbSubscribeList); - } - } - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilGenerateLowPowerSubscribeEventList( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in ULONG MediaSpecificWakeUpEvents, - __in ULONG WakeUpFlags, - __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, - __out PULONG OutputSubscribeListSize - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG NativeSubscribeCount=0; - ULONG NativeSubscribeListSize = 0; - PMBB_SUBSCRIBE_EVENT_LIST NativeSubscribeList = NULL; - PMBB_SUBSCRIBE_EVENT_ENTRY EventEntry = NULL; - ULONG i = 0; - ULONG CurrentOffset = 0; - ULONG CurrentEvent = 0; - ULONG BasicConnectCommands = 0; - - do - { - // Determine required size based on MediaSpecicWakeUpEvents and WakeUpFlags (grouped by service ID) - - // Count number of MBB_UUID_BASIC_CONNECT_CONSTANT wake ups - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_REGISTER_STATE_ENABLED) - { - BasicConnectCommands++; - } - - if (WakeUpFlags & NDIS_PM_WAKE_ON_MEDIA_DISCONNECT_ENABLED) - { - BasicConnectCommands++; - } - - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_PACKET_STATE_ENABLED) - { - BasicConnectCommands++; - } - - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_UICC_CHANGE_ENABLED) - { - BasicConnectCommands++; - } - - if (BasicConnectCommands > 0) - { - NativeSubscribeCount++; - NativeSubscribeListSize += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) ; - - NativeSubscribeListSize += sizeof(ULONG) * BasicConnectCommands-1; - } - - // Count number of MBB_UUID_SMS_CONSTANT wake ups - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_SMS_RECEIVE_ENABLED) - { - NativeSubscribeCount++; - NativeSubscribeListSize += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) ; - } - - // Count number of MBB_UUID_USSD_CONSTANT wake ups - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_USSD_RECEIVE_ENABLED) - { - NativeSubscribeCount++; - NativeSubscribeListSize += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList) ; - } - - NativeSubscribeListSize += FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement); - NativeSubscribeListSize += sizeof(MBB_ARRAY_ELEMENT) * NativeSubscribeCount; - - if( (NativeSubscribeList = ALLOCATE_NONPAGED_POOL( NativeSubscribeListSize )) == NULL ) - { - TraceError( WMBCLASS_OID, "[Util] FAILED to allocate %d bytes for low power MBB_SUBSCRIBE_EVENT_LIST", - NativeSubscribeListSize - ); - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - - *OutputSubscribeListSize = NativeSubscribeListSize; - NativeSubscribeList->Count = NativeSubscribeCount; - - CurrentOffset=FIELD_OFFSET(MBB_SUBSCRIBE_EVENT_LIST, ArrayElement) + (sizeof(NativeSubscribeList->ArrayElement[0]) * NativeSubscribeList->Count); - - // Populate the subsribe list with the MBB_UUID_BASIC_CONNECT_CONSTANT wake ups - if (BasicConnectCommands > 0) - { - GUID TempGuid=MBB_UUID_BASIC_CONNECT_CONSTANT; - - EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)NativeSubscribeList+CurrentOffset); - - MBB_UUID_TO_NET(&EventEntry->DeviceServiceId, &TempGuid); - EventEntry->CIDCount = BasicConnectCommands; - - i=0; - - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_REGISTER_STATE_ENABLED) - { - EventEntry->CIDList[i]=MBB_BASIC_CID_REGISTER_STATE; - i++; - } - if (WakeUpFlags & NDIS_PM_WAKE_ON_MEDIA_DISCONNECT_ENABLED) - { - EventEntry->CIDList[i]=MBB_BASIC_CID_CONNECT; - i++; - } - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_PACKET_STATE_ENABLED) - { - EventEntry->CIDList[i]=MBB_BASIC_CID_PACKET_SERVICE; - i++; - } - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_UICC_CHANGE_ENABLED) - { - EventEntry->CIDList[i]=MBB_BASIC_CID_SUBSCRIBER_READY_INFO; - i++; - } - - NativeSubscribeList->ArrayElement[CurrentEvent].Offset=CurrentOffset; - NativeSubscribeList->ArrayElement[CurrentEvent].Size= RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList[i-1]); - - CurrentEvent++; - // Next event entry - CurrentOffset += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList[i-1]); - } - - // Populate the subsribe list with the MBB_UUID_SMS_CONSTANT wake ups - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_SMS_RECEIVE_ENABLED) - { - GUID TempGuid=MBB_UUID_SMS_CONSTANT; - - EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)NativeSubscribeList+CurrentOffset); - - MBB_UUID_TO_NET(&EventEntry->DeviceServiceId, &TempGuid); - EventEntry->CIDCount = 1; - EventEntry->CIDList[0]=MBB_SMS_CID_STATUS; - - // Next event entry - NativeSubscribeList->ArrayElement[CurrentEvent].Offset=CurrentOffset; - NativeSubscribeList->ArrayElement[CurrentEvent].Size= RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList); - - CurrentEvent++; - - // Next event entry - CurrentOffset += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList); - } - - // Populate the subsribe list with the MBB_UUID_USSD_CONSTANT wake ups - if (MediaSpecificWakeUpEvents & NDIS_WWAN_WAKE_ON_USSD_RECEIVE_ENABLED) - { - GUID TempGuid=MBB_UUID_USSD_CONSTANT; - - EventEntry =(PMBB_SUBSCRIBE_EVENT_ENTRY)((PBYTE)NativeSubscribeList+CurrentOffset); - - MBB_UUID_TO_NET(&EventEntry->DeviceServiceId, &TempGuid); - EventEntry->CIDCount = 1; - EventEntry->CIDList[0]=MBB_USSD_CID_USSD; - - // Next event entry - NativeSubscribeList->ArrayElement[CurrentEvent].Offset=CurrentOffset; - NativeSubscribeList->ArrayElement[CurrentEvent].Size= RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList); - - CurrentEvent++; - - // Next event entry - CurrentOffset += RTL_SIZEOF_THROUGH_FIELD(MBB_SUBSCRIBE_EVENT_ENTRY, CIDList); - } - - *OutputSubscribeList = NativeSubscribeList; - NativeSubscribeList = NULL; - } - while (FALSE); - - if (NativeSubscribeList != NULL) - FREE_POOL(NativeSubscribeList); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilGenerateFullPowerSubscribeEventList( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, - __in ULONG ExtSubscribeListSize, - __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, - __out PULONG OutputSubscribeListSize - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - PMBB_SUBSCRIBE_EVENT_LIST MergedSubscribeList = NULL; - ULONG MergedSubscribeBufferSize = 0; - - *OutputSubscribeList = NULL; - *OutputSubscribeListSize = 0; - do - { - // - // This function's job is to take the native device serices & create - // the subscribe list (with CIDs) for them. Also, take the extensibility device service subscribe list - // and merge it into the other list. It optimizes memory management by allocating memory - // for both lists when it creates the native device service's subscribe list - // - - // Fill the native one & leave space for the extensibility list - NdisStatus = MbbUtilWwanToMbbSubscribeEvents(Adapter, - NativeMbnServices, - ARRAYSIZE(NativeMbnServices), - FALSE, - ExtSubscribeList, - ExtSubscribeListSize, - &MergedSubscribeList, - &MergedSubscribeBufferSize - ); - - if( NdisStatus != NDIS_STATUS_SUCCESS) - { - TraceError( WMBCLASS_OID, "[Util] FAILED to allocate memory for merged MBB_SUBSCRIBE_EVENT_LIST"); - break; - } - - - *OutputSubscribeList = MergedSubscribeList; - *OutputSubscribeListSize = MergedSubscribeBufferSize; - MergedSubscribeList = NULL; - } - while (FALSE); - - if (MergedSubscribeList != NULL) - FREE_POOL(MergedSubscribeList); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilGenerateSubscribeEventList( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN FullPower, - __in ULONG MediaSpecificWakeUpEvents, - __in ULONG WakeUpFlags, - __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, - __in ULONG ExtSubscribeListSize, - __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, - __out PULONG OutputSubscribeListSize - ) -{ - if (FullPower) - { - // Will generate the full list - return MbbUtilGenerateFullPowerSubscribeEventList( - Adapter, - ExtSubscribeList, - ExtSubscribeListSize, - OutputSubscribeList, - OutputSubscribeListSize - ); - } - else - { - // Generate a limit list - return MbbUtilGenerateLowPowerSubscribeEventList( - Adapter, - MediaSpecificWakeUpEvents, - WakeUpFlags, - OutputSubscribeList, - OutputSubscribeListSize - ); - } - -} - -NDIS_STATUS -MbbUtilWwanToMbbAkapAuthChallenge( - __in PWWAN_AUTH_AKAP_CHALLENGE WwanAuthAkapChallenge, - __in ULONG UTF16ByteCount, - __in ULONG MbbSize, - __out_bcount(MbbSize) PMBB_AKAP_AUTH_CHALLENGE MbbAkapAuthChallenge - ) -{ - ULONG CurrentOffset; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ANSI_STRING AnsiString; - UNICODE_STRING UnicodeString; - - if( MbbSize < sizeof(MBB_AKAP_AUTH_CHALLENGE) ) - { - return NDIS_STATUS_BUFFER_OVERFLOW; - } - RtlCopyMemory( - MbbAkapAuthChallenge->Rand, - WwanAuthAkapChallenge->Rand, - WWAN_AUTH_RAND_LEN - ); - RtlCopyMemory( - MbbAkapAuthChallenge->Autn, - WwanAuthAkapChallenge->Autn, - WWAN_AUTH_AUTN_LEN - ); - CurrentOffset = ROUND_UP_COUNT( FIELD_OFFSET( MBB_AKAP_AUTH_CHALLENGE, DataBuffer ), ALIGN_DWORD ); - // - // NetworkName - // - if( MbbSize < (CurrentOffset + UTF16ByteCount) ) - { - return NDIS_STATUS_BUFFER_OVERFLOW; - } - NdisStatus = RtlUTF8ToUnicodeN( - (PWCHAR)(((PCHAR)MbbAkapAuthChallenge) + CurrentOffset), - UTF16ByteCount, - NULL, - (PCCH)(WwanAuthAkapChallenge->NetworkName), - WwanAuthAkapChallenge->NetworkNameLength - ); - if( STATUS_SUCCESS != NdisStatus ) - { - TraceError( WMBCLASS_OID, "[Util] FAILED RtlUTF8ToUnicodeN(AuthAkap.NetworkName=%s)=%!STATUS!, ignoring=%!BOOLEAN!", - WwanAuthAkapChallenge->NetworkName, - NdisStatus, - (STATUS_SOME_NOT_MAPPED == NdisStatus) - ); - if( STATUS_SOME_NOT_MAPPED != NdisStatus ) - return NdisStatus; - else - NdisStatus = STATUS_SUCCESS; - } - - MbbAkapAuthChallenge->NetworkName.Size = UTF16ByteCount; - MbbAkapAuthChallenge->NetworkName.Offset = CurrentOffset; - return NdisStatus; -} - -NDIS_STATUS -MbbUtilWwanToMbbUiccFilePath( - __in PWWAN_UICC_FILE_PATH WwanUiccFilePath, - __deref_out PMBB_UICC_FILE_PATH *MbbUiccFilePathOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; - - *ReturnedBufferSize = 0; - - BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_UICC_FILE_PATH, DataBuffer), ALIGN_DWORD); - - CurrentOffset = BufferSize; - - BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccFilePath->AppIdLength, ALIGN_DWORD); - BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccFilePath->FilePathLength * sizeof(USHORT), ALIGN_DWORD); - - if ((MbbUiccFilePath = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer = (PUCHAR)MbbUiccFilePath; - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbUiccFilePath->AppId, - (PUCHAR)WwanUiccFilePath->AppId, - WwanUiccFilePath->AppIdLength - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbUiccFilePath->FilePath, - (PUCHAR)WwanUiccFilePath->FilePath, - WwanUiccFilePath->FilePathLength * sizeof(USHORT) - ); - - *MbbUiccFilePathOut = MbbUiccFilePath; - - *ReturnedBufferSize = BufferSize; - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbUtilWwanToMbbUiccAccessBinary( - __in PWWAN_UICC_ACCESS_BINARY WwanUiccAccessBinary, - __deref_out_opt PMBB_UICC_ACCESS_BINARY *MbbUiccAccessBinaryOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_UICC_ACCESS_BINARY MbbUiccAccessBinary = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG MbbUiccFilePathLength; - PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; - - *MbbUiccAccessBinaryOut = NULL; - *ReturnedBufferSize = 0; - - BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_UICC_ACCESS_BINARY, DataBuffer), ALIGN_DWORD); - - CurrentOffset = BufferSize; - - NdisStatus = MbbUtilWwanToMbbUiccFilePath( - &WwanUiccAccessBinary->UiccFilePath, - &MbbUiccFilePath, - &MbbUiccFilePathLength - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - goto Cleanup; - } - - BufferSize += (ULONG)ROUND_UP_COUNT(MbbUiccFilePathLength, ALIGN_DWORD); - BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccAccessBinary->LocalPinSize, ALIGN_DWORD); - BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccAccessBinary->BinaryDataSize, ALIGN_DWORD); - - if ((MbbUiccAccessBinary = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) - { - NdisStatus = NDIS_STATUS_RESOURCES; - goto Cleanup; - } - - Buffer = (PUCHAR)MbbUiccAccessBinary; - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbUiccAccessBinary->UiccFilePath, - (PUCHAR)MbbUiccFilePath, - MbbUiccFilePathLength - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbUiccAccessBinary->LocalPin, - (PUCHAR)WwanUiccAccessBinary->LocalPin, - WwanUiccAccessBinary->LocalPinSize - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbUiccAccessBinary->BinaryData, - (PUCHAR)WwanUiccAccessBinary->BinaryData, - WwanUiccAccessBinary->BinaryDataSize - ); - - MbbUiccAccessBinary->FileOffset = WwanUiccAccessBinary->FileOffset; - MbbUiccAccessBinary->NumberOfBytes = WwanUiccAccessBinary->NumberOfBytes; - - *MbbUiccAccessBinaryOut = MbbUiccAccessBinary; - *ReturnedBufferSize = BufferSize; - -Cleanup: - if (NULL != MbbUiccFilePath) - { - FREE_POOL(MbbUiccFilePath); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilWwanToMbbUiccAccessRecord( - __in PWWAN_UICC_ACCESS_RECORD WwanUiccAccessRecord, - __deref_out_opt PMBB_UICC_ACCESS_RECORD *MbbUiccAccessRecordOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_UICC_ACCESS_RECORD MbbUiccAccessRecord = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG MbbUiccFilePathLength; - PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; - - *MbbUiccAccessRecordOut = NULL; - *ReturnedBufferSize = 0; - - BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_UICC_ACCESS_RECORD, DataBuffer), ALIGN_DWORD); - - CurrentOffset = BufferSize; - - NdisStatus = MbbUtilWwanToMbbUiccFilePath( - &WwanUiccAccessRecord->UiccFilePath, - &MbbUiccFilePath, - &MbbUiccFilePathLength - ); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - goto Cleanup; - } - - BufferSize += (ULONG)ROUND_UP_COUNT(MbbUiccFilePathLength, ALIGN_DWORD); - BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccAccessRecord->LocalPinSize, ALIGN_DWORD); - BufferSize += (ULONG)ROUND_UP_COUNT(WwanUiccAccessRecord->RecordDataSize, ALIGN_DWORD); - - if ((MbbUiccAccessRecord = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) - { - NdisStatus = NDIS_STATUS_RESOURCES; - goto Cleanup; - } - - Buffer = (PUCHAR)MbbUiccAccessRecord; - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbUiccAccessRecord->UiccFilePath, - (PUCHAR)MbbUiccFilePath, - MbbUiccFilePathLength - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbUiccAccessRecord->LocalPin, - (PUCHAR)WwanUiccAccessRecord->LocalPin, - WwanUiccAccessRecord->LocalPinSize - ); - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbUiccAccessRecord->RecordData, - (PUCHAR)WwanUiccAccessRecord->RecordData, - WwanUiccAccessRecord->RecordDataSize - ); - - MbbUiccAccessRecord->RecordNumber = WwanUiccAccessRecord->RecordNumber; - - *MbbUiccAccessRecordOut = MbbUiccAccessRecord; - *ReturnedBufferSize = BufferSize; - -Cleanup: - if (NULL != MbbUiccFilePath) - { - FREE_POOL(MbbUiccFilePath); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilWwanToMbbPinApp( - __in PWWAN_PIN_APP WwanPinApp, - __deref_out PMBB_PIN_APP *MbbPinAppOut, - __out PULONG ReturnedBufferSize -) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_PIN_APP MbbPinApp = NULL; - - *ReturnedBufferSize = 0; - *MbbPinAppOut = NULL; - - BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_PIN_APP, DataBuffer), ALIGN_DWORD); - - CurrentOffset = BufferSize; - - BufferSize += (ULONG)ROUND_UP_COUNT(WwanPinApp->AppIdLength, ALIGN_DWORD); - - if ((MbbPinApp = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer = (PUCHAR)MbbPinApp; - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&MbbPinApp->AppId, - (PUCHAR)WwanPinApp->AppId, - WwanPinApp->AppIdLength - ); - - *MbbPinAppOut = MbbPinApp; - - *ReturnedBufferSize = BufferSize; - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetDeviceSlotMappingInfo( - __in PWWAN_DEVICE_SLOT_MAPPING_INFO WwanDeviceSlotMappingInfo, - __deref_out_opt PMBB_MS_DEVICE_SLOT_MAPPING_INFO *MbbDeviceSlotMappingInfoOut, - __out PULONG ReturnedBufferSize -) -{ - PUCHAR WwanBuffer = NULL; - ULONG CurrentOffsetInWwanBuffer = 0; - PUCHAR MbbBuffer = NULL; - ULONG CurrentOffsetInMbbBuffer = 0; - ULONG MbbBufferSize = 0; - PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbDeviceSlotMappingInfo = NULL; - ULONG MapCount = 0; - ULONG MapIndex = 0; - - WwanBuffer = (PUCHAR)WwanDeviceSlotMappingInfo; - CurrentOffsetInWwanBuffer = sizeof(WWAN_DEVICE_SLOT_MAPPING_INFO); - MapCount = WwanDeviceSlotMappingInfo->SlotMapListHeader.ElementCount; - *MbbDeviceSlotMappingInfoOut = NULL; - *ReturnedBufferSize = 0; - - // Calculate the buffer size for MbbDeviceSlotMappingInfo. - MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_MS_DEVICE_SLOT_MAPPING_INFO, SlotMapList), ALIGN_DWORD); - MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * MapCount, ALIGN_DWORD); - - CurrentOffsetInMbbBuffer = MbbBufferSize; - - MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(ULONG) * MapCount, ALIGN_DWORD); - - // Allocate the buffer for MbbDeviceSlotMappingInfo. - MbbDeviceSlotMappingInfo = ALLOCATE_NONPAGED_POOL(MbbBufferSize); - if (NULL == MbbDeviceSlotMappingInfo) - { - return NDIS_STATUS_RESOURCES; - } - - MbbBuffer = (PUCHAR)MbbDeviceSlotMappingInfo; - - // Set the values of MbbDeviceSlotMappingInfo - MbbDeviceSlotMappingInfo->MapCount = MapCount; - CurrentOffsetInMbbBuffer = MbbUtilWwanListToMbbList(&(WwanDeviceSlotMappingInfo->SlotMapListHeader), - sizeof(ULONG), - MbbBuffer, - CurrentOffsetInMbbBuffer, - &(MbbDeviceSlotMappingInfo->SlotMapList[0])); - - *MbbDeviceSlotMappingInfoOut = MbbDeviceSlotMappingInfo; - *ReturnedBufferSize = MbbBufferSize; - - return NDIS_STATUS_SUCCESS; -} - -ULONG -MbbUtilWwanListToMbbList( - __in PWWAN_LIST_HEADER WwanListHeader, - __in ULONG WwanListElementSize, - __inout PUCHAR MbbBuffer, - __in ULONG CurrentOffsetInMbbBuffer, - __inout PMBB_ARRAY_ELEMENT MbbArray - ) -{ - PUCHAR WwanBuffer = (PUCHAR)WwanListHeader; - ULONG CurrentOffsetInWwanBuffer = sizeof(WWAN_LIST_HEADER); - ULONG MapCount = WwanListHeader->ElementCount; - ULONG MapIndex = 0; - ULONG ReturnedOffsetInMbbBuffer = CurrentOffsetInMbbBuffer; - - for (MapIndex = 0; MapIndex < MapCount; MapIndex++) - { - // Set the offsets and sizes. - MbbArray[MapIndex].Offset = ReturnedOffsetInMbbBuffer; - MbbArray[MapIndex].Size = WwanListElementSize; - - // Set the DataBuffer. -#pragma warning(suppress: 26007) - RtlCopyMemory(MbbBuffer + ReturnedOffsetInMbbBuffer, - WwanBuffer + CurrentOffsetInWwanBuffer, - WwanListElementSize); - - ReturnedOffsetInMbbBuffer += WwanListElementSize; - CurrentOffsetInWwanBuffer += WwanListElementSize; - } - - return ReturnedOffsetInMbbBuffer; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetDeviceBindingsInfo( - __in PWWAN_DEVICE_BINDINGS_INFO WwanSetDeviceBindingsInfo, - __deref_out PMBB_DEVICE_BINDINGS_INFO *MbbSetDeviceBindingsInfoOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR WwanBuffer = NULL; - ULONG CurrentOffsetInWwanBuffer = 0; - PUCHAR MbbBuffer = NULL; - ULONG CurrentOffsetInMbbBuffer = 0; - ULONG MbbBufferSize = 0; - PMBB_DEVICE_BINDINGS_INFO MbbDeviceBindingsInfo = NULL; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - ULONG MbbUiccFilePathLength[MAX_CNT_UICC_APPS_BOUND_TO_DEVICE] = { 0 }; - PMBB_UICC_FILE_PATH MbbUiccFilePath[MAX_CNT_UICC_APPS_BOUND_TO_DEVICE] = { NULL }; - ULONG AppCount = 0; - ULONG AppIndex = 0; - - WwanBuffer = (PUCHAR)WwanSetDeviceBindingsInfo; - CurrentOffsetInWwanBuffer = sizeof(WWAN_DEVICE_BINDINGS_INFO); - AppCount = WwanSetDeviceBindingsInfo->ApplicationListHeader.ElementCount; - *ReturnedBufferSize = 0; - - // WWAN_DEVICE_BINDINGS_INFO can specify at most MAX_CNT_UICC_APPS_BOUND_TO_DEVICE (= 2) UICC applications. - if (AppCount > MAX_CNT_UICC_APPS_BOUND_TO_DEVICE) - { - return NDIS_STATUS_INVALID_PARAMETER; - } - - // Generate the MBB_UICC_FILE_PATH based on WWAN_UICC_FILE_PATH and calculate the MbbBufferSize. - MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_DEVICE_BINDINGS_INFO, ApplicationList), ALIGN_DWORD); - MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * AppCount, ALIGN_DWORD); - CurrentOffsetInMbbBuffer = MbbBufferSize; - - for (AppIndex = 0; AppIndex < AppCount; AppIndex++) - { - NdisStatus = MbbUtilWwanToMbbUiccFilePath( - (PWWAN_UICC_FILE_PATH)(WwanBuffer + CurrentOffsetInWwanBuffer), - &(MbbUiccFilePath[AppIndex]), - &(MbbUiccFilePathLength[AppIndex])); - - if (NdisStatus != NDIS_STATUS_SUCCESS) - { - goto Cleanup; - } - - CurrentOffsetInWwanBuffer += sizeof(WWAN_UICC_FILE_PATH); - MbbBufferSize += MbbUiccFilePathLength[AppIndex]; - } - - // Allocate the buffer for MbbDeviceSlotMappingInfo. - MbbDeviceBindingsInfo = ALLOCATE_NONPAGED_POOL(MbbBufferSize); - if (NULL == MbbDeviceBindingsInfo) - { - NdisStatus = NDIS_STATUS_RESOURCES; - goto Cleanup; - } - - MbbBuffer = (PUCHAR)MbbDeviceBindingsInfo; - - // Set the values of MbbDeviceBindingsInfo - MbbDeviceBindingsInfo->ApplicationCount = AppCount; - for (AppIndex = 0; AppIndex < AppCount; AppIndex++) - { - CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( - MbbBuffer, - MbbBufferSize, - CurrentOffsetInMbbBuffer, - (PMBB_STRING)(&(MbbDeviceBindingsInfo->ApplicationList[AppIndex])), - (PUCHAR)(MbbUiccFilePath[AppIndex]), - MbbUiccFilePathLength[AppIndex]); - } - - *MbbSetDeviceBindingsInfoOut = MbbDeviceBindingsInfo; - *ReturnedBufferSize = MbbBufferSize; - -Cleanup: - for (AppIndex = 0; AppIndex < AppCount; AppIndex++) - { - if (NULL != MbbUiccFilePath[AppIndex]) - { - FREE_POOL(MbbUiccFilePath[AppIndex]); - } - } - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetRegisterStateEx( - __in PWWAN_SET_REGISTER_STATE_EX WwanSetRegisterStateEx, - __deref_out PMBB_SET_REGISTER_STATE_V2 *MbbSetRegisterStateV2Out, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR WwanBuffer = NULL; - ULONG CurrentOffsetInWwanBuffer = 0; - PUCHAR MbbBuffer = NULL; - ULONG CurrentOffsetInMbbBuffer = 0; - ULONG MbbBufferSize = 0; - PMBB_SET_REGISTER_STATE_V2 MbbSetRegisterStateV2 = NULL; - SIZE_T ProviderIdSize = 0; - ULONG DataClassCount = 0; - - WwanBuffer = (PUCHAR)WwanSetRegisterStateEx; - CurrentOffsetInWwanBuffer = sizeof(WWAN_SET_REGISTER_STATE_EX); - DataClassCount = WwanSetRegisterStateEx->AcquisitionOrderListHeader.ElementCount; - *ReturnedBufferSize = 0; - - if (WwanStructRegisterAcquisitionOrder != WwanSetRegisterStateEx->AcquisitionOrderListHeader.ElementType) - { - return NDIS_STATUS_INVALID_PARAMETER; - } - - // Calculate the MbbBufferSize. - MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_REGISTER_STATE_V2, AcquisitionOrder), ALIGN_DWORD); - MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT), ALIGN_DWORD); - CurrentOffsetInMbbBuffer = MbbBufferSize; - - if (RtlStringCbLengthW(WwanSetRegisterStateEx->ProviderId, sizeof(WwanSetRegisterStateEx->ProviderId), &ProviderIdSize) - != STATUS_SUCCESS) - { - ProviderIdSize = sizeof(WwanSetRegisterStateEx->ProviderId); - } - MbbBufferSize += ROUND_UP_COUNT((ULONG)ProviderIdSize, ALIGN_DWORD); - - MbbBufferSize += ROUND_UP_COUNT(sizeof(ULONG) * DataClassCount, ALIGN_DWORD); - - // Allocate the buffer for MbbSetRegisterStateV2. - MbbSetRegisterStateV2 = ALLOCATE_NONPAGED_POOL(MbbBufferSize); - if (NULL == MbbSetRegisterStateV2) - { - return NDIS_STATUS_RESOURCES; - } - - MbbBuffer = (PUCHAR)MbbSetRegisterStateV2; - - // Set the values of MbbSetRegisterStateV2 - CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( - MbbBuffer, - MbbBufferSize, - CurrentOffsetInMbbBuffer, - &(MbbSetRegisterStateV2->ProviderId), - (PUCHAR)(WwanSetRegisterStateEx->ProviderId), - (ULONG)ProviderIdSize); - - MbbSetRegisterStateV2->RegisterAction = (MBB_REGISTER_ACTION)WwanSetRegisterStateEx->RegisterAction; - MbbSetRegisterStateV2->DataClass = WwanSetRegisterStateEx->WwanDataClass; - MbbSetRegisterStateV2->VoiceClass = (MBB_REGISTRATION_VOICE_CLASS)WwanSetRegisterStateEx->WwanVoiceClass; - MbbSetRegisterStateV2->VoiceDomain = (MBB_REGISTRATION_VOICE_DOMAIN_PREFERENCE)WwanSetRegisterStateEx->WwanVoiceDomain; - MbbSetRegisterStateV2->CdmaRoamMode = (MBB_REGISTRATION_CDMA_ROAM_MODE)WwanSetRegisterStateEx->WwanCdmaRoamMode; - - CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( - MbbBuffer, - MbbBufferSize, - CurrentOffsetInMbbBuffer, - (PMBB_STRING)(&(MbbSetRegisterStateV2->AcquisitionOrder)), - (PUCHAR)(WwanBuffer + CurrentOffsetInWwanBuffer), - sizeof(ULONG) * DataClassCount); - - *MbbSetRegisterStateV2Out = MbbSetRegisterStateV2; - *ReturnedBufferSize = MbbBufferSize; - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetUiccOpenChannel( - __in PWWAN_SET_UICC_OPEN_CHANNEL WwanSetUiccOpenChannel, - __deref_out PMBB_SET_UICC_OPEN_CHANNEL *MbbSetUiccOpenChannelOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_SET_UICC_OPEN_CHANNEL MbbSetUiccOpenChannel = NULL; - MBB_ARRAY_ELEMENT AppId = { 0 }; - - *MbbSetUiccOpenChannelOut = NULL; - *ReturnedBufferSize = 0; - - BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_UICC_OPEN_CHANNEL, DataBuffer), ALIGN_DWORD); - - CurrentOffset = BufferSize; - - BufferSize += (ULONG)ROUND_UP_COUNT(WwanSetUiccOpenChannel->AppIdLength, ALIGN_DWORD); - - if ((MbbSetUiccOpenChannel = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer = (PUCHAR)MbbSetUiccOpenChannel; - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&AppId, - (PUCHAR)WwanSetUiccOpenChannel->AppId, - WwanSetUiccOpenChannel->AppIdLength - ); - - // In the MBIM Extension for Low-Level UICC Access, (OFFSET, SIZE) type pairs are spec'ed in - // reverse order of the MBIM v1.0. Convert the pair that is filled by the utility function. - MbbSetUiccOpenChannel->AppId.Size = AppId.Size; - MbbSetUiccOpenChannel->AppId.Offset = AppId.Offset; - - MbbSetUiccOpenChannel->SelectP2Arg = WwanSetUiccOpenChannel->SelectP2Arg; - MbbSetUiccOpenChannel->ChannelGroup = WwanSetUiccOpenChannel->ChannelGroup; - - *MbbSetUiccOpenChannelOut = MbbSetUiccOpenChannel; - *ReturnedBufferSize = BufferSize; - - return NDIS_STATUS_SUCCESS; -} - -VOID -MbbUtilWwanToMbbSetUiccCloseChannel( - __in PWWAN_SET_UICC_CLOSE_CHANNEL WwanSetUiccCloseChannel, - __out PMBB_SET_UICC_CLOSE_CHANNEL MbbSetUiccCloseChannel - ) -{ - MbbSetUiccCloseChannel->Channel = WwanSetUiccCloseChannel->Channel; - MbbSetUiccCloseChannel->ChannelGroup = WwanSetUiccCloseChannel->ChannelGroup; - MbbSetUiccCloseChannel->SelectP2Arg = WwanSetUiccCloseChannel->SelectP2Arg; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetUiccApdu( - __in PWWAN_SET_UICC_APDU WwanSetUiccApdu, - __deref_out PMBB_SET_UICC_APDU *MbbSetUiccApduOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_SET_UICC_APDU MbbSetUiccApdu = NULL; - MBB_ARRAY_ELEMENT Command = { 0 }; - - *MbbSetUiccApduOut = NULL; - *ReturnedBufferSize = 0; - - BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_UICC_APDU, DataBuffer), ALIGN_DWORD); - - CurrentOffset = BufferSize; - - BufferSize += (ULONG)ROUND_UP_COUNT(WwanSetUiccApdu->CommandLength, ALIGN_DWORD); - - if ((MbbSetUiccApdu = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer = (PUCHAR)MbbSetUiccApdu; - - CurrentOffset = MbbUtilWriteStringToBuffer( - Buffer, - BufferSize, - CurrentOffset, - (PMBB_STRING)&Command, - (PUCHAR)WwanSetUiccApdu->Command, - WwanSetUiccApdu->CommandLength - ); - - // In the MBIM Extension for Low-Level UICC Access, (OFFSET, SIZE) type pairs are spec'ed in - // reverse order of the MBIM v1.0. Convert the pair that is filled by the utility function. - MbbSetUiccApdu->Command.Size = Command.Size; - MbbSetUiccApdu->Command.Offset = Command.Offset; - - MbbSetUiccApdu->Channel = WwanSetUiccApdu->Channel; - MbbSetUiccApdu->SecureMessaging = (MBB_UICC_SECURE_MESSAGING)WwanSetUiccApdu->SecureMessaging; - MbbSetUiccApdu->Type = (MBB_UICC_CLASS_BYTE_TYPE)WwanSetUiccApdu->Type; - - *MbbSetUiccApduOut = MbbSetUiccApdu; - *ReturnedBufferSize = BufferSize; - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetUiccTerminalCapability( - __in PWWAN_LIST_HEADER WwanCapabilityListHeader, - __deref_out PMBB_SET_UICC_TERMINAL_CAPABILITY *MbbSetUiccTerminalCapabilityOut, - __out PULONG ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG BufferSize; - PMBB_SET_UICC_TERMINAL_CAPABILITY MbbSetUiccTerminalCapability = NULL; - ULONG CapabilityCount = 0; - - *MbbSetUiccTerminalCapabilityOut = NULL; - *ReturnedBufferSize = 0; - - CapabilityCount = WwanCapabilityListHeader->ElementCount; - - BufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_UICC_TERMINAL_CAPABILITY, CapabilityList), ALIGN_DWORD); - BufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * CapabilityCount, ALIGN_DWORD); - - CurrentOffset = BufferSize; - - BufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_UICC_TERMINAL_CAPABILITY_TLV) * CapabilityCount, ALIGN_DWORD); - - if ((MbbSetUiccTerminalCapability = ALLOCATE_NONPAGED_POOL(BufferSize)) == NULL) - { - return NDIS_STATUS_RESOURCES; - } - - Buffer = (PUCHAR)MbbSetUiccTerminalCapability; - - MbbSetUiccTerminalCapability->ElementCount = CapabilityCount; - CurrentOffset = MbbUtilWwanListToMbbList(WwanCapabilityListHeader, - sizeof(MBB_UICC_TERMINAL_CAPABILITY_TLV), - Buffer, - CurrentOffset, - &(MbbSetUiccTerminalCapability->CapabilityList[0])); - - *MbbSetUiccTerminalCapabilityOut = MbbSetUiccTerminalCapability; - *ReturnedBufferSize = BufferSize; - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetSarConfig( - _In_ PWWAN_SET_SAR_CONFIG WwanSetSarConfig, - _Outptr_ PMBB_SET_SAR_CONFIG *MbbSetSarConfigOut, - _Out_ PULONG ReturnedBufferSize -) -{ - ULONG CurrentOffsetInWwanBuffer = 0; - ULONG CurrentOffsetInMbbBuffer = 0; - ULONG MbbBufferSize = 0; - PMBB_SET_SAR_CONFIG MbbSetSarConfig = NULL; - ULONG SarIndexCount = 0; - - CurrentOffsetInWwanBuffer = sizeof(WWAN_SET_SAR_CONFIG); - SarIndexCount = WwanSetSarConfig->SarConfigIndexListHeader.ElementCount; - *ReturnedBufferSize = 0; - - if (WwanStructSarConfig != WwanSetSarConfig->SarConfigIndexListHeader.ElementType) - { - return NDIS_STATUS_INVALID_PARAMETER; - } - - // Calculate the MbbBufferSize. - MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_SET_SAR_CONFIG, Configurations), ALIGN_DWORD); - MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * SarIndexCount, ALIGN_DWORD); - CurrentOffsetInMbbBuffer = MbbBufferSize; - - MbbBufferSize += ROUND_UP_COUNT(sizeof(MBB_SAR_CONFIG_INDICES) * SarIndexCount, ALIGN_DWORD); - - // Allocate the buffer for MbbSetSarConfig. - MbbSetSarConfig = ALLOCATE_NONPAGED_POOL(MbbBufferSize); - if (NULL == MbbSetSarConfig) - { - return NDIS_STATUS_RESOURCES; - } - - // Set the values of MbbSetSarConfig - MbbSetSarConfig->SarMode = (MBB_SAR_CONTROL_MODE)WwanSetSarConfig->SarMode; - MbbSetSarConfig->SarBackoffStatus = (MBB_SAR_BACKOFF_STATE)WwanSetSarConfig->SarBackoffStatus; - MbbSetSarConfig->ElementCount = SarIndexCount; - - for (ULONG i = 0; i < SarIndexCount; i++) - { - CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbSetSarConfig, - MbbBufferSize, - CurrentOffsetInMbbBuffer, - (PMBB_STRING)(&(MbbSetSarConfig->Configurations[i])), - (PUCHAR)((PUCHAR)WwanSetSarConfig + CurrentOffsetInWwanBuffer), - sizeof(WWAN_SAR_CONFIG_INDICES)); - - CurrentOffsetInWwanBuffer += sizeof(WWAN_SAR_CONFIG_INDICES); - } - - *MbbSetSarConfigOut = MbbSetSarConfig; - *ReturnedBufferSize = MbbBufferSize; - - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetNetworkBlacklist( - _In_ PWWAN_NETWORK_BLACKLIST_INFO SetNetworkBlacklist, - _Outptr_ PMBB_MS_NETWORK_BLACKLIST_INFO *MbbNetworkBlacklistOut, - _Out_ PULONG ReturnedBufferSize -) -{ - ULONG CurrentOffsetInWwanBuffer = 0; - ULONG CurrentOffsetInMbbBuffer = 0; - ULONG MbbBufferSize = 0; - PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist = NULL; - ULONG BlacklistedProviderCount = SetNetworkBlacklist->BlacklistProviderList.ElementCount; - - CurrentOffsetInWwanBuffer = sizeof(WWAN_NETWORK_BLACKLIST_INFO); - - *ReturnedBufferSize = 0; - - // Calculate the MbbBufferSize. - MbbBufferSize = (ULONG)ROUND_UP_COUNT(FIELD_OFFSET(MBB_MS_NETWORK_BLACKLIST_INFO, Contexts), ALIGN_DWORD); - MbbBufferSize += (ULONG)ROUND_UP_COUNT(sizeof(MBB_ARRAY_ELEMENT) * BlacklistedProviderCount, ALIGN_DWORD); - CurrentOffsetInMbbBuffer = MbbBufferSize; - - MbbBufferSize += ROUND_UP_COUNT(sizeof(MBB_MS_NETWORK_BLACKLIST_PROVIDER) * BlacklistedProviderCount, ALIGN_DWORD); - - // Allocate the buffer for MbbNetworkBlacklist. - MbbNetworkBlacklist = ALLOCATE_NONPAGED_POOL(MbbBufferSize); - if (NULL == MbbNetworkBlacklist) - { - return NDIS_STATUS_RESOURCES; - } - - // Set the values of MbbNetworkBlacklist - MbbNetworkBlacklist->BlacklistState = (MBB_BASICCONNECTEXT_NETWORK_BLACKLIST_STATE)SetNetworkBlacklist->BlacklistState; - MbbNetworkBlacklist->ElementCount = BlacklistedProviderCount; - - for (ULONG i = 0; i < BlacklistedProviderCount; i++) - { - CurrentOffsetInMbbBuffer = MbbUtilWriteStringToBuffer( - (PUCHAR)MbbNetworkBlacklist, - MbbBufferSize, - CurrentOffsetInMbbBuffer, - (PMBB_STRING)(&(MbbNetworkBlacklist->Contexts[i])), - (PUCHAR)((PUCHAR)MbbNetworkBlacklist + CurrentOffsetInWwanBuffer), - sizeof(MBB_MS_NETWORK_BLACKLIST_PROVIDER)); - - CurrentOffsetInWwanBuffer += sizeof(MBB_MS_NETWORK_BLACKLIST_PROVIDER); - } - - *MbbNetworkBlacklistOut = MbbNetworkBlacklist; - *ReturnedBufferSize = MbbBufferSize; - - return NDIS_STATUS_SUCCESS; -} - - -// -// Mbb to Wwan -// - -WWAN_STATUS -MbbUtilMbbToWwanStatus( - __in MBB_STATUS MbbStatus - ) -{ - if( MBB_STATUS_IS_BASIC( MbbStatus ) ) - { - return MbbStatusMapTableBasic[MBB_STATUS_BASIC_INDEX(MbbStatus)]; - } - else if( MBB_STATUS_IS_SMS( MbbStatus ) ) - { - return MbbStatusMapTableSms[MBB_STATUS_SMS_INDEX(MbbStatus)]; - } - else if( MBB_STATUS_IS_UICC( MbbStatus ) ) - { - return MbbStatusMapTableUicc[MBB_STATUS_UICC_INDEX(MbbStatus)]; - } - else - { - TraceError( WMBCLASS_OID, "[Util][MBBStatus] INVALID MBB status code=%d", - MbbStatus - ); - - return WWAN_STATUS_FAILURE; - } -} - -VOID -MbbUtilMbbToWwanRadioState( - __in MBB_RADIO_STATE* MbbRadioState, - __out WWAN_RADIO* WwanRadio - ) -{ - *WwanRadio = (MBB_RADIO_STATE)*MbbRadioState ; -} - -NTSTATUS -MbbIsVariableFieldValid( - ULONG TotalMessageLength, - ULONG Offset, - ULONG Size, - ULONG MaxElements, - ULONG ElementSize - ) - -{ - ULONGLONG Temp; - - Temp = (ULONGLONG)Offset + Size; - - // - // does the field extend beyond the length of the whole message? - // - if (Temp > TotalMessageLength) - { - TraceError( WMBCLASS_OID, "Offset plus size exceeded total length, Offset=%d, Size=%d, Total=%d",Offset, Size, TotalMessageLength); - return STATUS_INVALID_PARAMETER; - } - - // - // Is the offset aligned on a dword boundary? - // - if (Offset != ROUND_UP_COUNT(Offset,ALIGN_DWORD)) - { - TraceError( WMBCLASS_OID, "Offset note dword aligned Offset=%d", Offset); - return STATUS_INVALID_PARAMETER; - } - - // - // Is the field bigger than the max we support? - // - if ((Size/ElementSize) > MaxElements) - { - TraceError( WMBCLASS_OID, "Size is larger than max elements Size=%d, Max=%d", Size/ElementSize , MaxElements); - return STATUS_INVALID_PARAMETER; - } - - // - // is the size an integral number of elements - // - if (Size % ElementSize != 0) - { - TraceError( WMBCLASS_OID, "Size is not a multiple of ElementSize Size=%d, element size=%d", Size, ElementSize); - return STATUS_INVALID_PARAMETER; - } - - return STATUS_SUCCESS; -} - - -NTSTATUS -MbbIsArrayFieldValid( - ULONG TotalMessageLength, - ULONG Offset, - ULONG ElementCount, - ULONG ElementSize - ) - -{ - ULONGLONG Temp; - ULONGLONG ArraySize; - - ArraySize= (ULONGLONG) ElementCount * ElementSize; - - if (ArraySize > ULONG_MAX) - { - TraceError( WMBCLASS_OID, "Array size is too big, Count=%d, Size=%d", ElementCount, ElementSize); - return STATUS_INVALID_PARAMETER; - } - - Temp = (ULONGLONG)Offset + ArraySize; - - // - // does the field extend beyond the length of the whole message? - // - if (Temp > TotalMessageLength) - { - TraceError( WMBCLASS_OID, "Offset plus size exceeded total length, Offset=%d, Size=%I64d, Total=%d",Offset, ArraySize, TotalMessageLength); - return STATUS_INVALID_PARAMETER; - } - - // - // Is the offset aligned on a dword boundary? - // - if (Offset != ROUND_UP_COUNT(Offset,ALIGN_DWORD)) - { - TraceError( WMBCLASS_OID, "Offset note dword aligned Offset=%d", Offset); - return STATUS_INVALID_PARAMETER; - } - - return STATUS_SUCCESS; -} - -VOID -MbbUtilMbbToWwanDeviceCaps( - __in PMBB_DEVICE_CAPS MbbDeviceCaps, - __in_ecount(ManufacturerStrLen) PWCHAR ManufacturerString, - __in ULONG ManufacturerStrLen, - __in_ecount(ModelStrLen) PWCHAR ModelString, - __in ULONG ModelStrLen, - __out PWWAN_DEVICE_CAPS WwanDeviceCaps, - __in BOOL fMultimode - ) -{ - WWAN_CELLULAR_CLASS* pCC = (WWAN_CELLULAR_CLASS*)(((PUCHAR)WwanDeviceCaps) + sizeof(*WwanDeviceCaps)); - - RtlZeroMemory(WwanDeviceCaps, sizeof(*WwanDeviceCaps)); - WwanDeviceCaps->CellularClassListHeader.ElementType = WwanStructCellularClass; - WwanDeviceCaps->CellularClassListHeader.ElementCount = 0; - - MbbDeviceCaps->CellularClass &= MbbCellularClassMaximum; - - WwanDeviceCaps->WwanDeviceType = (WWAN_DEVICE_TYPE)MbbDeviceCaps->DeviceType; - - if (MbbDeviceCaps->CellularClass & MbbCellularClassGsm) - { - - WwanDeviceCaps->WwanCellularClass = WwanCellularClassGsm; - } - else if (MbbDeviceCaps->CellularClass & MbbCellularClassCdma) - { - WwanDeviceCaps->WwanCellularClass = WwanCellularClassCdma; - } - - - WwanDeviceCaps->WwanVoiceClass = (WWAN_VOICE_CLASS)MbbDeviceCaps->VoiceClass; - WwanDeviceCaps->WwanSimClass = (WWAN_SIM_CLASS)MbbDeviceCaps->SimClass; - WwanDeviceCaps->WwanDataClass = (ULONG)MbbDeviceCaps->DataClass; - - WwanDeviceCaps->WwanGsmBandClass = (ULONG)WWAN_BAND_CLASS_UNKNOWN; - WwanDeviceCaps->WwanCdmaBandClass = (ULONG)WWAN_BAND_CLASS_UNKNOWN; - - WwanDeviceCaps->WwanSmsCaps = (ULONG)MbbDeviceCaps->SmsCaps; - WwanDeviceCaps->WwanControlCaps = (ULONG)MbbDeviceCaps->ControlCaps; - - - if(fMultimode) - { - WwanDeviceCaps->WwanControlCaps |= WWAN_CTRL_CAPS_MULTI_MODE; - WwanDeviceCaps->CellularClassListHeader.ElementCount = MbbCellularClassMaximum - 1 ; - - //for now we just have GSM and CDMA so hardcode, this is protected - //by a C_ASSERT - *pCC = WwanCellularClassGsm; - *(pCC+ 1) = WwanCellularClassCdma; - } - else - { - WwanDeviceCaps->WwanCellularClass = MbbDeviceCaps->CellularClass; - } - - // - // this bit is not in the mbim model - // - WwanDeviceCaps->WwanControlCaps &= ~WWAN_CTRL_CAPS_PROTECT_UNIQUEID; - - // - // translate this one to the right wwan bit - // - if (MbbDeviceCaps->ControlCaps & MbbControlCapsMultiCarrier) - { - WwanDeviceCaps->WwanControlCaps |= WWAN_CTRL_CAPS_MODEL_MULTI_CARRIER; - } - - WwanDeviceCaps->MaxActivatedContexts = MbbDeviceCaps->dwMaxSessions; - - MbbUtilPopulateStaticString(WwanDeviceCaps->CustomDataClass, MbbDeviceCaps, CustomDataClass); - - MbbUtilPopulateStaticString(WwanDeviceCaps->DeviceId, MbbDeviceCaps, DeviceIdString); - - MbbUtilPopulateStaticString(WwanDeviceCaps->FirmwareInfo, MbbDeviceCaps, FirmwareInfo); - - - RtlStringCchCopyNW( - WwanDeviceCaps->Manufacturer, - WWAN_MANUFACTURER_LEN, - ManufacturerString, - ManufacturerStrLen - ); - - RtlStringCchCopyNW( - WwanDeviceCaps->Model, - WWAN_MODEL_LEN, - ModelString, - ModelStrLen - ); - - return; -} - -VOID -MbbUtilMbbToWwanDeviceCapsV2( - __in PMBB_MS_DEVICE_CAPS_INFO_V2 MbbDeviceCaps, - __in_ecount(ManufacturerStrLen) PWCHAR ManufacturerString, - __in ULONG ManufacturerStrLen, - __in_ecount(ModelStrLen) PWCHAR ModelString, - __in ULONG ModelStrLen, - __out PWWAN_DEVICE_CAPS_EX WwanDeviceCaps, - __in BOOL fMultimode -) -{ - WWAN_CELLULAR_CLASS* pCC = (WWAN_CELLULAR_CLASS*)(((PUCHAR)WwanDeviceCaps) + sizeof(*WwanDeviceCaps)); - - RtlZeroMemory(WwanDeviceCaps, sizeof(*WwanDeviceCaps)); - WwanDeviceCaps->CellularClassListHeader.ElementType = WwanStructCellularClass; - WwanDeviceCaps->CellularClassListHeader.ElementCount = 0; - - MbbDeviceCaps->CellularClass &= MbbCellularClassMaximum; - - WwanDeviceCaps->WwanDeviceType = (WWAN_DEVICE_TYPE)MbbDeviceCaps->DeviceType; - - if (MbbDeviceCaps->CellularClass & MbbCellularClassGsm) - { - WwanDeviceCaps->WwanCellularClass = WwanCellularClassGsm; - } - else if (MbbDeviceCaps->CellularClass & MbbCellularClassCdma) - { - WwanDeviceCaps->WwanCellularClass = WwanCellularClassCdma; - } - - WwanDeviceCaps->WwanVoiceClass = (WWAN_VOICE_CLASS)MbbDeviceCaps->VoiceClass; - WwanDeviceCaps->WwanSimClass = (WWAN_SIM_CLASS)MbbDeviceCaps->SimClass; - WwanDeviceCaps->WwanDataClass = (ULONG)MbbDeviceCaps->DataClass; - - WwanDeviceCaps->WwanGsmBandClass = (ULONG)WWAN_BAND_CLASS_UNKNOWN; - WwanDeviceCaps->WwanCdmaBandClass = (ULONG)WWAN_BAND_CLASS_UNKNOWN; - - WwanDeviceCaps->WwanSmsCaps = (ULONG)MbbDeviceCaps->SmsCaps; - - WwanDeviceCaps->WwanControlCaps = (ULONG)MbbDeviceCaps->ControlCaps; - - if (fMultimode) - { - WwanDeviceCaps->WwanControlCaps |= WWAN_CTRL_CAPS_MULTI_MODE; - WwanDeviceCaps->CellularClassListHeader.ElementCount = MbbCellularClassMaximum - 1; - - //for now we just have GSM and CDMA so hardcode, this is protected - //by a C_ASSERT - *pCC = WwanCellularClassGsm; - *(pCC + 1) = WwanCellularClassCdma; - } - - // - // this bit is not in the mbim model - // - WwanDeviceCaps->WwanControlCaps &= ~WWAN_CTRL_CAPS_PROTECT_UNIQUEID; - - // - // translate this one to the right wwan bit - // - if (MbbDeviceCaps->ControlCaps & MbbControlCapsMultiCarrier) - { - WwanDeviceCaps->WwanControlCaps |= WWAN_CTRL_CAPS_MODEL_MULTI_CARRIER; - } - - WwanDeviceCaps->MaxActivatedContexts = MbbDeviceCaps->dwMaxSessions; - - MbbUtilPopulateStaticString(WwanDeviceCaps->CustomDataClass, MbbDeviceCaps, CustomDataClass); - - MbbUtilPopulateStaticString(WwanDeviceCaps->DeviceId, MbbDeviceCaps, DeviceIdString); - - MbbUtilPopulateStaticString(WwanDeviceCaps->FirmwareInfo, MbbDeviceCaps, FirmwareInfo); - - RtlStringCchCopyNW( - WwanDeviceCaps->Manufacturer, - WWAN_MANUFACTURER_LEN, - ManufacturerString, - ManufacturerStrLen - ); - - RtlStringCchCopyNW( - WwanDeviceCaps->Model, - WWAN_MODEL_LEN, - ModelString, - ModelStrLen - ); - - // - // new field added in WWAN_DEVICE_CAPS_EX - // - WwanDeviceCaps->ExecutorIndex = MbbDeviceCaps->ExecutorIndex; - - return; -} - -VOID -MbbUtilMbbToWwanReadyInfo( - __in PMBB_SUBSCRIBER_READY_INFO MbbReadyInfo, - __in PWWAN_READY_INFO WwanReadyInfo - ) -/*++ - Note: - Not all the information required to fill the WWAN_READY_INFO - structure is present in MBB_SUBSCRIBER_READY_INFO. Some of the - information will come from MBB_EMERGENCY_MODE and MBB_SMS_CONFIGURATION. ---*/ -{ - ULONG ElementCount = MbbReadyInfo->TelephoneNumberCount; - ULONG ElementIndex; - ULONG StringCb; - ULONG StringCch; - PWCHAR WwanTn; - PWCHAR MbbTn; - NTSTATUS NtStatus; - - WwanReadyInfo->ReadyState = (WWAN_READY_STATE)MbbReadyInfo->ReadyState; - - StringCb = MIN( MbbReadyInfo->SubscriberId.Size, (WWAN_SUBSCRIBERID_LEN-1) * sizeof(WCHAR) ); - RtlCopyMemory( - WwanReadyInfo->SubscriberId, - (((PCHAR)MbbReadyInfo) + MbbReadyInfo->SubscriberId.Offset), - StringCb - ); - StringCch = StringCb / sizeof(WCHAR); - WwanReadyInfo->SubscriberId[StringCch] = 0; - - StringCb = MIN( MbbReadyInfo->SimIccId.Size, (WWAN_SIMICCID_LEN-1) * sizeof(WCHAR) ); - RtlCopyMemory( - WwanReadyInfo->SimIccId, - (((PCHAR)MbbReadyInfo) + MbbReadyInfo->SimIccId.Offset), - StringCb - ); - StringCch = StringCb / sizeof(WCHAR); - WwanReadyInfo->SimIccId[StringCch] = 0; - - WwanReadyInfo->TNListHeader.ElementType = WwanStructTN; - WwanReadyInfo->TNListHeader.ElementCount = ElementCount; - - WwanTn = (PWCHAR)(WwanReadyInfo + 1); - - for( ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex ++ ) - { - MbbTn = (PWCHAR)((PCHAR)MbbReadyInfo + MbbReadyInfo->TelephoneNumbers[ElementIndex].Offset); - StringCb = MIN( MbbReadyInfo->TelephoneNumbers[ElementIndex].Size, (WWAN_TN_LEN-1) * sizeof(WCHAR) ); - RtlCopyMemory( - WwanTn, - MbbTn, - StringCb - ); - StringCch = StringCb / sizeof(WCHAR); - WwanTn[StringCch] = 0; - WwanTn += WWAN_TN_LEN; - } -} - -VOID -MbbUtilMbbToWwanPinInfo( - __in PMBB_PIN_INFO MbbPinInfo, - __out PWWAN_PIN_INFO WwanPinInfo - ) -{ - WwanPinInfo->PinType = (WWAN_PIN_TYPE)MbbPinInfo->PinType; - WwanPinInfo->PinState = (WWAN_PIN_STATE)MbbPinInfo->PinState; - WwanPinInfo->AttemptsRemaining = (ULONG)MbbPinInfo->AttemptsRemaining; -} - -VOID -MbbUtilMbbToWwanPinList( - __in PMBB_PIN_LIST MbbPinList, - __out PWWAN_PIN_LIST WwanPinList - ) -{ - ULONG PinIndex; - PWWAN_PIN_DESC WwanPinDesc; - PMBB_PIN_DESCRIPTION MbbPinDesc; - - WwanPinDesc = &WwanPinList->WwanPinDescPin1; - MbbPinDesc = &MbbPinList->PinDescPin1; - // - // A loop works because both the list are in the same order. - // - for( PinIndex = 0; - PinIndex < 10; - PinIndex ++ ) - { - WwanPinDesc[PinIndex].PinMode = (WWAN_PIN_MODE)MbbPinDesc[PinIndex].PinMode; - WwanPinDesc[PinIndex].PinFormat = (WWAN_PIN_FORMAT)MbbPinDesc[PinIndex].PinFormat; - WwanPinDesc[PinIndex].PinLengthMin = (ULONG)MbbPinDesc[PinIndex].PinLengthMin; - WwanPinDesc[PinIndex].PinLengthMax = (ULONG)MbbPinDesc[PinIndex].PinLengthMax; - } -} - -NDIS_STATUS -MbbUtilValidateMbbProvider( - __in ULONG MbbProviderSize, - __in_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; - - do - { - if( MbbProvider == NULL || - MbbProviderSize < sizeof(MBB_PROVIDER) ) - { - TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT BufferSize for MBB_PROVIDER, BufferSize[Received=%d Expected=%d]", - MbbProviderSize, - sizeof(MBB_PROVIDER) - ); - break; - } - if( MbbIsVariableFieldValid( - MbbProviderSize, - MbbProvider->ProviderId.Offset, - MbbProvider->ProviderId.Size, - MBB_MAXIMUM_PROVIDER_ID_LENGTH, - sizeof(WCHAR) - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util] INVALID MBB_PROVIDER.ProviderId Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - MbbProvider->ProviderId.Offset, - MbbProviderSize, - MbbProvider->ProviderId.Size, - MBB_MAXIMUM_PROVIDER_ID_LENGTH * sizeof(WCHAR) - ); - break; - } - if( MbbIsVariableFieldValid( - MbbProviderSize, - MbbProvider->ProviderName.Offset, - MbbProvider->ProviderName.Size, - MBB_MAXIMUM_PROVIDER_NAME_LENGTH, - sizeof(WCHAR) - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util] INVALID MBB_PROVIDER.ProviderName Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - MbbProvider->ProviderName.Offset, - MbbProviderSize, - MbbProvider->ProviderName.Size, - MBB_MAXIMUM_PROVIDER_NAME_LENGTH * sizeof(WCHAR) - ); - break; - } - if( MbbProvider->CellularClass >= MbbCellularClassMaximum ) - { - TraceError( WMBCLASS_OID, "[Util] INVALID MBB_PROVIDER.CellularClass=0x%x", MbbProvider->CellularClass ); - break; - } - NdisStatus = NDIS_STATUS_SUCCESS; - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilValidateMbbProviderList( - __in ULONG MbbProviderListSize, - __in_bcount(MbbProviderListSize) PMBB_PROVIDER_LIST MbbProviderList - ) -{ - ULONG ElementIndex; - ULONG ElementCount; - ULONG ExpectedSize; - NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; - NTSTATUS NtStatus = STATUS_SUCCESS; - - do - { - if( MbbProviderList == NULL || - MbbProviderListSize < RTL_SIZEOF_THROUGH_FIELD(MBB_PROVIDER_LIST, ProviderCount) ) - { - TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT BufferSize for MBB_PROVIDER_LIST, BufferSize[Received=%d Expected=%d]", - MbbProviderListSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_PROVIDER_LIST, ProviderCount) - ); - break; - } - - ElementCount = MbbProviderList->ProviderCount; - - NtStatus = RtlULongMult( - ElementCount, - sizeof(MBB_ARRAY_ELEMENT), - &ExpectedSize - ); - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[Util] Multiplication overflow occured, ElementCount=%d MBB_ARRAY_ELEMENT size=%d", - ElementCount, - sizeof(MBB_ARRAY_ELEMENT) - ); - break; - } - - NtStatus = RtlULongAdd( - ExpectedSize, - FIELD_OFFSET(MBB_PROVIDER_LIST, Providers), - &ExpectedSize - ); - if ( NT_ERROR(NtStatus) ) - { - TraceError( WMBCLASS_OID, "[Util] Addition overflow occured, ExpectedSize=%d FIELD_OFFSET=%d", - ExpectedSize, - FIELD_OFFSET(MBB_PROVIDER_LIST, Providers) - ); - break; - } - - if( ExpectedSize > MbbProviderListSize ) - { - TraceError( WMBCLASS_OID, "[Util] INSUFFICIENT BufferSize for MBB_PROVIDER_LIST, BufferSize[Received=%d Expected=%d] ProviderCount=%d", - MbbProviderListSize, - ExpectedSize, - MbbProviderList->ProviderCount - ); - break; - } - - for( ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex ++ ) - { - if( MbbIsVariableFieldValid( - MbbProviderListSize, - MbbProviderList->Providers[ElementIndex].Offset, - MbbProviderList->Providers[ElementIndex].Size, - ULONG_MAX, // MaxElements - 1 // ElementSize - ) != NDIS_STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util] INVALID INVALID MBB_PROVIDER_LIST.Providers[%d] Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - ElementIndex, - MbbProviderList->Providers[ElementIndex].Offset, - MbbProviderListSize, - MbbProviderList->Providers[ElementIndex].Size, - ULONG_MAX - ); - break; - } - if( MbbUtilValidateMbbProvider( - MbbProviderList->Providers[ElementIndex].Size, - (PMBB_PROVIDER)(((PCHAR)MbbProviderList) + MbbProviderList->Providers[ElementIndex].Offset) - ) != NDIS_STATUS_SUCCESS ) - { - break; - } - } - if( ElementIndex != ElementCount ) - break; - - NdisStatus = NDIS_STATUS_SUCCESS; - } - while( FALSE ); - - return NdisStatus; -} - - -VOID -MbbUtilMbbToWwanProvider( - __in PMBB_PROVIDER MbbProvider, - __in ULONG MbbDataClass, - __out PWWAN_PROVIDER WwanProvider - ) -{ - ULONG StringCb; - ULONG StringCch; - - WwanProvider->ProviderState = (ULONG)MbbProvider->ProviderState; - WwanProvider->WwanDataClass = MbbDataClass; - - StringCb = MIN( MbbProvider->ProviderId.Size, (WWAN_PROVIDERID_LEN-1) * sizeof(WCHAR) ); - RtlCopyMemory( - WwanProvider->ProviderId, - (((PCHAR)MbbProvider) + MbbProvider->ProviderId.Offset), - StringCb - ); - StringCch = StringCb / sizeof(WCHAR); - WwanProvider->ProviderId[StringCch] = 0; - - StringCb = MIN( MbbProvider->ProviderName.Size, (WWAN_PROVIDERNAME_LEN-1) * sizeof(WCHAR) ); - RtlCopyMemory( - WwanProvider->ProviderName, - (((PCHAR)MbbProvider) + MbbProvider->ProviderName.Offset), - StringCb - ); - StringCch = StringCb / sizeof(WCHAR); - WwanProvider->ProviderName[StringCch] = 0; -} - -VOID -MbbUtilMbbToWwanProvider2( - __in PMBB_PROVIDER MbbProvider, - __in ULONG MbbDataClass, - __out PWWAN_PROVIDER2 WwanProvider2 - ) -{ - MbbUtilMbbToWwanProvider( - MbbProvider, - MbbDataClass, - &WwanProvider2->Provider - ); - WwanProvider2->Rssi = MbbProvider->Rssi; - WwanProvider2->ErrorRate = MbbProvider->ErrorRate; - WwanProvider2->WwanCellularClass= (WWAN_CELLULAR_CLASS)(MbbProvider->CellularClass); -} - -VOID -MbbUtilMbbToWwanProviderList( - __in PMBB_PROVIDER_LIST MbbProviderList, - __in ULONG MbbDataClass, - __in BOOLEAN IsMultiCarrier, - __out PWWAN_LIST_HEADER WwanProviderList - ) -/*++ -Description: - Assumption that the Offsets and Sizes are already verified. ---*/ -{ - ULONG ElementIndex; - ULONG ElementCount = MbbProviderList->ProviderCount; - PWWAN_PROVIDER2 WwanProviders2 = (PWWAN_PROVIDER2)(WwanProviderList + 1); - PMBB_PROVIDER MbbProvider; - - UNREFERENCED_PARAMETER( IsMultiCarrier ); - - for( ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex ++ ) - { - MbbProvider = (PMBB_PROVIDER)(((PCHAR)MbbProviderList) + MbbProviderList->Providers[ElementIndex].Offset); - - MbbUtilMbbToWwanProvider2( - MbbProvider, - MbbDataClass, - &WwanProviders2[ElementIndex] - ); - } - WwanProviderList->ElementType = WwanStructProvider2; - WwanProviderList->ElementCount = ElementIndex; -} - -VOID -MbbUtilMbbToWwanRegistrationState( - __in PMBB_REGISTRATION_STATE MbbRegistrationState, - __out PWWAN_REGISTRATION_STATE WwanRegistrationState - ) -{ - WwanRegistrationState->uNwError = MbbRegistrationState->NetworkError; - WwanRegistrationState->RegisterState = (WWAN_REGISTER_STATE)MbbRegistrationState->RegisterState; - WwanRegistrationState->RegisterMode = (WWAN_REGISTER_MODE)MbbRegistrationState->RegisterMode; - WwanRegistrationState->WwanRegFlags = (ULONG)MbbRegistrationState->RegFlags; - WwanRegistrationState->CurrentCellularClass = (WWAN_CELLULAR_CLASS)MbbRegistrationState->CurrentCellularClass; - - MbbUtilPopulateStaticString(WwanRegistrationState->ProviderId, MbbRegistrationState, ProviderId); - - MbbUtilPopulateStaticString(WwanRegistrationState->ProviderName, MbbRegistrationState, ProviderName); - - MbbUtilPopulateStaticString(WwanRegistrationState->RoamingText, MbbRegistrationState, RoamingText); - -} - -VOID -MbbUtilMbbToWwanPacketService( - __in PMBB_PACKET_SERVICE MbbPacketService, - __out PWWAN_PACKET_SERVICE WwanPacketService - ) -{ - WwanPacketService->uNwError = MbbPacketService->NetworkError; - WwanPacketService->PacketServiceState = (WWAN_PACKET_SERVICE_STATE)MbbPacketService->PacketServiceState; - WwanPacketService->CurrentDataClass = (ULONG)MbbPacketService->HighestAvailableDataClass; -} - -VOID -MbbUtilMbbToWwanSignalState( - __in PMBB_SIGNAL_STATE MbbSignalState, - __out PWWAN_SIGNAL_STATE WwanSignalState - ) -/*++ -Description - MBB and WWAN default and disable values are inverted so - appropriate checks and translation is required. ---*/ -{ - WwanSignalState->Rssi = MbbSignalState->Rssi; - WwanSignalState->ErrorRate = MbbSignalState->ErrorRate; - - if( MBB_RSSI_DEFAULT == MbbSignalState->RssiInterval ) - WwanSignalState->RssiInterval = WWAN_RSSI_DEFAULT; - else if( MBB_RSSI_DISABLE == MbbSignalState->RssiInterval ) - WwanSignalState->RssiInterval = WWAN_RSSI_DISABLE; - else - WwanSignalState->RssiInterval = MbbSignalState->RssiInterval; - - if( MBB_RSSI_DEFAULT == MbbSignalState->RssiThreshold ) - WwanSignalState->RssiThreshold = WWAN_RSSI_DEFAULT; - else if( MBB_RSSI_DISABLE == MbbSignalState->RssiThreshold ) - WwanSignalState->RssiThreshold = WWAN_RSSI_DISABLE; - else - WwanSignalState->RssiThreshold = MbbSignalState->RssiThreshold; -} - -VOID -MbbUtilMbbToWwanContextState( - __in PMBB_CONTEXT_STATE MbbContextState, - __in ULONG ConnectId, - __out PWWAN_CONTEXT_STATE WwanContextState - ) -{ - WwanContextState->uNwError = MbbContextState->NetworkError; - WwanContextState->ConnectionId = ConnectId; - WwanContextState->ActivationState = (WWAN_ACTIVATION_STATE)MbbContextState->ActivationState; - WwanContextState->VoiceCallState = (WWAN_VOICE_CALL_STATE)MbbContextState->VoiceCallState; - - if(MbbContextState->IPType >= MbbContextIPTypeDefault && - MbbContextState->IPType < MbbContextIPTypeMaximum) - { - WwanContextState->IPType = MbbIpTypesMapTable [MbbContextState->IPType]; - } - else - { - TraceWarn(WMBCLASS_UTIL, "Invalid IPType returned from the Modem. Resetting it to IPTypeDefault and setting Context State as Deactivated"); - // Just to be sure, we set the ActivationState as DeActivated if at all we see an IPType out of bounds - WwanContextState->IPType = WwanIPTypeDefault; - WwanContextState->ActivationState = WwanActivationStateDeactivated; - } -} - -VOID -MbbUtilConvertMbbIPConfigFlagsToWwanIPConfigFlags( - ULONG MbbIPConfigflags, - WWAN_IP_CONFIGURATION_FLAGS* WwanConfigFlags - ) -{ - WwanConfigFlags->Value = MbbIPConfigflags; - WwanConfigFlags->AddressAvailable = MbbIPConfigflags & MbbIpFlagsAddressAvailable ? 1 : 0; - WwanConfigFlags->GatewayAvailable = MbbIPConfigflags & MbbIpFlagsGatewayAvailable ? 1 : 0; - WwanConfigFlags->DnsServerAvailable = MbbIPConfigflags & MbbIpFlagsDnsServerAvailable ? 1 : 0; - WwanConfigFlags->MTUAvailable = MbbIPConfigflags & MbbIpFlagsMTUAvailable ? 1 : 0; -} - -NDIS_STATUS -MbbUtilPopulateWwanIPAddressState( - __in PMBB_IP_ADDRESS_INFO IpAddressInfo, - __in PMBB_IPADDRESS_ENTRY IpTable, - __in PMBB_IPADDRESS_ENTRY GatewayTable, - __in PMBB_IPADDRESS_ENTRY DnsTable, - __in ULONG IpCount, - __in ULONG GatewayCount, - __in ULONG DnsCount, - __out PWWAN_IP_ADDRESS_STATE pWwanIPAddressState - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - do - { - if(!IpAddressInfo) - { - Status = NDIS_STATUS_FAILURE; - TraceError( WMBCLASS_UTIL, "[MbbUtilPopulateWwanIPAddressState] Received NULL Ipaddress information to copy"); - break; - } - - MbbUtilConvertMbbIPConfigFlagsToWwanIPConfigFlags(IpAddressInfo->IPv4Flags,&(pWwanIPAddressState->IPv4Flags)); - MbbUtilConvertMbbIPConfigFlagsToWwanIPConfigFlags(IpAddressInfo->IPv6Flags,&(pWwanIPAddressState->IPv6Flags)); - pWwanIPAddressState->IPv4MTU = IpAddressInfo->IPv4MTU; - pWwanIPAddressState->IPv6MTU = IpAddressInfo->IPv6MTU; - - if(IpTable) - { - pWwanIPAddressState->IpTable= ALLOCATE_NONPAGED_POOL(sizeof(MBB_IPADDRESS_ENTRY) * IpCount); - - if(!pWwanIPAddressState->IpTable) - { - Status = NDIS_STATUS_RESOURCES; - TraceError( WMBCLASS_UTIL, "[MbbUtilPopulateWwanIPAddressState] FAILED to allocate memory for IpTable"); - } - else - { - NdisMoveMemory(pWwanIPAddressState->IpTable, IpTable, sizeof(MBB_IPADDRESS_ENTRY) * IpCount); - pWwanIPAddressState->IpCount = IpCount; - } - } - - if(GatewayTable) - { - pWwanIPAddressState->GatewayTable = ALLOCATE_NONPAGED_POOL(sizeof(MBB_IPADDRESS_ENTRY) * GatewayCount); - - if(!pWwanIPAddressState->GatewayTable) - { - Status = NDIS_STATUS_RESOURCES; - TraceError( WMBCLASS_UTIL, "[MbbUtilPopulateWwanIPAddressState] FAILED to allocate memory for GatewayTable"); - } - else - { - NdisMoveMemory(pWwanIPAddressState->GatewayTable, GatewayTable, sizeof(MBB_IPADDRESS_ENTRY) * GatewayCount); - pWwanIPAddressState->GatewayCount = GatewayCount; - } - } - - if(DnsTable) - { - pWwanIPAddressState->DnsTable = ALLOCATE_NONPAGED_POOL(sizeof(MBB_IPADDRESS_ENTRY) * DnsCount); - - if(!pWwanIPAddressState->DnsTable) - { - Status = NDIS_STATUS_RESOURCES; - TraceError( WMBCLASS_UTIL, "[MbbUtilPopulateWwanIPAddressState] FAILED to allocate memory for DnsTable"); - } - else - { - NdisMoveMemory(pWwanIPAddressState->DnsTable, DnsTable, sizeof(MBB_IPADDRESS_ENTRY) * DnsCount); - pWwanIPAddressState->DnsCount = DnsCount; - } - } - }while(FALSE); - - return Status; -} - -WWAN_CONTEXT_TYPE -MbbUtilMbbToWwanContextType( - __in PGUID MbbContextTypeNetworkByteOrder - ) -{ - GUID MbbContextType; - WWAN_CONTEXT_TYPE WwanContextType; - - MBB_UUID_TO_HOST( &MbbContextType, MbbContextTypeNetworkByteOrder ); - - if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_NONE , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeNone; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_INTERNET , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeInternet; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_VPN , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeVpn; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_VOICE , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeVoice; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_VIDEO_SHARE , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeVideoShare; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_PURCHASE , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypePurchase; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_MMS , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeCustom; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_LOCAL , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeCustom; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_CONTEXT_TYPE_CUSTOM , sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeCustom; - else if (RtlCompareMemory(&MbbContextType, &MBB_UUID_CONTEXT_TYPE_IMS, sizeof(GUID)) == sizeof(GUID)) - WwanContextType = WwanContextTypeIms; - else if (RtlCompareMemory(&MbbContextType, &MBB_UUID_CONTEXT_TYPE_MS_ADMIN, sizeof(GUID)) == sizeof(GUID)) - WwanContextType = WwanContextTypeAdmin; - else if (RtlCompareMemory(&MbbContextType, &MBB_UUID_CONTEXT_TYPE_MS_APP, sizeof(GUID)) == sizeof(GUID)) - WwanContextType = WwanContextTypeApp; - else if( RtlCompareMemory( &MbbContextType, &MBB_UUID_BASIC_CONNECT_EXTENSIONS, sizeof(GUID) ) == sizeof(GUID) ) - WwanContextType = WwanContextTypeLteAttach; - else - WwanContextType = WwanContextTypeCustom; - - return WwanContextType; -} - -VOID -MbbUtilMbbToWwanContext( - __in PMBB_CONTEXT MbbContext, - __out PWWAN_CONTEXT WwanContext - ) -{ - WwanContext->ContextId = MbbContext->ContextId; - WwanContext->ContextType = MbbUtilMbbToWwanContextType( &MbbContext->ContextType ); - WwanContext->Compression = (WWAN_COMPRESSION)MbbContext->Compression; - WwanContext->AuthType = (WWAN_AUTH_PROTOCOL)MbbContext->AuthProtocol; - - MbbUtilPopulateStaticString(WwanContext->AccessString, MbbContext, AccessString ); - - MbbUtilPopulateStaticString(WwanContext->UserName, MbbContext, UserName ); - - MbbUtilPopulateStaticString(WwanContext->Password, MbbContext, Password ); - -} - -VOID -MbbUtilMbbToWwanLteAttachContext( - __in PMBB_MS_LTE_ATTACH_CONTEXT MbbLteAttachContext, - __out WWAN_CONTEXT_V2* WwanLteAttachContext - ) -{ - WwanLteAttachContext->basicInfo.ContextId = 0; - WwanLteAttachContext->basicInfo.ContextType = WwanContextTypeLteAttach; - WwanLteAttachContext->basicInfo.Compression = (WWAN_COMPRESSION)MbbLteAttachContext->Compression; - WwanLteAttachContext->basicInfo.AuthType = (WWAN_AUTH_PROTOCOL)MbbLteAttachContext->AuthProtocol; - - MbbUtilPopulateStaticString(WwanLteAttachContext->basicInfo.AccessString, MbbLteAttachContext, AccessString ); - - MbbUtilPopulateStaticString(WwanLteAttachContext->basicInfo.UserName, MbbLteAttachContext, UserName ); - - MbbUtilPopulateStaticString(WwanLteAttachContext->basicInfo.Password, MbbLteAttachContext, Password ); - - if(MbbLteAttachContext->IPType >= MbbContextIPTypeDefault && - MbbLteAttachContext->IPType < MbbContextIPTypeMaximum) - { - WwanLteAttachContext->IPType = MbbIpTypesMapTable [MbbLteAttachContext->IPType]; - } - else - { - TraceWarn(WMBCLASS_UTIL, "Invalid IPType returned from the Modem. Resetting it to IPTypeDefault"); - WwanLteAttachContext->IPType = WwanIPTypeDefault; - } - - WwanLteAttachContext->Roaming = (WWAN_CONTEXT_ROAMING_CONTROL)MbbLteAttachContext->Roaming; - - if (MbbLteAttachContext->Source >= MbbMsContextSourceAdmin && - MbbLteAttachContext->Source < MbbMsContextSourceMaximum) - { - WwanLteAttachContext->Source = MbbSourcesMapTable[MbbLteAttachContext->Source]; - } - else - { - TraceWarn(WMBCLASS_UTIL, "Invalid source returned from the Modem. Resetting it to WwanMaxProvisionSource"); - WwanLteAttachContext->Source = WwanMaxProvisionSource; - } -} - -VOID -MbbUtilMbbToWwanLteAttachStatus( -__in MBB_MS_LTE_ATTACH_STATUS* MbbLteAttachStatus, -__out PWWAN_LTE_ATTACH_STATUS WwanLteAttachStatus -) -{ - WwanLteAttachStatus->LteAttachState = MbbLteAttachStatus->LteAttachState; - if(MbbLteAttachStatus->IPType >= MbbContextIPTypeDefault && - MbbLteAttachStatus->IPType < MbbContextIPTypeMaximum) - { - WwanLteAttachStatus->IPType = MbbIpTypesMapTable [MbbLteAttachStatus->IPType]; - } - else - { - TraceWarn(WMBCLASS_UTIL, "Invalid IPType returned from the Modem. Resetting it to IPTypeDefault"); - WwanLteAttachStatus->IPType = WwanIPTypeDefault; - } - - WwanLteAttachStatus->basicInfo.ContextId = 0; - WwanLteAttachStatus->basicInfo.ContextType = WwanContextTypeLteAttach; - WwanLteAttachStatus->basicInfo.Compression = (WWAN_COMPRESSION)MbbLteAttachStatus->Compression; - WwanLteAttachStatus->basicInfo.AuthType = (WWAN_AUTH_PROTOCOL)MbbLteAttachStatus->AuthProtocol; - - MbbUtilPopulateStaticString(WwanLteAttachStatus->basicInfo.AccessString, MbbLteAttachStatus, AccessString ); - - MbbUtilPopulateStaticString(WwanLteAttachStatus->basicInfo.UserName, MbbLteAttachStatus, UserName ); - - MbbUtilPopulateStaticString(WwanLteAttachStatus->basicInfo.Password, MbbLteAttachStatus, Password ); -} - - -VOID -MbbUtilMbbToWwanContextList( - __in PMBB_CONTEXT_LIST MbbContextList, - __out PWWAN_LIST_HEADER WwanContextList - ) -{ - ULONG ContextIndex; - ULONG ContextCount = MbbContextList->ContextCount; - PMBB_CONTEXT MbbContext; - PWWAN_CONTEXT WwanContext; - - - WwanContext = (PWWAN_CONTEXT)(WwanContextList + 1); - - for( ContextIndex = 0; - ContextIndex < ContextCount; - ContextIndex ++ ) - { - MbbContext = (PMBB_CONTEXT)((PUCHAR)MbbContextList + MbbContextList->Contexts[ContextIndex].Offset); - - MbbUtilMbbToWwanContext( - MbbContext, - &WwanContext[ContextIndex] - ); - } - - WwanContextList->ElementType = WwanStructContext; - WwanContextList->ElementCount = ContextCount; -} - -VOID -MbbUtilMbbToWwanContextV2( - __in PMBB_MS_CONTEXT_V2 MbbContext, - __out PWWAN_CONTEXT_V2 WwanContext -) -{ - WwanContext->basicInfo.ContextId = MbbContext->ContextId; - WwanContext->basicInfo.ContextType = MbbUtilMbbToWwanContextType(&MbbContext->ContextType); - WwanContext->basicInfo.Compression = (WWAN_COMPRESSION)MbbContext->Compression; - WwanContext->basicInfo.AuthType = (WWAN_AUTH_PROTOCOL)MbbContext->AuthProtocol; - - MbbUtilPopulateStaticString(WwanContext->basicInfo.AccessString, MbbContext, AccessString); - - MbbUtilPopulateStaticString(WwanContext->basicInfo.UserName, MbbContext, UserName); - - MbbUtilPopulateStaticString(WwanContext->basicInfo.Password, MbbContext, Password); - - WwanContext->IPType = MbbIpTypesMapTable[MbbContext->IPType]; - WwanContext->Enable = (WWAN_CONTEXT_ENABLE)MbbContext->Enable; - WwanContext->Roaming = (WWAN_CONTEXT_ROAMING_CONTROL)MbbContext->Roaming; - WwanContext->MediaType = (WWAN_CONTEXT_MEDIA_TYPE)MbbContext->MediaType; - WwanContext->Source = MbbSourcesMapTable[MbbContext->Source]; -} - -VOID -MbbUtilMbbToWwanContextV2List( - __in PMBB_CONTEXT_LIST MbbContextList, - __out PWWAN_LIST_HEADER WwanContextList -) -{ - ULONG ContextIndex; - ULONG ContextCount = MbbContextList->ContextCount; - PMBB_MS_CONTEXT_V2 MbbContext; - PWWAN_CONTEXT_V2 WwanContext; - - - WwanContext = (PWWAN_CONTEXT_V2)(WwanContextList + 1); - - for (ContextIndex = 0; - ContextIndex < ContextCount; - ContextIndex++) - { - MbbContext = (PMBB_MS_CONTEXT_V2)((PUCHAR)MbbContextList + MbbContextList->Contexts[ContextIndex].Offset); - - MbbUtilMbbToWwanContextV2( - MbbContext, - &WwanContext[ContextIndex] - ); - } - - WwanContextList->ElementType = WwanStructContextV2; - WwanContextList->ElementCount = ContextCount; -} - -VOID -MbbUtilMbbToWwanServiceActivationStatus( - __in PMBB_SERVICE_ACTIVATION_STATUS MbbServiceActivationStatus, - __in ULONG VendorSpecificBufferSize, - __out PWWAN_SERVICE_ACTIVATION_STATUS WwanServiceActivationStatus - ) -{ - WwanServiceActivationStatus->uNwError = MbbServiceActivationStatus->NetworkError; - WwanServiceActivationStatus->uVendorSpecificBufferSize = VendorSpecificBufferSize; - - RtlCopyMemory( - WwanServiceActivationStatus + 1, - MbbServiceActivationStatus->VendorSpecificBuffer, - VendorSpecificBufferSize - ); -} - - -// SMS - -WWAN_SMS_FORMAT -MbbUtilMbbToWwanSmsFormat( - __in MBB_SMS_FORMAT MbbSmsFormat - ) -{ - switch( MbbSmsFormat ) - { - case MbbSmsFormatPdu: - return WwanSmsFormatPdu; - case MbbSmsFormatCdma: - return WwanSmsFormatCdma; - default: - return WwanSmsFormatMax; - } -} - -VOID -MbbUtilMbbToWwanSmsConfiguration( - __in PMBB_SMS_CONFIGURATION MbbSmsConfiguration, - __out PWWAN_SMS_CONFIGURATION WwanSmsConfiguration - ) -{ - NTSTATUS NtStatus; - ANSI_STRING AnsiString; - UNICODE_STRING UnicodeString; - - - AnsiString.Buffer = WwanSmsConfiguration->ScAddress; - AnsiString.MaximumLength = WWAN_SMS_ADDRESS_MAX_LEN - 1; - - UnicodeString.Buffer = (PWCHAR)(((PUCHAR)MbbSmsConfiguration) + MbbSmsConfiguration->ScAddress.Offset); - UnicodeString.Length = (USHORT)MbbSmsConfiguration->ScAddress.Size; - UnicodeString.MaximumLength = (USHORT)MbbSmsConfiguration->ScAddress.Size; - - if( (NtStatus = RtlUnicodeStringToAnsiString( - &AnsiString, - &UnicodeString, - FALSE // AllocateDestinationString - )) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_UTIL, "[MbbNdis] FAILED to convert ScAddress Length=%dbytes", MbbSmsConfiguration->ScAddress.Size ); - WwanSmsConfiguration->ScAddress[0] = 0; - } - else - { - WwanSmsConfiguration->ScAddress[AnsiString.Length] = 0; - } - - ASSERT( NtStatus == STATUS_SUCCESS ); - - WwanSmsConfiguration->SmsFormat = MbbUtilMbbToWwanSmsFormat( MbbSmsConfiguration->SmsFormat ); - WwanSmsConfiguration->ulMaxMessageIndex = MbbSmsConfiguration->MaxMessages; -} - -NDIS_STATUS -MbbUtilValidateMbbSmsPduRecord( - __in MBB_CELLULAR_CLASS CellularClass, - __in ULONG MbbSmsPduRecordSize, - __in_bcount(MbbSmsPduRecordSize) PMBB_SMS_PDU_RECORD MbbSmsPduRecord - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; - - do - { - if( MbbSmsPduRecordSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_PDU_RECORD, PduData) ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INSUFFICIENT Buffer size for MBB_SMS_PDU_RECORD, Received=%d Expected=%d", - MbbSmsPduRecordSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_PDU_RECORD, PduData) - ); - break; - } - - if( MbbIsVariableFieldValid( - MbbSmsPduRecordSize, - MbbSmsPduRecord->PduData.Offset, - MbbSmsPduRecord->PduData.Size, - (CellularClass == MbbCellularClassGsm) ? MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH : MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH, - sizeof(UCHAR) - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_PDU_RECORD.Address Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - MbbSmsPduRecord->PduData.Offset, - MbbSmsPduRecordSize, - MbbSmsPduRecord->PduData.Size, - ((CellularClass == MbbCellularClassGsm) ? MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH : MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH) * sizeof(UCHAR) - ); - break; - } - - NdisStatus = NDIS_STATUS_SUCCESS; - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilValidateMbbSmsCdmaRecord( - __in ULONG MbbSmsCdmaRecordSize, - __in_bcount(MbbSmsCdmaRecordSize) PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; - - do - { - if( MbbSmsCdmaRecordSize < RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_CDMA_RECORD, SizeInCharacters) ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INSUFFICIENT Buffer size for MBB_SMS_CDMA_RECORD, Received=%d Expected=%d", - MbbSmsCdmaRecordSize, - RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_CDMA_RECORD, SizeInCharacters) - ); - break; - } - - if( MbbIsVariableFieldValid( - MbbSmsCdmaRecordSize, - MbbSmsCdmaRecord->Address.Offset, - MbbSmsCdmaRecord->Address.Size, - MBB_MAXIMUM_SMS_ADDRESS_LENGTH, - sizeof(WCHAR) - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_CDMA_RECORD.Address Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - MbbSmsCdmaRecord->Address.Offset, - MbbSmsCdmaRecordSize, - MbbSmsCdmaRecord->Address.Size, - MBB_MAXIMUM_SMS_ADDRESS_LENGTH * sizeof(WCHAR) - ); - break; - } - - if( MbbIsVariableFieldValid( - MbbSmsCdmaRecordSize, - MbbSmsCdmaRecord->TimeStamp.Offset, - MbbSmsCdmaRecord->TimeStamp.Size, - MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH, - 1 - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_CDMA_RECORD.TimeStamp Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - MbbSmsCdmaRecord->TimeStamp.Offset, - MbbSmsCdmaRecordSize, - MbbSmsCdmaRecord->TimeStamp.Size, - MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH - ); - break; - } - - if( MbbIsVariableFieldValid( - MbbSmsCdmaRecordSize, - MbbSmsCdmaRecord->EncodedMessage.Offset, - MbbSmsCdmaRecord->EncodedMessage.Size, - MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH, - 1 - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_CDMA_RECORD.EncodedMessage Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - MbbSmsCdmaRecord->EncodedMessage.Offset, - MbbSmsCdmaRecordSize, - MbbSmsCdmaRecord->EncodedMessage.Size, - MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH - ); - break; - } - NdisStatus = NDIS_STATUS_SUCCESS; - } - while( FALSE ); - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilValidateMbbSmsReceive( - __in MBB_CELLULAR_CLASS CellularClass, - __in ULONG MbbSmsReceiveSize, - __in_bcount(MbbSmsReceiveSize) PMBB_SMS_RECEIVE MbbSmsReceive - ) -{ - ULONG ElementIndex; - ULONG ElementCount; - ULONG MbbMaxMessageSize; - NDIS_STATUS NdisStatus = NDIS_STATUS_INVALID_DATA; - ULONGLONG ExpectedSize; - - do - { - ExpectedSize = RTL_SIZEOF_THROUGH_FIELD(MBB_SMS_RECEIVE, MessageCount); - - if( MbbSmsReceive == NULL || - MbbSmsReceiveSize < ExpectedSize ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INSUFFICIENT BufferSize for MBB_SMS_RECEIVE, BufferSize[Received=%d Expected=%d]", - MbbSmsReceiveSize, - (ULONG)ExpectedSize - ); - break; - } - - ElementCount = MbbSmsReceive->MessageCount; - ExpectedSize += (ULONGLONG)ElementCount * sizeof(MBB_ARRAY_ELEMENT); - if( MbbSmsReceiveSize < ExpectedSize ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INSUFFICIENT BufferSize for MBB_SMS_RECEIVE.MessageElement[%d], BufferSize[Received=%d Expected=%I64u]", - ElementCount, - MbbSmsReceiveSize, - ExpectedSize - ); - break; - } - - if( MbbSmsReceive->SmsFormat == MbbSmsFormatPdu ) - { - - if ( CellularClass == MbbCellularClassGsm ) - { - MbbMaxMessageSize = ROUND_UP_COUNT( FIELD_OFFSET(MBB_SMS_PDU_RECORD,DataBuffer), ALIGN_DWORD ) \ - + ROUND_UP_COUNT( MBB_MAXIMUM_SMS_GSM_PDU_BUFFER_LENGTH, ALIGN_DWORD ); - } - else - { - - MbbMaxMessageSize = ROUND_UP_COUNT( FIELD_OFFSET(MBB_SMS_PDU_RECORD,DataBuffer), ALIGN_DWORD ) \ - + ROUND_UP_COUNT( MBB_MAXIMUM_SMS_CDMA_PDU_BUFFER_LENGTH, ALIGN_DWORD ); - } - } - else - { - MbbMaxMessageSize = ROUND_UP_COUNT( FIELD_OFFSET(MBB_SMS_CDMA_RECORD,DataBuffer), ALIGN_DWORD ) \ - + ROUND_UP_COUNT( (MBB_MAXIMUM_SMS_ADDRESS_LENGTH * sizeof(WCHAR)), ALIGN_DWORD ) \ - + ROUND_UP_COUNT( MBB_MAXIMUM_SMS_CDMA_TIMESTAMP_LENGTH, ALIGN_DWORD ) \ - + ROUND_UP_COUNT( MBB_MAXIMUM_SMS_CDMA_BUFFER_LENGTH, ALIGN_DWORD ); - } - - for( ElementIndex = 0; - ElementIndex < ElementCount; - ElementIndex ++ ) - { - if( MbbIsVariableFieldValid( - MbbSmsReceiveSize, - MbbSmsReceive->MessageElement[ElementIndex].Offset, - MbbSmsReceive->MessageElement[ElementIndex].Size, - MbbMaxMessageSize, - 1 - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID Offset/Size for MBB_SMS_RECEIVE.MessageElement[%d], Offset[Received=%d BufferSize=%d] Size[Received=%d MaxExpected=%d]", - ElementIndex, - MbbSmsReceive->MessageElement[ElementIndex].Offset, - MbbSmsReceiveSize, - MbbSmsReceive->MessageElement[ElementIndex].Size, - MbbMaxMessageSize - ); - break; - } - - if( MbbSmsReceive->SmsFormat == MbbSmsFormatPdu ) - { - if( MbbUtilValidateMbbSmsPduRecord( - CellularClass, - MbbSmsReceive->MessageElement[ElementIndex].Size, - (PMBB_SMS_PDU_RECORD)(((PUCHAR)MbbSmsReceive)+MbbSmsReceive->MessageElement[ElementIndex].Offset) - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_PDU_RECORD at MBB_SMS_RECEIVE.MessageElement[%d]", ElementIndex ); - break; - } - } - else - { - if( MbbUtilValidateMbbSmsCdmaRecord( - MbbSmsReceive->MessageElement[ElementIndex].Size, - (PMBB_SMS_CDMA_RECORD)(((PUCHAR)MbbSmsReceive)+MbbSmsReceive->MessageElement[ElementIndex].Offset) - ) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB_SMS_CDMA_RECORD at MBB_SMS_RECEIVE.MessageElement[%d]", ElementIndex ); - break; - } - } - } - - if( ElementIndex == ElementCount ) - NdisStatus = NDIS_STATUS_SUCCESS; - } - while( FALSE ); - - return NdisStatus; -} - -VOID -MbbUtilMbbToWwanSmsPduRecord( - __in PMBB_SMS_PDU_RECORD MbbSmsPduRecord, - __in MBB_CELLULAR_CLASS CellularClass, - __out PWWAN_SMS_PDU_RECORD WwanSmsPduRecord - ) -/*++ -Description: - For GSM-based devices, messages are hexadecimal strings that - represent messages in PDU format as defined in the - 3GPP TS 27.005 and 3GPP TS 23.040 specifications. - - For CDMA-based devices messages are byte arrays that represent - messages as defined in section 3.4.2.1 SMS Point-to-Point Message - in 3GPP2 specification C.S0015-A "Short Message Service (SMS) - for Wideband Spread Spectrum Systems". - -Assumption: - Buffer and length validation is already performed. ---*/ -{ - WwanSmsPduRecord->MessageIndex = MbbSmsPduRecord->MessageIndex; - WwanSmsPduRecord->MsgStatus = (WWAN_MSG_STATUS)MbbSmsPduRecord->MessageStatus; - // - // Although the MSDN document says that Pdu.Size should excluded the SMSC address length - // no test code or logo code handles it that way. Pdu.Size is the size of the complete PduData. - // - WwanSmsPduRecord->Size = (UCHAR)MbbSmsPduRecord->PduData.Size; - - if( CellularClass == MbbCellularClassGsm ) - { - MbbUtilByteStreamToHexString( - ((PUCHAR)MbbSmsPduRecord) + MbbSmsPduRecord->PduData.Offset, - MbbSmsPduRecord->PduData.Size, - WwanSmsPduRecord->PduData, - WWAN_SMS_PDU_HEX_BUF_LEN - ); - } - else if( CellularClass == MbbCellularClassCdma ) - { - RtlCopyMemory( - WwanSmsPduRecord->PduData, - ((PUCHAR)MbbSmsPduRecord) + MbbSmsPduRecord->PduData.Offset, - MbbSmsPduRecord->PduData.Size - ); - } -} - -VOID -MbbUtilMbbToWwanSmsCdmaRecord( - __in PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord, - __out PWWAN_SMS_CDMA_RECORD WwanSmsCdmaRecord - ) -/*++ -Assumption: - Buffer and length validation is already performed. ---*/ -{ - ULONG MinSize; - NTSTATUS NtStatus; - ANSI_STRING AnsiString; - UNICODE_STRING UnicodeString; - - RtlZeroMemory(WwanSmsCdmaRecord, sizeof(WWAN_SMS_CDMA_RECORD)); - - WwanSmsCdmaRecord->MessageIndex = MbbSmsCdmaRecord->MessageIndex; - WwanSmsCdmaRecord->MsgStatus = (WWAN_MSG_STATUS)MbbSmsCdmaRecord->MessageStatus; - WwanSmsCdmaRecord->EncodingId = (WWAN_SMS_CDMA_ENCODING)MbbSmsCdmaRecord->EncodingId; - WwanSmsCdmaRecord->LanguageId = (WWAN_SMS_CDMA_LANG)MbbSmsCdmaRecord->LanguageId; - // - // Address - // - AnsiString.Buffer = WwanSmsCdmaRecord->Address; - AnsiString.MaximumLength = WWAN_SMS_CDMA_ADDR_MAX_LEN - 1; - - UnicodeString.Buffer = (PWCHAR)(((PCHAR)MbbSmsCdmaRecord) + MbbSmsCdmaRecord->Address.Offset); - UnicodeString.Length = (USHORT)MbbSmsCdmaRecord->Address.Size; - UnicodeString.MaximumLength = (USHORT)MbbSmsCdmaRecord->Address.Size; - - if( (NtStatus = RtlUnicodeStringToAnsiString( - &AnsiString, - &UnicodeString, - FALSE // AllocateDestinationString - )) != STATUS_SUCCESS ) - { - TraceError( WMBCLASS_UTIL, "[Util][Sms] FAILED to convert MBB_SMS_CDMA_RECORD.Address Length=%dbytes", MbbSmsCdmaRecord->Address.Size ); - WwanSmsCdmaRecord->Address[0] = 0; - } - else - { - WwanSmsCdmaRecord->Address[AnsiString.Length] = 0; - } - ASSERT( NtStatus == STATUS_SUCCESS ); - // - // Timestamp - // - RtlZeroMemory( - WwanSmsCdmaRecord->ScTimeStamp, - WWAN_SMS_CDMA_TIMESTAMP_MAX_LEN - ); - RtlCopyMemory( - WwanSmsCdmaRecord->ScTimeStamp, - (((PCHAR)MbbSmsCdmaRecord) + MbbSmsCdmaRecord->TimeStamp.Offset), - MIN( MbbSmsCdmaRecord->TimeStamp.Size, WWAN_SMS_CDMA_TIMESTAMP_MAX_LEN ) - ); - // - // EncodedMessage - // - RtlCopyMemory( - WwanSmsCdmaRecord->EncodedMsg, - (((PCHAR)MbbSmsCdmaRecord) + MbbSmsCdmaRecord->EncodedMessage.Offset), - MIN( MbbSmsCdmaRecord->EncodedMessage.Size, WWAN_SMS_CDMA_MAX_BUF_LEN ) - ); - // - // If there is truncation SizeInBytes and SizeInCharacters will go out of sync - // since we dont know how to calculate SizeInCharacters. - // - WwanSmsCdmaRecord->SizeInBytes = (USHORT)MIN( MbbSmsCdmaRecord->EncodedMessage.Size, WWAN_SMS_CDMA_MAX_BUF_LEN ); - WwanSmsCdmaRecord->SizeInCharacters = (UCHAR)MbbSmsCdmaRecord->SizeInCharacters; -} - -NDIS_STATUS -MbbUtilMbbToWwanSmsReceive( - __in_bcount(MbbSmsReceiveSize) PMBB_SMS_RECEIVE MbbSmsReceive, - __in ULONG MbbSmsReceiveSize, - __in MBB_CELLULAR_CLASS CellularClass, - __out PWWAN_LIST_HEADER SmsListHeader - ) -{ - ULONG SmsIndex; - - if( MbbSmsReceive->SmsFormat == MbbSmsFormatPdu ) - { - PWWAN_SMS_PDU_RECORD WwanSmsPduRecord; - PMBB_SMS_PDU_RECORD MbbSmsPduRecord; - - if( CellularClass != MbbCellularClassGsm && - CellularClass != MbbCellularClassCdma ) - { - TraceError( WMBCLASS_UTIL, "[Util][Sms] FAILED to convert PDU record due to invalid CurrentCellularClass=%!MbbCellularClass!", - CellularClass - ); - return NDIS_STATUS_INVALID_STATE; - } - - SmsListHeader->ElementType = WwanStructSmsPdu; - - for(SmsIndex = 0; - SmsIndex < MbbSmsReceive->MessageCount; - SmsIndex ++ ) - { - MbbSmsPduRecord = (PMBB_SMS_PDU_RECORD)(((PCHAR)MbbSmsReceive) + MbbSmsReceive->MessageElement[SmsIndex].Offset); - WwanSmsPduRecord = &((PWWAN_SMS_PDU_RECORD)(SmsListHeader+1))[SmsIndex]; - - MbbUtilMbbToWwanSmsPduRecord( - MbbSmsPduRecord, - CellularClass, - WwanSmsPduRecord - ); - } - } - else if( MbbSmsReceive->SmsFormat == MbbSmsFormatCdma ) - { - PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord; - PWWAN_SMS_CDMA_RECORD WwanSmsCdmaRecord; - - SmsListHeader->ElementType = WwanStructSmsCdma; - - for(SmsIndex = 0; - SmsIndex < MbbSmsReceive->MessageCount; - SmsIndex ++ ) - { - MbbSmsCdmaRecord = (PMBB_SMS_CDMA_RECORD)(((PCHAR)MbbSmsReceive) + MbbSmsReceive->MessageElement[SmsIndex].Offset); - WwanSmsCdmaRecord = &((PWWAN_SMS_CDMA_RECORD)(SmsListHeader+1))[SmsIndex]; - - MbbUtilMbbToWwanSmsCdmaRecord( - MbbSmsCdmaRecord, - WwanSmsCdmaRecord - ); - } - } - else - { - TraceError( WMBCLASS_OID, "[Util][Sms] INVALID MBB SmsFormat=%d", MbbSmsReceive->SmsFormat ); - return NDIS_STATUS_INVALID_DATA; - } - SmsListHeader->ElementCount = MbbSmsReceive->MessageCount; - - return NDIS_STATUS_SUCCESS; -} - -VOID -MbbUtilMbbToWwanSmsStatus( - __in PMBB_SMS_STATUS MbbSmsStatus, - __out PWWAN_SMS_STATUS WwanSmsStatus - ) -{ - WwanSmsStatus->MessageIndex = MbbSmsStatus->MessageIndex; - WwanSmsStatus->uFlag = WWAN_SMS_FLAG_NONE; - - if( MbbSmsStatus->StatusFlags & MbbSmsFlagMessageStoreFull ) - WwanSmsStatus->uFlag |= WWAN_SMS_FLAG_MESSAGE_STORE_FULL; - - if( MbbSmsStatus->StatusFlags & MbbSmsFlagNewMessage ) - WwanSmsStatus->uFlag |= WWAN_SMS_FLAG_NEW_MESSAGE; -} - -VOID -MbbUtilMbbToWwanUiccFileStatus( - __in PMBB_UICC_FILE_STATUS MbbUiccFileStatus, - __out PWWAN_UICC_FILE_STATUS WwanUiccFileStatus - ) -{ - WwanUiccFileStatus->StatusWord1 = MbbUiccFileStatus->StatusWord1; - WwanUiccFileStatus->StatusWord2 = MbbUiccFileStatus->StatusWord2; - WwanUiccFileStatus->FileAccessibility = (WWAN_UICC_FILE_ACCESSIBILITY)MbbUiccFileStatus->FileAccessibility; - WwanUiccFileStatus->FileType = (WWAN_UICC_FILE_TYPE)MbbUiccFileStatus->FileType; - WwanUiccFileStatus->FileStructure = (WWAN_UICC_FILE_STRUCTURE)MbbUiccFileStatus->FileStructure; - WwanUiccFileStatus->ItemCount = MbbUiccFileStatus->ItemCount; - WwanUiccFileStatus->ItemSize = MbbUiccFileStatus->ItemSize; - - RtlCopyMemory( - WwanUiccFileStatus->FileLockStatus, - MbbUiccFileStatus->FileLockStatus, - sizeof(MbbUiccFileStatus->FileLockStatus) - ); -} - -VOID -MbbUtilMbbToWwanUiccResponse( - __in PMBB_UICC_RESPONSE MbbUiccResponse, - __out PWWAN_UICC_RESPONSE WwanUiccResponse - ) -{ - WwanUiccResponse->StatusWord1 = MbbUiccResponse->StatusWord1; - WwanUiccResponse->StatusWord2 = MbbUiccResponse->StatusWord2; - WwanUiccResponse->ResponseDataSize = (USHORT)MbbUiccResponse->ResponseData.Size; - - RtlCopyMemory( - WwanUiccResponse->ResponseData, - ((PUCHAR)MbbUiccResponse) + MbbUiccResponse->ResponseData.Offset, - MbbUiccResponse->ResponseData.Size - ); -} - -VOID -MbbUtilMbbToWwanUiccAppList( - __in PMBB_UICC_APP_LIST MbbUiccAppList, - __out PWWAN_UICC_APP_LIST WwanUiccAppList -) -{ - ULONG AppCount = MbbUiccAppList->AppCount; - ULONG AppIndex = 0; - PWWAN_UICC_APP_INFO WwanUiccAppInfo = NULL; - PMBB_UICC_APP_INFO MbbUiccAppInfo = NULL; - - WwanUiccAppList->Version = MbbUiccAppList->Version; - WwanUiccAppList->AppCount = MbbUiccAppList->AppCount; - WwanUiccAppList->ActiveAppIndex = MbbUiccAppList->ActiveAppIndex; - WwanUiccAppList->AppListSize = MbbUiccAppList->AppListSize; - - for (AppIndex = 0; AppIndex < AppCount; AppIndex++) - { - WwanUiccAppInfo = (PWWAN_UICC_APP_INFO)((PUCHAR)WwanUiccAppList - + sizeof(WWAN_UICC_APP_LIST) + sizeof(WWAN_UICC_APP_INFO) * AppIndex); - MbbUiccAppInfo = (PMBB_UICC_APP_INFO)((PUCHAR)MbbUiccAppList - + MbbUiccAppList->DataBuffer[AppIndex].Offset); - - WwanUiccAppInfo->AppType = (WWAN_UICC_APP_TYPE)MbbUiccAppInfo->AppType; - WwanUiccAppInfo->AppIdSize = (BYTE)(MbbUiccAppInfo->AppId.Size); - WwanUiccAppInfo->AppNameLength = (BYTE)(MbbUiccAppInfo->AppName.Size); - WwanUiccAppInfo->NumPins = MbbUiccAppInfo->NumPins; - RtlCopyMemory(WwanUiccAppInfo->AppId, - (PUCHAR)WwanUiccAppInfo + MbbUiccAppInfo->AppId.Offset, - MbbUiccAppInfo->AppId.Size); - RtlCopyMemory(WwanUiccAppInfo->AppName, - (PUCHAR)WwanUiccAppInfo + MbbUiccAppInfo->AppName.Offset, - MbbUiccAppInfo->AppName.Size); - RtlCopyMemory(WwanUiccAppInfo->PinRef, - (PUCHAR)WwanUiccAppInfo + MbbUiccAppInfo->PinRef.Offset, - MbbUiccAppInfo->PinRef.Size); - } -} - -VOID -MbbUtilMbbToWwanSysCapsInfo( - __in PMBB_MS_SYS_CAPS_INFO MbbSysCapsInfo, - __out PWWAN_SYS_CAPS_INFO WwanSysCapsInfo - ) -{ - WwanSysCapsInfo->NumberOfExecutors = MbbSysCapsInfo->NumberOfExecutors; - WwanSysCapsInfo->NumberOfSlots = MbbSysCapsInfo->NumberOfSlots; - WwanSysCapsInfo->Concurrency = MbbSysCapsInfo->Concurrency; - WwanSysCapsInfo->ModemID = MbbSysCapsInfo->ModemId; -} - -VOID -MbbUtilMbbToWwanDeviceSlotMappingInfo( - __in PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbDeviceSlotMappingInfo, - __out PWWAN_DEVICE_SLOT_MAPPING_INFO WwanDeviceSlotMappingInfo - ) -{ - WwanDeviceSlotMappingInfo->SlotMapListHeader.ElementType = WwanStructDeviceSlotMap; - WwanDeviceSlotMappingInfo->SlotMapListHeader.ElementCount = MbbDeviceSlotMappingInfo->MapCount; - - RtlCopyMemory((PUCHAR)WwanDeviceSlotMappingInfo + sizeof(WWAN_DEVICE_SLOT_MAPPING_INFO), - (PUCHAR)MbbDeviceSlotMappingInfo + MbbDeviceSlotMappingInfo->SlotMapList[0].Offset, - sizeof(ULONG) * MbbDeviceSlotMappingInfo->MapCount); -} - -VOID -MbbUtilMbbToWwanSlotInfo( - __in PMBB_MS_SLOT_INFO MbbSlotInfo, - __out PWWAN_SLOT_INFO WwanSlotInfo - ) -{ - WwanSlotInfo->SlotIndex = MbbSlotInfo->SlotIndex; - WwanSlotInfo->State = (WWAN_UICCSLOT_STATE)(MbbSlotInfo->State); -} - -VOID -MbbUtilMbbToWwanDeviceBindingsInfo( - __in PMBB_DEVICE_BINDINGS_INFO MbbDeviceBindingsInfo, - __out PWWAN_DEVICE_BINDINGS_INFO WwanDeviceBindingsInfo - ) -{ - ULONG AppCount = MbbDeviceBindingsInfo->ApplicationCount; - ULONG AppIndex = 0; - PWWAN_UICC_FILE_PATH WwanUiccFilePath = NULL; - PMBB_UICC_FILE_PATH MbbUiccFilePath = NULL; - - WwanDeviceBindingsInfo->ApplicationListHeader.ElementType = WwanStructUiccApplication; - WwanDeviceBindingsInfo->ApplicationListHeader.ElementCount = AppCount; - - for (AppIndex = 0; AppIndex < AppCount; AppIndex++) - { - WwanUiccFilePath = (PWWAN_UICC_FILE_PATH)((PUCHAR)WwanDeviceBindingsInfo - + sizeof(WWAN_DEVICE_BINDINGS_INFO) + sizeof(WWAN_UICC_FILE_PATH) * AppIndex); - MbbUiccFilePath = (PMBB_UICC_FILE_PATH)((PUCHAR)MbbDeviceBindingsInfo - + MbbDeviceBindingsInfo->ApplicationList[AppIndex].Offset); - - RtlZeroMemory(WwanUiccFilePath, sizeof(WWAN_UICC_FILE_PATH)); - - WwanUiccFilePath->AppIdLength = (BYTE)(MbbUiccFilePath->AppId.Size); - RtlCopyMemory(WwanUiccFilePath->AppId, - (PUCHAR)MbbUiccFilePath + MbbUiccFilePath->AppId.Offset, - MbbUiccFilePath->AppId.Size); - - // FilePath in MBB_UICC_FILE_PATH is not used for this OID/CID. - } -} - -VOID -MbbUtilMbbToWwanRegistrationStateInfoV2( - __in PMBB_REGISTRATION_STATE_INFOS_V2 MbbRegistrationStateInfosV2, - __out PWWAN_REGISTRATION_STATE_INFOS WwanRegistrationStateInfos - ) -{ - ULONG RegistrationStateCount = MbbRegistrationStateInfosV2->ElementCount; - ULONG RegistrationStateIndex = 0; - PWWAN_REGISTRATION_STATE_EX WwanRegistrationStateEx = NULL; - PMBB_REGISTRATION_STATE_V2 MbbRegistrationStateV2 = NULL; - - WwanRegistrationStateInfos->RegistrationStateListHeader.ElementType = WwanStructRegistrationState; - WwanRegistrationStateInfos->RegistrationStateListHeader.ElementCount = RegistrationStateCount; - - for (RegistrationStateIndex = 0; RegistrationStateIndex < RegistrationStateCount; RegistrationStateIndex++) - { - WwanRegistrationStateEx = (PWWAN_REGISTRATION_STATE_EX)((PUCHAR)WwanRegistrationStateInfos - + sizeof(WWAN_REGISTRATION_STATE_INFOS) + sizeof(WWAN_REGISTRATION_STATE_EX) * RegistrationStateIndex); - MbbRegistrationStateV2 = (PMBB_REGISTRATION_STATE_V2)((PUCHAR)MbbRegistrationStateInfosV2 - + MbbRegistrationStateInfosV2->RegistrationStateList[RegistrationStateIndex].Offset); - - RtlZeroMemory(WwanRegistrationStateEx, sizeof(WWAN_REGISTRATION_STATE_EX)); - - WwanRegistrationStateEx->uNwError = MbbRegistrationStateV2->NetworkError; - WwanRegistrationStateEx->RegisterState = (WWAN_REGISTER_STATE)(MbbRegistrationStateV2->RegisterState); - WwanRegistrationStateEx->RegisterMode = (WWAN_REGISTER_MODE)(MbbRegistrationStateV2->RegisterMode); - - MbbUtilPopulateStaticString(WwanRegistrationStateEx->ProviderId, MbbRegistrationStateV2, ProviderId); - MbbUtilPopulateStaticString(WwanRegistrationStateEx->ProviderName, MbbRegistrationStateV2, ProviderName); - MbbUtilPopulateStaticString(WwanRegistrationStateEx->RoamingText, MbbRegistrationStateV2, RoamingText); - - WwanRegistrationStateEx->WwanRegFlags = (DWORD)(MbbRegistrationStateV2->RegFlags); - WwanRegistrationStateEx->CurrentCellularClass = (WWAN_CELLULAR_CLASS)(MbbRegistrationStateV2->CurrentCellularClass); - WwanRegistrationStateEx->AvailableDataClasses = MbbRegistrationStateV2->AvailableDataClasses; - WwanRegistrationStateEx->VoiceSupport = MbbRegistrationStateV2->VoiceSupport; - WwanRegistrationStateEx->CurrentRATClass = MbbRegistrationStateV2->CurrentRATClass; - } -} - -VOID -MbbUtilMbbToWwanSignalStateInfoV2( - __in PMBB_SIGNAL_STATE_INFOS_V2 MbbSignalStateInfosV2, - __out PWWAN_SIGNAL_STATE_INFOS WwanSignalStateInfos - ) -{ - ULONG SignalStateCount = MbbSignalStateInfosV2->ElementCount; - ULONG SignalStateIndex = 0; - PWWAN_SIGNAL_STATE_EX WwanSignalStateEx = NULL; - PMBB_SIGNAL_STATE_V2 MbbSignalStateV2 = NULL; - - WwanSignalStateInfos->SignalStateListHeader.ElementType = WwanStructSignalState; - WwanSignalStateInfos->SignalStateListHeader.ElementCount = SignalStateCount; - - - for (SignalStateIndex = 0; SignalStateIndex < SignalStateCount; SignalStateIndex++) - { - WwanSignalStateEx = (PWWAN_SIGNAL_STATE_EX)((PUCHAR)WwanSignalStateInfos - + sizeof(WWAN_SIGNAL_STATE_INFOS) + sizeof(WWAN_SIGNAL_STATE_EX) * SignalStateIndex); - MbbSignalStateV2 = (PMBB_SIGNAL_STATE_V2)((PUCHAR)MbbSignalStateInfosV2 - + MbbSignalStateInfosV2->SignalStateList[SignalStateIndex].Offset); - - WwanSignalStateEx->Rssi = MbbSignalStateV2->Rssi; - WwanSignalStateEx->ErrorRate = MbbSignalStateV2->ErrorRate; - WwanSignalStateEx->RssiInterval = MbbSignalStateV2->RssiInterval; - WwanSignalStateEx->RssiThreshold = MbbSignalStateV2->RssiThreshold; - WwanSignalStateEx->ErrorRateThreshold = MbbSignalStateV2->ErrorRateThreshold; - WwanSignalStateEx->Snr = MbbSignalStateV2->Snr; - WwanSignalStateEx->SnrThreshold = MbbSignalStateV2->SnrThreshold; - WwanSignalStateEx->DataClass = MbbSignalStateV2->DataClass; - } -} - -VOID -MbbUtilMbbToWwanAtrInfo( - __in PMBB_ATR_INFO MbbAtrInfo, - __out PWWAN_ATR_INFO WwanAtrInfo - ) -{ - WwanAtrInfo->AtrLength = MbbAtrInfo->Atr.Size; - - RtlCopyMemory( - WwanAtrInfo->Atr, - (PUCHAR)MbbAtrInfo + MbbAtrInfo->Atr.Offset, - MbbAtrInfo->Atr.Size - ); -} - -VOID -MbbUtilMbbToWwanUiccOpenChannelInfo( - __in PMBB_UICC_OPEN_CHANNEL_INFO MbbUiccOpenChannelInfo, - __out PWWAN_UICC_OPEN_CHANNEL_INFO WwanUiccOpenChannelInfo - ) -{ - RtlCopyMemory( - WwanUiccOpenChannelInfo->Status, - MbbUiccOpenChannelInfo->Status, - WWAN_UICC_STATUS_LEN - ); - - WwanUiccOpenChannelInfo->Channel = MbbUiccOpenChannelInfo->Channel; - WwanUiccOpenChannelInfo->ResponseLength = MbbUiccOpenChannelInfo->Response.Size; - - RtlCopyMemory( - WwanUiccOpenChannelInfo->Response, - (PUCHAR)MbbUiccOpenChannelInfo + MbbUiccOpenChannelInfo->Response.Offset, - MbbUiccOpenChannelInfo->Response.Size - ); -} - -VOID -MbbUtilMbbToWwanUiccCloseChannelInfo( - __in PMBB_UICC_CLOSE_CHANNEL_INFO MbbUiccCloseChannelInfo, - __out PWWAN_UICC_CLOSE_CHANNEL_INFO WwanUiccCloseChannelInfo - ) -{ - RtlCopyMemory( - WwanUiccCloseChannelInfo->Status, - MbbUiccCloseChannelInfo->Status, - WWAN_UICC_STATUS_LEN - ); -} - -VOID -MbbUtilMbbToWwanUiccApduInfo( - __in PMBB_UICC_APDU_INFO MbbUiccApduInfo, - __out PWWAN_UICC_APDU_INFO WwanUiccApduInfo - ) -{ - RtlCopyMemory( - WwanUiccApduInfo->Status, - MbbUiccApduInfo->Status, - WWAN_UICC_STATUS_LEN - ); - - WwanUiccApduInfo->ResponseLength = MbbUiccApduInfo->Response.Size; - - RtlCopyMemory( - WwanUiccApduInfo->Response, - (PUCHAR)MbbUiccApduInfo + MbbUiccApduInfo->Response.Offset, - MbbUiccApduInfo->Response.Size - ); -} - -VOID -MbbUtilMbbToWwanUiccTerminalCapabilityInfo( - __in PMBB_UICC_TERMINAL_CAPABILITY_INFO MbbUiccTerminalCapabilityInfo, - __out PWWAN_LIST_HEADER WwanCapabilityListHeader - ) -{ - ULONG CapabilityCount = MbbUiccTerminalCapabilityInfo->ElementCount; - ULONG CapabilityIndex = 0; - - WwanCapabilityListHeader->ElementType = WwanStructUiccTerminalCapability; - WwanCapabilityListHeader->ElementCount = CapabilityCount; - - for (CapabilityIndex = 0; CapabilityIndex < CapabilityCount; CapabilityIndex++) - { - RtlCopyMemory( - (PUCHAR)WwanCapabilityListHeader + sizeof(WWAN_LIST_HEADER) + sizeof(WWAN_UICC_TERMINAL_CAPABILITY_TLV) * CapabilityIndex, - (PUCHAR)MbbUiccTerminalCapabilityInfo + MbbUiccTerminalCapabilityInfo->CapabilityList[CapabilityIndex].Offset, - sizeof(MBB_UICC_TERMINAL_CAPABILITY_TLV) - ); - } -} - -VOID -MbbUtilMbbToWwanSarConfigInfo( - _In_ PMBB_SAR_CONFIG_INFO MbbSarConfigInfo, - _Out_ PWWAN_SAR_CONFIG_INFO WwanSarConfigInfo -) -{ - ULONG count = MbbSarConfigInfo->ElementCount; - - WwanSarConfigInfo->SarMode = (WWAN_SAR_CONTROL_MODE)MbbSarConfigInfo->SarMode; - WwanSarConfigInfo->SarBackoffStatus = (WWAN_SAR_BACKOFF_STATE)MbbSarConfigInfo->SarBackoffStatus; - WwanSarConfigInfo->SarWifiIntegration = (WWAN_SAR_WIFI_HARDWARE_INTEGRATION)MbbSarConfigInfo->SarWifiIntegration; - WwanSarConfigInfo->SarConfigIndexListHeader.ElementType = WwanStructSarConfig; - WwanSarConfigInfo->SarConfigIndexListHeader.ElementCount = count; - - RtlCopyMemory( - (PBYTE)WwanSarConfigInfo + sizeof(WWAN_SAR_CONFIG_INFO), - (PBYTE)MbbSarConfigInfo + MbbSarConfigInfo->Configurations[0].Offset, - sizeof(WWAN_SAR_CONFIG_INDICES) * count - ); -} - -VOID -MbbUtilMbbToWwanTransmissionStatusInfo( - _In_ PMBB_SAR_TRANSMISSION_STATUS_INFO MbbTransmissionStatusInfo, - _Out_ PWWAN_SAR_TRANSMISSION_STATUS_INFO WwanTransmissionStatusInfo -) -{ - WwanTransmissionStatusInfo->ChannelNotification = (WWAN_SAR_TRANSMISSION_STATUS_NOTIFICATION_STATE)MbbTransmissionStatusInfo->ChannelNotification; - WwanTransmissionStatusInfo->TransmissionStatus = (WWAN_SAR_TRANSMISSION_STATUS)MbbTransmissionStatusInfo->TransmissionStatus; - WwanTransmissionStatusInfo->HysteresisTimer = MbbTransmissionStatusInfo->HysteresisTimer; -} - - -VOID -MbbUtilMbbToWwanNetworkBlackList( - __in PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist, - __out PWWAN_LIST_HEADER WwanBlacklistProviderList -) -{ - ULONG ProviderIndex; - ULONG ProviderCount = MbbNetworkBlacklist->ElementCount; - PMBB_MS_NETWORK_BLACKLIST_PROVIDER MbbProvider; - PWWAN_NETWORK_BLACKLIST_PROVIDER WwanProvider; - - WwanProvider = (PWWAN_NETWORK_BLACKLIST_PROVIDER)(WwanBlacklistProviderList + 1); - - for (ProviderIndex = 0; - ProviderIndex < ProviderCount; - ProviderIndex++) - { - MbbProvider = (PMBB_MS_NETWORK_BLACKLIST_PROVIDER)((PUCHAR)MbbNetworkBlacklist + MbbNetworkBlacklist->Contexts[ProviderIndex].Offset); - - WwanProvider[ProviderIndex].MCC = MbbProvider->MCC; - WwanProvider[ProviderIndex].MNC = MbbProvider->MNC; - WwanProvider[ProviderIndex].NetworkBlacklistType = MbbProvider->NetworkBlacklistType; - } - - WwanBlacklistProviderList->ElementType = WwanStructNetworkBlacklistProvider; - WwanBlacklistProviderList->ElementCount = ProviderCount; -} - -// -// Drain Object -// - -VOID -InitDrainObject( - PDRAIN_OBJECT DrainObject, - MBB_DRAIN_COMPLETE DrainCompleteCallback, - PVOID Context - ) -/*++ - The drain object is initialized as draining because - the first thing that will happen on miniport initialization - is the Restart handler will get called which will call - DrainComplete. DrainComplete requires that Draining is - set to TRUE and it will set Draining to FALSE starting the - queue. ---*/ -{ - RtlZeroMemory(DrainObject, sizeof(*DrainObject)); - - NdisAllocateSpinLock(&DrainObject->Lock); - DrainObject->Draining=TRUE; - DrainObject->DrainComplete=TRUE; - DrainObject->Count=0; - DrainObject->DrainCompleteCallback=DrainCompleteCallback; - DrainObject->Context=Context; -} - -VOID -StartDrain( - PDRAIN_OBJECT DrainObject - ) - -{ - BOOLEAN CallComplete=FALSE; - - NdisAcquireSpinLock(&DrainObject->Lock); - - ASSERT(!DrainObject->Draining); - - DrainObject->Draining=TRUE; - DrainObject->DrainComplete=FALSE; - - if (DrainObject->Count == 0) - { - CallComplete=TRUE; - DrainObject->DrainComplete=TRUE; - } - - NdisReleaseSpinLock(&DrainObject->Lock); - - if (CallComplete) - { - DrainObject->DrainCompleteCallback(DrainObject->Context); - } - - return; -} - -VOID -DrainComplete( - PDRAIN_OBJECT DrainObject - ) - -{ - NdisAcquireSpinLock(&DrainObject->Lock); - - ASSERT(DrainObject->Draining); - ASSERT(DrainObject->DrainComplete); - - DrainObject->Draining=FALSE; - - NdisReleaseSpinLock(&DrainObject->Lock); - -} - -BOOLEAN -DrainAddRef( - PDRAIN_OBJECT DrainObject - ) - -{ - BOOLEAN Ready=FALSE; - - NdisAcquireSpinLock(&DrainObject->Lock); - - if ( (Ready = !DrainObject->Draining) ) - { - DrainObject->Count++; - } - - NdisReleaseSpinLock(&DrainObject->Lock); - - return Ready; -} - -VOID -DrainRelease( - PDRAIN_OBJECT DrainObject - ) - -{ - BOOLEAN CallComplete=FALSE; - - NdisAcquireSpinLock(&DrainObject->Lock); - DrainObject->Count--; - if ((DrainObject->Count == 0) && DrainObject->Draining) - { - CallComplete=TRUE; - DrainObject->DrainComplete=TRUE; - } - NdisReleaseSpinLock(&DrainObject->Lock); - - if (CallComplete) - { - DrainObject->DrainCompleteCallback(DrainObject->Context); - } - - return; - - -} - -NTSTATUS -MbbEventActivityIdCtl ( - _Inout_ LPGUID ActivityId - ) -/* ++ -Routine Description: - - Creates an activity identifier - -Arguments: - - -ActivityId [in, out] - The identifier that indicates the activity associated with the event. The ActivityId - parameter provides a way to group related events and is used in end-to-end tracing. - -Return Value: - - STATUS_SUCCESS or an appropriate NTSTATUS value. - */ -{ - - if(ActivityId == NULL) - { - return STATUS_INVALID_PARAMETER; - } - - return EtwActivityIdControl(EVENT_ACTIVITY_CTRL_CREATE_ID, ActivityId); -} - -VOID -MbbWriteEvent ( - IN PCEVENT_DESCRIPTOR EventDescriptor, - IN LPGUID ActivityId OPTIONAL, - IN LPGUID RelatedActivityId OPTIONAL, - IN USHORT ArgCount, - ... - ) - -/*++ - -Routine Description: - - Writes an ETW event. - -Arguments: - - EventDescriptor - Supplies the event descriptor. - - ActivityId - Supplies the activity GUID to be associated with this event. - - ArgCount - Supplies the number of elements in the variable list. - - ... - Supplies the variable list of event data to write. - -Return Value: - - None. - ---*/ - -{ - va_list Arguments; - - va_start(Arguments, ArgCount); - - MbbWriteEventCommon( - GlobalControl.TraceHandle, - EventDescriptor, - ActivityId, - RelatedActivityId, - ArgCount, - Arguments - ); - - va_end(Arguments); - - return; -} - -VOID -MbbWriteEventOpn ( - IN PCEVENT_DESCRIPTOR EventDescriptor, - IN LPGUID ActivityId OPTIONAL, - IN LPGUID RelatedActivityId OPTIONAL, - IN USHORT ArgCount, - ... - ) - -/*++ - -Routine Description: - - Writes an ETW event for OPN. - -Arguments: - - EventDescriptor - Supplies the event descriptor. - - ActivityId - Supplies the activity GUID to be associated with this event. - - ArgCount - Supplies the number of elements in the variable list. - - ... - Supplies the variable list of event data to write. - -Return Value: - - None. - ---*/ - -{ - va_list Arguments; - - va_start(Arguments, ArgCount); - - MbbWriteEventCommon( - GlobalControl.TraceHandleOpn, - EventDescriptor, - ActivityId, - RelatedActivityId, - ArgCount, - Arguments - ); - - va_end(Arguments); - - return; -} - -VOID -MbbWriteEventCommon ( - IN REGHANDLE TraceHandle, - IN PCEVENT_DESCRIPTOR EventDescriptor, - IN LPGUID ActivityId OPTIONAL, - IN LPGUID RelatedActivityId OPTIONAL, - IN USHORT ArgCount, - IN va_list Arguments - ) - -/*++ - -Routine Description: - - Writes an ETW event. - -Arguments: - - TraceHandle - Supplies the trace handle. - - EventDescriptor - Supplies the event descriptor. - - ActivityId - Supplies the activity GUID to be associated with this event. - - ArgCount - Supplies the number of elements in the variable list. - - Arguments - Supplies the variable list of event data to write. - -Return Value: - - None. - ---*/ - -{ - - EVENT_DATA_DESCRIPTOR EventData[WMBCLASS_MAX_EVENT_DATA_DESCRIPTORS]; - PEVENT_DATA_DESCRIPTOR DataDescriptors; - ULONG EventDataCount = 0; - ULONG Length; - PVOID Source; - - if (TraceHandle == 0) - { - return; - } - - if (ArgCount > MAX_EVENT_DATA_DESCRIPTORS) { - return; - } - - if (ArgCount <= WMBCLASS_MAX_EVENT_DATA_DESCRIPTORS) { - DataDescriptors = &EventData[0]; - - } else { -#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "By Design: Allocate new data descriptors, release when ETW write finishes.") - DataDescriptors = ALLOCATE_NONPAGED_POOL(sizeof(EVENT_DATA_DESCRIPTOR) * ArgCount); - - if (!DataDescriptors) { - return; - } - } - - // - // Build up the event data descriptors. - // - - while (EventDataCount < ArgCount) { - Source = va_arg(Arguments, PVOID); - Length = va_arg(Arguments, ULONG); - - // - // EtwWrite expects that if Size > 0 then Ptr != NULL. - // Passing a null pointer with Size > 0 causes it to enter a critical - // region and then throw an exception without exiting the critical - // region. This makes driver verifier bugcheck because of a mismatched - // APC Disable count on the thread (even if the exception has been - // catched). - // - NT_ASSERT(Length == 0 || Source != NULL); - - DataDescriptors[EventDataCount].Ptr = (ULONGLONG)Source; - DataDescriptors[EventDataCount].Size = Length; - - EventDataCount++; - } - - // - // Write all the event data. - // - - if (RelatedActivityId == NULL) { - - EtwWrite(TraceHandle, - EventDescriptor, - ActivityId, - EventDataCount, - DataDescriptors); - } else { - - EtwWriteTransfer(TraceHandle, - EventDescriptor, - ActivityId, - RelatedActivityId, - EventDataCount, - DataDescriptors); - } - - if (DataDescriptors != &EventData[0]) { - - NT_ASSERT(DataDescriptors != NULL); - FREE_POOL(DataDescriptors); - } - - return; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetUSSD( - __out PMBB_SET_USSD MbbSetUSSD, - __in PWWAN_USSD_REQUEST WWanUSSDRequest -) -{ - NTSTATUS ntStatus; - // - // Convert WWAN -> MBB - // - if(WWanUSSDRequest->RequestType == WwanUssdRequestInitiate){ - MbbSetUSSD->USSDAction = MbbUSSDInitiate; - } - else if (WWanUSSDRequest->RequestType == WwanUssdRequestContinue){ - MbbSetUSSD->USSDAction = MbbUSSDContinue; - } - else if(WWanUSSDRequest->RequestType == WwanUssdRequestCancel) { - MbbSetUSSD->USSDAction = MbbUSSDCancel; - } - else { - TraceError( WMBCLASS_OID, "[Util][USSD] INVALID USSD Requestt Type from client =%d", WWanUSSDRequest->RequestType ); - return NDIS_STATUS_INVALID_PARAMETER; - } - - MbbSetUSSD->USSDDataCodingScheme = WWanUSSDRequest->UssdString.DataCodingScheme; - MbbSetUSSD->USSDPayload.Size = WWanUSSDRequest->UssdString.StringLength;//bytes - MbbSetUSSD->USSDPayload.Offset = FIELD_OFFSET(MBB_SET_USSD, DataBuffer); - - RtlCopyMemory(MbbSetUSSD->DataBuffer, - WWanUSSDRequest->UssdString.String, - MbbSetUSSD->USSDPayload.Size); - - return NDIS_STATUS_SUCCESS; - -} - -NDIS_STATUS -MbbUtilMbbToWwanUSSDEvent( - __in PMBB_USSD MbbUSSD, - __out PWWAN_USSD_EVENT WWanUSSDEvt - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - if ( MbbUSSD->USSDResponse == MbbUSSDNoActionRequired){ - WWanUSSDEvt->EventType= WwanUssdEventNoActionRequired; - } - else if (MbbUSSD->USSDResponse == MbbUSSDActionRequired){ - WWanUSSDEvt->EventType = WwanUssdEventActionRequired; - } - else if (MbbUSSD->USSDResponse == MbbUSSDTerminated){ - WWanUSSDEvt->EventType = WwanUssdEventTerminated; - } - else if (MbbUSSD->USSDResponse == MbbUSSDOtherLocalClient){ - WWanUSSDEvt->EventType = WwanUssdEventOtherLocalClient; - } - else if (MbbUSSD->USSDResponse == MbbUSSDOperationNotSupported){ - WWanUSSDEvt->EventType = WwanUssdEventOperationNotSupported; - } - else if (MbbUSSD->USSDResponse == MbbUSSDNetworkTimeOut){ - WWanUSSDEvt->EventType = WwanUssdEventNetworkTimeOut; - } - else{ - // - // Todo: no invalid status code in WWAN_USSD_RESPONSE, should probably define one. - // - // - // Device/network is returning invalid data. - // - TraceError( WMBCLASS_OID, "[Util][USSD] INVALID USSD Response from device =%d", MbbUSSD->USSDResponse ); - return NDIS_STATUS_INVALID_DATA; - } - - WWanUSSDEvt->UssdString.DataCodingScheme = (BYTE)MbbUSSD->USSDDataCodingScheme; - - if (MbbUSSD->USSDSessionState == MbbUSSDNewSession){ - WWanUSSDEvt->SessionState = WwanUssdSessionStateNew; - } - else if (MbbUSSD->USSDSessionState == MbbUSSDExistingSession){ - WWanUSSDEvt->SessionState = WwanUssdSessionStateExisting; - } - else - { - // - // Todo: no invalid status code in WWAN_USSD_RESPONSE, should probably define one. - // - // - // Device/network is returning invalid data. - // - TraceError( WMBCLASS_OID, "[Util][USSD] INVALID USSD Response.SessionState from device =%d", MbbUSSD->USSDSessionState ); - return NDIS_STATUS_INVALID_DATA; - } - - WWanUSSDEvt->UssdString.StringLength = 0; - - if (MbbUSSD->USSDPayload.Size > MBB_USSD_STRING_LEN_MAX) - { - // - // Device/network is returning invalid data. - // - TraceError( WMBCLASS_OID, "[Util][USSD] INVALID USSD Response from device =%d", MbbUSSD->USSDPayload.Size ); - NdisStatus = NDIS_STATUS_INVALID_DATA; - - } - else - { - WWanUSSDEvt->UssdString.StringLength = (BYTE)MbbUSSD->USSDPayload.Size; - - RtlCopyMemory(WWanUSSDEvt->UssdString.String, - MbbUSSD->DataBuffer, - MbbUSSD->USSDPayload.Size - ); - } - - return NdisStatus; - -} - - -ULONG -MbbUtilWriteStringToBuffer( - __in_ecount(BufferSize) PUCHAR Start, - __in ULONG BufferSize, - __in ULONG CurrentOffset, - __in PMBB_STRING StringDesc, - __in_ecount(SourceLength) PCUCHAR SourceString, - __in ULONG SourceLength - ) - -{ - - CurrentOffset= ROUND_UP_COUNT(CurrentOffset, ALIGN_DWORD); - - // - // Only copy if the buffer is not overflown. - // - if( ((ULONGLONG)CurrentOffset) + SourceLength <= BufferSize ) - { - StringDesc->Offset=0; - StringDesc->Size=SourceLength; - - if (StringDesc->Size > 0) - { - // - // only set this if the size is non zero. otherwise offset and size are both zero. - StringDesc->Offset=CurrentOffset; - - RtlCopyMemory(&Start[CurrentOffset], SourceString, SourceLength); - - CurrentOffset= ROUND_UP_COUNT(CurrentOffset+SourceLength, ALIGN_DWORD); - - } - } - else - { - ASSERT(((ULONGLONG)CurrentOffset) + SourceLength <= BufferSize); - DbgBreakPoint(); - } - return CurrentOffset; - -} - -BOOLEAN -MbbUtilIsNativeMbnService( - __in GUID* DeviceServiceGuid - ) -{ - ULONG i = 0; - - for (i = 0; i < ARRAYSIZE(NativeMbnServices); i++) - { - if (RtlCompareMemory(&NativeMbnServices[i], DeviceServiceGuid, sizeof(GUID)) - == sizeof(GUID)) - { - // Matching ID - return TRUE; - } - } - - return FALSE; -} - -PMBB_DS -MbbUtilFindDeviceService( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in GUID* DeviceServiceGuid - ) -{ - ULONG i = 0; - - for (i = 0; i < Adapter->DeviceServiceState.ServicesCount; i++) - { - if (RtlCompareMemory(&(Adapter->DeviceServiceState.ServicesList[i].DeviceServiceId), DeviceServiceGuid, sizeof(GUID)) - == sizeof(GUID)) - { - // Matching ID - return &(Adapter->DeviceServiceState.ServicesList[i]); - } - } - - return NULL; -} - -_Requires_lock_not_held_(&Port->Lock) -NDIS_STATUS -MbbUtilAddNoMatchFilter( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_PORT Port - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PUCHAR PatternBuffer = NULL; - ULONG PatternSize = MBB_NO_MATCH_WOL_PATTERN_SIZE; - ULONG TotalPatternLength = 0; - ULONG MaskSize = 0; - ULONG PatternNameSize = 0; - RTL_BITMAP BitMap; - PNDIS_PM_WOL_PATTERN NoMatchWolPattern = NULL; - NDIS_PM_COUNTED_STRING PatternFriendlyName = {0}; - NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; - - struct _WOL_BITMAP_PATTERN *WoLBitMapPattern = NULL; - - if(!Port ) - { - return NDIS_STATUS_INVALID_PARAMETER; - } - - // - // First, round up to an integral multiple of the number of bits in ULONG. - // Then, determine the number of bytes required to store the bit-mask. - // - - MaskSize = (((PatternSize + RTL_BITS_OF(ULONG) - 1) & ~(RTL_BITS_OF(ULONG) - 1))/ RTL_BITS_OF(UCHAR)); - - TotalPatternLength = sizeof(NDIS_PM_WOL_PATTERN) + PatternSize + MaskSize; - - PatternBuffer = ALLOCATE_NONPAGED_POOL(TotalPatternLength); - - if(PatternBuffer == NULL) - { - Status = NDIS_STATUS_RESOURCES; - goto Cleanup; - } - - NdisZeroMemory(PatternBuffer, TotalPatternLength); - - NoMatchWolPattern = (PNDIS_PM_WOL_PATTERN) PatternBuffer; - WoLBitMapPattern = &NoMatchWolPattern->WoLPattern.WoLBitMapPattern; - - NoMatchWolPattern->Header.Revision = NDIS_PM_WOL_PATTERN_REVISION_2; - NoMatchWolPattern->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; - NoMatchWolPattern->Header.Size = NDIS_SIZEOF_NDIS_PM_WOL_PATTERN_REVISION_2; - NoMatchWolPattern->WoLPacketType = NdisPMWoLPacketBitmapPattern; - NoMatchWolPattern->Priority = NDIS_PM_WOL_PRIORITY_NORMAL; - NoMatchWolPattern->PatternId = MBB_NO_MATCH_WOL_PATTERN_ID; // invalid pattern Id - - WoLBitMapPattern->MaskOffset = sizeof(NDIS_PM_WOL_PATTERN); - WoLBitMapPattern->MaskSize = MaskSize; - WoLBitMapPattern->PatternOffset = sizeof(NDIS_PM_WOL_PATTERN) + MaskSize; - WoLBitMapPattern->PatternSize = PatternSize; - - RtlInitializeBitMap( - &BitMap, - (PULONG) (PatternBuffer + sizeof(NDIS_PM_WOL_PATTERN)), - MaskSize * RTL_BITS_OF(UCHAR)); - - //set the first bit of the mask - RtlSetBits(&BitMap, 0, 1); - - MBB_ACQUIRE_PORT_LOCK(Port); - PortNumber = Port->PortNumber; - MBB_RELEASE_PORT_LOCK(Port); - - // Add the no-match filter - - Status = MbbUtilSetPowerFilterPattern( - Adapter, - PortNumber, - NoMatchWolPattern->PatternId, - PatternBuffer + NoMatchWolPattern->WoLPattern.WoLBitMapPattern.MaskOffset, - NoMatchWolPattern->WoLPattern.WoLBitMapPattern.MaskSize, - PatternBuffer + NoMatchWolPattern->WoLPattern.WoLBitMapPattern.PatternOffset, - NoMatchWolPattern->WoLPattern.WoLBitMapPattern.PatternSize - ); - - if(Status == NDIS_STATUS_SUCCESS) - { - MBB_ACQUIRE_PORT_LOCK(Port); - Port->HasNoMatchWolPattern = TRUE; - MBB_RELEASE_PORT_LOCK(Port); - } - - -Cleanup: - - if(PatternBuffer) - { - FREE_POOL(PatternBuffer); - PatternBuffer = NULL; - } - - if(Status == NDIS_STATUS_SUCCESS) - { - TraceInfo( WMBCLASS_OID, "[Util] Successfully added a no-match filter to adapter powerfilter table for connected port %lu", PortNumber); - } - else - { - TraceError( WMBCLASS_OID, "[Util] Failed to add no-match filter to adapter powerfilter table for connected port %lu. Status = %!status!", PortNumber, Status); - } - - return Status; -} - - -_Requires_lock_not_held_(&Port->Lock) -NTSTATUS -MbbUtilRemoveNoMatchFilter( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_PORT Port - ) -{ - // Clear all the no-match patterns for this port number, if any if this is a valid - // pattern. Doing this will free up the slots in the adapter filter table - // as it doesnt make sense to have a No-match WOL pattern and - // a valid WOL pattern set for a session Id. - - NTSTATUS Status = STATUS_SUCCESS; - BOOLEAN fHasNoMatchWolPattern = FALSE; - NDIS_PORT_NUMBER PortNumber = NDIS_DEFAULT_PORT_NUMBER; - - if(!Port ) - { - Status = STATUS_INVALID_PARAMETER; - goto Cleanup; - } - - MBB_ACQUIRE_PORT_LOCK(Port); - PortNumber = Port->PortNumber; - fHasNoMatchWolPattern = Port->HasNoMatchWolPattern; - MBB_RELEASE_PORT_LOCK(Port); - - if(fHasNoMatchWolPattern) - { - Status = MbbUtilSetPowerFilterPattern( - Adapter, - PortNumber, - MBB_NO_MATCH_WOL_PATTERN_ID, - NULL, - 0, - NULL, - 0 - ); - - if(NT_SUCCESS(Status)) - { - MBB_ACQUIRE_PORT_LOCK(Port); - Port->HasNoMatchWolPattern = FALSE; - MBB_RELEASE_PORT_LOCK(Port); - - TraceInfo( WMBCLASS_OID, "[Util] Successfully cleared the no-match WOL pattern for connected port %lu from the adapter power filter table", PortNumber); - } - } - - Cleanup: - - if(!NT_SUCCESS(Status)) - { - TraceError( WMBCLASS_OID, "[Util] Failed to clear the no-match WOL pattern for connected port %lu from the adapter power filter table. Status = %!status!", PortNumber, Status); - } - - return Status; -} - -VOID -MbbUtilClearPowerFilterAtIndex( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in ULONG Index - ) -{ - Adapter->PowerFilterTable[Index].InUse=FALSE; - Adapter->PowerFilterTable[Index].PortNumber = MBB_INVALID_PORT_NUMBER; - Adapter->PowerFilterTable[Index].PatternId=0; - - if(Adapter->PowerFilterTable[Index].Mask != NULL) - { - FREE_POOL(Adapter->PowerFilterTable[Index].Mask); - Adapter->PowerFilterTable[Index].Mask=NULL; - } - - if(Adapter->PowerFilterTable[Index].Pattern !=NULL) - { - FREE_POOL(Adapter->PowerFilterTable[Index].Pattern); - Adapter->PowerFilterTable[Index].Pattern=NULL; - } -} - - -NTSTATUS -MbbUtilSetPowerFilterPattern( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in NDIS_PORT_NUMBER PortNumber, - __in ULONG PatternId, - __in_bcount_opt(MaskSize) PCUCHAR Mask, - __in ULONG MaskSize, - __in_bcount_opt(PatternSize) PCUCHAR Pattern, - __in ULONG PatternSize - ) -{ - ULONG i=0; - ULONG Index=0; - ULONG j=0; - ULONG k=0; - ULONG NcmPatternSize=0; - NTSTATUS Status=STATUS_SUCCESS; - PUCHAR NcmPattern=NULL; - PUCHAR NcmMask=NULL; - UCHAR LastMaskByte; - - if (MaskSize > 0xffff) - { - // - // NCM only has a ushort for mask count - // - Status= STATUS_INVALID_PARAMETER; - goto Cleanup; - } - - if (MaskSize == 0) - { - // - // this means the caller wants to clear and existing mask - // - - for (i=0; iBusParams.PowerFiltersSupported; i++) - { - if (Adapter->PowerFilterTable[i].InUse - && (Adapter->PowerFilterTable[i].PatternId == PatternId) - && Adapter->PowerFilterTable[i].PortNumber == PortNumber) // same pattern may be plumbed for multiple port numbers - { - break; - } - } - - if (i < Adapter->BusParams.PowerFiltersSupported) - { - MbbUtilClearPowerFilterAtIndex(Adapter, i); - } - else - { - // - // mask not found - // - TraceError( WMBCLASS_OID, "[Util] power filter id not found =%d", PatternId ); - - Status= STATUS_INVALID_PARAMETER; - - ASSERT(0); - - goto Cleanup; - } - } - else - { - // Get the next available slot in adapter power filter table - for (i = 0; i < Adapter->BusParams.PowerFiltersSupported; i++) - { - if (!Adapter->PowerFilterTable[i].InUse) - { - break; - } - } - - if (i == Adapter->BusParams.PowerFiltersSupported) - { - // this means all the slots in the adapter power filter table - // are used and we cannot plumb any more wake patterns - - TraceError( WMBCLASS_OID, "[Util] max wake patterns already plumbed. Returning"); - - Status= STATUS_INVALID_PARAMETER; - - goto Cleanup; - } - - - NcmMask=ALLOCATE_NONPAGED_POOL(PatternSize); - - if (NcmMask == NULL) - { - TraceError( WMBCLASS_OID, "[Util] MbbUtilSetPowerFilterPattern failed to allocate memory for NcmMask"); - - Status=STATUS_NO_MEMORY; - - goto Cleanup; - } - - RtlZeroMemory(NcmMask, PatternSize); - - - NcmPattern=ALLOCATE_NONPAGED_POOL(PatternSize); - - if (NcmPattern == NULL) - { - TraceError( WMBCLASS_OID, "[Util] MbbUtilSetPowerFilterPattern failed to allocate memory for NcmPattern"); - - Status=STATUS_NO_MEMORY; - - goto Cleanup; - } - - // - // translate the mask bit to mask bytes - // - for (k=0; kPowerFilterTable[i].InUse = TRUE; - Adapter->PowerFilterTable[i].PortNumber = PortNumber; - Adapter->PowerFilterTable[i].PatternId = PatternId; - Adapter->PowerFilterTable[i].MaskSize = PatternSize; - - Adapter->PowerFilterTable[i].Mask=NcmMask; - NcmMask=NULL; - - Adapter->PowerFilterTable[i].Pattern=NcmPattern; - NcmPattern=NULL; - } - -Cleanup: - - if (NcmMask != NULL) - { - FREE_POOL(NcmMask); - NcmMask=NULL; - } - - if (NcmPattern != NULL) - { - FREE_POOL(NcmPattern); - NcmPattern=NULL; - } - - return Status; -} - -NDIS_STATUS -MbbUtilWwanToMbbSetPacketFilter( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN Set, - __in NDIS_PORT_NUMBER PortNumber, - __out PMBB_PACKET_FILTERS *ReturnedMbbPacketFilters, - __out ULONG *ReturnedBufferSize - ) -{ - PUCHAR Buffer; - ULONG CurrentOffset; - ULONG LocalOffset; - ULONG BufferSize; - PMBB_PACKET_FILTERS MbbPacketFilters=NULL; - PMBB_SINGLE_PACKET_FILTER MbbSinglePacketFilter=NULL; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - ULONG FiltersInUse=0; - ULONG i=0; - ULONG CurrentFilter=0; - PMBB_PORT Port = NULL; - ULONG SessionId = MBB_INVALID_SESSION_ID; - - *ReturnedBufferSize=0; - *ReturnedMbbPacketFilters=NULL; - - BufferSize= ROUND_UP_COUNT(FIELD_OFFSET(MBB_PACKET_FILTERS, ArrayElement), ALIGN_DWORD); - - do - { - // Check if the port number corresponds to an active session - // Find the port corresponding to the port number - Port = MbbWwanTranslatePortNumberToPort(Adapter, PortNumber); - - if(!Port) - { - TraceError( WMBCLASS_POWER, "MbbUtilWwanToMbbSetPacketFilter: Invalid port number %lu", PortNumber); - Status = NDIS_STATUS_INVALID_PORT; - break; - } - - MBB_ACQUIRE_PORT_LOCK(Port); - - if( Port->ConnectionState.ConnectionUp) - { - SessionId = Port->SessionId; - TraceInfo( WMBCLASS_POWER, "MbbUtilWwanToMbbSetPacketFilter: Read the port session id as %d",SessionId); - } - else - { - Status = NDIS_STATUS_INVALID_PARAMETER; - TraceError( WMBCLASS_POWER, "MbbUtilWwanToMbbSetPacketFilter: Port %lu is not connected", PortNumber); - MBB_RELEASE_PORT_LOCK(Port); - break; - } - - MBB_RELEASE_PORT_LOCK(Port); - - if(SessionId == MBB_INVALID_SESSION_ID) - { - Status = NDIS_STATUS_INVALID_PARAMETER; - TraceError( WMBCLASS_POWER, "MbbUtilWwanToMbbSetPacketFilter: Invalid session Id %d", SessionId); - break; - } - - if (Set) - { - for (i=0; iBusParams.PowerFiltersSupported; i++) - { - if (Adapter->PowerFilterTable[i].InUse - && PortNumber == Adapter->PowerFilterTable[i].PortNumber) - { - FiltersInUse++; - - // - // array elemet header - // - BufferSize += ROUND_UP_COUNT(sizeof(MBB_SINGLE_PACKET_FILTER), ALIGN_DWORD); - - BufferSize += ROUND_UP_COUNT(FIELD_OFFSET(MBB_SINGLE_PACKET_FILTER,DataBuffer), ALIGN_DWORD); - - BufferSize += ROUND_UP_COUNT(Adapter->PowerFilterTable[i].MaskSize, ALIGN_DWORD); - BufferSize += ROUND_UP_COUNT(Adapter->PowerFilterTable[i].MaskSize, ALIGN_DWORD); - } - } - } - - - MbbPacketFilters = ALLOCATE_NONPAGED_POOL( BufferSize ); - - if ( MbbPacketFilters == NULL ) - { - Status = NDIS_STATUS_RESOURCES; - break; - } - - Buffer=(PUCHAR)MbbPacketFilters; - - MbbPacketFilters->SessionId = SessionId; - MbbPacketFilters->PacketFiltersCount=FiltersInUse; - - // - // start the current offset after the array elements - // - CurrentOffset = FIELD_OFFSET( MBB_PACKET_FILTERS, ArrayElement ) + (sizeof(MbbPacketFilters->ArrayElement[0]) * FiltersInUse); - - if (FiltersInUse > 0) - { - for (i=0; iBusParams.PowerFiltersSupported; i++) - { - if (Adapter->PowerFilterTable[i].InUse - && PortNumber == Adapter->PowerFilterTable[i].PortNumber) - { - MbbPacketFilters->ArrayElement[CurrentFilter].Offset=CurrentOffset; - - MbbSinglePacketFilter=(PMBB_SINGLE_PACKET_FILTER)&Buffer[CurrentOffset]; - - LocalOffset=FIELD_OFFSET( MBB_SINGLE_PACKET_FILTER, DataBuffer ); - - - MbbSinglePacketFilter->FilterSize=Adapter->PowerFilterTable[i].MaskSize; - MbbSinglePacketFilter->PacketFilterOffset=LocalOffset; - - RtlCopyMemory(&Buffer[CurrentOffset+LocalOffset],Adapter->PowerFilterTable[i].Pattern, Adapter->PowerFilterTable[i].MaskSize); - - LocalOffset += ROUND_UP_COUNT(Adapter->PowerFilterTable[i].MaskSize, ALIGN_DWORD); - - MbbSinglePacketFilter->PacketMaskOffset=LocalOffset; - - RtlCopyMemory(&Buffer[CurrentOffset+LocalOffset],Adapter->PowerFilterTable[i].Mask, Adapter->PowerFilterTable[i].MaskSize); - - LocalOffset += ROUND_UP_COUNT(Adapter->PowerFilterTable[i].MaskSize, ALIGN_DWORD); - - CurrentOffset+=LocalOffset; - - MbbPacketFilters->ArrayElement[CurrentFilter].Size=LocalOffset; - - CurrentFilter++; - - } - } - } - - *ReturnedBufferSize=BufferSize; - *ReturnedMbbPacketFilters=MbbPacketFilters; - }while(FALSE); - - if(Status != NDIS_STATUS_SUCCESS) - { - if(MbbPacketFilters != NULL) - { - FREE_POOL(MbbPacketFilters); - MbbPacketFilters = NULL; - } - } - - if(Port) - { - // Remove the reference added during find - Dereference(Port); - } - - return Status; -} - -WWAN_STATUS -MbbUtilNdisToWwanStatus( - __in NDIS_STATUS NdisStatus - ) -{ - switch( NdisStatus ) - { - case NDIS_STATUS_SUCCESS: - return WWAN_STATUS_SUCCESS; - case NDIS_STATUS_PENDING: - return WWAN_STATUS_SUCCESS; - default: - return WWAN_STATUS_FAILURE; - } -} - -VOID -MbbUtilNdisMiniportIndicateStatusEx( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PNDIS_STATUS_INDICATION StatusIndication - ) -{ - MbbWriteEvent( - &NDIS_STATUS_INDICATION_EVENT, - NULL, - NULL, - 5, - &Adapter->TraceInstance, - sizeof(Adapter->TraceInstance), - &StatusIndication->StatusCode, - sizeof(StatusIndication->StatusCode), - &StatusIndication->RequestId, - sizeof(StatusIndication->RequestId), - &StatusIndication->DestinationHandle, - sizeof(StatusIndication->DestinationHandle), - &StatusIndication->StatusBufferSize, - sizeof(StatusIndication->StatusBufferSize) - ); - - NdisMIndicateStatusEx( - Adapter->MiniportAdapterHandle, - StatusIndication - ); - - return; -} - - -NDIS_STATUS -MbbUtilWwanToMbbGetVisible( - __in PWWAN_GET_VISIBLE_PROVIDERS WwanVisibleProviders, - __out PMBB_GET_VISIBLE_PROVIDERS MbbVisibleProviders - ) -{ - MbbVisibleProviders->Action = WwanVisibleProviders->Action; - - if( MbbVisibleProviders->Action >= MbbVisibleProvidersActionMax ) - return NDIS_STATUS_INVALID_DATA; - else - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS -MbbUtilWwanAssignMacAddress( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ NDIS_WWAN_MAC_ADDRESS macAddress - ) -{ - NDIS_STATUS Status = NDIS_STATUS_FAILURE; - BOOLEAN found = FALSE; - ULONG addressId = 1; - ULONG i = 0; - UCHAR macAddress0; - ULONG maxActivatedContexts = 0; - - /* - * Define the scheme that we select MAC address. - * The very first MAC will just use the MAC address from the EEPROM. - * For the rest we set the U/L bit (bit 1) in MAC address and iterate till - * we find a unique MAC address. - */ - MbbAdapterPortsLock(Adapter); - maxActivatedContexts = Adapter->MaxActivatedContexts; - MbbAdapterPortsUnlock(Adapter); - - for(addressId = 1; addressId < maxActivatedContexts; addressId++) - { - found = FALSE; - - macAddress0 = (UCHAR)(((addressId)<<2)|0x02); - - // check if this unique. Since we only altering the first byte of the - // mac address we need to compare with only first byte of the mac - // address of the ports - - MbbAdapterPortsLock(Adapter); - - for(i = 0; i < Adapter->NumberOfPorts; i++) - { - if(NdisEqualMemory(&(Adapter->PortList[i]->MACAddress[0]),&macAddress0,sizeof(UCHAR))) - { - found = TRUE; - break; - } - } - - MbbAdapterPortsUnlock(Adapter); - - if(!found) - { - macAddress[0] = macAddress0; - Status = NDIS_STATUS_SUCCESS; - break; - } - } - - - return Status; -} - -NDIS_STATUS -MbbUtilProcessSetConnectState( - __in PMBB_REQUEST_CONTEXT Request, - __in PWWAN_SET_CONTEXT_STATE SetContextState, - __in ULONG SessionId - ) -{ - ULONG MbbSetContextStateSize; - ULONG AccessStringCchLength; - ULONG UserNameCchLength; - ULONG PasswordCchLength; - SIZE_T StringCchLength; - NDIS_STATUS NdisStatus; - PMBB_CONTEXT_STATE MbbContextState; - PMBB_SET_CONTEXT_STATE MbbSetContextState; - - do - { - if(!SetContextState) - { - NdisStatus = NDIS_STATUS_FAILURE; - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] MbbUtilProcessSetConnectState: SetContextState is NULL parameter",Request->RequestId); - break; - } - - // - // Determine the length of the strings - // - NdisStatus = RtlStringCchLengthW( - SetContextState->AccessString, - WWAN_ACCESSSTRING_LEN, - &StringCchLength - ); - if( NT_ERROR( NdisStatus ) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to get strlen for AccessString, Status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - AccessStringCchLength = (ULONG)StringCchLength; - - NdisStatus = RtlStringCchLengthW( - SetContextState->UserName, - WWAN_USERNAME_LEN, - &StringCchLength - ); - if( NT_ERROR( NdisStatus ) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to get strlen for UserName, Status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - UserNameCchLength = (ULONG)StringCchLength; - - NdisStatus = RtlStringCchLengthW( - SetContextState->Password, - WWAN_PASSWORD_LEN, - &StringCchLength - ); - if( NT_ERROR( NdisStatus ) ) - { - TraceError( WMBCLASS_OID, "[MbbNdis][ReqID=0x%04x] FAILED to get strlen for Password, Status=%!STATUS!", - Request->RequestId, - NdisStatus - ); - break; - } - PasswordCchLength = (ULONG)StringCchLength; - - MbbSetContextStateSize = FIELD_OFFSET(MBB_SET_CONTEXT_STATE, DataBuffer); - MbbSetContextStateSize = ROUND_UP_COUNT( MbbSetContextStateSize, ALIGN_DWORD ); - MbbSetContextStateSize += MIN(AccessStringCchLength,MBB_MAXIMUM_ACCESS_STRING_LENGTH) * sizeof(WCHAR); - MbbSetContextStateSize = ROUND_UP_COUNT( MbbSetContextStateSize, ALIGN_DWORD ); - MbbSetContextStateSize += MIN(UserNameCchLength,MBB_MAXIMUM_USERNAME_LENGTH) * sizeof(WCHAR); - MbbSetContextStateSize = ROUND_UP_COUNT( MbbSetContextStateSize, ALIGN_DWORD ); - MbbSetContextStateSize += MIN(PasswordCchLength,MBB_MAXIMUM_PASSWORD_LENGTH) * sizeof(WCHAR); - - if( (MbbSetContextState = (PMBB_SET_CONTEXT_STATE) ALLOCATE_NONPAGED_POOL( MbbSetContextStateSize )) == NULL ) - { - NdisStatus = NDIS_STATUS_RESOURCES; - break; - } - Request->HandlerContext.DataToFreeOnCompletion = MbbSetContextState; - - MbbUtilWwanToMbbSetContextState( - SetContextState, - AccessStringCchLength, - UserNameCchLength, - PasswordCchLength, - MbbSetContextStateSize, - SessionId, - MbbSetContextState - ); - - NdisStatus = MbbUtilSetAttributeWithParameter( - Request, - (PCHAR) MbbSetContextState, - MbbSetContextStateSize - ); - }while(FALSE); - - return NdisStatus; -} - - -NDIS_STATUS -MbbUtilWwanCreateMac( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PMINIPORT_ADAPTER_CONTEXT Adapter= (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); - PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; - PMBB_PORT NewPort = NULL; - PNDIS_WWAN_MAC_INFO NdisWwanMacInfo = NULL; - - do - { - OidRequest->DATA.METHOD_INFORMATION.BytesWritten = 0; - OidRequest->DATA.METHOD_INFORMATION.BytesRead = 0; - OidRequest->DATA.METHOD_INFORMATION.BytesNeeded = 0; - - Status = MbbWwanAllocatePort(Adapter, TRUE, &NewPort); - - if (Status != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID,"Failed to allocate a new port\n"); - break; - } - - // Add it to the adapter list - MbbWwanAddPortToAdapterList(Adapter,&NewPort); - - // Done creating the new virtual adapter - - NdisWwanMacInfo = (PNDIS_WWAN_MAC_INFO)OidRequest->DATA.METHOD_INFORMATION.InformationBuffer; - NdisWwanMacInfo->uNdisPortNumber = NewPort->PortNumber; - - NdisMoveMemory(NdisWwanMacInfo->MacAddr, Adapter->MACAddress, sizeof(NDIS_WWAN_MAC_ADDRESS)); - - // Adjust the mac address - Status = MbbUtilWwanAssignMacAddress(Adapter, NdisWwanMacInfo->MacAddr); - - if(Status != NDIS_STATUS_SUCCESS) - { - TraceError(WMBCLASS_OID,"Failed to assign a MAC address to the port with port number %lu\n",NewPort->PortNumber); - break; - } - - //Copy the adjusted MAC address to the port - NdisMoveMemory(NewPort->MACAddress, NdisWwanMacInfo->MacAddr, sizeof(NDIS_WWAN_MAC_ADDRESS)); - - OidRequest->DATA.METHOD_INFORMATION.BytesWritten = sizeof(NDIS_WWAN_MAC_INFO); - - // Save the port context in the Request handlercontext so that we can access it - // in the completion routine - - // Add a reference to the port which will be removed in the completion routine - Reference(NewPort); - Request->HandlerContext.Parameters.NdisPortContext.Port = NewPort; - - TraceInfo(WMBCLASS_OID,"Created a new Port \n"); - } while (FALSE); - - return Status; -} - -NDIS_STATUS -MbbUtilWwanCreateMacComplete( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port, - _In_ NDIS_STATUS NdisStatus - ) -{ - NDIS_STATUS Status = NdisStatus; - NDIS_PORT_NUMBER PortNumber; - - if(Port != NULL) - { - if (Status == NDIS_STATUS_SUCCESS) - { - // - // We can now activate the port. We cannot do this while - // we are processing the OID as the OS would deadlock. - // - - - // If this port has been allocated with NDIS, activate it. This notification - // goes upto the OS and it would handle the request - Status = MbbWwanActivatePort(Adapter, Port); - ASSERT(Status == NDIS_STATUS_SUCCESS); - } - else - { - MBB_ACQUIRE_PORT_LOCK(Port); - PortNumber = Port->PortNumber; - MBB_RELEASE_PORT_LOCK(Port); - - if (IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - // If port is not getting activated, remove it from the adapter port list - // and deallocate it so that it can get freed - - if (MbbWwanRemovePortFromAdapterList(Adapter, Port)) - { - MbbWwanDeallocatePort(Port); - } - else - { - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Port(0x%p) with port number %lu was already removed", Port, Port->PortNumber); - } - } - } - } - - return Status; -} - -NDIS_STATUS -MbbUtilWwanDeleteMac( - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PMINIPORT_ADAPTER_CONTEXT Adapter= (PMINIPORT_ADAPTER_CONTEXT) MbbReqMgrGetAdapterHandle(Request); - PNDIS_OID_REQUEST OidRequest = Request->OidContext.OidRequest; - PNDIS_WWAN_MAC_INFO NdisWwanMacInfo = NULL; - PMBB_PORT DestinationPort = NULL; - NDIS_PORT_NUMBER PortNumber; - - do - { - NdisWwanMacInfo = (PNDIS_WWAN_MAC_INFO)OidRequest->DATA.SET_INFORMATION.InformationBuffer; - PortNumber = NdisWwanMacInfo->uNdisPortNumber; - - // - // First we would need to translate from the NDIS_PORT_NUMBER - // to our port structure. This is done by walking the PortList - // Since OID calls are serialized, we do not expect the Portlist to change - // while we are trying to find the port or for the port to get deleted - // until this OID is completed. So we do not need to protect the Port/PortList - // in any way - // - - DestinationPort = MbbWwanTranslatePortNumberToPort( - Adapter, - PortNumber - ); - - if (DestinationPort == NULL) - { - TraceError(WMBCLASS_OID, "Unable to find Port corresponding to PortNumber %d\n", NdisWwanMacInfo->uNdisPortNumber); - Status = NDIS_STATUS_INVALID_PORT; - break; - } - - if (!IS_ALLOCATED_PORT_NUMBER(PortNumber)) - { - // This port has been allocate with NDIS. When we are done, delete the - // port - TraceError(WMBCLASS_OID, "Invalid port number specified %lu\n", NdisWwanMacInfo->uNdisPortNumber); - Status = NDIS_STATUS_INVALID_PORT; - break; - } - - // remove it from the adapter list - if (MbbWwanRemovePortFromAdapterList(Adapter, DestinationPort)) - { - - //Done deleting the mac state - OidRequest->DATA.SET_INFORMATION.BytesRead = sizeof(NDIS_WWAN_MAC_INFO); - - // Save the port number in the Request handlercontext so that we can access it - // in the completion routine - - // Add a reference to the port which will be removed in the completion routine - Reference(DestinationPort); - Request->HandlerContext.Parameters.NdisPortContext.Port = DestinationPort; - - TraceInfo(WMBCLASS_OID, "Removed the port %lu from adapter", NdisWwanMacInfo->uNdisPortNumber); - } - else - { - Status = NDIS_STATUS_INVALID_PORT_STATE; - TraceInfo(WMBCLASS_INIT, "%!FUNC!: Port(0x%p) was already removed", DestinationPort); - } - } while (FALSE); - - - // Remove the reference which got added in converting port number to port - if(DestinationPort != NULL) - { - Dereference(DestinationPort); - } - - return Status; -} - -NDIS_STATUS -MbbUtilWwanDeleteMacComplete( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port, - _In_ NDIS_STATUS NdisStatus - ) -{ - NDIS_STATUS Status = NdisStatus; - NDIS_PORT_NUMBER PortNumber; - - if(Port != NULL) - { - if (Status == NDIS_STATUS_SUCCESS) - { - // Check if the port has an activated context associated with it. - Status = MbbUtilDisconnectPortOnDeleteMac(Adapter,Port); - if(Status != NDIS_STATUS_SUCCESS) - { - - TraceError( WMBCLASS_OID, "[MbbAdapter]MbbUtilDisconnectPortOnDeleteMac FAILED to deactivate context. Status=%!status!",Status); - } - - // - // We can now deactivate the port. We cannot do this while we are processing - // the OID, else the OS would deadlock. - // - Status = MbbWwanDeactivatePort(Adapter, Port); - ASSERT(Status == NDIS_STATUS_SUCCESS); - - // Deallocate the port that the NDIS port can be freed - // and the port can be cleaned up. - - MbbWwanDeallocatePort(Port); - } - } - - return Status; -} - -NDIS_STATUS -MbbUtilDisconnectPortOnDeleteMac( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port - ) -{ - ULONG SessionId = MBB_INVALID_SESSION_ID; - ULONG MaxActivatedContexts = 0; - BOOLEAN DeactivateContext = FALSE; - PMBB_REQUEST_CONTEXT Request = NULL; - PMBB_REQUEST_MANAGER RequestManager = NULL; - LARGE_INTEGER Timeout; - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - - SessionId = MbbWwanGetPortSessionId(Port); - - MbbAdapterPortsLock(Adapter); - MaxActivatedContexts = Adapter->MaxActivatedContexts; - MbbAdapterPortsUnlock(Adapter); - - // No need of taking port lock as port is already - // removed from adapter port list - - if(SessionId <= MBB_DEFAULT_SESSION_ID - || SessionId >= MaxActivatedContexts) - { - // Return success here as this will be the case when - // deactivate context is done before port is torn down - return NDIS_STATUS_SUCCESS; - } - - MbbAdapterSessionIdPortTableLock(Adapter); - - if(Adapter->SessionIdPortTable[SessionId].InUse - && Adapter->SessionIdPortTable[SessionId].PortNumber == Port->PortNumber) - { - //means port has an active context associated with it - DeactivateContext = TRUE; - } - - MbbAdapterSessionIdPortTableUnlock(Adapter); - - if(DeactivateContext) - { - MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_CONNECT }; - - do - { - if( (RequestManager = MbbAdapterGetRequestManager( Adapter )) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbAdapter] FAILED to reference RequestManager for deactivate context" ); - NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY; - break; - } - - if( (Request = MbbReqMgrCreateRequest( - RequestManager, - NULL, - 0, - &NdisStatus)) == NULL ) - { - TraceError( WMBCLASS_OID, "[MbbAdapter] FAILED to allocate RequestContext for deactivate context" ); - break; - } - - Request->OidHandler = MbbNdisGetOidHandlerByCommand( &Command ); - - Request->HandlerContext.Parameters.ContextSessionId.SessionId = SessionId; - - NdisStatus = MbbReqMgrDispatchRequest( - Request, - TRUE, // Serialized - MbbUtilDeactivateContext, - MbbUtilInternalCIDCompletion, - MbbUtilInternalCIDResponse - ); - - if( NdisStatus != NDIS_STATUS_PENDING ) - { - MbbReqMgrDestroyRequest( - Request->RequestManager, - Request - ); - } - }while(FALSE); - } - - if( RequestManager != NULL ) - { - MbbReqMgrDeref( RequestManager ); - } - - return NdisStatus; -} - -NDIS_STATUS -MbbUtilDeactivateContext( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ) -{ - NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; - MBB_COMMAND Command = { MBB_UUID_BASIC_CONNECT_CONSTANT, MBB_BASIC_CID_CONNECT }; - PWWAN_SET_CONTEXT_STATE WwanSetContextState = ALLOCATE_NONPAGED_POOL(sizeof(WWAN_SET_CONTEXT_STATE)); - - if(!WwanSetContextState) - { - TraceError( WMBCLASS_OID, "[MbbAdapter] MbbUtilDeactivateContext: FAILED to allocate WWAN_SET_CONTEXT_STATE" ); - return NDIS_STATUS_RESOURCES; - } - - NdisZeroMemory(WwanSetContextState, sizeof(*WwanSetContextState)); - - WwanSetContextState->ActivationCommand = WwanActivationCommandDeactivate; - - NdisStatus = MbbUtilProcessSetConnectState( - Request, - WwanSetContextState, - Request->HandlerContext.Parameters.ContextSessionId.SessionId); - - if(WwanSetContextState) - { - FREE_POOL(WwanSetContextState); - WwanSetContextState = NULL; - } - - return NdisStatus; -} - diff --git a/network/wwan/cxwmbclass/util.cpp b/network/wwan/cxwmbclass/util.cpp new file mode 100644 index 000000000..2e2e5f340 --- /dev/null +++ b/network/wwan/cxwmbclass/util.cpp @@ -0,0 +1,326 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +// +// INCLUDES +// +//////////////////////////////////////////////////////////////////////////////// +#include "precomp.h" + +NTSTATUS +MbbNtbDetectNdp32Loop(_In_ PNCM_NTH32 Nth) +{ + PNCM_NDP32 FirstNdp; + PNCM_NDP32 Ndp; + PNCM_NDP32 LoopNdp; + + if ((FirstNdp = MBB_NTH32_GET_FIRST_NDP(Nth)) == NULL) + return STATUS_SUCCESS; + + if (!MBB_NTB32_IS_VALID_NDP_LENGTH(Nth, FirstNdp)) + { + return STATUS_UNSUCCESSFUL; + } + LoopNdp = MBB_NDP32_GET_NEXT_NDP(Nth, FirstNdp); + + for (Ndp = FirstNdp; Ndp != NULL && LoopNdp != NULL; Ndp = MBB_NDP32_GET_NEXT_NDP(Nth, Ndp)) + { + if (!MBB_NTB32_IS_VALID_NDP_LENGTH(Nth, LoopNdp)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTB32_IS_VALID_NDP_LENGTH(Nth, Ndp)) + { + return STATUS_UNSUCCESSFUL; + } + + if (LoopNdp == Ndp) + { + return STATUS_UNSUCCESSFUL; + } + + if ((LoopNdp = MBB_NDP32_GET_NEXT_NDP(Nth, LoopNdp)) != NULL) + { + if (!MBB_NTB32_IS_VALID_NDP_LENGTH(Nth, LoopNdp)) + { + return STATUS_UNSUCCESSFUL; + } + LoopNdp = MBB_NDP32_GET_NEXT_NDP(Nth, LoopNdp); + } + } + return STATUS_SUCCESS; +} + +NTSTATUS +MbbNtbValidateNdp32(_In_ PNCM_NTH32 Nth, _In_ PNCM_NDP32 Ndp) +{ + ULONG Index; + ULONG DatagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp); + + if (!MBB_NTB32_IS_VALID_NDP_SIGNATURE(Ndp)) + { + return STATUS_UNSUCCESSFUL; + } + + if (MBB_NDP32_GET_SIGNATURE_TYPE(Ndp) == NCM_NDP32_IPS) + { + // + // Check if the session id is valid, else discard + // + + // Check if session Id is greater than maximum supported. Here + // we can also check against MaxActivatedContexts, but this would + // mean we need to take a lock for getting the value of maxactivatedcontexts + // The lock can be avoided by checking against the maximum number of ports + // supported by the class driver. SESSION_PORT_TABLE.InUse can be used + // to check whether the session id is in use. + + if (MBB_NDP32_GET_SESSIONID(Ndp) >= MBB_MAX_NUMBER_OF_SESSIONS) + { + return STATUS_UNSUCCESSFUL; + } + } + + if (!MBB_NTB32_IS_VALID_NDP_LENGTH(Nth, Ndp)) + { + return STATUS_UNSUCCESSFUL; + } + + for (Index = 0; Index < DatagramCount; Index++) + { + if (MBB_NTB32_IS_END_DATAGRAM(Nth, Ndp, Index)) + return STATUS_SUCCESS; + + if (!MBB_NTB32_IS_VALID_DATAGRAM(Nth, Ndp, Index)) + { + return STATUS_UNSUCCESSFUL; + } + } + return STATUS_SUCCESS; +} + +NTSTATUS +MbbNtbValidateNth32(_In_ PNCM_NTH32 Nth, _In_ ULONG BufferLength, _Out_opt_ ULONG* NdpCount) +{ + PNCM_NDP32 Ndp; + ULONG ndpCount = 0; + if (BufferLength < sizeof(NCM_NTH32)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTH32_IS_VALID_SIGNATURE(Nth)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTH32_IS_VALID_HEADER_LENGTH(Nth)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTH32_IS_VALID_BLOCK_LENGTH(Nth, BufferLength)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTH32_IS_VALID_FIRST_NDP(Nth)) + { + return STATUS_UNSUCCESSFUL; + } + + if (MbbNtbDetectNdp32Loop(Nth) != STATUS_SUCCESS) + return STATUS_UNSUCCESSFUL; + + for (Ndp = MBB_NTH32_GET_FIRST_NDP(Nth); Ndp != NULL; Ndp = MBB_NDP32_GET_NEXT_NDP(Nth, Ndp)) + { + if (MbbNtbValidateNdp32(Nth, Ndp) != STATUS_SUCCESS) + return STATUS_UNSUCCESSFUL; + ndpCount++; + } + if (NdpCount != NULL) + { + *NdpCount = ndpCount; + } + return STATUS_SUCCESS; +} + +NTSTATUS +MbbNtbDetectNdp16Loop(_In_ PNCM_NTH16 Nth) +{ + PNCM_NDP16 FirstNdp; + PNCM_NDP16 Ndp; + PNCM_NDP16 LoopNdp; + + if ((FirstNdp = MBB_NTH16_GET_FIRST_NDP(Nth)) == NULL) + return STATUS_SUCCESS; + + if (!MBB_NTB16_IS_VALID_NDP_LENGTH(Nth, FirstNdp)) + { + return STATUS_UNSUCCESSFUL; + } + LoopNdp = MBB_NDP16_GET_NEXT_NDP(Nth, FirstNdp); + + for (Ndp = FirstNdp; Ndp != NULL && LoopNdp != NULL; Ndp = MBB_NDP16_GET_NEXT_NDP(Nth, Ndp)) + { + if (!MBB_NTB16_IS_VALID_NDP_LENGTH(Nth, LoopNdp)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTB16_IS_VALID_NDP_LENGTH(Nth, Ndp)) + { + return STATUS_UNSUCCESSFUL; + } + + if (LoopNdp == Ndp) + { + return STATUS_UNSUCCESSFUL; + } + + if ((LoopNdp = MBB_NDP16_GET_NEXT_NDP(Nth, LoopNdp)) != NULL) + { + if (!MBB_NTB16_IS_VALID_NDP_LENGTH(Nth, LoopNdp)) + { + return STATUS_UNSUCCESSFUL; + } + LoopNdp = MBB_NDP16_GET_NEXT_NDP(Nth, LoopNdp); + } + } + return STATUS_SUCCESS; +} + +NTSTATUS +MbbNtbValidateNdp16(_In_ PNCM_NTH16 Nth, _In_ PNCM_NDP16 Ndp) +{ + ULONG Index; + ULONG DatagramCount = MBB_NDP16_GET_DATAGRAM_COUNT(Ndp); + + if (!MBB_NTB16_IS_VALID_NDP_SIGNATURE(Ndp)) + { + return STATUS_UNSUCCESSFUL; + } + + if (MBB_NDP16_GET_SIGNATURE_TYPE(Ndp) == NCM_NDP16_IPS) + { + // + // Check if the session id is valid, else discard + // + + // Check if session Id is greater than maximum supported. Here + // we can also check against MaxActivatedContexts, but this would + // mean we need to take a lock for getting the value of maxactivatedcontexts + // The lock can be avoided by checking against the maximum number of ports + // supported by the class driver. SESSION_PORT_TABLE.InUse can be used + // to check whether the session id is in use. + + if (MBB_NDP16_GET_SESSIONID(Ndp) >= MBB_MAX_NUMBER_OF_SESSIONS) + { + return STATUS_UNSUCCESSFUL; + } + } + + if (!MBB_NTB16_IS_VALID_NDP_LENGTH(Nth, Ndp)) + { + return STATUS_UNSUCCESSFUL; + } + + for (Index = 0; Index < DatagramCount; Index++) + { + if (MBB_NTB16_IS_END_DATAGRAM(Nth, Ndp, Index)) + return STATUS_SUCCESS; + + if (!MBB_NTB16_IS_VALID_DATAGRAM(Nth, Ndp, Index)) + { + return STATUS_UNSUCCESSFUL; + } + } + return STATUS_SUCCESS; +} + +NTSTATUS +MbbNtbValidateNth16(_In_ PNCM_NTH16 Nth, _In_ ULONG BufferLength, _Out_opt_ ULONG* NdpCount) +{ + PNCM_NDP16 Ndp; + ULONG ndpCount = 0; + if (BufferLength < sizeof(NCM_NTH16)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTH16_IS_VALID_SIGNATURE(Nth)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTH16_IS_VALID_HEADER_LENGTH(Nth)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTH16_IS_VALID_BLOCK_LENGTH(Nth, BufferLength)) + { + return STATUS_UNSUCCESSFUL; + } + + if (!MBB_NTH16_IS_VALID_FIRST_NDP(Nth)) + { + return STATUS_UNSUCCESSFUL; + } + + if (MbbNtbDetectNdp16Loop(Nth) != STATUS_SUCCESS) + return STATUS_UNSUCCESSFUL; + + for (Ndp = MBB_NTH16_GET_FIRST_NDP(Nth); Ndp != NULL; Ndp = MBB_NDP16_GET_NEXT_NDP(Nth, Ndp)) + { + if (MbbNtbValidateNdp16(Nth, Ndp) != STATUS_SUCCESS) + return STATUS_UNSUCCESSFUL; + ndpCount++; + } + + if (NdpCount != NULL) + { + *NdpCount = ndpCount; + } + return STATUS_SUCCESS; +} + +NTSTATUS +MbbNtbValidate(_In_ PVOID Nth, _In_ ULONG BufferLength, _In_ BOOLEAN Is32Bit, _Out_opt_ ULONG* NdpCount) +{ + if (Is32Bit == TRUE) + return MbbNtbValidateNth32((PNCM_NTH32)Nth, BufferLength, NdpCount); + else + return MbbNtbValidateNth16((PNCM_NTH16)Nth, BufferLength, NdpCount); +} + +NTSTATUS +CreateNonPagedWdfMemory(_In_ ULONG ObjectSize, _Out_ WDFMEMORY* WdfMemory, _Out_opt_ PVOID* ObjectMemory, _In_ WDFOBJECT Parent, _In_ ULONG PoolTag = 0) +{ + NTSTATUS status; + WDF_OBJECT_ATTRIBUTES objectAttribs; + + WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs); + objectAttribs.ParentObject = Parent; + + status = WdfMemoryCreate(&objectAttribs, NonPagedPoolNx, PoolTag, ObjectSize, WdfMemory, ObjectMemory); + + return status; +} + +PMDL AllocateNonPagedMdl(_In_reads_bytes_(Length) PVOID VirtualAddress, _In_ ULONG Length) +{ + PMDL Mdl; + + Mdl = IoAllocateMdl(VirtualAddress, Length, FALSE, FALSE, NULL); + + if (Mdl) + { + MmBuildMdlForNonPagedPool(Mdl); + Mdl->Next = NULL; + } + + return Mdl; +} diff --git a/network/wwan/cxwmbclass/util.h b/network/wwan/cxwmbclass/util.h deleted file mode 100644 index 9c9cb7afc..000000000 --- a/network/wwan/cxwmbclass/util.h +++ /dev/null @@ -1,1263 +0,0 @@ -/*************************************************************************** - -Copyright (c) 2010 Microsoft Corporation - -Module Name: - - Util.h - -Abstract: - - This file contains the message definitions for helper functions. - All data conversion from MBB structures to WWAN structures and - vice versa is present in Util.c. - - Note the MbbUtilXxx routines do not perform length validation - as they require the caller to perform validation and allocate - sufficient memory. - -Environment: - - kernel mode only - -Notes: - - -Revision History: - - 3/2/2010 : TriRoy : Added MbbUtilXxx routines - -Authors: - - BrianL - TriRoy - -****************************************************************************/ - -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// - -// -// Infrastructure for testability. -// Flags can be added to conditionally simulate test situations. -// MbbGlobalTestFlags can be set from the debugger to trigger conditions. -// -//typedef enum -//{ -// MbbTestFlagNone = 0x00000000, -// MbbTestFlagSimulateQueryDeviceServiceDispatchFailure = 0x00000001, -// MbbTestFlagSimulateQueryDeviceServiceTimeout = 0x00000002, -// MbbTestFlagSimulateInvalidResponseBufferSize = 0x00000004 -// -//} MBB_TEST_FLAG; -// -//extern volatile ULONG MbbGlobalTestFlags; - -typedef union -{ - ULONG Value; - struct - { - ULONG NoPostAllocation:1; - }; - -} MBB_ALLOC_FLAGS; - -typedef __callback -VOID -(*MBB_WORKITEM_ROUTINE)( - __in PVOID Context1, - __in PVOID Context2, - __in PVOID Context3, - __in PVOID Context4 - ); - -typedef enum -{ - MbbPoolTagDefault = '0CBM', - MbbPoolTagNtbSend = '1CBM', - MbbPoolTagNblSend = '2CBM', - MbbPoolTagNbSend = '3CBM', - MbbPoolTagNtbReceive = '4CBM', - MbbPoolTagNblReceive = '5CBM', - MbbPoolTagMdlReceive = '6CBM', - MbbPoolTagNbPool = '7CBM', - MbbPoolTagNblPool = '8CBM', - MbbPoolTagTimer = '9CBM', - MbbPoolTagRequest = 'rCBM', - MbbPoolTagPort = 'pCBM', - MbbPoolTagNblFastIOContext = 'cOIF' -} MBB_POOL_TAG; - -#define ALLOCATE_PAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_PAGED, _y, MbbPoolTagDefault) -#define ALLOCATE_NONPAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_NON_PAGED, _y, MbbPoolTagDefault) -#define ALLOCATE_NONPAGED_POOL_WITH_TAG(_x, _y) ExAllocatePool2(POOL_FLAG_NON_PAGED, _x, _y) - -#define FREE_POOL(_x) {ExFreePool(_x);_x=NULL;}; - -#define ALLOCATE_LOOKASIDE(LOOKASIDELIST) NdisAllocateFromNPagedLookasideList( LOOKASIDELIST ) -#define FREE_LOOKASIDE(MEMORY,LOOKASIDELIST) { NdisFreeToNPagedLookasideList( (LOOKASIDELIST), (MEMORY) ); (MEMORY) = NULL; }; - -#define MIN( _X_, _Y_ ) (((_X_) < (_Y_))? (_X_): (_Y_)) -#define MAX( _X_, _Y_ ) (((_X_) > (_Y_))? (_X_): (_Y_)) - -#define ALIGN_FLOOR( _VALUE_, _ALIGN_ ) ((SIZE_T)(_VALUE_) - (((SIZE_T)(_VALUE_))%((SIZE_T)(_ALIGN_)))) -#define ALIGN_CIELING( _VALUE_, _ALIGN_ ) ALIGN_FLOOR( _VALUE_, _ALIGN_ ) + ((SIZE_T)(_ALIGN_)) -#define ALIGN( _VALUE_, _ALIGN_ ) ALIGN_CIELING( _VALUE_, _ALIGN_ ) -#define ALIGN_AT_OFFSET( _VALUE_, _ALIGN_, _OFFSET_ ) (((SIZE_T)(_VALUE_) <= (ALIGN_FLOOR(_VALUE_,_ALIGN_)+(_OFFSET_)))? (ALIGN_FLOOR(_VALUE_,_ALIGN_)+(_OFFSET_)): (ALIGN(_VALUE_,_ALIGN_)+(_OFFSET_))) - -#define MBB_BAD_POINTER ((PVOID)0x5A5A5A5A) - -#define MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION( NSI, MINIPORTADAPTERHANDLE, STATUS ) \ -{ \ - (NSI)->Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; \ - (NSI)->Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; \ - (NSI)->Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; \ - (NSI)->SourceHandle = (MINIPORTADAPTERHANDLE); \ - (NSI)->PortNumber = 0; \ - (NSI)->StatusCode = (STATUS); \ - (NSI)->Flags = 0; \ - (NSI)->DestinationHandle = NULL; \ - (NSI)->RequestId = 0; \ - RtlZeroMemory( &(NSI)->Guid, sizeof((NSI)->Guid) ); \ -} - -#define MBB_INITIALIZE_REQUEST_NDIS_STATUS_INDICATION( NSI, REQ, STATUS ) \ -{ \ - MBB_UTIL_INITIALIZE_NDIS_STATUS_INDICATION(NSI, (REQ)->RequestManager->AdapterContext->MiniportAdapterHandle, STATUS) \ - (NSI)->DestinationHandle = (REQ)->OidContext.OidRequestHandle; \ - (NSI)->RequestId = (REQ)->OidContext.OidRequestId; \ -} - -#define MbbUtilPopulateStaticString(_StaticString, _ContainingStruct, _MbbString) \ -{ \ - ASSERT(sizeof(_StaticString) > _ContainingStruct->_MbbString.Size); \ - \ - RtlZeroMemory( \ - &_StaticString[0], \ - sizeof(_StaticString) \ - ); \ - \ - RtlCopyMemory( \ - &_StaticString[0], \ - ((PUCHAR)_ContainingStruct) + _ContainingStruct->_MbbString.Offset, \ - _ContainingStruct->_MbbString.Size \ - ); \ -} - -#define MBB_INIT_MBB_STRING(_X_) \ -{ \ - (_X_)->Size = 0; \ - (_X_)->Offset = 0; \ -} - - -#define MBB_INVALID_SESSION_ID -1 -#define MBB_INVALID_PORT_NUMBER -1 - -#define MBB_NO_MATCH_WOL_PATTERN_ID 0 -#define MBB_NO_MATCH_WOL_PATTERN_SIZE 8 // 8 bytes - 0x00000000 - - -//////////////////////////////////////////////////////////////////////////////// -// -// DECLARATIONS -// -//////////////////////////////////////////////////////////////////////////////// -PCSTR -GetOidName( - __in NDIS_OID Oid - ); - -BOOLEAN -IsSameGuid(GUID * pgGuid1, GUID *pgGuid2); - -BOOLEAN -IsZeroGuid( - __in GUID* pGuid - ); - -NDIS_STATUS -GetDeviceFriendlyName( - __in NDIS_HANDLE MiniportAdapterHandle, - __out PANSI_STRING AnsiName - ); - -VOID -FreeAdapterBlock( - _In_ __drv_freesMem(Mem) PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -PCHAR -MbbUtilGetCommandString( - __in PMBB_COMMAND Command - ); - -BOOLEAN -MbbUtilIsBasicCommand( - __in PMBB_COMMAND Command - ); - -BOOLEAN -MbbUtilIsValidDeviceService( - __in GUID* DeviceServiceGuid - ); - -NDIS_STATUS -MbbUtilSendMessageFragmentsAndLog( - __in PMBB_REQUEST_CONTEXT Request - ); - -NDIS_STATUS -MbbUtilSendMessageFragments( - __in PMBB_REQUEST_CONTEXT Request - ); - -NDIS_STATUS -MbbUtilSetupCommandMessage( - __in PMBB_REQUEST_CONTEXT Request, - __in PMBB_COMMAND Command, - __in MBB_COMMAND_TYPE CommandType, - __in_bcount_opt(InputBufferLength) PUCHAR InputBuffer, - __in ULONG InputBufferLength - ); - -NDIS_STATUS -MbbUtilInternalCIDQuery( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ); - -VOID -MbbUtilInternalCIDCompletion( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); - -VOID -MbbUtilInternalCIDResponse( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -VOID -MbbUtilCommonCIDResponse( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize, - __in_opt PMBB_OID_HANDLER_ENTRY OidHandler - ); - -NDIS_STATUS -MbbUtilQueryAttribute( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -NDIS_STATUS -MbbUtilQueryAttributeWithParameter( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(GetRequestParametersSize) PUCHAR GetRequestParameters, - __in ULONG GetRequestParametersSize - ); - -NDIS_STATUS -MbbUtilSetAttributeWithParameter( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(SetParametersSize) PUCHAR SetParameters, - __in ULONG SetParametersSize - ); - -NDIS_STATUS -MbbUtilDeviceServiceCommand( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbUtilUiccAccessBinary( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -NDIS_STATUS -MbbUtilUiccAccessRecord( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -PCSTR -MbbUtilGetWwanIndicationString( - __in NDIS_STATUS Indication - ); - -// -// Allocator -// - -__drv_allocatesMem(Mem) -__drv_aliasesMem -PVOID -MbbAllocMgrInitialize( - __in ULONG AllocationSize, - __in ULONG AllocationCount, - __in ULONG PoolTag, - __in MBB_ALLOC_FLAGS Flags - ); - -VOID -MbbAllocMgrCleanup( - __in __drv_freesMem(Mem) PVOID AllocMgrHandle - ); - -PVOID -MbbAllocMgrAllocate( - __in PVOID AllocMgrHandle - ); - -VOID -MbbAllocMgrFree( - __in PVOID AllocHandle - ); - -// -// Buffer Manager -// - -__drv_allocatesMem(Mem) -__drv_aliasesMem -PVOID -MbbBufMgrInitialize( - __in ULONG BufferCount, - __in ULONG BufferLength - ); - -VOID -MbbBufMgrCleanup( - __in __drv_freesMem(Mem) PVOID ManagerHandle - ); - -// -// Work Item -// - -__drv_allocatesMem(Mem) -__drv_aliasesMem -PVOID -MbbWorkMgrInitialize( - __in ULONG InitialWorkItemCount - ); - -VOID -MbbWorkMgrCleanup( - __in __drv_freesMem(Mem) PVOID WorkItemManagerHandle - ); - -NDIS_STATUS -MbbWorkMgrQueueWorkItem( - __in PVOID WorkItemManagerHandle, - __in_opt PVOID Context1, - __in_opt PVOID Context2, - __in_opt PVOID Context3, - __in_opt PVOID Context4, - __in MBB_WORKITEM_ROUTINE Routine - ); - -// -// Wwan to Mbb -// - - -VOID -MbbUtilWwanToMbbRadioState( - __in WWAN_RADIO* WwanRadio, - __out MBB_RADIO_STATE* MbbRadioState - ); - -NTSTATUS -MbbUtilWwanToMbbPinAction( - __in PWWAN_PIN_ACTION WwanPinAction, - __out PMBB_PIN_ACTION * MbbPinActionOut, - __out PULONG ReturnedBufferSize - ); - -NTSTATUS -MbbUtilWwanToMbbPinActionEx2( - __in PWWAN_PIN_ACTION_EX2 WwanPinAction, - __out PMBB_PIN_ACTION_EX2 *MbbPinActionOut, - __out PULONG ReturnedBufferSize - ); - -ULONG -MbbUtilWwanToMbbProvider( - __in PWWAN_PROVIDER WwanProvider, - __in MBB_CELLULAR_CLASS MbbCellularClass, - __in ULONG Rssi, - __in ULONG ErrorRate, - __in ULONG MbbProviderSize, - __out_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider - ); - -ULONG -MbbUtilWwanToMbbProvider2( - __in PWWAN_PROVIDER2 WwanProvider2, - __in ULONG MbbProviderSize, - __out_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider - ); - -NDIS_STATUS -MbbUtilWwanToMbbProviderList( - __in PWWAN_LIST_HEADER WwanProviderList, - __in BOOLEAN IsMultiCarrierCapable, - __in_opt MBB_CELLULAR_CLASS MbbCellularClass, - __out_bcount(*MbbProviderListSize) PMBB_PROVIDER_LIST MbbProviderList, - __inout PULONG MbbProviderListSize - ); - -NTSTATUS -MbbUtilWwanToMbbSetRegisterState( - __in PWWAN_SET_REGISTER_STATE WwanSetRegisterState, - __out PMBB_SET_REGISTER_STATE *MbbSetRegisterStateOut, - __out PULONG ReturnedBufferSize - ); - - -NDIS_STATUS -MbbUtilWwanToMbbSetPacketService( - __in WWAN_PACKET_SERVICE_ACTION PacketServiceAction, - __out PMBB_SET_PACKET_SERVICE MbbSetPacketService - ); - -VOID -MbbUtilAdjustSignalStateConfigurationForDevice( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __inout PWWAN_SET_SIGNAL_INDICATION WwanSetSignalIndication - ); - -VOID -MbbUtilWwanToMbbSetSignalStateIndication( - __in PWWAN_SET_SIGNAL_INDICATION WwanSetSignalIndication, - __out PMBB_SET_SIGNAL_INDICATION MbbSetSignalStateIndication - ); - -VOID -MbbUtilWwanToMbbSetContextState( - __in PWWAN_SET_CONTEXT_STATE WwanSetContextState, - __in ULONG AccessStringCchLength, - __in ULONG UserNameCchLength, - __in ULONG PasswordCchLength, - __in ULONG MbbSetContextStateSize, - __in ULONG SessionId, - __out PMBB_SET_CONTEXT_STATE MbbSetContextState - ); - -NTSTATUS -MbbUtilWwanToMbbSetLteAttachContext( - __in PWWAN_SET_LTE_ATTACH WwanSetContextBuffer, - __out PMBB_SET_MS_CONTEXT_LTE_ATTACH_CONFIG *ReturnedMbbSetContext, - __out ULONG *ReturnedBufferSize - ); - -VOID -MbbUtilMbbToWwanLteAttachConfigInfo( - __in MBB_MS_LTE_ATTACH_CONFIG_INFO* MbbLteAttachContextList, - __out PWWAN_LTE_ATTACH_CONFIG WwanLteAttachContext - ); - -VOID -MbbUtilMbbToWwanLteAttachContext( - __in PMBB_MS_LTE_ATTACH_CONTEXT MbbLteAttachContext, - __out WWAN_CONTEXT_V2* WwanLteAttachContext - ); - -VOID -MbbUtilMbbToWwanLteAttachStatus( - __in MBB_MS_LTE_ATTACH_STATUS* MbbLteAttachStatus, - __out PWWAN_LTE_ATTACH_STATUS WwanLteAttachStatus - ); - -NTSTATUS -MbbUtilWwanToMbbSetContext( - __in PWWAN_SET_CONTEXT WwanSetContext, - __out PMBB_SET_CONTEXT *ReturnedMbbSetContext, - __out ULONG *ReturnedBufferSize - ); - -NTSTATUS -MbbUtilWwanToMbbSetContextV2( - __in PWWAN_SET_PROVISIONED_CONTEXT_V2 WwanSetContext, - __out PMBB_SET_MS_CONTEXT_PROVISIONED_CONTEXT_V2 *ReturnedMbbSetContext, - __out ULONG *ReturnedBufferSize -); - -NTSTATUS -MbbUtilWwanToMbbSmsSetConfiguration( - __in PWWAN_SET_SMS_CONFIGURATION WwanSmsSetConfiguration, - __in ULONG ScAddressSize, - __out PMBB_SET_SMS_CONFIGURATION *MbbSmsSetConfigurationReturn, - __out PULONG ReturnedBufferSize - ); - - -VOID -MbbUtilWwanToMbbSmsRead( - __in PWWAN_SMS_READ WwanSmsRead, - __out PMBB_SMS_READ MbbSmsRead - ); -#if 0 -NDIS_STATUS -MbbUtilWwanToMbbSmsSend( - __in PWWAN_SMS_SEND WwanSmsSend, - __in MBB_CELLULAR_CLASS CellularClass, - __out_bcount(MbbSmsSendSize) PMBB_SMS_SEND MbbSmsSend, - __in ULONG MbbSmsSendSize - ); -#endif - -MBB_SMS_FORMAT -MbbUtilWwanToMbbSmsFormat( - __in WWAN_SMS_FORMAT WwanSmsFormat - ); - - -NDIS_STATUS -MbbUtilWwanToMbbSmsSendPdu( - __in PWWAN_SMS_SEND_PDU WwanSmsSendPdu, - __in MBB_CELLULAR_CLASS CellularClass, - __out PMBB_SMS_SEND *ReturnedMbbSmsSend, - __out PULONG MbbSmsSendSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbSmsSendCdma( - __in PWWAN_SMS_SEND_CDMA WwanSmsSendCdma, - __out PMBB_SMS_SEND *ReturnedMbbSmsSend, - __out PULONG MbbSmsSendSize - ); - - - -VOID -MbbUtilWwanToMbbSmsDelete( - __in PWWAN_SMS_FILTER WwanSmsFilter, - __out PMBB_SMS_DELETE MbbSmsDelete - ); - -NDIS_STATUS -MbbUtilWwanToMbbSubscribeEvents( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in_ecount(GuidCount) GUID* GuidList, - __in ULONG GuidCount, - __in BOOL ExternalRequest, - __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, - __in ULONG ExtSubscribeListSize, - __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, - __out PULONG OutputSubscribeBufferSize - ); - -NDIS_STATUS -MbbUtilGenerateSubscribeEventList( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN FullPower, - __in ULONG MediaSpecificWakeUpEvents, - __in ULONG WakeUpFlags, - __in_bcount(ExtSubscribeListSize) PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList, - __in ULONG ExtSubscribeListSize, - __out PMBB_SUBSCRIBE_EVENT_LIST* OutputSubscribeList, - __out PULONG OutputSubscribeListSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbAkapAuthChallenge( - __in PWWAN_AUTH_AKAP_CHALLENGE WwanAuthAkapChallenge, - __in ULONG UTF16ByteCount, - __in ULONG MbbSize, - __out_bcount(MbbSize) PMBB_AKAP_AUTH_CHALLENGE MbbAkapAuthChallenge - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetPacketFilter( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in BOOLEAN Set, - __in NDIS_PORT_NUMBER PortNumber, - __out PMBB_PACKET_FILTERS *ReturnedMbbPacketFilters, - __out ULONG *ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbUiccFilePath( - __in PWWAN_UICC_FILE_PATH WwanUiccFilePath, - __deref_out PMBB_UICC_FILE_PATH *MbbUiccFilePathOut, - __out PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbUiccAccessBinary( - __in PWWAN_UICC_ACCESS_BINARY WwanUiccAccessBinary, - __deref_out_opt PMBB_UICC_ACCESS_BINARY *MbbUiccAccessBinaryOut, - __out PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbUiccAccessRecord( - __in PWWAN_UICC_ACCESS_RECORD WwanUiccAccessRecord, - __deref_out_opt PMBB_UICC_ACCESS_RECORD *MbbUiccAccessRecordOut, - __out PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbPinApp( - __in PWWAN_PIN_APP WwanPinApp, - __deref_out PMBB_PIN_APP *MbbPinAppOut, - __out PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetDeviceSlotMappingInfo( - __in PWWAN_DEVICE_SLOT_MAPPING_INFO WwanDeviceSlotMappingInfo, - __deref_out_opt PMBB_MS_DEVICE_SLOT_MAPPING_INFO *MbbDeviceSlotMappingInfoOut, - __out PULONG ReturnedBufferSize - ); - -ULONG -MbbUtilWwanListToMbbList( - __in PWWAN_LIST_HEADER WwanListHeader, - __in ULONG WwanListElementSize, - __inout PUCHAR MbbBuffer, - __in ULONG CurrentOffsetInMbbBuffer, - __inout PMBB_ARRAY_ELEMENT MbbArray - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetDeviceBindingsInfo( - __in PWWAN_DEVICE_BINDINGS_INFO WwanSetDeviceBindingsInfo, - __deref_out PMBB_DEVICE_BINDINGS_INFO *MbbSetDeviceBindingsInfoOut, - __out PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetRegisterStateEx( - __in PWWAN_SET_REGISTER_STATE_EX WwanSetRegisterStateEx, - __deref_out PMBB_SET_REGISTER_STATE_V2 *MbbSetRegisterStateV2Out, - __out PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetUiccOpenChannel( - __in PWWAN_SET_UICC_OPEN_CHANNEL WwanSetUiccOpenChannel, - __deref_out PMBB_SET_UICC_OPEN_CHANNEL *MbbSetUiccOpenChannelOut, - __out PULONG ReturnedBufferSize - ); - -VOID -MbbUtilWwanToMbbSetUiccCloseChannel( - __in PWWAN_SET_UICC_CLOSE_CHANNEL WwanSetUiccCloseChannel, - __out PMBB_SET_UICC_CLOSE_CHANNEL MbbSetUiccCloseChannel - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetUiccApdu( - __in PWWAN_SET_UICC_APDU WwanSetUiccApdu, - __deref_out PMBB_SET_UICC_APDU *MbbSetUiccApduOut, - __out PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetUiccTerminalCapability( - __in PWWAN_LIST_HEADER WwanCapabilityListHeader, - __deref_out PMBB_SET_UICC_TERMINAL_CAPABILITY *MbbSetUiccTerminalCapabilityOut, - __out PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetSarConfig( - _In_ PWWAN_SET_SAR_CONFIG WwanSetSarConfig, - _Outptr_ PMBB_SET_SAR_CONFIG *MbbSetSarConfigOut, - _Out_ PULONG ReturnedBufferSize - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetNetworkBlacklist( - _In_ PWWAN_NETWORK_BLACKLIST_INFO SetNetworkBlacklist, - _Outptr_ PMBB_MS_NETWORK_BLACKLIST_INFO *MbbNetworkBlacklistOut, - _Out_ PULONG ReturnedBufferSize - ); - -// -// Mbb to Wwan -// - -WWAN_STATUS -MbbUtilMbbToWwanStatus( - __in MBB_STATUS MbbStatus - ); - -VOID -MbbUtilMbbToWwanDeviceCaps( - __in PMBB_DEVICE_CAPS MbbDeviceCaps, - __in_ecount(ManufacturerStrLen) PWCHAR ManufacturerString, - __in ULONG ManufacturerStrLen, - __in_ecount(ModelStrLen) PWCHAR ModelString, - __in ULONG ModelStrLen, - __out PWWAN_DEVICE_CAPS WwanDeviceCaps, - __in BOOL fMultimode - ); - -VOID -MbbUtilMbbToWwanDeviceCapsV2( - __in PMBB_MS_DEVICE_CAPS_INFO_V2 MbbDeviceCaps, - __in_ecount(ManufacturerStrLen) PWCHAR ManufacturerString, - __in ULONG ManufacturerStrLen, - __in_ecount(ModelStrLen) PWCHAR ModelString, - __in ULONG ModelStrLen, - __out PWWAN_DEVICE_CAPS_EX WwanDeviceCaps, - __in BOOL fMultimode -); - -VOID -MbbUtilMbbToWwanRadioState( - __in MBB_RADIO_STATE* MbbRadioState, - __out WWAN_RADIO* WwanRadio - ); - -VOID -MbbUtilMbbToWwanReadyInfo( - __in PMBB_SUBSCRIBER_READY_INFO MbbReadyInfo, - __in PWWAN_READY_INFO WwanReadyInfo - ); - -VOID -MbbUtilMbbToWwanPinInfo( - __in PMBB_PIN_INFO MbbPinInfo, - __out PWWAN_PIN_INFO WwanPinInfo - ); - -VOID -MbbUtilMbbToWwanPinList( - __in PMBB_PIN_LIST MbbPinList, - __out PWWAN_PIN_LIST WwanPinList - ); - -VOID -MbbUtilMbbToWwanProvider( - __in PMBB_PROVIDER MbbProvider, - __in ULONG MbbDataClass, - __out PWWAN_PROVIDER WwanProvider - ); - -VOID -MbbUtilMbbToWwanProvider2( - __in PMBB_PROVIDER MbbProvider, - __in ULONG MbbDataClass, - __out PWWAN_PROVIDER2 WwanProvider2 - ); - -VOID -MbbUtilMbbToWwanProviderList( - __in PMBB_PROVIDER_LIST MbbProviderList, - __in ULONG MbbDataClass, - __in BOOLEAN IsMultiCarrier, - __out PWWAN_LIST_HEADER WwanProviderList - ); - -VOID -MbbUtilMbbToWwanRegistrationState( - __in PMBB_REGISTRATION_STATE MbbRegistrationState, - __out PWWAN_REGISTRATION_STATE WwanRegistrationState - ); - -VOID -MbbUtilMbbToWwanPacketService( - __in PMBB_PACKET_SERVICE MbbPacketService, - __out PWWAN_PACKET_SERVICE WwanPacketService - ); - -VOID -MbbUtilMbbToWwanSignalState( - __in PMBB_SIGNAL_STATE MbbSignalState, - __out PWWAN_SIGNAL_STATE WwanSignalState - ); - -VOID -MbbUtilMbbToWwanContextState( - __in PMBB_CONTEXT_STATE MbbContextState, - __in ULONG ConnectId, - __out PWWAN_CONTEXT_STATE WwanContextState - ); - -NDIS_STATUS -MbbUtilPopulateWwanIPAddressState( - __in PMBB_IP_ADDRESS_INFO IPAddressInfo, - __in PMBB_IPADDRESS_ENTRY IpTable, - __in PMBB_IPADDRESS_ENTRY GatewayTable, - __in PMBB_IPADDRESS_ENTRY DnsTable, - __in ULONG IpCount, - __in ULONG GatewayCount, - __in ULONG DnsCount, - __out PWWAN_IP_ADDRESS_STATE pWwanIPAddressState - ); - -VOID -MbbUtilMbbToWwanContext( - __in PMBB_CONTEXT MbbContext, - __out PWWAN_CONTEXT WwanContext - ); - -VOID -MbbUtilMbbToWwanContextList( - __in PMBB_CONTEXT_LIST MbbContextList, - __out PWWAN_LIST_HEADER WwanContextList - ); - -VOID -MbbUtilMbbToWwanContextV2( - __in PMBB_MS_CONTEXT_V2 MbbContext, - __out PWWAN_CONTEXT_V2 WwanContext - ); - -VOID -MbbUtilMbbToWwanContextV2List( - __in PMBB_CONTEXT_LIST MbbContextList, - __out PWWAN_LIST_HEADER WwanContextList - ); - -VOID -MbbUtilMbbToWwanServiceActivationStatus( - __in PMBB_SERVICE_ACTIVATION_STATUS MbbServiceActivationStatus, - __in ULONG VendorSpecificBufferSize, - __out PWWAN_SERVICE_ACTIVATION_STATUS WwanServiceActivationStatus - ); - -VOID -MbbUtilMbbToWwanSmsConfiguration( - __in PMBB_SMS_CONFIGURATION MbbSmsConfiguration, - __out PWWAN_SMS_CONFIGURATION WwanSmsConfiguration - ); - -NDIS_STATUS -MbbUtilValidateMbbSmsPduRecord( - __in MBB_CELLULAR_CLASS CellularClass, - __in ULONG MbbSmsPduRecordSize, - __in_bcount(MbbSmsPduRecordSize) PMBB_SMS_PDU_RECORD MbbSmsPduRecord - ); - -NDIS_STATUS -MbbUtilValidateMbbSmsCdmaRecord( - __in ULONG MbbSmsCdmaRecordSize, - __in_bcount(MbbSmsCdmaRecordSize) PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord - ); - -NDIS_STATUS -MbbUtilValidateMbbSmsReceive( - __in MBB_CELLULAR_CLASS CellularClass, - __in ULONG MbbSmsReceiveSize, - __in_bcount(MbbSmsReceiveSize) PMBB_SMS_RECEIVE MbbSmsReceive - ); - -VOID -MbbUtilMbbToWwanSmsPduRecord( - __in PMBB_SMS_PDU_RECORD MbbSmsPduRecord, - __in MBB_CELLULAR_CLASS CellularClass, - __out PWWAN_SMS_PDU_RECORD WwanSmsPduRecord - ); - -VOID -MbbUtilMbbToWwanSmsCdmaRecord( - __in PMBB_SMS_CDMA_RECORD MbbSmsCdmaRecord, - __out PWWAN_SMS_CDMA_RECORD WwanSmsCdmaRecord - ); - -NDIS_STATUS -MbbUtilMbbToWwanSmsReceive( - __in_bcount(MbbSmsReceiveSize) PMBB_SMS_RECEIVE MbbSmsReceive, - __in ULONG MbbSmsReceiveSize, - __in MBB_CELLULAR_CLASS CellularClass, - __out PWWAN_LIST_HEADER SmsListHeader - ); - -VOID -MbbUtilMbbToWwanSmsStatus( - __in PMBB_SMS_STATUS MbbSmsStatus, - __out PWWAN_SMS_STATUS WwanSmsStatus - ); - -VOID -MbbUtilMbbToWwanUiccAppList( - __in PMBB_UICC_APP_LIST MbbUiccAppList, - __out PWWAN_UICC_APP_LIST WwanUiccAppList - ); - -VOID -MbbUtilMbbToWwanUiccFileStatus( - __in PMBB_UICC_FILE_STATUS MbbUiccFileStatus, - __out PWWAN_UICC_FILE_STATUS WwanUiccFileStatus - ); - -VOID -MbbUtilMbbToWwanUiccResponse( - __in PMBB_UICC_RESPONSE MbbUiccResponse, - __out PWWAN_UICC_RESPONSE WwanUiccResponse - ); - -VOID -MbbUtilMbbToWwanSysCapsInfo( - __in PMBB_MS_SYS_CAPS_INFO MbbSysCapsInfo, - __out PWWAN_SYS_CAPS_INFO WwanSysCapsInfo - ); - -VOID -MbbUtilMbbToWwanDeviceSlotMappingInfo( - __in PMBB_MS_DEVICE_SLOT_MAPPING_INFO MbbDeviceSlotMappingInfo, - __out PWWAN_DEVICE_SLOT_MAPPING_INFO WwanDeviceSlotMappingInfo - ); - -VOID -MbbUtilMbbToWwanSlotInfo( - __in PMBB_MS_SLOT_INFO MbbSlotInfo, - __out PWWAN_SLOT_INFO WwanSlotInfo - ); - -VOID -MbbUtilMbbToWwanDeviceBindingsInfo( - __in PMBB_DEVICE_BINDINGS_INFO MbbDeviceBindingsInfo, - __out PWWAN_DEVICE_BINDINGS_INFO WwanDeviceBindingsInfo - ); - -VOID -MbbUtilMbbToWwanRegistrationStateInfoV2( - __in PMBB_REGISTRATION_STATE_INFOS_V2 MbbRegistrationStateInfosV2, - __out PWWAN_REGISTRATION_STATE_INFOS WwanRegistrationStateInfos - ); - -VOID -MbbUtilMbbToWwanSignalStateInfoV2( - __in PMBB_SIGNAL_STATE_INFOS_V2 MbbSignalStateInfosV2, - __out PWWAN_SIGNAL_STATE_INFOS WwanSignalStateInfos - ); - -VOID -MbbUtilMbbToWwanAtrInfo( - __in PMBB_ATR_INFO MbbAtrInfo, - __out PWWAN_ATR_INFO WwanAtrInfo - ); - -VOID -MbbUtilMbbToWwanUiccOpenChannelInfo( - __in PMBB_UICC_OPEN_CHANNEL_INFO MbbUiccOpenChannelInfo, - __out PWWAN_UICC_OPEN_CHANNEL_INFO WwanUiccOpenChannelInfo - ); - -VOID -MbbUtilMbbToWwanUiccCloseChannelInfo( - __in PMBB_UICC_CLOSE_CHANNEL_INFO MbbUiccCloseChannelInfo, - __out PWWAN_UICC_CLOSE_CHANNEL_INFO WwanUiccCloseChannelInfo - ); - -VOID -MbbUtilMbbToWwanUiccApduInfo( - __in PMBB_UICC_APDU_INFO MbbUiccApduInfo, - __out PWWAN_UICC_APDU_INFO WwanUiccApduInfo - ); - -VOID -MbbUtilMbbToWwanUiccTerminalCapabilityInfo( - __in PMBB_UICC_TERMINAL_CAPABILITY_INFO MbbUiccTerminalCapabilityInfo, - __out PWWAN_LIST_HEADER WwanCapabilityListHeader - ); - -VOID -MbbUtilMbbToWwanSarConfigInfo( - _In_ PMBB_SAR_CONFIG_INFO MbbSarConfigInfo, - _Out_ PWWAN_SAR_CONFIG_INFO WwanSarConfigInfo - ); - -VOID -MbbUtilMbbToWwanTransmissionStatusInfo( - _In_ PMBB_SAR_TRANSMISSION_STATUS_INFO MbbTransmissionStatusInfo, - _Out_ PWWAN_SAR_TRANSMISSION_STATUS_INFO WwanTransmissionStatusInfo - ); - -// -// Drain Object -// -VOID -InitDrainObject( - PDRAIN_OBJECT DrainObject, - MBB_DRAIN_COMPLETE DrainCompleteCallback, - PVOID Context - ); - -VOID -StartDrain( - PDRAIN_OBJECT DrainObject - ); - -VOID -DrainComplete( - PDRAIN_OBJECT DrainObject - ); - -BOOLEAN -DrainAddRef( - PDRAIN_OBJECT DrainObject - ); - -VOID -DrainRelease( - PDRAIN_OBJECT DrainObject - ); - -NTSTATUS -MbbEventActivityIdCtl ( - _Inout_ LPGUID ActivityId - ); - - -VOID -MbbWriteEvent ( - IN PCEVENT_DESCRIPTOR EventDescriptor, - IN LPGUID ActivityId OPTIONAL, - IN LPGUID RelatedActivityId OPTIONAL, - IN USHORT ArgCount, - ... - ); - -VOID -MbbWriteEventOpn ( - IN PCEVENT_DESCRIPTOR EventDescriptor, - IN LPGUID ActivityId OPTIONAL, - IN LPGUID RelatedActivityId OPTIONAL, - IN USHORT ArgCount, - ... - ); - -VOID -MbbWriteEventCommon ( - IN REGHANDLE TraceHandle, - IN PCEVENT_DESCRIPTOR EventDescriptor, - IN LPGUID ActivityId OPTIONAL, - IN LPGUID RelatedActivityId OPTIONAL, - IN USHORT ArgCount, - IN va_list Arguments - ); - -NDIS_STATUS -MbbUtilWwanToMbbSetUSSD( - __out PMBB_SET_USSD MbbSetUSSD, - __in PWWAN_USSD_REQUEST WWanUSSDRequest - ); - -NDIS_STATUS -MbbUtilMbbToWwanUSSDEvent( - __in PMBB_USSD MbbUSSD, - __out PWWAN_USSD_EVENT WWanUSSDEvt - ); - -VOID -MbbUtilMbbToWwanNetworkBlackList( - __in PMBB_MS_NETWORK_BLACKLIST_INFO MbbNetworkBlacklist, - __out PWWAN_LIST_HEADER BlacklistProviderList - ); - -// -// Validation routines -// - -NTSTATUS -MbbIsVariableFieldValid( - ULONG TotalLength, - ULONG Offset, - ULONG Size, - ULONG MaxLength, - ULONG ElementSize - ); - -NTSTATUS -MbbIsArrayFieldValid( - ULONG TotalMessageLength, - ULONG Offset, - ULONG ElementCount, - ULONG ElementSize - ); - - -NDIS_STATUS -MbbUtilValidateMbbProvider( - __in ULONG MbbProviderSize, - __in_bcount(MbbProviderSize) PMBB_PROVIDER MbbProvider - ); - -NDIS_STATUS -MbbUtilValidateMbbProviderList( - __in ULONG MbbProviderListSize, - __in_bcount(MbbProviderListSize) PMBB_PROVIDER_LIST MbbProviderList - ); - -ULONG -MbbUtilWriteStringToBuffer( - __in_ecount(BufferSize) PUCHAR Start, - __in ULONG BufferSize, - __in ULONG CurrentOffset, - __in PMBB_STRING StringDesc, - __in_ecount(SourceLength) PCUCHAR SourceString, - __in ULONG SourceLength - ); - -BOOLEAN -MbbUtilIsNativeMbnService( - __in GUID* DeviceServiceGuid - ); - -PMBB_DS -MbbUtilFindDeviceService( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in GUID* DeviceServiceGuid - ); - -// -// Hex string routines -// -NDIS_STATUS -MbbUtilHexStringToUchar( - __in_ecount(2) PCHAR HexString, - __out PUCHAR Value - ); - -NDIS_STATUS -MbbUtilHexStringToByteStream( - __in_bcount_z(HexStringSize) PCHAR HexString, - __in ULONG HexStringSize, - __out_bcount(ByteStreamSize) PUCHAR ByteStream, - __in ULONG ByteStreamSize - ); - -VOID -MbbUtilByteStreamToHexString( - __in_bcount(ByteStreamSize) PUCHAR ByteStream, - __in ULONG ByteStreamSize, - __out_bcount_z(HexStringSize) PCHAR HexString, - __in ULONG HexStringSize - ); - -_Requires_lock_not_held_(&Port->Lock) -NDIS_STATUS -MbbUtilAddNoMatchFilter( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_PORT Port - ); - -_Requires_lock_not_held_(&Port->Lock) -NTSTATUS -MbbUtilRemoveNoMatchFilter( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PMBB_PORT Port - ); - - -VOID -MbbUtilClearPowerFilterAtIndex( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in ULONG Index - ); - -NTSTATUS -MbbUtilSetPowerFilterPattern( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in NDIS_PORT_NUMBER PortNumber, - __in ULONG PatternId, - __in_bcount_opt(MaskSize) PCUCHAR Mask, - __in ULONG MaskSize, - __in_bcount_opt(PatternSize) PCUCHAR Pattern, - __in ULONG PatternSize - ); - -WWAN_STATUS -MbbUtilNdisToWwanStatus( - __in NDIS_STATUS NdisStatus - ); - -VOID -MbbUtilNdisMiniportIndicateStatusEx( - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in PNDIS_STATUS_INDICATION StatusIndication - ); - -VOID -MbbUtilSendMbimError( - __in ULONG TransactionId, - __in MBB_ERROR ErrorCode, - __in PMINIPORT_ADAPTER_CONTEXT Adapter, - __in GUID ActivityId, - __in PMBB_COMMAND Command - ); - -NDIS_STATUS -MbbUtilWwanToMbbGetVisible( - __in PWWAN_GET_VISIBLE_PROVIDERS WwanVisibleProviders, - __out PMBB_GET_VISIBLE_PROVIDERS MbbVisibleProviders - ); - -NDIS_STATUS -MbbUtilWwanCreateMac( - __in PMBB_REQUEST_CONTEXT Request - ); - -NDIS_STATUS -MbbUtilWwanDeleteMac( - __in PMBB_REQUEST_CONTEXT Request - ); - -NDIS_STATUS -MbbUtilWwanAssignMacAddress( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ NDIS_WWAN_MAC_ADDRESS macAddress - - ); - -NDIS_STATUS -MbbUtilProcessSetConnectState( - __in PMBB_REQUEST_CONTEXT Request, - __in PWWAN_SET_CONTEXT_STATE SetContextState, - __in ULONG SessionId - ); - -NDIS_STATUS -MbbUtilWwanCreateMacComplete( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port, - _In_ NDIS_STATUS NdisStatus - ); - -NDIS_STATUS -MbbUtilWwanDeleteMacComplete( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port, - _In_ NDIS_STATUS NdisStatus - ); - -NDIS_STATUS -MbbUtilDisconnectPortOnDeleteMac( - _In_ PMINIPORT_ADAPTER_CONTEXT Adapter, - _In_ PMBB_PORT Port - ); - -NDIS_STATUS -MbbUtilDeactivateContext( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ); diff --git a/network/wwan/cxwmbclass/utils.cpp b/network/wwan/cxwmbclass/utils.cpp new file mode 100644 index 000000000..12d331c31 --- /dev/null +++ b/network/wwan/cxwmbclass/utils.cpp @@ -0,0 +1,589 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +#include + +NTSTATUS +SendSyncControlCommand( + __in WDFUSBDEVICE WdfUsbDevice, + __in WDF_USB_BMREQUEST_DIRECTION Direction, + __in WDF_USB_BMREQUEST_RECIPIENT Recipient, + __in BYTE Request, + __in USHORT Value, + __inout_bcount_opt(BufferLength) PUCHAR Buffer, + __in ULONG BufferLength, + __out_opt PULONG BytesTransfered) + +{ + + NTSTATUS Status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_MEMORY_DESCRIPTOR memoryDescriptor; + WDF_REQUEST_SEND_OPTIONS SendOptions; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + + usbDeviceContext = GetUsbDeviceContext(WdfUsbDevice); + + if (Buffer != NULL) + { + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDescriptor, (PVOID)Buffer, BufferLength); + } + + WDF_USB_CONTROL_SETUP_PACKET_INIT_CLASS(&controlSetupPacket, Direction, Recipient, Request, Value, usbDeviceContext->UsbCommunicationInterfaceIndex); + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, 0); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(10)); + + Status = WdfUsbTargetDeviceSendControlTransferSynchronously( + WdfUsbDevice, WDF_NO_HANDLE, &SendOptions, &controlSetupPacket, (Buffer != NULL) ? &memoryDescriptor : NULL, BytesTransfered); + + if (!NT_SUCCESS(Status)) + { + BOOLEAN ToHost = Direction == BmRequestDeviceToHost; + } + + return Status; +} + +NTSTATUS +TransactControlChannel( + __in PBUS_OBJECT BusObject, + __in ULONG TimeOut, + __in_bcount_opt(InBufferLength) PUCHAR InBuffer, + __in ULONG InBufferLength, + __out_bcount_opt(OutBufferLength) PUCHAR OutBuffer, + __in ULONG OutBufferLength, + __out PULONG BytesRead) + +{ + ULONG BytesTransfered = 0; + NTSTATUS Status; + + *BytesRead = 0; + + Status = SendSyncControlCommand( + BusObject->WdfUsbDevice, BmRequestHostToDevice, BmRequestToInterface, SEND_ENCAPSULATE_COMMAND, 0, InBuffer, InBufferLength, &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + if (BytesTransfered < InBufferLength) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + Status = WaitForResponseAvailible(BusObject, TimeOut); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + Status = SendSyncControlCommand( + BusObject->WdfUsbDevice, BmRequestDeviceToHost, BmRequestToInterface, GET_ENCAPSULATE_RESPONSE, 0, OutBuffer, OutBufferLength, &BytesTransfered); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + *BytesRead = BytesTransfered; + +Cleanup: + + return Status; +} + +NTSTATUS +ReadInterrupt(_In_ PBUS_OBJECT BusObject, _Inout_updates_bytes_(BufferLength) PUCHAR Buffer, _In_ ULONG BufferLength, _In_ ULONG Timeout, _Out_ PULONG BytesRead) + +{ + + NTSTATUS status; + WDF_OBJECT_ATTRIBUTES attributes; + WDFMEMORY memHandle = NULL; + + WDFREQUEST request = NULL; + BOOLEAN SentToDevice = FALSE; + WDF_REQUEST_SEND_OPTIONS SendOptions; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + WDF_MEMORY_DESCRIPTOR MemoryDescriptor; + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&MemoryDescriptor, (PVOID)Buffer, BufferLength); + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(Timeout)); + + status = WdfUsbTargetPipeReadSynchronously(usbDeviceContext->InterruptPipe, NULL, &SendOptions, &MemoryDescriptor, BytesRead); + + return status; +} + +NTSTATUS +GetDeviceString(__in WDFUSBDEVICE UsbDevice, __in UCHAR Index, __out PWSTR* String) + +{ + NTSTATUS Status; + WDF_REQUEST_SEND_OPTIONS SendOptions; + USHORT CharacterCount = 0; + ULONG AllocationSize = 0; + PWSTR AllocatedString = NULL; + + WDF_REQUEST_SEND_OPTIONS_INIT(&SendOptions, 0); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&SendOptions, WDF_REL_TIMEOUT_IN_SEC(DEFAULT_IO_TIMEOUT)); + + *String = NULL; + + Status = WdfUsbTargetDeviceQueryString(UsbDevice, NULL, &SendOptions, NULL, &CharacterCount, Index, 0); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + // + // allocate one more char to make sure sting is null terminated + // + AllocationSize = (CharacterCount + 1) * sizeof(WCHAR); + + AllocatedString = (PWSTR)ALLOCATE_PAGED_POOL(AllocationSize); + + if (AllocatedString == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Cleanup; + } + + RtlZeroMemory(AllocatedString, AllocationSize); + + Status = WdfUsbTargetDeviceQueryString(UsbDevice, NULL, &SendOptions, AllocatedString, &CharacterCount, Index, 0); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + *String = AllocatedString; + AllocatedString = NULL; + +Cleanup: + + if (AllocatedString != NULL) + { + FREE_POOL(AllocatedString); + AllocatedString = NULL; + } + + return Status; +} + +NTSTATUS +MbbBusSetPacketFilter(__in MBB_BUS_HANDLE BusHandle, __in ULONG PacketFilter) + +{ + + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + ULONG BytesTransfered = 0; + UCHAR ReadBuffer[256]; + + Status = SendSyncControlCommand( + BusObject->WdfUsbDevice, BmRequestHostToDevice, BmRequestToInterface, SET_PACKET_FILTER, 0, (PUCHAR)&PacketFilter, sizeof(PacketFilter), &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + if (BytesTransfered < sizeof(PacketFilter)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + return Status; +} + +NTSTATUS +MbbBusSetNtbInSize(__in MBB_BUS_HANDLE BusHandle, __in ULONG InSize) + +{ + + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + ULONG BytesTransfered = 0; + + Status = SendSyncControlCommand( + BusObject->WdfUsbDevice, BmRequestHostToDevice, BmRequestToInterface, SET_NTB_INPUT_SIZE, 0, (PUCHAR)&InSize, sizeof(InSize), &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + if (BytesTransfered < sizeof(InSize)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + return Status; +} + +NTSTATUS +MbbBusGetStat(__in MBB_BUS_HANDLE BusHandle, __in USHORT StatIndex, __out ULONGLONG* Value) + +{ + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + ULONG BytesTransfered = 0; + +#pragma warning(suppress : 6001) + Status = SendSyncControlCommand( + BusObject->WdfUsbDevice, BmRequestDeviceToHost, BmRequestToInterface, GET_STATISTIC, StatIndex, (PUCHAR)Value, sizeof(*Value), &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + if (BytesTransfered < sizeof(Value)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + return Status; +} + +NTSTATUS +MbbBusSetNtbFormat(__in MBB_BUS_HANDLE BusHandle, __in USHORT Format) + +{ + + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + ULONG BytesTransfered = 0; + + Status = SendSyncControlCommand( + BusObject->WdfUsbDevice, BmRequestHostToDevice, BmRequestToInterface, SET_NBT_FORMAT, Format, (PUCHAR)NULL, 0, &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + } + + return Status; +} + +NTSTATUS +MbbBusResetFunction(__in MBB_BUS_HANDLE BusHandle) + +{ + + PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; + NTSTATUS Status; + ULONG BytesTransfered = 0; + + Status = SendSyncControlCommand( + BusObject->WdfUsbDevice, BmRequestHostToDevice, BmRequestToInterface, RESET_FUNCTION, 0, (PUCHAR)NULL, 0, &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + } + + return Status; +} + +NTSTATUS +MbbBusResetDeviceAndSetParms(__in PBUS_OBJECT BusObject) + +{ + NTSTATUS Status; + USHORT NtbFormat = NCM_SET_NTB_FORMAT_16_BIT; + + // + // put the device back into a known state + // + Status = MbbBusResetFunction(BusObject); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + Status = MbbBusSetNtbInSize(BusObject, BusObject->MaxBulkInTransfer); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + + if ((BusObject->NtbParam.bmNtbFormatSupported & NCM_NTB_FORMAT_32_BIT) == NCM_NTB_FORMAT_32_BIT) + { + // + // device supports 32 bit mode + // + if (BusObject->NtbFormat32Bit) + { + // + // the device can actually handle a transfer larger than 16bit, change to 32 bit + // + NtbFormat = NCM_SET_NTB_FORMAT_32_BIT; + } + + // + // set the format + // + Status = MbbBusSetNtbFormat(BusObject, NtbFormat); + + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + } + +Cleanup: + + return Status; +} + +ULONG +ProcessInterruptPipeRead( + PBUS_OBJECT BusObject, + __in_ecount(NewFragmentLength) PCUCHAR NewFragment, + ULONG NewFragmentLength, + __out_ecount(MessageBufferSize) PUCHAR CompleteMessageBuffer, + ULONG MessageBufferSize) + +{ + + ULONG CompleteMessageLength = 0; + PUSB_CDC_NOTIFICATION CdcNotification = NULL; + + ASSERT(MessageBufferSize == sizeof(BusObject->InterruptReassemnblyBuffer)); + + if (BusObject->CurrentOffset == 0) + { + // + // beggining of interrupt transfer + // + if ((NewFragmentLength >= sizeof(*CdcNotification)) && (NewFragmentLength <= sizeof(BusObject->InterruptReassemnblyBuffer))) + { + // + // big enough for a notification + // + CdcNotification = (PUSB_CDC_NOTIFICATION)NewFragment; + + if ((CdcNotification->bmRequestType == 0xa1)) + { + BusObject->ExpectLength = sizeof(*CdcNotification) + CdcNotification->wLength; + + RtlCopyMemory(&BusObject->InterruptReassemnblyBuffer[BusObject->CurrentOffset], NewFragment, NewFragmentLength); + + BusObject->CurrentOffset += NewFragmentLength; + } + else + { + // + // wrong request type, drop + // + } + } + else + { + // + // not big enough to be a cdc notification, drop + // + } + } + else + { + // + // we already have some of the data + // + if ((NewFragmentLength + BusObject->CurrentOffset) <= sizeof(BusObject->InterruptReassemnblyBuffer)) + { + // + // still room in the NewFragment + // + RtlCopyMemory(&BusObject->InterruptReassemnblyBuffer[BusObject->CurrentOffset], NewFragment, NewFragmentLength); + } + else + { + // + // over flow, Keep procssing until we get the whole thing so we don't get out of sync + // + } + BusObject->CurrentOffset += NewFragmentLength; + } + + if (BusObject->CurrentOffset < BusObject->ExpectLength) + { + // + // we don't have the whole thing yet, keep going + // + if (NewFragmentLength == 0) + { + // + // got a zero length transfer, reset the re-assembly state + BusObject->ExpectLength = 0; + BusObject->CurrentOffset = 0; + } + } + else + { + if (BusObject->CurrentOffset == BusObject->ExpectLength) + { + // + // got it all + // + if ((BusObject->CurrentOffset <= sizeof(BusObject->InterruptReassemnblyBuffer)) && (BusObject->CurrentOffset <= MessageBufferSize)) + { + // + // the whole thing fit in the NewFragment + // + RtlCopyMemory(CompleteMessageBuffer, BusObject->InterruptReassemnblyBuffer, BusObject->CurrentOffset); + + CompleteMessageLength = BusObject->CurrentOffset; + BusObject->CurrentOffset = 0; + } + else + { + // + // it is bigger than the re-assembly NewFragment, + // drop it + // + } + + // + // done with the current re-assembled NewFragment + // + BusObject->ExpectLength = 0; + BusObject->CurrentOffset = 0; + } + else + { + // + // current offset is beyond the what we expected + // + ASSERT(0); + } + } + + return CompleteMessageLength; +} + +NTSTATUS +WaitForResponseAvailible(PBUS_OBJECT BusObject, ULONG TimeOut) + +{ + NTSTATUS Status; + UCHAR IndicateBuffer[INTERRUPT_REASSEMBLY_BUFFER_SIZE]; + ULONG BufferLength = 0; + ULONG BytesTransfered = 0; + BOOLEAN ExitLoop = FALSE; + PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; + PUSB_CDC_NOTIFICATION Notification = NULL; + + usbDeviceContext = GetUsbDeviceContext(BusObject->WdfUsbDevice); + + BusObject->ExpectLength = 0; + BusObject->CurrentOffset = 0; + + while (!ExitLoop) + { + + Status = ReadInterrupt(BusObject, BusObject->SyncInterruptReadBuffer, usbDeviceContext->InterruptPipeMaxPacket, TimeOut, &BytesTransfered); + + if (NT_SUCCESS(Status)) + { + + BufferLength = ProcessInterruptPipeRead( + BusObject, BusObject->SyncInterruptReadBuffer, BytesTransfered, IndicateBuffer, sizeof(IndicateBuffer)); + + if (BufferLength == 0) + { + // + // + // don't have a complete message yet + // + continue; + } + else + { + if (BufferLength < sizeof(*Notification)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + goto Cleanup; + } + + Notification = (PUSB_CDC_NOTIFICATION)IndicateBuffer; + + if (Notification->bNotificationCode != USB_CDC_NOTIFICATION_RESPONSE_AVAILABLE) + { + continue; + } + } + } + else + { + goto Cleanup; + } + + ExitLoop = TRUE; + } + + Status = STATUS_SUCCESS; + +Cleanup: + + return Status; +} + +BOOLEAN IsUsbCapDeviceInfoValid(_In_ USB_CAP_DEVICE_INFO UsbCapDeviceInfo, _In_ ULONG CapResultLength) +{ + if (CapResultLength < sizeof(USB_CAP_DEVICE_INFO_HEADER)) + { + return FALSE; + } + switch (UsbCapDeviceInfo.DeviceInfoHeader.DeviceType) + { + case USB_CAP_DEVICE_TYPE_UDE_MBIM: __fallthrough; + case USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO: + // Only support version 1.0 now + if (UsbCapDeviceInfo.DeviceInfoHeader.DeviceMajorVersion == 0x1 && UsbCapDeviceInfo.DeviceInfoHeader.DeviceMinorVersion == 0x0) + { + return TRUE; + } + else + { + return FALSE; + } + default: return FALSE; + } +} + +/*++ + +Routine Description: + + Check if the bus type is Ude + +Arguments: + + BusHandle - identifies the instance of the bus layer. + +Return Value: + + TRUE - The bus type is Ude + FALSE - The bus type isn't Ude + +--*/ +BOOLEAN +MbbBusIsUde(_In_ MBB_BUS_HANDLE BusHandle) +{ + USB_CAP_DEVICE_TYPE DeviceType = ((PBUS_OBJECT)BusHandle)->UsbCapDeviceInfo.DeviceInfoHeader.DeviceType; + return (DeviceType == USB_CAP_DEVICE_TYPE_UDE_MBIM || DeviceType == USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO); +} diff --git a/network/wwan/cxwmbclass/wmbclass.h b/network/wwan/cxwmbclass/wmbclass.h deleted file mode 100644 index 343ee8f53..000000000 --- a/network/wwan/cxwmbclass/wmbclass.h +++ /dev/null @@ -1,1096 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -//////////////////////////////////////////////////////////////////////////////// -// -// DEFINES -// -//////////////////////////////////////////////////////////////////////////////// -#define WMBCLASS_INTERFACE_TYPE NdisInterfaceInternal; -#define WMBCLASS_CHECK_FOR_HANG_INTERVAL 3; -#define WMBCLASS_MAX_WOL_PATTERN (256) -#define WMBCLASS_MAX_MBIM_WOL_PATTERN (192) - - -#define MBB_DEFAULT_SESSION_ID 0 - -#define MBB_REGVAL_NETCFGID L"NetCfgInstanceId" -#define MBB_REGVAL_OVERRIDE_NAME L"AllowDriverToOverrideDeviceName" -#define MBB_REGVAL_RADIO_OFF L"RadioOff" -#define MBB_REGVAL_LAST_IPv4 L"LastIPv4" -#define MBB_REGVAL_LAST_IPv6 L"LastIPv6" -#define MBB_REGVAL_LAST_GWv4 L"LastGWv4" -#define MBB_REGVAL_LAST_GWv6 L"LastGWv6" -#define MBB_REGVAL_LAST_DNSv4 L"LastDNSv4" -#define MBB_REGVAL_LAST_DNSv6 L"LastDNSv6" - -#define MBB_LOCK_TAKEN TRUE -#define MBB_LOCK_NOT_TAKEN FALSE - -#define MBB_PSEUDO_IMEI L"002099001761481" -#define MBB_PSEUDO_ESN L"12816777215" - -#define MBB_MAC_ADDRESS_LENGTH 6 - - -#define MBB_MAX_SERVICE_ACTIVATION_BUFFER 0x10000 -#define MBB_MAX_READY_INFO_PHONE_NUMBERS 100 -#define MBB_MAX_PROVIDER_LIST_SIZE 1024 -#define MBB_MAX_PROVISIONED_CONTEXTS 1024 - -#define MBB_STATUS_INDICATION_ALREADY_SENT NDIS_STATUS_NOT_RECOGNIZED - -#define MBB_MAX_NUMBER_OF_PORTS 11 // including the default port - - -//////////////////////////////////////////////////////////////////////////////// -// -// TYPEDEFS -// -//////////////////////////////////////////////////////////////////////////////// - -// -// Forward declaration -// - -typedef struct _MBB_PORT MBB_PORT, *PMBB_PORT; - -typedef struct _MINIPORT_DRIVER_CONTEXT -{ - WDFDRIVER hDriver; - NDIS_HANDLE NdisDriverHandle; - HANDLE IpInterfaceNotificationHandle; - HANDLE IpRouteNotificationHandle; - HANDLE IpUnicastAddressNotificationHandle; - PVOID IpWorkItemManagerHandle; - NDIS_SPIN_LOCK AdapterListLock; - LIST_ENTRY AdapterList; - REGHANDLE TraceHandle; - ULONG CurrentTraceInstance; - REGHANDLE TraceHandleOpn; -} MINIPORT_DRIVER_CONTEXT, -*PMINIPORT_DRIVER_CONTEXT; - -typedef struct _MBB_OID_HANDLER_ENTRY MBB_OID_HANDLER_ENTRY; -typedef struct _MBB_OID_HANDLER_ENTRY* PMBB_OID_HANDLER_ENTRY; - -typedef struct _MBB_REQUEST_CONTEXT MBB_REQUEST_CONTEXT; -typedef struct _MBB_REQUEST_CONTEXT* PMBB_REQUEST_CONTEXT; - -typedef struct _MBB_REQUEST_MANAGER MBB_REQUEST_MANAGER; -typedef struct _MBB_REQUEST_MANAGER* PMBB_REQUEST_MANAGER; - -typedef struct _MINIPORT_ADAPTER_CONTEXT MINIPORT_ADAPTER_CONTEXT; -typedef struct _MINIPORT_ADAPTER_CONTEXT *PMINIPORT_ADAPTER_CONTEXT; - -typedef -__callback VOID -(*MBB_REQUEST_COMPLETION_CALLBACK)( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); - -typedef -__callback NDIS_STATUS -(*MBB_REQUEST_DISPATCH_ROUTINE)( - __in MBB_PROTOCOL_HANDLE AdapterHandle, - __in PMBB_REQUEST_CONTEXT Request - ); - -typedef -__callback VOID -(*MBB_REQUEST_RESPONSE_HANDLER)( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); -/*++ - Description - Callback invoked when the response is ready or was failed to retrieve. - - Parameters - __in PMBB_REQUEST_CONTEXT Request - In case of command response the request context used to send the encapsulated command. - In case of status indication arbitrary request context used to retrieve the status indication. - - __in NDIS_STATUS NdisStatus - Whether retrieving the response was successful. - This is used to distinguish whether the host was unsuccessful in retrieving a reponse or - whether the device completed the response with failure status. - - __in MBB_STATUS MbbStatus - If the host was successful in retrieving the response i.e. NdisStatus is NDIS_STATUS_SUCCESS - then the status that the device returned. - - __in_bcount_opt(InBufferSize) PUCHAR InBuffer - If the host was successful in retrieving the response i.e. NdisStatus is NDIS_STATUS_SUCCESS - and the device responded successfully i.e. MBB_STATUS_SUCCESS( ) then the response buffer. - - __in ULONG InBufferSize - If the host was successful in retrieving the response i.e. NdisStatus is NDIS_STATUS_SUCCESS - and the device responded successfully i.e. MBB_STATUS_SUCCESS( ) then the response buffer length. - - Return Value - None ---*/ - -typedef NDIS_STATUS -(*MBB_OID_SET_HANDLER)( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize - ); - -typedef NDIS_STATUS -(*MBB_OID_QUERY_HANDLER)( - __in PMBB_REQUEST_CONTEXT Request, - __in_bcount_opt(*InBufferSize) PUCHAR InBuffer, - __in PULONG InBufferSize, - __out_bcount_part_opt(*OutBufferSize,*OutBufferSize) PUCHAR OutBuffer, - __inout PULONG OutBufferSize - ); - -typedef VOID -(*MBB_OID_COMPLETION_HANDLER)( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus - ); - -typedef NDIS_STATUS -(*MBB_OID_RESPONSE_HANDLER)( - __in PMBB_REQUEST_CONTEXT Request, - __in NDIS_STATUS NdisStatus, - __in MBB_STATUS MbbStatus, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); - -struct _MBB_OID_HANDLER_ENTRY -{ - NDIS_OID Oid; - ULONG IsSettable:1; - ULONG IsQueryable:1; - ULONG IsSerialized:1; - ULONG IsIndicationRequired:1; - ULONG CompleteRequestOnSendComplete:1; - // - // Valid for InBuffers i.e. Sets and Methods - // - UCHAR NdisObjectHeaderType; - UCHAR NdisObjectHeaderRevision; - USHORT NdisObjectHeaderSize; - - MBB_OID_SET_HANDLER SetHandler; - ULONG MinSetInBufferSize; - - MBB_OID_QUERY_HANDLER QueryHandler; - ULONG MinQueryInBufferSize; - ULONG MinQueryOutBufferSize; - // - // Valid, if a Response CID is associated with this OID - // - MBB_COMMAND ResponseCommand; - ULONG ResponseBufferLength; - MBB_OID_RESPONSE_HANDLER ResponseHandler; - // - // Optional completion handler for cleanup on send failure. - // - MBB_OID_COMPLETION_HANDLER CompletionHandler; -}; - -typedef enum -{ - // - // Dispatch the request. Request may be queued behind others. - // - MbbRequestEventDispatch = 0, - // - // Request is current, start processing the request. - // - MbbRequestEventStart, - // - // Request was cancelled - // - MbbRequestEventCancel, - // - // Bus layer indicated (un)succesful sending of all fragments - // - MbbRequestEventSendComplete, - // - // A response matching the TransactionId of the request was received. - // - MbbRequestEventResponseReceived, - // - // Same as MbbRequestStateResponseReceived but with MBB_STATUS_MORE_DATA. - // - MbbRequestEventResponseReceivedMoreData, - // - // - // - MbbRequestEventMaximum - -} MBB_REQUEST_EVENT; - -typedef enum -{ - // - // Initial state, request is created and ready to be dispatched. - // If the request is cancelled in this state the request owner - // is not notified about the cancellation since the request - // is not dispatched yet and does not have a completion routine. - // - MbbRequestStateReady = 0, - // - // Request is queued for dispatch as requests are serialized. - // The request may be started immediately if its the current request - // or may have to wait for other requests to complete. When the request - // is cancelled in this state the completion callback is called with failure. - // - MbbRequestStateDispatching, - // - // Initial state, when not queued. - // Dispatch routine has sent all the fragments to the bus layer - // which is still sending them to the device. - // - MbbRequestStateSendPending, - // - // Bus layer completed sending all fragments to the device. - // The FSM notifies the CompletionCallback. - // - MbbRequestStateSendComplete, - // - // The host received response from the device matching the TransactionId - // of this request. The rquest will be completed to higher layers. - // The FSM notifies the ResponseAvailable callback. - // - MbbRequestStateResponseReceived, - // - // Same as MbbRequestStateResponseReceived but with MBB_STATUS_MORE_DATA. - // More MbbRequestEventResponseReceived or MbbRequestEventResponseReceivedMoreData - // are expected. - // - MbbRequestStateResponseReceivedMoreData, - // - // The request is cancelled. - // The device didnt respond within a defined amount of time. - // The request will complete with failure status. - // The FSM notifies the CompletionCallback / ResponseAvailable callback. - // - MbbRequestStateCancelled, - // - // Catch invalid state transitions. - // - MbbRequestStateInvalid, - // - // - // - MbbRequestStateMaximum - -} MBB_REQUEST_STATE; - -typedef struct -{ - ULONG InUse:1; - ULONG Allocated:1; - -} MBB_EVENT_FLAGS; - -typedef struct _MBB_EVENT_ENTRY -{ - LIST_ENTRY EventLink; - MBB_EVENT_FLAGS EventFlags; - MBB_REQUEST_EVENT Event; - PMBB_REQUEST_CONTEXT Request; - PVOID EventData; - ULONG EventDataLength; - -} MBB_EVENT_ENTRY, -*PMBB_EVENT_ENTRY; - -typedef struct _MBB_REASSEMBLE_CONTEXT -{ - PUCHAR FragmentBuffer; - ULONG FragmentBufferLength; - ULONG FragmentLength; - PUCHAR Buffer; - ULONG BufferLength; - ULONG BufferOffset; - ULONG DataLength; - ULONG TransactionId; - ULONG FragmentCount; - ULONG NextFragment; - NDIS_STATUS NdisStatus; - MBB_STATUS MbbStatus; - MBB_COMMAND Command; - -} MBB_REASSEMBLE_CONTEXT, -*PMBB_REASSEMBLE_CONTEXT; - -typedef -__callback VOID -(*MBB_DRAIN_COMPLETE)( - __in PVOID Context - ); - - -typedef struct _DRAIN_OBJECT { - - NDIS_SPIN_LOCK Lock; - ULONG Count; - BOOL Draining; - BOOL DrainComplete; - - MBB_DRAIN_COMPLETE DrainCompleteCallback; - PVOID Context; - -} DRAIN_OBJECT, *PDRAIN_OBJECT; - -VOID -InitDrainObject( - PDRAIN_OBJECT DrainObject, - MBB_DRAIN_COMPLETE DrainCompleteCallback, - PVOID Context - ); - -VOID -StartDrain( - PDRAIN_OBJECT DrainObject - ); - -VOID -DrainComplete( - PDRAIN_OBJECT DrainObject - ); - -BOOLEAN -DrainAddRef( - PDRAIN_OBJECT DrainObject - ); - -VOID -DrainRelease( - PDRAIN_OBJECT DrainObject - ); - -// -// MBB_NDIS_OID_STATE -// -// Oids have multi-states to correctly complete them -// without race condition between the dispatch thread -// and the completion thread. Note that request manager -// can call a completion routine if the request was -// cancelled or dispatch failed. Thus the oids completion -// handler may be called without the dispatch handler -// ever being called. All the different possibilities or -// states are tracked through the oid state. -// -typedef enum -{ - MbbNdisOidStateNone = 0, - // - // The oid is pending with request manager - // to be dispatched. The oid can get cancelled - // without the Oid Dispatch routine ever being - // called. If the Oid Completion routine runs - // at this state then it should - // - MbbNdisOidStatePending, - // - // Oid Dispatch routine is currently running. - // If the Oid completion routine runs during - // this state then it will defer the oid - // completion to the dispatch handler. - // - MbbNdisOidStateDispatching, - // - // Oid dispatch routine has completed. If the - // Oid completion routine runs after this point - // then it will complete the Oid. - // - MbbNdisOidStateDispatched, - // - // Oid completion routine has run. If the Dispatch - // routine finds this state then it means that the - // Oid completion routine has deferred the Oid - // competion. The Dispatch routine will complete Oid. - // - MbbNdisOidStateComplete, - MbbNdisOidStateMax - -} MBB_NDIS_OID_STATE; - -struct _MBB_REQUEST_CONTEXT -{ - // - // Request Management - // - - LIST_ENTRY ManagerLink; - ULONG RequestId; - ULONG TransactionId; - GUID ActivityId; - - // Controls the lifetime of the request. - // On creation the RefCount is set to 1. - // Destroy drops this initial RefCount. - // When the RefCount drops to zero request is freed. - ULONG ReferenceCount; - // Tracks the request. - // RequestManager->Lock is used to synchronize - // access to the fields of the request. - PMBB_REQUEST_MANAGER RequestManager; - // Event to wait for request to get into desired state - Send Complete, - // Response received - KEVENT WaitEvent; - - PMBB_OID_HANDLER_ENTRY OidHandler; - - // - // State Machine - // - - ULONGLONG DispatchTime; - MBB_REQUEST_STATE State; - MBB_REQUEST_STATE LastState; - MBB_REQUEST_EVENT LastEvent; - - // - // Pre-allocated resources for forward progress. - // - - MBB_EVENT_ENTRY EventEntries[MbbRequestEventMaximum]; - - // - // Per sub-component contexts - // - - // Valid if request was created for ndis oid. - struct - { - PNDIS_OID_REQUEST OidRequest; - PVOID OidRequestId; - NDIS_HANDLE OidRequestHandle; - NDIS_STATUS OidStatus; - BOOLEAN IsSetOid; - // synchronized with interlock - MBB_NDIS_OID_STATE OidState; - - } OidContext; - - struct - { - BOOLEAN IsSerialized; - BOOLEAN IsQueued; - LIST_ENTRY QueueLink; - LIST_ENTRY CancelLink; - LIST_ENTRY TimeoutLink; - MBB_REQUEST_DISPATCH_ROUTINE DispatchRoutine; - MBB_REQUEST_COMPLETION_CALLBACK CompletionCallback; - MBB_REQUEST_RESPONSE_HANDLER ResponseHandler; - - } ReqMgrContext; - - struct - { - PVOID DataToFreeOnCompletion; - PVOID DataToFreeOnResponse; - BOOLEAN IsIndication; - // - // Send Command - // - struct - { - // Static fields - ULONG FragmentLength; - ULONG FragmentCount; - PUCHAR Data; - ULONG DataLength; - MBB_COMMAND Command; - MBB_COMMAND_TYPE CommandType; - // Dynamic fields - BOOLEAN IsProcessing; - ULONG NextFragmentIndex; - ULONG FragmentSentCount; - NDIS_STATUS SendStatus; - - } Command; - // - // Get Response - // - MBB_REASSEMBLE_CONTEXT Response; - // - // Parameters - // - union { - struct { - WCHAR DeviceId[WWAN_DEVICEID_LEN]; - GUID CurrentQueriedDeviceService; - ULONG IsUssdCapsValid:1; - ULONG IsAuthCapsValid:1; - ULONG NdisDeviceCapsSize; - PNDIS_WWAN_DEVICE_CAPS NdisDeviceCaps; - } DeviceCaps; - - struct { - ULONG IsWwanEmergencyModeValid:1; - ULONG IsCdmaShortMsgSizeValid:1; - ULONG IsQueryReadyInfo:1; - ULONG IsFirstCid:1; - ULONG NdisReadyInfoSize; - PNDIS_WWAN_READY_INFO NdisReadyInfo; - WWAN_EMERGENCY_MODE WwanEmergencyMode; - UCHAR CdmaShortMsgSize; - } SubscriberReadyInfo; - - struct { - ULONG IsWwanAvailableDataClassValid:1; - ULONG IsQuery:1; - ULONG IsFirstCid:1; - ULONG NdisPacketServiceStateSize; - PNDIS_WWAN_PACKET_SERVICE_STATE NdisPacketServiceState; - ULONG AvailableDataClass; - } PacketServiceState; - - struct { - BOOLEAN Activate; - ULONG ConnectionId; - ULONG SessionId; - } Connect; - - struct { - MBB_CONNECTION_STATE ConnectionState; - ULONG SessionId; - } IpAddress; - struct { - // The radio state set that was requested - WWAN_RADIO SetAction; - } RadioState; - struct { - // Info about the external request - PMBB_SUBSCRIBE_EVENT_LIST ExtList; // Memory managed via DataToFreeOnResponse - ULONG ExtSize; - } EventSubscribe; - struct { - GUID DeviceServiceGuid; - ULONG SessionId; - MBB_DSS_LINK_STATE LinkState; - } DssSession; - - struct { - // used for sync device services subscription changes - BOOLEAN FullPower; - ULONG MediaSpecificWakeUpEvents; - ULONG WakeUpFlags; - } SyncDeviceServiceSubription; - struct { - BOOLEAN Set; - NDIS_PORT_NUMBER PortNumber; - } SetPacketFilter; - struct { - PMBB_PORT Port; - } NdisPortContext; - struct { - ULONG SessionId; - } ContextSessionId; - } Parameters; - - } HandlerContext; -}; - -typedef enum -{ - MbbTimerTypeRequest = 0, - MbbTimerTypeFragment, - MbbTimerTypeMaximum - -} MBB_TIMER_TYPE; - -typedef struct _MBB_TIMER_CONTEXT -{ - MBB_TIMER_TYPE TimerType; - ULONGLONG TimerArmTime; - NDIS_HANDLE TimerHandle; - ULONG TimerDelayInMS; - ULONG TimerPeriodInMS; - ULONG TimerToleranceInMS; - PNDIS_TIMER_FUNCTION TimerFunction; - PMBB_REQUEST_MANAGER RequestManager; - -} MBB_TIMER_CONTEXT, -*PMBB_TIMER_CONTEXT; - -typedef struct _MBB_REQUEST_MANAGER -{ - PMINIPORT_ADAPTER_CONTEXT AdapterContext; - LIST_ENTRY AllocatedRequestList; - LIST_ENTRY PendingRequestQueue; - MBB_TIMER_CONTEXT TimerContexts[MbbTimerTypeMaximum]; - PMBB_REQUEST_CONTEXT CurrentRequest; - NDIS_SPIN_LOCK Spinlock; - KEVENT NoAllocatedRequestEvent; - ULONG RequestIdCounter; - DRAIN_OBJECT DrainObject; - KEVENT DrainCompleteEvent; - // - // Pre-allocated resources for fragmentation & reassembly - // - struct - { - ULONG ControlFragmentLength; - ULONG BulkFragmentLength; - PVOID BufferManager; - BOOLEAN ReassembleInUse; - MBB_REASSEMBLE_CONTEXT Reassemble; - - } Fragmentation; - // - // Work Item - // - PVOID WorkItemManagerHandle; - // - // Request allocator - // - PVOID RequestAllocatorHandle; - // BOOLEAN to indicate whether the Request Manager is currently closed and Draining all the - // outstanding requests in the Queue. Used in the Surprise Removal Path - BOOLEAN IsClosed; - -} MBB_REQUEST_MANAGER, -*PMBB_REQUEST_MANAGER; - -typedef enum -{ - MbbDataPathTelmetryStatusNotReport = 0, - MbbDataPathTelmetryStatusReportSuccess, - MbbDataPathTelmetryStatusReportHang -} MBB_DATA_PATH_TELMETRY_STATUS; - -typedef struct _MBB_SEND_QUEUE -{ - // - // Queue state - // - NDIS_SPIN_LOCK Lock; - BOOLEAN ProcessingQueue; - DRAIN_OBJECT QueueDrainObject; - // - // Lookaside lists - // - NPAGED_LOOKASIDE_LIST NblLookasideList; - NPAGED_LOOKASIDE_LIST NtbLookasideList; - NPAGED_LOOKASIDE_LIST NbLookasideList; - // - // Track NTBs - // - ULONG ConcurrentSends; - ULONG MaxConcurrentSends; - LIST_ENTRY NtbQueue; - ULONG NtbSequence; - // - // Track NBLs - // - LIST_ENTRY NblTrackList; - LIST_ENTRY NblDispatchQueue; - KEVENT NblQueueEmptyEvent; - // - // Handles - // - PMINIPORT_ADAPTER_CONTEXT AdapterContext; - MBB_BUS_HANDLE BusHandle; - PCHAR PaddingBuffer; - -#if DBG - // - // Testing - // - PCHAR ScratchBuffer; - ULONG ScratchLength; -#endif - - // - // NBL pool for DSS - // - NDIS_HANDLE NblPool; - MBB_DATA_PATH_TELMETRY_STATUS LastDataPathTelemetryStatus; - -} MBB_SEND_QUEUE, -*PMBB_SEND_QUEUE; - -typedef struct _MBB_RECEIVE_QUEUE -{ - // - // Queue State - // - BOOLEAN LookasideList; - NDIS_SPIN_LOCK Lock; - KEVENT QueueEmptyEvent; - DRAIN_OBJECT QueueDrainObject; - // - // Track Receives - // - LIST_ENTRY ReceivedQueue; - // - // Resources - // - NDIS_HANDLE NblPool; - NPAGED_LOOKASIDE_LIST ReceiveLookasideList; - -} MBB_RECEIVE_QUEUE, -*PMBB_RECEIVE_QUEUE; - -typedef enum _STATE_CHANGE_TYPE { - - STATE_CHANGE_TYPE_PAUSE = 0, - STATE_CHANGE_TYPE_RESTART = 1, - STATE_CHANGE_TYPE_POWER = 2, - STATE_CHANGE_TYPE_RESET = 3, - STATE_CHANGE_TYPE_STALL_CLEAR = 4, - STATE_CHANGE_MAX =5 - -} STATE_CHANGE_TYPE, *PSTATE_CHANGE_TYPE; - -#define STATE_CHANGE_EVENT_RESERVE_COUNT (10) - -typedef struct _STATE_CHANGE_EVENT { - - LIST_ENTRY ListEntry; - STATE_CHANGE_TYPE EventType; - PVOID Context1; - PVOID Context2; - - union { - struct { - PMBB_REQUEST_CONTEXT Request; - NET_DEVICE_POWER_STATE NewPower; - } Power; - struct { - NTSTATUS PipeStartStatus; - } Reset; - }; - -} STATE_CHANGE_EVENT, *PSTATE_CHANGE_EVENT; - -typedef -__callback VOID -(*MBB_STATE_CHANGE_HANDLER)( - PSTATE_CHANGE_EVENT StateChange - ); - - - -typedef struct _ADAPTER_STATE { - - BOOLEAN ShuttingDown; - - BOOLEAN Started; - - NET_DEVICE_POWER_STATE CurrentPowerState; - - BOOLEAN Hung; - - PSTATE_CHANGE_EVENT RunningEvent; - - ULONG PendingActions; - - NDIS_SPIN_LOCK Lock; - NDIS_HANDLE WorkItem; - LIST_ENTRY ListEntry; - PSTATE_CHANGE_EVENT CurrentEvent; - - LIST_ENTRY FreeList; - - MBB_STATE_CHANGE_HANDLER Handlers[STATE_CHANGE_MAX]; - - KEVENT StallClearCompleteEvent; - -} ADAPTER_STATE, *PADAPTER_STATE; - -// Per-device service state -typedef struct _MBB_DS -{ - // Device service ID (from device) - GUID DeviceServiceId; - - // DSS state (from device) - WWAN_DEVICE_SERVICE_SESSION_CAPABILITY DSSCapability; - ULONG MaxDSSInstances; - - // Number of CIDs supported (from device) - ULONG CIDCount; - - // Pointer to the CID list (from device) - PULONG CIDList; - - -} MBB_DS, *PMBB_DS; - -// The state for all device services -typedef struct _MBB_DS_STATE -{ - // Number of supported services (from device) - ULONG ServicesCount; - - // Pointer to list of device services (from device) - PMBB_DS ServicesList; - - // Maximum number of DSS sessions (from device) - ULONG MaxDSSSessions; - - // Subscribe OID settings - ULONG ExtSubscribeListBufferSize; - PMBB_SUBSCRIBE_EVENT_LIST ExtSubscribeList; - -} MBB_DS_STATE, *PMBB_DS_STATE; - -typedef union -{ - ULONG Value; - struct - { - ULONG IsMultiCarrier:1; - ULONG IsUssdCapable:1; - ULONG IsSimAuthCapable:1; - ULONG IsAkaAuthCapable:1; - ULONG IsAkapAuthCapable:1; - ULONG IsShowIMSI:1; - ULONG ShutdownNotificationCapable:1; - ULONG IsPreshutdownCapable:1; - ULONG IsProvisionedContextV2Capable : 1; - ULONG IsNetworkBlacklistCapable : 1; - ULONG IsSARCapable : 1; - ULONG IsLTEAttachConfigCapable : 1; - ULONG IsMultiSIMCapable : 1; - ULONG IsUiccLowLevelCapable : 1; - ULONG IsDeviceCapsV2Capable : 1; - ULONG IsPcoCapable : 1; - ULONG IsDeviceResetCapable : 1; - ULONG IsBaseStationsInfoCapable : 1; - }; -} ADAPTER_FLAGS; - -typedef struct _POWER_FILTER_LOOKUP { - - ULONG PatternId; - BOOLEAN InUse; - ULONG MaskSize; - PUCHAR Mask; - PUCHAR Pattern; - NDIS_PORT_NUMBER PortNumber; -} POWER_FILTER_LOOKUP, *PPOWER_FILTER_LOOKUP; - -typedef struct _SESSIONID_PORTNUMBER_ENTRY -{ - // Indicates whether the session Id is in use or not - BOOLEAN InUse; - - // Valid only when InUse is set. Corresponds - // to the NDIS PORT number for this session - NDIS_PORT_NUMBER PortNumber; - -} SESSIONID_PORTNUMBER_ENTRY, *PSESSIONID_PORTNUMBER_ENTRY; - - -typedef struct _MINIPORT_ADAPTER_CONTEXT -{ - // - // NDIS information - // - NDIS_SPIN_LOCK Lock; - ULONG Reference; - NDIS_HANDLE MiniportAdapterHandle; - ULONG TraceInstance; - - NET_IFINDEX IfIndex; - NET_LUID NetLuid; - BOOLEAN OverrideDeviceName; - GUID NetCfgId; - LIST_ENTRY DriverLink; - UCHAR MACAddress[MBB_MAC_ADDRESS_LENGTH]; - // - // Bus information - // - PDEVICE_OBJECT Pdo; - PDEVICE_OBJECT Fdo; - PDEVICE_OBJECT NextDeviceObject; - ANSI_STRING FriendlyName; - MBB_BUS_HANDLE BusHandle; - MBB_BUS_PARAMETERS BusParams; - // - // Adapter State - // - ADAPTER_STATE AdapterState; - // - // Request processing - // - MBB_SEND_QUEUE SendQueue; - MBB_RECEIVE_QUEUE ReceiveQueue; - MBB_REQUEST_MANAGER RequestManagerAllocation; - PMBB_REQUEST_MANAGER RequestManager; - // - // Stats - // - ULONG64 MaxLinkSpeed; - ULONG64 CurrentLinkSpeed; - - ULONGLONG UplinkSpeed; - ULONGLONG DownlinkSpeed; - - ULONGLONG GenXmitFramesOk; - ULONGLONG GenRcvFramesOk; - NDIS_STATISTICS_INFO Stats; - - // Radio state: TRUE = OFF, FALSE = ON - BOOLEAN RadioOff; - - BOOLEAN AvailableDataClassValid; - ULONG AvailableDataClass; - ULONG AdapterDataClass; - ADAPTER_FLAGS AdapterFlags; - // Used for multi-mode adapters - MBB_CELLULAR_CLASS AdapterSupportedCellularClass; - MBB_CELLULAR_CLASS AdapterCurrentCellularClass; - - PPOWER_FILTER_LOOKUP PowerFilterTable; - - NDIS_MINIPORT_SYSPOWER_NOTIFY LastLowSystemPowerState; - - // - // Device services related state - // - MBB_DS_STATE DeviceServiceState; - - // - // Protects Port specific information i.e - // 1) NumberofPorts - // 2) PortList. - // 3) MaxActivatedContexts - // Separate lock is required to protect Port specific - // information to avoid contention for Adapter lock. - // - - NDIS_SPIN_LOCK PortsLock; - - /** - * List to hold the ports created on this adapter - */ - MBB_PORT* PortList[MBB_MAX_NUMBER_OF_PORTS]; - ULONG NumberOfPorts; - - // Indicates how many PDP contexts can this adapter(device) hold. - // This should come from OID_WWAN_DEVICE_CAPS - ULONG MaxActivatedContexts; - - NDIS_SPIN_LOCK SessionIdPortTableLock; - - SESSIONID_PORTNUMBER_ENTRY SessionIdPortTable[MBB_MAX_NUMBER_OF_PORTS]; - - BOOLEAN SurpriseRemoved; -} MINIPORT_ADAPTER_CONTEXT, -*PMINIPORT_ADAPTER_CONTEXT; - -extern MINIPORT_DRIVER_CONTEXT GlobalControl; - -// MBB services natively supported by Windows via OIDs -static GUID NativeMbnServices[] = -{ - MBB_UUID_BASIC_CONNECT_CONSTANT, - MBB_UUID_SMS_CONSTANT, - MBB_UUID_USSD_CONSTANT, - MBB_UUID_AUTH_CONSTANT, - MBB_UUID_DSS_CONSTANT, - MBB_UUID_BASIC_CONNECT_EXT_CONSTANT -}; - - -//////////////////////////////////////////////////////////////////////////////// -// -// PROTOTYPES -// -//////////////////////////////////////////////////////////////////////////////// -// -// Driver routines -// -_Acquires_lock_( Driver->AdapterListLock ) -__drv_raisesIRQL(DISPATCH_LEVEL) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_savesIRQLGlobal( NdisSpinLock, Driver ) -VOID -MbbDriverLockAdapterList( - __in PMINIPORT_DRIVER_CONTEXT Driver - ); - -_Releases_lock_( Driver->AdapterListLock ) -__drv_maxIRQL(DISPATCH_LEVEL) -__drv_minIRQL(DISPATCH_LEVEL) -__drv_restoresIRQLGlobal( NdisSpinLock, Driver ) -VOID -MbbDriverUnlockAdapterList( - __in PMINIPORT_DRIVER_CONTEXT Driver - ); - -VOID -MbbDriverAddAdapter( - __in PMINIPORT_DRIVER_CONTEXT Driver, - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -VOID -MbbDriverRemoveAdapter( - __in PMINIPORT_DRIVER_CONTEXT Driver, - __in PMINIPORT_ADAPTER_CONTEXT Adapter - ); - -PMINIPORT_ADAPTER_CONTEXT -MbbDriverFindAdapterByNetLuid( - __in PMINIPORT_DRIVER_CONTEXT Driver, - __in PNET_LUID NetLuid - ); -// -// NDIS Miniport routines -// -MINIPORT_OID_REQUEST MbbNdisMiniportOidRequest; -MINIPORT_CANCEL_OID_REQUEST MbbNdisMiniportCancelOidRequest; -MINIPORT_SEND_NET_BUFFER_LISTS MbbNdisMiniportSendNetBufferLists; -MINIPORT_CANCEL_SEND MbbNdisMiniportCancelSend; -MINIPORT_RETURN_NET_BUFFER_LISTS MbbNdisMiniportReturnNetBufferLists; - -MBB_BUS_HANDLE -MbbNdisGetBusHandle( - __in MBB_PROTOCOL_HANDLE AdapterHandle - ); - -VOID -MbbNdisReceiveCallback( - __in MBB_PROTOCOL_HANDLE ProtocolHandle, - __in MBB_RECEIVE_CONTEXT ReceiveContext, - __in PMDL Mdl - ); - -VOID -DrainCompleteCallback( - PVOID Context - ); - -PMBB_OID_HANDLER_ENTRY -MbbNdisGetOidHandlerByCommand( - __in PMBB_COMMAND Command - ); - -// Dss Send complete handler -VOID -MbbNdisDeviceServiceSessionSendComplete( - __in MBB_REQUEST_HANDLE RequestHandle, - __in NDIS_STATUS NdisStatus - ); - -// Dss Receive handler -NDIS_STATUS -MbbNdisDeviceServiceSessionReceive( - __in PMINIPORT_ADAPTER_CONTEXT AdapterContext, - __in ULONG SessionId, - __in_bcount_opt(InBufferSize) PUCHAR InBuffer, - __in ULONG InBufferSize - ); diff --git a/network/wwan/cxwmbclass/wmbclass.rc b/network/wwan/cxwmbclass/wmbclass.rc deleted file mode 100644 index e42268c29..000000000 --- a/network/wwan/cxwmbclass/wmbclass.rc +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -#include -#include -#include "wmbclassEvents.rc" - -/*-----------------------------------------------*/ -/* the following lines are specific to this file */ -/*-----------------------------------------------*/ - -#define VER_FILETYPE VFT_DRV - -#define VER_FILESUBTYPE VFT2_DRV_NETWORK - -#define VER_FILEDESCRIPTION_STR "Windows Mobile Broadband Class NDIS Miniport" - -#define VER_INTERNALNAME_STR "wmbclass.sys" -#define VER_ORIGINALFILENAME_STR "wmbclass.sys" - -#include "common.ver" From bcfbc7dccba3e814fc8df79c9b8f978a9d0045eb Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Fri, 28 Oct 2022 00:29:39 -0700 Subject: [PATCH 06/15] remove dup --- network/wwan/cxwmbclass/inc/precomp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/network/wwan/cxwmbclass/inc/precomp.h b/network/wwan/cxwmbclass/inc/precomp.h index 57a1aa3f2..2dcae53e6 100644 --- a/network/wwan/cxwmbclass/inc/precomp.h +++ b/network/wwan/cxwmbclass/inc/precomp.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include From 77d441d6dd30b6ecf9880798a66667666b891c87 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Fri, 28 Oct 2022 00:33:07 -0700 Subject: [PATCH 07/15] remove useless file --- network/wwan/cxwmbclass/inc/MapWwanMbb.h | 217 ----------------------- 1 file changed, 217 deletions(-) delete mode 100644 network/wwan/cxwmbclass/inc/MapWwanMbb.h diff --git a/network/wwan/cxwmbclass/inc/MapWwanMbb.h b/network/wwan/cxwmbclass/inc/MapWwanMbb.h deleted file mode 100644 index 8d695f273..000000000 --- a/network/wwan/cxwmbclass/inc/MapWwanMbb.h +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include - -#pragma once -//////////////////////////////////////////////////////////////////////////////// -// -// Table mapping between WWAN type enum to its corresponding MBB type enum -// payload or other way around. When update the table, please double -// check wwan.h and MbbMessages.h -// -//////////////////////////////////////////////////////////////////////////////// - -#pragma region To_WWAN_ENUM -WWAN_STATUS MbbStatusMapTableBasic[MBB_STATUS_BASIC_COUNT()] = { - // MBB_STATUS_SUCCESS = 0, - WWAN_STATUS_SUCCESS, - // MBB_STATUS_BUSY = 1, - WWAN_STATUS_BUSY, - // MBB_STATUS_FAILURE = 2, - WWAN_STATUS_FAILURE, - // MBB_STATUS_SIM_NOT_INSERTED = 3, - WWAN_STATUS_SIM_NOT_INSERTED, - // MBB_STATUS_BAD_SIM = 4, - WWAN_STATUS_BAD_SIM, - // MBB_STATUS_PIN_REQUIRED = 5, - WWAN_STATUS_PIN_REQUIRED, - // MBB_STATUS_PIN_DISABLED = 6, - WWAN_STATUS_PIN_DISABLED, - // MBB_STATUS_NOT_REGISTERED = 7, - WWAN_STATUS_NOT_REGISTERED, - // MBB_STATUS_PROVIDERS_NOT_FOUND = 8, - WWAN_STATUS_PROVIDERS_NOT_FOUND, - // MBB_STATUS_NO_DEVICE_SUPPORT = 9, - WWAN_STATUS_NO_DEVICE_SUPPORT, - // MBB_STATUS_PROVIDER_NOT_VISIBLE = 10, - WWAN_STATUS_PROVIDER_NOT_VISIBLE, - // MBB_STATUS_DATA_CLASS_NOT_AVAILABLE = 11, - WWAN_STATUS_DATA_CLASS_NOT_AVAILABLE, - // MBB_STATUS_PACKET_SVC_DETACHED = 12, - WWAN_STATUS_PACKET_SVC_DETACHED, - // MBB_STATUS_MAX_ACTIVATED_CONTEXTS = 13, - WWAN_STATUS_MAX_ACTIVATED_CONTEXTS, - // MBB_STATUS_NOT_INITIALIZED = 14, - WWAN_STATUS_NOT_INITIALIZED, - // MBB_STATUS_VOICE_CALL_IN_PROGRESS = 15, - WWAN_STATUS_VOICE_CALL_IN_PROGRESS, - // MBB_STATUS_CONTEXT_NOT_ACTIVATED = 16, - WWAN_STATUS_CONTEXT_NOT_ACTIVATED, - // MBB_STATUS_SERVICE_NOT_ACTIVATED = 17, - WWAN_STATUS_SERVICE_NOT_ACTIVATED, - // MBB_STATUS_INVALID_ACCESS_STRING = 18, - WWAN_STATUS_INVALID_ACCESS_STRING, - // MBB_STATUS_INVALID_USER_NAME_PWD = 19, - WWAN_STATUS_INVALID_USER_NAME_PWD, - // MBB_STATUS_RADIO_POWER_OFF = 20, - WWAN_STATUS_RADIO_POWER_OFF, - // MBB_STATUS_INVALID_PARAMETERS = 21, - WWAN_STATUS_INVALID_PARAMETERS, - // MBB_STATUS_READ_FAILURE = 22, - WWAN_STATUS_READ_FAILURE, - // MBB_STATUS_WRITE_FAILURE = 23, - WWAN_STATUS_WRITE_FAILURE, - // MBB_STATUS_DENIED_POLICY = 24, - WWAN_STATUS_DENIED_POLICY, - // MBIM_STATUS_NO_PHONEBOOK 25, - WWAN_STATUS_FAILURE, - // MBIM_STATUS_PARAMETER_TOO_LONG 26, - WWAN_STATUS_FAILURE, - // MBIM_STATUS_STK_BUSY 27, - WWAN_STATUS_FAILURE, - // MBIM_STATUS_OPERATION_NOT_ALLOWED 28, - WWAN_STATUS_NO_DEVICE_SUPPORT, - // MBIM_STATUS _MEMORY_FAILURE 29, - WWAN_STATUS_SMS_MEMORY_FAILURE, - // MBIM_STATUS_INVALID_MEMORY_INDEX 30, - WWAN_STATUS_SMS_INVALID_MEMORY_INDEX, - // MBIM_STATUS_MEMORY_FULL 31, - WWAN_STATUS_SMS_MEMORY_FULL, - // MBIM_STATUS _FILTER_NOT_SUPPORTED 32, - WWAN_STATUS_SMS_FILTER_NOT_SUPPORTED, - // MBIM_STATUS_DSS_INSTANCE_LIMIT 33, - WWAN_STATUS_FAILURE, - // MBIM_STATUS_INVALID_DEVICE_SERVICE_OPERATION 34, - WWAN_STATUS_FAILURE, - // MBIM_STATUS_AUTH_INCORRECT_AUTN 35, - WWAN_STATUS_AUTH_INCORRECT_AUTN, - // MBIM_STATUS_AUTH_SYNC_FAILURE 36, - WWAN_STATUS_AUTH_SYNC_FAILURE, - // MBIM_STATUS_AUTH_AMF_NOT_SET 37, - WWAN_STATUS_AUTH_AMF_NOT_SET, - // MBIM_STATUS_CONTEXT_NOT_SUPPORTED 38, - WWAN_STATUS_MORE_DATA, - // MBB_STATUS_SHAREABILITY_CONDITION_ERROR 39, - WWAN_STATUS_SHAREABILITY_CONDITION_ERROR, - // MBB_STATUS_PIN_FAILURE 40, - WWAN_STATUS_PIN_FAILURE, - // MBB_STATUS_NO_LTE_ATTACH_CONFIG 41, - WWAN_STATUS_NO_LTE_ATTACH_CONFIG - -}; - -WWAN_STATUS MbbStatusMapTableSms[MBB_STATUS_SMS_COUNT()] = { - - // MBB_STATUS_SMS_UNKNOWN_SMSC_ADDRESS = 100, - WWAN_STATUS_SMS_UNKNOWN_SMSC_ADDRESS, - // MBB_STATUS_SMS_NETWORK_TIMEOUT = 101, - WWAN_STATUS_SMS_NETWORK_TIMEOUT, - // MBB_STATUS_SMS_LANG_NOT_SUPPORTED = 102, - WWAN_STATUS_SMS_LANG_NOT_SUPPORTED, - // MBB_STATUS_SMS_ENCODING_NOT_SUPPORTED = 103, - WWAN_STATUS_SMS_ENCODING_NOT_SUPPORTED, - // MBB_STATUS_SMS_FORMAT_NOT_SUPPORTED = 104, - WWAN_STATUS_SMS_FORMAT_NOT_SUPPORTED, - // MBB_STATUS_SMS_MORE_DATA = 105, - WWAN_STATUS_SMS_MORE_DATA - -}; - -WWAN_STATUS MbbStatusMapTableUicc[MBB_STATUS_UICC_COUNT()] = { - - // MBB_STATUS_UICC_NO_LOGICAL_CHANNELS = 0x87430001, - WWAN_STATUS_UICC_NO_LOGICAL_CHANNELS, - // MBB_STATUS_UICC_SELECT_FAILED = 0x87430002, - WWAN_STATUS_UICC_SELECT_FAILED, - // MBB_STATUS_UICC_INVALID_LOGICAL_CHANNEL = 0x87430003, - WWAN_STATUS_UICC_INVALID_LOGICAL_CHANNEL - -}; - -WWAN_STATUS MbbStatusMapTable4_0[MBB_STATUS_4_0_COUNT()] = { - // MBB_STATUS_MATCHING_PDU_SESSION_FOUND = 200, - WWAN_STATUS_SESSION_ALREADY_EXISTS, - // MBB_STATUS_DISSOCIATION_NEEDED_FOR_APPLICATION = 201, - WWAN_STATUS_DISSOCIATION_NEEDED_FOR_APPLICATION, - // MBB_STATUS_ERROR_INVALID_SLOT = 202, - WWAN_STATUS_ERROR_INVALID_SLOT, - // MBB_STATUS_NO_MATCHING_URSP_RULE = 203, - WWAN_STATUS_NO_MATCHING_URSP_RULE, - // MBB_STATUS_NO_DEFAULT_URSP_RULE = 204, - WWAN_STATUS_NO_DEFAULT_URSP_RULE -}; - -// defining the maping table for IpTypes -// this implementation assume that the MBB_CONTEXT_IP_TYPE -// does not have gaps and will end with MbbContextIPTypeMaximum -WWAN_IP_TYPE MbbIpTypesMapTable[MbbContextIPTypeMaximum] = { - // MbbContextIPTypeDefault = 0, - WwanIPTypeDefault, - // MbbContextIPTypeIPv4 = 1, - WwanIPTypeIPv4, - // MbbContextIPTypeIPv6 = 2, - WwanIPTypeIPv6, - // MbbContextIPTypeIPv4v6 = 3, - WwanIPTypeIpv4v6, - // MbbContextIPTypeIPv4AndIPv6 = 4, - // IPv4AndIPv6 is reported as IPv4v6 - // SHOULD NOT be mapped to WwanIPTypeXlat!!!! - WwanIPTypeIpv4v6}; - -WWAN_CONFIGURATION_SOURCE MbbSourcesMapTable[MbbMsContextSourceMaximum] = { - // MbbMsContextSourceAdmin = 0, - WwanAdminProvisioned, - // MbbMsContextSourceUser = 1, - WwanUserProvisioned, - // MbbMsContextSourceOperator = 2, - WwanOperatorProvisioned, - // MbbMsContextSourceModem = 3, - WwanModemProvisioned, - // MbbMsContextSourceDevice = 4, - WwanDeviceProvisioned, -}; - -WWAN_CONTEXT_OPERATIONS MbbLteAttachOperationsMapTable[MbbMsLteAttachContextOperationMaximum] = { - // MbbMsLteAttachContextOperationDefault = 0, - WwanContextOperationDefault, - // MbbMsLteAttachContextOperationRestoreFactory = 1, - WwanContextOperationRestoreFactory, - // MbbMsLteAttachContextOperationMaximum = 2, -}; -#pragma endregion To_WWAN_ENUM - -#pragma region To_MBB_ENUM -MBB_CONTEXT_IP_TYPE WwanIpTypesMapTable[] = { - // WwanIPTypeDefault = 0, - MbbContextIPTypeDefault, - // WwanIPTypeIPv4, - MbbContextIPTypeIPv4, - // WwanIPTypeIPv6, - MbbContextIPTypeIPv6, - // WwanIPTypeIpv4v6, - MbbContextIPTypeIPv4v6, -}; - -MBB_BASICCONNECTEXT_CONTEXT_SOURCE WwanSourcsMapTable[WwanMaxProvisionSource] = { - // WwanUserProvisioned = 0, // the source is user(s) - MbbMsContextSourceUser, - // WwanAdminProvisioned, // the source is administrator - MbbMsContextSourceAdmin, - // WwanOperatorProvisioned, // the source is mobile operator - MbbMsContextSourceOperator, - // WwanDeviceProvisioned, // the source is device (such as MultiVariant), but not from modem - MbbMsContextSourceDevice, - // WwanModemProvisioned, // the source is modem (such as pre-configured in modem) - MbbMsContextSourceModem, -}; - -MBB_BASICCONNECTEXT_LTEATTACH_CONTEXT_OPERATIONS -WwanLteAttachOperationsMapTable[WwanContextOperationMaximum] = { - // WwanContextOperationDefault = 0, - MbbMsLteAttachContextOperationDefault, - // WwanContextOperationDelete = 1, - MbbMsLteAttachContextOperationMaximum, // no deletion operation for LTE Attach - // WwanContextOperationRestoreFactory = 2, - MbbMsLteAttachContextOperationRestoreFactory, - // WwanContextOperationMaximum = 3 -}; -#pragma endregion To_MBB_ENUM \ No newline at end of file From 5a1f1caeca7255c45b3569694ef72376bb539e50 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Fri, 28 Oct 2022 01:36:10 -0700 Subject: [PATCH 08/15] build pass with vs 2022 --- network/wwan/cxwmbclass/businit.cpp | 6 - .../wwan/cxwmbclass/cxwmbclass/cxwmbclass.sln | 35 ++++ .../cxwmbclass/cxwmbclass/cxwmbclass.inf | 118 +++++++++++++ .../cxwmbclass/cxwmbclass/cxwmbclass.vcxproj | 156 ++++++++++++++++++ .../cxwmbclass/cxwmbclass.vcxproj.filters | 119 +++++++++++++ network/wwan/cxwmbclass/datapipe.cpp | 3 - network/wwan/cxwmbclass/inc/WwanDrvCmn.h | 33 ---- network/wwan/cxwmbclass/inc/device.h | 1 + network/wwan/cxwmbclass/inc/mbbmessages.h | 11 +- network/wwan/cxwmbclass/inc/precomp.h | 4 +- network/wwan/cxwmbclass/inc/usbbus.h | 9 +- network/wwan/cxwmbclass/inc/util.h | 3 +- network/wwan/cxwmbclass/inc/utils.h | 2 +- network/wwan/cxwmbclass/txqueue.cpp | 4 +- network/wwan/cxwmbclass/utils.cpp | 3 +- 15 files changed, 443 insertions(+), 64 deletions(-) create mode 100644 network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.sln create mode 100644 network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf create mode 100644 network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj create mode 100644 network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters delete mode 100644 network/wwan/cxwmbclass/inc/WwanDrvCmn.h diff --git a/network/wwan/cxwmbclass/businit.cpp b/network/wwan/cxwmbclass/businit.cpp index 063415c02..33f045bc6 100644 --- a/network/wwan/cxwmbclass/businit.cpp +++ b/network/wwan/cxwmbclass/businit.cpp @@ -80,15 +80,12 @@ MbbBusInitializeByWdf( UCHAR numInterfaces; UCHAR interfaceIndex; UCHAR i; - UCHAR index; USHORT DescriptorSize = 0; - UCHAR DummyBuffer; UCHAR CurrentSetting; USHORT BulkInPacketSize = 0; WDF_USB_CONTINUOUS_READER_CONFIG ReaderConfig; PIRP UsbSsIrp = NULL; - USB_IDLE_CALLBACK_INFO UsbSsCallback; PBUS_OBJECT BusObject = NULL; @@ -1367,7 +1364,6 @@ VOID InterruptPipeReadComplete(__in WDFUSBPIPE Pipe, __in WDFMEMORY Memory, __in PVOID Buffer = NULL; PUSB_CDC_NOTIFICATION CdcNotification = NULL; PUSB_CDC_NOTIFICATION_SPEED_CHANGE CdcSpeedChangeNotification = NULL; - MBB_CONNECTION_STATE ConnectStateChange; ULONG TempBytesTransfered = (ULONG)NumBytesTransfered; UCHAR IndicateBuffer[INTERRUPT_REASSEMBLY_BUFFER_SIZE]; ULONG BufferLength = 0; @@ -1409,7 +1405,6 @@ MbbBusQueryBusParameters(__in MBB_BUS_HANDLE BusHandle, __out PMBB_BUS_PARAMETER { PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - NTSTATUS Status; RtlZeroMemory(BusParameters, sizeof(*BusParameters)); @@ -1943,7 +1938,6 @@ MbbBusClose(__in MBB_BUS_HANDLE BusHandle, __in ULONG TransactionId, __in BOOLEA MBB_CLOSE_MESSAGE CloseMessage; PMBB_CLOSE_DONE CloseDoneMessage = NULL; UCHAR ReadBuffer[256]; - WDF_USB_CONTINUOUS_READER_CONFIG ReaderConfig; PUSB_DEVICE_CONTEXT usbDeviceContext = NULL; diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.sln b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.sln new file mode 100644 index 000000000..249990f1e --- /dev/null +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cxwmbclass", "cxwmbclass\cxwmbclass.vcxproj", "{11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Debug|ARM64.Build.0 = Debug|ARM64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Debug|x64.ActiveCfg = Debug|x64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Debug|x64.Build.0 = Debug|x64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Debug|x64.Deploy.0 = Debug|x64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Release|ARM64.ActiveCfg = Release|ARM64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Release|ARM64.Build.0 = Release|ARM64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Release|ARM64.Deploy.0 = Release|ARM64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Release|x64.ActiveCfg = Release|x64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Release|x64.Build.0 = Release|x64 + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C}.Release|x64.Deploy.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3DEAC1E8-F245-49DC-AD26-8A3694201775} + EndGlobalSection +EndGlobal diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf new file mode 100644 index 000000000..3cdd74491 --- /dev/null +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf @@ -0,0 +1,118 @@ +;------------------------------------------------------------------------------- +; netwmbclass.inf +; +; Copyright (c) Microsoft Corporation. All rights reserved. + +[version] +Signature = "$Windows NT$" +Class = Net +ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} +Provider = %ManufacturerName% +CatalogFile=cxwmbclass.cat +DriverVer = ; will be filled in at build time by StampInf +PnpLockdown = 1 + +[SourceDisksNames] +3426=windows cd + +[SourceDisksFiles] +cxwmbclass.sys = 3426 + +[DestinationDirs] +DefaultDestDir=13 + +[Manufacturer] +%ManufacturerName% = Msft,NT$ARCH$ + +[Msft.NT$ARCH$] + ; DisplayName Section DeviceID + ; ----------- ------- -------- +%wmbclass.DeviceDesc% = wmbclass.ndi, USB\MS_COMP_MBIM +%wmbclass.DeviceDesc% = wmbclass.ndi, USB\class_02&subclass_0e&prot_00 + +;------------------------------------------------------------------------------- +; Adapter DDInstall and Services section +; for NetAdapter drivers +[wmbclass.ndi] +AddReg = wmbclass.Reg +CopyFiles = wmbclassCopyFiles +Characteristics = 0x4 ; NCF_PHYSICAL +BusType = 15 +*IfType = 243; IF_TYPE_WWANPP +*MediaType = 9; NdisMediumWirelessWan +*PhysicalMediaType = 8; NdisPhysicalMediumWirelessWan +EnableDhcp = 0; Disable DHCP + +[wmbclassCopyFiles] +cxwmbclass.sys,,,0x0100 + +[wmbclass.ndi.HW] +Include = pci.inf +Needs = PciD3ColdSupported.HW +AddReg = wmbclass.ndi.AddReg.HW + +[wmbclass.ndi.AddReg.HW] +HKR,,"AllowIdleIrpInD3",0x00010001,0x1 + +[wmbclass.ndi.Services] +AddService = %ServiceName%, 2, wmbclass.Service, wmbclass.EventLog + +; For mobile broadband drivers +[wmbclass.Reg] +HKR, Ndi, Service, 0, %ServiceName% +HKR, Ndi\Interfaces, UpperRange, 0, "flpp4, flpp6" +HKR, Ndi\Interfaces, LowerRange, 0, "ppip" +HKR, , AllowDriverToOverrideDeviceName, 0x00010001, 1 + +; standard INF keywords for NetAdapter drivers +; using AddReg directive so they will work when this INF being Includes/Needs + +HKR, NetworkInterface, *IfConnectorPresent, 0x00010001, 1 +HKR, NetworkInterface, *ConnectionType, 0x00010001, 1 +HKR, NetworkInterface, *DirectionType, 0x00010001, 0 +HKR, NetworkInterface, *AccessType, 0x00010001, 2 +HKR, NetworkInterface, *HardwareLoopback, 0x00010001, 0 +HKR, , NumberOfNetworkInterfaces, 0x00010001, 17 + +; Selective Suspend +HKR,Ndi\params\*SelectiveSuspend,ParamDesc,,%SelectiveSuspend% +HKR,Ndi\params\*SelectiveSuspend,default,,"1" +HKR,Ndi\params\*SelectiveSuspend,type,,"enum" +HKR,Ndi\params\*SelectiveSuspend\enum,0,,%Disabled% +HKR,Ndi\params\*SelectiveSuspend\enum,1,,%Enabled% + +;----------------------------------------------------------------------------- +; Driver and Service Section +; + +; For wmbclass.x drivers +[wmbclass.Service] +DisplayName = %wmbclass.Service.DispName% +ServiceType = 1 ;%SERVICE_KERNEL_DRIVER% +StartType = 3 ;%SERVICE_DEMAND_START% +ErrorControl = 1 ;%SERVICE_ERROR_NORMAL% +ServiceBinary = %13%\cxwmbclass.sys +LoadOrderGroup = NDIS + +[wmbclass.EventLog] +AddReg = wmbclass.AddEventLog.Reg + +[wmbclass.AddEventLog.Reg] +HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\netevent.dll" +HKR, , TypesSupported, 0x00010001, 7 + +;----------------------------------------------------------------------------- +; Non-localizable Strings +; +[Strings] +ServiceName = "cxwmbclass" + +;----------------------------------------------------------------------------- +; Localizable Strings +; +ManufacturerName = "Sample Code" +wmbclass.DeviceDesc = "Generic Mobile Broadband Adapter" +wmbclass.Service.DispName = "USB Mobile Broadband Adapter Driver" +Disabled = "Disabled" +Enabled = "Enabled" +SelectiveSuspend = "Selective Suspend" diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj new file mode 100644 index 000000000..2e08b1e57 --- /dev/null +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + {11CC63F7-F6D0-4CED-99BA-C5FDAE88D29C} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 12.0 + Debug + x64 + cxwmbclass + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + + + + + + + + + DbgengKernelDebugger + $(SolutionDir)\..\inc;$(IncludePath) + $(KIT_SHARED_INC_PATH_WDK)\netcx\shared\1.0;$(KM_IncludePath)\mbbcx\1.0;$(KIT_SHARED_INC_PATH_WDK);$(KM_IncludePath)\netcx\kmdf\adapter\2.3;$(ExternalIncludePath) + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + sha256 + + + 4748;%(DisableSpecificWarnings);4101;4189;4100;4267 + Level3 + + + $(WindowsDDK_LibraryPath)\x64\ndis.lib;$(WindowsDDK_LibraryPath)\x64\netio.lib;$(WindowsDDK_LibraryPath)\x64\usbd.lib;$(WindowsDDK_LibraryPath)\x64\usbdex.lib;$(WindowsDDK_LibraryPath)\x64\wdmguid.lib;$(WindowsDDK_LibraryPath)\x64\netcx\kmdf\adapter\2.3\netadaptercxstub.lib;$(WindowsDDK_LibraryPath)\x64\mbbcx\1.0\mbbcxstub.lib;%(AdditionalDependencies) + + + + + sha256 + + + + + sha256 + + + + + sha256 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters new file mode 100644 index 000000000..431229f6c --- /dev/null +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters @@ -0,0 +1,119 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Driver Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/network/wwan/cxwmbclass/datapipe.cpp b/network/wwan/cxwmbclass/datapipe.cpp index aaa607ced..4452b7617 100644 --- a/network/wwan/cxwmbclass/datapipe.cpp +++ b/network/wwan/cxwmbclass/datapipe.cpp @@ -199,7 +199,6 @@ NTSTATUS MbbUsbDeviceStartDataPipes(__in PUSB_DEVICE_CONTEXT usbDeviceContext) { NTSTATUS Status; - NTSTATUS TempStatus; WdfWaitLockAcquire(usbDeviceContext->PipeStateLock, NULL); @@ -263,9 +262,7 @@ MbbBusStartDataPipes(__in MBB_BUS_HANDLE BusHandle) VOID MbbUsbDeviceStopDataPipes(__in PUSB_DEVICE_CONTEXT usbDeviceContext) { - WDF_USB_INTERFACE_SELECT_SETTING_PARAMS SettingParams; WDFUSBINTERFACE UsbInterface = NULL; - NTSTATUS Status; WdfWaitLockAcquire(usbDeviceContext->PipeStateLock, NULL); diff --git a/network/wwan/cxwmbclass/inc/WwanDrvCmn.h b/network/wwan/cxwmbclass/inc/WwanDrvCmn.h deleted file mode 100644 index 6c9a76f46..000000000 --- a/network/wwan/cxwmbclass/inc/WwanDrvCmn.h +++ /dev/null @@ -1,33 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - WwanDrvCmn.h - -Abstract: - Contains common functions declarations used by WWAN - class driver and WWAN virtual miniport. - -Revision History: - When What - ---------- ---------------------------------------------- - 12-18-2012 Created - -Notes: - ---*/ -#pragma once - -EXTERN_C -VOID WwanAdjustDhcpSettings(__in NET_LUID AdapterNetLuid, __in GUID AdapterNetCfgId, __in BOOLEAN EnableDhcp); - -EXTERN_C -NDIS_STATUS -WwanUpdateIPStack( - __in NDIS_HANDLE MiniportAdapterHandle, - __in PWWAN_IP_ADDRESS_STATE IpAddressState, - __in NET_LUID AdapterNetLuid, - __in GUID AdapterNetCfgId, - __in ULONG AdapterIfIndex, - __in BOOLEAN IsDeviceReportedChange); diff --git a/network/wwan/cxwmbclass/inc/device.h b/network/wwan/cxwmbclass/inc/device.h index 519b4d719..ae5be1112 100644 --- a/network/wwan/cxwmbclass/inc/device.h +++ b/network/wwan/cxwmbclass/inc/device.h @@ -9,6 +9,7 @@ // Its context is similar to MINIPORT_ADAPTER_CONTEXT in wmbclass.sys. // // See wmbclass.h for the definition of MBB_DEVICE_CONTEXT +#pragma once typedef struct _WMBCLASS_DEVICE_CONTEXT { diff --git a/network/wwan/cxwmbclass/inc/mbbmessages.h b/network/wwan/cxwmbclass/inc/mbbmessages.h index eb7542072..33cc07379 100644 --- a/network/wwan/cxwmbclass/inc/mbbmessages.h +++ b/network/wwan/cxwmbclass/inc/mbbmessages.h @@ -20,13 +20,13 @@ #define __REQUIRED_RPCSAL_H_VERSION__ 100 #endif -#include "rpc.h" -#include "rpcndr.h" - +#if 0 +#include +#include #ifndef __RPCNDR_H_VERSION__ #error this stub requires an updated version of #endif /* __RPCNDR_H_VERSION__ */ - +#endif #ifndef __MbbMessages_h__ #define __MbbMessages_h__ @@ -3257,9 +3257,6 @@ typedef struct _MBB_WAKE_PACKET *PMBB_WAKE_PACKET; #include -extern RPC_IF_HANDLE __MIDL_itf_MbbMessages_0000_0000_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_MbbMessages_0000_0000_v0_0_s_ifspec; - /* Additional Prototypes for ALL interfaces */ /* end of Additional Prototypes */ diff --git a/network/wwan/cxwmbclass/inc/precomp.h b/network/wwan/cxwmbclass/inc/precomp.h index 2dcae53e6..c0ac2e6c5 100644 --- a/network/wwan/cxwmbclass/inc/precomp.h +++ b/network/wwan/cxwmbclass/inc/precomp.h @@ -3,6 +3,7 @@ #include #include + #include #include #include @@ -28,9 +29,10 @@ #include #include + #include "mbbncm.h" -#include "mbbmessages.h" +#include "mbbmessages.h" #define MBB_MAX_NUMBER_OF_SESSIONS 17 // including the default session for the physical/primary interface #define MBB_DEFAULT_SESSION_ID 0 // for physical/primay interface. Must be 0. Do NOT change it. #define MBB_INVALID_SESSION_ID MBB_MAX_NUMBER_OF_SESSIONS diff --git a/network/wwan/cxwmbclass/inc/usbbus.h b/network/wwan/cxwmbclass/inc/usbbus.h index 3fc87948c..dd2a0cca3 100644 --- a/network/wwan/cxwmbclass/inc/usbbus.h +++ b/network/wwan/cxwmbclass/inc/usbbus.h @@ -1,14 +1,7 @@ // // Copyright (C) Microsoft. All rights reserved. // - -#define ALLOCATE_PAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_PAGED, _y, 'UBMW') - -#define FREE_POOL(_x) \ - { \ - ExFreePool(_x); \ - _x = NULL; \ - }; +#pragma once #define INITIALIZE_PASSIVE_LOCK(__lock) KeInitializeGuardedMutex(__lock) diff --git a/network/wwan/cxwmbclass/inc/util.h b/network/wwan/cxwmbclass/inc/util.h index b42d5233f..675af5656 100644 --- a/network/wwan/cxwmbclass/inc/util.h +++ b/network/wwan/cxwmbclass/inc/util.h @@ -1,7 +1,7 @@ // // Copyright (c) 2010 Microsoft Corporation // - +#pragma once typedef enum { MbbPoolTagDefault = '0CBM', @@ -11,6 +11,7 @@ typedef enum MbbPoolTagMdlReceive = '6CBM' } MBB_POOL_TAG; +#define ALLOCATE_PAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_PAGED, _y, MbbPoolTagDefault) #define ALLOCATE_NONPAGED_POOL(_y) ExAllocatePool2(POOL_FLAG_NON_PAGED, _y, MbbPoolTagDefault) #define ALLOCATE_NONPAGED_POOL_WITH_TAG(_x, _y) ExAllocatePool2(POOL_FLAG_NON_PAGED, _x, _y) diff --git a/network/wwan/cxwmbclass/inc/utils.h b/network/wwan/cxwmbclass/inc/utils.h index 06b15264f..e7d06637f 100644 --- a/network/wwan/cxwmbclass/inc/utils.h +++ b/network/wwan/cxwmbclass/inc/utils.h @@ -1,7 +1,7 @@ // // Copyright (C) Microsoft. All rights reserved. // - +#pragma once NTSTATUS SendSyncControlCommand( __in WDFUSBDEVICE WdfUsbDevice, diff --git a/network/wwan/cxwmbclass/txqueue.cpp b/network/wwan/cxwmbclass/txqueue.cpp index 55fc5e7a9..3b233fb77 100644 --- a/network/wwan/cxwmbclass/txqueue.cpp +++ b/network/wwan/cxwmbclass/txqueue.cpp @@ -764,7 +764,7 @@ void EvtTxQueueAdvance(_In_ NETPACKETQUEUE TxQueue) NET_RING * pr = NetRingCollectionGetPacketRing(rings); while (pr->BeginIndex != pr->EndIndex) { - UINT32 const packetIndex = pr->BeginIndex; + UINT32 packetIndex = pr->BeginIndex; auto packet = NetRingGetPacketAtIndex(pr, packetIndex); if (packet->Ignore) { @@ -806,7 +806,7 @@ void EvtTxQueueAdvance(_In_ NETPACKETQUEUE TxQueue) break; } - UINT32 const packetIndex = pr->BeginIndex; + packetIndex = pr->BeginIndex; packet = NetRingGetPacketAtIndex(pr, packetIndex); } diff --git a/network/wwan/cxwmbclass/utils.cpp b/network/wwan/cxwmbclass/utils.cpp index 12d331c31..ec791ab44 100644 --- a/network/wwan/cxwmbclass/utils.cpp +++ b/network/wwan/cxwmbclass/utils.cpp @@ -2,7 +2,7 @@ // Copyright (C) Microsoft. All rights reserved. // #include - +#include "util.h" NTSTATUS SendSyncControlCommand( __in WDFUSBDEVICE WdfUsbDevice, @@ -107,7 +107,6 @@ ReadInterrupt(_In_ PBUS_OBJECT BusObject, _Inout_updates_bytes_(BufferLength) PU { NTSTATUS status; - WDF_OBJECT_ATTRIBUTES attributes; WDFMEMORY memHandle = NULL; WDFREQUEST request = NULL; From 023a7bb6c175d49f1845201348570c0ec0f021aa Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Fri, 28 Oct 2022 01:49:54 -0700 Subject: [PATCH 09/15] make all favor built --- .../cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj index 2e08b1e57..21a67422b 100644 --- a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj @@ -75,6 +75,8 @@ DbgengKernelDebugger + $(SolutionDir)\..\inc;$(IncludePath) + $(KIT_SHARED_INC_PATH_WDK)\netcx\shared\1.0;$(KM_IncludePath)\mbbcx\1.0;$(KIT_SHARED_INC_PATH_WDK);$(KM_IncludePath)\netcx\kmdf\adapter\2.3;$(ExternalIncludePath) DbgengKernelDebugger @@ -98,6 +100,12 @@ sha256 + + Level3 + + + $(WindowsDDK_LibraryPath)\x64\ndis.lib;$(WindowsDDK_LibraryPath)\x64\netio.lib;$(WindowsDDK_LibraryPath)\x64\usbd.lib;$(WindowsDDK_LibraryPath)\x64\usbdex.lib;$(WindowsDDK_LibraryPath)\x64\wdmguid.lib;$(WindowsDDK_LibraryPath)\x64\netcx\kmdf\adapter\2.3\netadaptercxstub.lib;$(WindowsDDK_LibraryPath)\x64\mbbcx\1.0\mbbcxstub.lib;%(AdditionalDependencies) + From c8024cfb0c349c7033af3464ffc7624f74342559 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Fri, 28 Oct 2022 01:59:02 -0700 Subject: [PATCH 10/15] update comment --- network/wwan/cxwmbclass/adapter.cpp | 6 +++--- network/wwan/cxwmbclass/device.cpp | 14 ++------------ network/wwan/cxwmbclass/driver.cpp | 5 ++--- network/wwan/cxwmbclass/inc/adapter.h | 4 ++++ network/wwan/cxwmbclass/inc/device.h | 9 --------- network/wwan/cxwmbclass/inc/power.h | 4 ++++ network/wwan/cxwmbclass/inc/precomp.h | 5 ++++- network/wwan/cxwmbclass/inc/rxqueue.h | 4 ++++ network/wwan/cxwmbclass/inc/txqueue.h | 3 +++ network/wwan/cxwmbclass/inc/util.h | 2 +- network/wwan/cxwmbclass/power.cpp | 5 ++--- network/wwan/cxwmbclass/rxqueue.cpp | 11 ++--------- network/wwan/cxwmbclass/txqueue.cpp | 5 ++--- 13 files changed, 33 insertions(+), 44 deletions(-) diff --git a/network/wwan/cxwmbclass/adapter.cpp b/network/wwan/cxwmbclass/adapter.cpp index 17d7e941a..ed60b427d 100644 --- a/network/wwan/cxwmbclass/adapter.cpp +++ b/network/wwan/cxwmbclass/adapter.cpp @@ -1,7 +1,7 @@ -//------------------------------------------------------------------------------- -// Net Adapter source file // -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. +// + #include "precomp.h" #include "device.h" diff --git a/network/wwan/cxwmbclass/device.cpp b/network/wwan/cxwmbclass/device.cpp index 1a7dfc958..0aadfc355 100644 --- a/network/wwan/cxwmbclass/device.cpp +++ b/network/wwan/cxwmbclass/device.cpp @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------- -// Net Adapter source file // -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. +// #include "precomp.h" @@ -58,12 +57,6 @@ _Use_decl_annotations_ VOID EvtMbbDeviceReceiveMbimFragment(WDFDEVICE Device, MB if (receiveStatus != STATUS_PENDING) { - // Note: There isn't a case where receiveStatus is STATUS_SUCCESS, it is either pending - // or an error code. The API signature itself is incomplete since it does not return how - // many bytes were read if the request was completed synchronously. Leaving a telemetry - // assert here in case someone changes MbbBusReceiveMessageFragment - //MICROSOFT_TELEMETRY_ASSERT_KM(NT_ERROR(receiveStatus)); - completionRoutine(deviceContext, Fragment, receiveStatus, 0); } } @@ -196,9 +189,6 @@ MbbInitializeHardware(_In_ PWMBCLASS_DEVICE_CONTEXT DeviceContext) mbimExVer); MbbDeviceSetMbimParameters(DeviceContext->WdfDevice, &mbimParams); - //MBB_DEVICE_OPTIONAL_PARAMETERS optionalParameters; - //MBB_DEVICE_OPTIONAL_PARAMETERS_INIT(&optionalParameters, manufacturer, model, MbbBusIsUde(DeviceContext->BusHandle)); - //MbbDeviceSetOptionalParameters(DeviceContext->WdfDevice, &optionalParameters); MBB_DEVICE_WAKE_CAPABILITIES mbbWakeCapabilities; MBB_DEVICE_WAKE_CAPABILITIES_INIT(&mbbWakeCapabilities); diff --git a/network/wwan/cxwmbclass/driver.cpp b/network/wwan/cxwmbclass/driver.cpp index 490472df2..e1c8bc69e 100644 --- a/network/wwan/cxwmbclass/driver.cpp +++ b/network/wwan/cxwmbclass/driver.cpp @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------- -// Net Adapter source file // -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. +// #include "precomp.h" diff --git a/network/wwan/cxwmbclass/inc/adapter.h b/network/wwan/cxwmbclass/inc/adapter.h index 09f83bc2a..236daad42 100644 --- a/network/wwan/cxwmbclass/inc/adapter.h +++ b/network/wwan/cxwmbclass/inc/adapter.h @@ -1,3 +1,7 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + #pragma once // packet and header sizes diff --git a/network/wwan/cxwmbclass/inc/device.h b/network/wwan/cxwmbclass/inc/device.h index ae5be1112..87d8c8c0f 100644 --- a/network/wwan/cxwmbclass/inc/device.h +++ b/network/wwan/cxwmbclass/inc/device.h @@ -1,14 +1,5 @@ #pragma once -// "Device" in nawmbclass.sys represents an MBB device (or a modem). It may be embbeded or USB-plugged. -// A device may contain multiple NetAdapter instances for the support of MPDP. -// Each NetAdapter instance in a device corresponds to one PDP context in the modem. -// Each NetAdapter instance in a device presents an IP interface to TCP/IP. -// -// "Device" in nawmbclass.sys is the equivalent of "Adapter" in wmbclass.sys. -// Its context is similar to MINIPORT_ADAPTER_CONTEXT in wmbclass.sys. -// -// See wmbclass.h for the definition of MBB_DEVICE_CONTEXT #pragma once typedef struct _WMBCLASS_DEVICE_CONTEXT diff --git a/network/wwan/cxwmbclass/inc/power.h b/network/wwan/cxwmbclass/inc/power.h index 4aa8593a0..0205fb8ee 100644 --- a/network/wwan/cxwmbclass/inc/power.h +++ b/network/wwan/cxwmbclass/inc/power.h @@ -1,3 +1,7 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + #pragma once EVT_WDF_DEVICE_D0_ENTRY EvtDeviceD0Entry; diff --git a/network/wwan/cxwmbclass/inc/precomp.h b/network/wwan/cxwmbclass/inc/precomp.h index c0ac2e6c5..a0821e500 100644 --- a/network/wwan/cxwmbclass/inc/precomp.h +++ b/network/wwan/cxwmbclass/inc/precomp.h @@ -1,5 +1,8 @@ -#pragma once +// +// Copyright (C) Microsoft. All rights reserved. +// +#pragma once #include #include diff --git a/network/wwan/cxwmbclass/inc/rxqueue.h b/network/wwan/cxwmbclass/inc/rxqueue.h index 0db01a789..fa57e6e05 100644 --- a/network/wwan/cxwmbclass/inc/rxqueue.h +++ b/network/wwan/cxwmbclass/inc/rxqueue.h @@ -1,3 +1,7 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// + #pragma once typedef struct _MBB_RXQUEUE_CONTEXT diff --git a/network/wwan/cxwmbclass/inc/txqueue.h b/network/wwan/cxwmbclass/inc/txqueue.h index 239a9f420..7bab9c076 100644 --- a/network/wwan/cxwmbclass/inc/txqueue.h +++ b/network/wwan/cxwmbclass/inc/txqueue.h @@ -1,3 +1,6 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// #pragma once typedef struct _MBB_TXQUEUE_CONTEXT diff --git a/network/wwan/cxwmbclass/inc/util.h b/network/wwan/cxwmbclass/inc/util.h index 675af5656..12d166b47 100644 --- a/network/wwan/cxwmbclass/inc/util.h +++ b/network/wwan/cxwmbclass/inc/util.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2010 Microsoft Corporation +// Copyright (C) Microsoft. All rights reserved. // #pragma once typedef enum diff --git a/network/wwan/cxwmbclass/power.cpp b/network/wwan/cxwmbclass/power.cpp index 5a67ed1a4..e0726975c 100644 --- a/network/wwan/cxwmbclass/power.cpp +++ b/network/wwan/cxwmbclass/power.cpp @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------- -// Net Adapter source file // -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. +// #include "precomp.h" diff --git a/network/wwan/cxwmbclass/rxqueue.cpp b/network/wwan/cxwmbclass/rxqueue.cpp index 947e020d0..836201a56 100644 --- a/network/wwan/cxwmbclass/rxqueue.cpp +++ b/network/wwan/cxwmbclass/rxqueue.cpp @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------- -// Net Adapter source file // -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. +// #include "precomp.h" @@ -255,15 +254,11 @@ MbbRecvNtbUnpackIpNdp32(_In_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext, _In_ PN NTSTATUS status = STATUS_SUCCESS; ULONG datagramCount = MBB_NDP32_GET_DATAGRAM_COUNT(Ndp32); -// NET_RING_PACKET_ITERATOR pi = NetRingGetAllPackets(RxQueueContext->DatapathDescriptor); -// NET_RING_FRAGMENT_ITERATOR fi = NetRingGetAllFragments(RxQueueContext->DatapathDescriptor); NET_RING * pr = NetRingCollectionGetPacketRing(RxQueueContext->DatapathDescriptor); NET_RING * fr = NetRingCollectionGetFragmentRing(RxQueueContext->DatapathDescriptor); while ((incompletedDatagram = MBB_NDP32_GET_DATAGRAM(Nth32, Ndp32, *IncompletedDatagramIndex)) != NULL) { - // If all packets have been unpacked, break to avoid inappropriate device which doesn't fully follow NCM protocol to have zero dwDatagramIndex and zero dwDatagramLength as a terminator. - // It will crash OS like bug https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/19970558 if (*IncompletedDatagramIndex >= datagramCount) { break; @@ -323,8 +318,6 @@ MbbRecvNtbUnpackIpNdp16(_In_ PMBB_RECEIVE_NDP_CONTEXT ReceiveNdpContext, _In_ PN while ((incompletedDatagram = MBB_NDP16_GET_DATAGRAM(Nth16, Ndp16, *IncompletedDatagramIndex)) != NULL) { - // If all packets have been unpacked, break to avoid inappropriate device which doesn't fully follow NCM protocol to have zero dwDatagramIndex and zero dwDatagramLength as a terminator. - // It will crash OS like bug https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/19970558 if (*IncompletedDatagramIndex >= datagramCount) { break; diff --git a/network/wwan/cxwmbclass/txqueue.cpp b/network/wwan/cxwmbclass/txqueue.cpp index 3b233fb77..9708b8b2a 100644 --- a/network/wwan/cxwmbclass/txqueue.cpp +++ b/network/wwan/cxwmbclass/txqueue.cpp @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------- -// Net Adapter source file // -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (C) Microsoft. All rights reserved. +// #include "precomp.h" From d918f939466047ec7fca680f87ea742ea75baddb Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Mon, 31 Oct 2022 18:01:09 -0700 Subject: [PATCH 11/15] remove fastio related code --- network/wwan/cxwmbclass/businit.cpp | 331 ++++++------------ .../cxwmbclass/cxwmbclass/cxwmbclass.vcxproj | 4 - .../cxwmbclass/cxwmbclass.vcxproj.filters | 12 - network/wwan/cxwmbclass/inc/BusFastIO.h | 35 -- network/wwan/cxwmbclass/inc/device.h | 4 +- network/wwan/cxwmbclass/inc/mbbfastio.h | 102 ------ network/wwan/cxwmbclass/inc/mbbmessages.h | 4 +- network/wwan/cxwmbclass/inc/precomp.h | 3 - network/wwan/cxwmbclass/inc/usbbus.h | 8 - network/wwan/cxwmbclass/selsuspend.cpp | 79 ----- 10 files changed, 106 insertions(+), 476 deletions(-) delete mode 100644 network/wwan/cxwmbclass/inc/BusFastIO.h delete mode 100644 network/wwan/cxwmbclass/inc/mbbfastio.h delete mode 100644 network/wwan/cxwmbclass/selsuspend.cpp diff --git a/network/wwan/cxwmbclass/businit.cpp b/network/wwan/cxwmbclass/businit.cpp index 33f045bc6..a4109adab 100644 --- a/network/wwan/cxwmbclass/businit.cpp +++ b/network/wwan/cxwmbclass/businit.cpp @@ -12,7 +12,7 @@ typedef struct _USB_DESCRIPTOR_HEADER BYTE bLength; BYTE bDescriptorType; -} USB_DESCRIPTOR_HEADER, *PUSB_DESCRIPTOR_HEADER; +} USB_DESCRIPTOR_HEADER, * PUSB_DESCRIPTOR_HEADER; #pragma pack(pop) @@ -89,7 +89,7 @@ MbbBusInitializeByWdf( PBUS_OBJECT BusObject = NULL; - USB_CAP_DEVICE_INFO usbCapDeviceInfo = {USB_CAP_DEVICE_TYPE_MAXIMUM, 0, 0, 0}; + USB_CAP_DEVICE_INFO usbCapDeviceInfo = { USB_CAP_DEVICE_TYPE_MAXIMUM, 0, 0, 0 }; ULONG capResultLength = 0; WDF_USB_DEVICE_INFORMATION deviceInformation; @@ -436,8 +436,8 @@ MbbBusInitializeByWdf( if (BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceType == USB_CAP_DEVICE_TYPE_UDE_MBIM) { BusObject->MaxBulkInTransfer = BusObject->NtbParam.dwNtbInMaxSize < MAX_HOST_NTB_SIZE_FOR_UDE_MBIM - ? BusObject->NtbParam.dwNtbInMaxSize - : MAX_HOST_NTB_SIZE_FOR_UDE_MBIM; + ? BusObject->NtbParam.dwNtbInMaxSize + : MAX_HOST_NTB_SIZE_FOR_UDE_MBIM; } else { @@ -675,8 +675,8 @@ MbbParseConfigDescriptor( if ((InterfaceDescriptor->bInterfaceClass == MBIM_CC_INTERFACE_CLASS) && ((InterfaceDescriptor->bInterfaceSubClass == MBIM_CC_INTERFACE_SUBCLASS)) && (InterfaceDescriptor->bInterfaceProtocol == MBIM_CC_INTERFACE_PROTOCOL || - InterfaceDescriptor->bInterfaceProtocol == MBIM_CC_INTERFACE_NBL_PROTOCOL || - InterfaceDescriptor->bInterfaceProtocol == MBIM_CC_INTERFACE_NETPACKET_PROTOCOL)) + InterfaceDescriptor->bInterfaceProtocol == MBIM_CC_INTERFACE_NBL_PROTOCOL || + InterfaceDescriptor->bInterfaceProtocol == MBIM_CC_INTERFACE_NETPACKET_PROTOCOL)) { *CommunicationClassInterface = InterfaceDescriptor->bInterfaceNumber; @@ -983,7 +983,7 @@ SetActivityIdForRequest(__in WDFREQUEST Request, __in LPGUID ActivityId) do { - GUID zeroGuid = {0}; + GUID zeroGuid = { 0 }; if (ActivityId == NULL || IsEqualGUID(*ActivityId, zeroGuid)) { @@ -1029,50 +1029,50 @@ MbbBusSendMessageFragment( __in LPGUID ActivityId, __in MBB_BUS_SEND_COMPLETION_CALLBACK SendCompletionCallback) -/* - Description - The protocol layer call this routine to request the bus layer to - send a message fragment. Fragmentation / Reassembly is handled by - the protocol layer and it will only handle fragments that are within - the maximum transfer size of the bus. + /* + Description + The protocol layer call this routine to request the bus layer to + send a message fragment. Fragmentation / Reassembly is handled by + the protocol layer and it will only handle fragments that are within + the maximum transfer size of the bus. - This routine is asynchronous and returns immediately after queueing - the transfer. The caller is notified of the completion through the - callback. + This routine is asynchronous and returns immediately after queueing + the transfer. The caller is notified of the completion through the + callback. - Parameters - __in MBB_BUS_HANDLE BusHandle, - BusHandle identifies the instance of the bus layer. + Parameters + __in MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. - __in MBB_REQUEST_HANDLE RequestHandle, - Identifies the request. + __in MBB_REQUEST_HANDLE RequestHandle, + Identifies the request. - __in PVOID MessageFragment, - The data payload that needs to be sent. + __in PVOID MessageFragment, + The data payload that needs to be sent. - __in ULONG FragmentLength, - Length of the data payload. This will not be greater than the - maximum transfer size supported by the bus. + __in ULONG FragmentLength, + Length of the data payload. This will not be greater than the + maximum transfer size supported by the bus. - __in LPGUID ActivityId, - The activity Id to be associated with this fragment transfer. - This activity Id will also be used by USB for logging USB events. + __in LPGUID ActivityId, + The activity Id to be associated with this fragment transfer. + This activity Id will also be used by USB for logging USB events. - __in MBB_BUS_SEND_COMPLETION_CALLBACK SendCompletionCallback - The completion callback routine that will be called by the bus - when the transfer is complete. + __in MBB_BUS_SEND_COMPLETION_CALLBACK SendCompletionCallback + The completion callback routine that will be called by the bus + when the transfer is complete. - Return Value + Return Value - NTSTATUS_SUCCESS - The transfer has completed successfully. SendCompletionCallback will NOT be called. + NTSTATUS_SUCCESS + The transfer has completed successfully. SendCompletionCallback will NOT be called. - NTSTATUS_PENDING - The transfer was queued. SendCompletionCallback will be called on completion. + NTSTATUS_PENDING + The transfer was queued. SendCompletionCallback will be called on completion. - Other failure code - The transfer could not be queued. SendCompletionCallback will NOT be called. -*/ + Other failure code + The transfer could not be queued. SendCompletionCallback will NOT be called. + */ { @@ -1173,7 +1173,7 @@ VOID ReceiveCompletionRoutine(__in WDFREQUEST Request, __in WDFIOTARGET Target, { PREQUEST_CONTEXT ReqContext = NULL; - GUID ActivityId = {0}; + GUID ActivityId = { 0 }; PIRP Irp = NULL; NTSTATUS Status = STATUS_INVALID_PARAMETER; @@ -1208,61 +1208,61 @@ MbbBusReceiveMessageFragment( _In_ ULONG FragmentLength, _In_ LPGUID ActivityId, _In_ MBB_BUS_RECEIVE_COMPLETION_CALLBACK ReceiveCompletionCallback) -/* - Description + /* + Description - Parameters + Parameters - Return Value + Return Value - NTSTATUS_SUCCESS - Initialization was successful. + NTSTATUS_SUCCESS + Initialization was successful. - Other failure code -*/ -/* - Description - The protocol layer call this routine to request the bus layer to - receive data from the device. Reassembly is handled by the protocol layer. + Other failure code + */ + /* + Description + The protocol layer call this routine to request the bus layer to + receive data from the device. Reassembly is handled by the protocol layer. - This routine is asynchronous and returns immediately after queueing - the transfer. The caller is notified of the completion through the - callback. + This routine is asynchronous and returns immediately after queueing + the transfer. The caller is notified of the completion through the + callback. - Parameters - _In_ MBB_BUS_HANDLE BusHandle, - BusHandle identifies the instance of the bus layer. + Parameters + _In_ MBB_BUS_HANDLE BusHandle, + BusHandle identifies the instance of the bus layer. - _In_ MBB_REQUEST_HANDLE RequestHandle, - Identifies the request. + _In_ MBB_REQUEST_HANDLE RequestHandle, + Identifies the request. - _In_ __drv_aliasesMem PVOID MessageFragment, - The data buffer that would be filled with the received data. + _In_ __drv_aliasesMem PVOID MessageFragment, + The data buffer that would be filled with the received data. - _In_ ULONG FragmentLength, - Length of the data requested from the device. This will not be - greater than the maximum transfer size supported by the bus. + _In_ ULONG FragmentLength, + Length of the data requested from the device. This will not be + greater than the maximum transfer size supported by the bus. - _In_ LPGUID ActivityId, - The activity Id to be associated with this fragment transfer. - This activity Id will also be used by USB for logging USB events. + _In_ LPGUID ActivityId, + The activity Id to be associated with this fragment transfer. + This activity Id will also be used by USB for logging USB events. - _In_ MBB_BUS_RECEIVE_COMPLETION_CALLBACK ReceiveCompletionCallback - The completion callback routine that will be called by the bus - when the transfer is complete. + _In_ MBB_BUS_RECEIVE_COMPLETION_CALLBACK ReceiveCompletionCallback + The completion callback routine that will be called by the bus + when the transfer is complete. - Return Value + Return Value - NTSTATUS_SUCCESS - The transfer has completed successfully. ReceiveCompletionCallback will NOT be called. + NTSTATUS_SUCCESS + The transfer has completed successfully. ReceiveCompletionCallback will NOT be called. - NTSTATUS_PENDING - The transfer was queued. ReceiveCompletionCallback will be called on completion. + NTSTATUS_PENDING + The transfer was queued. ReceiveCompletionCallback will be called on completion. - Other failure code - The transfer could not be queued. ReceiveCompletionCallback will NOT be called. -*/ + Other failure code + The transfer could not be queued. ReceiveCompletionCallback will NOT be called. + */ { WDF_USB_CONTROL_SETUP_PACKET packet; @@ -1477,146 +1477,32 @@ NTSTATUS MbbBusHandshake(_In_ PBUS_OBJECT BusObject, _In_ ULONG TransactionId, _ MBB_OPEN_MESSAGE_FASTIO OpenMessageFastIO; PMBB_OPEN_DONE_FASTIO OpenDoneMessageFastIO = NULL; - if (MbbBusIsFastIO(BusObject)) - { - if (FastIOSendNetBufferListsComplete == NULL || FastIOIndicateReceiveNetBufferLists == NULL) - { - Status = STATUS_NOT_SUPPORTED; - goto Cleanup; - } - RtlZeroMemory(&OpenMessageFastIO, sizeof(OpenMessageFastIO)); - - OpenMessageFastIO.MessageHeader.MessageType = MBB_MESSAGE_TYPE_OPEN; - OpenMessageFastIO.MessageHeader.MessageLength = sizeof(OpenMessageFastIO); - OpenMessageFastIO.MessageHeader.MessageTransactionId = TransactionId; - OpenMessageFastIO.MaximumControlTransfer = - BusObject->MaxControlChannelSize < MAX_CONTROL_MESSAGE_SIZE ? BusObject->MaxControlChannelSize : MAX_CONTROL_MESSAGE_SIZE; - OpenMessageFastIO.AdapterContext = BusObject->ProtocolHandle; - OpenMessageFastIO.SendNetBufferListsCompleteHandler = FastIOSendNetBufferListsComplete; - OpenMessageFastIO.ReceiveNetBufferListsHandler = FastIOIndicateReceiveNetBufferLists; - - do - { - - RetryCount++; - - Status = TransactControlChannel( - BusObject, - RetryCount * INITIAL_OPEN_TIMEOUT, - (PUCHAR)&OpenMessageFastIO, - sizeof(OpenMessageFastIO), - (PUCHAR)&ReadBuffer[0], - sizeof(ReadBuffer), - &BytesTransferred); - } while ((Status == STATUS_IO_TIMEOUT) && (RetryCount < MAX_OPEN_RETRY_ATTEMPTS)); - - if (NT_SUCCESS(Status)) - { - if (BytesTransferred < sizeof(*OpenDoneMessageFastIO)) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - } - - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - OpenDoneMessageFastIO = (PMBB_OPEN_DONE_FASTIO)&ReadBuffer[0]; + RtlZeroMemory(&OpenMessage, sizeof(OpenMessage)); - if ((OpenDoneMessageFastIO->MessageHeader.MessageType != MBB_MESSAGE_TYPE_OPEN_DONE) || - (OpenDoneMessageFastIO->MessageHeader.MessageLength < sizeof(MBB_OPEN_DONE_FASTIO)) || - (OpenDoneMessageFastIO->MessageHeader.MessageTransactionId != OpenMessageFastIO.MessageHeader.MessageTransactionId)) - { - Status = STATUS_NDIS_INVALID_DATA; - - goto Cleanup; - } - - if (OpenDoneMessageFastIO->MbbStatus != STATUS_SUCCESS) - { - Status = STATUS_OPEN_FAILED; - - goto Cleanup; - } + OpenMessage.MessageHeader.MessageType = MBB_MESSAGE_TYPE_OPEN; + OpenMessage.MessageHeader.MessageLength = sizeof(OpenMessage); + OpenMessage.MessageHeader.MessageTransactionId = TransactionId; + OpenMessage.MaximumControlTransfer = + BusObject->MaxControlChannelSize < MAX_CONTROL_MESSAGE_SIZE ? BusObject->MaxControlChannelSize : MAX_CONTROL_MESSAGE_SIZE; - if (BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceMajorVersion == 0x1 && - BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceMinorVersion == 0x0) - { - BusObject->ModemContext = OpenDoneMessageFastIO->ModemContext; - BusObject->SendNetBufferListsHandler = (FastIOSendNetBufferListsHandler)OpenDoneMessageFastIO->SendNetBufferListsHandler; - if (BusObject->SendNetBufferListsHandler == NULL) - { - Status = STATUS_OPEN_FAILED; - goto Cleanup; - } - BusObject->ReturnNetBufferListsHandler = (FastIOReturnNetBufferListsHandler)OpenDoneMessageFastIO->ReturnNetBufferListsHandler; - if (BusObject->ReturnNetBufferListsHandler == NULL) - { - Status = STATUS_OPEN_FAILED; - goto Cleanup; - } - BusObject->CancelSendHandler = (FastIOCancelSendHandler)OpenDoneMessageFastIO->CancelSendHandler; - if (BusObject->CancelSendHandler == NULL) - { - Status = STATUS_OPEN_FAILED; - goto Cleanup; - } - BusObject->HaltHandler = (FastIOHaltHandler)OpenDoneMessageFastIO->HaltHandler; - if (BusObject->HaltHandler == NULL) - { - Status = STATUS_OPEN_FAILED; - goto Cleanup; - } - BusObject->PauseHandler = (FastIOPauseHandler)OpenDoneMessageFastIO->PauseHandler; - if (BusObject->PauseHandler == NULL) - { - Status = STATUS_OPEN_FAILED; - goto Cleanup; - } - BusObject->ShutdownHandler = (FastIOShutdownHandler)OpenDoneMessageFastIO->ShutdownHandler; - BusObject->ResetHandler = (FastIOResetHandler)OpenDoneMessageFastIO->ResetHandler; - BusObject->RestartHandler = (FastIORestartHandler)OpenDoneMessageFastIO->RestartHandler; - if (BusObject->RestartHandler == NULL) - { - Status = STATUS_OPEN_FAILED; - goto Cleanup; - } - } - } - else + do { - RtlZeroMemory(&OpenMessage, sizeof(OpenMessage)); - - OpenMessage.MessageHeader.MessageType = MBB_MESSAGE_TYPE_OPEN; - OpenMessage.MessageHeader.MessageLength = sizeof(OpenMessage); - OpenMessage.MessageHeader.MessageTransactionId = TransactionId; - OpenMessage.MaximumControlTransfer = - BusObject->MaxControlChannelSize < MAX_CONTROL_MESSAGE_SIZE ? BusObject->MaxControlChannelSize : MAX_CONTROL_MESSAGE_SIZE; - - do - { - - RetryCount++; + RetryCount++; - Status = TransactControlChannel( - BusObject, RetryCount * INITIAL_OPEN_TIMEOUT, (PUCHAR)&OpenMessage, sizeof(OpenMessage), (PUCHAR)&ReadBuffer[0], sizeof(ReadBuffer), &BytesTransferred); - } while ((Status == STATUS_IO_TIMEOUT) && (RetryCount < MAX_OPEN_RETRY_ATTEMPTS)); + Status = TransactControlChannel( + BusObject, RetryCount * INITIAL_OPEN_TIMEOUT, (PUCHAR)&OpenMessage, sizeof(OpenMessage), (PUCHAR)&ReadBuffer[0], sizeof(ReadBuffer), &BytesTransferred); + } while ((Status == STATUS_IO_TIMEOUT) && (RetryCount < MAX_OPEN_RETRY_ATTEMPTS)); - if (NT_SUCCESS(Status)) - { - if (BytesTransferred < sizeof(*OpenDoneMessage)) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - } - - if (!NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) + { + if (BytesTransferred < sizeof(*OpenDoneMessage)) { - goto Cleanup; + Status = STATUS_INFO_LENGTH_MISMATCH; } + } + if (NT_SUCCESS(Status)) + { OpenDoneMessage = (PMBB_OPEN_DONE)&ReadBuffer[0]; if ((OpenDoneMessage->MessageHeader.MessageType != MBB_MESSAGE_TYPE_OPEN_DONE) || @@ -1624,29 +1510,12 @@ NTSTATUS MbbBusHandshake(_In_ PBUS_OBJECT BusObject, _In_ ULONG TransactionId, _ (OpenDoneMessage->MessageHeader.MessageTransactionId != OpenMessage.MessageHeader.MessageTransactionId)) { Status = STATUS_NDIS_INVALID_DATA; - - goto Cleanup; } - - if (OpenDoneMessage->MbbStatus != STATUS_SUCCESS) + else if (OpenDoneMessage->MbbStatus != STATUS_SUCCESS) { Status = STATUS_OPEN_FAILED; - - goto Cleanup; } } -Cleanup: - if (!NT_SUCCESS(Status)) - { - BusObject->SendNetBufferListsHandler = NULL; - BusObject->ReturnNetBufferListsHandler = NULL; - BusObject->CancelSendHandler = NULL; - BusObject->HaltHandler = NULL; - BusObject->PauseHandler = NULL; - BusObject->ShutdownHandler = NULL; - BusObject->ResetHandler = NULL; - BusObject->RestartHandler = NULL; - } return Status; } @@ -2034,4 +1903,4 @@ VOID MbbBusSetNotificationState(__in MBB_BUS_HANDLE BusHandle, __in BOOLEAN Enab } return; -} +} \ No newline at end of file diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj index 21a67422b..38c6e53ba 100644 --- a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj @@ -125,14 +125,12 @@ - - @@ -140,11 +138,9 @@ - - diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters index 431229f6c..383a12b3a 100644 --- a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters @@ -27,9 +27,6 @@ Source Files - - Source Files - Source Files @@ -48,9 +45,6 @@ Source Files - - Source Files - Source Files @@ -68,9 +62,6 @@ Header Files - - Header Files - Header Files @@ -80,9 +71,6 @@ Header Files - - Header Files - Header Files diff --git a/network/wwan/cxwmbclass/inc/BusFastIO.h b/network/wwan/cxwmbclass/inc/BusFastIO.h deleted file mode 100644 index fd396f2e3..000000000 --- a/network/wwan/cxwmbclass/inc/BusFastIO.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -// FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE FastIOSendNetBufferListsComplete; -// FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS FastIOIndicateReceiveNetBufferLists; - -_IRQL_requires_max_(DISPATCH_LEVEL) -EXTERN_C VOID MbbBusSendNetBufferLists(_In_ MBB_BUS_HANDLE BusHandle, _In_ PNET_BUFFER_LIST NetBufferList, _In_ ULONG SessionId, _In_ ULONG SendFlags); - -_IRQL_requires_max_(DISPATCH_LEVEL) -EXTERN_C VOID MbbBusReturnNetBufferLists(_In_ MBB_BUS_HANDLE BusHandle, _In_ PNET_BUFFER_LIST NetBufferList, _In_ ULONG ReturnFlags); - -_IRQL_requires_max_(DISPATCH_LEVEL) -EXTERN_C VOID MbbBusCancelSendHandler(_In_ MBB_BUS_HANDLE BusHandle, _In_ PVOID CancelId); - -_IRQL_requires_(PASSIVE_LEVEL) -EXTERN_C -VOID MbbBusHalt(_In_ MBB_BUS_HANDLE BusHandle, _In_ NDIS_HALT_ACTION HaltAction); - -_IRQL_requires_(PASSIVE_LEVEL) -EXTERN_C -NDIS_STATUS -MbbBusPause(_In_ MBB_BUS_HANDLE BusHandle); - -_When_(ShutdownAction == NdisShutdownPowerOff, _IRQL_requires_(PASSIVE_LEVEL)) - _When_(ShutdownAction == NdisShutdownBugCheck, _IRQL_requires_(HIGH_LEVEL)) - EXTERN_C VOID MbbBusShutdown(_In_ MBB_BUS_HANDLE BusHandle, _In_ NDIS_SHUTDOWN_ACTION ShutdownAction); - - _IRQL_requires_max_(DISPATCH_LEVEL) - EXTERN_C NDIS_STATUS MbbBusReset(_In_ MBB_BUS_HANDLE BusHandle); - - _IRQL_requires_max_(DISPATCH_LEVEL) - EXTERN_C NDIS_STATUS MbbBusRestart(_In_ MBB_BUS_HANDLE BusHandle); - - _IRQL_requires_max_(DISPATCH_LEVEL) - EXTERN_C BOOLEAN MbbBusIsFastIO(_In_ MBB_BUS_HANDLE BusHandle); \ No newline at end of file diff --git a/network/wwan/cxwmbclass/inc/device.h b/network/wwan/cxwmbclass/inc/device.h index 87d8c8c0f..a00ea7f40 100644 --- a/network/wwan/cxwmbclass/inc/device.h +++ b/network/wwan/cxwmbclass/inc/device.h @@ -1,4 +1,6 @@ -#pragma once +// +// Copyright (C) Microsoft. All rights reserved. +// #pragma once diff --git a/network/wwan/cxwmbclass/inc/mbbfastio.h b/network/wwan/cxwmbclass/inc/mbbfastio.h deleted file mode 100644 index 6b2114a2a..000000000 --- a/network/wwan/cxwmbclass/inc/mbbfastio.h +++ /dev/null @@ -1,102 +0,0 @@ -//This header file depends on and defines NDIS_SUPPORT_NDIS670 or higher - -#pragma once -#if (NTDDI_VERSION >= NTDDI_WIN10_RS2 || NDIS_SUPPORT_NDIS670) - -typedef -_IRQL_requires_max_(DISPATCH_LEVEL) -_Function_class_(FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE) -VOID -FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE( - _In_ PVOID MiniportAdapterContext, - _In_ PNET_BUFFER_LIST NetBufferList, - _In_ ULONG SendCompleteFlags - ); -typedef FASTIO_SEND_NET_BUFFER_LISTS_COMPLETE (*FastIOSendNetBufferListsCompleteHandler); -typedef -_IRQL_requires_max_(DISPATCH_LEVEL) -_Function_class_(FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS) -VOID -FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS( - _In_ PVOID MiniportAdapterContext, - _In_ PNET_BUFFER_LIST NetBufferList, - _In_ ULONG SessionId, - _In_ ULONG NumberOfNetBufferLists, - _In_ ULONG ReceiveFlags - ); -typedef FASTIO_INDICATE_RECEIVE_NET_BUFFER_LISTS (*FastIOIndicateReceiveNetBufferListsHandler); -typedef -_IRQL_requires_max_(DISPATCH_LEVEL) -_Function_class_(FASTIO_SEND_NET_BUFFER_LISTS) -VOID -FASTIO_SEND_NET_BUFFER_LISTS( - _In_ PVOID ModemContext, - _In_ PNET_BUFFER_LIST NetBufferList, - _In_ ULONG SessionId, - _In_ ULONG SendFlags - ); -typedef FASTIO_SEND_NET_BUFFER_LISTS (*FastIOSendNetBufferListsHandler); -typedef -_IRQL_requires_max_(DISPATCH_LEVEL) -_Function_class_(FASTIO_RETURN_NET_BUFFER_LISTS) -VOID -FASTIO_RETURN_NET_BUFFER_LISTS( - _In_ PVOID ModemContext, - _In_ PNET_BUFFER_LIST NetBufferList, - _In_ ULONG ReturnFlags - ); -typedef FASTIO_RETURN_NET_BUFFER_LISTS (*FastIOReturnNetBufferListsHandler); -typedef -_IRQL_requires_max_(DISPATCH_LEVEL) -_Function_class_(FASTIO_CANCEL_SEND) -VOID -FASTIO_CANCEL_SEND( - _In_ PVOID ModemContext, - _In_ PVOID CancelId - ); -typedef FASTIO_CANCEL_SEND (*FastIOCancelSendHandler); -typedef -_IRQL_requires_(PASSIVE_LEVEL) -_Function_class_(FASTIO_HALT) -VOID -FASTIO_HALT( - _In_ PVOID ModemContext, - _In_ NDIS_HALT_ACTION HaltAction - ); -typedef FASTIO_HALT (*FastIOHaltHandler); -typedef -_IRQL_requires_(PASSIVE_LEVEL) -_Function_class_(FASTIO_PAUSE) -NDIS_STATUS -FASTIO_PAUSE( - _In_ PVOID ModemContext - ); -typedef FASTIO_PAUSE (*FastIOPauseHandler); -typedef -_When_(ShutdownAction==NdisShutdownPowerOff, _IRQL_requires_(PASSIVE_LEVEL)) -_When_(ShutdownAction==NdisShutdownBugCheck, _IRQL_requires_(HIGH_LEVEL)) -_Function_class_(FASTIO_SHUTDOWN) -VOID -FASTIO_SHUTDOWN( - _In_ PVOID ModemContext, - _In_ NDIS_SHUTDOWN_ACTION ShutdownAction - ); -typedef FASTIO_SHUTDOWN (*FastIOShutdownHandler); -typedef -_IRQL_requires_max_(DISPATCH_LEVEL) -_Function_class_(FASTIO_RESET) -NDIS_STATUS -FASTIO_RESET( - _In_ PVOID ModemContext - ); -typedef FASTIO_RESET (*FastIOResetHandler); -typedef -_IRQL_requires_(PASSIVE_LEVEL) -_Function_class_(FASTIO_RESTART) -NDIS_STATUS -FASTIO_RESTART( - _In_ PVOID ModemContext - ); -typedef FASTIO_RESTART (*FastIORestartHandler); - -#endif // (NTDDI_VERSION >= NTDDI_WIN10_RS2 || NDIS_SUPPORT_NDIS670) diff --git a/network/wwan/cxwmbclass/inc/mbbmessages.h b/network/wwan/cxwmbclass/inc/mbbmessages.h index 33cc07379..61957009f 100644 --- a/network/wwan/cxwmbclass/inc/mbbmessages.h +++ b/network/wwan/cxwmbclass/inc/mbbmessages.h @@ -1,4 +1,6 @@ - +// +// Copyright (C) Microsoft. All rights reserved. +// /* this ALWAYS GENERATED file contains the definitions for the interfaces */ diff --git a/network/wwan/cxwmbclass/inc/precomp.h b/network/wwan/cxwmbclass/inc/precomp.h index a0821e500..706407ba0 100644 --- a/network/wwan/cxwmbclass/inc/precomp.h +++ b/network/wwan/cxwmbclass/inc/precomp.h @@ -26,8 +26,6 @@ #include -#include "mbbfastio.h" - #define INITGUID #include @@ -44,7 +42,6 @@ #define WMBCLASS_RADIO_STATE_ON 1 #include "BusInterface.h" -#include "BusFastIO.h" #include "align.h" #include "device.h" diff --git a/network/wwan/cxwmbclass/inc/usbbus.h b/network/wwan/cxwmbclass/inc/usbbus.h index dd2a0cca3..cca02f60a 100644 --- a/network/wwan/cxwmbclass/inc/usbbus.h +++ b/network/wwan/cxwmbclass/inc/usbbus.h @@ -146,14 +146,6 @@ typedef struct _BUS_OBJECT USB_CAP_DEVICE_INFO UsbCapDeviceInfo; PVOID ModemContext; - FastIOSendNetBufferListsHandler SendNetBufferListsHandler; - FastIOReturnNetBufferListsHandler ReturnNetBufferListsHandler; - FastIOCancelSendHandler CancelSendHandler; - FastIOHaltHandler HaltHandler; - FastIOPauseHandler PauseHandler; - FastIOShutdownHandler ShutdownHandler; - FastIOResetHandler ResetHandler; - FastIORestartHandler RestartHandler; } BUS_OBJECT, *PBUS_OBJECT; typedef struct _WDF_DEVICE_INFO diff --git a/network/wwan/cxwmbclass/selsuspend.cpp b/network/wwan/cxwmbclass/selsuspend.cpp deleted file mode 100644 index c2b2e2421..000000000 --- a/network/wwan/cxwmbclass/selsuspend.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// -#include - -_Function_class_(IO_COMPLETION_ROUTINE) -NTSTATUS -MbbUsbBusIdleRequestCompletion(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID Context) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)Context; - - KeSetEvent(&BusObject->UsbSsIrpComplete, IO_NO_INCREMENT, FALSE); - - (*BusObject->IdleNotificationComplete)(BusObject->ProtocolHandle, Irp->IoStatus.Status); - - return STATUS_MORE_PROCESSING_REQUIRED; -} - -NTSTATUS -MbbBusIdleNotification(__in MBB_BUS_HANDLE BusHandle, __in BOOLEAN ForceIdle) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - NTSTATUS Status = STATUS_SUCCESS; - PIO_STACK_LOCATION IoSp = NULL; - - // - // This routine is invoked by NDIS when it has detected that the miniport - // is idle. The miniport must prepare to issue its selective suspend IRP - // to the USB stack. The driver can return NDIS_STATUS_BUSY if it is - // not ready to go to idle at this moment; NDIS will then retry later. - // Otherwise, the miniport should return NDIS_STATUS_PENDING. - // - - KeResetEvent(&BusObject->UsbSsIrpComplete); - - IoReuseIrp(BusObject->UsbSsIrp, STATUS_NOT_SUPPORTED); - - IoSp = IoGetNextIrpStackLocation(BusObject->UsbSsIrp); - - IoSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; - - IoSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION; - IoSp->Parameters.DeviceIoControl.InputBufferLength = sizeof(BusObject->UsbSsCallback); - IoSp->Parameters.DeviceIoControl.Type3InputBuffer = &BusObject->UsbSsCallback; - - IoSetCompletionRoutine(BusObject->UsbSsIrp, MbbUsbBusIdleRequestCompletion, BusObject, TRUE, TRUE, TRUE); - - Status = IoCallDriver(BusObject->Fdo, BusObject->UsbSsIrp); - - if (!NT_SUCCESS(Status)) - { - KeSetEvent(&BusObject->UsbSsIrpComplete, IO_NO_INCREMENT, FALSE); - - return STATUS_UNSUCCESSFUL; - } - - return STATUS_PENDING; -} - -VOID MbbBusCancelIdleNotification(__in MBB_BUS_HANDLE BusHandle) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - - // This routine is called if NDIS needs to cancel an idle notification. - // All that is needed is to cancel the selective suspend IRP. - // - - IoCancelIrp(BusObject->UsbSsIrp); - - return; -} - -VOID MbbBusMiniportUsbIdle(PVOID Context) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)Context; - - (*BusObject->IdleConfirmCallback)(BusObject->ProtocolHandle, PowerDeviceD2); - return; -} From f908253cbabb8f44e433d8908725b8f93a7f10b7 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Mon, 31 Oct 2022 18:04:54 -0700 Subject: [PATCH 12/15] remove fastio --- network/wwan/cxwmbclass/BusFastIO.cpp | 85 --------------------------- 1 file changed, 85 deletions(-) delete mode 100644 network/wwan/cxwmbclass/BusFastIO.cpp diff --git a/network/wwan/cxwmbclass/BusFastIO.cpp b/network/wwan/cxwmbclass/BusFastIO.cpp deleted file mode 100644 index ad125d355..000000000 --- a/network/wwan/cxwmbclass/BusFastIO.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// -// Copyright (C) Microsoft. All rights reserved. -// - -#include - -VOID MbbBusSendNetBufferLists(_In_ MBB_BUS_HANDLE BusHandle, _In_ PNET_BUFFER_LIST NetBufferList, _In_ ULONG SessionId, _In_ ULONG SendFlags) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - BusObject->SendNetBufferListsHandler(BusObject->ModemContext, NetBufferList, SessionId, SendFlags); -} - -VOID MbbBusReturnNetBufferLists(_In_ MBB_BUS_HANDLE BusHandle, _In_ PNET_BUFFER_LIST NetBufferList, _In_ ULONG ReturnFlags) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - BusObject->ReturnNetBufferListsHandler(BusObject->ModemContext, NetBufferList, ReturnFlags); -} - -VOID MbbBusCancelSendHandler(_In_ MBB_BUS_HANDLE BusHandle, _In_ PVOID CancelId) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - BusObject->CancelSendHandler(BusObject->ModemContext, CancelId); -} - -VOID MbbBusHalt(_In_ MBB_BUS_HANDLE BusHandle, _In_ NDIS_HALT_ACTION HaltAction) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - if (BusObject->State == BUS_STATE_OPENED) - { - BusObject->HaltHandler(BusObject->ModemContext, HaltAction); - } -} - -_IRQL_requires_(PASSIVE_LEVEL) -NDIS_STATUS -MbbBusPause(_In_ MBB_BUS_HANDLE BusHandle) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - if (BusObject->State == BUS_STATE_OPENED) - { - Status = BusObject->PauseHandler(BusObject->ModemContext); - } - return Status; -} - -_When_(ShutdownAction == NdisShutdownPowerOff, _IRQL_requires_(PASSIVE_LEVEL)) - _When_(ShutdownAction == NdisShutdownBugCheck, _IRQL_requires_(HIGH_LEVEL)) VOID - MbbBusShutdown(_In_ MBB_BUS_HANDLE BusHandle, _In_ NDIS_SHUTDOWN_ACTION ShutdownAction) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - if (BusObject->ShutdownHandler && BusObject->State == BUS_STATE_OPENED) - { - BusObject->ShutdownHandler(BusObject->ModemContext, ShutdownAction); - } -} - -_IRQL_requires_max_(DISPATCH_LEVEL) NDIS_STATUS MbbBusReset(_In_ MBB_BUS_HANDLE BusHandle) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - if (BusObject->ResetHandler && BusObject->State == BUS_STATE_OPENED) - { - Status = BusObject->ResetHandler(BusObject->ModemContext); - } - return Status; -} - -_IRQL_requires_max_(DISPATCH_LEVEL) NDIS_STATUS MbbBusRestart(_In_ MBB_BUS_HANDLE BusHandle) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - if (BusObject->State == BUS_STATE_OPENED) - { - Status = BusObject->RestartHandler(BusObject->ModemContext); - } - return Status; -} - -BOOLEAN -MbbBusIsFastIO(_In_ MBB_BUS_HANDLE BusHandle) -{ - PBUS_OBJECT BusObject = (PBUS_OBJECT)BusHandle; - return (BusObject->UsbCapDeviceInfo.DeviceInfoHeader.DeviceType == USB_CAP_DEVICE_TYPE_UDE_MBIM_FASTIO); -} From 6c381baf274aff96786ac052c32be0fffbc106b3 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Wed, 2 Nov 2022 14:49:32 -0700 Subject: [PATCH 13/15] remove compatiable ID for building pass --- network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf index 3cdd74491..ed5ccc36e 100644 --- a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf @@ -27,8 +27,7 @@ DefaultDestDir=13 [Msft.NT$ARCH$] ; DisplayName Section DeviceID ; ----------- ------- -------- -%wmbclass.DeviceDesc% = wmbclass.ndi, USB\MS_COMP_MBIM -%wmbclass.DeviceDesc% = wmbclass.ndi, USB\class_02&subclass_0e&prot_00 +%wmbclass.DeviceDesc% = wmbclass.ndi, USB\VID_1199&PID_9071&MI_0C ;Sierra Wireless EM7430 Qualcomm Snapdragon X7 LTE-A ;------------------------------------------------------------------------------- ; Adapter DDInstall and Services section From 29f72dcb230f899c1658789a6de4b641360261cd Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Wed, 2 Nov 2022 15:32:32 -0700 Subject: [PATCH 14/15] build arm64 pass --- .../cxwmbclass/cxwmbclass/cxwmbclass.inf | 2 ++ .../cxwmbclass/cxwmbclass/cxwmbclass.vcxproj | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf index ed5ccc36e..69055bfbd 100644 --- a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf @@ -27,6 +27,8 @@ DefaultDestDir=13 [Msft.NT$ARCH$] ; DisplayName Section DeviceID ; ----------- ------- -------- +;%wmbclass.DeviceDesc% = wmbclass.ndi, USB\MS_COMP_MBIM +;%wmbclass.DeviceDesc% = wmbclass.ndi, USB\class_02&subclass_0e&prot_00 %wmbclass.DeviceDesc% = wmbclass.ndi, USB\VID_1199&PID_9071&MI_0C ;Sierra Wireless EM7430 Qualcomm Snapdragon X7 LTE-A ;------------------------------------------------------------------------------- diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj index 38c6e53ba..65a96ce53 100644 --- a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj @@ -80,9 +80,13 @@ DbgengKernelDebugger + $(SolutionDir)\..\inc;$(IncludePath) + $(KIT_SHARED_INC_PATH_WDK)\netcx\shared\1.0;$(KM_IncludePath)\mbbcx\1.0;$(KIT_SHARED_INC_PATH_WDK);$(KM_IncludePath)\netcx\kmdf\adapter\2.3;$(ExternalIncludePath) DbgengKernelDebugger + $(SolutionDir)\..\inc;$(IncludePath) + $(KIT_SHARED_INC_PATH_WDK)\netcx\shared\1.0;$(KM_IncludePath)\mbbcx\1.0;$(KIT_SHARED_INC_PATH_WDK);$(KM_IncludePath)\netcx\kmdf\adapter\2.3;$(ExternalIncludePath) @@ -111,11 +115,23 @@ sha256 + + Level3 + + + $(WindowsDDK_LibraryPath)\arm64\ndis.lib;$(WindowsDDK_LibraryPath)\arm64\netio.lib;$(WindowsDDK_LibraryPath)\arm64\usbd.lib;$(WindowsDDK_LibraryPath)\arm64\usbdex.lib;$(WindowsDDK_LibraryPath)\arm64\wdmguid.lib;$(WindowsDDK_LibraryPath)\arm64\netcx\kmdf\adapter\2.3\netadaptercxstub.lib;$(WindowsDDK_LibraryPath)\arm64\mbbcx\1.0\mbbcxstub.lib;%(AdditionalDependencies) + sha256 + + Level3 + + + $(WindowsDDK_LibraryPath)\arm64\ndis.lib;$(WindowsDDK_LibraryPath)\arm64\netio.lib;$(WindowsDDK_LibraryPath)\arm64\usbd.lib;$(WindowsDDK_LibraryPath)\arm64\usbdex.lib;$(WindowsDDK_LibraryPath)\arm64\wdmguid.lib;$(WindowsDDK_LibraryPath)\arm64\netcx\kmdf\adapter\2.3\netadaptercxstub.lib;$(WindowsDDK_LibraryPath)\arm64\mbbcx\1.0\mbbcxstub.lib;%(AdditionalDependencies) + From 28dfce82e433dcb3df9da259c2d4c0ac91438b11 Mon Sep 17 00:00:00 2001 From: AJ Tsai Date: Wed, 2 Nov 2022 17:46:50 -0700 Subject: [PATCH 15/15] modify file layout --- .../{cxwmbclass => }/cxwmbclass.sln | 0 .../{cxwmbclass => }/cxwmbclass.inf | 0 .../{cxwmbclass => }/cxwmbclass.vcxproj | 58 +++++++++---------- .../cxwmbclass.vcxproj.filters | 50 ++++++++-------- 4 files changed, 54 insertions(+), 54 deletions(-) rename network/wwan/cxwmbclass/{cxwmbclass => }/cxwmbclass.sln (100%) rename network/wwan/cxwmbclass/cxwmbclass/{cxwmbclass => }/cxwmbclass.inf (100%) rename network/wwan/cxwmbclass/cxwmbclass/{cxwmbclass => }/cxwmbclass.vcxproj (85%) rename network/wwan/cxwmbclass/cxwmbclass/{cxwmbclass => }/cxwmbclass.vcxproj.filters (69%) diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.sln b/network/wwan/cxwmbclass/cxwmbclass.sln similarity index 100% rename from network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.sln rename to network/wwan/cxwmbclass/cxwmbclass.sln diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.inf similarity index 100% rename from network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.inf rename to network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.inf diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj similarity index 85% rename from network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj rename to network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj index 65a96ce53..9d7d5b16b 100644 --- a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj @@ -70,22 +70,22 @@ DbgengKernelDebugger - $(SolutionDir)\..\inc;$(IncludePath) + $(SolutionDir)\inc;$(IncludePath) $(KIT_SHARED_INC_PATH_WDK)\netcx\shared\1.0;$(KM_IncludePath)\mbbcx\1.0;$(KIT_SHARED_INC_PATH_WDK);$(KM_IncludePath)\netcx\kmdf\adapter\2.3;$(ExternalIncludePath) DbgengKernelDebugger - $(SolutionDir)\..\inc;$(IncludePath) + $(SolutionDir)\inc;$(IncludePath) $(KIT_SHARED_INC_PATH_WDK)\netcx\shared\1.0;$(KM_IncludePath)\mbbcx\1.0;$(KIT_SHARED_INC_PATH_WDK);$(KM_IncludePath)\netcx\kmdf\adapter\2.3;$(ExternalIncludePath) DbgengKernelDebugger - $(SolutionDir)\..\inc;$(IncludePath) + $(SolutionDir)\inc;$(IncludePath) $(KIT_SHARED_INC_PATH_WDK)\netcx\shared\1.0;$(KM_IncludePath)\mbbcx\1.0;$(KIT_SHARED_INC_PATH_WDK);$(KM_IncludePath)\netcx\kmdf\adapter\2.3;$(ExternalIncludePath) DbgengKernelDebugger - $(SolutionDir)\..\inc;$(IncludePath) + $(SolutionDir)\inc;$(IncludePath) $(KIT_SHARED_INC_PATH_WDK)\netcx\shared\1.0;$(KM_IncludePath)\mbbcx\1.0;$(KIT_SHARED_INC_PATH_WDK);$(KM_IncludePath)\netcx\kmdf\adapter\2.3;$(ExternalIncludePath) @@ -140,35 +140,35 @@ - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + diff --git a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters similarity index 69% rename from network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters rename to network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters index 383a12b3a..7136df259 100644 --- a/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters +++ b/network/wwan/cxwmbclass/cxwmbclass/cxwmbclass.vcxproj.filters @@ -24,83 +24,83 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Resource Files