summaryrefslogtreecommitdiff
path: root/network/ndis/ndisprot
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
committerDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
commit97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch)
tree46f3701832d70b420eb0fc0eb93261f9da45db3f /network/ndis/ndisprot
parentef1905bf1e8825bb31120dfb27e0daf3154d859a (diff)
Initial publish
Diffstat (limited to 'network/ndis/ndisprot')
-rw-r--r--network/ndis/ndisprot/6x/ReadMe.md84
-rw-r--r--network/ndis/ndisprot/6x/ndisprot60.sln63
-rw-r--r--network/ndis/ndisprot/6x/sys/60/ndisprot60.inf90
-rw-r--r--network/ndis/ndisprot/6x/sys/60/ndisprot60.rc49
-rw-r--r--network/ndis/ndisprot/6x/sys/60/ndisprot60.vcxproj265
-rw-r--r--network/ndis/ndisprot/6x/sys/60/ndisprot60.vcxproj.Filters49
-rw-r--r--network/ndis/ndisprot/6x/sys/60/precompsrc.c1
-rw-r--r--network/ndis/ndisprot/6x/sys/630/ndisprot630.inf109
-rw-r--r--network/ndis/ndisprot/6x/sys/630/ndisprot630.rc49
-rw-r--r--network/ndis/ndisprot/6x/sys/630/ndisprot630.vcxproj265
-rw-r--r--network/ndis/ndisprot/6x/sys/630/ndisprot630.vcxproj.Filters49
-rw-r--r--network/ndis/ndisprot/6x/sys/630/precompsrc.c1
-rw-r--r--network/ndis/ndisprot/6x/sys/debug.c425
-rw-r--r--network/ndis/ndisprot/6x/sys/debug.h220
-rw-r--r--network/ndis/ndisprot/6x/sys/excallbk.c195
-rw-r--r--network/ndis/ndisprot/6x/sys/macros.h234
-rw-r--r--network/ndis/ndisprot/6x/sys/ndisbind.c2061
-rw-r--r--network/ndis/ndisprot/6x/sys/ndisprot.h567
-rw-r--r--network/ndis/ndisprot/6x/sys/ntdisp.c916
-rw-r--r--network/ndis/ndisprot/6x/sys/precomp.h18
-rw-r--r--network/ndis/ndisprot/6x/sys/protuser.h92
-rw-r--r--network/ndis/ndisprot/6x/sys/recv.c1119
-rw-r--r--network/ndis/ndisprot/6x/sys/send.c463
-rw-r--r--network/ndis/ndisprot/6x/test/prottest.c665
-rw-r--r--network/ndis/ndisprot/6x/test/prottest.vcxproj243
-rw-r--r--network/ndis/ndisprot/6x/test/prottest.vcxproj.Filters22
26 files changed, 8314 insertions, 0 deletions
diff --git a/network/ndis/ndisprot/6x/ReadMe.md b/network/ndis/ndisprot/6x/ReadMe.md
new file mode 100644
index 00000000..63e3a5ec
--- /dev/null
+++ b/network/ndis/ndisprot/6x/ReadMe.md
@@ -0,0 +1,84 @@
+NDIS Connection-less Protocol Driver Sample
+===========================================
+
+This sample demonstrates a connection-less NDIS 6.0 protocol.The driver supports sending and receiving raw Ethernet frames using `ReadFile`/`WriteFile` calls from user-mode. It only receives frames with a specific EtherType field. As an NDIS protocol, it illustrates how to establish and tear down bindings to Ethernet adapters, i.e. those that export medium type **NdisMedium802\_3**. It shows how to set a packet filter, send and receive data, and handle plug-and-play events.
+
+
+INSTALLATION
+------------
+
+The driver is installed using the INF file ndisprot.inf, which is provided in the driver directory. In Network Connections UI, select an adapter and open **Properties.**
+
+Click **Install**, then **Protocol**, then **Add**, and then **Have disk**. Then point to the location of the .inf and driver.
+
+Select **Sample NDIS Protocol Driver** and click **OK**. After installing the protocol, copy over the test application prottest.exe to a convenient location. Please note that the driver service has been set to manual start in the INF file. As a result, it doesn't get loaded automatically when you install.
+
+Usage
+-----
+
+To start the driver, type **Net start ndisprot**.
+
+To stop the driver, type **Net stop ndisprot**.
+
+To test the driver, run **prottest**. For help on usage, run **prottest -?**
+
+**usage: PROTTEST [options] \<devicename\>**
+
+**options:**
+
+<table>
+<colgroup>
+<col width="50%" />
+<col width="50%" />
+</colgroup>
+<tbody>
+<tr class="odd">
+<td align="left">-e
+Enumerate devices</td>
+<td align="left">-r
+Read</td>
+</tr>
+</tbody>
+</table>
+
+Prottest exercises the IOCTLs supported by NDISPROT, and sends and/or receives data on the selected device. In order to use prottest, the user must have administrative privilege. Users should pass down a big enough buffer in order to receive the entire received data. If the length of the buffer passed down is smaller than the length of the received data, NDISPROT will only copy part of the data and discard the rest when the given buffer is full.
+
+Use the **–e** option to enumerate all devices to which NDISPROT is bound:
+
+**C:\\prot\>prottest -n 2 \\DEVICE\\{9273DA7D-5275-4B9A-AC56-68A49D121F1F}**
+
+**DoWriteProc: finished sending 2 packets of 100 bytes each**
+
+**DoReadProc finished: read 2 packets**
+
+**Note**  
+
+With a checked version of ndisprot.sys, you can control the volume of debug information generated by changing the variable `ndisprotDebugLevel`. Refer to debug.h for more information.
+
+For more information, see [NDIS Protocol Drivers](http://msdn.microsoft.com/en-us/library/windows/hardware/ff566821) in the network devices design guide.
+
+File Manifest
+-------------
+
+<table>
+<colgroup>
+<col width="50%" />
+<col width="50%" />
+</colgroup>
+<thead>
+<tr class="header">
+<th align="left">File
+Description</th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left">prottest.c
+User-mode test application</td>
+<td align="left">debug.c
+Routines to aid debugging</td>
+</tr>
+</tbody>
+</table>
+
+
diff --git a/network/ndis/ndisprot/6x/ndisprot60.sln b/network/ndis/ndisprot/6x/ndisprot60.sln
new file mode 100644
index 00000000..cc13f976
--- /dev/null
+++ b/network/ndis/ndisprot/6x/ndisprot60.sln
@@ -0,0 +1,63 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0
+MinimumVisualStudioVersion = 12.0
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "60", "60", "{39A2B1A3-5281-47DF-A0A5-B08E1F979C9E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sys", "Sys", "{C09D8AF9-55C0-4192-A787-B6CA08D83AD0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "630", "630", "{7BA6C25F-BBE2-4331-B598-C5F03E11B45D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{A41A7FEE-D4C4-4D9E-B7B3-679200586B93}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ndisprot60", "sys\60\ndisprot60.vcxproj", "{74918B99-A7A2-4462-9330-D61ED648B991}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ndisprot630", "sys\630\ndisprot630.vcxproj", "{DB252AE8-E32C-4E60-B0EB-33A2CB80861C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "prottest", "test\prottest.vcxproj", "{0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {74918B99-A7A2-4462-9330-D61ED648B991}.Debug|Win32.ActiveCfg = Debug|Win32
+ {74918B99-A7A2-4462-9330-D61ED648B991}.Debug|Win32.Build.0 = Debug|Win32
+ {74918B99-A7A2-4462-9330-D61ED648B991}.Release|Win32.ActiveCfg = Release|Win32
+ {74918B99-A7A2-4462-9330-D61ED648B991}.Release|Win32.Build.0 = Release|Win32
+ {74918B99-A7A2-4462-9330-D61ED648B991}.Debug|x64.ActiveCfg = Debug|x64
+ {74918B99-A7A2-4462-9330-D61ED648B991}.Debug|x64.Build.0 = Debug|x64
+ {74918B99-A7A2-4462-9330-D61ED648B991}.Release|x64.ActiveCfg = Release|x64
+ {74918B99-A7A2-4462-9330-D61ED648B991}.Release|x64.Build.0 = Release|x64
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C}.Debug|Win32.Build.0 = Debug|Win32
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C}.Release|Win32.ActiveCfg = Release|Win32
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C}.Release|Win32.Build.0 = Release|Win32
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C}.Debug|x64.ActiveCfg = Debug|x64
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C}.Debug|x64.Build.0 = Debug|x64
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C}.Release|x64.ActiveCfg = Release|x64
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C}.Release|x64.Build.0 = Release|x64
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}.Debug|Win32.Build.0 = Debug|Win32
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}.Release|Win32.ActiveCfg = Release|Win32
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}.Release|Win32.Build.0 = Release|Win32
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}.Debug|x64.ActiveCfg = Debug|x64
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}.Debug|x64.Build.0 = Debug|x64
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}.Release|x64.ActiveCfg = Release|x64
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {74918B99-A7A2-4462-9330-D61ED648B991} = {39A2B1A3-5281-47DF-A0A5-B08E1F979C9E}
+ {DB252AE8-E32C-4E60-B0EB-33A2CB80861C} = {7BA6C25F-BBE2-4331-B598-C5F03E11B45D}
+ {0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0} = {A41A7FEE-D4C4-4D9E-B7B3-679200586B93}
+ {39A2B1A3-5281-47DF-A0A5-B08E1F979C9E} = {C09D8AF9-55C0-4192-A787-B6CA08D83AD0}
+ {7BA6C25F-BBE2-4331-B598-C5F03E11B45D} = {C09D8AF9-55C0-4192-A787-B6CA08D83AD0}
+ EndGlobalSection
+EndGlobal
diff --git a/network/ndis/ndisprot/6x/sys/60/ndisprot60.inf b/network/ndis/ndisprot/6x/sys/60/ndisprot60.inf
new file mode 100644
index 00000000..5618bfcf
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/60/ndisprot60.inf
@@ -0,0 +1,90 @@
+;-------------------------------------------------------------------------
+; NDISPROT60.INF -- Sample NDIS Protocol Driver
+;
+; Copyright (c) 2003, Microsoft Corporation
+;-------------------------------------------------------------------------
+[version]
+Signature = "$Windows NT$"
+Class = NetTrans
+ClassGUID = {4d36e975-e325-11ce-bfc1-08002be10318}
+Provider = %Msft%
+DriverVer = 10/01/2002,4.2
+CatalogFile = ndisprot60.cat
+
+
+[Manufacturer]
+%Msft%=MSFT,NTx86,NTia64,NTamd64
+
+[MSFT.NTx86]
+%NDISPROT_Desc%=Install, MS_NDISPROT
+
+[MSFT.NTia64]
+%NDISPROT_Desc%=Install, MS_NDISPROT
+
+[MSFT.NTamd64]
+%NDISPROT_Desc%=Install, MS_NDISPROT
+
+;-------------------------------------------------------------------------
+; Installation Section
+;-------------------------------------------------------------------------
+[Install]
+AddReg=Inst_Ndi
+Characteristics=0x0 ;
+CopyFiles=CpyFiles_Sys
+
+;-------------------------------------------------------------------------
+; Ndi installation support
+;-------------------------------------------------------------------------
+[Inst_Ndi]
+HKR,Ndi,Service,,"Ndisprot"
+HKR,Ndi,HelpText,,%NDISPROT_HelpText%
+HKR,Ndi\Interfaces, UpperRange,, noupper
+HKR,"Ndi\Interfaces","LowerRange",,"ndis5,ndis4,ndis5_prot"
+
+;-------------------------------------------------------------------------
+; Service installation support
+;-------------------------------------------------------------------------
+[Install.Services]
+AddService=Ndisprot,,NDISPROT_Service_Inst
+
+[NDISPROT_Service_Inst]
+DisplayName = %NDISPROT_Desc%
+ServiceType = 1 ;SERVICE_KERNEL_DRIVER
+StartType = 3 ;SERVICE_DEMAND_START
+ErrorControl = 1 ;SERVICE_ERROR_NORMAL
+ServiceBinary = %12%\ndisprot60.sys
+Description = %NDISPROT_Desc%
+
+[Install.Remove.Services]
+DelService=Ndisprot,0x200
+
+;-------------------------------------------------------------------------
+; Declare Destination Directories for file copy/deletion
+;-------------------------------------------------------------------------
+[SourceDisksNames]
+1=%DiskDescription%,"",,
+
+[SourceDisksFiles]
+ndisprot60.sys=1
+
+
+[DestinationDirs]
+CpyFiles_Sys = 12 ; DIRID_DRIVERS
+
+
+;-------------------------------------------------------------------------
+; Files to Copy/Delete - Referenced by Install and Remove sections above
+;-------------------------------------------------------------------------
+[CpyFiles_Sys]
+Ndisprot60.sys,,,2
+
+[Strings]
+Msft = "Your Company"
+DiskDescription = "Microsoft Ndisprot Sample Protocol Driver Disk"
+NDISPROT_Desc = "Sample NDIS Protocol Driver"
+NDISPROT_HelpText = "A driver to support user-mode I/O on NDIS devices"
+
+
+
+
+
diff --git a/network/ndis/ndisprot/6x/sys/60/ndisprot60.rc b/network/ndis/ndisprot/6x/sys/60/ndisprot60.rc
new file mode 100644
index 00000000..59a37c53
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/60/ndisprot60.rc
@@ -0,0 +1,49 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ ndisprot.rc
+
+Abstract:
+
+ Internal resource file for driver.
+
+--*/
+
+#include <windows.h>
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_NETWORK
+
+#define VER_FILEDESCRIPTION_STR "NDIS User mode I/O Driver"
+#define VER_INTERNALNAME_STR "NDISPROT60.SYS"
+#define VER_ORIGINALFILENAME_STR "NDISPROT60.SYS"
+#define VER_LANGNEUTRAL
+
+#define VER_FILEVERSION 4,20,00,0000
+#define VER_FILEVERSION_STR "4.20.00.0000"
+
+#undef VER_PRODUCTVERSION
+#define VER_PRODUCTVERSION VER_FILEVERSION
+
+#undef VER_PRODUCTVERSION_STR
+#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
+
+#define VER_LEGALCOPYRIGHT_STR "Copyright (C) 2010 Microsoft Corporation"
+
+#undef VER_COMPANYNAME_STR
+#define VER_COMPANYNAME_STR "Microsoft Corporation"
+
+#undef VER_PRODUCTNAME_STR
+#define VER_PRODUCTNAME_STR "NDIS 6.0 Sample Protocol Driver"
+
+#include "common.ver"
+
diff --git a/network/ndis/ndisprot/6x/sys/60/ndisprot60.vcxproj b/network/ndis/ndisprot/6x/sys/60/ndisprot60.vcxproj
new file mode 100644
index 00000000..068f19e0
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/60/ndisprot60.vcxproj
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{74918B99-A7A2-4462-9330-D61ED648B991}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{F57A9742-AE91-4E5C-AAF8-582BEC93A8CA}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>WDM</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>WDM</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>WDM</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>WDM</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>ndisprot60</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>ndisprot60</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>ndisprot60</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>ndisprot60</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS60=1</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\debug.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\ExCallbk.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\ndisbind.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\ntdisp.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\recv.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\send.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="precompsrc.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Create</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ResourceCompile Include="ndisprot60.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/network/ndis/ndisprot/6x/sys/60/ndisprot60.vcxproj.Filters b/network/ndis/ndisprot/6x/sys/60/ndisprot60.vcxproj.Filters
new file mode 100644
index 00000000..e971259b
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/60/ndisprot60.vcxproj.Filters
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{FC988553-FCE1-455C-A2B8-4253B2E40339}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{CA13EBCF-7249-4085-AEED-A9AB9756BBDF}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{B5901951-2387-48ED-83C6-A5D259BF7E0D}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{FCDA9B5C-B135-477F-BC65-BE9761005881}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\debug.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\ExCallbk.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\ndisbind.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\ntdisp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\recv.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\send.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="precompsrc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ndisprot60.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/network/ndis/ndisprot/6x/sys/60/precompsrc.c b/network/ndis/ndisprot/6x/sys/60/precompsrc.c
new file mode 100644
index 00000000..5944cf51
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/60/precompsrc.c
@@ -0,0 +1 @@
+#include "precomp.h" \ No newline at end of file
diff --git a/network/ndis/ndisprot/6x/sys/630/ndisprot630.inf b/network/ndis/ndisprot/6x/sys/630/ndisprot630.inf
new file mode 100644
index 00000000..0fc1eb67
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/630/ndisprot630.inf
@@ -0,0 +1,109 @@
+;-------------------------------------------------------------------------
+; NDISPROT630.INF -- Sample NDIS Protocol Driver
+;
+; Copyright (c) 2003, Microsoft Corporation
+;-------------------------------------------------------------------------
+[version]
+Signature = "$Windows NT$"
+Class = NetTrans
+ClassGUID = {4d36e975-e325-11ce-bfc1-08002be10318}
+Provider = %Msft%
+DriverVer = 07/16/2010,4.2
+CatalogFile = ndisprot630.cat
+
+
+[Manufacturer]
+%Msft%=MSFT,NTx86,NTia64,NTamd64,NTarm,NTarm64
+
+[MSFT.NTx86]
+%NDISPROT_Desc%=Install, MS_NDISPROT
+
+[MSFT.NTia64]
+%NDISPROT_Desc%=Install, MS_NDISPROT
+
+[MSFT.NTamd64]
+%NDISPROT_Desc%=Install, MS_NDISPROT
+
+[MSFT.NTarm]
+%NDISPROT_Desc%=Install, MS_NDISPROT
+
+[MSFT.NTarm64]
+%NDISPROT_Desc%=Install, MS_NDISPROT
+
+;-------------------------------------------------------------------------
+; Installation Section
+;-------------------------------------------------------------------------
+[Install]
+AddReg=Inst_Ndi
+Characteristics=0x0 ;
+CopyFiles=CpyFiles_Sys
+
+;-------------------------------------------------------------------------
+; Ndi installation support
+;-------------------------------------------------------------------------
+[Inst_Ndi]
+HKR,Ndi,Service,,"Ndisprot"
+HKR,Ndi,HelpText,,%NDISPROT_HelpText%
+HKR,Ndi\Interfaces, UpperRange,, noupper
+HKR,"Ndi\Interfaces","LowerRange",,"ndis5,ndis4,ndis5_prot"
+
+;-------------------------------------------------------------------------
+; Service installation support
+;-------------------------------------------------------------------------
+[Install.Services]
+AddService=Ndisprot,,NDISPROT_Service_Inst
+
+[NDISPROT_Service_Inst]
+DisplayName = %NDISPROT_Desc%
+ServiceType = 1 ;SERVICE_KERNEL_DRIVER
+StartType = 3 ;SERVICE_DEMAND_START
+ErrorControl = 1 ;SERVICE_ERROR_NORMAL
+ServiceBinary = %12%\ndisprot630.sys
+Description = %NDISPROT_Desc%
+AddReg = NdisImPlatformBinding_Reg
+
+[NdisImPlatformBinding_Reg]
+; By default, when an LBFO team or Bridge is created, all protocols will be
+; unbound from the underlying members and bound to the TNic(s). This keyword
+; allows a component to opt out of the default behavior
+; To prevent binding this protocol to the TNic(s):
+; HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,1 ; Do not bind to TNic
+; To prevent unbinding this protocol from underlying members:
+; HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,2 ; Do not unbind from Members
+; To prevent both binding to TNic and unbinding from members:
+; HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,3 ; Do not bind to TNic or unbind from Members
+HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,0 ; Subscribe to default behavior
+
+[Install.Remove.Services]
+DelService=Ndisprot,0x200
+
+;-------------------------------------------------------------------------
+; Declare Destination Directories for file copy/deletion
+;-------------------------------------------------------------------------
+[SourceDisksNames]
+1=%DiskDescription%,"",,
+
+[SourceDisksFiles]
+ndisprot630.sys=1
+
+
+[DestinationDirs]
+CpyFiles_Sys = 12 ; DIRID_DRIVERS
+
+
+;-------------------------------------------------------------------------
+; Files to Copy/Delete - Referenced by Install and Remove sections above
+;-------------------------------------------------------------------------
+[CpyFiles_Sys]
+Ndisprot630.sys,,,2
+
+[Strings]
+Msft = "Your Company"
+DiskDescription = "Microsoft Ndisprot Sample Protocol Driver Disk"
+NDISPROT_Desc = "Sample NDIS Protocol Driver"
+NDISPROT_HelpText = "A driver to support user-mode I/O on NDIS devices"
+
+
+
+
+
diff --git a/network/ndis/ndisprot/6x/sys/630/ndisprot630.rc b/network/ndis/ndisprot/6x/sys/630/ndisprot630.rc
new file mode 100644
index 00000000..f50de3f9
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/630/ndisprot630.rc
@@ -0,0 +1,49 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ ndisprot.rc
+
+Abstract:
+
+ Internal resource file for driver.
+
+--*/
+
+#include <windows.h>
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_NETWORK
+
+#define VER_FILEDESCRIPTION_STR "NDIS User mode I/O Driver"
+#define VER_INTERNALNAME_STR "NDISPROT630.SYS"
+#define VER_ORIGINALFILENAME_STR "NDISPROT630.SYS"
+#define VER_LANGNEUTRAL
+
+#define VER_FILEVERSION 4,20,00,0000
+#define VER_FILEVERSION_STR "4.20.00.0000"
+
+#undef VER_PRODUCTVERSION
+#define VER_PRODUCTVERSION VER_FILEVERSION
+
+#undef VER_PRODUCTVERSION_STR
+#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
+
+#define VER_LEGALCOPYRIGHT_STR "Copyright (C) 2010 Microsoft Corporation"
+
+#undef VER_COMPANYNAME_STR
+#define VER_COMPANYNAME_STR "Microsoft Corporation"
+
+#undef VER_PRODUCTNAME_STR
+#define VER_PRODUCTNAME_STR "NDIS 6.30 Sample Protocol Driver"
+
+#include "common.ver"
+
diff --git a/network/ndis/ndisprot/6x/sys/630/ndisprot630.vcxproj b/network/ndis/ndisprot/6x/sys/630/ndisprot630.vcxproj
new file mode 100644
index 00000000..5a913947
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/630/ndisprot630.vcxproj
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{DB252AE8-E32C-4E60-B0EB-33A2CB80861C}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{FA9D6F91-6B1C-4EFF-BAEA-E67F4CFE9D3E}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>WDM</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>WDM</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>WDM</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>WDM</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>ndisprot630</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>ndisprot630</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>ndisprot630</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>ndisprot630</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\wdmsec.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\debug.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\ExCallbk.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\ndisbind.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\ntdisp.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\recv.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="..\send.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="precompsrc.c">
+ <AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Create</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ResourceCompile Include="ndisprot630.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/network/ndis/ndisprot/6x/sys/630/ndisprot630.vcxproj.Filters b/network/ndis/ndisprot/6x/sys/630/ndisprot630.vcxproj.Filters
new file mode 100644
index 00000000..bbdb53e8
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/630/ndisprot630.vcxproj.Filters
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{088C6D92-3084-464D-B6CD-B47E67D278B5}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{EDCAD0DA-E747-487E-8458-BAC6BA5E5744}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{9F1E323E-8118-4CAC-8124-DA41F78075BE}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{5EA1AAE7-3C58-475C-84F0-40DCDF8823E9}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\debug.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\ExCallbk.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\ndisbind.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\ntdisp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\recv.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\send.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="precompsrc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ndisprot630.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/network/ndis/ndisprot/6x/sys/630/precompsrc.c b/network/ndis/ndisprot/6x/sys/630/precompsrc.c
new file mode 100644
index 00000000..5944cf51
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/630/precompsrc.c
@@ -0,0 +1 @@
+#include "precomp.h" \ No newline at end of file
diff --git a/network/ndis/ndisprot/6x/sys/debug.c b/network/ndis/ndisprot/6x/sys/debug.c
new file mode 100644
index 00000000..40e90984
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/debug.c
@@ -0,0 +1,425 @@
+/*++
+
+Copyright (c) 1997 Microsoft Corporation
+
+Module Name:
+
+ debug.c
+
+Abstract:
+
+ This module contains all debug-related code.
+
+Revision History:
+
+Notes:
+
+--*/
+
+#include <precomp.h>
+
+#define __FILENUMBER 'GBED'
+
+#if DBG
+
+INT ndisprotDebugLevel=DL_WARN;
+
+NDIS_SPIN_LOCK ndisprotDbgLogLock;
+
+PNPROTD_ALLOCATION ndisprotdMemoryHead = (PNPROTD_ALLOCATION)NULL;
+PNPROTD_ALLOCATION ndisprotdMemoryTail = (PNPROTD_ALLOCATION)NULL;
+ULONG ndisprotdAllocCount = 0; // how many allocated so far (unfreed)
+
+NDIS_SPIN_LOCK ndisprotdMemoryLock;
+BOOLEAN ndisprotdInitDone = FALSE;
+
+
+PVOID
+ndisprotAuditAllocMem(
+ PVOID pPointer,
+ ULONG Size,
+ ULONG FileNumber,
+ ULONG LineNumber
+)
+{
+ PVOID pBuffer;
+ PNPROTD_ALLOCATION pAllocInfo;
+
+ if (!ndisprotdInitDone)
+ {
+ NdisAllocateSpinLock(&(ndisprotdMemoryLock));
+ ndisprotdInitDone = TRUE;
+ }
+
+ NdisAllocateMemoryWithTag(
+ (PVOID *)&pAllocInfo,
+ Size+sizeof(NPROTD_ALLOCATION),
+ (ULONG)'oiuN'
+ );
+
+ if (pAllocInfo == (PNPROTD_ALLOCATION)NULL)
+ {
+ DEBUGP(DL_VERY_LOUD+50,
+ ("ndisprotAuditAllocMem: file %d, line %d, Size %d failed!\n",
+ FileNumber, LineNumber, Size));
+ pBuffer = NULL;
+ }
+ else
+ {
+ pBuffer = (PVOID)&(pAllocInfo->UserData);
+ NPROT_SET_MEM(pBuffer, 0xaf, Size);
+ pAllocInfo->Signature = NPROTD_MEMORY_SIGNATURE;
+ pAllocInfo->FileNumber = FileNumber;
+ pAllocInfo->LineNumber = LineNumber;
+ pAllocInfo->Size = Size;
+ pAllocInfo->Location = (ULONG_PTR)pPointer;
+ pAllocInfo->Next = (PNPROTD_ALLOCATION)NULL;
+
+ NdisAcquireSpinLock(&(ndisprotdMemoryLock));
+
+ pAllocInfo->Prev = ndisprotdMemoryTail;
+ if (ndisprotdMemoryTail == (PNPROTD_ALLOCATION)NULL)
+ {
+ // empty list
+ ndisprotdMemoryHead = ndisprotdMemoryTail = pAllocInfo;
+ }
+ else
+ {
+ ndisprotdMemoryTail->Next = pAllocInfo;
+ }
+ ndisprotdMemoryTail = pAllocInfo;
+
+ ndisprotdAllocCount++;
+ NdisReleaseSpinLock(&(ndisprotdMemoryLock));
+ }
+
+ DEBUGP(DL_VERY_LOUD+100,
+ ("ndisprotAuditAllocMem: file %c%c%c%c, line %d, %d bytes, [0x%p] <- 0x%p\n",
+ (CHAR)(FileNumber & 0xff),
+ (CHAR)((FileNumber >> 8) & 0xff),
+ (CHAR)((FileNumber >> 16) & 0xff),
+ (CHAR)((FileNumber >> 24) & 0xff),
+ LineNumber, Size, pPointer, pBuffer));
+
+ return (pBuffer);
+
+}
+
+
+VOID
+ndisprotAuditFreeMem(
+ PVOID Pointer
+)
+{
+ PNPROTD_ALLOCATION pAllocInfo;
+
+ NdisAcquireSpinLock(&(ndisprotdMemoryLock));
+
+ pAllocInfo = CONTAINING_RECORD(Pointer, NPROTD_ALLOCATION, UserData);
+
+ if (pAllocInfo->Signature != NPROTD_MEMORY_SIGNATURE)
+ {
+ DEBUGP(DL_ERROR,
+ ("ndisprotAuditFreeMem: unknown buffer 0x%p!\n", Pointer));
+ NdisReleaseSpinLock(&(ndisprotdMemoryLock));
+#if DBG
+ DbgBreakPoint();
+#endif
+ return;
+ }
+
+ pAllocInfo->Signature = (ULONG)'DEAD';
+ if (pAllocInfo->Prev != (PNPROTD_ALLOCATION)NULL)
+ {
+ pAllocInfo->Prev->Next = pAllocInfo->Next;
+ }
+ else
+ {
+ ndisprotdMemoryHead = pAllocInfo->Next;
+ }
+ if (pAllocInfo->Next != (PNPROTD_ALLOCATION)NULL)
+ {
+ pAllocInfo->Next->Prev = pAllocInfo->Prev;
+ }
+ else
+ {
+ ndisprotdMemoryTail = pAllocInfo->Prev;
+ }
+ ndisprotdAllocCount--;
+ NdisReleaseSpinLock(&(ndisprotdMemoryLock));
+
+ NdisFreeMemory(pAllocInfo, 0, 0);
+}
+
+
+VOID
+ndisprotAuditShutdown(
+ VOID
+)
+{
+ if (ndisprotdInitDone)
+ {
+ if (ndisprotdAllocCount != 0)
+ {
+ DEBUGP(DL_ERROR, ("AuditShutdown: unfreed memory, %d blocks!\n",
+ ndisprotdAllocCount));
+ DEBUGP(DL_ERROR, ("MemoryHead: 0x%p, MemoryTail: 0x%p\n",
+ ndisprotdMemoryHead, ndisprotdMemoryTail));
+ DbgBreakPoint();
+ {
+ PNPROTD_ALLOCATION pAllocInfo;
+
+ while (ndisprotdMemoryHead != (PNPROTD_ALLOCATION)NULL)
+ {
+ pAllocInfo = ndisprotdMemoryHead;
+ DEBUGP(DL_INFO, ("AuditShutdown: will free 0x%p\n", pAllocInfo));
+ ndisprotAuditFreeMem(&(pAllocInfo->UserData));
+ }
+ }
+ }
+ ndisprotdInitDone = FALSE;
+ }
+}
+
+#define MAX_HD_LENGTH 128
+
+VOID
+DbgPrintHexDump(
+ IN PUCHAR pBuffer,
+ IN ULONG Length
+)
+/*++
+
+Routine Description:
+
+ Print a hex dump of the given contiguous buffer. If the length
+ is too long, we truncate it.
+
+Arguments:
+
+ pBuffer - Points to start of data to be dumped
+ Length - Length of above.
+
+Return Value:
+
+ None
+
+--*/
+{
+ ULONG i;
+
+ if (Length > MAX_HD_LENGTH)
+ {
+ Length = MAX_HD_LENGTH;
+ }
+
+ for (i = 0; i < Length; i++)
+ {
+ //
+ // Check if we are at the end of a line
+ //
+ if ((i > 0) && ((i & 0xf) == 0))
+ {
+ DbgPrint("\n");
+ }
+
+ //
+ // Print addr if we are at start of a new line
+ //
+ if ((i & 0xf) == 0)
+ {
+ DbgPrint("%08p ", pBuffer);
+ }
+
+ DbgPrint(" %02x", *pBuffer++);
+ }
+
+ //
+ // Terminate the last line.
+ //
+ if (Length > 0)
+ {
+ DbgPrint("\n");
+ }
+}
+#endif // DBG
+
+
+#if DBG_SPIN_LOCK
+ULONG ndisprotdSpinLockInitDone = 0;
+NDIS_SPIN_LOCK ndisprotdLockLock;
+
+VOID
+ndisprotAllocateSpinLock(
+ IN PNPROT_LOCK pLock,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+)
+{
+ if (ndisprotdSpinLockInitDone == 0)
+ {
+ ndisprotdSpinLockInitDone = 1;
+ NdisAllocateSpinLock(&(ndisprotdLockLock));
+ }
+
+ NdisAcquireSpinLock(&(ndisprotdLockLock));
+ pLock->Signature = NPROTL_SIG;
+ pLock->TouchedByFileNumber = FileNumber;
+ pLock->TouchedInLineNumber = LineNumber;
+ pLock->IsAcquired = 0;
+ pLock->OwnerThread = 0;
+ NdisAllocateSpinLock(&(pLock->NdisLock));
+ NdisReleaseSpinLock(&(ndisprotdLockLock));
+}
+
+VOID
+ndisprotFreeSpinLock(
+ IN PNPROT_LOCK pLock,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+)
+{
+
+ NdisAcquireSpinLock(&(ndisprotdLockLock));
+ pLock->Signature = NUIOL_SIG;
+ pLock->TouchedByFileNumber = FileNumber;
+ pLock->TouchedInLineNumber = LineNumber;
+ pLock->IsAcquired = 0;
+ pLock->OwnerThread = 0;
+ NdisFreeSpinLock(&(pLock->NdisLock));
+ NdisReleaseSpinLock(&(ndisprotdLockLock));
+}
+
+VOID
+ndisprotFreeDbgLock(
+ VOID
+ )
+{
+
+ ASSERT(ndisprotdSpinLockInitDone == 1);
+
+ ndisprotdSpinLockInitDone = 0;
+ NdisFreeSpinLock(&(ndisprotdLockLock));
+}
+
+VOID
+ndisprotAcquireSpinLock(
+ IN PNPROT_LOCK pLock,
+ IN BOOLEAN DispatchLevel,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+)
+{
+ PKTHREAD pThread;
+
+ pThread = KeGetCurrentThread();
+ if (DispatchLevel == TRUE)
+ {
+ NdisDprAcquireSpinLock(&(ndisprotdLockLock));
+ }
+ else
+ {
+ NdisAcquireSpinLock(&(ndisprotdLockLock));
+ }
+ if (pLock->Signature != NPROTL_SIG)
+ {
+ DbgPrint("Trying to acquire uninited lock 0x%x, File %c%c%c%c, Line %d\n",
+ pLock,
+ (CHAR)(FileNumber & 0xff),
+ (CHAR)((FileNumber >> 8) & 0xff),
+ (CHAR)((FileNumber >> 16) & 0xff),
+ (CHAR)((FileNumber >> 24) & 0xff),
+ LineNumber);
+ DbgBreakPoint();
+ }
+
+ if (pLock->IsAcquired != 0)
+ {
+ if (pLock->OwnerThread == pThread)
+ {
+ DbgPrint("Detected multiple locking!: pLock 0x%x, File %c%c%c%c, Line %d\n",
+ pLock,
+ (CHAR)(FileNumber & 0xff),
+ (CHAR)((FileNumber >> 8) & 0xff),
+ (CHAR)((FileNumber >> 16) & 0xff),
+ (CHAR)((FileNumber >> 24) & 0xff),
+ LineNumber);
+ DbgPrint("pLock 0x%x already acquired in File %c%c%c%c, Line %d\n",
+ pLock,
+ (CHAR)(pLock->TouchedByFileNumber & 0xff),
+ (CHAR)((pLock->TouchedByFileNumber >> 8) & 0xff),
+ (CHAR)((pLock->TouchedByFileNumber >> 16) & 0xff),
+ (CHAR)((pLock->TouchedByFileNumber >> 24) & 0xff),
+ pLock->TouchedInLineNumber);
+ DbgBreakPoint();
+ }
+ }
+
+ pLock->IsAcquired++;
+ if (DispatchLevel == TRUE)
+ {
+ NdisDprReleaseSpinLock(&(ndisprotdLockLock));
+ NdisDprAcquireSpinLock(&(pLock->NdisLock));
+ }
+ else
+ {
+ NdisReleaseSpinLock(&(ndisprotdLockLock));
+ NdisAcquireSpinLock(&(pLock->NdisLock));
+ }
+
+ //
+ // Mark this lock.
+ //
+ pLock->OwnerThread = pThread;
+ pLock->TouchedByFileNumber = FileNumber;
+ pLock->TouchedInLineNumber = LineNumber;
+}
+
+
+VOID
+ndisprotReleaseSpinLock(
+ IN PNPROT_LOCK pLock,
+ IN BOOLEAN DispatchLevel,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+)
+{
+ NdisDprAcquireSpinLock(&(ndisprotdLockLock));
+ if (pLock->Signature != NPROTL_SIG)
+ {
+ DbgPrint("Trying to release uninited lock 0x%x, File %c%c%c%c, Line %d\n",
+ pLock,
+ (CHAR)(FileNumber & 0xff),
+ (CHAR)((FileNumber >> 8) & 0xff),
+ (CHAR)((FileNumber >> 16) & 0xff),
+ (CHAR)((FileNumber >> 24) & 0xff),
+ LineNumber);
+ DbgBreakPoint();
+ }
+
+ if (pLock->IsAcquired == 0)
+ {
+ DbgPrint("Detected release of unacquired lock 0x%x, File %c%c%c%c, Line %d\n",
+ pLock,
+ (CHAR)(FileNumber & 0xff),
+ (CHAR)((FileNumber >> 8) & 0xff),
+ (CHAR)((FileNumber >> 16) & 0xff),
+ (CHAR)((FileNumber >> 24) & 0xff),
+ LineNumber);
+ DbgBreakPoint();
+ }
+ pLock->TouchedByFileNumber = FileNumber;
+ pLock->TouchedInLineNumber = LineNumber;
+ pLock->IsAcquired--;
+ pLock->OwnerThread = 0;
+ NdisDprReleaseSpinLock(&(ndisprotdLockLock));
+ if (DispatchLevel == TRUE)
+ {
+ NdisDprReleaseSpinLock(&(pLock->NdisLock));
+ }
+ else
+ {
+ NdisReleaseSpinLock(&(pLock->NdisLock));
+ }
+}
+#endif // DBG_SPIN_LOCK
diff --git a/network/ndis/ndisprot/6x/sys/debug.h b/network/ndis/ndisprot/6x/sys/debug.h
new file mode 100644
index 00000000..64de3453
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/debug.h
@@ -0,0 +1,220 @@
+/*++
+
+Copyright (c) 2000 Microsoft Corporation
+
+Module Name:
+
+ debug.h
+
+Abstract:
+
+ Debug macros for NDISPROT
+
+Revision History:
+
+Notes:
+
+--*/
+
+#ifndef _NPROTDEBUG__H
+#define _NPROTDEBUG__H
+
+//
+// Message verbosity: lower values indicate higher urgency
+//
+#define DL_EXTRA_LOUD 20
+#define DL_VERY_LOUD 10
+#define DL_LOUD 8
+#define DL_INFO 6
+#define DL_WARN 4
+#define DL_ERROR 2
+#define DL_FATAL 0
+
+#if DBG_SPIN_LOCK
+
+typedef struct _NPROT_LOCK
+{
+ ULONG Signature;
+ ULONG IsAcquired;
+ PKTHREAD OwnerThread;
+ ULONG TouchedByFileNumber;
+ ULONG TouchedInLineNumber;
+ NDIS_SPIN_LOCK NdisLock;
+} NPROT_LOCK, *PNPROT_LOCK;
+
+#define NPROTL_SIG 'KCOL'
+
+extern NDIS_SPIN_LOCK ndisprotDbgLogLock;
+
+extern
+VOID
+ndisprotAllocateSpinLock(
+ IN PNPROT_LOCK pLock,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+);
+
+extern
+VOID
+ndisprotFreeSpinLock(
+ IN PNPROT_LOCK pLock,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+);
+
+extern
+VOID
+ndisprotAcquireSpinLock(
+ IN PNPROT_LOCK pLock,
+ IN BOOLEAN DispatchLevel,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+);
+
+extern
+VOID
+ndisprotReleaseSpinLock(
+ IN PNPROT_LOCK pLock,
+ IN BOOLEAN DispatchLevel,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+);
+
+extern
+VOID
+ndisprotFreeDbgLock(
+ VOID
+);
+
+#define CHECK_LOCK_COUNT(Count) \
+ { \
+ if ((INT)(Count) < 0) \
+ { \
+ DbgPrint("Lock Count %d is < 0! File %s, Line %d\n",\
+ Count, __FILE__, __LINE__); \
+ DbgBreakPoint(); \
+ } \
+ }
+#else
+
+#define CHECK_LOCK_COUNT(Count)
+
+typedef NDIS_SPIN_LOCK NPROT_LOCK;
+typedef PNDIS_SPIN_LOCK PNPROT_LOCK;
+
+#endif // DBG_SPIN_LOCK
+
+#if DBG
+
+extern INT ndisprotDebugLevel;
+
+
+#define DEBUGP(lev, stmt) \
+ { \
+ if ((lev) <= ndisprotDebugLevel) \
+ { \
+ DbgPrint("Ndisprot: "); DbgPrint stmt; \
+ } \
+ }
+
+#define DEBUGPDUMP(lev, pBuf, Len) \
+ { \
+ if ((lev) <= ndisprotDebugLevel) \
+ { \
+ DbgPrintHexDump((PUCHAR)(pBuf), (ULONG)(Len)); \
+ } \
+ }
+
+#define NPROT_ASSERT(exp) \
+ { \
+ if (!(exp)) \
+ { \
+ DbgPrint("Ndisprot: assert " #exp " failed in" \
+ " file %s, line %d\n", __FILE__, __LINE__); \
+ DbgBreakPoint(); \
+ } \
+ }
+
+#define NPROT_SET_SIGNATURE(s, t)\
+ (s)->t##_sig = t##_signature;
+
+#define NPROT_STRUCT_ASSERT(s, t) \
+ if ((s)->t##_sig != t##_signature) \
+ { \
+ DbgPrint("ndisprot: assertion failure" \
+ " for type " #t " at 0x%p in file %s, line %d\n", \
+ s, __FILE__, __LINE__); \
+ DbgBreakPoint(); \
+ }
+
+
+//
+// Memory Allocation/Freeing Audit:
+//
+
+//
+// The NPROTD_ALLOCATION structure stores all info about one allocation
+//
+typedef struct _NPROTD_ALLOCATION {
+
+ ULONG Signature;
+ struct _NPROTD_ALLOCATION *Next;
+ struct _NPROTD_ALLOCATION *Prev;
+ ULONG FileNumber;
+ ULONG LineNumber;
+ ULONG Size;
+ ULONG_PTR Location; // where the returned ptr was stored
+ union
+ {
+ ULONGLONG Alignment;
+ UCHAR UserData;
+ };
+
+} NPROTD_ALLOCATION, *PNPROTD_ALLOCATION;
+
+#define NPROTD_MEMORY_SIGNATURE (ULONG)'CSII'
+
+extern
+PVOID
+ndisprotAuditAllocMem (
+ PVOID pPointer,
+ ULONG Size,
+ ULONG FileNumber,
+ ULONG LineNumber
+);
+
+extern
+VOID
+ndisprotAuditFreeMem(
+ PVOID Pointer
+);
+
+extern
+VOID
+ndisprotAuditShutdown(
+ VOID
+);
+
+extern
+VOID
+DbgPrintHexDump(
+ PUCHAR pBuffer,
+ ULONG Length
+);
+
+#else
+
+//
+// No debug
+//
+#define DEBUGP(lev, stmt)
+#define DEBUGPDUMP(lev, pBuf, Len)
+
+#define NPROT_ASSERT(exp)
+#define NPROT_SET_SIGNATURE(s, t) UNREFERENCED_PARAMETER(s)
+#define NPROT_STRUCT_ASSERT(s, t) UNREFERENCED_PARAMETER(s)
+
+#endif // DBG
+
+
+#endif // _NPROTDEBUG__H
diff --git a/network/ndis/ndisprot/6x/sys/excallbk.c b/network/ndis/ndisprot/6x/sys/excallbk.c
new file mode 100644
index 00000000..baa2298c
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/excallbk.c
@@ -0,0 +1,195 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ ExCallbk.c
+
+Abstract: The routines in this module helps to solve driver load order
+ dependency between this sample and NDISWDM sample. These
+ routines are not required in a typical protocol driver. By default
+ this module is not included in the sample. You include these routines
+ by adding EX_CALLBACK defines to the 'sources' file. Read the
+ NDISWDM samples readme file for more information on how ExCallback
+ kernel interfaces are used to solve driver load order issue.
+
+
+Environment:
+
+ Kernel mode
+
+
+Revision History:
+
+--*/
+
+#include "precomp.h"
+
+#ifdef EX_CALLBACK
+
+#define __FILENUMBER 'LCxE'
+
+#define NDISPROT_CALLBACK_NAME L"\\Callback\\NdisProtCallbackObject"
+
+#define CALLBACK_SOURCE_NDISPROT 0
+#define CALLBACK_SOURCE_NDISWDM 1
+
+PCALLBACK_OBJECT CallbackObject = NULL;
+PVOID CallbackRegisterationHandle = NULL;
+
+typedef VOID (* NOTIFY_PRESENCE_CALLBACK)(OUT PVOID Source);
+
+#ifdef ALLOC_PRAGMA
+
+#pragma alloc_text(PAGE, ndisprotRegisterExCallBack)
+#pragma alloc_text(PAGE, ndisprotUnregisterExCallBack)
+
+#endif // ALLOC_PRAGMA
+
+BOOLEAN
+ndisprotRegisterExCallBack()
+{
+ OBJECT_ATTRIBUTES ObjectAttr;
+ UNICODE_STRING CallBackObjectName;
+ NTSTATUS Status;
+ BOOLEAN bResult = TRUE;
+
+ DEBUGP(DL_LOUD, ("--> ndisprotRegisterExCallBack\n"));
+
+ PAGED_CODE();
+
+ do {
+
+ RtlInitUnicodeString(&CallBackObjectName, NDISPROT_CALLBACK_NAME);
+
+ InitializeObjectAttributes(&ObjectAttr,
+ &CallBackObjectName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+ NULL,
+ NULL);
+
+ Status = ExCreateCallback(&CallbackObject,
+ &ObjectAttr,
+ TRUE,
+ TRUE);
+
+
+ if (!NT_SUCCESS(Status))
+ {
+
+ DEBUGP(DL_ERROR, ("RegisterExCallBack: failed to create callback %lx\n", Status));
+ bResult = FALSE;
+ break;
+ }
+
+ CallbackRegisterationHandle = ExRegisterCallback(CallbackObject,
+ ndisprotCallback,
+ (PVOID)NULL);
+ if (CallbackRegisterationHandle == NULL)
+ {
+ DEBUGP(DL_ERROR,("RegisterExCallBack: failed to register a Callback routine%lx\n", Status));
+ bResult = FALSE;
+ break;
+ }
+
+ ExNotifyCallback(CallbackObject,
+ (PVOID)CALLBACK_SOURCE_NDISPROT,
+ (PVOID)NULL);
+
+
+ }while(FALSE);
+
+ if(!bResult) {
+ if (CallbackRegisterationHandle)
+ {
+ ExUnregisterCallback(CallbackRegisterationHandle);
+ CallbackRegisterationHandle = NULL;
+ }
+
+ if (CallbackObject)
+ {
+ ObDereferenceObject(CallbackObject);
+ CallbackObject = NULL;
+ }
+ }
+
+ DEBUGP(DL_LOUD, ("<-- ndisprotRegisterExCallBack\n"));
+
+ return bResult;
+
+}
+
+VOID
+ndisprotUnregisterExCallBack()
+{
+ DEBUGP(DL_LOUD, ("--> ndisprotUnregisterExCallBack\n"));
+
+ PAGED_CODE();
+
+ if (CallbackRegisterationHandle)
+ {
+ ExUnregisterCallback(CallbackRegisterationHandle);
+ CallbackRegisterationHandle = NULL;
+ }
+
+ if (CallbackObject)
+ {
+ ObDereferenceObject(CallbackObject);
+ CallbackObject = NULL;
+ }
+
+ DEBUGP(DL_LOUD, ("<-- ndisprotUnregisterExCallBack\n"));
+
+}
+
+VOID
+ndisprotCallback(
+ PVOID CallBackContext,
+ PVOID Source,
+ PVOID CallbackAddr
+ )
+{
+ NOTIFY_PRESENCE_CALLBACK func;
+
+ DEBUGP(DL_LOUD, ("==>ndisprotoCallback: Source %lx, CallbackAddr %p\n",
+ Source, CallbackAddr));
+
+ //
+ // if we are the one issuing this notification, just return
+ //
+ if (Source == CALLBACK_SOURCE_NDISPROT) {
+ return;
+ }
+
+ //
+ // Notification is coming from NDISWDM
+ // let it know that you are here
+ //
+ ASSERT(Source == (PVOID)CALLBACK_SOURCE_NDISWDM);
+
+ if(Source == (PVOID)CALLBACK_SOURCE_NDISWDM) {
+
+ ASSERT(CallbackAddr);
+
+ if (CallbackAddr == NULL)
+ {
+ DEBUGP(DL_ERROR, ("Callback called with invalid address %p\n", CallbackAddr));
+ return;
+ }
+
+ func = CallbackAddr;
+
+ func(CALLBACK_SOURCE_NDISPROT);
+ }
+
+ DEBUGP(DL_LOUD, ("<==ndisprotoCallback: Source, %lx\n", Source));
+
+}
+
+#endif
diff --git a/network/ndis/ndisprot/6x/sys/macros.h b/network/ndis/ndisprot/6x/sys/macros.h
new file mode 100644
index 00000000..d750129c
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/macros.h
@@ -0,0 +1,234 @@
+/*++
+
+Copyright (c) 2000 Microsoft Corporation
+
+Module Name:
+
+ macros.h
+
+Abstract:
+
+ Some macros for NDISPROT.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+
+#ifndef MIN
+#define MIN(_a, _b) ((_a) < (_b)? (_a): (_b))
+#endif
+
+#if DBG
+#define NPROT_REF_OPEN(_pOpen) ndisprotDbgRefOpen(_pOpen, __FILENUMBER, __LINE__)
+#define NPROT_DEREF_OPEN(_pOpen) ndisprotDbgDerefOpen(_pOpen, __FILENUMBER, __LINE__)
+#else
+#define NPROT_REF_OPEN(_pOpen) ndisprotRefOpen(_pOpen)
+#define NPROT_DEREF_OPEN(_pOpen) ndisprotDerefOpen(_pOpen)
+#endif
+
+
+//
+// Spinlock macros
+//
+#if DBG_SPIN_LOCK
+
+#define NPROT_INIT_LOCK(_pLock) \
+ ndisprotAllocateSpinLock(_pLock, __FILENUMBER, __LINE__)
+
+#define NPROT_ACQUIRE_LOCK(_pLock, DispatchLevel) \
+ ndisprotAcquireSpinLock(_pLock, DispatchLevel,__FILENUMBER, __LINE__)
+
+#define NPROT_RELEASE_LOCK(_pLock,DispatchLevel) \
+ ndisprotReleaseSpinLock(_pLock, DispatchLevel,__FILENUMBER, __LINE__)
+
+#define NPROT_FREE_LOCK(_pLock) \
+ ndisprotFreeSpinLock(_pLock, __FILENUMBER, __LINE__)
+
+#define NPROT_FREE_DBG_LOCK() \
+ ndisprotFreeDbgLock()
+#else
+
+#define NPROT_INIT_LOCK(_pLock) NdisAllocateSpinLock(_pLock)
+#define NPROT_ACQUIRE_LOCK(_pLock, DispatchLevel) \
+ { \
+ if (DispatchLevel == TRUE) \
+ { \
+ NdisDprAcquireSpinLock(_pLock); \
+ } \
+ else \
+ { \
+ NdisAcquireSpinLock(_pLock); \
+ } \
+ }
+#define NPROT_RELEASE_LOCK(_pLock, DispatchLevel) \
+ { \
+ if (DispatchLevel == TRUE) \
+ { \
+ NdisDprReleaseSpinLock(_pLock); \
+ } \
+ else \
+ { \
+ NdisReleaseSpinLock(_pLock); \
+ } \
+ }
+
+#define NPROT_FREE_LOCK(_pLock) NdisFreeSpinLock(_pLock)
+
+#define NPROT_FREE_DBG_LOCK()
+
+#endif // DBG
+
+//
+// List manipulation.
+//
+#define NPROT_INIT_LIST_HEAD(_pList) InitializeListHead(_pList)
+#define NPROT_IS_LIST_EMPTY(_pList) IsListEmpty(_pList)
+#define NPROT_INSERT_HEAD_LIST(_pList, _pEnt) InsertHeadList(_pList, _pEnt)
+#define NPROT_INSERT_TAIL_LIST(_pList, _pEnt) InsertTailList(_pList, _pEnt)
+#define NPROT_REMOVE_ENTRY_LIST(_pEnt) RemoveEntryList(_pEnt)
+#define NPROT_REMOVE_HEAD_LIST(_pList) RemoveHeadList(_pList)
+
+
+
+#define NPROT_RCV_NBL_TO_LIST_ENTRY(_pNbl) \
+ (&((PNPROT_RECV_NBL_RSVD)(NET_BUFFER_LIST_PROTOCOL_RESERVED(_pNbl)))->Link)
+
+#define NPROT_RCV_NBL_FROM_LIST_ENTRY(_pEnt) \
+ (((PNPROT_RECV_NBL_RSVD)(CONTAINING_RECORD(_pEnt, NPROT_RECV_NBL_RSVD, Link)))->pNetBufferList)
+
+
+//
+// Send net buffer list context
+//
+#define NPROT_IRP_FROM_SEND_NBL(_pNbl) \
+ (((PNPROT_SEND_NETBUFLIST_RSVD)((_pNbl)->Context->ContextData + (_pNbl)->Context->Offset))->pIrp)
+
+#define NPROT_SEND_NBL_RSVD(_pNbl) \
+ ((PNPROT_SEND_NETBUFLIST_RSVD)((_pNbl)->Context->ContextData + (_pNbl)->Context->Offset))
+
+
+#define NPROT_REF_SEND_NBL(_pNbl) \
+ (VOID)NdisInterlockedIncrement((PLONG)&NPROT_SEND_NBL_RSVD(_pNbl)->RefCount)
+
+
+#define NPROT_DEREF_SEND_NBL(_pNbl, DispatchLevel) \
+ { \
+ if (NdisInterlockedDecrement((PLONG)&NPROT_SEND_NBL_RSVD(_pNbl)->RefCount) == 0) \
+ { \
+ NdisFreeNetBufferList(_pNbl); \
+ } \
+ }
+
+//
+// Cancel IDs are generated by using the partial cancel ID we got from
+// NDIS ORed with a monotonically increasing locally generated ID.
+//
+#define NPROT_CANCEL_ID_LOW_MASK (((ULONG_PTR)-1) >> 8)
+
+#define NPROT_GET_NEXT_CANCEL_ID() \
+ (PVOID)(Globals.PartialCancelId | \
+ ((NdisInterlockedIncrement((PLONG)&Globals.LocalCancelId)) & NPROT_CANCEL_ID_LOW_MASK))
+
+
+//
+// Memory allocation
+//
+#if DBG
+#define NPROT_ALLOC_MEM(_pVar, _Size) \
+ (_pVar) = ndisprotAuditAllocMem( \
+ (PVOID)&(_pVar), \
+ _Size, \
+ __FILENUMBER, \
+ __LINE__);
+
+#define NPROT_FREE_MEM(_pMem) \
+ ndisprotAuditFreeMem(_pMem);
+
+#else
+
+#define NPROT_ALLOC_MEM(_pVar, _Size) \
+ NdisAllocateMemoryWithTag((PVOID *)(&_pVar), (_Size), NPROT_ALLOC_TAG)
+
+#define NPROT_FREE_MEM(_pMem) \
+ NdisFreeMemory(_pMem, 0, 0)
+
+#endif // DBG
+
+
+#define NPROT_ZERO_MEM(_pMem, _ByteCount) \
+ NdisZeroMemory(_pMem, _ByteCount)
+
+#define NPROT_COPY_MEM(_pDst, _pSrc, _ByteCount) \
+ NdisMoveMemory(_pDst, _pSrc, _ByteCount)
+
+#define NPROT_MEM_CMP(_p1, _p2, _ByteCount) \
+ NdisEqualMemory(_p1, _p2, _ByteCount)
+
+#define NPROT_SET_MEM(_pMem, _ByteVal, _ByteCount) \
+ NdisFillMemory(_pMem, _ByteCount, _ByteVal)
+
+//
+// Events.
+//
+#define NPROT_INIT_EVENT(_pEvent) NdisInitializeEvent(_pEvent)
+#define NPROT_SIGNAL_EVENT(_pEvent) NdisSetEvent(_pEvent)
+#define NPROT_WAIT_EVENT(_pEvent, _MsToWait) NdisWaitEvent(_pEvent, _MsToWait)
+
+
+//
+// Flags
+//
+#define NPROT_SET_FLAGS(_FlagsVar, _Mask, _BitsToSet) \
+ (_FlagsVar) = ((_FlagsVar) & ~(_Mask)) | (_BitsToSet)
+
+#define NPROT_TEST_FLAGS(_FlagsVar, _Mask, _BitsToCheck) \
+ (((_FlagsVar) & (_Mask)) == (_BitsToCheck))
+
+
+#define NDIS_STATUS_TO_NT_STATUS(_NdisStatus, _pNtStatus) \
+{ \
+ /* \
+ * The following NDIS status codes map directly to NT status codes. \
+ */ \
+ if (((NDIS_STATUS_SUCCESS == (_NdisStatus)) || \
+ (NDIS_STATUS_PENDING == (_NdisStatus)) || \
+ (NDIS_STATUS_BUFFER_OVERFLOW == (_NdisStatus)) || \
+ (NDIS_STATUS_FAILURE == (_NdisStatus)) || \
+ (NDIS_STATUS_RESOURCES == (_NdisStatus)) || \
+ (NDIS_STATUS_NOT_SUPPORTED == (_NdisStatus)))) \
+ { \
+ *(_pNtStatus) = (NTSTATUS)(_NdisStatus); \
+ } \
+ else if (NDIS_STATUS_BUFFER_TOO_SHORT == (_NdisStatus)) \
+ { \
+ /* \
+ * The above NDIS status codes require a little special casing. \
+ */ \
+ *(_pNtStatus) = STATUS_BUFFER_TOO_SMALL; \
+ } \
+ else if (NDIS_STATUS_INVALID_LENGTH == (_NdisStatus)) \
+ { \
+ *(_pNtStatus) = STATUS_INVALID_BUFFER_SIZE; \
+ } \
+ else if (NDIS_STATUS_INVALID_DATA == (_NdisStatus)) \
+ { \
+ *(_pNtStatus) = STATUS_INVALID_PARAMETER; \
+ } \
+ else if (NDIS_STATUS_ADAPTER_NOT_FOUND == (_NdisStatus)) \
+ { \
+ *(_pNtStatus) = STATUS_NO_MORE_ENTRIES; \
+ } \
+ else if (NDIS_STATUS_ADAPTER_NOT_READY == (_NdisStatus)) \
+ { \
+ *(_pNtStatus) = STATUS_DEVICE_NOT_READY; \
+ } \
+ else \
+ { \
+ *(_pNtStatus) = STATUS_UNSUCCESSFUL; \
+ } \
+}
diff --git a/network/ndis/ndisprot/6x/sys/ndisbind.c b/network/ndis/ndisprot/6x/sys/ndisbind.c
new file mode 100644
index 00000000..5257d3a2
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/ndisbind.c
@@ -0,0 +1,2061 @@
+/*++
+
+Copyright (c) 2000 Microsoft Corporation
+
+Module Name:
+
+ ndisbind.c
+
+Abstract:
+
+ NDIS protocol entry points and utility routines to handle binding
+ and unbinding from adapters.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+
+#include "precomp.h"
+
+#define __FILENUMBER 'DNIB'
+
+NDIS_OID ndisprotSupportedSetOids[] =
+{
+ OID_802_11_INFRASTRUCTURE_MODE,
+ OID_802_11_AUTHENTICATION_MODE,
+ OID_802_11_RELOAD_DEFAULTS,
+ OID_802_11_REMOVE_WEP,
+ OID_802_11_WEP_STATUS,
+ OID_802_11_BSSID_LIST_SCAN,
+ OID_802_11_ADD_WEP,
+ OID_802_11_SSID,
+ OID_802_11_BSSID,
+ OID_802_11_BSSID_LIST,
+ OID_802_11_DISASSOCIATE,
+ OID_802_11_STATISTICS, // Later used by power management
+ OID_802_11_POWER_MODE, // Later used by power management
+ OID_802_11_NETWORK_TYPE_IN_USE,
+ OID_802_11_RSSI,
+ OID_802_11_SUPPORTED_RATES,
+ OID_802_11_CONFIGURATION,
+ OID_802_3_MULTICAST_LIST,
+};
+
+NDIS_STATUS
+NdisprotBindAdapter(
+ IN NDIS_HANDLE ProtocolDriverContext,
+ IN NDIS_HANDLE BindContext,
+ IN PNDIS_BIND_PARAMETERS BindParameters
+ )
+/*++
+
+Routine Description:
+
+ Protocol Bind Handler entry point called when NDIS wants us
+ to bind to an adapter. We go ahead and set up a binding.
+ An OPEN_CONTEXT structure is allocated to keep state about
+ this binding.
+
+Arguments:
+
+
+Return Value:
+
+ None
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ NDIS_STATUS Status;
+
+ UNREFERENCED_PARAMETER(ProtocolDriverContext);
+
+ do
+ {
+ //
+ // Allocate our context for this open.
+ //
+ NPROT_ALLOC_MEM(pOpenContext, sizeof(NDISPROT_OPEN_CONTEXT));
+ if (pOpenContext == NULL)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ break;
+ }
+
+ //
+ // Initialize it.
+ //
+ NPROT_ZERO_MEM(pOpenContext, sizeof(NDISPROT_OPEN_CONTEXT));
+ NPROT_SET_SIGNATURE(pOpenContext, oc);
+
+ NPROT_INIT_LOCK(&pOpenContext->Lock);
+ NPROT_INIT_LIST_HEAD(&pOpenContext->PendedReads);
+ NPROT_INIT_LIST_HEAD(&pOpenContext->PendedWrites);
+ NPROT_INIT_LIST_HEAD(&pOpenContext->RecvNetBufListQueue);
+ NPROT_INIT_EVENT(&pOpenContext->PoweredUpEvent);
+
+
+ //
+ // Start off by assuming that the device below is powered up.
+ //
+ NPROT_SIGNAL_EVENT(&pOpenContext->PoweredUpEvent);
+
+ NPROT_REF_OPEN(pOpenContext); // Bind
+
+ //
+ // Add it to the global list.
+ //
+ NPROT_ACQUIRE_LOCK(&Globals.GlobalLock, FALSE);
+
+ NPROT_INSERT_TAIL_LIST(&Globals.OpenList,
+ &pOpenContext->Link);
+
+ NPROT_RELEASE_LOCK(&Globals.GlobalLock, FALSE);
+
+ pOpenContext->State = NdisprotInitializing;
+
+ //
+ // Here we reference the open context to make sure that even if
+ // ndisprotCreateBinding failed, open context is still valid
+ //
+ NPROT_REF_OPEN(pOpenContext);
+ //
+ // Set up the NDIS binding, ndisprotCreateBinding does the cleanup for the
+ // binding if somehow it fails to create the binding, the
+ //
+ Status = ndisprotCreateBinding(
+ pOpenContext,
+ BindParameters,
+ BindContext,
+ (PUCHAR)BindParameters->AdapterName->Buffer,
+ BindParameters->AdapterName->Length);
+
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ //
+ // Dereference the open context because we referenced it before we call
+ // ndisprotCreateBinding
+ //
+ NPROT_DEREF_OPEN(pOpenContext);
+ break;
+ }
+ //
+ // Dereference the open context because we referenced it before we call
+ // ndisprotCreateBinding
+ //
+ NPROT_DEREF_OPEN(pOpenContext);
+ }
+ while (FALSE);
+
+ return Status;
+
+}
+
+VOID
+NdisprotOpenAdapterComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN NDIS_STATUS Status
+ )
+/*++
+
+Routine Description:
+
+ Completion routine called by NDIS if our call to NdisOpenAdapterEx
+ pends. Wake up the thread that called NdisOpenAdapterEx.
+
+Arguments:
+
+ ProtocolBindingContext - pointer to open context structure
+ Status - status of the open
+
+Return Value:
+
+ None
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ pOpenContext->BindStatus = Status;
+
+ NPROT_SIGNAL_EVENT(&pOpenContext->BindEvent);
+}
+
+
+NDIS_STATUS
+NdisprotUnbindAdapter(
+ IN NDIS_HANDLE UnbindContext,
+ IN NDIS_HANDLE ProtocolBindingContext
+ )
+/*++
+
+Routine Description:
+
+ NDIS calls this when it wants us to close the binding to an adapter.
+
+Arguments:
+
+ ProtocolBindingContext - pointer to open context structure
+ UnbindContext - to use in NdisCompleteUnbindAdapter if we return pending
+
+Return Value:
+
+ pending or success
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+
+ UNREFERENCED_PARAMETER(UnbindContext);
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ //
+ // Mark this open as having seen an Unbind.
+ //
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_UNBIND_FLAGS, NPROTO_UNBIND_RECEIVED);
+
+ //
+ // In case we had threads blocked for the device below to be powered
+ // up, wake them up.
+ //
+ NPROT_SIGNAL_EVENT(&pOpenContext->PoweredUpEvent);
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ pOpenContext->State = NdisprotClosing;
+
+ ndisprotShutdownBinding(pOpenContext);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+
+VOID
+NdisprotCloseAdapterComplete(
+ IN NDIS_HANDLE ProtocolBindingContext
+ )
+/*++
+
+Routine Description:
+
+ Called by NDIS to complete a pended call to NdisCloseAdapter.
+ We wake up the thread waiting for this completion.
+
+Arguments:
+
+ ProtocolBindingContext - pointer to open context structure
+
+Return Value:
+
+ None
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ NPROT_SIGNAL_EVENT(&pOpenContext->BindEvent);
+}
+
+NDIS_STATUS
+NdisprotPnPEventHandler(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN PNET_PNP_EVENT_NOTIFICATION pNetPnPEventNotification
+ )
+/*++
+
+Routine Description:
+
+ Called by NDIS to notify us of a PNP event. The most significant
+ one for us is power state change.
+
+Arguments:
+
+ ProtocolBindingContext - pointer to open context structure
+ this is NULL for global reconfig events.
+
+ pNetPnPEventNotification - pointer to the PNP event notification
+
+Return Value:
+
+ Our processing status for the PNP event.
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PUCHAR Buffer = NULL;
+ ULONG BufferLength = 0;
+ PNDIS_PROTOCOL_RESTART_PARAMETERS RestartParameters = NULL;
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
+
+ switch (pNetPnPEventNotification->NetPnPEvent.NetEvent)
+ {
+ case NetEventSetPower:
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+ pOpenContext->PowerState = *(PNET_DEVICE_POWER_STATE)pNetPnPEventNotification->NetPnPEvent.Buffer;
+
+ if (pOpenContext->PowerState > NetDeviceStateD0)
+ {
+ //
+ // The device below is transitioning to a low power state.
+ // Block any threads attempting to query the device while
+ // in this state.
+ //
+ NPROT_INIT_EVENT(&pOpenContext->PoweredUpEvent);
+
+ //
+ // There is no need to wait for pending I/O here.
+ // We wait for it in the NetEventPause handler.
+ //
+
+ //
+ // Return any receives that we had queued up.
+ //
+ ndisprotFlushReceiveQueue(pOpenContext);
+ DEBUGP(DL_INFO, ("PnPEvent: Open %p, SetPower to %d\n",
+ pOpenContext, pOpenContext->PowerState));
+ }
+ else
+ {
+ //
+ // The device below is powered up.
+ //
+ DEBUGP(DL_INFO, ("PnPEvent: Open %p, SetPower ON: %d\n",
+ pOpenContext, pOpenContext->PowerState));
+ NPROT_SIGNAL_EVENT(&pOpenContext->PoweredUpEvent);
+ }
+
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+
+ case NetEventQueryPower:
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+
+ case NetEventBindsComplete:
+ NPROT_SIGNAL_EVENT(&Globals.BindsComplete);
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+
+ case NetEventPause:
+ //
+ // Wait all sends to be complete.
+ //
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+ pOpenContext->State = NdisprotPausing;
+
+ //
+ // we could also complete the PnP Event asynchrously.
+ //
+ while (TRUE)
+ {
+ if (pOpenContext->PendedSendCount == 0)
+ break;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ DEBUGP(DL_INFO, ("PnPEvent: Open %p, outstanding count is %d\n", pOpenContext,
+ pOpenContext->PendedSendCount));
+
+ NdisMSleep(100000); // 100 ms.
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ //
+ // Return all queued receives.
+ //
+ ndisprotFlushReceiveQueue(pOpenContext);
+ pOpenContext->State = NdisprotPaused;
+
+ break;
+
+ case NetEventRestart:
+
+
+ ASSERT(pOpenContext->State == NdisprotPaused);
+ //
+ // Get the updated attributes
+ //
+ Buffer = pNetPnPEventNotification->NetPnPEvent.Buffer;
+ if (Buffer == NULL)
+ {
+ pOpenContext->State = NdisprotRunning;
+ break;
+ }
+ BufferLength = pNetPnPEventNotification->NetPnPEvent.BufferLength;
+
+ ASSERT(BufferLength == sizeof(NDIS_PROTOCOL_RESTART_PARAMETERS));
+
+ RestartParameters = (PNDIS_PROTOCOL_RESTART_PARAMETERS)Buffer;
+ ndisprotRestart(pOpenContext,RestartParameters);
+
+
+ pOpenContext->State = NdisprotRunning;
+ break;
+
+ case NetEventQueryRemoveDevice:
+ case NetEventCancelRemoveDevice:
+ case NetEventReconfigure:
+ case NetEventBindList:
+ case NetEventPnPCapabilities:
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+
+ default:
+ Status = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ DEBUGP(DL_INFO, ("PnPEvent: Open %p, Event %d, Status %x\n",
+ pOpenContext, pNetPnPEventNotification->NetPnPEvent.NetEvent, Status));
+
+ return (Status);
+}
+
+VOID
+NdisprotProtocolUnloadHandler(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ NDIS calls this on a usermode request to uninstall us.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None
+
+--*/
+{
+ ndisprotDoProtocolUnload();
+}
+
+NDIS_STATUS
+ndisprotCreateBinding(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN PNDIS_BIND_PARAMETERS BindParameters,
+ IN NDIS_HANDLE BindContext,
+ _In_reads_bytes_(BindingInfoLength) IN PUCHAR pBindingInfo,
+ IN ULONG BindingInfoLength
+ )
+/*++
+
+Routine Description:
+
+ Utility function to create an NDIS binding to the indicated device,
+ if no such binding exists.
+
+ Here is where we also allocate additional resources (e.g. packet pool)
+ for the binding.
+
+ NOTE: this function blocks and finishes synchronously.
+
+Arguments:
+
+ pOpenContext - pointer to open context block
+ BindParameters - pointer to NDIS_BIND_PARAMETERS
+ BindConext - pointer to NDIS bind context
+ pBindingInfo - pointer to unicode device name string
+ BindingInfoLength - length in bytes of the above.
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS if a binding was successfully set up.
+ NDIS_STATUS_XXX error code on any failure.
+
+--*/
+{
+ NDIS_STATUS Status;
+ NDIS_MEDIUM MediumArray[1] = {NdisMedium802_3};
+ NDIS_OPEN_PARAMETERS OpenParameters;
+ NET_BUFFER_LIST_POOL_PARAMETERS PoolParameters;
+ UINT SelectedMediumIndex;
+ BOOLEAN fOpenComplete = FALSE;
+ ULONG GenericUlong = 0;
+ NET_FRAME_TYPE FrameTypeArray[2] = {NDIS_ETH_TYPE_802_1X, NDIS_ETH_TYPE_802_1Q};
+#if DBG
+ PNDISPROT_OPEN_CONTEXT pTmpOpenContext;
+#endif
+
+ DEBUGP(DL_LOUD, ("CreateBinding: open %p/%x, device [%s]\n",
+ pOpenContext, pOpenContext->Flags, pBindingInfo));
+
+ Status = NDIS_STATUS_SUCCESS;
+
+ do
+ {
+ //
+ // Check if we already have a binding to this device.
+ //
+#if DBG
+ pTmpOpenContext = ndisprotLookupDevice(pBindingInfo, BindingInfoLength);
+
+ ASSERT(pTmpOpenContext == NULL);
+
+ if (pTmpOpenContext != NULL)
+ {
+ DEBUGP(DL_WARN,
+ ("CreateBinding: Binding to device %ws already exists on open %p\n",
+ pTmpOpenContext->DeviceName.Buffer, pTmpOpenContext));
+
+ NPROT_DEREF_OPEN(pTmpOpenContext); // temp ref added by Lookup
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+#endif
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_OPENING);
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Copy in the device name. Add room for a NULL terminator.
+ //
+ NPROT_ALLOC_MEM(pOpenContext->DeviceName.Buffer, BindingInfoLength + sizeof(WCHAR));
+ if (pOpenContext->DeviceName.Buffer == NULL)
+ {
+ DEBUGP(DL_WARN, ("CreateBinding: failed to alloc device name buf (%d bytes)\n",
+ BindingInfoLength + sizeof(WCHAR)));
+ Status = NDIS_STATUS_RESOURCES;
+ break;
+ }
+
+ NPROT_COPY_MEM(pOpenContext->DeviceName.Buffer, pBindingInfo, BindingInfoLength);
+#pragma prefast(suppress: 12009, "DeviceName length will not cause overflow")
+ *(PWCHAR)((PUCHAR)pOpenContext->DeviceName.Buffer + BindingInfoLength) = L'\0';
+ NdisInitUnicodeString(&pOpenContext->DeviceName, pOpenContext->DeviceName.Buffer);
+
+ NdisZeroMemory(&PoolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));
+
+ PoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
+ PoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
+ PoolParameters.Header.Size = sizeof(PoolParameters);
+ PoolParameters.ProtocolId = NDIS_PROTOCOL_ID_IPX ;
+ PoolParameters.ContextSize = sizeof(NPROT_SEND_NETBUFLIST_RSVD);
+ PoolParameters.fAllocateNetBuffer = TRUE;
+ PoolParameters.PoolTag = NPROT_ALLOC_TAG;
+
+ pOpenContext->SendNetBufferListPool = NdisAllocateNetBufferListPool(
+ Globals.NdisProtocolHandle,
+ &PoolParameters);
+ if (pOpenContext->SendNetBufferListPool == NULL)
+ {
+ DEBUGP(DL_WARN, ("CreateBinding: failed to alloc"
+ " send net buffer list pool\n"));
+
+ Status = NDIS_STATUS_RESOURCES;
+ break;
+ }
+
+ PoolParameters.ContextSize = 0;
+
+ pOpenContext->RecvNetBufferListPool = NdisAllocateNetBufferListPool(
+ Globals.NdisProtocolHandle,
+ &PoolParameters);
+
+ if (pOpenContext->RecvNetBufferListPool == NULL)
+ {
+ DEBUGP(DL_WARN, ("CreateBinding: failed to alloc"
+ " recv net buffer list pool.\n"));
+
+ Status = NDIS_STATUS_RESOURCES;
+ break;
+ }
+
+ //
+ // Assume that the device is powered up.
+ //
+ pOpenContext->PowerState = NetDeviceStateD0;
+
+ //
+ // Open the adapter.
+ //
+ NPROT_INIT_EVENT(&pOpenContext->BindEvent);
+
+ NPROT_ZERO_MEM(&OpenParameters, sizeof(NDIS_OPEN_PARAMETERS));
+ OpenParameters.Header.Revision = NDIS_OPEN_PARAMETERS_REVISION_1;
+ OpenParameters.Header.Size = sizeof(NDIS_OPEN_PARAMETERS);
+ OpenParameters.Header.Type = NDIS_OBJECT_TYPE_OPEN_PARAMETERS;
+ OpenParameters.AdapterName = BindParameters->AdapterName;
+ OpenParameters.MediumArray = &MediumArray[0];
+ OpenParameters.MediumArraySize = sizeof(MediumArray) / sizeof(NDIS_MEDIUM);
+ OpenParameters.SelectedMediumIndex = &SelectedMediumIndex;
+ OpenParameters.FrameTypeArray = &FrameTypeArray[0];
+ OpenParameters.FrameTypeArraySize = sizeof(FrameTypeArray) / sizeof(NET_FRAME_TYPE);
+
+
+ NDIS_DECLARE_PROTOCOL_OPEN_CONTEXT(NDISPROT_OPEN_CONTEXT);
+ Status = NdisOpenAdapterEx(Globals.NdisProtocolHandle,
+ (NDIS_HANDLE)pOpenContext,
+ &OpenParameters,
+ BindContext,
+ &pOpenContext->BindingHandle);
+
+ if (Status == NDIS_STATUS_PENDING)
+ {
+ NPROT_WAIT_EVENT(&pOpenContext->BindEvent, 0);
+ Status = pOpenContext->BindStatus;
+ }
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGP(DL_WARN, ("CreateBinding: NdisOpenAdapter (%ws) failed: %x\n",
+ pOpenContext->DeviceName.Buffer, Status));
+ break;
+ }
+
+ pOpenContext->State = NdisprotPaused;
+
+ fOpenComplete = TRUE;
+
+ //
+ // Get the friendly name for the adapter. It is not fatal for this
+ // to fail.
+ //
+ (VOID)NdisQueryAdapterInstanceName(
+ &pOpenContext->DeviceDescr,
+ pOpenContext->BindingHandle
+ );
+
+ NdisMoveMemory(&pOpenContext->CurrentAddress[0],
+ BindParameters->CurrentMacAddress,
+ NPROT_MAC_ADDR_LEN);
+ //
+ // Get MAC options.
+ //
+ pOpenContext->MacOptions = BindParameters->MacOptions;
+
+
+ //
+ // Get the max frame size.
+ //
+ pOpenContext->MaxFrameSize = BindParameters->MtuSize;
+
+ //
+ // Get the media connect status.
+ //
+ GenericUlong = BindParameters->MediaConnectState;
+
+ if (GenericUlong == NdisMediaStateConnected)
+ {
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_MEDIA_FLAGS, NPROTO_MEDIA_CONNECTED);
+ }
+ else
+ {
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_MEDIA_FLAGS, NPROTO_MEDIA_DISCONNECTED);
+ }
+ //
+ // Get the back fill size
+ //
+ pOpenContext->DataBackFillSize = BindParameters->DataBackFillSize;
+ pOpenContext->ContextBackFillSize = BindParameters->ContextBackFillSize;
+
+ //
+ // Mark this open. Also check if we received an Unbind while
+ // we were setting this up.
+ //
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE);
+
+ ASSERT(!NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_UNBIND_FLAGS, NPROTO_UNBIND_RECEIVED));
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ }
+ while (FALSE);
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Check if we had actually finished opening the adapter.
+ //
+ if (fOpenComplete)
+ {
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE);
+ }
+ else if (NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_OPENING))
+ {
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_FAILED);
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ ndisprotShutdownBinding(pOpenContext);
+ }
+
+ DEBUGP(DL_INFO, ("CreateBinding: OpenContext %p, Status %x\n",
+ pOpenContext, Status));
+
+ return (Status);
+}
+
+
+
+VOID
+ndisprotShutdownBinding(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ )
+/*++
+
+Routine Description:
+
+ Utility function to shut down the NDIS binding, if one exists, on
+ the specified open. This is written to be called from:
+
+ ndisprotCreateBinding - on failure
+ NdisprotUnbindAdapter
+
+ We handle the case where a binding is in the process of being set up.
+ This precaution is not needed if this routine is only called from
+ the context of our UnbindAdapter handler, but they are here in case
+ we initiate unbinding from elsewhere (e.g. on processing a user command).
+
+ NOTE: this blocks and finishes synchronously.
+
+Arguments:
+
+ pOpenContext - pointer to open context block
+
+Return Value:
+
+ None
+
+--*/
+{
+ NDIS_STATUS Status;
+ BOOLEAN DoCloseBinding = FALSE;
+ NPROT_EVENT ClosingEvent;
+
+ do
+ {
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_OPENING))
+ {
+ //
+ // We are still in the process of setting up this binding.
+ //
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ break;
+ }
+
+ if (NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE))
+ {
+ ASSERT(pOpenContext->ClosingEvent == NULL);
+ pOpenContext->ClosingEvent = NULL;
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_CLOSING);
+
+ if (pOpenContext->PendedSendCount != 0)
+ {
+ pOpenContext->ClosingEvent = &ClosingEvent;
+ NPROT_INIT_EVENT(&ClosingEvent);
+ }
+
+ DoCloseBinding = TRUE;
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (DoCloseBinding)
+ {
+ ULONG PacketFilter = 0;
+ ULONG BytesRead = 0;
+
+ //
+ // Set Packet filter to 0 before closing the binding
+ //
+ Status = ndisprotDoRequest(
+ pOpenContext,
+ NDIS_DEFAULT_PORT_NUMBER,
+ NdisRequestSetInformation,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ &PacketFilter,
+ sizeof(PacketFilter),
+ &BytesRead);
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGP(DL_WARN, ("ShutDownBinding: set packet filter failed: %x\n", Status));
+ }
+
+ //
+ // Set multicast list to null before closing the binding
+ //
+ Status = ndisprotDoRequest(
+ pOpenContext,
+ NDIS_DEFAULT_PORT_NUMBER,
+ NdisRequestSetInformation,
+ OID_802_3_MULTICAST_LIST,
+ NULL,
+ 0,
+ &BytesRead);
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGP(DL_WARN, ("ShutDownBinding: set multicast list failed: %x\n", Status));
+ }
+
+ //
+ // Wait for any pending sends or requests on
+ // the binding to complete.
+ //
+ ndisprotWaitForPendingIO(pOpenContext, TRUE);
+
+ //
+ // Discard any queued receives.
+ //
+ ndisprotFlushReceiveQueue(pOpenContext);
+
+ //
+ // Close the binding now.
+ //
+ NPROT_INIT_EVENT(&pOpenContext->BindEvent);
+
+ DEBUGP(DL_INFO, ("ShutdownBinding: Closing OpenContext %p,"
+ " BindingHandle %p\n",
+ pOpenContext, pOpenContext->BindingHandle));
+
+ Status = NdisCloseAdapterEx(pOpenContext->BindingHandle);
+
+ if (Status == NDIS_STATUS_PENDING)
+ {
+ NPROT_WAIT_EVENT(&pOpenContext->BindEvent, 0);
+ Status = pOpenContext->BindStatus;
+ }
+
+ NPROT_ASSERT(Status == NDIS_STATUS_SUCCESS);
+
+ pOpenContext->BindingHandle = NULL;
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_IDLE);
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_UNBIND_FLAGS, 0);
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ }
+ } while (FALSE);
+
+
+ //
+ // Remove it from the global list.
+ //
+ NPROT_ACQUIRE_LOCK(&Globals.GlobalLock, FALSE);
+
+ NPROT_REMOVE_ENTRY_LIST(&pOpenContext->Link);
+
+ NPROT_RELEASE_LOCK(&Globals.GlobalLock, FALSE);
+
+ //
+ // Free any other resources allocated for this bind.
+ //
+ ndisprotFreeBindResources(pOpenContext);
+
+ NPROT_DEREF_OPEN(pOpenContext); // Shutdown binding
+
+}
+
+
+VOID
+ndisprotFreeBindResources(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ )
+/*++
+
+Routine Description:
+
+ Free any resources set up for an NDIS binding.
+
+Arguments:
+
+ pOpenContext - pointer to open context block
+
+Return Value:
+
+ None
+
+--*/
+{
+ if (pOpenContext->SendNetBufferListPool != NULL)
+ {
+ NdisFreeNetBufferListPool(pOpenContext->SendNetBufferListPool);
+ pOpenContext->SendNetBufferListPool = NULL;
+ }
+
+ if (pOpenContext->RecvNetBufferListPool != NULL)
+ {
+ NdisFreeNetBufferListPool(pOpenContext->RecvNetBufferListPool);
+ pOpenContext->RecvNetBufferListPool = NULL;
+ }
+
+ if (pOpenContext->DeviceName.Buffer != NULL)
+ {
+ NPROT_FREE_MEM(pOpenContext->DeviceName.Buffer);
+ pOpenContext->DeviceName.Buffer = NULL;
+ pOpenContext->DeviceName.Length =
+ pOpenContext->DeviceName.MaximumLength = 0;
+ }
+
+ if (pOpenContext->DeviceDescr.Buffer != NULL)
+ {
+ //
+ // this would have been allocated by NdisQueryAdpaterInstanceName.
+ //
+ NdisFreeMemory(pOpenContext->DeviceDescr.Buffer, 0, 0);
+ pOpenContext->DeviceDescr.Buffer = NULL;
+ }
+}
+
+
+VOID
+ndisprotWaitForPendingIO(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN BOOLEAN DoCancelReads
+ )
+/*++
+
+Routine Description:
+
+ Utility function to wait for all outstanding I/O to complete
+ on an open context. It is assumed that the open context
+ won't go away while we are in this routine.
+
+Arguments:
+
+ pOpenContext - pointer to open context structure
+ DoCancelReads - do we wait for pending reads to go away (and cancel them)?
+
+Return Value:
+
+ None
+
+--*/
+{
+ //
+ // Wait for any pending sends or requests on the binding to complete.
+ //
+ if (pOpenContext->PendedSendCount == 0)
+ {
+ ASSERT(pOpenContext->ClosingEvent == NULL);
+ }
+ else
+ {
+ ASSERT(pOpenContext->ClosingEvent != NULL);
+ DEBUGP(DL_WARN, ("WaitForPendingIO: Open %p, %d pended sends\n",
+ pOpenContext, pOpenContext->PendedSendCount));
+
+ NPROT_WAIT_EVENT(pOpenContext->ClosingEvent, 0);
+
+ }
+
+ if (DoCancelReads)
+ {
+ //
+ // Wait for any pended reads to complete/cancel.
+ //
+ while (pOpenContext->PendedReadCount != 0)
+ {
+ DEBUGP(DL_INFO, ("WaitForPendingIO: Open %p, %d pended reads\n",
+ pOpenContext, pOpenContext->PendedReadCount));
+
+ //
+ // Cancel any pending reads.
+ //
+ ndisprotCancelPendingReads(pOpenContext);
+
+ NdisMSleep(100000); // 100 ms.
+ }
+ }
+
+}
+
+
+VOID
+ndisprotDoProtocolUnload(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Utility routine to handle unload from the NDIS protocol side.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None
+
+--*/
+{
+ NDIS_HANDLE ProtocolHandle;
+
+ DEBUGP(DL_INFO, ("ProtocolUnload: ProtocolHandle %lp\n",
+ Globals.NdisProtocolHandle));
+
+ if (Globals.NdisProtocolHandle != NULL)
+ {
+ ProtocolHandle = Globals.NdisProtocolHandle;
+ Globals.NdisProtocolHandle = NULL;
+
+ NdisDeregisterProtocolDriver(ProtocolHandle);
+
+ }
+}
+
+
+NDIS_STATUS
+ndisprotDoRequest(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN NDIS_PORT_NUMBER PortNumber,
+ IN NDIS_REQUEST_TYPE RequestType,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG pBytesProcessed
+ )
+/*++
+
+Routine Description:
+
+ Utility routine that forms and sends an NDIS_REQUEST to the
+ miniport, waits for it to complete, and returns status
+ to the caller.
+
+ NOTE: this assumes that the calling routine ensures validity
+ of the binding handle until this returns.
+
+Arguments:
+
+ pOpenContext - pointer to our open context
+ PortNumber - the port to issue the request
+ RequestType - NdisRequest[Set|Query|Method]Information
+ Oid - the object being set/queried
+ InformationBuffer - data for the request
+ InformationBufferLength - length of the above
+ pBytesProcessed - place to return bytes read/written
+
+Return Value:
+
+ Status of the set/query/method request
+
+--*/
+{
+ NDISPROT_REQUEST ReqContext;
+ PNDIS_OID_REQUEST pNdisRequest = &ReqContext.Request;
+ NDIS_STATUS Status;
+
+
+ NdisZeroMemory(&ReqContext, sizeof(ReqContext));
+
+ NPROT_INIT_EVENT(&ReqContext.ReqEvent);
+ pNdisRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
+ pNdisRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
+ pNdisRequest->Header.Size = sizeof(NDIS_OID_REQUEST);
+ pNdisRequest->RequestType = RequestType;
+ pNdisRequest->PortNumber = PortNumber;
+
+ switch (RequestType)
+ {
+ case NdisRequestQueryInformation:
+ pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
+ pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =
+ InformationBuffer;
+ pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
+ InformationBufferLength;
+ break;
+
+ case NdisRequestSetInformation:
+ pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
+ pNdisRequest->DATA.SET_INFORMATION.InformationBuffer =
+ InformationBuffer;
+ pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength =
+ InformationBufferLength;
+ break;
+
+ default:
+ NPROT_ASSERT(FALSE);
+ break;
+ }
+
+ pNdisRequest->RequestId = NPROT_GET_NEXT_CANCEL_ID();
+ Status = NdisOidRequest(pOpenContext->BindingHandle,
+ pNdisRequest);
+
+
+ if (Status == NDIS_STATUS_PENDING)
+ {
+
+ NPROT_WAIT_EVENT(&ReqContext.ReqEvent, 0);
+ Status = ReqContext.Status;
+ }
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ *pBytesProcessed = (RequestType == NdisRequestQueryInformation)?
+ pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten:
+ pNdisRequest->DATA.SET_INFORMATION.BytesRead;
+
+ //
+ // The driver below should set the correct value to BytesWritten
+ // or BytesRead. But now, we just truncate the value to InformationBufferLength
+ //
+ if (*pBytesProcessed > InformationBufferLength)
+ {
+ *pBytesProcessed = InformationBufferLength;
+ }
+ }
+
+ return (Status);
+}
+
+
+NDIS_STATUS
+ndisprotValidateOpenAndDoRequest(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN NDIS_REQUEST_TYPE RequestType,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG pBytesProcessed,
+ IN BOOLEAN bWaitForPowerOn
+ )
+/*++
+
+Routine Description:
+
+ Utility routine to prevalidate and reference an open context
+ before calling ndisprotDoRequest. This routine makes sure
+ we have a valid binding.
+
+Arguments:
+
+ pOpenContext - pointer to our open context
+ RequestType - NdisRequest[Set|Query]Information
+ Oid - the object being set/queried
+ InformationBuffer - data for the request
+ InformationBufferLength - length of the above
+ pBytesProcessed - place to return bytes read/written
+ bWaitForPowerOn - Wait for the device to be powered on if it isn't already.
+
+Return Value:
+
+ Status of the set/query request
+
+--*/
+{
+ NDIS_STATUS Status;
+
+ do
+ {
+ if (pOpenContext == NULL)
+ {
+ DEBUGP(DL_WARN, ("ValidateOpenAndDoRequest: request on unassociated file object!\n"));
+ Status = NDIS_STATUS_INVALID_DATA;
+ break;
+ }
+
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Proceed only if we have a binding.
+ //
+ if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE))
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ Status = NDIS_STATUS_INVALID_DATA;
+ break;
+ }
+
+ NPROT_ASSERT(pOpenContext->BindingHandle != NULL);
+
+ //
+ // Make sure that the binding does not go away until we
+ // are finished with the request.
+ //
+ pOpenContext->PendedSendCount++;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (bWaitForPowerOn)
+ {
+ //
+ // Wait for the device below to be powered up.
+ // We don't wait indefinitely here - this is to avoid
+ // a PROCESS_HAS_LOCKED_PAGES bugcheck that could happen
+ // if the calling process terminates, and this IRP doesn't
+ // complete within a reasonable time. An alternative would
+ // be to explicitly handle cancellation of this IRP.
+ //
+ //NPROT_WAIT_EVENT(&pOpenContext->PoweredUpEvent, 4500);
+ //the following replace NPROT_WAIT_EVENT(&pOpenContext->PoweredUpEvent, 4500); to supress prefast warning 28193
+ NdisWaitEvent(&pOpenContext->PoweredUpEvent, 4500);
+ }
+
+ if (pOpenContext->PowerState == NetDeviceStateD0)
+ {
+
+ Status = ndisprotDoRequest(
+ pOpenContext,
+ NDIS_DEFAULT_PORT_NUMBER,
+ RequestType,
+ Oid,
+ InformationBuffer,
+ InformationBufferLength,
+ pBytesProcessed);
+ }
+ else
+ {
+ Status = NDIS_STATUS_ADAPTER_NOT_READY;
+ }
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+ //
+ // Let go of the binding.
+ //
+ pOpenContext->PendedSendCount --;
+ if ((NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_CLOSING))
+ && (pOpenContext->PendedSendCount == 0))
+ {
+ ASSERT(pOpenContext->ClosingEvent != NULL);
+ NPROT_SIGNAL_EVENT(pOpenContext->ClosingEvent);
+ pOpenContext->ClosingEvent = NULL;
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ }
+ while (FALSE);
+
+ DEBUGP(DL_LOUD, ("ValidateOpenAndDoReq: Open %p/%x, OID %x, Status %x\n",
+ pOpenContext, pOpenContext->Flags, Oid, Status));
+
+ return (Status);
+}
+
+
+VOID
+NdisprotRequestComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN PNDIS_OID_REQUEST pNdisRequest,
+ IN NDIS_STATUS Status
+ )
+/*++
+
+Routine Description:
+
+ NDIS entry point indicating completion of a pended NDIS_REQUEST.
+
+Arguments:
+
+ ProtocolBindingContext - pointer to open context
+ pNdisRequest - pointer to NDIS request
+ Status - status of reset completion
+
+Return Value:
+
+ None
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ PNDISPROT_REQUEST pReqContext;
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ //
+ // Get at the request context.
+ //
+ pReqContext = CONTAINING_RECORD(pNdisRequest, NDISPROT_REQUEST, Request);
+
+ //
+ // Save away the completion status.
+ //
+ pReqContext->Status = Status;
+
+ //
+ // Wake up the thread blocked for this request to complete.
+ //
+ NPROT_SIGNAL_EVENT(&pReqContext->ReqEvent);
+}
+
+
+VOID
+NdisprotStatus(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN PNDIS_STATUS_INDICATION StatusIndication
+ )
+/*++
+
+Routine Description:
+
+ Protocol entry point called by NDIS to indicate a change
+ in status at the miniport.
+
+ We make note of reset and media connect status indications.
+
+Arguments:
+
+ ProtocolBindingContext - pointer to open context
+ StatusIndication - pointer to NDIS_STATUS_INDICATION
+
+Return Value:
+
+ None
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ NDIS_STATUS GeneralStatus;
+ PNDIS_LINK_STATE LinkState;
+
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+
+ if ((StatusIndication->Header.Type != NDIS_OBJECT_TYPE_STATUS_INDICATION)
+ || (StatusIndication->Header.Size != sizeof(NDIS_STATUS_INDICATION)))
+ {
+ DEBUGP(DL_INFO, ("Status: Received an invalid status indication: Open %p, StatusIndication %p\n",
+ pOpenContext, StatusIndication));
+ return;
+ }
+
+ GeneralStatus = StatusIndication->StatusCode;
+
+ DEBUGP(DL_INFO, ("Status: Open %p, Status %x\n",
+ pOpenContext, GeneralStatus));
+
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ do
+ {
+ if (pOpenContext->PowerState != NetDeviceStateD0)
+ {
+ //
+ //
+ // The device is in a low power state.
+
+ //
+ // We continue and make note of status indications
+ //
+
+ //
+ // NOTE that any actions we take based on these
+ // status indications should take into account
+ // the current device power state.
+ //
+ }
+
+ switch(GeneralStatus)
+ {
+ case NDIS_STATUS_RESET_START:
+
+ NPROT_ASSERT(!NPROT_TEST_FLAGS(pOpenContext->Flags,
+ NPROTO_RESET_FLAGS,
+ NPROTO_RESET_IN_PROGRESS));
+
+ NPROT_SET_FLAGS(pOpenContext->Flags,
+ NPROTO_RESET_FLAGS,
+ NPROTO_RESET_IN_PROGRESS);
+
+ break;
+
+ case NDIS_STATUS_RESET_END:
+
+ NPROT_ASSERT(NPROT_TEST_FLAGS(pOpenContext->Flags,
+ NPROTO_RESET_FLAGS,
+ NPROTO_RESET_IN_PROGRESS));
+
+ NPROT_SET_FLAGS(pOpenContext->Flags,
+ NPROTO_RESET_FLAGS,
+ NPROTO_NOT_RESETTING);
+
+ break;
+
+ case NDIS_STATUS_LINK_STATE:
+
+ ASSERT(StatusIndication->StatusBufferSize >= sizeof(NDIS_LINK_STATE));
+
+ LinkState = (PNDIS_LINK_STATE)StatusIndication->StatusBuffer;
+
+ if (LinkState->MediaConnectState == MediaConnectStateConnected)
+ {
+ NPROT_SET_FLAGS(pOpenContext->Flags,
+ NPROTO_MEDIA_FLAGS,
+ NPROTO_MEDIA_CONNECTED);
+ }
+ else
+ {
+ NPROT_SET_FLAGS(pOpenContext->Flags,
+ NPROTO_MEDIA_FLAGS,
+ NPROTO_MEDIA_DISCONNECTED);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ while (FALSE);
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+}
+
+NDIS_STATUS
+ndisprotWriteString(
+ _Out_writes_bytes_to_(OutputLength, *pBytesWritten)
+ PUCHAR pBuffer,
+ _In_ ULONG OutputLength,
+ _Out_ PULONG pBytesWritten,
+ _In_ PNDIS_STRING String
+ )
+/*++
+
+Routine Description:
+
+ Writes an NDIS_STRING to an output buffer as a NULL-terminated string
+
+Arguments:
+
+ pBuffer - output buffer
+ OutputLength - size of pBuffer
+ pBytesWritten - receives the number of bytes written to pBuffer
+ String - NDIS_STRING to write
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS if successful
+ NDIS_STATUS_BUFFER_OVERFLOW if OutputLength is insufficient
+
+--*/
+{
+ ULONG BytesNeeded = String->Length + sizeof(UNICODE_NULL);
+
+ if (OutputLength < BytesNeeded)
+ {
+ return NDIS_STATUS_BUFFER_OVERFLOW;
+ }
+
+ NPROT_COPY_MEM(pBuffer, String->Buffer, String->Length);
+ *(PWCHAR)(pBuffer + String->Length) = UNICODE_NULL;
+
+ *pBytesWritten = BytesNeeded;
+ return NDIS_STATUS_SUCCESS;
+}
+
+NDIS_STATUS
+ndisprotQueryBinding(
+ _Inout_updates_bytes_to_(OutputLength, *pBytesReturned)
+ PUCHAR pBuffer,
+ _In_ ULONG InputLength,
+ _In_ ULONG OutputLength,
+ _Out_ PULONG pBytesReturned
+ )
+/*++
+
+Routine Description:
+
+ Return information about the specified binding.
+
+Arguments:
+
+ pBuffer - pointer to NDISPROT_QUERY_BINDING
+ InputLength - input buffer size
+ OutputLength - output buffer size
+ pBytesReturned - place to return copied byte count.
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS if successful, failure code otherwise.
+
+--*/
+{
+ PNDISPROT_QUERY_BINDING pQueryBinding;
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ PLIST_ENTRY pEnt;
+ ULONG BindingIndex;
+ NDIS_STATUS Status;
+ ULONG DeviceNameOffset;
+ ULONG DeviceDescrOffset;
+ ULONG StringBytesWritten;
+
+ do
+ {
+ *pBytesReturned = 0;
+
+ if (InputLength < sizeof(NDISPROT_QUERY_BINDING))
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ break;
+ }
+
+ if (OutputLength < sizeof(NDISPROT_QUERY_BINDING))
+ {
+ Status = NDIS_STATUS_BUFFER_OVERFLOW;
+ break;
+ }
+
+ pQueryBinding = (PNDISPROT_QUERY_BINDING)pBuffer;
+ BindingIndex = pQueryBinding->BindingIndex;
+
+ Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+
+ pOpenContext = NULL;
+
+ NPROT_ACQUIRE_LOCK(&Globals.GlobalLock, FALSE);
+
+ for (pEnt = Globals.OpenList.Flink;
+ pEnt != &Globals.OpenList;
+ pEnt = pEnt->Flink)
+ {
+ pOpenContext = CONTAINING_RECORD(pEnt, NDISPROT_OPEN_CONTEXT, Link);
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Skip if not bound.
+ //
+ if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE))
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ continue;
+ }
+
+ if (BindingIndex == 0)
+ {
+ //
+ // Got the binding we are looking for. Copy the device
+ // name and description strings to the output buffer.
+ //
+ DEBUGP(DL_INFO,
+ ("QueryBinding: found open %p\n", pOpenContext));
+
+ pQueryBinding->DeviceNameOffset = 0;
+ pQueryBinding->DeviceNameLength = pOpenContext->DeviceName.Length;
+ pQueryBinding->DeviceDescrOffset = 0;
+ pQueryBinding->DeviceDescrLength = pOpenContext->DeviceDescr.Length;
+
+ *pBytesReturned = sizeof(NDISPROT_QUERY_BINDING);
+
+ //
+ // Copy the DeviceName string
+ //
+
+ DeviceNameOffset = sizeof(NDISPROT_QUERY_BINDING);
+
+ Status = ndisprotWriteString(pBuffer + DeviceNameOffset,
+ OutputLength - DeviceNameOffset,
+ &StringBytesWritten,
+ &pOpenContext->DeviceName);
+
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ break;
+ }
+
+ pQueryBinding->DeviceNameOffset = DeviceNameOffset;
+ *pBytesReturned += StringBytesWritten;
+
+ //
+ // Copy the DeviceDescr string
+ //
+
+ DeviceDescrOffset = DeviceNameOffset + StringBytesWritten;
+
+ Status = ndisprotWriteString(pBuffer + DeviceDescrOffset,
+ OutputLength - DeviceDescrOffset,
+ &StringBytesWritten,
+ &pOpenContext->DeviceDescr);
+
+ if (NDIS_STATUS_SUCCESS != Status)
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ break;
+ }
+
+ pQueryBinding->DeviceDescrOffset = DeviceDescrOffset;
+ *pBytesReturned += StringBytesWritten;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ BindingIndex--;
+ }
+
+ NPROT_RELEASE_LOCK(&Globals.GlobalLock, FALSE);
+
+ }
+ while (FALSE);
+
+ return (Status);
+}
+
+PNDISPROT_OPEN_CONTEXT
+ndisprotLookupDevice(
+ _In_reads_bytes_(BindingInfoLength) IN PUCHAR pBindingInfo,
+ IN ULONG BindingInfoLength
+ )
+/*++
+
+Routine Description:
+
+ Search our global list for an open context structure that
+ has a binding to the specified device, and return a pointer
+ to it.
+
+ NOTE: we reference the open that we return.
+
+Arguments:
+
+ pBindingInfo - pointer to unicode device name string
+ BindingInfoLength - length in bytes of the above.
+
+Return Value:
+
+ Pointer to the matching open context if found, else NULL
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ PLIST_ENTRY pEnt;
+
+ pOpenContext = NULL;
+
+ NPROT_ACQUIRE_LOCK(&Globals.GlobalLock, FALSE);
+
+ for (pEnt = Globals.OpenList.Flink;
+ pEnt != &Globals.OpenList;
+ pEnt = pEnt->Flink)
+ {
+ pOpenContext = CONTAINING_RECORD(pEnt, NDISPROT_OPEN_CONTEXT, Link);
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ //
+ // Check if this has the name we are looking for.
+ //
+ if ((pOpenContext->DeviceName.Length == BindingInfoLength) &&
+ NPROT_MEM_CMP(pOpenContext->DeviceName.Buffer, pBindingInfo, BindingInfoLength))
+ {
+ NPROT_REF_OPEN(pOpenContext); // ref added by LookupDevice
+ break;
+ }
+
+ pOpenContext = NULL;
+ }
+
+ NPROT_RELEASE_LOCK(&Globals.GlobalLock, FALSE);
+
+ return (pOpenContext);
+}
+
+
+NDIS_STATUS
+ndisprotQueryOidValue(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ OUT PVOID pDataBuffer,
+ IN ULONG BufferLength,
+ OUT PULONG pBytesWritten
+ )
+/*++
+
+Routine Description:
+
+ Query an arbitrary OID value from the miniport.
+
+Arguments:
+
+ pOpenContext - pointer to open context representing our binding to the miniport
+ pDataBuffer - place to store the returned value
+ BufferLength - length of the above
+ pBytesWritten - place to return length returned
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS if we successfully queried the OID.
+ NDIS_STATUS_XXX error code otherwise.
+
+--*/
+{
+ NDIS_STATUS Status;
+ PNDISPROT_QUERY_OID pQuery;
+ NDIS_OID Oid;
+
+ Oid = 0;
+
+ do
+ {
+ if (BufferLength < sizeof(NDISPROT_QUERY_OID))
+ {
+ Status = NDIS_STATUS_BUFFER_TOO_SHORT;
+ break;
+ }
+
+ pQuery = (PNDISPROT_QUERY_OID)pDataBuffer;
+ Oid = pQuery->Oid;
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE))
+ {
+ DEBUGP(DL_WARN,
+ ("QueryOid: Open %p/%x is in invalid state\n",
+ pOpenContext, pOpenContext->Flags));
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+
+ //
+ // Make sure the binding doesn't go away.
+ //
+ pOpenContext->PendedSendCount++;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ Status = ndisprotDoRequest(
+ pOpenContext,
+ pQuery->PortNumber,
+ NdisRequestQueryInformation,
+ Oid,
+ &pQuery->Data[0],
+ BufferLength - FIELD_OFFSET(NDISPROT_QUERY_OID, Data),
+ pBytesWritten);
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Let go of the binding.
+ //
+ pOpenContext->PendedSendCount --;
+ if ((NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_CLOSING))
+ && (pOpenContext->PendedSendCount == 0))
+ {
+ ASSERT(pOpenContext->ClosingEvent != NULL);
+ NPROT_SIGNAL_EVENT(pOpenContext->ClosingEvent);
+ pOpenContext->ClosingEvent = NULL;
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ *pBytesWritten += FIELD_OFFSET(NDISPROT_QUERY_OID, Data);
+ }
+
+ }
+ while (FALSE);
+
+ DEBUGP(DL_LOUD, ("QueryOid: Open %p/%x, OID %x, Status %x\n",
+ pOpenContext, pOpenContext->Flags, Oid, Status));
+
+ return (Status);
+
+}
+
+NDIS_STATUS
+ndisprotSetOidValue(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ OUT PVOID pDataBuffer,
+ IN ULONG BufferLength
+ )
+/*++
+
+Routine Description:
+
+ Set an arbitrary OID value to the miniport.
+
+Arguments:
+
+ pOpenContext - pointer to open context representing our binding to the miniport
+ pDataBuffer - buffer that contains the value to be set
+ BufferLength - length of the above
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS if we successfully set the OID
+ NDIS_STATUS_XXX error code otherwise.
+
+--*/
+{
+ NDIS_STATUS Status;
+ PNDISPROT_SET_OID pSet;
+ NDIS_OID Oid;
+ ULONG BytesWritten;
+
+ Oid = 0;
+
+ do
+ {
+ if (BufferLength < sizeof(NDISPROT_SET_OID))
+ {
+ Status = NDIS_STATUS_BUFFER_TOO_SHORT;
+ break;
+ }
+
+ pSet = (PNDISPROT_SET_OID)pDataBuffer;
+ Oid = pSet->Oid;
+
+ //
+ // We should check the OID is settable by the user mode apps
+ //
+ if (!ndisprotValidOid(Oid))
+ {
+ DEBUGP(DL_WARN, ("SetOid: Oid %x cannot be set\n", Oid));
+
+ Status = NDIS_STATUS_INVALID_DATA;
+ break;
+ }
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE))
+ {
+ DEBUGP(DL_WARN,
+ ("SetOid: Open %p/%x is in invalid state\n",
+ pOpenContext, pOpenContext->Flags));
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+
+ //
+ // Make sure the binding doesn't go away.
+ //
+ pOpenContext->PendedSendCount++;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ Status = ndisprotDoRequest(
+ pOpenContext,
+ pSet->PortNumber,
+ NdisRequestSetInformation,
+ Oid,
+ &pSet->Data[0],
+ BufferLength - FIELD_OFFSET(NDISPROT_SET_OID, Data),
+ &BytesWritten);
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Let go of the binding.
+ //
+ pOpenContext->PendedSendCount --;
+ if ((NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_CLOSING))
+ && (pOpenContext->PendedSendCount == 0))
+ {
+ ASSERT(pOpenContext->ClosingEvent != NULL);
+ NPROT_SIGNAL_EVENT(pOpenContext->ClosingEvent);
+ pOpenContext->ClosingEvent = NULL;
+ }
+
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ }
+ while (FALSE);
+
+ DEBUGP(DL_LOUD, ("SetOid: Open %p/%x, OID %x, Status %x\n",
+ pOpenContext, pOpenContext->Flags, Oid, Status));
+
+ return (Status);
+}
+
+BOOLEAN
+ndisprotValidOid(
+ IN NDIS_OID Oid
+ )
+/*++
+
+Routine Description:
+
+ Validate whether the given set OID is settable or not.
+
+Arguments:
+
+ Oid - The OID which the user tries to set.
+
+Return Value:
+
+ TRUE if the OID is allowed to set
+ FALSE otherwise.
+
+--*/
+{
+ UINT i;
+ UINT NumOids;
+
+ NumOids = sizeof(ndisprotSupportedSetOids) / sizeof(NDIS_OID);
+
+ for (i = 0; i < NumOids; i++)
+ {
+ if (ndisprotSupportedSetOids[i] == Oid)
+ {
+ break;
+ }
+ }
+
+ return (i < NumOids);
+}
+
+
+
+VOID
+#pragma warning(suppress:6262) // Function is only 22 bytes over the 1k guideline, reasonable enough.
+ndisprotRestart(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN PNDIS_PROTOCOL_RESTART_PARAMETERS RestartParameters
+ )
+/*++
+
+Routine Description:
+
+ Handle restart attributes changes.
+
+Arguments:
+
+ pOpenContext - pointer to open context
+ RestartParameters - pointer to ndis restart parameters
+
+Return Value:
+
+ None
+
+NOTE: Protocols should query any attribute:
+ 1. the attribute is not included in the RestartAttributes
+ and 2. The protocol cares about whether the attributes is changed by underlying driver.
+
+--*/
+
+{
+ ULONG Length;
+ ULONG TotalLength = 0;
+ PUCHAR Buffer;
+ ULONG BufferLength;
+#define NPROT_MAX_FILTER_NAME_LENGTH 512
+
+ WCHAR FilterNameBuffer[NPROT_MAX_FILTER_NAME_LENGTH];
+ PNDIS_RESTART_ATTRIBUTES NdisRestartAttributes;
+ PNDIS_RESTART_GENERAL_ATTRIBUTES NdisGeneralAttributes;
+
+ DEBUGP(DL_LOUD, ("ndisprotRestart: Open %p", pOpenContext));
+ //
+ // Check the filter stack changes
+ //
+ if (RestartParameters->FilterModuleNameBuffer != NULL)
+ {
+
+ Buffer = RestartParameters->FilterModuleNameBuffer;
+
+ while (RestartParameters->FilterModuleNameBufferLength > TotalLength)
+ {
+
+ BufferLength = *(PUSHORT)Buffer;
+
+ TotalLength += BufferLength + sizeof(USHORT);
+ Length = BufferLength + sizeof(USHORT);
+
+ if (BufferLength >= (NPROT_MAX_FILTER_NAME_LENGTH * sizeof(WCHAR)))
+ {
+ BufferLength = (NPROT_MAX_FILTER_NAME_LENGTH - 1) * sizeof(WCHAR);
+ }
+ NdisMoveMemory(FilterNameBuffer, Buffer + sizeof(USHORT), BufferLength);
+
+ BufferLength /= sizeof(WCHAR);
+
+ //
+ // BufferLength is bounded by the check above. Check again to suppress
+ // prefast warning
+ //
+ if (BufferLength < NPROT_MAX_FILTER_NAME_LENGTH)
+ {
+ FilterNameBuffer[BufferLength] = 0;
+ }
+
+ DEBUGP(DL_INFO, ("Filter: %ws\n", FilterNameBuffer));
+
+ Buffer += Length;
+ }
+ }
+ //
+ // Checked for updated attributes
+ //
+ NdisRestartAttributes = RestartParameters->RestartAttributes;
+
+ //
+ // NdisProt is only interested in the generic attributes.
+ //
+ while (NdisRestartAttributes != NULL)
+ {
+ if (NdisRestartAttributes->Oid == OID_GEN_MINIPORT_RESTART_ATTRIBUTES)
+ {
+ break;
+ }
+ NdisRestartAttributes = NdisRestartAttributes->Next;
+ }
+
+ //
+ // Pick up the new attributes of interest
+ //
+ if (NdisRestartAttributes != NULL)
+ {
+ NdisGeneralAttributes = (PNDIS_RESTART_GENERAL_ATTRIBUTES)NdisRestartAttributes->Data;
+
+ pOpenContext->MacOptions = NdisGeneralAttributes->MacOptions;
+ pOpenContext->MaxFrameSize = NdisGeneralAttributes->MtuSize;
+ }
+
+ DEBUGP(DL_LOUD, ("ndisprotRestart: Open %p", pOpenContext));
+
+}
+
+
diff --git a/network/ndis/ndisprot/6x/sys/ndisprot.h b/network/ndis/ndisprot/6x/sys/ndisprot.h
new file mode 100644
index 00000000..60ebb2af
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/ndisprot.h
@@ -0,0 +1,567 @@
+/*++
+
+Copyright (c) 2000 Microsoft Corporation
+
+Module Name:
+
+ ndisprot.h
+
+Abstract:
+
+ Data structures, defines and function prototypes for NDISPROT.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#ifndef __NDISPROT__H
+#define __NDISPROT__H
+
+#pragma warning(disable:28930) // Unused assignment of pointer, by design in samples
+#pragma warning(disable:28931) // Unused assignment of variable, by design in samples
+
+//
+// Update the driver version number every time you release a new driver
+// The high word is the major version. The low word is the minor version.
+// Also make sure that VER_FILEVERSION specified in the .RC file also
+// matches with the driver version.
+//
+// Let's say we're version 4.2.
+//
+#define MAJOR_DRIVER_VERSION 0x04
+#define MINOR_DRIVER_VERISON 0x02
+
+
+//
+// Define the NDIS protocol interface version that this driver targets.
+//
+#if defined(NDIS60)
+# define NDIS_PROT_MAJOR_VERSION 6
+# define NDIS_PROT_MINOR_VERSION 0
+#elif defined(NDIS630)
+# define NDIS_PROT_MAJOR_VERSION 6
+# define NDIS_PROT_MINOR_VERSION 30
+#else
+# error Unsupported NDIS version
+#endif
+
+
+#define NT_DEVICE_NAME L"\\Device\\Ndisprot"
+#define DOS_DEVICE_NAME L"\\Global??\\Ndisprot"
+
+
+//
+// Abstract types
+//
+typedef NDIS_EVENT NPROT_EVENT, *PNPROT_EVENT;
+
+#define MAX_MULTICAST_ADDRESS 0x20
+
+#define NPROT_MAC_ADDR_LEN 6
+
+
+typedef enum _NDISPROT_OPEN_STATE{
+ NdisprotInitializing,
+ NdisprotRunning,
+ NdisprotPausing,
+ NdisprotPaused,
+ NdisprotRestarting,
+ NdisprotClosing
+} NDISPROT_OPEN_STATE;
+//
+// The Open Context represents an open of our device object.
+// We allocate this on processing a BindAdapter from NDIS,
+// and free it when all references (see below) to it are gone.
+//
+// Binding/unbinding to an NDIS device:
+//
+// On processing a BindAdapter call from NDIS, we set up a binding
+// to the specified NDIS device (miniport). This binding is
+// torn down when NDIS asks us to Unbind by calling
+// our UnbindAdapter handler.
+//
+// Receiving data:
+//
+// While an NDIS binding exists, read IRPs are queued on this
+// structure, to be processed when packets are received.
+// If data arrives in the absense of a pended read IRP, we
+// queue it, to the extent of one packet, i.e. we save the
+// contents of the latest packet received. We fail read IRPs
+// received when no NDIS binding exists (or is in the process
+// of being torn down).
+//
+// Sending data:
+//
+// Write IRPs are used to send data. Each write IRP maps to
+// a single NDIS packet. Packet send-completion is mapped to
+// write IRP completion. We use NDIS 5.1 CancelSend to support
+// write IRP cancellation. Write IRPs that arrive when we don't
+// have an active NDIS binding are failed.
+//
+// Reference count:
+//
+// The following are long-lived references:
+// OPEN_DEVICE ioctl (goes away on processing a Close IRP)
+// Pended read IRPs
+// Queued received packets
+// Uncompleted write IRPs (outstanding sends)
+// Existence of NDIS binding
+//
+typedef struct _NDISPROT_OPEN_CONTEXT
+{
+ LIST_ENTRY Link; // Link into global list
+ ULONG Flags; // State information
+ ULONG RefCount;
+ NPROT_LOCK Lock;
+
+ PFILE_OBJECT pFileObject; // Set on OPEN_DEVICE
+
+ NDIS_HANDLE BindingHandle;
+ NDIS_HANDLE SendNetBufferListPool;
+ // let every net buffer list contain one net buffer(don't know how many net buffers can be include in one list.
+ NDIS_HANDLE RecvNetBufferListPool;
+
+ ULONG MacOptions;
+ ULONG MaxFrameSize;
+ ULONG DataBackFillSize;
+ ULONG ContextBackFillSize;
+
+ LIST_ENTRY PendedWrites; // pended Write IRPs
+ ULONG PendedSendCount;
+
+ LIST_ENTRY PendedReads; // pended Read IRPs
+ ULONG PendedReadCount;
+ LIST_ENTRY RecvNetBufListQueue;
+ ULONG RecvNetBufListCount;
+
+ NET_DEVICE_POWER_STATE PowerState;
+ NDIS_EVENT PoweredUpEvent; // signalled iff PowerState is D0
+ NDIS_STRING DeviceName; // used in NdisOpenAdapter
+ NDIS_STRING DeviceDescr; // friendly name
+
+ NDIS_STATUS BindStatus; // for Open/CloseAdapter
+ NPROT_EVENT BindEvent; // for Open/CloseAdapter
+
+ ULONG oc_sig; // Signature for sanity
+ NDISPROT_OPEN_STATE State;
+ PNPROT_EVENT ClosingEvent;
+ UCHAR CurrentAddress[NPROT_MAC_ADDR_LEN];
+ UCHAR MCastAddress[MAX_MULTICAST_ADDRESS][NPROT_MAC_ADDR_LEN];
+} NDISPROT_OPEN_CONTEXT, *PNDISPROT_OPEN_CONTEXT;
+
+
+#define oc_signature 'OiuN'
+
+//
+// Definitions for Flags above.
+//
+#define NPROTO_BIND_IDLE 0x00000000
+#define NPROTO_BIND_OPENING 0x00000001
+#define NPROTO_BIND_FAILED 0x00000002
+#define NPROTO_BIND_ACTIVE 0x00000004
+#define NPROTO_BIND_CLOSING 0x00000008
+#define NPROTO_BIND_FLAGS 0x0000000F // State of the binding
+
+#define NPROTO_OPEN_IDLE 0x00000000
+#define NPROTO_OPEN_ACTIVE 0x00000010
+#define NPROTO_OPEN_FLAGS 0x000000F0 // State of the I/O open
+
+#define NPROTO_RESET_IN_PROGRESS 0x00000100
+#define NPROTO_NOT_RESETTING 0x00000000
+#define NPROTO_RESET_FLAGS 0x00000100
+
+#define NPROTO_MEDIA_CONNECTED 0x00000000
+#define NPROTO_MEDIA_DISCONNECTED 0x00000200
+#define NPROTO_MEDIA_FLAGS 0x00000200
+
+#define NPROTO_READ_SERVICING 0x00100000 // Is the read service
+ // routine running?
+#define NPROTO_READ_FLAGS 0x00100000
+
+#define NPROTO_UNBIND_RECEIVED 0x10000000 // Seen NDIS Unbind?
+#define NPROTO_UNBIND_FLAGS 0x10000000
+
+
+#define NPROT_ALLOCATED_NBL 0x10000000
+#define NPROT_NBL_RETREAT_RECV_RSVD 0x20000000
+
+//
+// Globals:
+//
+typedef struct _NDISPROT_GLOBALS
+{
+ PDRIVER_OBJECT pDriverObject;
+ PDEVICE_OBJECT ControlDeviceObject;
+ NDIS_HANDLE NdisProtocolHandle;
+ USHORT EthType; // frame type we are interested in
+ UCHAR PartialCancelId; // for cancelling sends
+ ULONG LocalCancelId;
+ LIST_ENTRY OpenList; // of OPEN_CONTEXT structures
+ NPROT_LOCK GlobalLock; // to protect the above
+ NPROT_EVENT BindsComplete; // have we seen NetEventBindsComplete?
+} NDISPROT_GLOBALS, *PNDISPROT_GLOBALS;
+
+
+//
+// The following are arranged in the way a little-endian processor
+// would read 2 bytes off the wire.
+//
+#define NPROT_ETH_TYPE 0x8e88
+#define NPROT_8021P_TAG_TYPE 0x0081
+
+//
+// NDIS Request context structure
+//
+typedef struct _NDISPROT_REQUEST
+{
+ NDIS_OID_REQUEST Request;
+ NPROT_EVENT ReqEvent;
+ ULONG Status;
+
+} NDISPROT_REQUEST, *PNDISPROT_REQUEST;
+
+
+#define NPROTO_PACKET_FILTER (NDIS_PACKET_TYPE_DIRECTED| \
+ NDIS_PACKET_TYPE_MULTICAST| \
+ NDIS_PACKET_TYPE_BROADCAST)
+
+//
+// Send packet pool bounds
+//
+/*
+#define MIN_SEND_PACKET_POOL_SIZE 20
+*/
+#define MAX_SEND_PACKET_POOL_SIZE 400
+
+
+//
+// ProtocolReserved in sent packets. We save a pointer to the IRP
+// that generated the send.
+//
+// The RefCount is used to determine when to free the packet back
+// to its pool. It is used to synchronize between a thread completing
+// a send and a thread attempting to cancel a send.
+//
+typedef struct _NPROT_SEND_NETBUFLIST_RSVD
+{
+ PIRP pIrp;
+ ULONG RefCount;
+
+} NPROT_SEND_NETBUFLIST_RSVD, *PNPROT_SEND_NETBUFLIST_RSVD;
+//
+// Receive packet pool bounds
+//
+#define MIN_RECV_PACKET_POOL_SIZE 4
+#define MAX_RECV_PACKET_POOL_SIZE 20
+
+//
+// Max receive packets we allow to be queued up
+//
+#define MAX_RECV_QUEUE_SIZE 4
+
+//
+// ProtocolReserved in received packets: we link these
+// packets up in a queue waiting for Read IRPs.
+//
+typedef struct _NPROT_RECV_NBL_RSVD
+{
+ LIST_ENTRY Link;
+ PNET_BUFFER_LIST pNetBufferList; // used if we had to partial-map
+
+} NPROT_RECV_NBL_RSVD, *PNPROT_RECV_NBL_RSVD;
+
+
+#include <pshpack1.h>
+
+typedef struct _NDISPROT_ETH_HEADER
+{
+ UCHAR DstAddr[NPROT_MAC_ADDR_LEN];
+ UCHAR SrcAddr[NPROT_MAC_ADDR_LEN];
+ USHORT EthType;
+
+} NDISPROT_ETH_HEADER;
+
+typedef struct _NDISPROT_ETH_HEADER UNALIGNED * PNDISPROT_ETH_HEADER;
+
+#include <poppack.h>
+
+
+extern NDISPROT_GLOBALS Globals;
+
+
+#define NPROT_ALLOC_TAG 'oiuN'
+
+
+//
+// Prototypes.
+//
+
+DRIVER_INITIALIZE DriverEntry;
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT pDriverObject,
+ IN PUNICODE_STRING pRegistryPath
+ );
+
+DRIVER_UNLOAD NdisprotUnload;
+VOID
+NdisprotUnload(
+ IN PDRIVER_OBJECT pDriverObject
+ );
+
+_Dispatch_type_(IRP_MJ_CREATE) DRIVER_DISPATCH NdisprotOpen;
+
+NTSTATUS
+NdisprotOpen(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ );
+
+_Dispatch_type_(IRP_MJ_CLOSE) DRIVER_DISPATCH NdisprotClose;
+NTSTATUS
+NdisprotClose(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ );
+
+_Dispatch_type_(IRP_MJ_CLEANUP) DRIVER_DISPATCH NdisprotCleanup;
+NTSTATUS
+NdisprotCleanup(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ );
+
+_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) DRIVER_DISPATCH NdisprotIoControl;
+_Function_class_(DRIVER_DISPATCH)
+_IRQL_requires_(PASSIVE_LEVEL)
+_IRQL_requires_same_
+NTSTATUS
+NdisprotIoControl(
+ _In_ IN PDEVICE_OBJECT pDeviceObject,
+ _Inout_ IN PIRP pIrp
+ );
+
+NTSTATUS
+ndisprotOpenDevice(
+ _In_reads_bytes_(DeviceNameLength) IN PUCHAR pDeviceName,
+ IN ULONG DeviceNameLength,
+ IN PFILE_OBJECT pFileObject,
+ OUT PNDISPROT_OPEN_CONTEXT * ppOpenContext
+ );
+
+VOID
+ndisprotRefOpen(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ );
+
+VOID
+ndisprotDerefOpen(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ );
+
+#if DBG
+VOID
+ndisprotDbgRefOpen(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+ );
+
+VOID
+ndisprotDbgDerefOpen(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+ );
+#endif // DBG
+
+PROTOCOL_BIND_ADAPTER_EX NdisprotBindAdapter;
+
+PROTOCOL_OPEN_ADAPTER_COMPLETE_EX NdisprotOpenAdapterComplete;
+
+PROTOCOL_UNBIND_ADAPTER_EX NdisprotUnbindAdapter;
+
+PROTOCOL_CLOSE_ADAPTER_COMPLETE_EX NdisprotCloseAdapterComplete;
+
+
+PROTOCOL_NET_PNP_EVENT NdisprotPnPEventHandler;
+
+VOID
+NdisprotProtocolUnloadHandler(
+ VOID
+ );
+
+NDIS_STATUS
+ndisprotCreateBinding(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN PNDIS_BIND_PARAMETERS BindParameters,
+ IN NDIS_HANDLE BindContext,
+ _In_reads_bytes_(BindingInfoLength) IN PUCHAR pBindingInfo,
+ IN ULONG BindingInfoLength
+ );
+
+VOID
+ndisprotShutdownBinding(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ );
+
+VOID
+ndisprotFreeBindResources(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ );
+
+VOID
+ndisprotWaitForPendingIO(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN BOOLEAN DoCancelReads
+ );
+
+VOID
+ndisprotDoProtocolUnload(
+ VOID
+ );
+
+NDIS_STATUS
+ndisprotDoRequest(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN NDIS_PORT_NUMBER PortNumber,
+ IN NDIS_REQUEST_TYPE RequestType,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG pBytesProcessed
+ );
+
+NDIS_STATUS
+ndisprotValidateOpenAndDoRequest(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN NDIS_REQUEST_TYPE RequestType,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG pBytesProcessed,
+ IN BOOLEAN bWaitForPowerOn
+ );
+
+PROTOCOL_OID_REQUEST_COMPLETE NdisprotRequestComplete;
+
+PROTOCOL_STATUS_EX NdisprotStatus;
+
+NDIS_STATUS
+ndisprotQueryBinding(
+ _Inout_updates_bytes_to_(OutputLength, *pBytesReturned)
+ PUCHAR pBuffer,
+ _In_ ULONG InputLength,
+ _In_ ULONG OutputLength,
+ _Out_ PULONG pBytesReturned
+ );
+
+PNDISPROT_OPEN_CONTEXT
+ndisprotLookupDevice(
+ _In_reads_bytes_(BindingInfoLength) IN PUCHAR pBindingInfo,
+ IN ULONG BindingInfoLength
+ );
+
+NDIS_STATUS
+ndisprotQueryOidValue(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ OUT PVOID pDataBuffer,
+ IN ULONG BufferLength,
+ OUT PULONG pBytesWritten
+ );
+
+NDIS_STATUS
+ndisprotSetOidValue(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ OUT PVOID pDataBuffer,
+ IN ULONG BufferLength
+ );
+
+BOOLEAN
+ndisprotValidOid(
+ IN NDIS_OID Oid
+ );
+
+_Dispatch_type_(IRP_MJ_READ) DRIVER_DISPATCH NdisprotRead;
+NTSTATUS
+NdisprotRead(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ );
+
+DRIVER_CANCEL NdisprotCancelRead;
+VOID
+NdisprotCancelRead(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ );
+
+VOID
+ndisprotServiceReads(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ );
+
+PROTOCOL_RECEIVE_NET_BUFFER_LISTS NdisprotReceiveNetBufferLists;
+
+VOID
+ndisprotQueueReceiveNetBufferList(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN PNET_BUFFER_LIST pRcvNetBufList,
+ BOOLEAN DispatchLevel
+ );
+
+_Success_(return != 0)
+PNET_BUFFER_LIST
+ndisprotAllocateReceiveNetBufferList(
+ _In_ PNDISPROT_OPEN_CONTEXT pOpenContext,
+ _In_ UINT DataLength,
+ _Outptr_result_bytebuffer_(DataLength)
+ PUCHAR * ppDataBuffer
+ );
+
+VOID
+ndisprotFreeReceiveNetBufferList(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN PNET_BUFFER_LIST pNetBufferList,
+ IN BOOLEAN DispatchLevel
+ );
+
+VOID
+ndisprotCancelPendingReads(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ );
+
+VOID
+ndisprotFlushReceiveQueue(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ );
+
+_Dispatch_type_(IRP_MJ_WRITE) DRIVER_DISPATCH NdisprotWrite;
+NTSTATUS
+NdisprotWrite(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ );
+
+DRIVER_CANCEL NdisprotCancelWrite;
+VOID
+NdisprotCancelWrite(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ );
+
+PROTOCOL_SEND_NET_BUFFER_LISTS_COMPLETE NdisprotSendComplete;
+
+VOID
+ndisprotRestart(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN PNDIS_PROTOCOL_RESTART_PARAMETERS RestartParameters
+ );
+
+#endif // __NDISPROT__H
+
+
diff --git a/network/ndis/ndisprot/6x/sys/ntdisp.c b/network/ndis/ndisprot/6x/sys/ntdisp.c
new file mode 100644
index 00000000..21ceeaeb
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/ntdisp.c
@@ -0,0 +1,916 @@
+/*++
+
+Copyright (c) 2000 Microsoft Corporation
+
+Module Name:
+
+ ntdisp.c
+
+Abstract:
+
+ NT Entry points and dispatch routines for NDISPROT.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "precomp.h"
+
+#define __FILENUMBER 'PSID'
+
+
+#ifdef ALLOC_PRAGMA
+
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(PAGE, NdisprotUnload)
+#pragma alloc_text(PAGE, NdisprotOpen)
+#pragma alloc_text(PAGE, NdisprotClose)
+#pragma alloc_text(PAGE, NdisprotIoControl)
+
+#endif // ALLOC_PRAGMA
+
+
+//
+// Globals:
+//
+NDISPROT_GLOBALS Globals = {0};
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT pDriverObject,
+ IN PUNICODE_STRING pRegistryPath
+ )
+/*++
+
+Routine Description:
+
+ Called on loading. We create a device object to handle user-mode requests
+ on, and register ourselves as a protocol with NDIS.
+
+Arguments:
+
+ pDriverObject - Pointer to driver object created by system.
+
+ pRegistryPath - Pointer to the Unicode name of the registry path
+ for this driver.
+
+Return Value:
+
+ NT Status code
+
+--*/
+{
+ NDIS_PROTOCOL_DRIVER_CHARACTERISTICS protocolChar = {0};
+ NTSTATUS status = STATUS_SUCCESS;
+ NDIS_STRING protoName = NDIS_STRING_CONST("NDISPROT");
+ UNICODE_STRING ntDeviceName;
+ UNICODE_STRING win32DeviceName;
+ BOOLEAN fSymbolicLink = FALSE;
+ PDEVICE_OBJECT deviceObject = NULL;
+ NDIS_HANDLE ProtocolDriverContext={0};
+
+ UNREFERENCED_PARAMETER(pRegistryPath);
+
+ DEBUGP(DL_LOUD, ("DriverEntry\n"));
+
+ Globals.pDriverObject = pDriverObject;
+ Globals.EthType = NPROT_ETH_TYPE;
+ NPROT_INIT_EVENT(&Globals.BindsComplete);
+
+ do
+ {
+ //
+ // Create our device object using which an application can
+ // access NDIS devices.
+ //
+ RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
+
+ status = IoCreateDevice (pDriverObject,
+ 0,
+ &ntDeviceName,
+ FILE_DEVICE_NETWORK,
+ FILE_DEVICE_SECURE_OPEN,
+ FALSE,
+ &deviceObject);
+
+ if (!NT_SUCCESS (status))
+ {
+ //
+ // Either not enough memory to create a deviceobject or another
+ // deviceobject with the same name exits. This could happen
+ // if you install another instance of this device.
+ //
+ break;
+ }
+
+ RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
+
+ status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);
+
+ if (!NT_SUCCESS(status))
+ {
+ break;
+ }
+
+ fSymbolicLink = TRUE;
+
+ deviceObject->Flags |= DO_DIRECT_IO;
+ Globals.ControlDeviceObject = deviceObject;
+
+ NPROT_INIT_LIST_HEAD(&Globals.OpenList);
+ NPROT_INIT_LOCK(&Globals.GlobalLock);
+
+ //
+ // Initialize the protocol characterstic structure
+ //
+#if (NDIS_SUPPORT_NDIS630)
+ {C_ASSERT(sizeof(protocolChar) >= NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2);}
+ protocolChar.Header.Type = NDIS_OBJECT_TYPE_PROTOCOL_DRIVER_CHARACTERISTICS,
+ protocolChar.Header.Size = NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2;
+ protocolChar.Header.Revision = NDIS_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2;
+#elif (NDIS_SUPPORT_NDIS6)
+ {C_ASSERT(sizeof(protocolChar) >= NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1);}
+ protocolChar.Header.Type = NDIS_OBJECT_TYPE_PROTOCOL_DRIVER_CHARACTERISTICS,
+ protocolChar.Header.Size = NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1;
+ protocolChar.Header.Revision = NDIS_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1;
+#endif // NDIS MINIPORT VERSION
+
+ protocolChar.MajorNdisVersion = NDIS_PROT_MAJOR_VERSION;
+ protocolChar.MinorNdisVersion = NDIS_PROT_MINOR_VERSION;
+ protocolChar.MajorDriverVersion = MAJOR_DRIVER_VERSION;
+ protocolChar.MinorDriverVersion = MINOR_DRIVER_VERISON;
+ protocolChar.Name = protoName;
+ protocolChar.SetOptionsHandler = NULL;
+ protocolChar.OpenAdapterCompleteHandlerEx = NdisprotOpenAdapterComplete;
+ protocolChar.CloseAdapterCompleteHandlerEx = NdisprotCloseAdapterComplete;
+ protocolChar.SendNetBufferListsCompleteHandler = NdisprotSendComplete;
+ protocolChar.OidRequestCompleteHandler = NdisprotRequestComplete;
+ protocolChar.StatusHandlerEx = NdisprotStatus;
+ protocolChar.UninstallHandler = NULL;
+ protocolChar.ReceiveNetBufferListsHandler = NdisprotReceiveNetBufferLists;
+ protocolChar.NetPnPEventHandler = NdisprotPnPEventHandler;
+ protocolChar.BindAdapterHandlerEx = NdisprotBindAdapter;
+ protocolChar.UnbindAdapterHandlerEx = NdisprotUnbindAdapter;
+
+ //
+ // Register as a protocol driver
+ //
+
+ status = NdisRegisterProtocolDriver(ProtocolDriverContext, // driver context
+ &protocolChar,
+ &Globals.NdisProtocolHandle);
+
+ if (status != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n"));
+ status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ Globals.PartialCancelId = NdisGeneratePartialCancelId();
+ Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
+ DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId));
+
+ //
+ // Now set only the dispatch points we would like to handle.
+ //
+
+ pDriverObject->MajorFunction[IRP_MJ_CREATE] = NdisprotOpen;
+
+ pDriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisprotClose;
+
+ pDriverObject->MajorFunction[IRP_MJ_READ] = NdisprotRead;
+
+ pDriverObject->MajorFunction[IRP_MJ_WRITE] = NdisprotWrite;
+
+ pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = NdisprotCleanup;
+
+ pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NdisprotIoControl;
+
+
+ pDriverObject->DriverUnload = NdisprotUnload;
+
+ status = STATUS_SUCCESS;
+
+
+ }
+ while (FALSE);
+
+
+ if (!NT_SUCCESS(status))
+ {
+ if (deviceObject)
+ {
+ KeEnterCriticalRegion();
+ IoDeleteDevice(deviceObject);
+ KeLeaveCriticalRegion();
+ Globals.ControlDeviceObject = NULL;
+ }
+
+ if (fSymbolicLink)
+ {
+ IoDeleteSymbolicLink(&win32DeviceName);
+ fSymbolicLink = FALSE;
+ }
+
+ if (Globals.NdisProtocolHandle)
+ {
+ NdisDeregisterProtocolDriver(Globals.NdisProtocolHandle);
+ Globals.NdisProtocolHandle = NULL;
+ }
+ }
+
+ return status;
+}
+
+
+VOID
+NdisprotUnload(
+ IN PDRIVER_OBJECT DriverObject
+ )
+/*++
+
+Routine Description:
+
+ Free all the allocated resources, etc.
+
+Arguments:
+
+ DriverObject - pointer to a driver object.
+
+Return Value:
+
+ VOID.
+
+--*/
+{
+
+ UNICODE_STRING win32DeviceName;
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ DEBUGP(DL_LOUD, ("Unload Enter\n"));
+
+ //
+ // First delete the Control deviceobject and the corresponding
+ // symbolicLink
+ //
+ RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
+
+ IoDeleteSymbolicLink(&win32DeviceName);
+
+
+ if (Globals.ControlDeviceObject)
+ {
+ IoDeleteDevice(Globals.ControlDeviceObject);
+ Globals.ControlDeviceObject = NULL;
+ }
+
+
+ ndisprotDoProtocolUnload();
+
+#if DBG
+ ndisprotAuditShutdown();
+#endif
+
+ DEBUGP(DL_LOUD, ("Unload Exit\n"));
+}
+
+
+
+NTSTATUS
+NdisprotOpen(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ )
+/*++
+
+Routine Description:
+
+ This is the dispatch routine for handling IRP_MJ_CREATE.
+ We simply succeed this.
+
+Arguments:
+
+ pDeviceObject - Pointer to the device object.
+
+ pIrp - Pointer to the request packet.
+
+Return Value:
+
+ Status is returned.
+
+--*/
+{
+ PIO_STACK_LOCATION pIrpSp;
+ NTSTATUS NtStatus = STATUS_SUCCESS;
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(pDeviceObject);
+
+ pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
+ pIrpSp->FileObject->FsContext = NULL;
+
+ DEBUGP(DL_INFO, ("Open: FileObject %p\n", pIrpSp->FileObject));
+
+ pIrp->IoStatus.Information = 0;
+ pIrp->IoStatus.Status = NtStatus;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ return NtStatus;
+}
+
+NTSTATUS
+NdisprotClose(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ )
+/*++
+
+Routine Description:
+
+ This is the dispatch routine for handling IRP_MJ_CLOSE.
+ We simply succeed this.
+
+Arguments:
+
+ pDeviceObject - Pointer to the device object.
+
+ pIrp - Pointer to the request packet.
+
+Return Value:
+
+ Status is returned.
+
+--*/
+{
+ NTSTATUS NtStatus;
+ PIO_STACK_LOCATION pIrpSp;
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(pDeviceObject);
+
+ pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
+ pOpenContext = pIrpSp->FileObject->FsContext;
+
+ DEBUGP(DL_INFO, ("Close: FileObject %p\n",
+ IoGetCurrentIrpStackLocation(pIrp)->FileObject));
+
+ if (pOpenContext != NULL)
+ {
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ //
+ // Deref the endpoint
+ //
+ NPROT_DEREF_OPEN(pOpenContext); // Close
+ }
+
+ pIrpSp->FileObject->FsContext = NULL;
+ NtStatus = STATUS_SUCCESS;
+ pIrp->IoStatus.Information = 0;
+ pIrp->IoStatus.Status = NtStatus;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ return NtStatus;
+}
+
+
+
+NTSTATUS
+NdisprotCleanup(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ )
+/*++
+
+Routine Description:
+
+ This is the dispatch routine for handling IRP_MJ_CLEANUP.
+
+Arguments:
+
+ pDeviceObject - Pointer to the device object.
+
+ pIrp - Pointer to the request packet.
+
+Return Value:
+
+ Status is returned.
+
+--*/
+{
+ PIO_STACK_LOCATION pIrpSp;
+ NTSTATUS NtStatus;
+ NDIS_STATUS NdisStatus;
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ ULONG PacketFilter;
+ ULONG BytesProcessed;
+
+
+ UNREFERENCED_PARAMETER(pDeviceObject);
+
+ pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
+ pOpenContext = pIrpSp->FileObject->FsContext;
+
+ DEBUGP(DL_VERY_LOUD, ("Cleanup: FileObject %p, Open %p\n",
+ pIrpSp->FileObject, pOpenContext));
+
+ if (pOpenContext != NULL)
+ {
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ //
+ // Set the packet filter to 0, telling NDIS that we aren't
+ // interested in any more receives.
+ //
+ PacketFilter = 0;
+ NdisStatus = ndisprotValidateOpenAndDoRequest(
+ pOpenContext,
+ NdisRequestSetInformation,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ &PacketFilter,
+ sizeof(PacketFilter),
+ &BytesProcessed,
+ FALSE // Don't wait for device to be powered on
+ );
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGP(DL_INFO, ("Cleanup: Open %p, set packet filter (%x) failed: %x\n",
+ pOpenContext, PacketFilter, NdisStatus));
+ //
+ // Ignore the result. If this failed, we may continue
+ // to get indicated receives, which will be handled
+ // appropriately.
+ //
+ NdisStatus = NDIS_STATUS_SUCCESS;
+ }
+
+ //
+ // Mark this endpoint.
+ //
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_OPEN_FLAGS, NPROTO_OPEN_IDLE);
+ pOpenContext->pFileObject = NULL;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Cancel any pending reads.
+ //
+ ndisprotCancelPendingReads(pOpenContext);
+ //
+ // Clean up the receive packet queue
+ //
+ ndisprotFlushReceiveQueue(pOpenContext);
+ }
+
+ NtStatus = STATUS_SUCCESS;
+
+ pIrp->IoStatus.Information = 0;
+ pIrp->IoStatus.Status = NtStatus;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ DEBUGP(DL_INFO, ("Cleanup: OpenContext %p\n", pOpenContext));
+
+ return (NtStatus);
+}
+
+NTSTATUS
+NdisprotIoControl(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ )
+/*++
+
+Routine Description:
+
+ This is the dispatch routine for handling device ioctl requests.
+
+Arguments:
+
+ pDeviceObject - Pointer to the device object.
+
+ pIrp - Pointer to the request packet.
+
+Return Value:
+
+ Status is returned.
+
+--*/
+{
+ PIO_STACK_LOCATION pIrpSp;
+ ULONG FunctionCode;
+ NTSTATUS NtStatus;
+ NDIS_STATUS Status;
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ ULONG BytesReturned;
+#if !DBG
+ UNREFERENCED_PARAMETER(pDeviceObject);
+#endif
+ PAGED_CODE();
+ DEBUGP(DL_LOUD, ("IoControl: DevObj %p, Irp %p\n", pDeviceObject, pIrp));
+
+ pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
+
+ FunctionCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode;
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)pIrpSp->FileObject->FsContext;
+ BytesReturned = 0;
+
+ switch (FunctionCode)
+ {
+ case IOCTL_NDISPROT_BIND_WAIT:
+ //
+ // Block until we have seen a NetEventBindsComplete event,
+ // meaning that we have finished binding to all running
+ // adapters that we are supposed to bind to.
+ //
+ // If we don't get this event in 5 seconds, time out.
+ //
+ NPROT_ASSERT((FunctionCode & 0x3) == METHOD_BUFFERED);
+
+ if (NPROT_WAIT_EVENT(&Globals.BindsComplete, 5000))
+ {
+ NtStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ NtStatus = STATUS_TIMEOUT;
+ }
+ DEBUGP(DL_INFO, ("IoControl: BindWait returning %x\n", NtStatus));
+ break;
+
+ case IOCTL_NDISPROT_QUERY_BINDING:
+
+ NPROT_ASSERT((FunctionCode & 0x3) == METHOD_BUFFERED);
+
+ Status = ndisprotQueryBinding(
+ pIrp->AssociatedIrp.SystemBuffer,
+ pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
+ pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
+ &BytesReturned
+ );
+
+ NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
+
+ DEBUGP(DL_LOUD, ("IoControl: QueryBinding returning %x\n", NtStatus));
+
+ break;
+
+ case IOCTL_NDISPROT_OPEN_DEVICE:
+
+ NPROT_ASSERT((FunctionCode & 0x3) == METHOD_BUFFERED);
+ if (pOpenContext != NULL)
+ {
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+ DEBUGP(DL_WARN, ("IoControl: OPEN_DEVICE: FileObj %p already"
+ " associated with open %p\n", pIrpSp->FileObject, pOpenContext));
+
+ NtStatus = STATUS_DEVICE_BUSY;
+ break;
+ }
+
+ NtStatus = ndisprotOpenDevice(
+ pIrp->AssociatedIrp.SystemBuffer,
+ pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
+ pIrpSp->FileObject,
+ &pOpenContext
+ );
+
+ if (NT_SUCCESS(NtStatus))
+ {
+
+ DEBUGP(DL_VERY_LOUD, ("IoControl OPEN_DEVICE: Open %p <-> FileObject %p\n",
+ pOpenContext, pIrpSp->FileObject));
+
+ }
+ else
+ {
+ DEBUGP(DL_INFO, ("NdisprotIoControl: IOCTL_NDISPROT_OPEN_DEVICE, ndisprotOpenDevice failed %lx\n", NtStatus));
+ }
+
+ break;
+
+ case IOCTL_NDISPROT_QUERY_OID_VALUE:
+
+ NPROT_ASSERT((FunctionCode & 0x3) == METHOD_BUFFERED);
+ if (pOpenContext != NULL)
+ {
+ Status = ndisprotQueryOidValue(
+ pOpenContext,
+ pIrp->AssociatedIrp.SystemBuffer,
+ pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
+ &BytesReturned
+ );
+
+ NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
+ }
+ else
+ {
+ NtStatus = STATUS_DEVICE_NOT_CONNECTED;
+ }
+ break;
+
+ case IOCTL_NDISPROT_SET_OID_VALUE:
+
+ NPROT_ASSERT((FunctionCode & 0x3) == METHOD_BUFFERED);
+ if (pOpenContext != NULL)
+ {
+ Status = ndisprotSetOidValue(
+ pOpenContext,
+ pIrp->AssociatedIrp.SystemBuffer,
+ pIrpSp->Parameters.DeviceIoControl.InputBufferLength
+ );
+
+ BytesReturned = 0;
+
+ NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
+ }
+ else
+ {
+ NtStatus = STATUS_DEVICE_NOT_CONNECTED;
+ }
+ break;
+
+ default:
+
+ NtStatus = STATUS_NOT_SUPPORTED;
+ break;
+ }
+
+ if (NtStatus != STATUS_PENDING)
+ {
+ pIrp->IoStatus.Information = BytesReturned;
+ pIrp->IoStatus.Status = NtStatus;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ }
+
+ return NtStatus;
+}
+
+
+
+NTSTATUS
+ndisprotOpenDevice(
+ _In_reads_bytes_(DeviceNameLength) IN PUCHAR pDeviceName,
+ IN ULONG DeviceNameLength,
+ IN PFILE_OBJECT pFileObject,
+ OUT PNDISPROT_OPEN_CONTEXT * ppOpenContext
+ )
+/*++
+
+Routine Description:
+
+ Helper routine called to process IOCTL_NDISPROT_OPEN_DEVICE. Check if
+ there is a binding to the specified device, and is not associated with
+ a file object already. If so, make an association between the binding
+ and this file object.
+
+Arguments:
+
+ pDeviceName - pointer to device name string
+ DeviceNameLength - length of above
+ pFileObject - pointer to file object being associated with the device binding
+
+Return Value:
+
+ Status is returned.
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ NTSTATUS NtStatus;
+ ULONG PacketFilter;
+ NDIS_STATUS NdisStatus;
+ ULONG BytesProcessed;
+ PNDISPROT_OPEN_CONTEXT pCurrentOpenContext = NULL;
+
+ pOpenContext = NULL;
+
+ do
+ {
+ pOpenContext = ndisprotLookupDevice(
+ pDeviceName,
+ DeviceNameLength
+ );
+
+ if (pOpenContext == NULL)
+ {
+ DEBUGP(DL_WARN, ("ndisprotOpenDevice: couldn't find device\n"));
+ NtStatus = STATUS_OBJECT_NAME_NOT_FOUND;
+ break;
+ }
+
+ //
+ // else ndisprotLookupDevice would have addref'ed the open.
+ //
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_OPEN_FLAGS, NPROTO_OPEN_IDLE))
+ {
+ NPROT_ASSERT(pOpenContext->pFileObject != NULL);
+
+ DEBUGP(DL_WARN, ("ndisprotOpenDevice: Open %p/%x already associated"
+ " with another FileObject %p\n",
+ pOpenContext, pOpenContext->Flags, pOpenContext->pFileObject));
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_DEREF_OPEN(pOpenContext); // ndisprotOpenDevice failure
+ NtStatus = STATUS_DEVICE_BUSY;
+ break;
+ }
+ //
+ // This InterlockedXXX function performs an atomic operation: First it compare
+ // pFileObject->FsContext with NULL, if they are equal, the function puts pOpenContext
+ // into FsContext, and return NULL. Otherwise, it return pFileObject->FsContext without
+ // changing anything.
+ //
+
+ if ((pCurrentOpenContext = InterlockedCompareExchangePointer (& (pFileObject->FsContext), pOpenContext, NULL)) != NULL)
+ {
+ //
+ // pFileObject->FsContext already is used by other open
+ //
+ DEBUGP(DL_WARN, ("ndisprotOpenDevice: FileObject %p already associated"
+ " with another Open %p/%x\n",
+ pFileObject, pCurrentOpenContext, pCurrentOpenContext->Flags)); //BUG
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_DEREF_OPEN(pOpenContext); // ndisprotOpenDevice failure
+ NtStatus = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ pOpenContext->pFileObject = pFileObject;
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_OPEN_FLAGS, NPROTO_OPEN_ACTIVE);
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Set the packet filter now.
+ //
+ PacketFilter = NPROTO_PACKET_FILTER;
+ NdisStatus = ndisprotValidateOpenAndDoRequest(
+ pOpenContext,
+ NdisRequestSetInformation,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ &PacketFilter,
+ sizeof(PacketFilter),
+ &BytesProcessed,
+ TRUE // Do wait for power on
+ );
+
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGP(DL_WARN, ("openDevice: Open %p: set packet filter (%x) failed: %x\n",
+ pOpenContext, PacketFilter, NdisStatus));
+
+ //
+ // Undo all that we did above.
+ //
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+ //
+ // Need to set pFileObject->FsContext to NULL again, so others can open a device
+ // for this file object later
+ //
+ pCurrentOpenContext = InterlockedCompareExchangePointer (& (pFileObject->FsContext), NULL, pOpenContext);
+
+
+ NPROT_ASSERT(pCurrentOpenContext == pOpenContext);
+
+ NPROT_SET_FLAGS(pOpenContext->Flags, NPROTO_OPEN_FLAGS, NPROTO_OPEN_IDLE);
+ pOpenContext->pFileObject = NULL;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_DEREF_OPEN(pOpenContext); // ndisprotOpenDevice failure
+
+ NDIS_STATUS_TO_NT_STATUS(NdisStatus, &NtStatus);
+ break;
+ }
+
+ *ppOpenContext = pOpenContext;
+
+ NtStatus = STATUS_SUCCESS;
+ }
+ while (FALSE);
+
+ return (NtStatus);
+}
+
+
+VOID
+ndisprotRefOpen(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ )
+/*++
+
+Routine Description:
+
+ Reference the given open context.
+
+ NOTE: Can be called with or without holding the opencontext lock.
+
+Arguments:
+
+ pOpenContext - pointer to open context
+
+Return Value:
+
+ None
+
+--*/
+{
+ NdisInterlockedIncrement((PLONG)&pOpenContext->RefCount);
+}
+
+
+VOID
+ndisprotDerefOpen(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ )
+/*++
+
+Routine Description:
+
+ Dereference the given open context. If the ref count goes to zero,
+ free it.
+
+ NOTE: called without holding the opencontext lock
+
+Arguments:
+
+ pOpenContext - pointer to open context
+
+Return Value:
+
+ None
+
+--*/
+{
+ if (NdisInterlockedDecrement((PLONG)&pOpenContext->RefCount) == 0)
+ {
+ DEBUGP(DL_INFO, ("DerefOpen: Open %p, Flags %x, ref count is zero!\n",
+ pOpenContext, pOpenContext->Flags));
+
+ NPROT_ASSERT(pOpenContext->BindingHandle == NULL);
+ NPROT_ASSERT(pOpenContext->RefCount == 0);
+ NPROT_ASSERT(pOpenContext->pFileObject == NULL);
+
+ pOpenContext->oc_sig++;
+
+ //
+ // Free it.
+ //
+ NPROT_FREE_MEM(pOpenContext);
+ }
+}
+
+#if DBG
+VOID
+ndisprotDbgRefOpen(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+ )
+{
+ DEBUGP(DL_VERY_LOUD, (" RefOpen: Open %p, old ref %d, File %c%c%c%c, line %d\n",
+ pOpenContext,
+ pOpenContext->RefCount,
+ (CHAR)(FileNumber),
+ (CHAR)(FileNumber >> 8),
+ (CHAR)(FileNumber >> 16),
+ (CHAR)(FileNumber >> 24),
+ LineNumber));
+
+ ndisprotRefOpen(pOpenContext);
+}
+
+VOID
+ndisprotDbgDerefOpen(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN ULONG FileNumber,
+ IN ULONG LineNumber
+ )
+{
+ DEBUGP(DL_VERY_LOUD, ("DerefOpen: Open %p, old ref %d, File %c%c%c%c, line %d\n",
+ pOpenContext,
+ pOpenContext->RefCount,
+ (CHAR)(FileNumber),
+ (CHAR)(FileNumber >> 8),
+ (CHAR)(FileNumber >> 16),
+ (CHAR)(FileNumber >> 24),
+ LineNumber));
+
+ ndisprotDerefOpen(pOpenContext);
+}
+
+#endif // DBG
+
diff --git a/network/ndis/ndisprot/6x/sys/precomp.h b/network/ndis/ndisprot/6x/sys/precomp.h
new file mode 100644
index 00000000..1e9c0b78
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/precomp.h
@@ -0,0 +1,18 @@
+#pragma warning(disable:4214) // bit field types other than int
+
+#pragma warning(disable:4201) // nameless struct/union
+#pragma warning(disable:4115) // named type definition in parentheses
+#pragma warning(disable:4127) // conditional expression is constant
+#pragma warning(disable:4054) // cast of function pointer to PVOID
+#pragma warning(disable:4244) // conversion from 'int' to 'BOOLEAN', possible loss of data
+#pragma warning(disable:4206) // nonstandard extension used : translation unit is empty
+
+#include "ndis.h"
+#include "ntddk.h"
+#include <wmistr.h>
+#include <wdmsec.h>
+#include <wdmguid.h>
+#include "debug.h"
+#include "ndisprot.h"
+#include "macros.h"
+#include "protuser.h"
diff --git a/network/ndis/ndisprot/6x/sys/protuser.h b/network/ndis/ndisprot/6x/sys/protuser.h
new file mode 100644
index 00000000..823d1ef5
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/protuser.h
@@ -0,0 +1,92 @@
+/*++
+
+Copyright (c) 2000 Microsoft Corporation
+
+Module Name:
+
+ nuiouser.h
+
+Abstract:
+
+ Constants and types to access the NDISPROT driver.
+ Users must also include ntddndis.h
+
+Environment:
+
+ User/Kernel mode.
+
+Revision History:
+
+--*/
+
+#ifndef __NPROTUSER__H
+#define __NPROTUSER__H
+
+
+#define FSCTL_NDISPROT_BASE FILE_DEVICE_NETWORK
+
+#define _NDISPROT_CTL_CODE(_Function, _Method, _Access) \
+ CTL_CODE(FSCTL_NDISPROT_BASE, _Function, _Method, _Access)
+
+#define IOCTL_NDISPROT_OPEN_DEVICE \
+ _NDISPROT_CTL_CODE(0x200, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_NDISPROT_QUERY_OID_VALUE \
+ _NDISPROT_CTL_CODE(0x201, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_NDISPROT_SET_OID_VALUE \
+ _NDISPROT_CTL_CODE(0x205, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_NDISPROT_QUERY_BINDING \
+ _NDISPROT_CTL_CODE(0x203, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_NDISPROT_BIND_WAIT \
+ _NDISPROT_CTL_CODE(0x204, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+
+
+
+//
+// Structure to go with IOCTL_NDISPROT_QUERY_OID_VALUE.
+// The Data part is of variable length, determined by
+// the input buffer length passed to DeviceIoControl.
+//
+typedef struct _NDISPROT_QUERY_OID
+{
+ NDIS_OID Oid;
+ NDIS_PORT_NUMBER PortNumber;
+ UCHAR Data[sizeof(ULONG)];
+} NDISPROT_QUERY_OID, *PNDISPROT_QUERY_OID;
+
+//
+// Structure to go with IOCTL_NDISPROT_SET_OID_VALUE.
+// The Data part is of variable length, determined
+// by the input buffer length passed to DeviceIoControl.
+//
+typedef struct _NDISPROT_SET_OID
+{
+ NDIS_OID Oid;
+ NDIS_PORT_NUMBER PortNumber;
+ UCHAR Data[sizeof(ULONG)];
+} NDISPROT_SET_OID, *PNDISPROT_SET_OID;
+
+
+//
+// Structure to go with IOCTL_NDISPROT_QUERY_BINDING.
+// The input parameter is BindingIndex, which is the
+// index into the list of bindings active at the driver.
+// On successful completion, we get back a device name
+// and a device descriptor (friendly name).
+//
+typedef struct _NDISPROT_QUERY_BINDING
+{
+ ULONG BindingIndex; // 0-based binding number
+ ULONG DeviceNameOffset; // from start of this struct
+ ULONG DeviceNameLength; // in bytes
+ ULONG DeviceDescrOffset; // from start of this struct
+ ULONG DeviceDescrLength; // in bytes
+
+} NDISPROT_QUERY_BINDING, *PNDISPROT_QUERY_BINDING;
+
+#endif // __NPROTUSER__H
+
diff --git a/network/ndis/ndisprot/6x/sys/recv.c b/network/ndis/ndisprot/6x/sys/recv.c
new file mode 100644
index 00000000..71c867f1
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/recv.c
@@ -0,0 +1,1119 @@
+/*++
+
+Copyright (c) 2000 Microsoft Corporation
+
+Module Name:
+
+ recv.c
+
+Abstract:
+
+ NDIS protocol entry points and utility routines to handle receiving
+ data.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "precomp.h"
+
+#define __FILENUMBER 'VCER'
+
+
+
+NTSTATUS
+NdisprotRead(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ )
+/*++
+
+Routine Description:
+
+ Dispatch routine to handle IRP_MJ_READ.
+
+Arguments:
+
+ pDeviceObject - pointer to our device object
+ pIrp - Pointer to request packet
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PIO_STACK_LOCATION pIrpSp;
+ NTSTATUS NtStatus;
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+
+ UNREFERENCED_PARAMETER(pDeviceObject);
+
+ pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
+ pOpenContext = pIrpSp->FileObject->FsContext;
+
+ do
+ {
+ //
+ // Validate!
+ //
+ if (pOpenContext == NULL)
+ {
+ DEBUGP(DL_FATAL, ("Read: NULL FsContext on FileObject %p\n",
+ pIrpSp->FileObject));
+ NtStatus = STATUS_INVALID_HANDLE;
+ break;
+ }
+
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ if (pIrp->MdlAddress == NULL)
+ {
+ DEBUGP(DL_FATAL, ("Read: NULL MDL address on IRP %p\n", pIrp));
+ NtStatus = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Try to get a virtual address for the MDL.
+ //
+ if (MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority) == NULL)
+ {
+ DEBUGP(DL_FATAL, ("Read: MmGetSystemAddr failed for IRP %p, MDL %p\n",
+ pIrp, pIrp->MdlAddress));
+ NtStatus = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE))
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ NtStatus = STATUS_INVALID_HANDLE;
+ break;
+ }
+
+ IoSetCancelRoutine(pIrp, NdisprotCancelRead);
+
+ if (pIrp->Cancel &&
+ IoSetCancelRoutine(pIrp, NULL))
+ {
+
+ //
+ // IRP has been canceled but the I/O manager did not manage to call our cancel routine. This
+ // code is safe referencing the Irp->Cancel field without locks because of the memory barriers
+ // in the interlocked exchange sequences used by IoSetCancelRoutine.
+ //
+
+ NtStatus = STATUS_CANCELLED;
+
+ // IRP should be completed after releasing the lock
+
+ }
+ else
+ {
+
+ //
+ // Add this IRP to the list of pended Read IRPs
+ //
+ NPROT_INSERT_TAIL_LIST(&pOpenContext->PendedReads, &pIrp->Tail.Overlay.ListEntry);
+ pIrp->Tail.Overlay.DriverContext[0] = (PVOID)pOpenContext;
+
+ NPROT_REF_OPEN(pOpenContext); // pended read IRP
+ pOpenContext->PendedReadCount++;
+ IoMarkIrpPending(pIrp);
+
+
+ NtStatus = STATUS_PENDING;
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+ //
+ // Run the service routine for reads.
+ //
+ ndisprotServiceReads(pOpenContext);
+
+ }
+ while (FALSE);
+
+ if (NtStatus != STATUS_PENDING)
+ {
+ NPROT_ASSERT(NtStatus != STATUS_SUCCESS);
+ pIrp->IoStatus.Information = 0;
+ pIrp->IoStatus.Status = NtStatus;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ }
+
+ return (NtStatus);
+}
+
+
+VOID
+NdisprotCancelRead(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ )
+/*++
+
+Routine Description:
+
+ Cancel a pending read IRP. We unlink the IRP from the open context
+ queue and complete it.
+
+Arguments:
+
+ pDeviceObject - pointer to our device object
+ pIrp - IRP to be cancelled
+
+Return Value:
+
+ None
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+
+ UNREFERENCED_PARAMETER(pDeviceObject);
+
+ IoReleaseCancelSpinLock(pIrp->CancelIrql);
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT) pIrp->Tail.Overlay.DriverContext[0];
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_REMOVE_ENTRY_LIST(&pIrp->Tail.Overlay.ListEntry);
+ pOpenContext->PendedReadCount--;
+
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ DEBUGP(DL_INFO, ("CancelRead: Open %p, IRP %p\n", pOpenContext, pIrp));
+ pIrp->IoStatus.Status = STATUS_CANCELLED;
+ pIrp->IoStatus.Information = 0;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ NPROT_DEREF_OPEN(pOpenContext); // Cancel removed pended Read
+
+}
+
+
+
+VOID
+ndisprotServiceReads(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ )
+/*++
+
+Routine Description:
+
+ Utility routine to copy received data into user buffers and
+ complete READ IRPs.
+
+Arguments:
+
+ pOpenContext - pointer to open context
+
+Return Value:
+
+ None
+
+--*/
+{
+ PIRP pIrp = NULL;
+ PLIST_ENTRY pIrpEntry;
+ PNET_BUFFER_LIST pRcvNetBufList;
+ PLIST_ENTRY pRcvNetBufListEntry;
+ PUCHAR pSrc, pDst;
+ ULONG BytesRemaining; // at pDst
+ PMDL pMdl;
+ ULONG BytesAvailable;
+ BOOLEAN FoundPendingIrp = FALSE;
+ ULONG SrcTotalLength = 0; // Source NetBuffer DataLenght
+ ULONG Offset = 0; // CurrentMdlOffset
+ ULONG BytesToCopy = 0;
+
+ DEBUGP(DL_VERY_LOUD, ("ServiceReads: open %p/%x\n",
+ pOpenContext, pOpenContext->Flags));
+
+ NPROT_REF_OPEN(pOpenContext); // temp ref - service reads
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ while (!NPROT_IS_LIST_EMPTY(&pOpenContext->PendedReads) &&
+ !NPROT_IS_LIST_EMPTY(&pOpenContext->RecvNetBufListQueue))
+ {
+ FoundPendingIrp = FALSE;
+
+ //
+ // Get the first pended Read IRP
+ //
+ pIrpEntry = pOpenContext->PendedReads.Flink;
+ while (pIrpEntry != &pOpenContext->PendedReads)
+ {
+ pIrp = CONTAINING_RECORD(pIrpEntry, IRP, Tail.Overlay.ListEntry);
+
+ //
+ // Check to see if it is being cancelled.
+ //
+ if (IoSetCancelRoutine(pIrp, NULL))
+ {
+ //
+ // It isn't being cancelled, and can't be cancelled henceforth.
+ //
+ NPROT_REMOVE_ENTRY_LIST(pIrpEntry);
+ FoundPendingIrp = TRUE;
+ break;
+
+ //
+ // NOTE: we decrement PendedReadCount way below in the
+ // while loop, to avoid letting through a thread trying
+ // to unbind.
+ //
+ }
+ else
+ {
+ //
+ // The IRP is being cancelled; let the cancel routine handle it.
+ //
+ DEBUGP(DL_INFO, ("ServiceReads: open %p, skipping cancelled IRP %p\n",
+ pOpenContext, pIrp));
+
+ pIrpEntry = pIrpEntry->Flink;
+ }
+ }
+
+ if (FoundPendingIrp == FALSE)
+ {
+ break;
+ }
+ //
+ // Get the first queued receive packet
+ //
+ pRcvNetBufListEntry = pOpenContext->RecvNetBufListQueue.Flink;
+ NPROT_REMOVE_ENTRY_LIST(pRcvNetBufListEntry);
+
+ pOpenContext->RecvNetBufListCount --;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_DEREF_OPEN(pOpenContext); // Service: dequeue rcv packet
+
+ pRcvNetBufList = NPROT_RCV_NBL_FROM_LIST_ENTRY(pRcvNetBufListEntry);
+ NPROT_ASSERT(pRcvNetBufList != NULL);
+ _Analysis_assume_(pRcvNetBufList != NULL);
+ NPROT_RCV_NBL_FROM_LIST_ENTRY(pRcvNetBufListEntry) = NULL;
+
+ //
+ // Copy as much data as possible from the receive packet to
+ // the IRP MDL.
+ //
+
+ pDst = NULL;
+ NdisQueryMdl(pIrp->MdlAddress, &pDst, &BytesRemaining, NormalPagePriority);
+ NPROT_ASSERT(pDst != NULL); // since it was already mapped
+ _Analysis_assume_(pDst != NULL);
+
+ pMdl = NET_BUFFER_CURRENT_MDL(NET_BUFFER_LIST_FIRST_NB(pRcvNetBufList));
+
+ //
+ // Copy the data in the received packet into the buffer provided by the client.
+ // If the length of the receive packet is greater than length of the given buffer,
+ // we just copy as many bytes as we can. Once the buffer is full, we just discard
+ // the rest of the data, and complete the IRP sucessfully even we only did a partial copy.
+ //
+
+ SrcTotalLength = NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pRcvNetBufList));
+ Offset = NET_BUFFER_CURRENT_MDL_OFFSET(NET_BUFFER_LIST_FIRST_NB(pRcvNetBufList));
+
+ while (BytesRemaining && (pMdl != NULL) && SrcTotalLength)
+ {
+ pSrc = NULL;
+ NdisQueryMdl(pMdl, &pSrc, &BytesAvailable, NormalPagePriority);
+
+ if (pSrc == NULL)
+ {
+ DEBUGP(DL_FATAL,
+ ("ServiceReads: Open %p, NdisQueryMdl failed for MDL %p\n",
+ pOpenContext, pMdl));
+ break;
+ }
+
+ NPROT_ASSERT(BytesAvailable > Offset);
+
+ BytesToCopy = MIN(BytesAvailable - Offset, BytesRemaining);
+ BytesToCopy = MIN(BytesToCopy, SrcTotalLength);
+
+ NPROT_COPY_MEM(pDst, pSrc + Offset, BytesToCopy);
+ BytesRemaining -= BytesToCopy;
+ pDst += BytesToCopy;
+ SrcTotalLength -= BytesToCopy;
+
+ //
+ // CurrentMdlOffset is used only for the first Mdl processed. For the remaining Mdls, it is 0.
+ //
+ Offset = 0;
+
+ NdisGetNextMdl(pMdl, &pMdl);
+ }
+
+ //
+ // Complete the IRP.
+ //
+ pIrp->IoStatus.Status = STATUS_SUCCESS;
+ pIrp->IoStatus.Information = MmGetMdlByteCount(pIrp->MdlAddress) - BytesRemaining;
+
+ DEBUGP(DL_INFO, ("ServiceReads: Open %p, IRP %p completed with %d bytes\n",
+ pOpenContext, pIrp, (ULONG)pIrp->IoStatus.Information));
+
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ ndisprotFreeReceiveNetBufferList(pOpenContext, pRcvNetBufList,FALSE);
+
+
+ NPROT_DEREF_OPEN(pOpenContext); // took out pended Read
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+ pOpenContext->PendedReadCount--;
+
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_DEREF_OPEN(pOpenContext); // temp ref - service reads
+}
+
+
+VOID
+NdisprotReceiveNetBufferLists(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN PNET_BUFFER_LIST pNetBufferLists,
+ IN NDIS_PORT_NUMBER PortNumber,
+ IN ULONG NumberOfNetBufferLists,
+ IN ULONG ReceiveFlags
+ )
+/*++
+
+Routine Description:
+
+ Protocol entry point called by NDIS if the driver below
+ uses NDIS 6 net buffer list indications.
+
+ If the miniport allows us to hold on to this net buffer list, we
+ use it as is, otherwise we make a copy.
+
+Arguments:
+
+ ProtocolBindingContext - pointer to open context
+ pNetBufferLists - a list of the Net Buffer lists being indicated up.
+ PortNumber - Port on which the Net Bufer list was received
+ NumberOfNetBufferLists - the number of NetBufferLists in this indication
+ ReceiveFlags - indicates whether the NetBufferLists can be pended in
+ the protocol driver.
+
+Return Value:
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ PMDL pMdl = NULL;
+ UINT BufferLength;
+ PNDISPROT_ETH_HEADER pEthHeader = NULL;
+ PNET_BUFFER_LIST pCopyNetBufList;
+ PUCHAR pCopyBuf;
+ ULONG TotalLength;
+ ULONG BytesCopied;
+ PNET_BUFFER_LIST pNetBufList;
+ PNET_BUFFER_LIST pNetBufListOrig = NULL;
+ PNET_BUFFER_LIST pNextNetBufList;
+ PNET_BUFFER_LIST pReturnNetBufList = NULL;
+ PNET_BUFFER_LIST pLastReturnNetBufList = NULL;
+ NTSTATUS NtStatus;
+ BOOLEAN bAcceptedReceive;
+ ULONG Offset;
+ ULONG ReturnFlags = 0;
+ BOOLEAN DispatchLevel;
+ BOOLEAN NoReadIRP = FALSE;
+
+ UNREFERENCED_PARAMETER(PortNumber);
+ UNREFERENCED_PARAMETER(NumberOfNetBufferLists);
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
+
+ if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags))
+ {
+ NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL);
+ }
+
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+ if ((pOpenContext->State == NdisprotPausing)
+ || (pOpenContext->State == NdisprotPaused))
+ {
+ if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags) == TRUE)
+ {
+
+ NdisReturnNetBufferLists(pOpenContext->BindingHandle,
+ pNetBufferLists,
+ ReturnFlags);
+ }
+ return;
+ }
+
+ pNetBufList = pNetBufferLists;
+
+ while (pNetBufList != NULL)
+ {
+ pNextNetBufList = NET_BUFFER_LIST_NEXT_NBL (pNetBufList);
+
+ NBL_CLEAR_PROT_RSVD_FLAG(pNetBufList, NBL_PROT_RSVD_FLAGS);
+ bAcceptedReceive = FALSE;
+
+ //
+ // Get first MDL and data length in the list
+ //
+ pMdl = NET_BUFFER_CURRENT_MDL(NET_BUFFER_LIST_FIRST_NB(pNetBufList));
+ TotalLength = NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pNetBufList));
+ Offset = NET_BUFFER_CURRENT_MDL_OFFSET(NET_BUFFER_LIST_FIRST_NB(pNetBufList));
+ BufferLength = 0;
+
+ do
+ {
+ ASSERT(pMdl != NULL);
+ if (pMdl)
+ {
+ NdisQueryMdl(
+ pMdl,
+ &pEthHeader,
+ &BufferLength,
+ NormalPagePriority);
+ }
+
+ if (pEthHeader == NULL)
+ {
+ //
+ // The system is low on resources. Set up to handle failure
+ // below.
+ //
+ BufferLength = 0;
+ break;
+ }
+
+ if (BufferLength == 0)
+ {
+ break;
+ }
+
+ ASSERT(BufferLength > Offset);
+
+ BufferLength -= Offset;
+ pEthHeader = (PNDISPROT_ETH_HEADER)((PUCHAR)pEthHeader + Offset);
+
+ if (BufferLength < sizeof(NDISPROT_ETH_HEADER))
+ {
+ DEBUGP(DL_WARN,
+ ("ReceiveNetBufferList: Open %p, runt nbl %p, first buffer length %d\n",
+ pOpenContext, pNetBufList, BufferLength));
+
+ break;
+ }
+
+ //
+ // Check the EtherType. If the Ether type indicates presence of
+ // a tag, then the "real" Ether type is 4 bytes further down.
+ //
+ if (pEthHeader->EthType == NPROT_8021P_TAG_TYPE)
+ {
+ USHORT UNALIGNED *pEthType;
+
+ if (BufferLength < (sizeof(NDISPROT_ETH_HEADER) + 4))
+ {
+ break;
+ }
+
+ pEthType = (USHORT UNALIGNED *)((PUCHAR)&pEthHeader->EthType + 4);
+
+ if (*pEthType != Globals.EthType)
+ {
+ break;
+ }
+ }
+ else if (pEthHeader->EthType != Globals.EthType)
+ {
+ break;
+ }
+
+ bAcceptedReceive = TRUE;
+ DEBUGP(DL_LOUD, ("ReceiveNetBufferList: Open %p, interesting nbl %p\n",
+ pOpenContext, pNetBufList));
+
+ //
+ // If the miniport is out of resources, we can't queue
+ // this list of net buffer list - make a copy if this is so.
+ //
+ DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags);
+
+ NoReadIRP = NPROT_IS_LIST_EMPTY(&pOpenContext->PendedReads);
+
+ if (NoReadIRP || NDIS_TEST_RECEIVE_CANNOT_PEND(ReceiveFlags))
+ {
+ bAcceptedReceive = FALSE;
+ pCopyNetBufList = ndisprotAllocateReceiveNetBufferList(
+ pOpenContext,
+ TotalLength,
+ &pCopyBuf);
+
+ if (pCopyNetBufList == NULL)
+ {
+ DEBUGP(DL_FATAL, ("ReceiveNetBufferList: Open %p, failed to"
+ " alloc copy, %d bytes\n", pOpenContext, TotalLength));
+ break;
+ }
+ NBL_SET_PROT_RSVD_FLAG(pCopyNetBufList, NPROT_ALLOCATED_NBL);
+ //
+ // Copy the data to the new allocated NetBufferList
+ //
+ NtStatus = NdisCopyFromNetBufferToNetBuffer(NET_BUFFER_LIST_FIRST_NB(pCopyNetBufList),
+ 0,
+ TotalLength,
+ NET_BUFFER_LIST_FIRST_NB(pNetBufList),
+ 0,
+ &BytesCopied);
+
+
+ if (NtStatus != STATUS_SUCCESS)
+ {
+ DEBUGP(DL_FATAL, ("ReceiveNetBufferList: Open %p, failed to"
+ " copy the data, %d bytes\n", pOpenContext, TotalLength));
+ //
+ // Free the NetBufferList and memory allocate before
+ //
+ ndisprotFreeReceiveNetBufferList(pOpenContext,
+ pCopyNetBufList,
+ DispatchLevel);
+ break;
+ }
+
+ NPROT_ASSERT(BytesCopied == TotalLength);
+
+
+ //
+ // The other members of NET_BUFFER_DATA structure are already initialized properly during allocation.
+ //
+ NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pCopyNetBufList)) = BytesCopied;
+
+ //
+ //save a copy for no Read IRP case
+ //
+ if(NoReadIRP)
+ {
+ pNetBufListOrig = pNetBufList;
+ }
+ pNetBufList = pCopyNetBufList;
+
+ }
+ //
+ // Queue this up and service any pending Read IRPs.
+ //
+ ndisprotQueueReceiveNetBufferList(pOpenContext, pNetBufList, DispatchLevel);
+
+ }
+ while (FALSE);
+
+ //
+ // Ndisprot is not interested this NetBufferList, return the
+ // NetBufferList back to the miniport if the miniport gave us
+ // ownership of it
+ //
+ if ((bAcceptedReceive == FALSE) &&
+ (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags) == TRUE))
+ {
+ // Restore pNetBufList if it was overwritten earlier
+ if (pNetBufListOrig != NULL)
+ {
+ pNetBufList = pNetBufListOrig;
+
+ pNetBufListOrig = NULL;
+ }
+ if (pReturnNetBufList == NULL)
+ {
+ pReturnNetBufList = pNetBufList;
+ }
+ else
+ {
+ NET_BUFFER_LIST_NEXT_NBL(pLastReturnNetBufList) = pNetBufList;
+ }
+ pLastReturnNetBufList = pNetBufList;
+ NET_BUFFER_LIST_NEXT_NBL(pNetBufList) = NULL;
+
+ }
+
+ pNetBufList = pNextNetBufList;
+ } // end of the for loop
+
+ if (pReturnNetBufList != NULL)
+ {
+ NdisReturnNetBufferLists(pOpenContext->BindingHandle,
+ pReturnNetBufList,
+ ReturnFlags);
+ }
+
+}
+
+
+VOID
+ndisprotQueueReceiveNetBufferList(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN PNET_BUFFER_LIST pRcvNetBufList,
+ IN BOOLEAN DispatchLevel
+ )
+/*++
+
+Routine Description:
+
+ Queue up a received net buffer list on the open context structure.
+ If the queue size goes beyond a water mark, discard a Net Buffer list
+ at the head of the queue.
+
+ Finally, run the queue service routine.
+
+Arguments:
+
+ pOpenContext - pointer to open context
+ pRcvPacket - the received packet
+ DipatchLevel - the irql level
+
+Return Value:
+
+ None
+
+--*/
+{
+ PLIST_ENTRY pEnt;
+ PLIST_ENTRY pDiscardEnt;
+ PNET_BUFFER_LIST pDiscardNetBufList;
+
+ do
+ {
+
+ NPROT_REF_OPEN(pOpenContext); // queued rcv net buffer list
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, DispatchLevel);
+
+ if ((pOpenContext->State == NdisprotPaused)
+ || (pOpenContext->State == NdisprotPausing))
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, DispatchLevel);
+
+ ndisprotFreeReceiveNetBufferList(pOpenContext, pRcvNetBufList, DispatchLevel);
+ break;
+ }
+
+ //
+ // Check if the binding is in the proper state to receive
+ // this net buffer list.
+ //
+ if (NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE) &&
+ (pOpenContext->PowerState == NetDeviceStateD0))
+ {
+
+ //
+ // Queue the net buffer list
+ //
+ pEnt = NPROT_RCV_NBL_TO_LIST_ENTRY(pRcvNetBufList);
+ NPROT_INSERT_TAIL_LIST(&pOpenContext->RecvNetBufListQueue, pEnt);
+ NPROT_RCV_NBL_FROM_LIST_ENTRY(pEnt) = pRcvNetBufList;
+ pOpenContext->RecvNetBufListCount++;
+
+ DEBUGP(DL_VERY_LOUD, ("QueueReceiveNetBufferList: open %p,"
+ " queued nbl %p, queue size %d\n",
+ pOpenContext, pRcvNetBufList, pOpenContext->RecvNetBufListCount));
+
+ }
+ else
+ {
+ //
+ // Received this net buffer list when the binding is going away.
+ // Drop this.
+ //
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, DispatchLevel);
+
+ ndisprotFreeReceiveNetBufferList(pOpenContext, pRcvNetBufList, DispatchLevel);
+
+ NPROT_DEREF_OPEN(pOpenContext); // dropped rcv packet - bad state
+ break;
+ }
+
+
+ //
+ // Trim the queue if it has grown too big.
+ //
+ if (pOpenContext->RecvNetBufListCount > MAX_RECV_QUEUE_SIZE)
+ {
+ //
+ // Remove the head of the queue.
+ //
+ pDiscardEnt = pOpenContext->RecvNetBufListQueue.Flink;
+ NPROT_REMOVE_ENTRY_LIST(pDiscardEnt);
+
+ pOpenContext->RecvNetBufListCount --;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, DispatchLevel);
+
+ pDiscardNetBufList = NPROT_RCV_NBL_FROM_LIST_ENTRY(pDiscardEnt);
+
+ NPROT_RCV_NBL_FROM_LIST_ENTRY(pDiscardEnt) = NULL;
+
+ ndisprotFreeReceiveNetBufferList(pOpenContext, pDiscardNetBufList, DispatchLevel);
+
+ NPROT_DEREF_OPEN(pOpenContext); // dropped rcv packet - queue too long
+
+ DEBUGP(DL_INFO, ("QueueReceiveNetBufferList: open %p queue"
+ " too long, discarded %p\n",
+ pOpenContext, pDiscardNetBufList));
+ }
+ else
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, DispatchLevel);
+ }
+
+ //
+ // Run the receive queue service routine now.
+ //
+ ndisprotServiceReads(pOpenContext);
+ }
+ while (FALSE);
+}
+
+_Success_(return != 0)
+PNET_BUFFER_LIST
+ndisprotAllocateReceiveNetBufferList(
+ _In_ PNDISPROT_OPEN_CONTEXT pOpenContext,
+ _In_ UINT DataLength,
+ _Outptr_result_bytebuffer_(DataLength)
+ PUCHAR * ppDataBuffer
+ )
+/*++
+
+Routine Description:
+
+ Allocate resources to copy and queue a received net buffer list
+
+Arguments:
+
+ pOpenContext - pointer to open context for received packet
+ DataLength - total length in bytes of the net buffer list's first net buffer
+ ppDataBuffer - place to return pointer to allocated buffer
+
+Return Value:
+
+ Pointer to NDIS packet if successful, else NULL.
+
+--*/
+{
+ PNET_BUFFER_LIST pNetBufList;
+ PMDL pMdl;
+ PUCHAR pDataBuffer;
+
+ pNetBufList = NULL;
+ pMdl = NULL;
+ pDataBuffer = NULL;
+ *ppDataBuffer = NULL;
+
+ do
+ {
+ NPROT_ALLOC_MEM(pDataBuffer, DataLength);
+
+ if (pDataBuffer == NULL)
+ {
+ DEBUGP(DL_FATAL, ("AllocRcvNbl: open %p, failed to alloc"
+ " data buffer %d bytes\n", pOpenContext, DataLength));
+ break;
+ }
+
+ //
+ // Make this an NDIS buffer.
+ //
+ pMdl = NdisAllocateMdl(pOpenContext->BindingHandle, pDataBuffer, DataLength);
+
+ if (pMdl == NULL)
+ {
+ DEBUGP(DL_FATAL, ("AllocateRcvNbl: open %p, failed to alloc"
+ " MDL, %d bytes\n", pOpenContext, DataLength));
+ break;
+ }
+
+ pNetBufList = NdisAllocateNetBufferAndNetBufferList(
+ pOpenContext->RecvNetBufferListPool,
+ 0, // ContextSize
+ 0, // ContextBackfill
+ pMdl, // MdlChain
+ 0, // DataOffset
+ DataLength); // DataLength
+
+ if (pNetBufList == NULL)
+ {
+ DEBUGP(DL_FATAL, ("AllocateRcvNbl: open %p, failed to alloc"
+ " Net Buffer List, %d bytes\n", pOpenContext, DataLength));
+ break;
+ }
+
+
+ *ppDataBuffer = pDataBuffer;
+
+ }
+ while (FALSE);
+
+ if (pNetBufList == NULL)
+ {
+ //
+ // Clean up
+ //
+ if (pMdl != NULL)
+ {
+ NdisFreeMdl(pMdl);
+ }
+
+ if (pDataBuffer != NULL)
+ {
+ NPROT_FREE_MEM(pDataBuffer);
+ }
+ }
+
+ return (pNetBufList);
+}
+
+
+
+VOID
+ndisprotFreeReceiveNetBufferList(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext,
+ IN PNET_BUFFER_LIST pNetBufferList,
+ IN BOOLEAN DispatchLevel
+ )
+/*++
+
+Routine Description:
+
+ Free up all resources associated with a received net buffer list. If this
+ is a local copy, free the net buffer list to our receive pool, else return
+ this to the miniport.
+
+Arguments:
+
+ pOpenContext - pointer to open context
+ pNetBufferList - pointer to net buffer list to be freed.
+ DipatchLevel - the irql level
+
+Return Value:
+
+ None
+
+--*/
+{
+ PMDL pMdl;
+ UINT TotalLength;
+ UINT BufferLength;
+ PUCHAR pCopyData = NULL;
+ ULONG ReturnFlags = 0;
+
+
+ do
+ {
+ if (NBL_TEST_PROT_RSVD_FLAG(pNetBufferList, NPROT_ALLOCATED_NBL))
+ {
+ //
+ // This is a local copy.
+ //
+
+ pMdl = NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(pNetBufferList));
+ TotalLength = NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pNetBufferList));
+
+ NPROT_ASSERT(pMdl != NULL);
+
+ NdisQueryMdl(
+ pMdl,
+ (PVOID *)&pCopyData,
+ &BufferLength,
+ NormalPagePriority);
+
+ NPROT_ASSERT(BufferLength == TotalLength);
+
+
+ NPROT_ASSERT(pCopyData != NULL); // we would have allocated non-paged pool
+
+
+ NdisFreeNetBufferList(pNetBufferList);
+
+ NdisFreeMdl(pMdl);
+
+ NPROT_FREE_MEM(pCopyData);
+ break;
+ }
+ //
+ // The NetBufferList should be returned
+
+ NET_BUFFER_LIST_NEXT_NBL(pNetBufferList) = NULL;
+
+ if (DispatchLevel)
+ {
+ NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL);
+ }
+
+ NdisReturnNetBufferLists(pOpenContext->BindingHandle,
+ pNetBufferList,
+ ReturnFlags);
+ }
+ while (FALSE);
+
+}
+
+
+VOID
+ndisprotCancelPendingReads(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ )
+/*++
+
+Routine Description:
+
+ Cancel any pending read IRPs queued on the given open.
+
+Arguments:
+
+ pOpenContext - pointer to open context
+
+Return Value:
+
+ None
+
+--*/
+{
+ PIRP pIrp;
+ PLIST_ENTRY pIrpEntry;
+
+ NPROT_REF_OPEN(pOpenContext); // temp ref - cancel reads
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ while (!NPROT_IS_LIST_EMPTY(&pOpenContext->PendedReads))
+ {
+ //
+ // Get the first pended Read IRP
+ //
+ pIrpEntry = pOpenContext->PendedReads.Flink;
+ pIrp = CONTAINING_RECORD(pIrpEntry, IRP, Tail.Overlay.ListEntry);
+
+ //
+ // Check to see if it is being cancelled.
+ //
+ if (IoSetCancelRoutine(pIrp, NULL))
+ {
+ //
+ // It isn't being cancelled, and can't be cancelled henceforth.
+ //
+ NPROT_REMOVE_ENTRY_LIST(pIrpEntry);
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Complete the IRP.
+ //
+ pIrp->IoStatus.Status = STATUS_CANCELLED;
+ pIrp->IoStatus.Information = 0;
+
+ DEBUGP(DL_INFO, ("CancelPendingReads: Open %p, IRP %p cancelled\n",
+ pOpenContext, pIrp));
+
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ NPROT_DEREF_OPEN(pOpenContext); // took out pended Read for cancelling
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+ pOpenContext->PendedReadCount--;
+ }
+ else
+ {
+ //
+ // It is being cancelled, let the cancel routine handle it.
+ //
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Give the cancel routine some breathing space, otherwise
+ // we might end up examining the same (cancelled) IRP over
+ // and over again.
+ //
+ NdisMSleep(100000); // 100 ms.
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+ }
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_DEREF_OPEN(pOpenContext); // temp ref - cancel reads
+}
+
+
+VOID
+ndisprotFlushReceiveQueue(
+ IN PNDISPROT_OPEN_CONTEXT pOpenContext
+ )
+/*++
+
+Routine Description:
+
+ Free any receive packets queued up on the specified open
+
+Arguments:
+
+ pOpenContext - pointer to open context
+
+Return Value:
+
+ None
+
+--*/
+{
+ PLIST_ENTRY pRcvNetBufListEntry;
+ PNET_BUFFER_LIST pRcvNetBufList;
+
+ NPROT_REF_OPEN(pOpenContext); // temp ref - flushRcvQueue
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ while (!NPROT_IS_LIST_EMPTY(&pOpenContext->RecvNetBufListQueue))
+ {
+ //
+ // Get the first queued receive packet
+ //
+ pRcvNetBufListEntry = pOpenContext->RecvNetBufListQueue.Flink;
+ NPROT_REMOVE_ENTRY_LIST(pRcvNetBufListEntry);
+
+ pOpenContext->RecvNetBufListCount--;
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ pRcvNetBufList = NPROT_RCV_NBL_FROM_LIST_ENTRY(pRcvNetBufListEntry);
+ NPROT_RCV_NBL_FROM_LIST_ENTRY(pRcvNetBufListEntry) = NULL;
+
+ DEBUGP(DL_LOUD, ("FlushReceiveQueue: open %p, nbl %p\n",
+ pOpenContext, pRcvNetBufList));
+
+ ndisprotFreeReceiveNetBufferList(pOpenContext, pRcvNetBufList, FALSE);
+
+ NPROT_DEREF_OPEN(pOpenContext); // took out pended Read
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ NPROT_DEREF_OPEN(pOpenContext); // temp ref - flushRcvQueue
+}
+
+
diff --git a/network/ndis/ndisprot/6x/sys/send.c b/network/ndis/ndisprot/6x/sys/send.c
new file mode 100644
index 00000000..b2be7300
--- /dev/null
+++ b/network/ndis/ndisprot/6x/sys/send.c
@@ -0,0 +1,463 @@
+/*++
+
+Copyright (c) 2000 Microsoft Corporation
+
+Module Name:
+
+ send.c
+
+Abstract:
+
+ NDIS protocol entry points and utility routines to handle sending
+ data.
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "precomp.h"
+
+#define __FILENUMBER 'DNES'
+
+
+
+
+NTSTATUS
+NdisprotWrite(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ )
+/*++
+
+Routine Description:
+
+ Dispatch routine to handle IRP_MJ_WRITE.
+
+Arguments:
+
+ pDeviceObject - pointer to our device object
+ pIrp - Pointer to request packet
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PIO_STACK_LOCATION pIrpSp;
+ ULONG DataLength;
+ NTSTATUS NtStatus;
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ PNET_BUFFER_LIST pNetBufferList;
+ PMDL pMdl;
+ NDISPROT_ETH_HEADER UNALIGNED *pEthHeader;
+ PVOID CancelId;
+ ULONG SendFlags = 0;
+
+ UNREFERENCED_PARAMETER(pDeviceObject);
+
+ pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
+ pOpenContext = pIrpSp->FileObject->FsContext;
+
+
+ do
+ {
+ if (pOpenContext == NULL)
+ {
+ DEBUGP(DL_WARN, ("Write: FileObject %p not yet associated with a device\n",
+ pIrpSp->FileObject));
+ NtStatus = STATUS_INVALID_HANDLE;
+ break;
+ }
+
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ if (pIrp->MdlAddress == NULL)
+ {
+ DEBUGP(DL_FATAL, ("Write: NULL MDL address on IRP %p\n", pIrp));
+ NtStatus = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Try to get a virtual address for the MDL.
+ //
+
+ pEthHeader = NULL;
+ NdisQueryMdl(pIrp->MdlAddress, &pEthHeader, &DataLength, NormalPagePriority);
+
+ if (pEthHeader == NULL)
+ {
+ DEBUGP(DL_FATAL, ("Write: MmGetSystemAddr failed for"
+ " IRP %p, MDL %p\n",
+ pIrp, pIrp->MdlAddress));
+ NtStatus = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ //
+ // Sanity-check the length.
+ //
+ if (DataLength < sizeof(NDISPROT_ETH_HEADER))
+ {
+ DEBUGP(DL_WARN, ("Write: too small to be a valid packet (%d bytes)\n",
+ DataLength));
+ NtStatus = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ if (DataLength > (pOpenContext->MaxFrameSize + sizeof(NDISPROT_ETH_HEADER)))
+ {
+ DEBUGP(DL_WARN, ("Write: Open %p: data length (%d)"
+ " larger than max frame size (%d)\n",
+ pOpenContext, DataLength, pOpenContext->MaxFrameSize));
+
+ NtStatus = STATUS_INVALID_BUFFER_SIZE;
+ break;
+ }
+
+ if (pEthHeader->EthType != Globals.EthType)
+ {
+ DEBUGP(DL_WARN, ("Write: Failing send with EthType %x\n",
+ pEthHeader->EthType));
+ NtStatus = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (!NPROT_MEM_CMP(pEthHeader->SrcAddr, pOpenContext->CurrentAddress, NPROT_MAC_ADDR_LEN))
+ {
+ DEBUGP(DL_WARN, ("Write: Failing with invalid Source address"));
+ NtStatus = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_ACTIVE))
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ DEBUGP(DL_FATAL, ("Write: Open %p is not bound"
+ " or in low power state\n", pOpenContext));
+
+ NtStatus = STATUS_INVALID_HANDLE;
+ break;
+ }
+
+ if (pOpenContext->State != NdisprotRunning ||
+ pOpenContext->PowerState != NetDeviceStateD0)
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ DEBUGP(DL_INFO, ("Device is not ready.\n"));
+ NtStatus = STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+
+ pMdl = pIrp->MdlAddress;
+ NPROT_ASSERT(pOpenContext->SendNetBufferListPool != NULL);
+ pNetBufferList = NdisAllocateNetBufferAndNetBufferList(
+ pOpenContext->SendNetBufferListPool,
+ sizeof(NPROT_SEND_NETBUFLIST_RSVD), //Request control offset delta
+ 0, // back fill size
+ pMdl,
+ 0, // Data offset
+ DataLength);
+
+ if (pNetBufferList == NULL)
+ {
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ DEBUGP(DL_FATAL, ("Write: open %p, failed to alloc send net buffer list\n",
+ pOpenContext));
+ NtStatus = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+ pOpenContext->PendedSendCount++;
+
+ NPROT_REF_OPEN(pOpenContext); // pended send
+
+ IoMarkIrpPending(pIrp);
+
+ //
+ // Initialize the NetBufferList ref count. This NetBufferList will be freed
+ // when this count goes to zero.
+ //
+ NPROT_SEND_NBL_RSVD(pNetBufferList)->RefCount = 1;
+
+ //
+ // We set up a cancel ID on each send NetBufferList (which maps to a Write IRP),
+ // and save the NetBufferList pointer in the IRP. If the IRP gets cancelled, we use
+ // NdisCancelSendNetBufferLists() to cancel the NetBufferList.
+ //
+
+ CancelId = NPROT_GET_NEXT_CANCEL_ID();
+ NDIS_SET_NET_BUFFER_LIST_CANCEL_ID(pNetBufferList, CancelId);
+ pIrp->Tail.Overlay.DriverContext[0] = (PVOID)pOpenContext;
+ pIrp->Tail.Overlay.DriverContext[1] = (PVOID)pNetBufferList;
+ pIrp->Tail.Overlay.DriverContext[2] = CancelId;
+
+ NPROT_INSERT_TAIL_LIST(&pOpenContext->PendedWrites, &pIrp->Tail.Overlay.ListEntry);
+
+ IoSetCancelRoutine(pIrp, NdisprotCancelWrite);
+
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ //
+ // Set a back pointer from the packet to the IRP.
+ //
+ NPROT_IRP_FROM_SEND_NBL(pNetBufferList) = pIrp;
+
+ NtStatus = STATUS_PENDING;
+
+
+#if SEND_DBG
+ {
+ PUCHAR pData;
+
+ pData = MmGetSystemAddressForMdlSafe(pMdl, NormalPagePriority);
+ NPROT_ASSERT(pEthHeader == pData);
+
+ DEBUGP(DL_VERY_LOUD,
+ ("Write: MDL %p, MdlFlags %x, SystemAddr %p, %d bytes\n",
+ pIrp->MdlAddress, pIrp->MdlAddress->MdlFlags, pData, DataLength));
+
+ DEBUGPDUMP(DL_VERY_LOUD, pData, MIN(DataLength, 48));
+ }
+#endif // SEND_DBG
+
+ pNetBufferList->SourceHandle = pOpenContext->BindingHandle;
+ ASSERT (NDIS_MDL_LINKAGE(pMdl) == NULL);
+
+ SendFlags |= NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK;
+
+ NdisSendNetBufferLists(
+ pOpenContext->BindingHandle,
+ pNetBufferList,
+ NDIS_DEFAULT_PORT_NUMBER,
+ SendFlags);
+
+ }
+ while (FALSE);
+
+ if (NtStatus != STATUS_PENDING)
+ {
+ pIrp->IoStatus.Status = NtStatus;
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+ }
+
+ return (NtStatus);
+}
+
+
+
+VOID
+NdisprotCancelWrite(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PIRP pIrp
+ )
+/*++
+
+Routine Description:
+
+ Cancel a pending write IRP. This routine attempt to cancel the NDIS send.
+
+Arguments:
+
+ pDeviceObject - pointer to our device object
+ pIrp - IRP to be cancelled
+
+Return Value:
+
+ None
+
+--*/
+{
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ PLIST_ENTRY pIrpEntry;
+ BOOLEAN FoundIrp = FALSE;
+
+ UNREFERENCED_PARAMETER(pDeviceObject);
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT) pIrp->Tail.Overlay.DriverContext[0];
+ if (pOpenContext == NULL)
+ {
+ //
+ // The IRP is going to be completed from send complete function
+ //
+ IoReleaseCancelSpinLock(pIrp->CancelIrql);
+ return;
+ }
+
+ NPROT_REF_OPEN(pOpenContext);
+ IoReleaseCancelSpinLock(pIrp->CancelIrql);
+
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+
+ //
+ // Try to locate the IRP in the pended write queue. The send completion
+ // routine may be running and might have removed it from there.
+ //
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, FALSE);
+
+ for (pIrpEntry = pOpenContext->PendedWrites.Flink;
+ pIrpEntry != &pOpenContext->PendedWrites;
+ pIrpEntry = pIrpEntry->Flink)
+ {
+ if (pIrp == CONTAINING_RECORD(pIrpEntry, IRP, Tail.Overlay.ListEntry))
+ {
+ FoundIrp = TRUE;
+ break;
+ }
+ }
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, FALSE);
+
+ if (FoundIrp)
+ {
+ PVOID CancelId;
+
+ CancelId = pIrp->Tail.Overlay.DriverContext[2];
+ //
+ // Either the send completion routine hasn't run, or we got a peak
+ // at the IRP/netbufferlist before it had a chance to take it out of the
+ // pending IRP queue.
+ //
+ // We do not complete the IRP here - note that we didn't dequeue it
+ // above. This is because we always want the send complete routine to
+ // complete the IRP. And this in turn is because the NetBufferlist that was
+ // prepared from the IRP has a buffer chain pointing to data associated
+ // with this IRP. Therefore we cannot complete the IRP before the driver
+ // below us is done with the data it pointed to.
+ //
+
+ //
+ // Request NDIS to cancel this send. The result of this call is that
+ // our SendComplete handler will be called (if not already called).
+ //
+ DEBUGP(DL_INFO, ("CancelWrite: cancelling nbl %p on Open %p\n",
+ pIrp->Tail.Overlay.DriverContext[1], pOpenContext));
+
+ NdisCancelSendNetBufferLists(
+ pOpenContext->BindingHandle,
+ CancelId);
+
+ }
+ //
+ // else the send completion routine has already picked up this IRP.
+ //
+ NPROT_DEREF_OPEN(pOpenContext);
+}
+
+
+VOID
+NdisprotSendComplete(
+ IN NDIS_HANDLE ProtocolBindingContext,
+ IN PNET_BUFFER_LIST pNetBufferList,
+ IN ULONG SendCompleteFlags
+ )
+/*++
+
+Routine Description:
+
+ NDIS entry point called to signify completion of a packet send.
+ We pick up and complete the Write IRP corresponding to this packet.
+
+Arguments:
+
+ ProtocolBindingContext - pointer to open context
+ pNetBufferList - NetBufferList that completed send
+ SendCompleteFlags - Specifies if the caller is at DISPATCH level
+
+Return Value:
+
+ None
+
+--*/
+{
+ PIRP pIrp;
+ PIO_STACK_LOCATION pIrpSp;
+ PNDISPROT_OPEN_CONTEXT pOpenContext;
+ PNET_BUFFER_LIST CurrNetBufferList = NULL;
+ PNET_BUFFER_LIST NextNetBufferList;
+ NDIS_STATUS CompletionStatus;
+ BOOLEAN DispatchLevel;
+
+ pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
+ NPROT_STRUCT_ASSERT(pOpenContext, oc);
+ DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendCompleteFlags);
+
+ for (CurrNetBufferList = pNetBufferList;
+ CurrNetBufferList != NULL;
+ CurrNetBufferList = NextNetBufferList)
+ {
+ NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(CurrNetBufferList);
+
+ pIrp = NPROT_IRP_FROM_SEND_NBL(CurrNetBufferList);
+
+ IoAcquireCancelSpinLock(&pIrp->CancelIrql);
+ IoSetCancelRoutine(pIrp, NULL);
+ pIrp->Tail.Overlay.DriverContext[0] = NULL;
+ pIrp->Tail.Overlay.DriverContext[1] = NULL;
+ IoReleaseCancelSpinLock(pIrp->CancelIrql);
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, DispatchLevel);
+
+ NPROT_REMOVE_ENTRY_LIST(&pIrp->Tail.Overlay.ListEntry);
+
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, DispatchLevel);
+
+ CompletionStatus = NET_BUFFER_LIST_STATUS(CurrNetBufferList);
+
+
+ //
+ // We are done with the NDIS_PACKET:
+ //
+ NPROT_DEREF_SEND_NBL(CurrNetBufferList, DispatchLevel);
+
+ //
+ // Complete the Write IRP with the right status.
+ //
+ pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
+ if (CompletionStatus == NDIS_STATUS_SUCCESS)
+ {
+ pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length;
+ pIrp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ pIrp->IoStatus.Information = 0;
+ pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ }
+
+ DEBUGP(DL_INFO, ("SendComplete: NetBufferList %p/IRP %p/Length %d "
+ "completed with status %x\n",
+ CurrNetBufferList, pIrp, pIrp->IoStatus.Information, pIrp->IoStatus.Status));
+
+ IoCompleteRequest(pIrp, IO_NO_INCREMENT);
+
+ NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, DispatchLevel);
+ pOpenContext->PendedSendCount--;
+
+ if ((NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_CLOSING))
+ && (pOpenContext->PendedSendCount == 0))
+ {
+ ASSERT(pOpenContext->ClosingEvent != NULL);
+ NPROT_SIGNAL_EVENT(pOpenContext->ClosingEvent);
+ pOpenContext->ClosingEvent = NULL;
+ }
+ NPROT_RELEASE_LOCK(&pOpenContext->Lock, DispatchLevel);
+
+ NPROT_DEREF_OPEN(pOpenContext); // send complete - dequeued send IRP
+ }
+
+}
+
+
diff --git a/network/ndis/ndisprot/6x/test/prottest.c b/network/ndis/ndisprot/6x/test/prottest.c
new file mode 100644
index 00000000..54af3ddc
--- /dev/null
+++ b/network/ndis/ndisprot/6x/test/prottest.c
@@ -0,0 +1,665 @@
+//
+// UIOTEST.C
+//
+// Test program for ndisprot.sys
+//
+// usage: UIOTEST [options] <devicename>
+//
+// options:
+// -e: Enumerate devices
+// -r: Read
+// -w: Write (default)
+// -l <length>: length of each packet (default: %d)\n", PacketLength
+// -n <count>: number of packets (defaults to infinity)
+// -m <MAC address> (defaults to local MAC)
+//
+
+#pragma warning(disable:4201) // nameless struct/union
+#pragma warning(disable:4127) // conditional expression is constant
+
+#include <windows.h>
+#include <winioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <ctype.h>
+#include <malloc.h>
+
+#include <winerror.h>
+#include <winsock.h>
+
+#include <ntddndis.h>
+#include "protuser.h"
+
+// this is needed to prevent comppiler from complaining about
+// pragma prefast statements below
+#ifndef _PREFAST_
+ #pragma warning(disable:4068)
+#endif
+
+#ifndef NDIS_STATUS
+#define NDIS_STATUS ULONG
+#endif
+
+#if DBG
+#define DEBUGP(stmt) printf stmt
+#else
+#define DEBUGP(stmt)
+#endif
+
+#define PRINTF(stmt) printf stmt
+
+#ifndef MAC_ADDR_LEN
+#define MAC_ADDR_LEN 6
+#endif
+
+#define MAX_NDIS_DEVICE_NAME_LEN 256
+
+CHAR NdisProtDevice[] = "\\\\.\\\\NdisProt";
+CHAR * pNdisProtDevice = &NdisProtDevice[0];
+
+BOOLEAN DoEnumerate = FALSE;
+BOOLEAN DoReads = FALSE;
+INT NumberOfPackets = -1;
+ULONG PacketLength = 100;
+UCHAR SrcMacAddr[MAC_ADDR_LEN];
+UCHAR DstMacAddr[MAC_ADDR_LEN];
+BOOLEAN bDstMacSpecified = FALSE;
+CHAR * pNdisDeviceName = "JUNK";
+USHORT EthType = 0x8e88;
+BOOLEAN bUseFakeAddress = FALSE;
+UCHAR FakeSrcMacAddr[MAC_ADDR_LEN] = {0};
+
+
+#include <pshpack1.h>
+
+typedef struct _ETH_HEADER
+{
+ UCHAR DstAddr[MAC_ADDR_LEN];
+ UCHAR SrcAddr[MAC_ADDR_LEN];
+ USHORT EthType;
+} ETH_HEADER, *PETH_HEADER;
+
+#include <poppack.h>
+
+
+VOID
+PrintUsage()
+{
+ PRINTF(("usage: PROTTEST [options] <devicename>\n"));
+ PRINTF(("options:\n"));
+ PRINTF((" -e: Enumerate devices\n"));
+ PRINTF((" -r: Read\n"));
+ PRINTF((" -w: Write (default)\n"));
+ PRINTF((" -l <length>: length of each packet (default: %d)\n", PacketLength));
+ PRINTF((" -n <count>: number of packets (defaults to infinity)\n"));
+ PRINTF((" -m <MAC address> (defaults to local MAC)\n"));
+ PRINTF((" -f Use a fake address to send out the packets.\n"));
+
+
+}
+
+BOOL
+GetOptions(
+ INT argc,
+ _In_reads_(argc+1) CHAR *argv[]
+)
+{
+ INT i, j;
+ CHAR *pOption;
+ ULONG DstMacAddrUlong[MAC_ADDR_LEN];
+ INT RetVal;
+ PCSTR Parameter;
+
+ do
+ {
+ if (argc < 2)
+ {
+ PRINTF(("Missing <devicename> argument\n"));
+ return FALSE;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ pOption = argv[i];
+
+ if ((*pOption == '-') || (*pOption == '/'))
+ {
+ pOption++;
+ if (*pOption == '\0')
+ {
+ DEBUGP(("Badly formed option\n"));
+ return (FALSE);
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ if (i < argc - 2)
+ {
+ Parameter = argv[i+1];
+ }
+ else
+ {
+ Parameter = NULL;
+ }
+
+ switch (*pOption)
+ {
+ case 'e':
+ DoEnumerate = TRUE;
+ break;
+
+ case 'f':
+ bUseFakeAddress = TRUE;
+ break;
+
+ case 'r':
+ DoReads = TRUE;
+ break;
+
+ case 'w':
+ DoReads = FALSE;
+ break;
+
+ case 'l':
+
+ if (Parameter != NULL)
+ {
+ RetVal = atoi(Parameter);
+ if (RetVal != 0)
+ {
+ PacketLength = RetVal;
+ DEBUGP((" Option: PacketLength = %d\n", PacketLength));
+ i++;
+ break;
+ }
+ }
+ PRINTF(("Option l needs PacketLength parameter\n"));
+ return (FALSE);
+
+ case 'n':
+
+ if (Parameter != NULL)
+ {
+ RetVal = atoi(Parameter);
+ if (RetVal != 0)
+ {
+ NumberOfPackets = RetVal;
+ DEBUGP((" Option: NumberOfPackets = %d\n", NumberOfPackets));
+ i++;
+ break;
+ }
+ }
+ PRINTF(("Option n needs NumberOfPackets parameter\n"));
+ return (FALSE);
+
+ case 'm':
+
+ if (Parameter != NULL)
+ {
+ RetVal = sscanf_s(Parameter, "%2x:%2x:%2x:%2x:%2x:%2x",
+ &DstMacAddrUlong[0],
+ &DstMacAddrUlong[1],
+ &DstMacAddrUlong[2],
+ &DstMacAddrUlong[3],
+ &DstMacAddrUlong[4],
+ &DstMacAddrUlong[5]);
+
+ if (RetVal == 6)
+ {
+ for (j = 0; j < MAC_ADDR_LEN; j++)
+ {
+ DstMacAddr[j] = (UCHAR)DstMacAddrUlong[j];
+ }
+
+ DEBUGP((" Option: Dest MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ DstMacAddr[0],
+ DstMacAddr[1],
+ DstMacAddr[2],
+ DstMacAddr[3],
+ DstMacAddr[4],
+ DstMacAddr[5]));
+ bDstMacSpecified = TRUE;
+
+ i++;
+ break;
+ }
+ }
+
+ PRINTF(("Option m needs MAC address parameter\n"));
+ return (FALSE);
+
+ case '?':
+ return (FALSE);
+
+ default:
+ PRINTF(("Unknown option %c\n", *pOption));
+ return (FALSE);
+ }
+ }
+
+ pNdisDeviceName = argv[i];
+
+ }
+ while (FALSE);
+
+ return TRUE;
+}
+
+
+HANDLE
+OpenHandle(
+ _In_ PSTR pDeviceName
+)
+{
+ DWORD DesiredAccess;
+ DWORD ShareMode;
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL;
+
+ DWORD CreationDistribution;
+ DWORD FlagsAndAttributes;
+ HANDLE Handle;
+ DWORD BytesReturned;
+
+ DesiredAccess = GENERIC_READ|GENERIC_WRITE;
+ ShareMode = 0;
+ CreationDistribution = OPEN_EXISTING;
+ FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+
+ Handle = CreateFileA(
+ pDeviceName,
+ DesiredAccess,
+ ShareMode,
+ lpSecurityAttributes,
+ CreationDistribution,
+ FlagsAndAttributes,
+ NULL
+ );
+ if (Handle == INVALID_HANDLE_VALUE)
+ {
+ DEBUGP(("Creating file failed, error %x\n", GetLastError()));
+ return Handle;
+ }
+ //
+ // Wait for the driver to finish binding.
+ //
+ if (!DeviceIoControl(
+ Handle,
+ IOCTL_NDISPROT_BIND_WAIT,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL))
+ {
+ DEBUGP(("IOCTL_NDISIO_BIND_WAIT failed, error %x\n", GetLastError()));
+ CloseHandle(Handle);
+ Handle = INVALID_HANDLE_VALUE;
+ }
+
+ return (Handle);
+}
+
+
+BOOL
+OpenNdisDevice(
+ _In_ HANDLE Handle,
+ _In_ PCSTR pDeviceName
+)
+{
+ WCHAR wNdisDeviceName[MAX_NDIS_DEVICE_NAME_LEN];
+ INT wNameLength;
+ SIZE_T NameLength = strlen(pDeviceName);
+ DWORD BytesReturned;
+ SIZE_T i;
+
+
+ //
+ // Convert to unicode string - non-localized...
+ //
+ wNameLength = 0;
+ for (i = 0; i < NameLength && i < MAX_NDIS_DEVICE_NAME_LEN-1; i++)
+ {
+ wNdisDeviceName[i] = (WCHAR)pDeviceName[i];
+ wNameLength++;
+ }
+ wNdisDeviceName[i] = L'\0';
+
+ DEBUGP(("Trying to access NDIS Device: %ws\n", wNdisDeviceName));
+
+ return (DeviceIoControl(
+ Handle,
+ IOCTL_NDISPROT_OPEN_DEVICE,
+ (LPVOID)&wNdisDeviceName[0],
+ wNameLength*sizeof(WCHAR),
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL));
+
+}
+
+_Success_(return)
+BOOL
+GetSrcMac(
+ _In_ HANDLE Handle,
+ _Out_writes_bytes_(MAC_ADDR_LEN) PUCHAR pSrcMacAddr
+ )
+{
+ DWORD BytesReturned;
+ BOOLEAN bSuccess;
+ UCHAR QueryBuffer[sizeof(NDISPROT_QUERY_OID) + MAC_ADDR_LEN];
+ PNDISPROT_QUERY_OID pQueryOid;
+
+
+ DEBUGP(("Trying to get src mac address\n"));
+
+ pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
+ pQueryOid->Oid = OID_802_3_CURRENT_ADDRESS;
+ pQueryOid->PortNumber = 0;
+
+ bSuccess = (BOOLEAN)DeviceIoControl(
+ Handle,
+ IOCTL_NDISPROT_QUERY_OID_VALUE,
+ (LPVOID)&QueryBuffer[0],
+ sizeof(QueryBuffer),
+ (LPVOID)&QueryBuffer[0],
+ sizeof(QueryBuffer),
+ &BytesReturned,
+ NULL);
+
+ if (bSuccess)
+ {
+ DEBUGP(("GetSrcMac: IoControl success, BytesReturned = %d\n",
+ BytesReturned));
+
+#pragma warning(suppress:6202) // buffer overrun warning - enough space allocated in QueryBuffer
+ memcpy(pSrcMacAddr, pQueryOid->Data, MAC_ADDR_LEN);
+ }
+ else
+ {
+ DEBUGP(("GetSrcMac: IoControl failed: %d\n", GetLastError()));
+ }
+
+ return (bSuccess);
+}
+
+
+
+VOID
+DoReadProc(
+ HANDLE Handle
+ )
+{
+ PUCHAR pReadBuf = NULL;
+ INT ReadCount = 0;
+ BOOLEAN bSuccess;
+ ULONG BytesRead;
+
+ DEBUGP(("DoReadProc\n"));
+
+ do
+ {
+ pReadBuf = malloc(PacketLength);
+
+ if (pReadBuf == NULL)
+ {
+ PRINTF(("DoReadProc: failed to alloc %d bytes\n", PacketLength));
+ break;
+ }
+
+ ReadCount = 0;
+ while (TRUE)
+ {
+ bSuccess = (BOOLEAN)ReadFile(
+ Handle,
+ (LPVOID)pReadBuf,
+ PacketLength,
+ &BytesRead,
+ NULL);
+
+ if (!bSuccess)
+ {
+ PRINTF(("DoReadProc: ReadFile failed on Handle %p, error %x\n",
+ Handle, GetLastError()));
+ break;
+ }
+ ReadCount++;
+
+ DEBUGP(("DoReadProc: read pkt # %d, %d bytes\n", ReadCount, BytesRead));
+
+ if ((NumberOfPackets != -1) && (ReadCount == NumberOfPackets))
+ {
+ break;
+ }
+ }
+ }
+ while (FALSE);
+
+ if (pReadBuf)
+ {
+ free(pReadBuf);
+ }
+
+ PRINTF(("DoReadProc finished: read %d packets\n", ReadCount));
+
+}
+
+
+VOID
+DoWriteProc(
+ HANDLE Handle
+ )
+{
+ PUCHAR pWriteBuf = NULL;
+ PUCHAR pData;
+ UINT i;
+ INT SendCount;
+ PETH_HEADER pEthHeader;
+ DWORD BytesWritten;
+ BOOLEAN bSuccess;
+
+ DEBUGP(("DoWriteProc\n"));
+ SendCount = 0;
+
+ do
+ {
+ pWriteBuf = malloc(PacketLength);
+
+ if (pWriteBuf == NULL)
+ {
+ DEBUGP(("DoWriteProc: Failed to malloc %d bytes\n", PacketLength));
+ break;
+ }
+ pEthHeader = (PETH_HEADER)pWriteBuf;
+ pEthHeader->EthType = EthType;
+
+ if (bUseFakeAddress)
+ {
+ memcpy(pEthHeader->SrcAddr, FakeSrcMacAddr, MAC_ADDR_LEN);
+ }
+ else
+ {
+ memcpy(pEthHeader->SrcAddr, SrcMacAddr, MAC_ADDR_LEN);
+ }
+
+ memcpy(pEthHeader->DstAddr, DstMacAddr, MAC_ADDR_LEN);
+
+ pData = (PUCHAR)(pEthHeader + 1);
+ for (i = 0; i < PacketLength - sizeof(ETH_HEADER); i++)
+ {
+ *pData++ = (UCHAR)i;
+ }
+
+ SendCount = 0;
+
+ while (TRUE)
+ {
+
+ bSuccess = (BOOLEAN)WriteFile(
+ Handle,
+ pWriteBuf,
+ PacketLength,
+ &BytesWritten,
+ NULL);
+ if (!bSuccess)
+ {
+ PRINTF(("DoWriteProc: WriteFile failed on Handle %p\n", Handle));
+ break;
+ }
+ SendCount++;
+
+ DEBUGP(("DoWriteProc: sent %d bytes\n", BytesWritten));
+
+ if ((NumberOfPackets != -1) && (SendCount == NumberOfPackets))
+ {
+ break;
+ }
+ }
+
+ }
+ while (FALSE);
+
+ if (pWriteBuf)
+ {
+ free(pWriteBuf);
+ }
+
+ PRINTF(("DoWriteProc: finished sending %d packets of %d bytes each\n",
+ SendCount, PacketLength));
+}
+
+VOID
+EnumerateDevices(
+ HANDLE Handle
+ )
+{
+ typedef __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) QueryBindingCharBuf;
+ QueryBindingCharBuf Buf[1024];
+ DWORD BufLength = sizeof(Buf);
+ DWORD BytesWritten;
+ DWORD i;
+ PNDISPROT_QUERY_BINDING pQueryBinding;
+
+ pQueryBinding = (PNDISPROT_QUERY_BINDING)Buf;
+
+ i = 0;
+ for (pQueryBinding->BindingIndex = i;
+ /* NOTHING */;
+ pQueryBinding->BindingIndex = ++i)
+ {
+ if (DeviceIoControl(
+ Handle,
+ IOCTL_NDISPROT_QUERY_BINDING,
+ pQueryBinding,
+ sizeof(NDISPROT_QUERY_BINDING),
+ Buf,
+ BufLength,
+ &BytesWritten,
+ NULL))
+ {
+ PRINTF(("%2d. %ws\n - %ws\n",
+ pQueryBinding->BindingIndex,
+ (WCHAR *)((PUCHAR)pQueryBinding + pQueryBinding->DeviceNameOffset),
+ (WCHAR *)((PUCHAR )pQueryBinding + pQueryBinding->DeviceDescrOffset)));
+
+ memset(Buf, 0, BufLength);
+ }
+ else
+ {
+ ULONG rc = GetLastError();
+ if (rc != ERROR_NO_MORE_ITEMS)
+ {
+ PRINTF(("EnumerateDevices: terminated abnormally, error %d\n", rc));
+ }
+ break;
+ }
+ }
+}
+
+
+
+
+VOID __cdecl
+main(
+ INT argc,
+ _In_reads_(argc+1) LPSTR *argv
+)
+{
+ HANDLE DeviceHandle;
+
+ DeviceHandle = INVALID_HANDLE_VALUE;
+
+ do
+ {
+ if (!GetOptions(argc, argv))
+ {
+ PrintUsage();
+ break;
+ }
+
+ DeviceHandle = OpenHandle(pNdisProtDevice);
+
+ if (DeviceHandle == INVALID_HANDLE_VALUE)
+ {
+ PRINTF(("Failed to open %s\n", pNdisProtDevice));
+ break;
+ }
+
+ if (DoEnumerate)
+ {
+ EnumerateDevices(DeviceHandle);
+ break;
+ }
+
+ if (!OpenNdisDevice(DeviceHandle, pNdisDeviceName))
+ {
+ PRINTF(("Failed to access %s\n", pNdisDeviceName));
+ break;
+ }
+
+ DEBUGP(("Opened device %s successfully!\n", pNdisDeviceName));
+
+ if (!GetSrcMac(DeviceHandle, SrcMacAddr))
+ {
+ PRINTF(("Failed to obtain local MAC address\n"));
+ break;
+ }
+
+
+ DEBUGP(("Got local MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ SrcMacAddr[0],
+ SrcMacAddr[1],
+ SrcMacAddr[2],
+ SrcMacAddr[3],
+ SrcMacAddr[4],
+ SrcMacAddr[5]));
+
+ if (!bDstMacSpecified)
+ {
+ memcpy(DstMacAddr, SrcMacAddr, MAC_ADDR_LEN);
+ }
+
+ if (DoReads)
+ {
+ DoReadProc(DeviceHandle);
+ }
+ else
+ {
+ DoWriteProc(DeviceHandle);
+ DoReadProc(DeviceHandle);
+ }
+
+ }
+ while (FALSE);
+
+ if (DeviceHandle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(DeviceHandle);
+ }
+}
diff --git a/network/ndis/ndisprot/6x/test/prottest.vcxproj b/network/ndis/ndisprot/6x/test/prottest.vcxproj
new file mode 100644
index 00000000..7706c8e3
--- /dev/null
+++ b/network/ndis/ndisprot/6x/test/prottest.vcxproj
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{0AD0B8E0-5A3E-43FE-8E27-E5BB3DB184B0}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{B8B7CF7B-163A-4705-B726-3B7251D8BD10}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>prottest</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>prottest</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>prottest</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>prottest</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE=1</PreprocessorDefinitions>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32WIN_</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);user32.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);user32.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);user32.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);user32.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="prottest.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/network/ndis/ndisprot/6x/test/prottest.vcxproj.Filters b/network/ndis/ndisprot/6x/test/prottest.vcxproj.Filters
new file mode 100644
index 00000000..8b87abfa
--- /dev/null
+++ b/network/ndis/ndisprot/6x/test/prottest.vcxproj.Filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{5DB43F2D-E248-4063-B2E6-D0F81FCF5D84}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{3B8958F0-D888-4CE4-9473-3300FDF5A2B3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{35E32097-01E2-4113-877C-7E88FDCD0FAA}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="prottest.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file