Add Windows Tunnel Mode Miniport Driver (ottmp) (#993)

* Add Windows Tunnel Mode Miniport Driver (ottmp)
This commit is contained in:
Nick Banks
2016-12-07 14:57:32 -08:00
committed by Jonathan Hui
parent 8b07e4a67d
commit 1d999ccea3
22 changed files with 4510 additions and 65 deletions
+2
View File
@@ -42,6 +42,8 @@ install:
- cmd: reg import .appveyor\ThreadEtw.reg
- ps: Restart-Computer -Force
- ps: Start-Sleep -s 10
before_build:
- cmd: ren "C:\Program Files (x86)\Windows Kits\10\include\00wdf" "wdf"
build:
project: etc/visual-studio/openthread.sln
verbosity: minimal
+3
View File
@@ -39,6 +39,9 @@ REM Copy the relavant binaries
copy build\bin\%Platform2%\%Configuration%\sys\otlwf\* release
copy build\bin\%Platform2%\%Configuration%\sys\otlwf.cer release
copy build\bin\%Platform2%\%Configuration%\sys\otlwf.pdb release\symbols
copy build\bin\%Platform2%\%Configuration%\sys\ottmp\* release
copy build\bin\%Platform2%\%Configuration%\sys\ottmp.cer release
copy build\bin\%Platform2%\%Configuration%\sys\ottmp.pdb release\symbols
copy build\bin\%Platform2%\%Configuration%\dll\otApi.dll release
copy build\bin\%Platform2%\%Configuration%\dll\otApi.lib release\libs
copy build\bin\%Platform2%\%Configuration%\dll\otApi.pdb release\symbols
+21
View File
@@ -59,6 +59,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenThread", "OpenThread.vc
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spinel_k", "spinel_k.vcxproj", "{A55766B5-58B6-4519-835E-5A4B7C164B5A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ottmp", "ottmp.vcxproj", "{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@@ -311,6 +313,24 @@ Global
{A55766B5-58B6-4519-835E-5A4B7C164B5A}.Release|x86.ActiveCfg = Release|Win32
{A55766B5-58B6-4519-835E-5A4B7C164B5A}.Release|x86.Build.0 = Release|Win32
{A55766B5-58B6-4519-835E-5A4B7C164B5A}.Release|x86.Deploy.0 = Release|Win32
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|ARM.ActiveCfg = Debug|ARM
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|ARM.Build.0 = Debug|ARM
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|ARM.Deploy.0 = Debug|ARM
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|x64.ActiveCfg = Debug|x64
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|x64.Build.0 = Debug|x64
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|x64.Deploy.0 = Debug|x64
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|x86.ActiveCfg = Debug|Win32
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|x86.Build.0 = Debug|Win32
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Debug|x86.Deploy.0 = Debug|Win32
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|ARM.ActiveCfg = Release|ARM
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|ARM.Build.0 = Release|ARM
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|ARM.Deploy.0 = Release|ARM
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|x64.ActiveCfg = Release|x64
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|x64.Build.0 = Release|x64
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|x64.Deploy.0 = Release|x64
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|x86.ActiveCfg = Release|Win32
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|x86.Build.0 = Release|Win32
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}.Release|x86.Deploy.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -334,5 +354,6 @@ Global
{D5577E51-FA31-4802-8669-1DB32805935E} = {35F6AB71-5BD2-4D53-8A51-D75CCD4CCC3D}
{F8C22844-9B93-4978-80DF-8AF2B37A7ABB} = {76EA541E-CAB1-4DB5-A39F-E3DB2A78CDDD}
{A55766B5-58B6-4519-835E-5A4B7C164B5A} = {95BD0669-04C8-4EEB-B3CC-0535B03F4468}
{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D} = {61E8A4A0-8138-49DB-97B4-3BEC87C8E133}
EndGlobalSection
EndGlobal
+102
View File
@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="openthread.configuration.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{1EAFF7C8-8215-4EDA-83B2-EEB56CECE84D}</ProjectGuid>
<TemplateGuid>{497e31cb-056b-4f31-abb8-447fd55ee5a5}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<RootNamespace>Thread</RootNamespace>
<TargetVersion>Windows10</TargetVersion>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup>
<OutDir>..\..\build\bin\$(Platform)\$(Configuration)\sys\</OutDir>
<IntDir>..\..\build\obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreProcessorDefinitions>
%(PreProcessorDefinitions);
NDIS_MINIPORT_DRIVER=1;
NDIS_WDM=1;
NDIS650_MINIPORT=1;
OTTMP_LEGACY=1;
</PreProcessorDefinitions>
<AdditionalIncludeDirectories>
%(AdditionalIncludeDirectories);
..\..\include;
..\..\examples\drivers\windows\include;
..\..\examples\drivers\windows\ottmp;
</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>%(DisableSpecificWarnings);4200;4201;4214</DisableSpecificWarnings>
<WppEnabled>true</WppEnabled>
<WppScanConfigurationData>..\..\include\platform\logging-windows.h</WppScanConfigurationData>
<WppAdditionalOptions>-km %(WppAdditionalOptions)</WppAdditionalOptions>
<WppModuleName>ottmp</WppModuleName>
<WppSearchString>WPP_INIT_TRACING</WppSearchString>
<EnablePREfast>true</EnablePREfast>
</ClCompile>
<ResourceCompile>
<PreProcessorDefinitions>
%(PreProcessorDefinitions);
NDIS_MINIPORT_DRIVER=1;
NDIS_WDM=1;
NDIS650_MINIPORT=1;
OTTMP_LEGACY=1;
</PreProcessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..;.;</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>
%(AdditionalDependencies);
ndis.lib;
</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command Condition="'$(Platform)'=='ARM'">inf2cat /driver:$(TargetDir) /os:8_ARM</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\examples\drivers\windows\ottmp\adapter.cpp" />
<ClCompile Include="..\..\examples\drivers\windows\ottmp\device.cpp" />
<ClCompile Include="..\..\examples\drivers\windows\ottmp\driver.cpp" />
<ClCompile Include="..\..\examples\drivers\windows\ottmp\hdlc.cpp" />
<ClCompile Include="..\..\examples\drivers\windows\ottmp\oid.cpp" />
<ClCompile Include="..\..\examples\drivers\windows\ottmp\serial.cpp" />
<ResourceCompile Include="..\..\examples\drivers\windows\ottmp\ottmp.rc" />
<Inf Include="..\..\examples\drivers\windows\ottmp\ottmp.inf" />
<ClInclude Include="..\..\examples\drivers\windows\ottmp\adapter.hpp" />
<ClInclude Include="..\..\examples\drivers\windows\ottmp\device.hpp" />
<ClInclude Include="..\..\examples\drivers\windows\ottmp\driver.hpp" />
<ClInclude Include="..\..\examples\drivers\windows\ottmp\hardware.hpp" />
<ClInclude Include="..\..\examples\drivers\windows\ottmp\hdlc.hpp" />
<ClInclude Include="..\..\examples\drivers\windows\ottmp\oid.hpp" />
<ClInclude Include="..\..\examples\drivers\windows\ottmp\pch.hpp" />
<ClInclude Include="..\..\examples\drivers\windows\ottmp\serial.hpp" />
</ItemGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{BED10704-BFDA-427C-BB01-B08F20AB1718}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{A6C61B28-961C-4B63-892B-A7E5EB2A4B3E}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{0CBFC63C-11CB-4E5F-95F1-187BE3F6DA44}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Driver Files">
<UniqueIdentifier>{6C2BAFD4-E244-4FF2-A002-FBCCF14AFA9D}</UniqueIdentifier>
<Extensions>inf;inv;inx;mof;mc;</Extensions>
</Filter>
</ItemGroup>
</Project>
+63 -65
View File
@@ -26,83 +26,81 @@
; POSSIBILITY OF SUCH DAMAGE.
;
[version]
; Do not change these values
Signature = "$Windows NT$"
Class = NetService
ClassGUID = {4D36E974-E325-11CE-BFC1-08002BE10318}
Provider = %openthread%
DriverVer =
CatalogFile = otLwf.cat
[Version]
Signature = "$Windows NT$"
Class = NetService
ClassGUID = {4D36E974-E325-11CE-BFC1-08002BE10318}
Provider = %OpenThread%
DriverVer =
PnpLockDown = 1
CatalogFile = otLwf.cat
[Manufacturer]
%openthread%=OpenThread,NT$ARCH$
%OpenThread% = OpenThread,NT$ARCH$
; otLwf can be used with netcfg.exe to install/uninstall the driver.
[OpenThread.NT$ARCH$]
%otLwf_Desc%=Install, otLwf
%otlwf.DeviceDesc% = otlwf.ndi, otLwf
;-------------------------------------------------------------------------
; Installation Section
;-------------------------------------------------------------------------
[Install]
AddReg=Inst_Ndi
Characteristics=0x40000
NetCfgInstanceId="{B3A3845A-164E-4727-B12E-32B8DCE1F6CD}"
;-------------------------------------------------------------------------------
; OpenThread NDIS Filter Driver
;-------------------------------------------------------------------------------
[otlwf.ndi]
Characteristics = 0x40000
NetCfgInstanceId = "{B3A3845A-164E-4727-B12E-32B8DCE1F6CD}"
AddReg = otlwf.Reg
Copyfiles = otLwf.CopyFiles
Copyfiles = otLwf.copyfiles.sys
[otlwf.ndi.Services]
AddService = otLwf, , otlwf.Service
[otlwf.ndi.Remove.Services]
; The SPSVCINST_STOPSERVICE flag instructs SCM to stop the NT service
; before uninstalling the driver.
DelService = otLwf, 0x200 ; SPSVCINST_STOPSERVICE
;-------------------------------------------------------------------------------
; OpenThread NDIS Filter Common
;-------------------------------------------------------------------------------
[otlwf.Reg]
HKR, Ndi, Service, , "otLwf"
HKR, Ndi, CoServices, 0x00010000, "otLwf"
HKR, Ndi, FilterClass, , ms_medium_converter_top
HKR, Ndi, FilterType, 0x00010001, 0x00000002
HKR, Ndi, FilterRunType, 0x00010001, 0x00000002 ;OPTIONAL filter
HKR, Ndi\Interfaces, UpperRange, , "noupper"
HKR, Ndi\Interfaces, LowerRange, , "nolower"
HKR, Ndi\Interfaces, FilterMediaTypes, , "802.15.4"
;-------------------------------------------------------------------------------
; Driver and Service Section
;-------------------------------------------------------------------------------
[otLwf.CopyFiles]
otLwf.sys,,,2
[otlwf.Service]
DisplayName = %otlwf.Service.DispName%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
StartType = 1 ;SERVICE_SYSTEM_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\otLwf.sys
LoadOrderGroup = NDIS
Description = %otlwf.DeviceDesc%
[SourceDisksNames]
1=%otLwf_Desc%,"",,
1 = %otlwf.DeviceDesc%,"",,
[SourceDisksFiles]
; TODO: Include any related files that should be installed with your driver.
otLwf.sys=1
otLwf.sys = 1
[DestinationDirs]
DefaultDestDir=12
otLwf.copyfiles.sys=12
[otLwf.copyfiles.sys]
otLwf.sys,,,2
;-------------------------------------------------------------------------
; Ndi installation support
;-------------------------------------------------------------------------
[Inst_Ndi]
HKR, Ndi,Service,,"otLwf"
HKR, Ndi,CoServices,0x00010000,"otLwf"
HKR, Ndi,HelpText,,%otLwf_HelpText%
HKR, Ndi,FilterClass,, ms_medium_converter_top
HKR, Ndi,FilterType,0x00010001,0x00000002
HKR, Ndi,FilterRunType, 0x00010001, 0x00000002 ;OPTIONAL filter
HKR, Ndi\Interfaces,UpperRange,,"noupper"
HKR, Ndi\Interfaces,LowerRange,,"nolower"
HKR, Ndi\Interfaces, FilterMediaTypes,,"802.15.4"
;-------------------------------------------------------------------------
; Service installation support
;-------------------------------------------------------------------------
[Install.Services]
AddService=otLwf,,otLwf_Service_Inst
[otLwf_Service_Inst]
DisplayName = %otLwf_Desc%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
; Typically you will want your filter driver to start with SERVICE_SYSTEM_START.
; If it is an Optional filter, you may also use 3;SERVICE_DEMAND_START.
StartType = 1 ;SERVICE_SYSTEM_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\otLwf.sys
LoadOrderGroup = NDIS
Description = %otLwf_Desc%
[Install.Remove.Services]
; The SPSVCINST_STOPSERVICE flag instructs SCM to stop the NT service
; before uninstalling the driver.
DelService=otLwf,0x200 ; SPSVCINST_STOPSERVICE
DefaultDestDir = 12
otLwf.CopyFiles = 12
;-------------------------------------------------------------------------------
; Localizable Strings
;-------------------------------------------------------------------------------
[Strings]
openthread = "OpenThread"
otLwf_Desc = "OpenThread NDIS LightWeight Filter"
otLwf_HelpText = "OpenThread NDIS LightWeight Filter"
OpenThread = "OpenThread"
otlwf.DeviceDesc = "OpenThread NDIS LightWeight Filter"
otlwf.Service.DispName = "OpenThread NDIS LightWeight Filter"
+547
View File
@@ -0,0 +1,547 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This module implements code to manage the NETADAPTER object for the
* network adapter.
*/
#include "pch.hpp"
#include "adapter.tmh"
PAGED
_IRQL_requires_max_(PASSIVE_LEVEL)
NDIS_STATUS
AdapterInitialize(
_In_ NDIS_HANDLE MiniportAdapterHandle,
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
)
/*++
Routine Description:
AdapterInitialize function is called to initialize the Network Adapter
at the time of Pnp Add device.
This routine initializes the context of the adapter object
Arguments:
MiniportAdapterHandle - Handle to the NDIS Miniport Adapter object.
AdapterContext - The context associated with the adapter
Return Value:
NTSTATUS - A failure here will indicate a fatal error in the driver.
--*/
{
NDIS_STATUS Status;
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
do
{
NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES AdapterRegistration = { 0 };
NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES AdapterGeneral = { 0 };
NDIS_PM_CAPABILITIES PmCapabilities = { 0 };
//
// First, set the registration attributes.
//
AdapterRegistration.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
AdapterRegistration.Header.Size = sizeof(AdapterRegistration);
AdapterRegistration.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_2;
AdapterRegistration.MiniportAdapterContext = AdapterContext;
AdapterRegistration.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_SURPRISE_REMOVE_OK | NDIS_MINIPORT_ATTRIBUTES_NDIS_WDM | NDIS_MINIPORT_ATTRIBUTES_NO_PAUSE_ON_SUSPEND;
AdapterRegistration.InterfaceType = NdisInterfacePNPBus;
NDIS_DECLARE_MINIPORT_ADAPTER_CONTEXT(_OTTMP_ADAPTER_CONTEXT);
Status = NdisMSetMiniportAttributes(
MiniportAdapterHandle,
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&AdapterRegistration);
if (NDIS_STATUS_SUCCESS != Status)
{
LogError(DRIVER_DEFAULT, "[%p] NdisSetOptionalHandlers Status %!NDIS_STATUS!", AdapterContext, Status);
break;
}
//
// Next, set the general attributes.
//
AdapterGeneral.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
AdapterGeneral.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
AdapterGeneral.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
//
// Specify the medium type that the NIC can support but not
// necessarily the medium type that the NIC currently uses.
//
AdapterGeneral.MediaType = NIC_MEDIUM_TYPE;
//
// Specifiy medium type that the NIC currently uses.
//
AdapterGeneral.PhysicalMediumType = NdisPhysicalMediumNative802_15_4;
//
// We have to lie about the MTU, so that TCPIP will bind to us.
// Specifically, we have to rely that the ThreadLwf will fragment
// the packets appropriately.
//
AdapterGeneral.MtuSize = HW_MAX_FRAME_SIZE;
AdapterGeneral.MaxXmitLinkSpeed = NIC_RECV_XMIT_SPEED;
AdapterGeneral.XmitLinkSpeed = NIC_RECV_XMIT_SPEED;
AdapterGeneral.MaxRcvLinkSpeed = NIC_RECV_XMIT_SPEED;
AdapterGeneral.RcvLinkSpeed = NIC_RECV_XMIT_SPEED;
AdapterGeneral.MediaConnectState = MediaConnectStateConnected;
AdapterGeneral.MediaDuplexState = MediaDuplexStateFull;
//
// The maximum number of bytes the NIC can provide as lookahead data.
// If that value is different from the size of the lookahead buffer
// supported by bound protocols, NDIS will call MiniportOidRequest to
// set the size of the lookahead buffer provided by the miniport driver
// to the minimum of the miniport driver and protocol(s) values. If the
// driver always indicates up full packets with
// NdisMIndicateReceiveNetBufferLists, it should set this value to the
// maximum total frame size, which excludes the header.
//
// Upper-layer drivers examine lookahead data to determine whether a
// packet that is associated with the lookahead data is intended for
// one or more of their clients. If the underlying driver supports
// multipacket receive indications, bound protocols are given full net
// packets on every indication. Consequently, this value is identical
// to that returned for OID_GEN_RECEIVE_BLOCK_SIZE.
//
AdapterGeneral.LookaheadSize = HW_MAX_FRAME_SIZE;
AdapterGeneral.PowerManagementCapabilities = NULL;
AdapterGeneral.MacOptions = NIC_MAC_OPTIONS;
AdapterGeneral.SupportedPacketFilters = NIC_SUPPORTED_FILTERS;
//
// The maximum number of multicast addresses the NIC driver can manage.
// This list is global for all protocols bound to (or above) the NIC.
// Consequently, a protocol can receive NDIS_STATUS_MULTICAST_FULL from
// the NIC driver when attempting to set the multicast address list,
// even if the number of elements in the given list is less than the
// number originally returned for this query.
//
AdapterGeneral.MaxMulticastListSize = NIC_MAX_MCAST_LIST;
AdapterGeneral.MacAddressLength = NIC_MACADDR_SIZE;
//
// Return the MAC address of the NIC burnt in the hardware.
//
memcpy(AdapterGeneral.PermanentMacAddress, &AdapterContext->ExtendedAddress, sizeof(AdapterContext->ExtendedAddress));
memcpy(AdapterGeneral.CurrentMacAddress, &AdapterContext->ExtendedAddress, sizeof(AdapterContext->ExtendedAddress));
AdapterGeneral.RecvScaleCapabilities = NULL;
AdapterGeneral.AccessType = NET_IF_ACCESS_BROADCAST;
AdapterGeneral.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
AdapterGeneral.ConnectionType = NET_IF_CONNECTION_DEDICATED;
AdapterGeneral.IfType = IF_TYPE_IEEE802154;
AdapterGeneral.IfConnectorPresent = TRUE;
AdapterGeneral.SupportedStatistics = NIC_SUPPORTED_STATISTICS;
AdapterGeneral.SupportedPauseFunctions = NdisPauseFunctionsUnsupported;
AdapterGeneral.DataBackFillSize = 0;
AdapterGeneral.ContextBackFillSize = 0;
//
// The SupportedOidList is an array of OIDs for objects that the
// underlying driver or its NIC supports. Objects include general,
// media-specific, and implementation-specific objects. NDIS forwards a
// subset of the returned list to protocols that make this query. That
// is, NDIS filters any supported statistics OIDs out of the list
// because protocols never make statistics queries.
//
AdapterGeneral.SupportedOidList = NICSupportedOids;
AdapterGeneral.SupportedOidListLength = SizeOfNICSupportedOids;
AdapterGeneral.AutoNegotiationFlags = NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED;
//
// Set the power management capabilities. All 0 basically means we don't
// support Dx for anything.
//
PmCapabilities.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
PmCapabilities.Header.Size = NDIS_SIZEOF_NDIS_PM_CAPABILITIES_REVISION_2;
PmCapabilities.Header.Revision = NDIS_PM_CAPABILITIES_REVISION_2;
AdapterGeneral.PowerManagementCapabilitiesEx = &PmCapabilities;
Status = NdisMSetMiniportAttributes(
MiniportAdapterHandle,
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&AdapterGeneral);
if (NDIS_STATUS_SUCCESS != Status)
{
LogError(DRIVER_DEFAULT, "[%p] NdisSetOptionalHandlers failed %!NDIS_STATUS!", AdapterContext, Status);
break;
}
} while (FALSE);
LogFuncExitNDIS(DRIVER_DEFAULT, Status);
return Status;
}
PAGED
_IRQL_requires_(PASSIVE_LEVEL)
VOID
AdapterUninitialize(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
)
{
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
SerialUninitialize(AdapterContext);
if (AdapterContext->Device)
{
WdfObjectDelete(AdapterContext->Device);
AdapterContext->Device = nullptr;
}
NdisFreeMemory(AdapterContext, 0, 0);
LogFuncExit(DRIVER_DEFAULT);
}
PAGED
_IRQL_requires_( PASSIVE_LEVEL )
_Function_class_( MINIPORT_RESTART )
NDIS_STATUS
MPRestart(
_In_ NDIS_HANDLE MiniportAdapterContext,
_In_ PNDIS_MINIPORT_RESTART_PARAMETERS /* RestartParameters */
)
/*++
Routine Description:
When a miniport receives a restart request, it enters into a Restarting
state. The miniport may begin indicating received data (e.g., using
NdisMIndicateReceiveNetBufferLists), handling status indications, and
processing OID requests in the Restarting state. However, no sends will be
requested while the miniport is in the Restarting state.
Once the miniport is ready to send data, it has entered the Running state.
The miniport informs NDIS that it is in the Running state by returning
NDIS_STATUS_SUCCESS from this MiniportRestart function; or if this function
has already returned NDIS_STATUS_PENDING, by calling NdisMRestartComplete.
MiniportRestart runs at IRQL = PASSIVE_LEVEL.
Arguments:
MiniportAdapterContext Pointer to the Adapter
RestartParameters Additional information about the restart operation
Return Value:
If the miniport is able to immediately enter the Running state, it should
return NDIS_STATUS_SUCCESS.
If the miniport is still in the Restarting state, it should return
NDIS_STATUS_PENDING now, and call NdisMRestartComplete when the miniport
has entered the Running state.
Other NDIS_STATUS codes indicate errors. If an error is encountered, the
miniport must return to the Paused state (i.e., stop indicating receives).
--*/
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
POTTMP_ADAPTER_CONTEXT AdapterContext = (POTTMP_ADAPTER_CONTEXT)MiniportAdapterContext;
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
// Set the running flag
AdapterContext->IsRunning = true;
LogFuncExitNDIS(DRIVER_DEFAULT, status);
return status;
}
PAGED
_IRQL_requires_( PASSIVE_LEVEL )
_Function_class_( MINIPORT_PAUSE )
NDIS_STATUS
MPPause(
_In_ NDIS_HANDLE MiniportAdapterContext,
_In_ PNDIS_MINIPORT_PAUSE_PARAMETERS /* MiniportPauseParameters */
)
/*++
Routine Description:
When a miniport receives a pause request, it enters into a Pausing state.
The miniport should not indicate up any more network data. Any pending
send requests must be completed, and new requests must be rejected with
NDIS_STATUS_PAUSED.
Once all sends have been completed and all recieve NBLs have returned to
the miniport, the miniport enters the Paused state.
While paused, the miniport can still service interrupts from the hardware
(to, for example, continue to indicate NDIS_STATUS_MEDIA_CONNECT
notifications).
The miniport must continue to be able to handle status indications and OID
requests. MiniportPause is different from MiniportHalt because, in
general, the MiniportPause operation won't release any resources.
MiniportPause must not attempt to acquire any resources where allocation
can fail, since MiniportPause itself must not fail.
MiniportPause runs at IRQL = PASSIVE_LEVEL.
Arguments:
MiniportAdapterContext Pointer to the Adapter
MiniportPauseParameters Additional information about the pause operation
Return Value:
If the miniport is able to immediately enter the Paused state, it should
return NDIS_STATUS_SUCCESS.
If the miniport must wait for send completions or pending receive NBLs, it
should return NDIS_STATUS_PENDING now, and call NDISMPauseComplete when the
miniport has entered the Paused state.
No other return value is permitted. The pause operation must not fail.
--*/
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
POTTMP_ADAPTER_CONTEXT AdapterContext = (POTTMP_ADAPTER_CONTEXT)MiniportAdapterContext;
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
// Clear the flag to indicate we are no longer running
AdapterContext->IsRunning = false;
LogFuncExitNDIS(DRIVER_DEFAULT, status);
return status;
}
VOID
MPSendNetBufferLists(
_In_ NDIS_HANDLE MiniportAdapterContext,
_In_ PNET_BUFFER_LIST NetBufferLists,
_In_ NDIS_PORT_NUMBER /* PortNumber */,
_In_ ULONG SendFlags
)
/*++
Routine Description:
Send Packet Array handler. Called by NDIS whenever a protocol
bound to our miniport sends one or more packets.
The input packet descriptor pointers have been ordered according
to the order in which the packets should be sent over the network
by the protocol driver that set up the packet array. The NDIS
library preserves the protocol-determined ordering when it submits
each packet array to MiniportSendPackets
As a deserialized driver, we are responsible for holding incoming send
packets in our internal queue until they can be transmitted over the
network and for preserving the protocol-determined ordering of packet
descriptors incoming to its MiniportSendPackets function.
A deserialized miniport driver must complete each incoming send packet
with NdisMSendComplete, and it cannot call NdisMSendResourcesAvailable.
Runs at IRQL <= DISPATCH_LEVEL
Arguments:
MiniportAdapterContext Pointer to our adapter
NetBufferLists Head of a list of NBLs to send
PortNumber A miniport adapter port. Default is 0.
SendFlags Additional flags for the send operation
Return Value:
None. Write status directly into each NBL with the NET_BUFFER_LIST_STATUS
macro.
--*/
{
POTTMP_ADAPTER_CONTEXT AdapterContext = (POTTMP_ADAPTER_CONTEXT)MiniportAdapterContext;
PNET_BUFFER_LIST FailedNbls = NULL;
LogFuncEntryMsg(DRIVER_DEFAULT, "NetBufferList: %p", NetBufferLists);
PNET_BUFFER_LIST CurrNbl = NetBufferLists;
while (CurrNbl)
{
PNET_BUFFER_LIST NextNbl = CurrNbl->Next;
CurrNbl->Next = NULL;
// Only allow one NB per NBL
if (CurrNbl->FirstNetBuffer == NULL ||
CurrNbl->FirstNetBuffer->Next != NULL)
{
CurrNbl->Status = STATUS_INVALID_PARAMETER;
}
else
{
// Try to queue up for send
NTSTATUS status = SerialSendData(AdapterContext, CurrNbl);
if (!NT_SUCCESS(status)) {
CurrNbl->Status = status;
}
else {
CurrNbl = NULL;
}
}
// If we still have the CurrNbl, it failed, so move it to the failure list
if (CurrNbl) {
CurrNbl->Next = FailedNbls;
FailedNbls = CurrNbl;
}
CurrNbl = NextNbl;
}
// Complete any failures
if (FailedNbls) {
NdisMSendNetBufferListsComplete(AdapterContext->Adapter, FailedNbls, (SendFlags & NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL));
}
LogFuncExit(DRIVER_DEFAULT);
}
VOID
MPCancelSend(
_In_ NDIS_HANDLE /* MiniportAdapterContext */,
_In_ PVOID /* CancelId */
)
/*++
Routine Description:
MiniportCancelSend cancels the transmission of all NET_BUFFER_LISTs that
are marked with a specified cancellation identifier. Miniport drivers
that queue send packets for more than one second should export this
handler. When a protocol driver or intermediate driver calls the
NdisCancelSendNetBufferLists function, NDIS calls the MiniportCancelSend
function of the appropriate lower-level driver (miniport driver or
intermediate driver) on the binding.
Runs at IRQL <= DISPATCH_LEVEL.
Arguments:
MiniportAdapterContext Pointer to our adapter
CancelId All the packets with this Id should be cancelled
Return Value:
None.
--*/
{
LogFuncEntry(DRIVER_DEFAULT);
LogFuncExit(DRIVER_DEFAULT);
}
VOID
MPReturnNetBufferLists(
_In_ NDIS_HANDLE /* MiniportAdapterContext */,
_In_ PNET_BUFFER_LIST NetBufferLists,
_In_ ULONG /* ReturnFlags */
)
/*++
Routine Description:
NDIS Miniport entry point called whenever protocols are done with one or
NBLs that we indicated up with NdisMIndicateReceiveNetBufferLists.
Note that the list of NBLs may be chained together from multiple separate
lists that were indicated up individually.
Arguments:
MiniportAdapterContext Pointer to our adapter
NetBufferLists NBLs being returned
ReturnFlags May contain the NDIS_RETURN_FLAGS_DISPATCH_LEVEL
flag, which if is set, indicates we can get a
small perf win by not checking or raising the
IRQL
Return Value:
None.
--*/
{
LogFuncEntry(DRIVER_DEFAULT);
// Iterate through all the NetBufferLists
for (PNET_BUFFER_LIST pNblNext, pNbl = NetBufferLists; pNbl; pNbl = pNblNext)
{
// Save next to temporary and clear member variable
pNblNext = NET_BUFFER_LIST_NEXT_NBL(pNbl);
NET_BUFFER_LIST_NEXT_NBL(pNbl) = NULL;
// Iterate through all the Netbuffers
for (PNET_BUFFER pNbNext, pNb = NET_BUFFER_LIST_FIRST_NB(pNbl); pNb; pNb = pNbNext)
{
pNbNext = NET_BUFFER_NEXT_NB(pNb);
NdisFreeNetBuffer(pNb);
}
NdisFreeNetBufferList(pNbl);
}
LogFuncExit(DRIVER_DEFAULT);
}
+224
View File
@@ -0,0 +1,224 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* Header file for the routines related to NETADAPTER Object for the
* Network Adapter
*/
#define NIC_TAG_RECV_NBL ((ULONG)'rMVT') // TVMr
#define OTTMP_ADAPTER_CONTEXT_SIGNATURE 'pdAt'
// The maximum size of one Spinel command / serial packet
#define MAX_SPINEL_COMMAND_LENGTH 1300
typedef struct _SERIAL_SEND_ITEM
{
LIST_ENTRY Link;
PNET_BUFFER_LIST NetBufferList;
WDFMEMORY WdfMemory;
ULONG EncodedBufferLength;
_Field_size_bytes_(EncodedBufferLength)
UCHAR EncodedBuffer[0];
} SERIAL_SEND_ITEM, *PSERIAL_SEND_ITEM;
const ULONG SERIAL_SEND_ITEM_SIZE = FIELD_OFFSET(SERIAL_SEND_ITEM, EncodedBuffer);
typedef struct _OTTMP_ADAPTER_CONTEXT {
ULONG Signature;
#ifdef OTTMP_LEGACY
NDIS_HANDLE Adapter;
#else
//
// Handle to the NETADAPTER object for this context
//
NETADAPTER Adapter;
#endif
//
// Handle to the corresponding WDFDEVICE
//
WDFDEVICE Device;
// Flag to indicate if the data path is enabled
bool IsConnected;
// Flag to indicate if the Adapter has been started or not
bool IsRunning;
#ifdef OTTMP_LEGACY
PGLOBALS pGlobals;
#else
// Receive packet pool
NETBUFFERLISTCOLLECTION ReceiveCollection;
#endif
ULONGLONG ExtendedAddress; // TODO - Cache
//
// Serial Device
//
WDFIOTARGET WdfIoTarget;
WDFSPINLOCK SendLock;
_Guarded_by_(SendLock)
LIST_ENTRY SendQueue;
bool SendQueueRunning;
WDFWORKITEM SendWorkItem;
WDFWORKITEM RecvWorkItem;
WDFREQUEST RecvReadRequest;
UCHAR RecvBuffer[MAX_SPINEL_COMMAND_LENGTH * 2];
ULONG RecvBufferLength;
//
// NIC configuration - This information is queried by the protocol drivers.
// Since this sample focuses on demonstrating the NDIS WDF model,
// it doesn't modify any these values during runtime.
// Please look at the netvmini630 sample to see how these values can be set
// and updated
// -------------------------------------------------------------------------
//
ULONG PacketFilter;
ULONG ulLookahead;
ULONG64 ulLinkSendSpeed;
ULONG64 ulLinkRecvSpeed;
ULONG ulMaxBusySends;
ULONG ulMaxBusyRecvs;
//
// Statistics -
// Since this sample focuses on demonstrating the NDIS WDF model,
// it doesn't modify any these values during runtime.
// Please look at the netvmini630 sample to see how these values can be set
// and updated
// -------------------------------------------------------------------------
//
// Packet counts
ULONG64 FramesRxDirected;
ULONG64 FramesRxMulticast;
ULONG64 FramesRxBroadcast;
ULONG64 FramesTxDirected;
ULONG64 FramesTxMulticast;
ULONG64 FramesTxBroadcast;
// Byte counts
ULONG64 BytesRxDirected;
ULONG64 BytesRxMulticast;
ULONG64 BytesRxBroadcast;
ULONG64 BytesTxDirected;
ULONG64 BytesTxMulticast;
ULONG64 BytesTxBroadcast;
// Count of transmit errors
ULONG TxAbortExcessCollisions;
ULONG TxLateCollisions;
ULONG TxDmaUnderrun;
ULONG TxLostCRS;
ULONG TxOKButDeferred;
ULONG OneRetry;
ULONG MoreThanOneRetry;
ULONG TotalRetries;
ULONG TransmitFailuresOther;
// Count of receive errors
ULONG RxCrcErrors;
ULONG RxAlignmentErrors;
ULONG RxResourceErrors;
ULONG RxDmaOverrunErrors;
ULONG RxCdtFrames;
ULONG RxRuntErrors;
} OTTMP_ADAPTER_CONTEXT, *POTTMP_ADAPTER_CONTEXT;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(OTTMP_ADAPTER_CONTEXT, GetAdapterContext);
typedef struct _WDF_DEVICE_INFO
{
POTTMP_ADAPTER_CONTEXT AdapterContext;
} WDF_DEVICE_INFO, *PWDF_DEVICE_INFO;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WDF_DEVICE_INFO, GetWdfDeviceInfo);
#ifdef OTTMP_LEGACY
PAGED MINIPORT_PAUSE MPPause;
PAGED MINIPORT_RESTART MPRestart;
MINIPORT_SEND_NET_BUFFER_LISTS MPSendNetBufferLists;
MINIPORT_RETURN_NET_BUFFER_LISTS MPReturnNetBufferLists;
MINIPORT_CANCEL_SEND MPCancelSend;
PAGED
_IRQL_requires_max_(PASSIVE_LEVEL)
NDIS_STATUS
AdapterInitialize(
_In_ NDIS_HANDLE MiniportAdapterHandle,
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
);
PAGED
_IRQL_requires_(PASSIVE_LEVEL)
VOID
AdapterUninitialize(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
);
#else
PAGED EVT_NET_ADAPTER_SET_CAPABILITIES EvtAdapterSetCapabilities;
PAGED EVT_NET_ADAPTER_START EvtAdapterStart;
PAGED EVT_NET_ADAPTER_PAUSE EvtAdapterPause;
EVT_NET_ADAPTER_SEND_NET_BUFFER_LISTS EvtAdapterSendNetBufferLists;
PAGED
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
AdapterInitialize(
_In_ NETADAPTER Adapter,
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext,
_In_ POTTMP_DEVICE_CONTEXT DeviceContext
);
#endif
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
AdapterIndicateEnergyScanComplete(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext,
_In_ NDIS_STATUS Status
);
EXT_CALLBACK AdapterEnergyScanTimerCallback;
+383
View File
@@ -0,0 +1,383 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This module implements code to manage the WDFDEVICE object for the
* network adapter.
*/
#include <initguid.h>
#include "pch.hpp"
#include "device.tmh"
PAGED
_IRQL_requires_( PASSIVE_LEVEL )
_Function_class_( MINIPORT_INITIALIZE )
NDIS_STATUS
MPInitializeEx(
_In_ NDIS_HANDLE MiniportAdapterHandle,
_In_ NDIS_HANDLE MiniportDriverContext,
_In_ PNDIS_MINIPORT_INIT_PARAMETERS /* MiniportInitParameters */
)
/*++
Routine Description:
The MiniportInitialize function is a required function that sets up a
NIC (or virtual NIC) for network I/O operations, claims all hardware
resources necessary to the NIC in the registry, and allocates resources
the driver needs to carry out network I/O operations.
MiniportInitialize runs at IRQL = PASSIVE_LEVEL.
Arguments:
Return Value:
NDIS_STATUS_xxx code
--*/
{
NDIS_STATUS Status = NDIS_STATUS_FAILURE;
PGLOBALS pGlobals = (PGLOBALS)MiniportDriverContext;
PDEVICE_OBJECT pPdo = nullptr;
PDEVICE_OBJECT pFdo = nullptr;
PDEVICE_OBJECT pNextDeviceObject = nullptr;
WDF_OBJECT_ATTRIBUTES attributes;
WDFDEVICE device = nullptr;
POTTMP_DEVICE_CONTEXT deviceContext = nullptr;
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
do
{
NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES AdapterRegistration = { 0 };
NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES AdapterGeneral = { 0 };
NDIS_PM_CAPABILITIES PmCapabilities = { 0 };
//
// NdisMGetDeviceProperty function enables us to get the:
// PDO - created by the bus driver to represent our device.
// FDO - created by NDIS to represent our miniport as a function
// driver.
// NextDeviceObject - deviceobject of another driver (filter)
// attached to us at the bottom.
// Since our driver is talking to NDISPROT, the NextDeviceObject
// is not useful. But if we were to talk to a driver that we
// are attached to as part of the devicestack then NextDeviceObject
// would be our target DeviceObject for sending read/write Requests.
//
NdisMGetDeviceProperty(
MiniportAdapterHandle,
&pPdo,
&pFdo,
&pNextDeviceObject,
nullptr,
nullptr);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, OTTMP_DEVICE_CONTEXT);
NTSTATUS ntStatus = WdfDeviceMiniportCreate(
pGlobals->WdfDriver,
&attributes,
pFdo,
pNextDeviceObject,
pPdo,
&device);
if (!NT_SUCCESS(ntStatus))
{
LogError(DRIVER_DEFAULT, "WdfDeviceMiniportCreate failed %!STATUS!", ntStatus);
Status = NDIS_STATUS_FAILURE;
break;
}
//
// Get WDF miniport device context.
//
deviceContext = GetDeviceContext(device);
deviceContext->Signature = OTTMP_DEVICE_CONTEXT_SIGNATURE;
deviceContext->Device = device;
//
// Allocate adapter context structure and initialize all the
// memory resources for sending and receiving packets.
//
deviceContext->AdapterContext = (POTTMP_ADAPTER_CONTEXT)NdisAllocateMemoryWithTagPriority(
pGlobals->hDriver,
sizeof(OTTMP_ADAPTER_CONTEXT),
OTTMP_ADAPTER_CONTEXT_SIGNATURE,
NormalPoolPriority);
if (deviceContext->AdapterContext == nullptr)
{
LogError(DRIVER_DEFAULT, "NdisAllocateMemoryWithTagPriority failed");
Status = NDIS_STATUS_RESOURCES;
break;
}
RtlZeroMemory(deviceContext->AdapterContext, sizeof(OTTMP_ADAPTER_CONTEXT));
deviceContext->AdapterContext->Signature = OTTMP_ADAPTER_CONTEXT_SIGNATURE;
deviceContext->AdapterContext->Adapter = MiniportAdapterHandle;
deviceContext->AdapterContext->Device = deviceContext->Device;
deviceContext->AdapterContext->pGlobals = pGlobals;
Status = AdapterInitialize(
MiniportAdapterHandle,
deviceContext->AdapterContext);
if (NDIS_STATUS_SUCCESS != Status)
{
LogError(DRIVER_DEFAULT, "AdapterInitialize failed %!NDIS_STATUS!", Status);
break;
}
ntStatus = SerialInitialize(deviceContext->AdapterContext);
if (!NT_SUCCESS(ntStatus))
{
Status = NDIS_STATUS_FAILURE;
break;
}
// Start the read loop
LogVerbose(DRIVER_DEFAULT, "Starting recv worker");
WdfWorkItemEnqueue(deviceContext->AdapterContext->RecvWorkItem);
} while (FALSE);
if (Status != NDIS_STATUS_SUCCESS)
{
if (deviceContext && deviceContext->AdapterContext)
{
AdapterUninitialize(deviceContext->AdapterContext);
deviceContext->AdapterContext = nullptr;
}
}
LogFuncExitNDIS(DRIVER_DEFAULT, Status);
return Status;
}
PAGED
VOID
MPHaltEx(
_In_ NDIS_HANDLE MiniportAdapterContext,
_In_ NDIS_HALT_ACTION HaltAction
)
/*++
Routine Description:
Halt handler is called when NDIS receives IRP_MN_STOP_DEVICE,
IRP_MN_SUPRISE_REMOVE or IRP_MN_REMOVE_DEVICE requests from the PNP
manager. Here, the driver should free all the resources acquired in
MiniportInitialize and stop access to the hardware. NDIS will not submit
any further request once this handler is invoked.
1) Free and unmap all I/O resources.
2) Disable interrupt and deregister interrupt handler.
3) Deregister shutdown handler regsitered by
NdisMRegisterAdapterShutdownHandler .
4) Cancel all queued up timer callbacks.
5) Finally wait indefinitely for all the outstanding receive
packets indicated to the protocol to return.
MiniportHalt runs at IRQL = PASSIVE_LEVEL.
Arguments:
MiniportAdapterContext Pointer to the Adapter
HaltAction The reason for halting the adapter
Return Value:
None.
--*/
{
POTTMP_ADAPTER_CONTEXT AdapterContext = (POTTMP_ADAPTER_CONTEXT)MiniportAdapterContext;
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
//
// Call Shutdown handler to disable interrupt and turn the hardware off
// by issuing a full reset
//
if (HaltAction != NdisHaltDeviceSurpriseRemoved)
{
MPShutdownEx(MiniportAdapterContext, NdisShutdownPowerOff);
}
AdapterUninitialize(AdapterContext);
LogFuncExit(DRIVER_DEFAULT);
}
VOID
MPShutdownEx(
_In_ NDIS_HANDLE /* MiniportAdapterContext */,
_In_ NDIS_SHUTDOWN_ACTION /* ShutdownAction */
)
/*++
Routine Description:
The MiniportShutdownEx handler restores hardware to its initial state when
the system is shut down, whether by the user or because an unrecoverable
system error occurred. This is to ensure that the NIC is in a known
state and ready to be reinitialized when the machine is rebooted after
a system shutdown occurs for any reason, including a crash dump.
Here just disable the interrupt and stop the DMA engine. Do not free
memory resources or wait for any packet transfers to complete. Do not call
into NDIS at this time.
This can be called at aribitrary IRQL, including in the context of a
bugcheck.
Arguments:
MiniportAdapterContext Pointer to our adapter
ShutdownAction The reason why NDIS called the shutdown function
Return Value:
None.
--*/
{
LogFuncEntry(DRIVER_DEFAULT);
LogFuncExit(DRIVER_DEFAULT);
}
PAGED
VOID
MPDevicePnpEventNotify(
_In_ NDIS_HANDLE /* MiniportAdapterContext */,
_In_ PNET_DEVICE_PNP_EVENT NetDevicePnPEvent
)
/*++
Routine Description:
Runs at IRQL = PASSIVE_LEVEL in the context of system thread.
Arguments:
MiniportAdapterContext Pointer to our adapter
NetDevicePnPEvent Self-explanatory
Return Value:
None.
--*/
{
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
switch (NetDevicePnPEvent->DevicePnPEvent)
{
case NdisDevicePnPEventQueryRemoved:
//
// Called when NDIS receives IRP_MN_QUERY_REMOVE_DEVICE.
//
LogInfo(DRIVER_DEFAULT, "MPPnPEventNotify: NdisDevicePnPEventQueryRemoved");
break;
case NdisDevicePnPEventRemoved:
//
// Called when NDIS receives IRP_MN_REMOVE_DEVICE.
// NDIS calls MiniportHalt function after this call returns.
//
LogInfo(DRIVER_DEFAULT, "MPPnPEventNotify: NdisDevicePnPEventRemoved");
break;
case NdisDevicePnPEventSurpriseRemoved:
//
// Called when NDIS receives IRP_MN_SUPRISE_REMOVAL.
// NDIS calls MiniportHalt function after this call returns.
//
LogInfo(DRIVER_DEFAULT, "MPDevicePnpEventNotify: NdisDevicePnPEventSurpriseRemoved");
break;
case NdisDevicePnPEventQueryStopped:
//
// Called when NDIS receives IRP_MN_QUERY_STOP_DEVICE. ??
//
LogInfo(DRIVER_DEFAULT, "MPPnPEventNotify: NdisDevicePnPEventQueryStopped");
break;
case NdisDevicePnPEventStopped:
//
// Called when NDIS receives IRP_MN_STOP_DEVICE.
// NDIS calls MiniportHalt function after this call returns.
//
//
LogInfo(DRIVER_DEFAULT, "MPPnPEventNotify: NdisDevicePnPEventStopped");
break;
case NdisDevicePnPEventPowerProfileChanged:
//
// After initializing a miniport driver and after miniport driver
// receives an OID_PNP_SET_POWER notification that specifies
// a device power state of NdisDeviceStateD0 (the powered-on state),
// NDIS calls the miniport's MiniportPnPEventNotify function with
// PnPEvent set to NdisDevicePnPEventPowerProfileChanged.
//
LogInfo(DRIVER_DEFAULT, "MPDevicePnpEventNotify: NdisDevicePnPEventPowerProfileChanged");
if (NetDevicePnPEvent->InformationBufferLength == sizeof( ULONG ))
{
const ULONG NdisPowerProfile = *((const ULONG *)NetDevicePnPEvent->InformationBuffer);
if (NdisPowerProfile == NdisPowerProfileBattery)
{
LogInfo(DRIVER_DEFAULT, "The host system is running on battery power");
}
else if (NdisPowerProfile == NdisPowerProfileAcOnLine)
{
LogInfo(DRIVER_DEFAULT, "The host system is running on AC power");
}
}
break;
default:
LogError(DRIVER_DEFAULT, "MPDevicePnpEventNotify: unknown PnP event 0x%x\n", NetDevicePnPEvent->DevicePnPEvent);
}
LogFuncExit(DRIVER_DEFAULT);
}
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* Header file for the routines related to WDFDEVICE representing the
* Network Adapter
*/
#pragma once
#define OTTMP_DEVICE_CONTEXT_SIGNATURE 'veDt'
typedef struct _OTTMP_DEVICE_CONTEXT {
//
// Signature for Sanity Check.
//
ULONG Signature;
//
// Handle to the WDFDEVICE of which this is the context
//
WDFDEVICE Device;
//
// Pointer to the Context of the corresponding NETADAPTER object
//
POTTMP_ADAPTER_CONTEXT AdapterContext;
} OTTMP_DEVICE_CONTEXT, *POTTMP_DEVICE_CONTEXT;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(OTTMP_DEVICE_CONTEXT, GetDeviceContext);
extern "C" {
#ifdef OTTMP_LEGACY
PAGED MINIPORT_INITIALIZE MPInitializeEx;
PAGED MINIPORT_HALT MPHaltEx;
MINIPORT_SHUTDOWN MPShutdownEx;
PAGED MINIPORT_DEVICE_PNP_EVENT_NOTIFY MPDevicePnpEventNotify;
#else
PAGED EVT_WDF_DRIVER_DEVICE_ADD EvtDriverDeviceAdd;
PAGED EVT_WDF_DEVICE_D0_EXIT EvtDeviceD0Exit;
PAGED EVT_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware;
PAGED EVT_WDF_DEVICE_RELEASE_HARDWARE EvtDeviceReleaseHardware;
PAGED EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT EvtDeviceSelfManagedIoInit;
PAGED EVT_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP EvtDeviceSelfManagedIoCleanup;
EVT_WDF_DEVICE_D0_ENTRY EvtDeviceD0Entry;
#endif
}
+273
View File
@@ -0,0 +1,273 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This module has code to deal with loading and unloading of the driver
*/
#include "pch.hpp"
#include "driver.tmh"
#ifdef OTTMP_LEGACY
static GLOBALS GlobalData = { 0 };
#endif
INITCODE
extern "C"
NTSTATUS
DriverEntry (
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
DriverEntry initializes the driver and is the first routine called by the
system after the driver is loaded. DriverEntry specifies the other entry
points in the function driver, such as EvtDevice and DriverUnload.
Parameters Description:
DriverObject - represents the instance of the function driver that is loaded
into memory. DriverEntry must initialize members of DriverObject before it
returns to the caller. DriverObject is allocated by the system before the
driver is loaded, and it is released by the system after the system unloads
the function driver from memory.
RegistryPath - represents the driver specific path in the Registry.
The function driver can use the path to store driver related data between
reboots. The path does not store hardware instance specific data.
Return Value:
A success status as determined by NT_SUCCESS macro, if successful.
--*/
{
NTSTATUS status;
WDF_DRIVER_CONFIG config;
#ifdef OTTMP_LEGACY
NDIS_STATUS ndisStatus = NDIS_STATUS_FAILURE;
NDIS_MINIPORT_DRIVER_CHARACTERISTICS MPChar = { 0 };
NET_BUFFER_LIST_POOL_PARAMETERS NblParams = { 0 };
NET_BUFFER_POOL_PARAMETERS NbParams = { 0 };
#endif
WPP_INIT_TRACING(DriverObject, RegistryPath);
LogFuncEntry(DRIVER_DEFAULT);
//
// Create the WdfDriver Object
//
WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);
#ifdef OTTMP_LEGACY
//
// 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;
#else
config.EvtDriverDeviceAdd = EvtDriverDeviceAdd;
config.EvtDriverUnload = EvtDriverUnload;
#endif
status = WdfDriverCreate(DriverObject,
RegistryPath,
WDF_NO_OBJECT_ATTRIBUTES,
&config,
#ifdef OTTMP_LEGACY
&GlobalData.WdfDriver
#else
NULL
#endif
);
if (!NT_SUCCESS(status))
{
LogError(DRIVER_DEFAULT, "WdfDriverCreate failed, %!STATUS!", status);
goto error;
}
#ifdef OTTMP_LEGACY
MPChar.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
MPChar.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
MPChar.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
// Version Suff
MPChar.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
MPChar.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
MPChar.MajorDriverVersion = NIC_VENDOR_DRIVER_VERSION_MAJOR;
MPChar.MinorDriverVersion = NIC_VENDOR_DRIVER_VERSION_MINOR;
MPChar.InitializeHandlerEx = MPInitializeEx;
MPChar.HaltHandlerEx = MPHaltEx;
MPChar.UnloadHandler = MPDriverUnload;
MPChar.PauseHandler = MPPause;
MPChar.RestartHandler = MPRestart;
MPChar.OidRequestHandler = MPOidRequest;
MPChar.SendNetBufferListsHandler = MPSendNetBufferLists;
MPChar.ReturnNetBufferListsHandler = MPReturnNetBufferLists;
MPChar.CancelSendHandler = MPCancelSend;
MPChar.DevicePnPEventNotifyHandler = MPDevicePnpEventNotify;
MPChar.ShutdownHandlerEx = MPShutdownEx;
MPChar.CancelOidRequestHandler = MPCancelOidRequest;
ndisStatus = NdisMRegisterMiniportDriver(DriverObject,
RegistryPath,
&GlobalData,
&MPChar,
&GlobalData.hDriver);
if (ndisStatus != NDIS_STATUS_SUCCESS)
{
LogError(DRIVER_DEFAULT, "NdisMRegisterMiniportDriver failed %!NDIS_STATUS!", ndisStatus);
status = STATUS_UNSUCCESSFUL;
goto error;
}
NblParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
NblParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
NblParams.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
NblParams.PoolTag = NIC_TAG_RECV_NBL;
GlobalData.hNblPool = NdisAllocateNetBufferListPool(GlobalData.hDriver, &NblParams);
if (GlobalData.hNblPool == 0)
{
LogError(DRIVER_DEFAULT, "NdisAllocateNetBufferListPool failed");
status = STATUS_INSUFFICIENT_RESOURCES;
goto error;
}
NbParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
NbParams.Header.Revision = NET_BUFFER_POOL_PARAMETERS_REVISION_1;
NbParams.Header.Size = NDIS_SIZEOF_NET_BUFFER_POOL_PARAMETERS_REVISION_1;
NbParams.PoolTag = NIC_TAG_RECV_NBL;
NbParams.DataSize = MAX_SPINEL_COMMAND_LENGTH;
GlobalData.hNbPool = NdisAllocateNetBufferPool(GlobalData.hDriver, &NbParams);
if (GlobalData.hNbPool == 0)
{
LogError(DRIVER_DEFAULT, "NdisAllocateNetBufferListPool failed");
status = STATUS_INSUFFICIENT_RESOURCES;
goto error;
}
#endif
error:
if (!NT_SUCCESS(status))
{
#ifdef OTTMP_LEGACY
MPDriverUnload(DriverObject);
#else
WPP_CLEANUP(DriverObject);
#endif
}
LogFuncExitNT(DRIVER_DEFAULT, status);
return status;
}
#ifdef OTTMP_LEGACY
PAGED
_Use_decl_annotations_
VOID
MPDriverUnload(
_In_ PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
MPDriverUnload will clean up the WPP resources that was allocated
for this driver.
Arguments:
DriverObject - Handle to a framework driver object created in DriverEntry
--*/
{
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
if (GlobalData.WdfDriver)
{
NT_ASSERT(GlobalData.WdfDriver == WdfGetDriver());
WdfDriverMiniportUnload(GlobalData.WdfDriver);
GlobalData.WdfDriver = nullptr;
}
if (GlobalData.hNblPool)
{
NdisFreeNetBufferListPool(GlobalData.hNblPool);
GlobalData.hNblPool = nullptr;
}
if (GlobalData.hDriver)
{
NdisMDeregisterMiniportDriver(GlobalData.hDriver);
GlobalData.hDriver = nullptr;
}
LogFuncExit(DRIVER_DEFAULT);
#pragma warning(suppress: 25024) // Dangerous cast
WPP_CLEANUP(DriverObject);
}
#else
PAGED
VOID
EvtDriverUnload(
WDFDRIVER Driver
)
/*++
Routine Description:
EvtDriverUnload will clean up the WPP resources that was allocated
for this driver.
Arguments:
Driver - Handle to a framework driver object created in DriverEntry
--*/
{
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
LogFuncExit(DRIVER_DEFAULT);
WPP_CLEANUP(WdfDriverWdmGetDriverObject(Driver));
}
#endif
+58
View File
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* Header file for the Driver Load / Unload routines
*/
#pragma once
extern "C" {
DRIVER_INITIALIZE DriverEntry;
}
#ifdef OTTMP_LEGACY
PAGED MINIPORT_UNLOAD MPDriverUnload;
typedef struct _GLOBALS
{
WDFDRIVER WdfDriver;
NDIS_HANDLE hDriver;
NDIS_HANDLE hNblPool;
NDIS_HANDLE hNbPool;
} GLOBALS, *PGLOBALS;
#else
PAGED EVT_WDF_DRIVER_UNLOAD EvtDriverUnload;
#endif
//
// Own Version
//
#define NIC_VENDOR_DRIVER_VERSION_MAJOR 1
#define NIC_VENDOR_DRIVER_VERSION_MINOR 0
#define NIC_VENDOR_DRIVER_VERSION ((NIC_VENDOR_DRIVER_VERSION_MAJOR << 16) | NIC_VENDOR_DRIVER_VERSION_MINOR)
+153
View File
@@ -0,0 +1,153 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This module defines constants that describe physical characteristics and
* limits of the underlying hardware.
*/
#pragma once
#ifndef IF_TYPE_IEEE802154
#define IF_TYPE_IEEE802154 259 // IEEE 802.15.4 WPAN interface
#define NdisPhysicalMediumNative802_15_4 (NDIS_PHYSICAL_MEDIUM)20
#endif
//
// Link layer addressing
// -----------------------------------------------------------------------------
//
// Number of bytes in a hardware address. 802.15.4 uses 8 byte addresses.
#define NIC_MACADDR_SIZE 8
//
// Frames
// -----------------------------------------------------------------------------
//
#define HW_MAX_FRAME_SIZE 1280
//
// Medium properties
// -----------------------------------------------------------------------------
//
#define NIC_MEDIUM_TYPE NdisMediumIP
// Claim to be 250kbps duplex
#define KILOBITS_PER_SECOND 1000ULL
#define MEGABITS_PER_SECOND 1000000ULL
#define NIC_RECV_XMIT_SPEED (250ULL*KILOBITS_PER_SECOND)
//
// Hardware limits
// -----------------------------------------------------------------------------
//
// Max number of multicast addresses supported in hardware
#define NIC_MAX_MCAST_LIST 32
// Maximum number of uncompleted sends that a single adapter will permit
#define NIC_MAX_BUSY_SENDS 1024
// Maximum number of received packets that can be in the OS at any time
// (Also known as the receive pool size)
#define NIC_MAX_OUTSTANDING_RECEIVES 32
//
// Physical adapter properties
// -----------------------------------------------------------------------------
//
// Change to your company name instead of using OpenThread
#define NIC_VENDOR_DESC "OpenThread"
// Highest byte is the NIC byte plus three vendor bytes. This is normally
// obtained from the NIC.
#define NIC_VENDOR_ID 0x00FFFFFF
#ifdef OTTMP_LEGACY
#define NIC_SUPPORTED_FILTERS ( \
NDIS_PACKET_TYPE_DIRECTED | \
NDIS_PACKET_TYPE_MULTICAST | \
NDIS_PACKET_TYPE_BROADCAST | \
NDIS_PACKET_TYPE_PROMISCUOUS | \
NDIS_PACKET_TYPE_ALL_MULTICAST)
#else
#define NIC_SUPPORTED_FILTERS (NET_PACKET_FILTER_TYPES_FLAGS) ( \
NET_PACKET_FILTER_TYPE_DIRECTED | \
NET_PACKET_FILTER_TYPE_MULTICAST | \
NET_PACKET_FILTER_TYPE_BROADCAST | \
NET_PACKET_FILTER_TYPE_PROMISCUOUS | \
NET_PACKET_FILTER_TYPE_ALL_MULTICAST)
#endif
//
// Specify a bitmask that defines optional properties of the NIC.
// This miniport indicates receive with NdisMIndicateReceiveNetBufferLists
// function. Such a driver should set this NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
// flag.
//
// NDIS_MAC_OPTION_NO_LOOPBACK tells NDIS that NIC has no internal
// loopback support so NDIS will manage loopbacks on behalf of
// this driver.
//
// NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA tells the protocol that
// our receive buffer is not on a device-specific card. If
// NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA is not set, multi-buffer
// indications are copied to a single flat buffer.
//
#define NIC_MAC_OPTIONS (\
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \
NDIS_MAC_OPTION_NO_LOOPBACK | \
NDIS_MAC_OPTION_8021P_PRIORITY | \
NDIS_MAC_OPTION_8021Q_VLAN)
// NDIS 6.x miniports must support all counters in OID_GEN_STATISTICS.
#define NIC_SUPPORTED_STATISTICS (\
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV | \
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV | \
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_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_MULTICAST_FRAMES_XMIT | \
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT | \
NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT | \
NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR | \
NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS | \
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV | \
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV | \
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV | \
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT | \
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT | \
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT)
+343
View File
@@ -0,0 +1,343 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements an HDLC-lite encoder and decoder.
*/
#include "pch.hpp"
#include "hdlc.tmh"
/**
* FCS lookup table
*/
enum
{
kInitFcs = 0xffff, ///< Initial FCS value.
kGoodFcs = 0xf0b8, ///< Good FCS value.
};
static bool
hdlc_byte_needs_escape(UCHAR byte)
{
switch (byte)
{
case HdlcXOn:
case HdlcXOff:
case HdlcEscapeSequence:
case HdlcFlagSequence:
case HdlcSpecial:
return true;
default:
return false;
}
}
/**
* This method updates an FCS.
*
* @param[in] aFcs The FCS to update.
* @param[in] aByte The input byte value.
*
* @returns The updated FCS.
*/
USHORT UpdateFcs(USHORT aFcs, UCHAR aByte)
{
const USHORT sFcsTable[256] =
{
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
return (aFcs >> 8) ^ sFcsTable[(aFcs ^ aByte) & 0xff];
}
ULONG
HdlcComputeEncodedByteLength(
_In_ UCHAR aByte
)
{
return hdlc_byte_needs_escape(aByte) ? 2 : 1;
}
ULONG
HdlcComputeEncodedLength(
_In_reads_bytes_(DecodedBufferLength)
PUCHAR DecodedBuffer,
_In_ ULONG DecodedBufferLength
)
{
USHORT Fcs = kInitFcs;
ULONG Length = 2; // Start and end sequence
for (ULONG i = 0; i < DecodedBufferLength; i++)
{
Length += HdlcComputeEncodedByteLength(DecodedBuffer[i]);
Fcs = UpdateFcs(Fcs, DecodedBuffer[i]);
}
Fcs ^= 0xffff;
Length += HdlcComputeEncodedByteLength(Fcs & 0xff);
Length += HdlcComputeEncodedByteLength(Fcs >> 8);
return Length;
}
bool
HdlcEncodeByte(
_In_ UCHAR aByte,
_Inout_ ULONG& Offset,
_In_ ULONG EncodedBufferLength,
_Out_writes_bytes_(EncodedBufferLength)
PUCHAR EncodedBuffer
)
{
if (hdlc_byte_needs_escape(aByte))
{
if (Offset + 2 > EncodedBufferLength) return false;
EncodedBuffer[Offset++] = HdlcEscapeSequence;
EncodedBuffer[Offset++] = (aByte ^ 0x20);
}
else
{
if (Offset + 1 > EncodedBufferLength) return false;
EncodedBuffer[Offset++] = aByte;
}
return true;
}
_Success_(return == true)
bool
HdlcEncodeBuffer(
_In_reads_bytes_(DecodedBufferLength)
PUCHAR DecodedBuffer,
_In_ ULONG DecodedBufferLength,
_Out_writes_bytes_(EncodedBufferLength)
PUCHAR EncodedBuffer,
_In_ ULONG EncodedBufferLength
)
{
USHORT Fcs = kInitFcs;
ULONG Offset = 0;
bool Complete = false;
if (Offset + 1 > EncodedBufferLength) goto error;
EncodedBuffer[Offset++] = HdlcFlagSequence;
for (ULONG i = 0; i < DecodedBufferLength; i++)
{
UCHAR aByte = DecodedBuffer[i];
if (!HdlcEncodeByte(aByte, Offset, EncodedBufferLength, EncodedBuffer)) {
goto error;
}
Fcs = UpdateFcs(Fcs, aByte);
}
Fcs ^= 0xffff;
if (!HdlcEncodeByte(Fcs & 0xff, Offset, EncodedBufferLength, EncodedBuffer) ||
!HdlcEncodeByte(Fcs >> 8, Offset, EncodedBufferLength, EncodedBuffer)) {
goto error;
}
if (Offset + 1 > EncodedBufferLength) goto error;
EncodedBuffer[Offset++] = HdlcFlagSequence;
NT_ASSERT(Offset == EncodedBufferLength);
Complete = true;
error:
return Complete;
}
enum HdlcDecodeState
{
kStateNoSync = 0,
kStateSync,
kStateEscaped,
};
_Success_(return == true)
bool
HdlcDecodeBuffer(
_In_reads_bytes_(*EncodedBufferLength)
PUCHAR EncodedBuffer,
_Inout_ PULONG EncodedBufferLength,
_Inout_ PULONG DecodedBufferLength,
_Out_writes_bytes_opt_(*DecodedBufferLength)
PUCHAR DecodedBuffer,
_Out_ bool* IsGood
)
{
UCHAR byte;
HdlcDecodeState state = kStateNoSync;
ULONG DecodedLength = 0;
USHORT Fcs = kInitFcs;
for (ULONG i = 0; i < *EncodedBufferLength; i++)
{
byte = EncodedBuffer[i];
switch (state)
{
case kStateNoSync:
{
if (byte == HdlcFlagSequence)
{
if (i != 0)
{
// Set the output for junk length
*EncodedBufferLength = i;
// Set the output 'IsGood' flag based on FCS
*IsGood = false;
return true;
}
else
{
state = kStateSync;
}
}
break;
}
case kStateSync:
{
switch (byte)
{
case HdlcEscapeSequence:
{
state = kStateEscaped;
break;
}
case HdlcFlagSequence:
{
// If it wasn't enough buffer to be a complete sequence, maybe we are
// actually between sequences. Leave the trailing escape character.
if (i < sizeof(USHORT) + 2)
{
// Set the output encoded buffer length
*EncodedBufferLength = i;
*IsGood = false;
}
else
{
// Set the output encoded buffer length
*EncodedBufferLength = i + 1;
// Set the decoded buffer length (subtract 2 for the FCS)
*DecodedBufferLength = DecodedLength - 2;
// Set the output 'IsGood' flag based on FCS
*IsGood = (Fcs == kGoodFcs);
}
return true;
}
default:
{
Fcs = UpdateFcs(Fcs, byte);
DecodedLength++;
if (DecodedBuffer)
{
if (*DecodedBufferLength >= DecodedLength)
{
DecodedBuffer[DecodedLength - 1] = byte;
}
}
break;
}
}
break;
}
case kStateEscaped:
{
if (i + 1 < *EncodedBufferLength)
{
byte ^= 0x20;
Fcs = UpdateFcs(Fcs, byte);
DecodedLength++;
if (DecodedBuffer)
{
if (*DecodedBufferLength >= DecodedLength)
{
DecodedBuffer[DecodedLength - 1] = byte;
}
}
state = kStateSync;
}
else
{
// Not enough buffer
}
break;
}
}
}
return false;
}
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for an HDLC-lite encoder and decoder.
*/
#pragma once
enum
{
HdlcXOn = 0x11,
HdlcXOff = 0x13,
HdlcFlagSequence = 0x7e, ///< HDLC Flag value
HdlcEscapeSequence = 0x7d, ///< HDLC Escape value
HdlcSpecial = 0xF8
};
ULONG
HdlcComputeEncodedLength(
_In_reads_bytes_(DecodedBufferLength)
PUCHAR DecodedBuffer,
_In_ ULONG DecodedBufferLength
);
_Success_(return == true)
bool
HdlcEncodeBuffer(
_In_reads_bytes_(DecodedBufferLength)
PUCHAR DecodedBuffer,
_In_ ULONG DecodedBufferLength,
_Out_writes_bytes_(EncodedBufferLength)
PUCHAR EncodedBuffer,
_In_ ULONG EncodedBufferLength
);
_Success_(return == true)
bool
HdlcDecodeBuffer(
_In_reads_bytes_(*EncodedBufferLength)
PUCHAR EncodedBuffer,
_Inout_ PULONG EncodedBufferLength,
_Inout_ PULONG DecodedBufferLength,
_Out_writes_bytes_opt_(*DecodedBufferLength)
PUCHAR DecodedBuffer,
_Out_ bool* IsGood
);
+408
View File
@@ -0,0 +1,408 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pch.hpp"
#include "oid.tmh"
template<typename _Datum>
PAGED NDIS_STATUS RequestQuery( _In_ PNDIS_OID_REQUEST OidRequest, const _Datum & value );
#define VERIFY_NDIS_OBJECT_HEADER(_header, _type, _revision, _size) \
(((_header).Type == _type) && \
((_header).Revision >= _revision) && \
((_header).Size >= _size))
#define VERIFY_NDIS_OBJECT_HEADER_PTR(_header, _type, _revision, _size) \
(((_header)->Type == _type) && \
((_header)->Revision >= _revision) && \
((_header)->Size >= _size))
#define VERIFY_NDIS_REQUEST_OBJECT_HEADER(_buffer, _type, _revision, _size) \
VERIFY_NDIS_OBJECT_HEADER_PTR(reinterpret_cast<PNDIS_OBJECT_HEADER>(_buffer), _type, _revision, _size)
#define ASSIGN_NDIS_OBJECT_HEADER(_header, _type, _revision, _size) \
(_header).Type = _type; \
(_header).Revision = _revision; \
(_header).Size = _size;
#define ASSIGN_NDIS_OBJECT_HEADER_PTR(_header, _type, _revision, _size) \
(_header)->Type = _type; \
(_header)->Revision = _revision; \
(_header)->Size = _size;
//
// List of Supported OIDs.
//
NDIS_OID NICSupportedOids[] =
{
// General
OID_GEN_CURRENT_LOOKAHEAD,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_INTERRUPT_MODERATION,
OID_GEN_LINK_PARAMETERS, // TODO: Mandatory Set
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_RCV_OK,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_RECEIVE_BUFFER_SPACE,
OID_GEN_STATISTICS,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_GEN_VENDOR_DRIVER_VERSION,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_VENDOR_ID,
OID_GEN_XMIT_OK,
OID_GEN_LINK_PARAMETERS, // TODO: Mandatory Set
// 802.3 Specific
OID_802_3_CURRENT_ADDRESS,
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAXIMUM_LIST_SIZE,
OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
OID_802_3_XMIT_MORE_COLLISIONS,
// PnP Stuff
OID_PNP_CAPABILITIES, // Optional
OID_PNP_QUERY_POWER, // Optional
// OpenThread Stuff
OID_OT_CAPABILITIES,
};
const ULONG SizeOfNICSupportedOids = sizeof(NICSupportedOids);
template<typename _Datum>
PAGED
NDIS_STATUS RequestQuery( _In_ PNDIS_OID_REQUEST OidRequest, const _Datum & value )
{
PAGED_CODE();
NT_ASSERT( (OidRequest->RequestType == NdisRequestQueryInformation) ||
(OidRequest->RequestType == NdisRequestQueryStatistics) );
if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < sizeof( _Datum ))
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof( _Datum );
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
return NDIS_STATUS_INVALID_LENGTH;
}
else
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof( _Datum );
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = sizeof( _Datum );
_Datum * pData = reinterpret_cast<_Datum *>(OidRequest->DATA.QUERY_INFORMATION.InformationBuffer);
*pData = value;
return NDIS_STATUS_SUCCESS;
}
}
PAGED
NDIS_STATUS RequestQuery32or64( _In_ PNDIS_OID_REQUEST OidRequest, const ULONG64 value )
{
PAGED_CODE();
NT_ASSERT( (OidRequest->RequestType == NdisRequestQueryInformation) ||
(OidRequest->RequestType == NdisRequestQueryStatistics) );
if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof( ULONG64 ))
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof( ULONG64 );
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = sizeof( ULONG64 );
PULONG64 pData = reinterpret_cast<PULONG64>(OidRequest->DATA.QUERY_INFORMATION.InformationBuffer);
*pData = value;
return NDIS_STATUS_SUCCESS;
}
else if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof( ULONG ))
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof( ULONG );
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = sizeof( ULONG );
PULONG pData = reinterpret_cast<PULONG>(OidRequest->DATA.QUERY_INFORMATION.InformationBuffer);
*pData = (ULONG)value;
return NDIS_STATUS_SUCCESS;
}
else
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof( ULONG64 );
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
return NDIS_STATUS_INVALID_LENGTH;
}
}
PAGED
NDIS_STATUS RequestQueryThreadCapabilities(_In_ PNDIS_OID_REQUEST OidRequest)
{
PAGED_CODE();
OT_CAPABILITIES caps = { 0 };
ASSIGN_NDIS_OBJECT_HEADER(caps.Header, NDIS_OBJECT_TYPE_DEFAULT, OT_CAPABILITIES_REVISION_1, SIZEOF_OT_CAPABILITIES_REVISION_1);
caps.MiniportMode = OT_MP_MODE_THREAD; // Thread Tunnel mode
if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < SIZEOF_OT_CAPABILITIES_REVISION_1)
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = SIZEOF_OT_CAPABILITIES_REVISION_1;
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
return NDIS_STATUS_INVALID_LENGTH;
}
else
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = SIZEOF_OT_CAPABILITIES_REVISION_1;
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = SIZEOF_OT_CAPABILITIES_REVISION_1;
memcpy(OidRequest->DATA.QUERY_INFORMATION.InformationBuffer, &caps, SIZEOF_OT_CAPABILITIES_REVISION_1);
return NDIS_STATUS_SUCCESS;
}
}
PAGED
NDIS_STATUS RequestQueryGenStatistics(_In_ PNDIS_OID_REQUEST OidRequest, _In_ POTTMP_ADAPTER_CONTEXT AdapterContext)
{
PAGED_CODE();
NDIS_STATISTICS_INFO statistics = { 0 };
ASSIGN_NDIS_OBJECT_HEADER(statistics.Header, NDIS_OBJECT_TYPE_DEFAULT, NDIS_SIZEOF_STATISTICS_INFO_REVISION_1, NDIS_STATISTICS_INFO_REVISION_1);
statistics.SupportedStatistics = NIC_SUPPORTED_STATISTICS;
/* Bytes in */
statistics.ifHCInOctets = AdapterContext->BytesRxDirected +
AdapterContext->BytesRxMulticast +
AdapterContext->BytesRxBroadcast;
statistics.ifHCInUcastOctets = AdapterContext->BytesRxDirected;
statistics.ifHCInMulticastOctets = AdapterContext->BytesRxMulticast;
statistics.ifHCInBroadcastOctets = AdapterContext->BytesRxBroadcast;
/* Packets in */
statistics.ifHCInUcastPkts = AdapterContext->FramesRxDirected;
statistics.ifHCInMulticastPkts = AdapterContext->FramesRxMulticast;
statistics.ifHCInBroadcastPkts = AdapterContext->FramesRxBroadcast;
/* Errors in */
statistics.ifInErrors = AdapterContext->RxCrcErrors +
AdapterContext->RxAlignmentErrors +
AdapterContext->RxDmaOverrunErrors +
AdapterContext->RxRuntErrors;
statistics.ifInDiscards = AdapterContext->RxResourceErrors;
/* Bytes out */
statistics.ifHCOutOctets = AdapterContext->BytesTxDirected +
AdapterContext->BytesTxMulticast +
AdapterContext->BytesTxBroadcast;
statistics.ifHCOutUcastOctets = AdapterContext->BytesTxDirected;
statistics.ifHCOutMulticastOctets = AdapterContext->BytesTxMulticast;
statistics.ifHCOutBroadcastOctets = AdapterContext->BytesTxBroadcast;
/* Packets out */
statistics.ifHCOutUcastPkts = AdapterContext->FramesTxDirected;
statistics.ifHCOutMulticastPkts = AdapterContext->FramesTxMulticast;
statistics.ifHCOutBroadcastPkts = AdapterContext->FramesTxBroadcast;
/* Errors out */
statistics.ifOutErrors = AdapterContext->TxAbortExcessCollisions +
AdapterContext->TxDmaUnderrun +
AdapterContext->TxLostCRS +
AdapterContext->TxLateCollisions+
AdapterContext->TransmitFailuresOther;
statistics.ifOutDiscards = 0ULL;
return RequestQuery(OidRequest, statistics);
}
PAGED
_Use_decl_annotations_
NDIS_STATUS
MPOidRequest(
_In_ NDIS_HANDLE MiniportAdapterContext,
_In_ PNDIS_OID_REQUEST OidRequest
)
{
POTTMP_ADAPTER_CONTEXT AdapterContext = (POTTMP_ADAPTER_CONTEXT)MiniportAdapterContext;
NDIS_STATUS status = NDIS_STATUS_NOT_SUPPORTED;
bool fFailExpected = false;
LogFuncEntry(DRIVER_DEFAULT);
PAGED_CODE();
switch (OidRequest->RequestType)
{
case NdisRequestSetInformation:
switch (OidRequest->DATA.QUERY_INFORMATION.Oid)
{
case OID_802_3_MULTICAST_LIST:
// TODO: Check with Jeffrey how to better handle this
status = NDIS_STATUS_MULTICAST_FULL;
fFailExpected = true;
break;
//
// Fake it until we make it :)
// We can't bind unless we report success for these OIDs
//
case OID_GEN_CURRENT_PACKET_FILTER:
case OID_PM_ADD_WOL_PATTERN:
case OID_PM_REMOVE_WOL_PATTERN:
case OID_GEN_CURRENT_LOOKAHEAD:
// TODO: Implement this
status = NDIS_STATUS_SUCCESS;
break;
// Explicitly not supported
case OID_GEN_INTERRUPT_MODERATION:
status = NDIS_STATUS_NOT_SUPPORTED;
fFailExpected = true;
break;
// Unknown
default:
status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
break;
case NdisRequestQueryInformation:
case NdisRequestQueryStatistics:
switch (OidRequest->DATA.QUERY_INFORMATION.Oid)
{
case OID_GEN_INTERRUPT_MODERATION:
{
static const NDIS_INTERRUPT_MODERATION_PARAMETERS nimp = {
{ NDIS_OBJECT_TYPE_DEFAULT, NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1, NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1 },
0,
NdisInterruptModerationNotSupported };
status = RequestQuery( OidRequest, nimp );
break;
}
case OID_GEN_RCV_OK:
status = RequestQuery32or64( OidRequest, AdapterContext->FramesRxBroadcast
+ AdapterContext->FramesRxMulticast
+ AdapterContext->FramesRxDirected );
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
status = RequestQuery<ULONG>( OidRequest, HW_MAX_FRAME_SIZE );
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
status = RequestQuery<ULONG>( OidRequest, HW_MAX_FRAME_SIZE * AdapterContext->ulMaxBusyRecvs );
break;
case OID_GEN_STATISTICS:
status = RequestQueryGenStatistics(OidRequest, AdapterContext);
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
status = RequestQuery<ULONG>( OidRequest, HW_MAX_FRAME_SIZE * AdapterContext->ulMaxBusySends );
break;
case OID_GEN_VENDOR_DESCRIPTION:
case OID_GEN_VENDOR_DRIVER_VERSION:
case OID_GEN_VENDOR_ID:
if (OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength < sizeof(NIC_VENDOR_DESC))
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof( NIC_VENDOR_DESC );
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
status = NDIS_STATUS_INVALID_LENGTH;
}
else
{
OidRequest->DATA.QUERY_INFORMATION.BytesNeeded = sizeof( NIC_VENDOR_DESC );
OidRequest->DATA.QUERY_INFORMATION.BytesWritten = sizeof( NIC_VENDOR_DESC );
memcpy(OidRequest->DATA.QUERY_INFORMATION.InformationBuffer, NIC_VENDOR_DESC, sizeof(NIC_VENDOR_DESC));
status = NDIS_STATUS_SUCCESS;
}
break;
case OID_GEN_XMIT_OK:
status = RequestQuery32or64( OidRequest, AdapterContext->FramesTxBroadcast
+ AdapterContext->FramesTxMulticast
+ AdapterContext->FramesTxDirected );
break;
case OID_802_3_CURRENT_ADDRESS:
status = RequestQuery( OidRequest, AdapterContext->ExtendedAddress );
break;
case OID_802_3_PERMANENT_ADDRESS:
status = RequestQuery( OidRequest, AdapterContext->ExtendedAddress );
break;
case OID_PNP_CAPABILITIES:
// We do not support low power
status = NDIS_STATUS_NOT_SUPPORTED;
fFailExpected = true;
break;
case OID_PNP_QUERY_POWER:
status = NDIS_STATUS_NOT_ACCEPTED;
fFailExpected = true;
break;
case OID_OT_CAPABILITIES:
status = RequestQueryThreadCapabilities( OidRequest );
break;
default:
status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
break;
case NdisRequestMethod:
break;
default:
status = NDIS_STATUS_INVALID_OID;
break;
}
UNREFERENCED_PARAMETER( OidRequest );
if (!fFailExpected && (status != NDIS_STATUS_SUCCESS))
{
LogFuncExitMsg(DRIVER_DEFAULT, " Type:%u Oid:%u Status:%!NDIS_STATUS!", OidRequest->RequestType, OidRequest->DATA.QUERY_INFORMATION.Oid, status);
}
else
{
// By not using LogFuncExitNDIS, this won't get auto-promoted to a warning on non-0 statuses
LogFuncExitMsg(DRIVER_DEFAULT, " Type:%u Oid:%u Status:%!NDIS_STATUS!", OidRequest->RequestType, OidRequest->DATA.QUERY_INFORMATION.Oid, status);
}
return status;
}
_Use_decl_annotations_
VOID
MPCancelOidRequest(
_In_ NDIS_HANDLE /* MiniportAdapterContext */,
_In_ PVOID /* pRequestId */
)
{
LogFuncEntry(DRIVER_DEFAULT);
LogFuncExit(DRIVER_DEFAULT);
}
+73
View File
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* Header file for the routines related to OIDs
*/
extern NDIS_OID NICSupportedOids[];
extern const ULONG SizeOfNICSupportedOids;
#ifdef OTTMP_LEGACY
PAGED MINIPORT_OID_REQUEST MPOidRequest;
MINIPORT_CANCEL_OID_REQUEST MPCancelOidRequest;
#else
EVT_NET_REQUEST_QUERY_DATA EvtQueryUlong;
EVT_NET_REQUEST_QUERY_DATA EvtQueryGenVendorDescription;
EVT_NET_REQUEST_QUERY_DATA EvtQueryAddress;
EVT_NET_REQUEST_QUERY_DATA EvtQueryGenStatistics;
EVT_NET_REQUEST_QUERY_DATA EvtQueryGenInterruptModeration;
EVT_NET_REQUEST_QUERY_DATA EvtQueryGenXmitRcvOk;
EVT_NET_REQUEST_QUERY_DATA EvtQueryThreadCapabilities;
EVT_NET_REQUEST_DEFAULT_SET_DATA EvtDefaultSetData;
NDIS_STATUS
AdapterSetInformation(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext,
_In_ PNDIS_OID_REQUEST NdisSetRequest);
NDIS_STATUS
AdapterQueryInformation(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext,
_Inout_ PNDIS_OID_REQUEST NdisQueryRequest
);
PAGED
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
AddDefaultRequestSequentialQueue(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
);
#endif
+121
View File
@@ -0,0 +1,121 @@
;
; Copyright (c) 2016, The OpenThread Authors.
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; 3. Neither the name of the copyright holder nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
; POSSIBILITY OF SUCH DAMAGE.
;
[Version]
Signature = "$Windows NT$"
Class = Net
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %OpenThread%
DriverVer =
PnpLockDown = 1
CatalogFile = ottmp.cat
[Manufacturer]
%OpenThread% = OpenThread,NT$ARCH$
[OpenThread.NT$ARCH$]
%ottmp.DeviceDesc% = ottmp.ndi, root\ottmp ; Root enumerated
;-------------------------------------------------------------------------------
; OpenThread Tunnel Thread Adapter
;-------------------------------------------------------------------------------
[ottmp.ndi]
Characteristics = 0x4 ; NCF_PHYSICAL
*IfType = 259 ; IF_TYPE_IEEE802154
*MediaType = 19 ; NdisMediumIP
*PhysicalMediaType = 20 ; NdisPhysicalMediumNative802_15_4
*IfConnectorPresent = 0
*AccessType = 2 ; NET_IF_ACCESS_BROADCAST
*ConnectionType = 1 ; NET_IF_CONNECTION_PASSIVE
*DirectionType = 0 ; NET_IF_DIRECTION_SENDRECEIVE
AddReg = ottmp.Reg
CopyFiles = ottmp.CopyFiles
[ottmp.ndi.Services]
AddService = ottmp, 2, ottmp.Service, ottmp.EventLog
;-------------------------------------------------------------------------------
; OpenThread Tunnel Miniport Common
;-------------------------------------------------------------------------------
[ottmp.Reg]
HKR, , BusNumber, 0, "0"
HKR, Ndi, Service, 0, "ottmp"
HKR, Ndi\Interfaces, UpperRange, 0, "flpp6"
HKR, Ndi\Interfaces, LowerRange, 0, "802.15.4"
;-------------------------------------------------------------------------------
; WDF Section
;-------------------------------------------------------------------------------
[ottmp.ndi.Wdf]
KmdfService = ottmp, ottmp.wdfsect
[ottmp.wdfsect]
KmdfLibraryVersion = $KMDFVERSION$
;-------------------------------------------------------------------------------
; Driver and Service Section
;-------------------------------------------------------------------------------
[ottmp.CopyFiles]
ottmp.sys,,,2
[ottmp.Service]
DisplayName = %ottmp.Service.DispName%
ServiceType = 1 ;%SERVICE_KERNEL_DRIVER%
StartType = 3 ;%SERVICE_DEMAND_START%
ErrorControl = 1 ;%SERVICE_ERROR_NORMAL%
ServiceBinary = %12%\ottmp.sys
LoadOrderGroup = NDIS
AddReg = TextModeFlags.Reg
Description = %ottmp.DeviceDesc%
[ottmp.EventLog]
AddReg = ottmp.AddEventLog.Reg
[ottmp.AddEventLog.Reg]
HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\netevent.dll"
HKR, , TypesSupported, 0x00010001, 7
[TextModeFlags.Reg]
HKR, , TextModeFlags, 0x00010001, 0x0001
[SourceDisksNames]
1 = %ottmp.DeviceDesc%,,,""
[SourceDisksFiles]
ottmp.sys = 1,,
[DestinationDirs]
ottmp.CopyFiles = 12
;-------------------------------------------------------------------------------
; Localizable Strings
;-------------------------------------------------------------------------------
[Strings]
OpenThread = "OpenThread"
ottmp.DeviceDesc = "OpenThread Tunnel Thread Adapter"
ottmp.Service.DispName = "OpenThread Tunnel Miniport"
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <windows.h>
#include <ntverp.h>
/*-----------------------------------------------*/
/* the following lines are specific to this file */
/*-----------------------------------------------*/
/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR
* and VER_INTERNALNAME_STR must be defined before including COMMON.VER
* The strings don't need a '\0', since common.ver has them.
*/
#define VER_FILETYPE VFT_DRV
/* possible values: VFT_UNKNOWN
VFT_APP
VFT_DLL
VFT_DRV
VFT_FONT
VFT_VXD
VFT_STATIC_LIB
*/
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
/* possible values VFT2_UNKNOWN
VFT2_DRV_PRINTER
VFT2_DRV_KEYBOARD
VFT2_DRV_LANGUAGE
VFT2_DRV_DISPLAY
VFT2_DRV_MOUSE
VFT2_DRV_NETWORK
VFT2_DRV_SYSTEM
VFT2_DRV_INSTALLABLE
VFT2_DRV_SOUND
VFT2_DRV_COMM
*/
#define VER_FILEDESCRIPTION_STR "OpenThread Tunnel Miniport"
#define VER_INTERNALNAME_STR "OTTMP.SYS"
#include "common.ver" // NT5.0 version file.
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//
// system headers
//
extern "C" {
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ntverp.h>
#include <ntddk.h>
#include <ntstrsafe.h>
#include <ntintsafe.h>
#include <ndis.h>
#include <WppRecorder.h>
#include <wdf.h>
#ifndef OTTMP_LEGACY
#include <netadaptercx.h>
#endif
#include <WdfMiniport.h>
#include <wdm.h>
#include <ntddser.h>
}
// Intellisense definition for DbgRaiseAssertionFailure because for some reason Visual Studio can't
// find it.
#ifdef __INTELLISENSE__
#define DbgRaiseAssertionFailure() ((void) 0)
#endif
#include "otOID.h"
#define CODE_SEG(seg) __declspec(code_seg(seg))
#define INITCODE CODE_SEG("INIT")
#define PAGED CODE_SEG("PAGE")
typedef struct _OTTMP_ADAPTER_CONTEXT *POTTMP_ADAPTER_CONTEXT;
typedef struct _OTTMP_DEVICE_CONTEXT *POTTMP_DEVICE_CONTEXT;
#include "hardware.hpp"
#include "hdlc.hpp"
#include "driver.hpp"
#include "adapter.hpp"
#include "device.hpp"
#include "serial.hpp"
#include "oid.hpp"
#include "platform/logging-windows.h"
File diff suppressed because it is too large Load Diff
+122
View File
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
PAGED
_No_competing_thread_
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
SerialInitialize(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
);
PAGED
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
SerialUninitialize(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
);
PAGED
_No_competing_thread_
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
SerialInitializeTarget(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext,
_In_ PCWSTR TargetName
);
PAGED
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
SerialUninitializeTarget(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
);
PAGED
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
SerialConfigure(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
);
PAGED
_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS
SerialCheckStatus(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext,
_In_ bool DataExpected
);
PAGED
_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS
SerialFlushAndCheckStatus(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext
);
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
SerialSendData(
_In_ POTTMP_ADAPTER_CONTEXT AdapterContext,
_In_ PNET_BUFFER_LIST NetBufferLists
);
PAGED
_Function_class_(EVT_WDF_WORKITEM)
_IRQL_requires_same_
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
SerialSendLoop(
_In_ WDFWORKITEM WorkItem
);
PAGED
_Function_class_(EVT_WDF_WORKITEM)
_IRQL_requires_same_
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
SerialRecvLoop(
_In_ WDFWORKITEM WorkItem
);
_Function_class_(EVT_WDF_REQUEST_COMPLETION_ROUTINE)
_IRQL_requires_same_
VOID
SerialRecvComplete(
_In_ WDFREQUEST Request,
_In_ WDFIOTARGET Target,
_In_ PWDF_REQUEST_COMPLETION_PARAMS Params,
_In_ WDFCONTEXT Context
);
VOID
DumpBuffer(
_In_reads_bytes_(aLength) PCUCHAR aBuf,
_In_ size_t aLength
);