├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── docs ├── development.md ├── fnlwf.md ├── fnmp.md ├── fnsock.md ├── isr.md ├── release.md └── wskclient.md ├── inc ├── fnioctl_km.h ├── fnioctl_um.h ├── fniotypes.h ├── fnlwfapi.h ├── fnlwfapistatus_km.h ├── fnlwfapistatus_um.h ├── fnlwfioctl.h ├── fnmpapi.h ├── fnmpapiconfig.h ├── fnmpapistatus_km.h ├── fnmpapistatus_um.h ├── fnmpioctl.h ├── fnoid.h ├── fnsock.h ├── invokesystemrelay.h ├── invokesystemrelayioctl.h ├── ndisoobtypes.h ├── pkthlp.h └── wskclient.h ├── src ├── common │ ├── inc │ │ ├── bounce.h │ │ ├── fnassert.h │ │ ├── fnio.h │ │ ├── fnrefcount.h │ │ ├── fnrtl.h │ │ ├── fnstatusconvert.h │ │ ├── fntimer.h │ │ └── pooltag.h │ └── lib │ │ ├── bounce │ │ ├── bounce.c │ │ └── bounce.vcxproj │ │ └── fnio │ │ ├── enqueue.c │ │ ├── filter.c │ │ ├── fnio.vcxproj │ │ ├── ioctlbounce.c │ │ ├── ioctlbounce.h │ │ └── precomp.h ├── isr │ ├── svc │ │ ├── isrsvc.vcxproj │ │ ├── main.cpp │ │ └── trace.h │ └── sys │ │ ├── client.c │ │ ├── client.h │ │ ├── dispatch.c │ │ ├── dispatch.h │ │ ├── isrdrv.vcxproj │ │ ├── precomp.h │ │ ├── requestqueue.c │ │ ├── requestqueue.h │ │ ├── service.c │ │ ├── service.h │ │ └── trace.h ├── lwf │ └── sys │ │ ├── default.c │ │ ├── default.h │ │ ├── dispatch.c │ │ ├── dispatch.h │ │ ├── filter.c │ │ ├── filter.h │ │ ├── fnlwf.rc │ │ ├── fnlwf.vcxproj │ │ ├── inf │ │ └── fnlwf.inx │ │ ├── oid.c │ │ ├── oid.h │ │ ├── precomp.h │ │ ├── rx.c │ │ ├── rx.h │ │ ├── status.c │ │ ├── status.h │ │ ├── trace.c │ │ ├── trace.h │ │ ├── tx.c │ │ └── tx.h ├── mp │ └── sys │ │ ├── dispatch.c │ │ ├── dispatch.h │ │ ├── exclusive.c │ │ ├── exclusive.h │ │ ├── fnmp.rc │ │ ├── fnmp.vcxproj │ │ ├── inf │ │ └── fnmp.inx │ │ ├── miniport.c │ │ ├── miniport.h │ │ ├── oid.c │ │ ├── oid.h │ │ ├── packages.config │ │ ├── port.c │ │ ├── port.h │ │ ├── precomp.h │ │ ├── rss.c │ │ ├── rss.h │ │ ├── rx.c │ │ ├── rx.h │ │ ├── shared.c │ │ ├── shared.h │ │ ├── trace.c │ │ ├── trace.h │ │ ├── tx.c │ │ └── tx.h ├── sock │ ├── km │ │ ├── fnsock_km.def │ │ ├── fnsock_km.vcxproj │ │ └── sock.c │ ├── trace.h │ └── um │ │ ├── fnsock_um.vcxproj │ │ └── sock.c ├── wnt.cpp.kernel.props ├── wnt.cpp.props └── wskclient │ ├── wskclient.c │ └── wskclient.vcxproj ├── test ├── cxplat │ ├── inc │ │ └── cxplat.h │ └── lib │ │ ├── km │ │ ├── cxplat.cpp │ │ └── cxplat_km.vcxproj │ │ ├── trace.h │ │ └── um │ │ ├── cxplat.cpp │ │ └── cxplat_um.vcxproj ├── debugcrt │ └── debugcrt.vcxproj ├── functional │ ├── bin │ │ ├── fnfunctionaltests.vcxproj │ │ ├── km │ │ │ ├── control.cpp │ │ │ ├── driver.cpp │ │ │ ├── fnfunctionaltestdrv.rc │ │ │ ├── fnfunctionaltestdrv.vcxproj │ │ │ ├── fnfunctionaltestdrvioctl.h │ │ │ └── trace.h │ │ └── main.cpp │ ├── fntest.h │ ├── fntrace.h │ ├── lib │ │ ├── fnfunctionaltestlib_km.vcxproj │ │ ├── fnfunctionaltestlib_um.vcxproj │ │ └── tests.cpp │ ├── testframeworkapi.h │ └── tests.h └── pkthlp │ ├── km │ ├── pkthlp_km.vcxproj │ └── precomp.h │ ├── pkthlp.c │ └── um │ ├── pkthlp_um.vcxproj │ └── precomp.h ├── tools ├── build.ps1 ├── common.ps1 ├── create-devkit.ps1 ├── create-nuget-package.ps1 ├── create-runtimekit.ps1 ├── fntrace.wprp ├── functional.ps1 ├── log.ps1 ├── nuget │ ├── README.md │ ├── win-net-test.nuspec.in │ └── win-net-test.props ├── prepare-machine.ps1 ├── prepare-onebranch-build.ps1 └── setup.ps1 ├── version.json └── wnt.sln /.gitattributes: -------------------------------------------------------------------------------- 1 | # Standardize line endings for all text files. 2 | * text eol=auto 3 | 4 | # Ensure text files stay text 5 | *.inx text 6 | *.xml text 7 | 8 | # Ensure binary files stay binary 9 | *.pgd binary 10 | *.png binary 11 | *.jpg binary 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | 2 | version: 2 3 | updates: 4 | 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "weekly" 9 | day: "saturday" 10 | 11 | - package-ecosystem: "gitsubmodule" 12 | directory: "/" 13 | schedule: 14 | interval: "weekly" 15 | day: "saturday" 16 | 17 | - package-ecosystem: nuget 18 | directory: "/" 19 | schedule: 20 | interval: "weekly" 21 | day: "saturday" 22 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/ndis-driver-library"] 2 | path = submodules/ndis-driver-library 3 | url = https://github.com/microsoft/ndis-driver-library 4 | [submodule "submodules/wil"] 5 | path = submodules/wil 6 | url = https://github.com/microsoft/wil 7 | [submodule "submodules/net-offloads"] 8 | path = submodules/net-offloads 9 | url = https://github.com/microsoft/net-offloads.git 10 | [submodule "submodules/undocked"] 11 | path = submodules/undocked 12 | url = https://github.com/microsoft/undocked.git 13 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Windows Network Testing 2 | 3 | [![CI](https://github.com/microsoft/win-net-test/actions/workflows/ci.yml/badge.svg)](https://github.com/microsoft/win-net-test/actions/workflows/ci.yml) 4 | 5 | This repository hosts tools used to test networking on Windows. 6 | 7 | ## Documentation 8 | 9 | * [Functional Miniport (FnMp)](./docs/fnmp.md) 10 | * [Functional Lwf (FnLwf)](./docs/fnlwf.md) 11 | * [Functional Sockets (FnSock)](./docs/fnsock.md) 12 | * [Invoke System Relay (Isr)](./docs/isr.md) 13 | * [WSK Client (wskclient)](./docs/wskclient.md) 14 | * [Development](./docs/development.md) 15 | 16 | ## Contributing 17 | 18 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 19 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 20 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 21 | 22 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 23 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 24 | provided by the bot. You will only need to do this once across all repos using our CLA. 25 | 26 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 27 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 28 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 29 | 30 | ## Trademarks 31 | 32 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 33 | trademarks or logos is subject to and must follow 34 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 35 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 36 | Any use of third-party trademarks or logos are subject to those third-party's policies. 37 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet) and [Xamarin](https://github.com/xamarin). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/development.md: -------------------------------------------------------------------------------- 1 | # How to develop 2 | 3 | ## Get the code 4 | 5 | Clone this repo and ensure all submodules are cloned with the `--recursive` option: 6 | 7 | ``` 8 | git clone https://github.com/microsoft/win-net-test.git --recursive 9 | ``` 10 | 11 | Or, if the repo was already cloned nonrecursively: 12 | 13 | ``` 14 | git submodule update --init --recursive 15 | ``` 16 | 17 | ## Build the code 18 | 19 | ### Prerequisites 20 | 21 | - [Visual Studio](https://visualstudio.microsoft.com/downloads/) 22 | - Visual Studio 2022 is recommended; Visual Studio 2019 or newer is required. 23 | - Latest Spectre-mitigated libs (via "Individual components" section of Visual Studio Installer) 24 | - [Windows Driver Kit](https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk) 25 | - WDK for Windows 11, version 22H2 (version 10.0.22621.x) is recommended; WDK for Windows Server 2022 LTSC or newer is required. 26 | 27 | ### Building 28 | 29 | Run in a Visual Studio "Developer Command Prompt": 30 | 31 | ```PowerShell 32 | .\tools\build.ps1 33 | ``` 34 | 35 | ## Test the code 36 | 37 | The test machine must have the "artifacts" and "tools" directories from the repo, either 38 | by cloning the repo and building the code or by copying them from another system. The 39 | file layout is assumed to be identical to that of the repo. 40 | 41 | ### Running functional tests 42 | 43 | One-time setup: 44 | 45 | ```Powershell 46 | .\tools\prepare-machine.ps1 -ForFunctionalTest 47 | ``` 48 | 49 | Running the tests: 50 | 51 | ```Powershell 52 | .\tools\functional.ps1 53 | ``` 54 | 55 | Querying the list of test cases: 56 | 57 | ```Powershell 58 | .\tools\functional.ps1 -ListTestCases 59 | ``` 60 | 61 | Running a specific test case: 62 | 63 | ```Powershell 64 | .\tools\functional.ps1 -TestCaseFilter "Name=MpBasicRx" 65 | ``` 66 | 67 | After the test, convert the logs: 68 | 69 | ```Powershell 70 | .\tools\log.ps1 -Convert -Name fnfunc 71 | ``` 72 | -------------------------------------------------------------------------------- /docs/fnlwf.md: -------------------------------------------------------------------------------- 1 | # Functional Lightweight Filter (FnLwf) 2 | 3 | This tool provides an [NDIS filter driver](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/ndis-filter-drivers) 4 | that is used as a hook into the middle of the [NDIS networking stack](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/ndis-driver-stack). 5 | 6 | ## API 7 | 8 | Test code can interact with the filter using the [fnlwfapi](../inc/fnlwfapi.h). 9 | Hooks for both the NDIS data path and the NDIS control are supported. 10 | -------------------------------------------------------------------------------- /docs/fnmp.md: -------------------------------------------------------------------------------- 1 | # Functional Miniport (FnMp) 2 | 3 | This tool provides an [NDIS miniport driver](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/ndis-miniport-drivers2) 4 | that is used as a hook into the lowest part of the [NDIS networking stack](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/ndis-driver-stack). 5 | 6 | ## API 7 | 8 | Test code can interact with the miniport using the [fnmpapi](../inc/fnmpapi.h). 9 | Hooks for both the NDIS data path and the NDIS control are supported. 10 | -------------------------------------------------------------------------------- /docs/fnsock.md: -------------------------------------------------------------------------------- 1 | # Functional Sockets (FnSock) 2 | 3 | This library provides a simple sockets API for test code that runs in both user and kernel mode. 4 | 5 | ## API 6 | 7 | Test code can leverage the API by including [fnsock.h](../inc/fnsock.h) and linking against fnsock_um.lib/fnsock_km.lib. 8 | -------------------------------------------------------------------------------- /docs/isr.md: -------------------------------------------------------------------------------- 1 | # Invoke System Relay (Isr) 2 | 3 | User-mode tests sometimes take a dependency on the user-mode only system() API. When porting these tests to kernel-mode, there is no straightforward translation. 4 | This tool provides a system()-like kernel-mode API that relays commands to user-mode, executes them, then returns the result. 5 | 6 | ## API 7 | 8 | Kernel-mode test code can interact with the API using [invokesystemrelay.h](../inc/invokesystemrelay.h). 9 | -------------------------------------------------------------------------------- /docs/release.md: -------------------------------------------------------------------------------- 1 | # Release 2 | 3 | All active development occurs on GitHub in the `main` branch. When it is time to release, the code is forked into a 4 | release branch where it is considered stable and will generally only receive servicing for security and bug fixes. 5 | New releases may be created at any time. 6 | 7 | ## Branches 8 | 9 | win-net-test has two primary types of branches: 10 | 11 | * **Main** - Main is the active development branch, and receives security and bug fixes just the same as the release 12 | branches. However, it may experience breaking changes as we develop new features. For this reason, it is recommended 13 | that no dependencies be taken on the main branch. 14 | 15 | * **Release** - Release branches only receive security and bug fixes, and are considered stable. There should be no 16 | breaking changes in these branches, and they can be used for stable products. 17 | 18 | ## Tags 19 | 20 | Tags are used for actual releases. Tags are created from the release branches, and are used to mark the code at a 21 | specific point in time. Tags are immutable, and should not be changed once created. 22 | 23 | ## Versioning 24 | 25 | win-net-test uses [Semantic Versioning](https://semver.org/) for versioning releases. 26 | The version number is defined in the release branch name and can also be found in the [version.json](../version.json) 27 | file. SemVer specifies that: 28 | 29 | - **Major** version changes indicate **breaking changes**. This means that code that worked in a previous major version 30 | may not work in the new major version. This is generally due to API changes, but can also be due to changes in 31 | behavior. 32 | 33 | - **Minor** version changes indicate **new features**. This means that code that worked in a previous minor version will 34 | continue to work in the new minor version. This is generally due to new APIs or features being added. 35 | 36 | - **Patch** version changes indicate **bug fixes**. This means that code that worked in a previous patch version will 37 | continue to work in the new patch version. 38 | 39 | win-net-test uses the `release/(major).(minor)` naming convention for all release **branches**. 40 | For example, the first official release branch will be `release/1.0`. 41 | 42 | win-net-test then uses the `v(major).(minor).(patch)` naming convention for all **tags**. 43 | For example, the first official release will be `v1.0.0`. 44 | 45 | # Release Process 46 | 47 | The following sections are generally for the maintainers of win-net-test. 48 | 49 | ## How to create a new release 50 | 51 | It is time for a new release! 52 | The process is somewhat manual, here is the step-by-step breakdown. 53 | 54 | ### Bump the version number 55 | 56 | Bump up the version number in `version.json`, respecting semantic versionning. 57 | Complete the pull request in the `main` branch, or in the `release/(major).(minor)` branch if patching an existing 58 | release. 59 | 60 | ### Create a release branch 61 | 62 | Create a new `release/(major).(minor)` branch from `main` from the last commit to include in the new release. 63 | 64 | ### Create a new tag 65 | 66 | From a command line in the `win-net-test` repos: 67 | 68 | - `git fetch` 69 | - `git checkout release/(major).(minor)` 70 | - `git tag v(major).(minor).(patch)` 71 | - `git push --tags` 72 | 73 | ### Gather artifacts 74 | 75 | Wait for the CI to successfully complete its run on the `release/(major).(minor)` branch, on the 76 | **commit tagged for the release**. 77 | Then, download the following artifacts from the run summary: 78 | 79 | - release_dev_artifacts_Release 80 | - release_runtime_artifacts_Release_arm64 81 | - release_runtime_artifacts_Release_x64 82 | 83 | Locally, extract them and collect the inner archives: 84 | - win-net-test.(major).(minor).(patch).nupkg 85 | - fn-runtime-arm64.zip 86 | - fn-runtime-x64.zip 87 | 88 | ## Create a new release in GitHub 89 | 90 | - Goto the the [Release section](https://github.com/microsoft/win-net-test/releases) 91 | - Draft a new release from the `release/(major).(minor)` branch 92 | - Select the tag `v(major).(minor).(patch)` 93 | - Clean up the release notes 94 | - Attach the archives and the Nuget package gathered previously 95 | - Publish it! 🎉 96 | 97 | ## Publish the NuGet package 98 | 99 | Go to [win-net-test on Nuget.org](https://www.nuget.org/packages/win-net-test). 100 | If you are not an owner yet, reach out to an owner for help. 101 | 102 | - Copy your API key or create a new one if needed 103 | - `nuget push .\win-net-test.(major).(minor).(patch).nupkg -Source https://api.nuget.org/v3/index.json` 104 | 105 | [Detailed instructions for publishing a NuGet package](https://learn.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package-using-visual-studio?tabs=nuget#publish-the-package) 106 | -------------------------------------------------------------------------------- /docs/wskclient.md: -------------------------------------------------------------------------------- 1 | # WSK Client (wskclient) 2 | 3 | This library provides a convenience wrapper around the [WSK API](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/introduction-to-winsock-kernel), hiding cumbersome details like NMR, IRP and MDL management. The common socket operations are provided in both synchronous and asynchronous flavors. 4 | 5 | ## API 6 | 7 | Test code can leverage the API by including [wskclient.h](../inc/wskclient.h) and linking against wskclient.lib. Kernel-mode only. 8 | -------------------------------------------------------------------------------- /inc/fnioctl_km.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | _IRQL_requires_max_(PASSIVE_LEVEL) 11 | NTSYSAPI 12 | NTSTATUS 13 | NTAPI 14 | ZwCreateEvent ( 15 | _Out_ PHANDLE EventHandle, 16 | _In_ ACCESS_MASK DesiredAccess, 17 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 18 | _In_ EVENT_TYPE EventType, 19 | _In_ BOOLEAN InitialState 20 | ); 21 | 22 | _When_(Timeout == NULL, _IRQL_requires_max_(APC_LEVEL)) 23 | _When_(Timeout->QuadPart != 0, _IRQL_requires_max_(APC_LEVEL)) 24 | _When_(Timeout->QuadPart == 0, _IRQL_requires_max_(DISPATCH_LEVEL)) 25 | NTSYSAPI 26 | NTSTATUS 27 | NTAPI 28 | ZwWaitForSingleObject( 29 | _In_ HANDLE Handle, 30 | _In_ BOOLEAN Alertable, 31 | _In_opt_ PLARGE_INTEGER Timeout 32 | ); 33 | 34 | typedef HANDLE FNIOCTL_HANDLE; 35 | 36 | inline 37 | NTSTATUS 38 | FnIoctlOpen( 39 | _In_ const WCHAR *DeviceName, 40 | _In_ UINT32 Disposition, 41 | _In_opt_ VOID *EaBuffer, 42 | _In_ UINT32 EaLength, 43 | _Out_ FNIOCTL_HANDLE *Handle 44 | ) 45 | { 46 | NTSTATUS Status; 47 | IO_STATUS_BLOCK IoStatusBlock; 48 | OBJECT_ATTRIBUTES ObjectAttributes; 49 | UNICODE_STRING UnicodeDeviceName; 50 | 51 | RtlInitUnicodeString(&UnicodeDeviceName, DeviceName); 52 | InitializeObjectAttributes( 53 | &ObjectAttributes, &UnicodeDeviceName, 54 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 55 | 56 | Status = 57 | ZwCreateFile( 58 | Handle, 59 | GENERIC_READ | GENERIC_WRITE, 60 | &ObjectAttributes, 61 | &IoStatusBlock, 62 | NULL, 63 | FILE_ATTRIBUTE_NORMAL, 64 | FILE_SHARE_WRITE, 65 | Disposition, 66 | 0, 67 | EaBuffer, 68 | EaLength); 69 | 70 | 71 | return Status; 72 | } 73 | 74 | inline 75 | VOID 76 | FnIoctlClose( 77 | _In_ FNIOCTL_HANDLE Handle 78 | ) 79 | { 80 | ZwClose(Handle); 81 | } 82 | 83 | inline 84 | NTSTATUS 85 | FnIoctl( 86 | _In_ FNIOCTL_HANDLE Handle, 87 | _In_ UINT32 Operation, 88 | _In_opt_ VOID *InBuffer, 89 | _In_ UINT32 InBufferSize, 90 | _Out_opt_ VOID *OutBuffer, 91 | _In_ UINT32 OutputBufferSize, 92 | _Out_opt_ UINT32 *BytesReturned, 93 | _In_opt_ VOID *Overlapped 94 | ) 95 | { 96 | NTSTATUS Status; 97 | IO_STATUS_BLOCK IoStatusBlock; 98 | OBJECT_ATTRIBUTES EventAttributes; 99 | HANDLE Event = NULL; 100 | 101 | UNREFERENCED_PARAMETER(Overlapped); 102 | 103 | if (BytesReturned != NULL) { 104 | *BytesReturned = 0; 105 | } 106 | 107 | InitializeObjectAttributes( 108 | &EventAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); 109 | 110 | Status = 111 | ZwCreateEvent( 112 | &Event, 113 | EVENT_ALL_ACCESS, 114 | &EventAttributes, 115 | SynchronizationEvent, 116 | FALSE); 117 | if (!NT_SUCCESS(Status)) { 118 | goto Exit; 119 | } 120 | 121 | Status = 122 | ZwDeviceIoControlFile( 123 | Handle, 124 | Event, 125 | NULL, 126 | NULL, 127 | &IoStatusBlock, 128 | Operation, 129 | InBuffer, 130 | InBufferSize, 131 | OutBuffer, 132 | OutputBufferSize); 133 | if (Status == STATUS_PENDING) { 134 | Status = ZwWaitForSingleObject(Event, FALSE, NULL); 135 | ASSERT(Status == STATUS_SUCCESS); 136 | if (!NT_SUCCESS(Status)) { 137 | goto Exit; 138 | } 139 | 140 | Status = IoStatusBlock.Status; 141 | } 142 | 143 | if (BytesReturned != NULL) { 144 | *BytesReturned = (UINT32)IoStatusBlock.Information; 145 | } 146 | 147 | Exit: 148 | 149 | if (Event != NULL) { 150 | ZwClose(Event); 151 | } 152 | 153 | return Status; 154 | } 155 | 156 | EXTERN_C_END 157 | -------------------------------------------------------------------------------- /inc/fnioctl_um.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | EXTERN_C_START 14 | 15 | #ifndef STATUS_SUCCESS 16 | #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) 17 | #endif 18 | 19 | #ifndef STATUS_UNSUCCESSFUL 20 | #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) 21 | #endif 22 | 23 | // 24 | // This file implements common file handle and IOCTL helpers. 25 | // 26 | 27 | // 28 | // This struct is defined in public kernel headers, but not user mode headers. 29 | // 30 | typedef struct _FILE_FULL_EA_INFORMATION { 31 | ULONG NextEntryOffset; 32 | UCHAR Flags; 33 | UCHAR EaNameLength; 34 | USHORT EaValueLength; 35 | CHAR EaName[1]; 36 | } FILE_FULL_EA_INFORMATION; 37 | 38 | typedef HANDLE FNIOCTL_HANDLE; 39 | 40 | inline 41 | HRESULT 42 | FnIoctlOpen( 43 | _In_ const WCHAR *DeviceName, 44 | _In_ UINT32 Disposition, 45 | _In_opt_ VOID *EaBuffer, 46 | _In_ UINT32 EaLength, 47 | _Out_ FNIOCTL_HANDLE *Handle 48 | ) 49 | { 50 | UNICODE_STRING DeviceNameUnicode; 51 | OBJECT_ATTRIBUTES ObjectAttributes; 52 | IO_STATUS_BLOCK IoStatusBlock; 53 | NTSTATUS Status; 54 | 55 | RtlInitUnicodeString(&DeviceNameUnicode, DeviceName); 56 | InitializeObjectAttributes( 57 | &ObjectAttributes, &DeviceNameUnicode, OBJ_CASE_INSENSITIVE, NULL, NULL); 58 | 59 | Status = 60 | NtCreateFile( 61 | Handle, 62 | GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 63 | &ObjectAttributes, 64 | &IoStatusBlock, 65 | NULL, 66 | 0L, 67 | FILE_SHARE_READ | FILE_SHARE_WRITE, 68 | Disposition, 69 | 0, 70 | EaBuffer, 71 | EaLength); 72 | 73 | return HRESULT_FROM_WIN32(RtlNtStatusToDosError(Status)); 74 | } 75 | 76 | inline 77 | VOID 78 | FnIoctlClose( 79 | _In_ FNIOCTL_HANDLE Handle 80 | ) 81 | { 82 | CloseHandle(Handle); 83 | } 84 | 85 | inline 86 | HRESULT 87 | FnIoctl( 88 | _In_ FNIOCTL_HANDLE Handle, 89 | _In_ UINT32 Operation, 90 | _In_opt_ VOID *InBuffer, 91 | _In_ UINT32 InBufferSize, 92 | _Out_opt_ VOID *OutBuffer, 93 | _In_ UINT32 OutputBufferSize, 94 | _Out_opt_ UINT32 *BytesReturned, 95 | _In_opt_ OVERLAPPED *Overlapped 96 | ) 97 | { 98 | NTSTATUS Status; 99 | IO_STATUS_BLOCK LocalIoStatusBlock = {0}; 100 | IO_STATUS_BLOCK *IoStatusBlock; 101 | HANDLE LocalEvent = NULL; 102 | HANDLE *Event; 103 | 104 | if (BytesReturned != NULL) { 105 | *BytesReturned = 0; 106 | } 107 | 108 | if (Overlapped == NULL) { 109 | IoStatusBlock = &LocalIoStatusBlock; 110 | Event = &LocalEvent; 111 | LocalEvent = CreateEventW(NULL, FALSE, FALSE, NULL); 112 | if (LocalEvent == NULL) { 113 | Status = STATUS_NO_MEMORY; 114 | goto Exit; 115 | } 116 | } else { 117 | IoStatusBlock = (IO_STATUS_BLOCK *)&Overlapped->Internal; 118 | Event = &Overlapped->hEvent; 119 | } 120 | 121 | IoStatusBlock->Status = STATUS_PENDING; 122 | 123 | Status = 124 | NtDeviceIoControlFile( 125 | Handle, *Event, NULL, NULL, IoStatusBlock, Operation, InBuffer, 126 | InBufferSize, OutBuffer, OutputBufferSize); 127 | 128 | if (Event == &LocalEvent && Status == STATUS_PENDING) { 129 | DWORD WaitResult = WaitForSingleObject(*Event, INFINITE); 130 | if (WaitResult != WAIT_OBJECT_0) { 131 | if (WaitResult != WAIT_FAILED) { 132 | Status = STATUS_UNSUCCESSFUL; 133 | } 134 | goto Exit; 135 | } 136 | 137 | Status = IoStatusBlock->Status; 138 | } 139 | 140 | if (BytesReturned != NULL) { 141 | *BytesReturned = (UINT32)IoStatusBlock->Information; 142 | } 143 | 144 | Exit: 145 | 146 | if (LocalEvent != NULL) { 147 | CloseHandle(LocalEvent); 148 | } 149 | 150 | return HRESULT_FROM_WIN32(RtlNtStatusToDosError(Status)); 151 | } 152 | 153 | EXTERN_C_END 154 | -------------------------------------------------------------------------------- /inc/fniotypes.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // This header contains definitions for data IO related IOCTLs supported by the 10 | // functional test miniport/lwf (fnmp/fnlwf). 11 | // 12 | 13 | #ifndef _KERNEL_MODE 14 | // 15 | // This header depends on the following headers included in the following order. 16 | // However, it is most likely too late to include these headers by the time this 17 | // header is included. 18 | // 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #endif 25 | 26 | EXTERN_C_START 27 | 28 | typedef struct _DATA_BUFFER { 29 | CONST UCHAR *VirtualAddress; 30 | UINT32 DataOffset; 31 | UINT32 DataLength; 32 | UINT32 BufferLength; 33 | } DATA_BUFFER; 34 | 35 | typedef struct _DATA_FRAME { 36 | DATA_BUFFER *Buffers; 37 | UINT16 BufferCount; 38 | 39 | #pragma warning(push) 40 | #pragma warning(disable:4201) // nonstandard extension used: nameless struct/union 41 | union { 42 | // 43 | // Used when submitting IO. 44 | // 45 | struct { 46 | UINT32 RssHashQueueId; 47 | NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO Checksum; 48 | NDIS_RSC_NBL_INFO Rsc; 49 | } Input; 50 | // 51 | // Used when retrieving filtered IO. 52 | // 53 | struct { 54 | PROCESSOR_NUMBER ProcessorNumber; 55 | UINT32 RssHash; 56 | NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO Checksum; 57 | NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO Lso; 58 | NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO Uso; 59 | } Output; 60 | }; 61 | #pragma warning(pop) 62 | } DATA_FRAME; 63 | 64 | typedef struct _DATA_FLUSH_OPTIONS { 65 | struct { 66 | UINT32 DpcLevel : 1; 67 | UINT32 LowResources : 1; 68 | UINT32 RssCpu : 1; 69 | } Flags; 70 | 71 | UINT32 RssCpuQueueId; 72 | } DATA_FLUSH_OPTIONS; 73 | 74 | // 75 | // Parameters for IOCTL_[RX|TX]_ENQUEUE. 76 | // 77 | 78 | typedef struct _DATA_ENQUEUE_IN { 79 | DATA_FRAME Frame; 80 | } DATA_ENQUEUE_IN; 81 | 82 | // 83 | // Parameters for IOCTL_[RX|TX]_FLUSH. 84 | // 85 | 86 | typedef struct _DATA_FLUSH_IN { 87 | DATA_FLUSH_OPTIONS Options; 88 | } DATA_FLUSH_IN; 89 | 90 | // 91 | // Parameters for IOCTL_[RX|TX]_FILTER. 92 | // 93 | 94 | typedef struct _DATA_FILTER_IN { 95 | const UCHAR *Pattern; 96 | const UCHAR *Mask; 97 | UINT32 Length; 98 | } DATA_FILTER_IN; 99 | 100 | // 101 | // Parameters for IOCTL_[RX|TX]_GET_FRAME. 102 | // 103 | 104 | typedef struct _DATA_GET_FRAME_IN { 105 | UINT32 Index; 106 | UINT32 SubIndex; 107 | } DATA_GET_FRAME_IN; 108 | 109 | // 110 | // Parameters for IOCTL_[RX|TX]_DEQUEUE_FRAME. 111 | // 112 | 113 | typedef struct _DATA_DEQUEUE_FRAME_IN { 114 | UINT32 Index; 115 | } DATA_DEQUEUE_FRAME_IN; 116 | 117 | // 118 | // The OID request interface. 119 | // 120 | 121 | typedef enum _FNIO_OID_REQUEST_INTERFACE { 122 | // 123 | // The regular, NDIS-serialized OID request interface. 124 | // 125 | OID_REQUEST_INTERFACE_REGULAR, 126 | 127 | // 128 | // The direct OID request interface. These requests are not serialized and 129 | // can be pended. 130 | // 131 | OID_REQUEST_INTERFACE_DIRECT, 132 | 133 | OID_REQUEST_INTERFACE_MAX 134 | } OID_REQUEST_INTERFACE; 135 | 136 | // 137 | // Helper type used by parameters for OID related IOCTLs. 138 | // 139 | 140 | typedef struct _OID_KEY_V0 { 141 | NDIS_OID Oid; 142 | NDIS_REQUEST_TYPE RequestType; 143 | OID_REQUEST_INTERFACE RequestInterface; 144 | } OID_KEY_V0; 145 | 146 | typedef struct _OID_KEY { 147 | NDIS_OID Oid; 148 | NDIS_REQUEST_TYPE RequestType; 149 | OID_REQUEST_INTERFACE RequestInterface; 150 | NDIS_PORT_NUMBER PortNumber; 151 | } OID_KEY; 152 | 153 | // 154 | // Offload interface. 155 | // 156 | 157 | typedef enum _FN_OFFLOAD_TYPE { 158 | FnOffloadCurrentConfig, 159 | FnOffloadHardwareCapabilities, 160 | } FN_OFFLOAD_TYPE; 161 | 162 | typedef struct _FN_OFFLOAD_OPTIONS { 163 | UINT32 GsoMaxOffloadSize; 164 | } FN_OFFLOAD_OPTIONS; 165 | 166 | EXTERN_C_END 167 | -------------------------------------------------------------------------------- /inc/fnlwfapistatus_km.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | #define FNLWFAPI_STATUS NTSTATUS 11 | #define FNLWFAPI_FAILED(X) !NT_SUCCESS(X) 12 | #define FNLWFAPI_SUCCEEDED(X) NT_SUCCESS(X) 13 | 14 | #define FNLWFAPI_STATUS_SUCCESS STATUS_SUCCESS 15 | #define FNLWFAPI_STATUS_NOT_FOUND STATUS_NOT_FOUND 16 | #define FNLWFAPI_STATUS_MORE_DATA STATUS_BUFFER_OVERFLOW 17 | #define FNLWFAPI_STATUS_NOT_READY STATUS_DEVICE_NOT_READY 18 | 19 | EXTERN_C_END 20 | -------------------------------------------------------------------------------- /inc/fnlwfapistatus_um.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | #define FNLWFAPI_STATUS HRESULT 11 | #define FNLWFAPI_FAILED(X) FAILED(X) 12 | #define FNLWFAPI_SUCCEEDED(X) SUCCEEDED(X) 13 | 14 | #define FNLWFAPI_STATUS_SUCCESS S_OK 15 | #define FNLWFAPI_STATUS_NOT_FOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND) 16 | #define FNLWFAPI_STATUS_MORE_DATA HRESULT_FROM_WIN32(ERROR_MORE_DATA) 17 | #define FNLWFAPI_STATUS_NOT_READY HRESULT_FROM_WIN32(ERROR_NOT_READY) 18 | 19 | EXTERN_C_END 20 | -------------------------------------------------------------------------------- /inc/fnlwfioctl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | #define FNLWF_IOCTL_CURRENT_VERSION 2 11 | 12 | #define FNLWF_DEVICE_NAME L"\\Device\\fnlwf" 13 | 14 | #define FNLWF_OPEN_PACKET_NAME "FnLwfOpenPacket0" 15 | 16 | // 17 | // Type of functional test LWF object to create or open. 18 | // 19 | typedef enum _FNLWF_FILE_TYPE { 20 | FNLWF_FILE_TYPE_DEFAULT, 21 | } FNLWF_FILE_TYPE; 22 | 23 | // 24 | // Open packet, the common header for NtCreateFile extended attributes. 25 | // 26 | typedef struct _FNLWF_OPEN_PACKET { 27 | UINT32 ApiVersion; 28 | FNLWF_FILE_TYPE ObjectType; 29 | } FNLWF_OPEN_PACKET; 30 | 31 | typedef struct _FNLWF_OPEN_DEFAULT { 32 | UINT32 IfIndex; 33 | } FNLWF_OPEN_DEFAULT; 34 | 35 | #define FNLWF_IOCTL_RX_FILTER \ 36 | CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS) 37 | #define FNLWF_IOCTL_RX_GET_FRAME \ 38 | CTL_CODE(FILE_DEVICE_NETWORK, 2, METHOD_BUFFERED, FILE_WRITE_ACCESS) 39 | #define FNLWF_IOCTL_RX_DEQUEUE_FRAME \ 40 | CTL_CODE(FILE_DEVICE_NETWORK, 3, METHOD_BUFFERED, FILE_WRITE_ACCESS) 41 | #define FNLWF_IOCTL_RX_FLUSH \ 42 | CTL_CODE(FILE_DEVICE_NETWORK, 4, METHOD_BUFFERED, FILE_WRITE_ACCESS) 43 | #define FNLWF_IOCTL_TX_ENQUEUE \ 44 | CTL_CODE(FILE_DEVICE_NETWORK, 5, METHOD_BUFFERED, FILE_WRITE_ACCESS) 45 | #define FNLWF_IOCTL_TX_FLUSH \ 46 | CTL_CODE(FILE_DEVICE_NETWORK, 6, METHOD_BUFFERED, FILE_WRITE_ACCESS) 47 | #define FNLWF_IOCTL_OID_SUBMIT_REQUEST \ 48 | CTL_CODE(FILE_DEVICE_NETWORK, 7, METHOD_BUFFERED, FILE_WRITE_ACCESS) 49 | #define FNLWF_IOCTL_STATUS_SET_FILTER \ 50 | CTL_CODE(FILE_DEVICE_NETWORK, 8, METHOD_BUFFERED, FILE_WRITE_ACCESS) 51 | #define FNLWF_IOCTL_STATUS_GET_INDICATION \ 52 | CTL_CODE(FILE_DEVICE_NETWORK, 9, METHOD_BUFFERED, FILE_WRITE_ACCESS) 53 | #define FNLWF_IOCTL_DATAPATH_GET_STATE \ 54 | CTL_CODE(FILE_DEVICE_NETWORK, 10, METHOD_BUFFERED, FILE_WRITE_ACCESS) 55 | 56 | 57 | // 58 | // Parameters for FNLWF_IOCTL_OID_SUBMIT_REQUEST. 59 | // 60 | 61 | typedef struct _OID_SUBMIT_REQUEST_IN_V0 { 62 | OID_KEY_V0 Key; 63 | VOID *InformationBuffer; 64 | UINT32 InformationBufferLength; 65 | } OID_SUBMIT_REQUEST_IN_V0; 66 | 67 | typedef struct _OID_SUBMIT_REQUEST_IN { 68 | const OID_KEY *Key; 69 | VOID *InformationBuffer; 70 | UINT32 InformationBufferLength; 71 | } OID_SUBMIT_REQUEST_IN; 72 | 73 | // 74 | // Parameters for FNLWF_IOCTL_STATUS_SET_FILTER. 75 | // 76 | 77 | typedef struct _STATUS_FILTER_IN { 78 | NDIS_STATUS StatusCode; 79 | BOOLEAN BlockIndications; 80 | BOOLEAN QueueIndications; 81 | } STATUS_FILTER_IN; 82 | 83 | EXTERN_C_END 84 | -------------------------------------------------------------------------------- /inc/fnmpapiconfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | #define FNMP_DEFAULT_RSS_QUEUES 4 11 | #define FNMP_MAX_RSS_INDIR_COUNT 128 12 | #define FNMP_MIN_MTU 1514 13 | #define FNMP_MAX_MTU (16 * 1024 * 1024) 14 | #define FNMP_DEFAULT_MTU FNMP_MAX_MTU 15 | #define FNMP_DEFAULT_MAX_GSO_SIZE 0x20000 16 | #define FNMP_DEFAULT_MIN_GSO_SEG_COUNT 2 17 | 18 | EXTERN_C_END 19 | -------------------------------------------------------------------------------- /inc/fnmpapistatus_km.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | #define FNMPAPI_STATUS NTSTATUS 11 | #define FNMPAPI_FAILED(X) !NT_SUCCESS(X) 12 | #define FNMPAPI_SUCCEEDED(X) NT_SUCCESS(X) 13 | 14 | #define FNMPAPI_STATUS_SUCCESS STATUS_SUCCESS 15 | #define FNMPAPI_STATUS_NOT_FOUND STATUS_NOT_FOUND 16 | #define FNMPAPI_STATUS_MORE_DATA STATUS_BUFFER_OVERFLOW 17 | 18 | EXTERN_C_END 19 | -------------------------------------------------------------------------------- /inc/fnmpapistatus_um.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | #define FNMPAPI_STATUS HRESULT 11 | #define FNMPAPI_FAILED(X) FAILED(X) 12 | #define FNMPAPI_SUCCEEDED(X) SUCCEEDED(X) 13 | 14 | #define FNMPAPI_STATUS_SUCCESS S_OK 15 | #define FNMPAPI_STATUS_NOT_FOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND) 16 | #define FNMPAPI_STATUS_MORE_DATA HRESULT_FROM_WIN32(ERROR_MORE_DATA) 17 | 18 | EXTERN_C_END 19 | -------------------------------------------------------------------------------- /inc/fnmpioctl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | #define FNMP_IOCTL_CURRENT_VERSION 2 11 | 12 | #define FNMP_DEVICE_NAME L"\\Device\\FNMP" 13 | 14 | #define FNMP_OPEN_PACKET_NAME "FnMpOpenPacket0" 15 | 16 | // 17 | // Type of functional test miniport object to create or open. 18 | // 19 | typedef enum _FNMP_FILE_TYPE { 20 | FNMP_FILE_TYPE_SHARED, 21 | FNMP_FILE_TYPE_EXCLUSIVE, 22 | } FNMP_FILE_TYPE; 23 | 24 | // 25 | // Open packet, the common header for NtCreateFile extended attributes. 26 | // 27 | typedef struct _FNMP_OPEN_PACKET { 28 | UINT32 ApiVersion; 29 | FNMP_FILE_TYPE ObjectType; 30 | } FNMP_OPEN_PACKET; 31 | 32 | typedef struct _FNMP_OPEN_SHARED { 33 | UINT32 IfIndex; 34 | } FNMP_OPEN_SHARED; 35 | 36 | typedef struct _FNMP_OPEN_EXCLUSIVE { 37 | UINT32 IfIndex; 38 | } FNMP_OPEN_EXCLUSIVE; 39 | 40 | #define FNMP_IOCTL_RX_ENQUEUE \ 41 | CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_BUFFERED, FILE_WRITE_ACCESS) 42 | #define FNMP_IOCTL_RX_FLUSH \ 43 | CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS) 44 | #define FNMP_IOCTL_TX_FILTER \ 45 | CTL_CODE(FILE_DEVICE_NETWORK, 4, METHOD_BUFFERED, FILE_WRITE_ACCESS) 46 | #define FNMP_IOCTL_TX_GET_FRAME \ 47 | CTL_CODE(FILE_DEVICE_NETWORK, 5, METHOD_BUFFERED, FILE_WRITE_ACCESS) 48 | #define FNMP_IOCTL_TX_DEQUEUE_FRAME \ 49 | CTL_CODE(FILE_DEVICE_NETWORK, 6, METHOD_BUFFERED, FILE_WRITE_ACCESS) 50 | #define FNMP_IOCTL_TX_FLUSH \ 51 | CTL_CODE(FILE_DEVICE_NETWORK, 7, METHOD_BUFFERED, FILE_WRITE_ACCESS) 52 | #define FNMP_IOCTL_MINIPORT_PAUSE_TIMESTAMP \ 53 | CTL_CODE(FILE_DEVICE_NETWORK, 8, METHOD_BUFFERED, FILE_WRITE_ACCESS) 54 | #define FNMP_IOCTL_MINIPORT_SET_MTU \ 55 | CTL_CODE(FILE_DEVICE_NETWORK, 9, METHOD_BUFFERED, FILE_WRITE_ACCESS) 56 | #define FNMP_IOCTL_OID_FILTER \ 57 | CTL_CODE(FILE_DEVICE_NETWORK, 10, METHOD_BUFFERED, FILE_WRITE_ACCESS) 58 | #define FNMP_IOCTL_OID_GET_REQUEST \ 59 | CTL_CODE(FILE_DEVICE_NETWORK, 11, METHOD_BUFFERED, FILE_WRITE_ACCESS) 60 | #define FNMP_IOCTL_OID_COMPLETE_REQUEST \ 61 | CTL_CODE(FILE_DEVICE_NETWORK, 12, METHOD_BUFFERED, FILE_WRITE_ACCESS) 62 | #define FNMP_IOCTL_MINIPORT_UPDATE_TASK_OFFLOAD \ 63 | CTL_CODE(FILE_DEVICE_NETWORK, 13, METHOD_BUFFERED, FILE_WRITE_ACCESS) 64 | #define FNMP_IOCTL_MINIPORT_ALLOCATE_PORT \ 65 | CTL_CODE(FILE_DEVICE_NETWORK, 14, METHOD_BUFFERED, FILE_WRITE_ACCESS) 66 | #define FNMP_IOCTL_MINIPORT_FREE_PORT \ 67 | CTL_CODE(FILE_DEVICE_NETWORK, 15, METHOD_BUFFERED, FILE_WRITE_ACCESS) 68 | #define FNMP_IOCTL_MINIPORT_ACTIVATE_PORT \ 69 | CTL_CODE(FILE_DEVICE_NETWORK, 16, METHOD_BUFFERED, FILE_WRITE_ACCESS) 70 | #define FNMP_IOCTL_MINIPORT_DEACTIVATE_PORT \ 71 | CTL_CODE(FILE_DEVICE_NETWORK, 17, METHOD_BUFFERED, FILE_WRITE_ACCESS) 72 | 73 | // 74 | // Parameters for FNMP_IOCTL_MINIPORT_MTU. 75 | // 76 | 77 | typedef struct _MINIPORT_SET_MTU_IN { 78 | UINT32 Mtu; 79 | } MINIPORT_SET_MTU_IN; 80 | 81 | // 82 | // Parameters for FNMP_IOCTL_OID_FILTER. 83 | // 84 | // InputBuffer: OID_KEY[] 85 | // InputBufferLength: sizeof(OID_KEY[]) 86 | // 87 | 88 | // 89 | // Parameters for FNMP_IOCTL_OID_GET_REQUEST. 90 | // 91 | // InputBuffer: OID_KEY 92 | // InputBufferLength: sizeof(OID_KEY) 93 | // 94 | 95 | // 96 | // Parameters for FNMP_IOCTL_OID_COMPLETE_REQUEST. 97 | // 98 | 99 | typedef struct _OID_COMPLETE_REQUEST_IN_V0 { 100 | OID_KEY_V0 Key; 101 | NDIS_STATUS Status; 102 | UINT32 InformationBufferLength; 103 | const VOID *InformationBuffer; 104 | } OID_COMPLETE_REQUEST_IN_V0; 105 | 106 | typedef struct _OID_COMPLETE_REQUEST_IN { 107 | const OID_KEY *Key; 108 | NDIS_STATUS Status; 109 | UINT32 InformationBufferLength; 110 | const VOID *InformationBuffer; 111 | } OID_COMPLETE_REQUEST_IN; 112 | 113 | // 114 | // Parameters for FNMP_IOCTL_MINIPORT_UPDATE_TASK_OFFLOAD. 115 | // 116 | 117 | typedef struct _MINIPORT_UPDATE_TASK_OFFLOAD_IN { 118 | FN_OFFLOAD_TYPE OffloadType; 119 | const NDIS_OFFLOAD_PARAMETERS *OffloadParameters; 120 | UINT32 OffloadParametersLength; 121 | const FN_OFFLOAD_OPTIONS *OffloadOptions; 122 | } MINIPORT_UPDATE_TASK_OFFLOAD_IN; 123 | 124 | // 125 | // Parameters for FNMP_IOCTL_MINIPORT_ALLOCATE_PORT. 126 | // 127 | // OutputBuffer: NDIS_PORT_NUMBER 128 | // OutputBufferLength: sizeof(NDIS_PORT_NUMBER) 129 | // 130 | 131 | // 132 | // Parameters for FNMP_IOCTL_MINIPORT_FREE_PORT. 133 | // 134 | // InputBuffer: NDIS_PORT_NUMBER 135 | // InputBufferLength: sizeof(NDIS_PORT_NUMBER) 136 | // 137 | 138 | // 139 | // Parameters for FNMP_IOCTL_MINIPORT_ACTIVATE_PORT. 140 | // 141 | // InputBuffer: NDIS_PORT_NUMBER 142 | // InputBufferLength: sizeof(NDIS_PORT_NUMBER) 143 | // 144 | 145 | // 146 | // Parameters for FNMP_IOCTL_MINIPORT_DEACTIVATE_PORT. 147 | // 148 | // InputBuffer: NDIS_PORT_NUMBER 149 | // InputBufferLength: sizeof(NDIS_PORT_NUMBER) 150 | // 151 | 152 | EXTERN_C_END 153 | -------------------------------------------------------------------------------- /inc/fnoid.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // This header contains private OIDs shared between tests and FNMP drivers. 10 | // NDIS requires private OIDs set the highest 8 bits. 11 | // 12 | 13 | EXTERN_C_START 14 | 15 | // 16 | // Set hardware offload capabilities. 17 | // 18 | #define OID_TCP_OFFLOAD_HW_PARAMETERS 0xff000000 19 | 20 | // 21 | // Set no-op. 22 | // 23 | #define OID_FNMP_SET_NOP 0xff000001 24 | 25 | // 26 | // Method direct no-op. 27 | // 28 | // N.B. This MUST be a pre-defined NDIS direct OID, else it will be treated as a 29 | // regular OID. 30 | // 31 | #define OID_FNMP_METHOD_DIRECT_NOP OID_TCP_TASK_IPSEC_OFFLOAD_V2_ADD_SA 32 | 33 | EXTERN_C_END 34 | -------------------------------------------------------------------------------- /inc/invokesystemrelay.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | EXTERN_C_START 12 | 13 | inline 14 | INT 15 | InvokeSystemRelay( 16 | _In_z_ const CHAR *Command 17 | ) 18 | { 19 | INT Result = -1; 20 | NTSTATUS Status; 21 | FNIOCTL_HANDLE Handle = NULL; 22 | ISR_OPEN_CLIENT *OpenClient; 23 | CHAR EaBuffer[ISR_OPEN_EA_LENGTH + sizeof(*OpenClient)]; 24 | 25 | OpenClient = 26 | (ISR_OPEN_CLIENT *) 27 | IsrInitializeEa(ISR_FILE_TYPE_CLIENT, EaBuffer, sizeof(EaBuffer)); 28 | 29 | Status = 30 | FnIoctlOpen( 31 | ISR_DEVICE_NAME, FILE_CREATE, EaBuffer, sizeof(EaBuffer), &Handle); 32 | if (!NT_SUCCESS(Status)) { 33 | goto Exit; 34 | } 35 | 36 | Status = 37 | FnIoctl( 38 | Handle, ISR_IOCTL_INVOKE_SYSTEM_SUBMIT, (VOID *)Command, 39 | (UINT32)strlen(Command) + 1, &Result, sizeof(Result), NULL, NULL); 40 | 41 | Exit: 42 | 43 | if (Handle != NULL) { 44 | FnIoctlClose(Handle); 45 | } 46 | 47 | return Result; 48 | } 49 | 50 | EXTERN_C_END 51 | -------------------------------------------------------------------------------- /inc/invokesystemrelayioctl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | #define ISR_DEVICE_NAME L"\\Device\\isrdrv" 11 | 12 | #define ISR_OPEN_PACKET_NAME "IsrOpenPacket0" 13 | 14 | // 15 | // Type of object to create or open. 16 | // 17 | typedef enum _ISR_FILE_TYPE { 18 | ISR_FILE_TYPE_CLIENT, 19 | ISR_FILE_TYPE_SERVICE, 20 | } ISR_FILE_TYPE; 21 | 22 | // 23 | // Open packet, the common header for NtCreateFile extended attributes. 24 | // 25 | typedef struct _ISR_OPEN_PACKET { 26 | ISR_FILE_TYPE ObjectType; 27 | } ISR_OPEN_PACKET; 28 | 29 | typedef struct _ISR_OPEN_CLIENT { 30 | UINT32 Reserved; 31 | } ISR_OPEN_CLIENT; 32 | 33 | typedef struct _ISR_OPEN_SERVICE { 34 | UINT32 Reserved; 35 | } ISR_OPEN_SERVICE; 36 | 37 | // 38 | // IOCTL interface. 39 | // 40 | #define ISR_MAX_COMMAND_LENGTH 1024 41 | 42 | typedef struct _ISR_GET_OUTPUT { 43 | UINT64 Id; 44 | CHAR Command[ISR_MAX_COMMAND_LENGTH]; 45 | } ISR_GET_OUTPUT; 46 | 47 | typedef struct _ISR_POST_INPUT { 48 | UINT64 Id; 49 | INT Result; 50 | } ISR_POST_INPUT; 51 | 52 | // 53 | // Issued by kernel mode clients to enqueue an invoke system request. 54 | // The request is processed asynchronously and the result is returned upon completion. 55 | // Asynchronous. 56 | // 57 | // Input: char *Command 58 | // Output: int Result 59 | // 60 | // TODO: add timeout so that these requests cannot pend forever 61 | // 62 | #define ISR_IOCTL_INVOKE_SYSTEM_SUBMIT \ 63 | CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS) 64 | 65 | // 66 | // Issued by invokesystemrelay user mode service to fetch an invoke system request. 67 | // This will pend indefinitely until a request is ready to be processed. 68 | // Asynchronous. Cancelable. 69 | // 70 | // Input: None 71 | // Output: ISR_GET_OUTPUT 72 | // 73 | #define ISR_IOCTL_INVOKE_SYSTEM_GET \ 74 | CTL_CODE(FILE_DEVICE_NETWORK, 2, METHOD_BUFFERED, FILE_WRITE_ACCESS) 75 | 76 | // 77 | // Issued by invokesystemrelay user mode service to return the result of an invoke system request. 78 | // Synchronous. 79 | // 80 | // Input: ISR_POST_INPUT 81 | // Output: None 82 | // 83 | #define ISR_IOCTL_INVOKE_SYSTEM_POST \ 84 | CTL_CODE(FILE_DEVICE_NETWORK, 3, METHOD_BUFFERED, FILE_WRITE_ACCESS) 85 | 86 | // 87 | // Helpers for opening handles. 88 | // 89 | 90 | #define ISR_OPEN_EA_LENGTH \ 91 | (sizeof(FILE_FULL_EA_INFORMATION) + \ 92 | sizeof(ISR_OPEN_PACKET_NAME) + \ 93 | sizeof(ISR_OPEN_PACKET)) 94 | 95 | inline 96 | VOID * 97 | IsrInitializeEa( 98 | _In_ ISR_FILE_TYPE FileType, 99 | _Out_ VOID *EaBuffer, 100 | _In_ UINT32 EaLength 101 | ) 102 | { 103 | FILE_FULL_EA_INFORMATION *EaHeader = (FILE_FULL_EA_INFORMATION *)EaBuffer; 104 | ISR_OPEN_PACKET *OpenPacket; 105 | 106 | if (EaLength < ISR_OPEN_EA_LENGTH) { 107 | __fastfail(FAST_FAIL_INVALID_ARG); 108 | } 109 | 110 | RtlZeroMemory(EaHeader, sizeof(*EaHeader)); 111 | EaHeader->EaNameLength = sizeof(ISR_OPEN_PACKET_NAME) - 1; 112 | RtlCopyMemory(EaHeader->EaName, ISR_OPEN_PACKET_NAME, sizeof(ISR_OPEN_PACKET_NAME)); 113 | EaHeader->EaValueLength = (USHORT)(EaLength - sizeof(*EaHeader) - sizeof(ISR_OPEN_PACKET_NAME)); 114 | 115 | OpenPacket = (ISR_OPEN_PACKET *)(EaHeader->EaName + sizeof(ISR_OPEN_PACKET_NAME)); 116 | OpenPacket->ObjectType = FileType; 117 | 118 | return OpenPacket + 1; 119 | } 120 | 121 | EXTERN_C_END 122 | -------------------------------------------------------------------------------- /inc/ndisoobtypes.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #pragma warning(push) 9 | #pragma warning(disable:4201) // nonstandard extension used: nameless struct/union 10 | 11 | EXTERN_C_START 12 | 13 | typedef struct _NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO 14 | { 15 | union 16 | { 17 | struct 18 | { 19 | ULONG IsIPv4 :1; 20 | ULONG IsIPv6 :1; 21 | ULONG TcpChecksum :1; 22 | ULONG UdpChecksum :1; 23 | ULONG IpHeaderChecksum :1; 24 | ULONG Reserved :11; 25 | ULONG TcpHeaderOffset :10; 26 | } Transmit; 27 | 28 | struct 29 | { 30 | ULONG TcpChecksumFailed :1; 31 | ULONG UdpChecksumFailed :1; 32 | ULONG IpChecksumFailed :1; 33 | ULONG TcpChecksumSucceeded :1; 34 | ULONG UdpChecksumSucceeded :1; 35 | ULONG IpChecksumSucceeded :1; 36 | ULONG Loopback :1; 37 | #if NDIS_SUPPORT_NDIS630 38 | ULONG TcpChecksumValueInvalid :1; 39 | ULONG IpChecksumValueInvalid :1; 40 | #endif // NDIS_SUPPORT_NDIS630 41 | } Receive; 42 | 43 | PVOID Value; 44 | }; 45 | } NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO, *PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO; 46 | 47 | // 48 | // NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO.Transmit.Type 49 | // 50 | #define NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE 0 51 | #define NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE 1 52 | 53 | // 54 | // NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO.LsoV2Transmit.IPVersion 55 | // 56 | #define NDIS_TCP_LARGE_SEND_OFFLOAD_IPv4 0 57 | #define NDIS_TCP_LARGE_SEND_OFFLOAD_IPv6 1 58 | 59 | // 60 | // The maximum length of the headers (MAC+IP+IP option or extension 61 | // headers+TCP+TCP options) when the protocol does large send offload. If 62 | // header is bigger than this value, it will not do LSO. 63 | // 64 | #define NDIS_LARGE_SEND_OFFLOAD_MAX_HEADER_LENGTH 128 65 | 66 | // 67 | // Per-NetBufferList information for TcpLargeSendNetBufferListInfo. 68 | // 69 | typedef struct _NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO 70 | { 71 | union 72 | { 73 | struct 74 | { 75 | ULONG Unused :30; 76 | ULONG Type :1; 77 | ULONG Reserved2 :1; 78 | } Transmit; 79 | 80 | struct 81 | { 82 | ULONG MSS :20; 83 | ULONG TcpHeaderOffset :10; 84 | ULONG Type :1; 85 | ULONG Reserved2 :1; 86 | } LsoV1Transmit; 87 | 88 | struct 89 | { 90 | ULONG TcpPayload :30; 91 | ULONG Type :1; 92 | ULONG Reserved2 :1; 93 | } LsoV1TransmitComplete; 94 | 95 | struct 96 | { 97 | ULONG MSS :20; 98 | ULONG TcpHeaderOffset :10; 99 | ULONG Type :1; 100 | ULONG IPVersion :1; 101 | } LsoV2Transmit; 102 | 103 | struct 104 | { 105 | ULONG Reserved :30; 106 | ULONG Type :1; 107 | ULONG Reserved2 :1; 108 | } LsoV2TransmitComplete; 109 | 110 | PVOID Value; 111 | }; 112 | } NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, *PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO; 113 | 114 | // 115 | // IP protocol version encoded in IPVersion field of 116 | // NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO->Transmit.IPVersion 117 | // 118 | #define NDIS_UDP_SEGMENTATION_OFFLOAD_IPV4 0 119 | #define NDIS_UDP_SEGMENTATION_OFFLOAD_IPV6 1 120 | 121 | // 122 | // Per-NetBufferList information for UdpSegmentationOffloadInfo. 123 | // 124 | typedef struct _NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO 125 | { 126 | union 127 | { 128 | struct 129 | { 130 | ULONG MSS :20; 131 | ULONG UdpHeaderOffset :10; 132 | ULONG Reserved :1; 133 | ULONG IPVersion :1; 134 | } Transmit; 135 | 136 | PVOID Value; 137 | }; 138 | } NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO, *PNDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO; 139 | 140 | // 141 | // TcpRecvSegCoalesceInfo 142 | // 143 | typedef union _NDIS_RSC_NBL_INFO 144 | { 145 | struct 146 | { 147 | USHORT CoalescedSegCount; 148 | USHORT DupAckCount; 149 | } Info; 150 | 151 | PVOID Value; 152 | } NDIS_RSC_NBL_INFO, *PNDIS_RSC_NBL_INFO; 153 | 154 | C_ASSERT(sizeof(NDIS_RSC_NBL_INFO) == sizeof(PVOID)); 155 | 156 | EXTERN_C_END 157 | 158 | #pragma warning(pop) 159 | -------------------------------------------------------------------------------- /src/common/inc/bounce.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | typedef struct _BOUNCE_BUFFER { 9 | VOID *Buffer; 10 | } BOUNCE_BUFFER; 11 | 12 | VOID 13 | BounceInitialize( 14 | _Out_ BOUNCE_BUFFER *Bounce 15 | ); 16 | 17 | VOID 18 | BounceCleanup( 19 | _Inout_ BOUNCE_BUFFER *Bounce 20 | ); 21 | 22 | VOID 23 | BounceFree( 24 | _In_opt_ CONST VOID *Buffer 25 | ); 26 | 27 | VOID * 28 | BounceRelease( 29 | _Inout_ BOUNCE_BUFFER *Bounce 30 | ); 31 | 32 | NTSTATUS 33 | BounceBuffer( 34 | _Inout_ BOUNCE_BUFFER *Bounce, 35 | _In_ KPROCESSOR_MODE RequestorMode, 36 | _In_opt_ CONST VOID *Buffer, 37 | _In_ SIZE_T BufferSize, 38 | _In_ UINT32 Alignment 39 | ); 40 | -------------------------------------------------------------------------------- /src/common/inc/fnassert.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | // 7 | // Provides assertion wrappers. 8 | // 9 | 10 | #pragma once 11 | 12 | #ifdef ASSERT 13 | #undef ASSERT 14 | #endif 15 | 16 | #ifdef _KERNEL_MODE 17 | #if DBG 18 | // Ensure the system bugchecks if KD is disabled. 19 | #define ASSERT(e) \ 20 | ((NT_ASSERT_ASSUME(e)) ? \ 21 | TRUE : (KD_DEBUGGER_ENABLED ? FALSE : (RtlFailFast(FAST_FAIL_INVALID_ARG), FALSE))) 22 | #else 23 | #define ASSERT(e) NT_ASSERT_ASSUME(e) 24 | #endif 25 | #else 26 | #if __SANITIZE_ADDRESS__ 27 | // Instead of asserting (which simply exits the process) generate an AV that ASAN will catch. 28 | #define ASSERT_ACTION ((*(UINT16 *)0xDEAD) = 0xDEAD) 29 | #endif 30 | #if DBG 31 | #ifndef ASSERT_ACTION 32 | #define ASSERT_ACTION DbgRaiseAssertionFailure() 33 | #endif 34 | #define ASSERT(e) ((e) ? TRUE : (ASSERT_ACTION, FALSE)) 35 | #elif defined(_PREFAST_) 36 | #define ASSERT(e) _Analysis_assume_(e) 37 | #else 38 | #define ASSERT(e) 39 | #endif 40 | #endif 41 | 42 | #ifdef _KERNEL_MODE 43 | #define FRE_ASSERT(e) \ 44 | (NT_VERIFY(e) ? TRUE : (RtlFailFast(FAST_FAIL_INVALID_ARG), FALSE)) 45 | #elif DBG 46 | #define FRE_ASSERT(e) (ASSERT(e) ? TRUE : (__fastfail(FAST_FAIL_INVALID_ARG), FALSE)) 47 | #else 48 | #define FRE_ASSERT(e) ((e) ? TRUE : (__fastfail(FAST_FAIL_INVALID_ARG), FALSE)) 49 | #endif 50 | -------------------------------------------------------------------------------- /src/common/inc/fnio.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include "fniotypes.h" 10 | 11 | typedef struct _DATA_FILTER DATA_FILTER; 12 | 13 | // 14 | // APIs for filtering, getting, and flushing IO. 15 | // 16 | 17 | _IRQL_requires_max_(DISPATCH_LEVEL) 18 | DATA_FILTER * 19 | FnIoCreateFilter( 20 | _In_ KPROCESSOR_MODE RequestorMode, 21 | _In_ VOID *InputBuffer, 22 | _In_ UINT32 InputBufferLength 23 | ); 24 | 25 | _IRQL_requires_max_(DISPATCH_LEVEL) 26 | VOID 27 | FnIoDeleteFilter( 28 | _In_ DATA_FILTER *Filter 29 | ); 30 | 31 | _IRQL_requires_max_(DISPATCH_LEVEL) 32 | NTSTATUS 33 | FnIoFilterNbl( 34 | _In_ DATA_FILTER *Filter, 35 | _In_ NET_BUFFER_LIST *Nbl 36 | ); 37 | 38 | _IRQL_requires_max_(DISPATCH_LEVEL) 39 | NTSTATUS 40 | FnIoGetFilteredFrame( 41 | _In_ DATA_FILTER *Filter, 42 | _In_ UINT32 Index, 43 | _In_ UINT32 SubIndex, 44 | _In_ IRP *Irp, 45 | _In_ IO_STACK_LOCATION *IrpSp 46 | ); 47 | 48 | _IRQL_requires_max_(DISPATCH_LEVEL) 49 | NTSTATUS 50 | FnIoDequeueFilteredFrame( 51 | _In_ DATA_FILTER *Filter, 52 | _In_ UINT32 Index 53 | ); 54 | 55 | _IRQL_requires_max_(DISPATCH_LEVEL) 56 | VOID 57 | FnIoFlushDequeuedFrames( 58 | _In_ DATA_FILTER *Filter, 59 | _Inout_ NBL_COUNTED_QUEUE *FlushQueue 60 | ); 61 | 62 | _IRQL_requires_max_(DISPATCH_LEVEL) 63 | VOID 64 | FnIoFlushAllFrames( 65 | _In_ DATA_FILTER *Filter, 66 | _Inout_ NBL_COUNTED_QUEUE *FlushQueue 67 | ); 68 | 69 | _IRQL_requires_max_(DISPATCH_LEVEL) 70 | BOOLEAN 71 | FnIoIsFilterWatchdogExpired( 72 | _In_ const DATA_FILTER *Filter 73 | ); 74 | 75 | // 76 | // APIs for queueing up new IO. 77 | // 78 | 79 | typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _ENQUEUE_NBL_CONTEXT { 80 | UINT32 TrailingMdlBytes; 81 | } ENQUEUE_NBL_CONTEXT; 82 | 83 | #define FNIO_ENQUEUE_NBL_CONTEXT_SIZE sizeof(ENQUEUE_NBL_CONTEXT) 84 | 85 | _IRQL_requires_max_(DISPATCH_LEVEL) 86 | NTSTATUS 87 | FnIoEnqueueFrameBegin( 88 | _In_ KPROCESSOR_MODE RequestorMode, 89 | _In_ VOID *InputBuffer, 90 | _In_ UINT32 InputBufferLength, 91 | _In_ NDIS_HANDLE NblPool, 92 | _Out_ DATA_ENQUEUE_IN *EnqueueIn, 93 | _Out_ NET_BUFFER_LIST **Nbl 94 | ); 95 | 96 | _IRQL_requires_max_(DISPATCH_LEVEL) 97 | VOID 98 | FnIoEnqueueFrameEnd( 99 | _In_ DATA_ENQUEUE_IN *EnqueueIn 100 | ); 101 | 102 | _IRQL_requires_max_(DISPATCH_LEVEL) 103 | VOID 104 | FnIoEnqueueFrameReturn( 105 | _In_ NET_BUFFER_LIST *Nbl 106 | ); 107 | -------------------------------------------------------------------------------- /src/common/inc/fnrefcount.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | typedef INT64 FN_REFERENCE_COUNT; 11 | 12 | inline 13 | VOID 14 | FnInitializeReferenceCount( 15 | _Out_ FN_REFERENCE_COUNT *RefCount 16 | ) 17 | { 18 | *RefCount = 1; 19 | } 20 | 21 | inline 22 | VOID 23 | FnInitializeReferenceCountEx( 24 | _Out_ FN_REFERENCE_COUNT *RefCount, 25 | _In_ SSIZE_T Bias 26 | ) 27 | { 28 | FRE_ASSERT(Bias > 0); 29 | *RefCount = Bias; 30 | } 31 | 32 | inline 33 | VOID 34 | FnIncrementReferenceCount( 35 | _Inout_ FN_REFERENCE_COUNT *RefCount 36 | ) 37 | { 38 | FRE_ASSERT(InterlockedIncrement64(RefCount) > 1); 39 | } 40 | 41 | inline 42 | BOOLEAN 43 | FnDecrementReferenceCount( 44 | _Inout_ FN_REFERENCE_COUNT *RefCount 45 | ) 46 | { 47 | INT64 NewValue = InterlockedDecrement64(RefCount); 48 | FRE_ASSERT(NewValue >= 0); 49 | 50 | return NewValue == 0; 51 | } 52 | -------------------------------------------------------------------------------- /src/common/inc/fnrtl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #ifndef FNMP_RTL_H 7 | #define FNMP_RTL_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #ifndef RTL_PTR_ADD 14 | #define RTL_PTR_ADD(Pointer, Value) \ 15 | ((VOID *)((ULONG_PTR)(Pointer) + (ULONG_PTR)(Value))) 16 | #endif 17 | 18 | #ifndef RTL_PTR_SUBTRACT 19 | #define RTL_PTR_SUBTRACT(Pointer, Value) \ 20 | ((PVOID)((ULONG_PTR)(Pointer) - (ULONG_PTR)(Value))) 21 | #endif 22 | 23 | #ifndef RTL_IS_POWER_OF_TWO 24 | #define RTL_IS_POWER_OF_TWO(Value) \ 25 | ((Value != 0) && !((Value) & ((Value) - 1))) 26 | #endif 27 | 28 | #ifndef RTL_IS_CLEAR_OR_SINGLE_FLAG 29 | #define RTL_IS_CLEAR_OR_SINGLE_FLAG(Flags, Mask) \ 30 | (((Flags) & (Mask)) == 0 || !(((Flags) & (Mask)) & (((Flags) & (Mask)) - 1))) 31 | #endif 32 | 33 | #ifndef RTL_NUM_ALIGN_DOWN 34 | #define RTL_NUM_ALIGN_DOWN(Number, Alignment) \ 35 | ((Number) - ((Number) & ((Alignment) - 1))) 36 | #endif 37 | 38 | #ifndef RTL_NUM_ALIGN_UP 39 | #define RTL_NUM_ALIGN_UP(Number, Alignment) \ 40 | RTL_NUM_ALIGN_DOWN((Number) + (Alignment) - 1, (Alignment)) 41 | #endif 42 | 43 | #ifndef RTL_PTR_SUBTRACT 44 | #define RTL_PTR_SUBTRACT(Pointer, Value) \ 45 | ((PVOID)((ULONG_PTR)(Pointer) - (ULONG_PTR)(Value))) 46 | #endif 47 | 48 | #ifndef ALIGN_DOWN_BY 49 | #define ALIGN_DOWN_BY(Length, Alignment) \ 50 | ((ULONG_PTR)(Length)& ~(Alignment - 1)) 51 | #endif 52 | 53 | #ifndef ALIGN_UP_BY 54 | #define ALIGN_UP_BY(Length, Alignment) \ 55 | (ALIGN_DOWN_BY(((ULONG_PTR)(Length) + Alignment - 1), Alignment)) 56 | #endif 57 | 58 | #define RTL_MILLISEC_TO_100NANOSEC(m) ((m) * 10000ui64) 59 | #define RTL_SEC_TO_100NANOSEC(s) ((s) * 10000000ui64) 60 | #define RTL_SEC_TO_MILLISEC(s) ((s) * 1000ui64) 61 | 62 | #ifndef ReadUInt64NoFence 63 | #define ReadUInt64NoFence ReadULong64NoFence 64 | #endif 65 | 66 | #ifndef htons 67 | #define htons _byteswap_ushort 68 | #endif 69 | 70 | #ifndef ntohs 71 | #define ntohs _byteswap_ushort 72 | #endif 73 | 74 | #ifndef htonl 75 | #define htonl _byteswap_ulong 76 | #endif 77 | 78 | #ifndef ntohl 79 | #define ntohl _byteswap_ulong 80 | #endif 81 | 82 | #if (!defined(NTDDI_WIN10_CO) || (WDK_NTDDI_VERSION < NTDDI_WIN10_CO)) && \ 83 | !defined(UINT32_VOLATILE_ACCESSORS) 84 | #define UINT32_VOLATILE_ACCESSORS 85 | 86 | FORCEINLINE 87 | UINT32 88 | ReadUInt32Acquire( 89 | _In_ _Interlocked_operand_ UINT32 const volatile *Source 90 | ) 91 | { 92 | return (UINT32)ReadULongAcquire((PULONG)Source); 93 | } 94 | 95 | FORCEINLINE 96 | UINT32 97 | ReadUInt32NoFence( 98 | _In_ _Interlocked_operand_ UINT32 const volatile *Source 99 | ) 100 | { 101 | return (UINT32)ReadULongNoFence((PULONG)Source); 102 | } 103 | 104 | FORCEINLINE 105 | VOID 106 | WriteUInt32Release( 107 | _Out_ _Interlocked_operand_ UINT32 volatile *Destination, 108 | _In_ UINT32 Value 109 | ) 110 | { 111 | WriteULongRelease((PULONG)Destination, (ULONG)Value); 112 | } 113 | 114 | FORCEINLINE 115 | VOID 116 | WriteUInt32NoFence( 117 | _Out_ _Interlocked_operand_ UINT32 volatile *Destination, 118 | _In_ UINT32 Value 119 | ) 120 | { 121 | WriteULongNoFence((PULONG)Destination, (ULONG)Value); 122 | } 123 | 124 | #endif 125 | 126 | #ifdef _KERNEL_MODE 127 | 128 | FORCEINLINE 129 | _IRQL_requires_max_(APC_LEVEL) 130 | _Acquires_exclusive_lock_(Lock) 131 | VOID 132 | RtlAcquirePushLockExclusive( 133 | _Inout_ EX_PUSH_LOCK *Lock 134 | ) 135 | { 136 | KeEnterCriticalRegion(); 137 | ExAcquirePushLockExclusive(Lock); 138 | } 139 | 140 | FORCEINLINE 141 | _IRQL_requires_max_(APC_LEVEL) 142 | _Releases_exclusive_lock_(Lock) 143 | VOID 144 | RtlReleasePushLockExclusive( 145 | _Inout_ EX_PUSH_LOCK *Lock 146 | ) 147 | { 148 | ExReleasePushLockExclusive(Lock); 149 | KeLeaveCriticalRegion(); 150 | } 151 | 152 | FORCEINLINE 153 | _IRQL_requires_max_(APC_LEVEL) 154 | _Acquires_shared_lock_(Lock) 155 | VOID 156 | RtlAcquirePushLockShared( 157 | _Inout_ EX_PUSH_LOCK *Lock 158 | ) 159 | { 160 | KeEnterCriticalRegion(); 161 | ExAcquirePushLockShared(Lock); 162 | } 163 | 164 | FORCEINLINE 165 | _IRQL_requires_max_(APC_LEVEL) 166 | _Releases_shared_lock_(Lock) 167 | VOID 168 | RtlReleasePushLockShared( 169 | _Inout_ EX_PUSH_LOCK *Lock 170 | ) 171 | { 172 | ExReleasePushLockShared(Lock); 173 | KeLeaveCriticalRegion(); 174 | } 175 | 176 | #ifndef _RTL_VOL_MEM_ACCESSORS_ 177 | 178 | FORCEINLINE 179 | VOID 180 | RtlCopyVolatileMemory( 181 | _Out_writes_bytes_(Size) VOID *Destination, 182 | _In_reads_bytes_(Size) volatile const VOID *Source, 183 | _In_ SIZE_T Size 184 | ) 185 | { 186 | RtlCopyMemory(Destination, (const VOID *)Source, Size); 187 | _ReadWriteBarrier(); 188 | } 189 | 190 | #endif 191 | 192 | FORCEINLINE 193 | HANDLE 194 | ReadHandleNoFence( 195 | _In_reads_bytes_(sizeof(HANDLE)) volatile CONST HANDLE *Address 196 | ) 197 | { 198 | return (HANDLE)ReadPointerNoFence((PVOID *)Address); 199 | } 200 | 201 | inline 202 | _IRQL_requires_max_(APC_LEVEL) 203 | NTSTATUS 204 | FnWaitObject( 205 | _In_ VOID *Object, 206 | _In_opt_ LARGE_INTEGER *Timeout 207 | ) 208 | { 209 | return KeWaitForSingleObject(Object, Executive, KernelMode, FALSE, Timeout); 210 | } 211 | 212 | #endif 213 | 214 | #ifdef __cplusplus 215 | } // extern "C" 216 | #endif 217 | 218 | #endif 219 | -------------------------------------------------------------------------------- /src/common/inc/fnstatusconvert.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | _IRQL_requires_max_(HIGH_LEVEL) 9 | NDIS_STATUS 10 | inline 11 | FnConvertNtStatusToNdisStatus(NTSTATUS NtStatus) 12 | { 13 | if (NT_SUCCESS(NtStatus) && 14 | NtStatus != STATUS_PENDING && 15 | NtStatus != STATUS_NDIS_INDICATION_REQUIRED) { 16 | return NDIS_STATUS_SUCCESS; 17 | } else { 18 | switch (NtStatus) { 19 | case STATUS_BUFFER_TOO_SMALL: 20 | return NDIS_STATUS_BUFFER_TOO_SHORT; 21 | default: 22 | return (NDIS_STATUS)NtStatus; 23 | } 24 | } 25 | } 26 | 27 | _IRQL_requires_max_(HIGH_LEVEL) 28 | NTSTATUS 29 | inline 30 | FnConvertNdisStatusToNtStatus(NDIS_STATUS NdisStatus) 31 | { 32 | if (NT_SUCCESS(NdisStatus) && 33 | NdisStatus != NDIS_STATUS_SUCCESS && 34 | NdisStatus != NDIS_STATUS_PENDING && 35 | NdisStatus != NDIS_STATUS_INDICATION_REQUIRED) { 36 | // 37 | // Case where an NDIS error is incorrectly mapped as a success by NT_SUCCESS macro 38 | // 39 | return STATUS_UNSUCCESSFUL; 40 | } else { 41 | switch (NdisStatus) { 42 | case NDIS_STATUS_BUFFER_TOO_SHORT: 43 | return STATUS_BUFFER_TOO_SMALL; 44 | default: 45 | return (NTSTATUS)NdisStatus; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/common/inc/fntimer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include "pooltag.h" 10 | 11 | DECLARE_HANDLE(FN_TIMER_HANDLE); 12 | 13 | typedef 14 | _IRQL_requires_max_(PASSIVE_LEVEL) 15 | VOID 16 | FN_TIMER_CALLBACK( 17 | _In_ VOID *CallbackContext 18 | ); 19 | 20 | typedef struct _FN_TIMER { 21 | FN_TIMER_CALLBACK *Callback; 22 | VOID *CallbackContext; 23 | HANDLE ThreadHandle; 24 | KEVENT CloseEvent; 25 | LARGE_INTEGER Timeout; 26 | } FN_TIMER; 27 | 28 | inline 29 | _IRQL_requires_same_ 30 | _Function_class_(KSTART_ROUTINE) 31 | VOID 32 | FnTimerWorker( 33 | _In_ VOID *Context 34 | ) 35 | { 36 | FN_TIMER *Timer = Context; 37 | NTSTATUS Status; 38 | 39 | while ((Status = FnWaitObject(&Timer->CloseEvent, &Timer->Timeout)) == STATUS_TIMEOUT) { 40 | Timer->Callback(Timer->CallbackContext); 41 | } 42 | 43 | ASSERT(Status == STATUS_SUCCESS); 44 | } 45 | 46 | inline 47 | VOID 48 | FnTimerDestroy( 49 | FN_TIMER *Timer 50 | ) 51 | { 52 | if (Timer->ThreadHandle != NULL) { 53 | ObDereferenceObject(Timer->ThreadHandle); 54 | } 55 | 56 | ExFreePoolWithTag(Timer, POOLTAG_TIMER); 57 | } 58 | 59 | inline 60 | _IRQL_requires_max_(PASSIVE_LEVEL) 61 | NTSTATUS 62 | FnTimerCreate( 63 | _Out_ FN_TIMER_HANDLE *Handle, 64 | _In_ FN_TIMER_CALLBACK *Callback, 65 | _In_ VOID *CallbackContext, 66 | _In_ UINT32 IntervalMs 67 | ) 68 | { 69 | NTSTATUS Status; 70 | FN_TIMER *Timer; 71 | HANDLE ThreadHandle = NULL; 72 | 73 | Timer = ExAllocatePoolZero(NonPagedPoolNx, sizeof(*Timer), POOLTAG_TIMER); 74 | if (Timer == NULL) { 75 | Status = STATUS_NO_MEMORY; 76 | goto Exit; 77 | } 78 | 79 | Timer->Callback = Callback; 80 | Timer->CallbackContext = CallbackContext; 81 | Timer->Timeout.QuadPart = -1i64 * RTL_MILLISEC_TO_100NANOSEC(IntervalMs); 82 | KeInitializeEvent(&Timer->CloseEvent, NotificationEvent, FALSE); 83 | 84 | Status = 85 | PsCreateSystemThread( 86 | &ThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, 87 | FnTimerWorker, Timer); 88 | if (!NT_SUCCESS(Status)) { 89 | goto Exit; 90 | } 91 | 92 | Status = 93 | ObReferenceObjectByHandle( 94 | ThreadHandle, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, &Timer->ThreadHandle, 95 | NULL); 96 | FRE_ASSERT(NT_SUCCESS(Status)); 97 | 98 | *Handle = (FN_TIMER_HANDLE)Timer; 99 | 100 | Exit: 101 | 102 | if (!NT_SUCCESS(Status)) { 103 | FnTimerDestroy(Timer); 104 | } 105 | 106 | if (ThreadHandle != NULL) { 107 | NT_VERIFY(NT_SUCCESS(ZwClose(ThreadHandle))); 108 | } 109 | 110 | return Status; 111 | } 112 | 113 | inline 114 | _IRQL_requires_max_(PASSIVE_LEVEL) 115 | VOID 116 | FnTimerClose( 117 | _In_ FN_TIMER_HANDLE Handle 118 | ) 119 | { 120 | FN_TIMER *Timer = (FN_TIMER *)Handle; 121 | 122 | NT_VERIFY(KeSetEvent(&Timer->CloseEvent, IO_NO_INCREMENT, FALSE) == FALSE); 123 | NT_VERIFY(FnWaitObject(Timer->ThreadHandle, NULL) == STATUS_SUCCESS); 124 | 125 | FnTimerDestroy(Timer); 126 | } 127 | -------------------------------------------------------------------------------- /src/common/inc/pooltag.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #define POOLTAG_BOUNCE_BUFFER 'fBoB' // BoBf 9 | 10 | #define POOLTAG_FNIO_FILTER 'iFoI' // IoFi 11 | #define POOLTAG_FNIO_BUFFER 'fBoI' // IoBf 12 | 13 | #define POOLTAG_MP_ADAPTER 'dApM' // MpAd 14 | #define POOLTAG_MP_EXCLUSIVE 'xEpM' // MpEx 15 | #define POOLTAG_MP_OID 'iOpM' // MpOi 16 | #define POOLTAG_MP_PORT 'tPpM' // MpPt 17 | #define POOLTAG_MP_RSS 'sRpM' // MpRs 18 | #define POOLTAG_MP_SHARED 'hSpM' // MpSh 19 | #define POOLTAG_MP_SHARED_RX 'rSpM' // MpSr 20 | #define POOLTAG_MP_SHARED_TX 'tSpM' // MpSt 21 | 22 | #define POOLTAG_LWF_FILTER 'iFfL' // LfFi 23 | #define POOLTAG_LWF_NBL 'bNfL' // LfNb 24 | #define POOLTAG_LWF_OID 'iOfL' // LfOi 25 | #define POOLTAG_LWF_DEFAULT 'fDfL' // LfDf 26 | #define POOLTAG_LWF_DEFAULT_RX 'rDfL' // LfDr 27 | #define POOLTAG_LWF_DEFAULT_STATUS 'sDfL' // LfDs 28 | #define POOLTAG_LWF_DEFAULT_TX 'tDfL' // LfDt 29 | 30 | #define POOLTAG_ISR_CLIENT 'CrsI' // IsrC 31 | #define POOLTAG_ISR_REQUEST 'RrsI' // IsrR 32 | #define POOLTAG_ISR_SERVICE 'SrsI' // IsrS 33 | 34 | #define POOLTAG_FNSOCK_SOCKET 'kSsF' // FsSk 35 | #define POOLTAG_FNSOCK_SEND 'sSsF' // FsSs 36 | #define POOLTAG_FNSOCK_RECV 'rSsF' // FsSr 37 | #define POOLTAG_FNSOCK_ACCEPT 'aSsF' // FsSa 38 | 39 | #define POOLTAG_TIMER 'mtnF' // Fntm 40 | -------------------------------------------------------------------------------- /src/common/lib/bounce/bounce.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include 7 | #include 8 | #include "bounce.h" 9 | #include "pooltag.h" 10 | 11 | VOID 12 | BounceInitialize( 13 | _Out_ BOUNCE_BUFFER *Bounce 14 | ) 15 | { 16 | RtlZeroMemory(Bounce, sizeof(*Bounce)); 17 | } 18 | 19 | VOID 20 | BounceCleanup( 21 | _Inout_ BOUNCE_BUFFER *Bounce 22 | ) 23 | { 24 | BounceFree(Bounce->Buffer); 25 | BounceInitialize(Bounce); 26 | } 27 | 28 | VOID 29 | BounceFree( 30 | _In_opt_ CONST VOID *Buffer 31 | ) 32 | { 33 | if (Buffer != NULL) { 34 | ExFreePoolWithTag((VOID *)Buffer, POOLTAG_BOUNCE_BUFFER); 35 | } 36 | } 37 | 38 | VOID * 39 | BounceRelease( 40 | _Inout_ BOUNCE_BUFFER *Bounce 41 | ) 42 | { 43 | VOID *Buffer = Bounce->Buffer; 44 | Bounce->Buffer = NULL; 45 | return Buffer; 46 | } 47 | 48 | __declspec(code_seg("PAGE")) 49 | NTSTATUS 50 | BounceBuffer( 51 | _Inout_ BOUNCE_BUFFER *Bounce, 52 | _In_ KPROCESSOR_MODE RequestorMode, 53 | _In_opt_ CONST VOID *Buffer, 54 | _In_ SIZE_T BufferSize, 55 | _In_ UINT32 Alignment 56 | ) 57 | { 58 | NTSTATUS Status; 59 | 60 | PAGED_CODE(); 61 | ASSERT(Bounce->Buffer == NULL); 62 | ASSERT(Alignment <= MEMORY_ALLOCATION_ALIGNMENT); 63 | 64 | if (BufferSize == 0) { 65 | // 66 | // Nothing to do. 67 | // 68 | Status = STATUS_SUCCESS; 69 | goto Exit; 70 | } 71 | 72 | Bounce->Buffer = 73 | ExAllocatePoolZero(NonPagedPoolNx, BufferSize, POOLTAG_BOUNCE_BUFFER); 74 | if (Bounce->Buffer == NULL) { 75 | Status = STATUS_NO_MEMORY; 76 | goto Exit; 77 | } 78 | 79 | __try { 80 | if (RequestorMode != KernelMode) { 81 | #pragma warning(suppress:6387) // Buffer could be NULL. 82 | ProbeForRead((VOID *)Buffer, BufferSize, Alignment); 83 | } 84 | #pragma warning(suppress:6387) // Buffer could be NULL. 85 | RtlCopyVolatileMemory(Bounce->Buffer, Buffer, BufferSize); 86 | } __except (EXCEPTION_EXECUTE_HANDLER) { 87 | Status = GetExceptionCode(); 88 | goto Exit; 89 | } 90 | 91 | Status = STATUS_SUCCESS; 92 | 93 | Exit: 94 | 95 | if (!NT_SUCCESS(Status)) { 96 | BounceCleanup(Bounce); 97 | } 98 | 99 | return Status; 100 | } 101 | -------------------------------------------------------------------------------- /src/common/lib/bounce/bounce.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {4a8c9c36-9b11-4bcf-9c48-0f33d4470d66} 5 | bounce 6 | drvlib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(SolutionDir)src\common\inc; 19 | %(AdditionalIncludeDirectories) 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/common/lib/fnio/enqueue.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include "precomp.h" 7 | 8 | static 9 | ENQUEUE_NBL_CONTEXT * 10 | FnIoEnqueueGetNblContext( 11 | _In_ NET_BUFFER_LIST *NetBufferList 12 | ) 13 | { 14 | return (ENQUEUE_NBL_CONTEXT *)NET_BUFFER_LIST_CONTEXT_DATA_START(NetBufferList); 15 | } 16 | 17 | _IRQL_requires_max_(DISPATCH_LEVEL) 18 | NTSTATUS 19 | FnIoEnqueueFrameBegin( 20 | _In_ KPROCESSOR_MODE RequestorMode, 21 | _In_ VOID *InputBuffer, 22 | _In_ UINT32 InputBufferLength, 23 | _In_ NDIS_HANDLE NblPool, 24 | _Out_ DATA_ENQUEUE_IN *EnqueueIn, 25 | _Out_ NET_BUFFER_LIST **NetBufferList 26 | ) 27 | { 28 | NET_BUFFER_LIST *Nbl = NULL; 29 | NET_BUFFER *Nb; 30 | ENQUEUE_NBL_CONTEXT *NblContext; 31 | NTSTATUS Status; 32 | 33 | *NetBufferList = NULL; 34 | 35 | Status = FnIoIoctlBounceEnqueue(RequestorMode, InputBuffer, InputBufferLength, EnqueueIn); 36 | if (!NT_SUCCESS(Status)) { 37 | goto Exit; 38 | } 39 | 40 | Nbl = NdisAllocateNetBufferAndNetBufferList(NblPool, sizeof(*NblContext), 0, NULL, 0, 0); 41 | if (Nbl == NULL) { 42 | Status = STATUS_NO_MEMORY; 43 | goto Exit; 44 | } 45 | 46 | Nb = NET_BUFFER_LIST_FIRST_NB(Nbl); 47 | NblContext = FnIoEnqueueGetNblContext(Nbl); 48 | RtlZeroMemory(NblContext, sizeof(*NblContext)); 49 | 50 | for (UINT32 BufferOffset = EnqueueIn->Frame.BufferCount; BufferOffset > 0; BufferOffset--) { 51 | CONST UINT32 BufferIndex = BufferOffset - 1; 52 | CONST DATA_BUFFER *RxBuffer = &EnqueueIn->Frame.Buffers[BufferIndex]; 53 | UCHAR *MdlBuffer; 54 | 55 | if (RxBuffer->DataOffset > 0 && BufferIndex > 0) { 56 | // 57 | // Only the first MDL can have a data offset. 58 | // 59 | Status = STATUS_INVALID_PARAMETER; 60 | goto Exit; 61 | } 62 | 63 | if (RxBuffer->DataOffset + RxBuffer->DataLength < RxBuffer->BufferLength && 64 | BufferOffset < EnqueueIn->Frame.BufferCount) { 65 | // 66 | // Only the last MDL can have a data trailer. 67 | // 68 | Status = STATUS_INVALID_PARAMETER; 69 | goto Exit; 70 | } 71 | 72 | // 73 | // Allocate an MDL and data to back the buffer. 74 | // 75 | Status = NdisRetreatNetBufferDataStart(Nb, RxBuffer->BufferLength, 0, NULL); 76 | if (Status != NDIS_STATUS_SUCCESS) { 77 | Status = STATUS_NO_MEMORY; 78 | goto Exit; 79 | } 80 | 81 | MdlBuffer = MmGetSystemAddressForMdlSafe(NET_BUFFER_CURRENT_MDL(Nb), LowPagePriority); 82 | if (MdlBuffer == NULL) { 83 | Status = STATUS_NO_MEMORY; 84 | goto Exit; 85 | } 86 | 87 | // 88 | // Copy the whole RX buffer, including leading and trailing bytes. 89 | // 90 | RtlCopyMemory(MdlBuffer, RxBuffer->VirtualAddress, RxBuffer->BufferLength); 91 | 92 | // 93 | // Fix up the trailing bytes of the final MDL. 94 | // 95 | if (BufferOffset == EnqueueIn->Frame.BufferCount) { 96 | NblContext->TrailingMdlBytes = 97 | RxBuffer->BufferLength - RxBuffer->DataLength - RxBuffer->DataOffset; 98 | NET_BUFFER_DATA_LENGTH(Nb) -= NblContext->TrailingMdlBytes; 99 | } 100 | 101 | // 102 | // Fix up the data offset for the leading MDL. 103 | // 104 | if (BufferIndex == 0) { 105 | NdisAdvanceNetBufferDataStart(Nb, RxBuffer->DataOffset, FALSE, NULL); 106 | } 107 | } 108 | 109 | *NetBufferList = Nbl; 110 | 111 | Exit: 112 | 113 | if (!NT_SUCCESS(Status)) { 114 | if (Nbl != NULL) { 115 | FnIoEnqueueFrameReturn(Nbl); 116 | } 117 | } 118 | 119 | return Status; 120 | } 121 | 122 | _IRQL_requires_max_(DISPATCH_LEVEL) 123 | VOID 124 | FnIoEnqueueFrameEnd( 125 | _In_ DATA_ENQUEUE_IN *EnqueueIn 126 | ) 127 | { 128 | FnIoIoctlCleanupEnqueue(EnqueueIn); 129 | } 130 | 131 | _IRQL_requires_max_(DISPATCH_LEVEL) 132 | VOID 133 | FnIoEnqueueFrameReturn( 134 | _In_ NET_BUFFER_LIST *Nbl 135 | ) 136 | { 137 | NET_BUFFER *Nb = NET_BUFFER_LIST_FIRST_NB(Nbl); 138 | ENQUEUE_NBL_CONTEXT *NblContext = FnIoEnqueueGetNblContext(Nbl); 139 | 140 | NET_BUFFER_DATA_LENGTH(Nb) += NblContext->TrailingMdlBytes; 141 | NdisRetreatNetBufferDataStart(Nb, NET_BUFFER_DATA_OFFSET(Nb), 0, NULL); 142 | NdisAdvanceNetBufferDataStart(Nb, NET_BUFFER_DATA_LENGTH(Nb), TRUE, NULL); 143 | NdisFreeNetBufferList(Nbl); 144 | } 145 | -------------------------------------------------------------------------------- /src/common/lib/fnio/fnio.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {d07edeb2-006f-4b32-8cd1-2b8fabd5879e} 5 | fnio 6 | drvlib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | $(SolutionDir)inc; 21 | $(SolutionDir)src\common\inc; 22 | %(AdditionalIncludeDirectories) 23 | 24 | 25 | NDIS684=1; 26 | %(PreprocessorDefinitions) 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/common/lib/fnio/ioctlbounce.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include "precomp.h" 9 | 10 | VOID 11 | FnIoIoctlCleanupFilter( 12 | _In_ DATA_FILTER_IN *FilterIn 13 | ); 14 | 15 | NTSTATUS 16 | FnIoIoctlBounceFilter( 17 | _In_ KPROCESSOR_MODE RequestorMode, 18 | _In_ CONST VOID *InputBuffer, 19 | _In_ SIZE_T InputBufferLength, 20 | _Out_ DATA_FILTER_IN *FilterIn 21 | ); 22 | 23 | VOID 24 | FnIoIoctlCleanupEnqueue( 25 | _Inout_ DATA_ENQUEUE_IN *EnqueueIn 26 | ); 27 | 28 | NTSTATUS 29 | FnIoIoctlBounceEnqueue( 30 | _In_ KPROCESSOR_MODE RequestorMode, 31 | _In_ CONST VOID *InputBuffer, 32 | _In_ SIZE_T InputBufferLength, 33 | _Out_ DATA_ENQUEUE_IN *EnqueueIn 34 | ); 35 | -------------------------------------------------------------------------------- /src/common/lib/fnio/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #pragma warning(disable:4201) // nonstandard extension used: nameless struct/union 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "ioctlbounce.h" 24 | -------------------------------------------------------------------------------- /src/isr/svc/isrsvc.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {32916b02-626c-4bdb-af0c-c586670bba0d} 5 | isrsvc 6 | exe 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | tracewpp.exe -odir:$(IntDir) -scan:$(SolutionDir)src\isr\svc\trace.h $(ProjectDir)*.cpp -p:isrsvc -cfgdir:"$(WindowsSdkDir)bin\$(TargetPlatformVersion)\WppConfig\Rev1" 19 | 20 | 21 | 22 | 23 | $(SolutionDir)inc; 24 | %(AdditionalIncludeDirectories) 25 | 26 | 27 | 28 | 29 | ntdll.lib; 30 | onecore.lib; 31 | advapi32.lib; 32 | %(AdditionalDependencies) 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/isr/svc/trace.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // DBE35650-5285-4CAF-B64A-B707B8ECAD2C 13 | // 14 | #define WPP_CONTROL_GUIDS \ 15 | WPP_DEFINE_CONTROL_GUID( \ 16 | IsrSvcTraceGuid, \ 17 | (DBE35650,5285,4CAF,B64A,B707B8ECAD2C), \ 18 | WPP_DEFINE_BIT(TRACE_CONTROL) \ 19 | ) 20 | 21 | // 22 | // The following system defined definitions may be used: 23 | // 24 | // TRACE_LEVEL_FATAL = 1 // Abnormal exit or termination. 25 | // TRACE_LEVEL_ERROR = 2 // Severe errors that need logging. 26 | // TRACE_LEVEL_WARNING = 3 // Warnings such as allocation failures. 27 | // TRACE_LEVEL_INFORMATION = 4 // Including non-error cases. 28 | // TRACE_LEVEL_VERBOSE = 5 // Detailed traces from intermediate steps. 29 | // 30 | // begin_wpp config 31 | // 32 | // USEPREFIX(TraceFatal,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 33 | // FUNC TraceFatal{LEVEL=TRACE_LEVEL_FATAL}(FLAGS,MSG,...); 34 | // 35 | // USEPREFIX(TraceError,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 36 | // FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR}(FLAGS,MSG,...); 37 | // 38 | // USEPREFIX(TraceWarn,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 39 | // FUNC TraceWarn{LEVEL=TRACE_LEVEL_WARNING}(FLAGS,MSG,...); 40 | // 41 | // USEPREFIX(TraceInfo,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 42 | // FUNC TraceInfo{LEVEL=TRACE_LEVEL_INFORMATION}(FLAGS,MSG,...); 43 | // 44 | // USEPREFIX(TraceVerbose,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 45 | // FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,MSG,...); 46 | // 47 | // USEPREFIX(TraceEnter,"%!STDPREFIX! %!FUNC!:%!LINE! --->%!SPACE!"); 48 | // FUNC TraceEnter{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,MSG,...); 49 | // 50 | // USEPREFIX(TraceExitSuccess,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE! "); 51 | // FUNC TraceExitSuccess{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,...); 52 | // USESUFFIX (TraceExitSuccess, "STATUS_SUCCESS"); 53 | // 54 | // USEPREFIX(TraceExitStatus,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE!"); 55 | // FUNC TraceExitStatus{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS); 56 | // USESUFFIX (TraceExitStatus, "%!STATUS!", Status); 57 | // 58 | // end_wpp 59 | // 60 | 61 | #define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) \ 62 | (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL)) 63 | #define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS) 64 | 65 | // 66 | // Opt-in to a WPP recorder feature that enables independent evaluation of 67 | // conditions to decide if a message needs to be sent to the recorder, an 68 | // enabled session, or both. 69 | // 70 | #define ENABLE_WPP_TRACE_FILTERING_WITH_WPP_RECORDER 1 71 | 72 | // 73 | // Logger and Enabled macros that support custom recorders. They simply delegate 74 | // to the default. 75 | // 76 | #define WPP_IFRLOG_LEVEL_FLAGS_ENABLED(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) 77 | #define WPP_IFRLOG_LEVEL_FLAGS_LOGGER(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) 78 | -------------------------------------------------------------------------------- /src/isr/sys/client.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | typedef struct _CLIENT_USER_CONTEXT { 9 | FILE_OBJECT_HEADER Header; 10 | } CLIENT_USER_CONTEXT; 11 | 12 | NTSTATUS 13 | ClientIrpCreate( 14 | _In_ IRP *Irp, 15 | _In_ IO_STACK_LOCATION *IrpSp, 16 | _In_ UCHAR Disposition, 17 | _In_ VOID *InputBuffer, 18 | _In_ SIZE_T InputBufferLength 19 | ); 20 | -------------------------------------------------------------------------------- /src/isr/sys/dispatch.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | typedef 11 | _IRQL_requires_max_(PASSIVE_LEVEL) 12 | NTSTATUS 13 | FILE_CREATE_ROUTINE( 14 | _In_ IRP *Irp, 15 | _In_ IO_STACK_LOCATION *IrpSp, 16 | _In_ UCHAR Disposition, 17 | _In_ VOID *InputBuffer, 18 | _In_ SIZE_T InputBufferLength 19 | ); 20 | 21 | typedef 22 | _IRQL_requires_max_(PASSIVE_LEVEL) 23 | NTSTATUS 24 | FILE_IRP_ROUTINE( 25 | _In_ IRP *Irp, 26 | _In_ IO_STACK_LOCATION *IrpSp 27 | ); 28 | 29 | typedef struct FILE_DISPATCH { 30 | FILE_IRP_ROUTINE *IoControl; 31 | FILE_IRP_ROUTINE *Cleanup; 32 | FILE_IRP_ROUTINE *Close; 33 | } FILE_DISPATCH; 34 | 35 | typedef struct FILE_OBJECT_HEADER { 36 | ISR_FILE_TYPE ObjectType; 37 | const FILE_DISPATCH *Dispatch; 38 | } FILE_OBJECT_HEADER; 39 | -------------------------------------------------------------------------------- /src/isr/sys/isrdrv.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {644a5488-7fb8-4c8b-a45a-981df9a56aef} 5 | isrdrv 6 | sys 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | $(SolutionDir)inc; 23 | $(SolutionDir)src\common\inc; 24 | %(AdditionalIncludeDirectories) 25 | 26 | true 27 | $(ProjectDir)trace.h 28 | true 29 | -p:isrdrv 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/isr/sys/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | #include "invokesystemrelayioctl.h" 12 | 13 | #include "dispatch.h" 14 | #include "client.h" 15 | #include "pooltag.h" 16 | #include "requestqueue.h" 17 | #include "service.h" 18 | #include "trace.h" 19 | -------------------------------------------------------------------------------- /src/isr/sys/requestqueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Client API. 10 | // 11 | 12 | // 13 | // Notifies the client when a specific request has been completed. 14 | // 15 | typedef 16 | _IRQL_requires_max_(PASSIVE_LEVEL) 17 | VOID 18 | CLIENT_REQUEST_COMPLETE_FN( 19 | _In_ UINT64 Id, 20 | _In_ VOID *Context, 21 | _In_ INT Result 22 | ); 23 | 24 | // 25 | // Registers a request queue client. The client adds requests and waits for 26 | // their completion. 27 | // 28 | // Only a single client may be registered at a time. 29 | // 30 | _IRQL_requires_max_(PASSIVE_LEVEL) 31 | NTSTATUS 32 | RqClientRegister( 33 | _In_ CLIENT_REQUEST_COMPLETE_FN *ClientRequestComplete 34 | ); 35 | 36 | // 37 | // Upon return, no client callbacks will be invoked. 38 | // 39 | _IRQL_requires_max_(PASSIVE_LEVEL) 40 | VOID 41 | RqClientDeregister( 42 | VOID 43 | ); 44 | 45 | // 46 | // Push a request onto the queue to be processed. 47 | // If successful, the result will be returned via the completion callback. 48 | // 49 | _IRQL_requires_max_(PASSIVE_LEVEL) 50 | NTSTATUS 51 | RqClientPushRequest( 52 | _In_ UINT64 Id, 53 | _In_ VOID *Context, 54 | _In_z_ CHAR *Command 55 | ); 56 | 57 | // 58 | // Service API. 59 | // 60 | 61 | typedef struct _ISR_REQUEST { 62 | LIST_ENTRY Link; 63 | UINT64 Id; 64 | VOID *ClientContext; 65 | CHAR Command[ISR_MAX_COMMAND_LENGTH]; 66 | } ISR_REQUEST; 67 | 68 | // 69 | // Notifies the service when a request is available for processing. 70 | // 71 | typedef 72 | _IRQL_requires_max_(PASSIVE_LEVEL) 73 | VOID 74 | SERVICE_REQUEST_AVAILABLE_FN( 75 | VOID 76 | ); 77 | 78 | // 79 | // Registers a request queue service. The service waits for requests to be 80 | // added, processes the requests, and posts their results. 81 | // 82 | // Only a single service may be registered at a time. 83 | // 84 | _IRQL_requires_max_(PASSIVE_LEVEL) 85 | NTSTATUS 86 | RqServiceRegister( 87 | _In_ SERVICE_REQUEST_AVAILABLE_FN *ServerRequestAvailable 88 | ); 89 | 90 | // 91 | // Upon return, no service callbacks will be invoked. 92 | // 93 | _IRQL_requires_max_(PASSIVE_LEVEL) 94 | VOID 95 | RqServiceDeregister( 96 | VOID 97 | ); 98 | 99 | // 100 | // Pop a request from the queue. 101 | // The service must post the request's result via RqServicePostRequestResult. 102 | // 103 | _IRQL_requires_max_(DISPATCH_LEVEL) 104 | NTSTATUS 105 | RqServicePopRequest( 106 | _Out_ ISR_REQUEST **Request 107 | ); 108 | 109 | // 110 | // Post the result for the specified request. 111 | // 112 | _IRQL_requires_max_(PASSIVE_LEVEL) 113 | VOID 114 | RqServiceCompleteRequest( 115 | _In_ ISR_REQUEST *Request, 116 | _In_ INT Result 117 | ); 118 | 119 | // 120 | // Module Init/Uninit. 121 | // 122 | 123 | _IRQL_requires_max_(PASSIVE_LEVEL) 124 | NTSTATUS 125 | RqInitialize( 126 | VOID 127 | ); 128 | 129 | _IRQL_requires_max_(PASSIVE_LEVEL) 130 | VOID 131 | RqUninitialize( 132 | VOID 133 | ); 134 | -------------------------------------------------------------------------------- /src/isr/sys/service.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | typedef struct _SERVICE_USER_CONTEXT { 9 | FILE_OBJECT_HEADER Header; 10 | } SERVICE_USER_CONTEXT; 11 | 12 | NTSTATUS 13 | ServiceIrpCreate( 14 | _In_ IRP *Irp, 15 | _In_ IO_STACK_LOCATION *IrpSp, 16 | _In_ UCHAR Disposition, 17 | _In_ VOID *InputBuffer, 18 | _In_ SIZE_T InputBufferLength 19 | ); 20 | 21 | _IRQL_requires_max_(PASSIVE_LEVEL) 22 | NTSTATUS 23 | ServiceInitialize( 24 | VOID 25 | ); 26 | 27 | _IRQL_requires_max_(PASSIVE_LEVEL) 28 | VOID 29 | ServiceUninitialize( 30 | VOID 31 | ); 32 | -------------------------------------------------------------------------------- /src/isr/sys/trace.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // ADAACE40-590D-488B-89C9-99798D20F2F6 13 | // 14 | #define WPP_CONTROL_GUIDS \ 15 | WPP_DEFINE_CONTROL_GUID( \ 16 | IsrDrvTraceGuid, \ 17 | (ADAACE40,590D,488B,89C9,99798D20F2F6), \ 18 | WPP_DEFINE_BIT(TRACE_CONTROL) \ 19 | ) 20 | 21 | // 22 | // The following system defined definitions may be used: 23 | // 24 | // TRACE_LEVEL_FATAL = 1 // Abnormal exit or termination. 25 | // TRACE_LEVEL_ERROR = 2 // Severe errors that need logging. 26 | // TRACE_LEVEL_WARNING = 3 // Warnings such as allocation failures. 27 | // TRACE_LEVEL_INFORMATION = 4 // Including non-error cases. 28 | // TRACE_LEVEL_VERBOSE = 5 // Detailed traces from intermediate steps. 29 | // 30 | // begin_wpp config 31 | // 32 | // USEPREFIX(TraceFatal,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 33 | // FUNC TraceFatal{LEVEL=TRACE_LEVEL_FATAL}(FLAGS,MSG,...); 34 | // 35 | // USEPREFIX(TraceError,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 36 | // FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR}(FLAGS,MSG,...); 37 | // 38 | // USEPREFIX(TraceWarn,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 39 | // FUNC TraceWarn{LEVEL=TRACE_LEVEL_WARNING}(FLAGS,MSG,...); 40 | // 41 | // USEPREFIX(TraceInfo,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 42 | // FUNC TraceInfo{LEVEL=TRACE_LEVEL_INFORMATION}(FLAGS,MSG,...); 43 | // 44 | // USEPREFIX(TraceVerbose,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 45 | // FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,MSG,...); 46 | // 47 | // USEPREFIX(TraceEnter,"%!STDPREFIX! %!FUNC!:%!LINE! --->%!SPACE!"); 48 | // FUNC TraceEnter{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,MSG,...); 49 | // 50 | // USEPREFIX(TraceExitSuccess,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE! "); 51 | // FUNC TraceExitSuccess{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,...); 52 | // USESUFFIX (TraceExitSuccess, "STATUS_SUCCESS"); 53 | // 54 | // USEPREFIX(TraceExitStatus,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE!"); 55 | // FUNC TraceExitStatus{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS); 56 | // USESUFFIX (TraceExitStatus, "%!STATUS!", Status); 57 | // 58 | // end_wpp 59 | // 60 | 61 | #define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) \ 62 | (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL)) 63 | #define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS) 64 | 65 | // 66 | // Opt-in to a WPP recorder feature that enables independent evaluation of 67 | // conditions to decide if a message needs to be sent to the recorder, an 68 | // enabled session, or both. 69 | // 70 | #define ENABLE_WPP_TRACE_FILTERING_WITH_WPP_RECORDER 1 71 | 72 | // 73 | // Logger and Enabled macros that support custom recorders. They simply delegate 74 | // to the default. 75 | // 76 | #define WPP_IFRLOG_LEVEL_FLAGS_ENABLED(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) 77 | #define WPP_IFRLOG_LEVEL_FLAGS_LOGGER(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) 78 | -------------------------------------------------------------------------------- /src/lwf/sys/default.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include "precomp.h" 7 | 8 | static 9 | _IRQL_requires_max_(PASSIVE_LEVEL) 10 | NTSTATUS 11 | DefaultIrpDeviceIoControl( 12 | _In_ IRP *Irp, 13 | _In_ IO_STACK_LOCATION *IrpSp 14 | ) 15 | { 16 | DEFAULT_CONTEXT *Default = IrpSp->FileObject->FsContext; 17 | NTSTATUS Status; 18 | 19 | switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { 20 | 21 | case FNLWF_IOCTL_RX_FILTER: 22 | Status = RxIrpFilter(Default->Rx, Irp, IrpSp); 23 | break; 24 | 25 | case FNLWF_IOCTL_RX_GET_FRAME: 26 | Status = RxIrpGetFrame(Default->Rx, Irp, IrpSp); 27 | break; 28 | 29 | case FNLWF_IOCTL_RX_DEQUEUE_FRAME: 30 | Status = RxIrpDequeueFrame(Default->Rx, Irp, IrpSp); 31 | break; 32 | 33 | case FNLWF_IOCTL_RX_FLUSH: 34 | Status = RxIrpFlush(Default->Rx, Irp, IrpSp); 35 | break; 36 | 37 | case FNLWF_IOCTL_TX_ENQUEUE: 38 | Status = TxIrpEnqueue(Default->Tx, Irp, IrpSp); 39 | break; 40 | 41 | case FNLWF_IOCTL_TX_FLUSH: 42 | Status = TxIrpFlush(Default->Tx, Irp, IrpSp); 43 | break; 44 | 45 | case FNLWF_IOCTL_OID_SUBMIT_REQUEST: 46 | Status = OidIrpSubmitRequest(Default, Irp, IrpSp); 47 | break; 48 | 49 | case FNLWF_IOCTL_STATUS_SET_FILTER: 50 | Status = StatusIrpFilter(Default->Status, Irp, IrpSp); 51 | break; 52 | 53 | case FNLWF_IOCTL_STATUS_GET_INDICATION: 54 | Status = StatusIrpGetIndication(Default->Status, Irp, IrpSp); 55 | break; 56 | 57 | case FNLWF_IOCTL_DATAPATH_GET_STATE: 58 | Status = FilterIrpGetDatapathState(Default->Filter, Irp, IrpSp); 59 | break; 60 | 61 | default: 62 | Status = STATUS_NOT_SUPPORTED; 63 | goto Exit; 64 | } 65 | 66 | Exit: 67 | 68 | return Status; 69 | } 70 | 71 | static 72 | VOID 73 | DefaultCleanup( 74 | _In_ DEFAULT_CONTEXT *Default 75 | ) 76 | { 77 | if (Default->Status != NULL) { 78 | StatusCleanup(Default->Status); 79 | } 80 | 81 | if (Default->Tx != NULL) { 82 | TxCleanup(Default->Tx); 83 | } 84 | 85 | if (Default->Rx != NULL) { 86 | RxCleanup(Default->Rx); 87 | } 88 | 89 | if (Default->Filter != NULL) { 90 | FilterDereferenceFilter(Default->Filter); 91 | } 92 | 93 | ExFreePoolWithTag(Default, POOLTAG_LWF_DEFAULT); 94 | } 95 | 96 | static 97 | _IRQL_requires_max_(PASSIVE_LEVEL) 98 | NTSTATUS 99 | DefaultIrpClose( 100 | _In_ IRP *Irp, 101 | _In_ IO_STACK_LOCATION *IrpSp 102 | ) 103 | { 104 | UNREFERENCED_PARAMETER(Irp); 105 | 106 | DefaultCleanup(IrpSp->FileObject->FsContext); 107 | 108 | return STATUS_SUCCESS; 109 | } 110 | 111 | static const FILE_DISPATCH DefaultFileDispatch = { 112 | .IoControl = DefaultIrpDeviceIoControl, 113 | .Close = DefaultIrpClose, 114 | }; 115 | 116 | NTSTATUS 117 | DefaultIrpCreate( 118 | _In_ IRP *Irp, 119 | _In_ IO_STACK_LOCATION *IrpSp, 120 | _In_ UCHAR Disposition, 121 | _In_ VOID *InputBuffer, 122 | _In_ SIZE_T InputBufferLength 123 | ) 124 | { 125 | NTSTATUS Status; 126 | DEFAULT_CONTEXT *Default = NULL; 127 | FNLWF_OPEN_DEFAULT *OpenDefault; 128 | 129 | UNREFERENCED_PARAMETER(Irp); 130 | UNREFERENCED_PARAMETER(Disposition); 131 | 132 | if (InputBufferLength < sizeof(*OpenDefault)) { 133 | Status = STATUS_BUFFER_TOO_SMALL; 134 | goto Exit; 135 | } 136 | OpenDefault = InputBuffer; 137 | 138 | Default = ExAllocatePoolZero(NonPagedPoolNx, sizeof(*Default), POOLTAG_LWF_DEFAULT); 139 | if (Default == NULL) { 140 | Status = STATUS_INSUFFICIENT_RESOURCES; 141 | goto Exit; 142 | } 143 | 144 | Default->Header.ObjectType = FNLWF_FILE_TYPE_DEFAULT; 145 | Default->Header.Dispatch = &DefaultFileDispatch; 146 | KeInitializeSpinLock(&Default->Lock); 147 | 148 | Default->Filter = FilterFindAndReferenceFilter(OpenDefault->IfIndex); 149 | if (Default->Filter == NULL) { 150 | Status = STATUS_NOT_FOUND; 151 | goto Exit; 152 | } 153 | 154 | Default->Rx = RxCreate(Default); 155 | if (Default->Rx == NULL) { 156 | Status = STATUS_NO_MEMORY; 157 | goto Exit; 158 | } 159 | 160 | Default->Tx = TxCreate(Default); 161 | if (Default->Tx == NULL) { 162 | Status = STATUS_NO_MEMORY; 163 | goto Exit; 164 | } 165 | 166 | Default->Status = StatusCreate(Default); 167 | if (Default->Status == NULL) { 168 | Status = STATUS_NO_MEMORY; 169 | goto Exit; 170 | } 171 | 172 | IrpSp->FileObject->FsContext = Default; 173 | Status = STATUS_SUCCESS; 174 | 175 | Exit: 176 | 177 | if (!NT_SUCCESS(Status)) { 178 | if (Default != NULL) { 179 | DefaultCleanup(Default); 180 | } 181 | } 182 | 183 | return Status; 184 | } 185 | -------------------------------------------------------------------------------- /src/lwf/sys/default.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include "dispatch.h" 9 | 10 | typedef struct _LWF_FILTER LWF_FILTER; 11 | typedef struct _DEFAULT_RX DEFAULT_RX; 12 | typedef struct _DEFAULT_TX DEFAULT_TX; 13 | typedef struct _DEFAULT_STATUS DEFAULT_STATUS; 14 | 15 | typedef struct _DEFAULT_CONTEXT { 16 | FILE_OBJECT_HEADER Header; 17 | KSPIN_LOCK Lock; 18 | LWF_FILTER *Filter; 19 | DEFAULT_RX *Rx; 20 | DEFAULT_TX *Tx; 21 | DEFAULT_STATUS *Status; 22 | } DEFAULT_CONTEXT; 23 | 24 | FILE_CREATE_ROUTINE DefaultIrpCreate; 25 | -------------------------------------------------------------------------------- /src/lwf/sys/dispatch.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | typedef 11 | _IRQL_requires_max_(PASSIVE_LEVEL) 12 | NTSTATUS 13 | FILE_CREATE_ROUTINE( 14 | _In_ IRP *Irp, 15 | _In_ IO_STACK_LOCATION *IrpSp, 16 | _In_ UCHAR Disposition, 17 | _In_ VOID *InputBuffer, 18 | _In_ SIZE_T InputBufferLength 19 | ); 20 | 21 | typedef 22 | _IRQL_requires_max_(PASSIVE_LEVEL) 23 | NTSTATUS 24 | FILE_IRP_ROUTINE( 25 | _In_ IRP *Irp, 26 | _In_ IO_STACK_LOCATION *IrpSp 27 | ); 28 | 29 | typedef struct FILE_DISPATCH { 30 | FILE_IRP_ROUTINE *IoControl; 31 | FILE_IRP_ROUTINE *Cleanup; 32 | FILE_IRP_ROUTINE *Close; 33 | } FILE_DISPATCH; 34 | 35 | typedef struct FILE_OBJECT_HEADER { 36 | FNLWF_FILE_TYPE ObjectType; 37 | const FILE_DISPATCH *Dispatch; 38 | UINT32 ApiVersion; 39 | } FILE_OBJECT_HEADER; 40 | -------------------------------------------------------------------------------- /src/lwf/sys/filter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | typedef enum _LWF_FILTER_STATE { 9 | FilterDetached, 10 | FilterPaused, 11 | FilterPausing, 12 | FilterRunning, 13 | } LWF_FILTER_STATE; 14 | 15 | typedef struct _LWF_FILTER { 16 | LIST_ENTRY FilterListLink; 17 | NDIS_HANDLE NdisFilterHandle; 18 | NET_IFINDEX MiniportIfIndex; 19 | LWF_FILTER_STATE NdisState; 20 | FN_REFERENCE_COUNT ReferenceCount; 21 | KSPIN_LOCK Lock; 22 | 23 | EX_RUNDOWN_REF NblRundown; 24 | EX_RUNDOWN_REF OidRundown; 25 | NDIS_HANDLE NblPool; 26 | LIST_ENTRY RxFilterList; 27 | LIST_ENTRY StatusFilterList; 28 | FN_TIMER_HANDLE WatchdogTimer; 29 | } LWF_FILTER; 30 | 31 | typedef struct _GLOBAL_CONTEXT { 32 | EX_PUSH_LOCK Lock; 33 | LIST_ENTRY FilterList; 34 | HANDLE NdisDriverHandle; 35 | UINT32 NdisVersion; 36 | } GLOBAL_CONTEXT; 37 | 38 | extern GLOBAL_CONTEXT LwfGlobalContext; 39 | 40 | NTSTATUS 41 | FilterStart( 42 | _In_ DRIVER_OBJECT *DriverObject 43 | ); 44 | 45 | VOID 46 | FilterStop( 47 | VOID 48 | ); 49 | 50 | VOID 51 | FilterDereferenceFilter( 52 | _In_ LWF_FILTER *Filter 53 | ); 54 | 55 | LWF_FILTER * 56 | FilterFindAndReferenceFilter( 57 | _In_ UINT32 IfIndex 58 | ); 59 | 60 | _IRQL_requires_max_(PASSIVE_LEVEL) 61 | NTSTATUS 62 | FilterIrpGetDatapathState( 63 | _In_ LWF_FILTER *Filter, 64 | _In_ IRP *Irp, 65 | _In_ IO_STACK_LOCATION *IrpSp 66 | ); 67 | 68 | _IRQL_requires_max_(DISPATCH_LEVEL) 69 | VOID 70 | FilterWatchdogFailure( 71 | _In_ LWF_FILTER *Filter, 72 | _In_z_ CONST CHAR *WatchdogType 73 | ); 74 | -------------------------------------------------------------------------------- /src/lwf/sys/fnlwf.rc: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include 7 | #include 8 | 9 | #define VER_FILETYPE VFT_DRV 10 | #define VER_FILESUBTYPE VFT2_DRV_NETWORK 11 | #define VER_FILEDESCRIPTION_STR "Functional Test Light Weight Filter" 12 | #define VER_INTERNALNAME_STR "fnlwf.sys" 13 | #define VER_ORIGINALFILENAME_STR "fnlwf.sys" 14 | 15 | #include "common.ver" 16 | -------------------------------------------------------------------------------- /src/lwf/sys/fnlwf.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {f819a7ae-2641-4275-a3ba-cf9283c9d519} 5 | fnlwf 6 | sys 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | {4a8c9c36-9b11-4bcf-9c48-0f33d4470d66} 15 | 16 | 17 | {d07edeb2-006f-4b32-8cd1-2b8fabd5879e} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | true 34 | 35 | 36 | 37 | 38 | 39 | $(SolutionDir)inc; 40 | $(SolutionDir)src\common\inc; 41 | $(SolutionDir)src\lwf\inc; 42 | %(AdditionalIncludeDirectories) 43 | 44 | 45 | NDIS_MINIPORT_DRIVER; 46 | NDIS685_MINIPORT=1; 47 | %(PreprocessorDefinitions) 48 | 49 | true 50 | $(ProjectDir)trace.h 51 | true 52 | -p:fnlwf 53 | 54 | 55 | 56 | ndis.lib; 57 | netio.lib; 58 | %(AdditionalDependencies) 59 | 60 | 61 | volatileaccessk.lib; 62 | %(AdditionalDependencies) 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/lwf/sys/inf/fnlwf.inx: -------------------------------------------------------------------------------- 1 | ; Copyright (c) 2020, Microsoft 2 | 3 | [Version] 4 | CatalogFile = fnlwf.cat 5 | Signature = "$WINDOWS NT$" 6 | Class = NetService 7 | ClassGUID = {4D36E974-E325-11CE-BFC1-08002BE10318} 8 | Provider = %Msft% 9 | PnpLockdown = 1 10 | 11 | [DestinationDirs] 12 | fnlwf.CopyFiles = %DIRID_DRIVERS% 13 | 14 | [SourceDisksNames] 15 | 1 = disk 16 | 17 | [SourceDisksFiles] 18 | fnlwf.sys = 1 19 | 20 | [Manufacturer] 21 | %Msft% = MSFT,NT$ARCH$.10.0...17763 22 | 23 | [MSFT.NT$ARCH$.10.0...17763] 24 | %fnlwf.DeviceDesc% = Install, ms_fnlwf 25 | 26 | [Install] 27 | Characteristics = %NCF_LW_FILTER% 28 | NetCfgInstanceId = "{4b399bac-cfdf-477b-9c72-abed8717bc1a}" 29 | CopyFiles = fnlwf.CopyFiles 30 | AddReg = fnlwf.ndi.reg 31 | 32 | [fnlwf.CopyFiles] 33 | fnlwf.sys 34 | 35 | [fnlwf.ndi.reg] 36 | HKR, Ndi, Service,, "fnlwf" 37 | HKR, Ndi, CoServices, %REG_MULTI_SZ%, "fnlwf" 38 | HKR, Ndi, HelpText,, %fnlwf.DeviceDesc% 39 | HKR, Ndi, FilterClass,, ms_firewall_upper 40 | HKR, Ndi, FilterType, %REG_DWORD%, %FILTER_TYPE_MODIFYING% 41 | HKR, Ndi, FilterRunType, %REG_DWORD%, %FILTER_RUN_TYPE_OPTIONAL% 42 | HKR, Ndi\Interfaces, UpperRange,, "noupper" 43 | HKR, Ndi\Interfaces, LowerRange,, "ndisvf" 44 | HKR, Ndi\Interfaces, FilterMediaTypes,, "ethernet, ndisvf" 45 | 46 | [Install.Services] 47 | AddService=fnlwf,, AddService 48 | 49 | [AddService] 50 | DisplayName = %fnlwf.DeviceDesc% 51 | ServiceType = 1 ;SERVICE_KERNEL_DRIVER 52 | StartType = 1 ;SERVICE_SYSTEM_START 53 | ErrorControl = 1 ;SERVICE_ERROR_NORMAL 54 | ServiceBinary = %12%\fnlwf.sys ; %DIRID_DRIVERS%\fnlwf.sys 55 | LoadOrderGroup = NDIS 56 | AddReg = AddServiceReg 57 | 58 | [AddServiceReg] 59 | ; Enable circular log buffer at verbose level during development. 60 | HKR, "Parameters", "VerboseOn", %REG_DWORD%, 1 61 | HKR, "Parameters", "LogPages", %REG_DWORD%, 64 62 | 63 | [Install.Remove.Services] 64 | DelService = fnlwf, %SPSVCINST_STOPSERVICE% 65 | 66 | [Strings] 67 | ; localizable strings 68 | Msft = "Microsoft Corporation" 69 | fnlwf.DeviceDesc = "FNLWF" 70 | 71 | ; non-localizable strings 72 | DIRID_DRIVERS = 12 73 | FILTER_RUN_TYPE_OPTIONAL = 2 74 | FILTER_TYPE_MODIFYING = 2 75 | NCF_LW_FILTER = 0x40000 76 | REG_MULTI_SZ = 0x10000 77 | REG_DWORD = 0x10001 78 | SPSVCINST_STOPSERVICE = 0x200 79 | -------------------------------------------------------------------------------- /src/lwf/sys/oid.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | FILTER_OID_REQUEST FilterOidRequest; 9 | FILTER_OID_REQUEST_COMPLETE FilterOidRequestComplete; 10 | FILTER_DIRECT_OID_REQUEST FilterDirectOidRequest; 11 | FILTER_DIRECT_OID_REQUEST_COMPLETE FilterDirectOidRequestComplete; 12 | 13 | _IRQL_requires_max_(PASSIVE_LEVEL) 14 | NTSTATUS 15 | OidIrpSubmitRequest( 16 | _In_ DEFAULT_CONTEXT *Default, 17 | _In_ IRP *Irp, 18 | _In_ IO_STACK_LOCATION *IrpSp 19 | ); 20 | -------------------------------------------------------------------------------- /src/lwf/sys/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "default.h" 22 | #include "dispatch.h" 23 | #include "filter.h" 24 | #include "oid.h" 25 | #include "pooltag.h" 26 | #include "rx.h" 27 | #include "status.h" 28 | #include "trace.h" 29 | #include "tx.h" 30 | #include "fnlwfioctl.h" 31 | 32 | #define LWF_APIVER(_N) (_N) 33 | -------------------------------------------------------------------------------- /src/lwf/sys/rx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | FILTER_RETURN_NET_BUFFER_LISTS FilterReturnNetBufferLists; 9 | FILTER_RECEIVE_NET_BUFFER_LISTS FilterReceiveNetBufferLists; 10 | 11 | typedef struct _DEFAULT_RX DEFAULT_RX; 12 | 13 | VOID 14 | RxCleanup( 15 | _In_ DEFAULT_RX *Rx 16 | ); 17 | 18 | DEFAULT_RX * 19 | RxCreate( 20 | _In_ DEFAULT_CONTEXT *Default 21 | ); 22 | 23 | _IRQL_requires_max_(PASSIVE_LEVEL) 24 | NTSTATUS 25 | RxIrpFilter( 26 | _In_ DEFAULT_RX *Rx, 27 | _In_ IRP *Irp, 28 | _In_ IO_STACK_LOCATION *IrpSp 29 | ); 30 | 31 | _IRQL_requires_max_(PASSIVE_LEVEL) 32 | NTSTATUS 33 | RxIrpGetFrame( 34 | _In_ DEFAULT_RX *Rx, 35 | _In_ IRP *Irp, 36 | _In_ IO_STACK_LOCATION *IrpSp 37 | ); 38 | 39 | _IRQL_requires_max_(PASSIVE_LEVEL) 40 | NTSTATUS 41 | RxIrpDequeueFrame( 42 | _In_ DEFAULT_RX *Rx, 43 | _In_ IRP *Irp, 44 | _In_ IO_STACK_LOCATION *IrpSp 45 | ); 46 | 47 | _IRQL_requires_max_(PASSIVE_LEVEL) 48 | NTSTATUS 49 | RxIrpFlush( 50 | _In_ DEFAULT_RX *Rx, 51 | _In_ IRP *Irp, 52 | _In_ IO_STACK_LOCATION *IrpSp 53 | ); 54 | 55 | _IRQL_requires_max_(PASSIVE_LEVEL) 56 | VOID 57 | RxWatchdogTimeout( 58 | _In_ LWF_FILTER *Filter 59 | ); 60 | -------------------------------------------------------------------------------- /src/lwf/sys/status.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | FILTER_STATUS FilterStatus; 9 | 10 | typedef struct _DEFAULT_STATUS DEFAULT_STATUS; 11 | 12 | VOID 13 | StatusCleanup( 14 | _In_ DEFAULT_STATUS *StatusFile 15 | ); 16 | 17 | DEFAULT_STATUS * 18 | StatusCreate( 19 | _In_ DEFAULT_CONTEXT *Default 20 | ); 21 | 22 | _IRQL_requires_max_(PASSIVE_LEVEL) 23 | NTSTATUS 24 | StatusIrpFilter( 25 | _In_ DEFAULT_STATUS *StatusFile, 26 | _In_ IRP *Irp, 27 | _In_ IO_STACK_LOCATION *IrpSp 28 | ); 29 | 30 | _IRQL_requires_max_(PASSIVE_LEVEL) 31 | NTSTATUS 32 | StatusIrpGetIndication( 33 | _In_ DEFAULT_STATUS *StatusFile, 34 | _In_ IRP *Irp, 35 | _In_ IO_STACK_LOCATION *IrpSp 36 | ); 37 | -------------------------------------------------------------------------------- /src/lwf/sys/trace.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include "precomp.h" 7 | #include "trace.tmh" 8 | 9 | VOID 10 | TraceNbls( 11 | _In_ NET_BUFFER_LIST *NblChain 12 | ) 13 | { 14 | while (NblChain != NULL) { 15 | TraceVerbose(TRACE_DATAPATH, "Nbl=%p", NblChain); 16 | NblChain = NblChain->Next; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/lwf/sys/trace.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // {D6143B61-9FD6-44BA-BA02-FAD9EA0C263D} 13 | // 14 | #define WPP_CONTROL_GUIDS \ 15 | WPP_DEFINE_CONTROL_GUID( \ 16 | FnLwfTraceGuid, \ 17 | (D6143B61,9FD6,44BA,BA02,FAD9EA0C263D), \ 18 | WPP_DEFINE_BIT(TRACE_CONTROL) \ 19 | WPP_DEFINE_BIT(TRACE_DATAPATH) \ 20 | ) 21 | 22 | // 23 | // The following system defined definitions may be used: 24 | // 25 | // TRACE_LEVEL_FATAL = 1 // Abnormal exit or termination. 26 | // TRACE_LEVEL_ERROR = 2 // Severe errors that need logging. 27 | // TRACE_LEVEL_WARNING = 3 // Warnings such as allocation failures. 28 | // TRACE_LEVEL_INFORMATION = 4 // Including non-error cases. 29 | // TRACE_LEVEL_VERBOSE = 5 // Detailed traces from intermediate steps. 30 | // 31 | // begin_wpp config 32 | // 33 | // USEPREFIX(TraceFatal,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 34 | // FUNC TraceFatal{LEVEL=TRACE_LEVEL_FATAL}(FLAGS,MSG,...); 35 | // 36 | // USEPREFIX(TraceError,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 37 | // FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR}(FLAGS,MSG,...); 38 | // 39 | // USEPREFIX(TraceWarn,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 40 | // FUNC TraceWarn{LEVEL=TRACE_LEVEL_WARNING}(FLAGS,MSG,...); 41 | // 42 | // USEPREFIX(TraceInfo,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 43 | // FUNC TraceInfo{LEVEL=TRACE_LEVEL_INFORMATION}(FLAGS,MSG,...); 44 | // 45 | // USEPREFIX(TraceVerbose,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 46 | // FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,MSG,...); 47 | // 48 | // USEPREFIX(TraceEnter,"%!STDPREFIX! %!FUNC!:%!LINE! --->%!SPACE!"); 49 | // FUNC TraceEnter{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,MSG,...); 50 | // 51 | // USEPREFIX(TraceExitSuccess,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE! "); 52 | // FUNC TraceExitSuccess{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,...); 53 | // USESUFFIX (TraceExitSuccess, "STATUS_SUCCESS"); 54 | // 55 | // USEPREFIX(TraceExitStatus,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE!"); 56 | // FUNC TraceExitStatus{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS); 57 | // USESUFFIX (TraceExitStatus, "%!STATUS!", Status); 58 | // 59 | // DEFINE_CPLX_TYPE(HEXDUMP, WPP_LOGHEXDUMP, WPP_HEXDUMP, ItemHEXDump, "s", _HEX_, 0, 2); 60 | // 61 | // end_wpp 62 | // 63 | 64 | #define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) \ 65 | (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL)) 66 | #define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS) 67 | 68 | // 69 | // Opt-in to a WPP recorder feature that enables independent evaluation of 70 | // conditions to decide if a message needs to be sent to the recorder, an 71 | // enabled session, or both. 72 | // 73 | #define ENABLE_WPP_TRACE_FILTERING_WITH_WPP_RECORDER 1 74 | 75 | // 76 | // Logger and Enabled macros that support custom recorders. They simply delegate 77 | // to the default. 78 | // 79 | #define WPP_IFRLOG_LEVEL_FLAGS_ENABLED(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) 80 | #define WPP_IFRLOG_LEVEL_FLAGS_LOGGER(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) 81 | 82 | #define WPP_LOGHEXDUMP(x) \ 83 | WPP_LOGPAIR(sizeof(UINT16), &(x).Length) \ 84 | WPP_LOGPAIR((x).Length, (x).Buffer) 85 | 86 | typedef struct _WPP_HEXDUMP { 87 | const VOID *Buffer; 88 | UINT16 Length; 89 | } WPP_HEXDUMP; 90 | 91 | FORCEINLINE 92 | WPP_HEXDUMP 93 | WppHexDump( 94 | _In_ const VOID *Buffer, 95 | _In_ SIZE_T Length 96 | ) 97 | { 98 | WPP_HEXDUMP WppHexDump; 99 | 100 | WppHexDump.Buffer = Buffer; 101 | 102 | if (Buffer == NULL) { 103 | WppHexDump.Length = 0; 104 | } else { 105 | WppHexDump.Length = (UINT16)min(Length, MAXUINT16); 106 | } 107 | 108 | return WppHexDump; 109 | } 110 | 111 | VOID 112 | TraceNbls( 113 | _In_ NET_BUFFER_LIST *NblChain 114 | ); 115 | -------------------------------------------------------------------------------- /src/lwf/sys/tx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | FILTER_SEND_NET_BUFFER_LISTS FilterSendNetBufferLists; 7 | FILTER_SEND_NET_BUFFER_LISTS_COMPLETE FilterSendNetBufferListsComplete; 8 | 9 | typedef struct _DEFAULT_TX DEFAULT_TX; 10 | 11 | VOID 12 | TxCleanup( 13 | _In_ DEFAULT_TX *Tx 14 | ); 15 | 16 | DEFAULT_TX * 17 | TxCreate( 18 | _In_ DEFAULT_CONTEXT *Default 19 | ); 20 | 21 | _IRQL_requires_max_(PASSIVE_LEVEL) 22 | NTSTATUS 23 | TxIrpEnqueue( 24 | _In_ DEFAULT_TX *Tx, 25 | _In_ IRP *Irp, 26 | _In_ IO_STACK_LOCATION *IrpSp 27 | ); 28 | 29 | _IRQL_requires_max_(PASSIVE_LEVEL) 30 | NTSTATUS 31 | TxIrpFlush( 32 | _In_ DEFAULT_TX *Tx, 33 | _In_ IRP *Irp, 34 | _In_ IO_STACK_LOCATION *IrpSp 35 | ); 36 | -------------------------------------------------------------------------------- /src/mp/sys/dispatch.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | typedef 9 | _IRQL_requires_max_(PASSIVE_LEVEL) 10 | NTSTATUS 11 | FILE_CREATE_ROUTINE( 12 | _In_ IRP *Irp, 13 | _In_ IO_STACK_LOCATION *IrpSp, 14 | _In_ UCHAR Disposition, 15 | _In_ VOID *InputBuffer, 16 | _In_ SIZE_T InputBufferLength 17 | ); 18 | 19 | typedef 20 | _IRQL_requires_max_(PASSIVE_LEVEL) 21 | NTSTATUS 22 | FILE_IRP_ROUTINE( 23 | _In_ IRP *Irp, 24 | _In_ IO_STACK_LOCATION *IrpSp 25 | ); 26 | 27 | typedef struct FILE_DISPATCH { 28 | FILE_IRP_ROUTINE *IoControl; 29 | FILE_IRP_ROUTINE *Cleanup; 30 | FILE_IRP_ROUTINE *Close; 31 | } FILE_DISPATCH; 32 | 33 | typedef struct FILE_OBJECT_HEADER { 34 | FNMP_FILE_TYPE ObjectType; 35 | CONST FILE_DISPATCH *Dispatch; 36 | UINT32 ApiVersion; 37 | } FILE_OBJECT_HEADER; 38 | 39 | NDIS_STATUS 40 | MpIoctlReference( 41 | VOID 42 | ); 43 | 44 | VOID 45 | MpIoctlDereference( 46 | VOID 47 | ); 48 | 49 | NDIS_STATUS 50 | MpIoctlStart( 51 | VOID 52 | ); 53 | 54 | VOID 55 | MpIoctlCleanup( 56 | VOID 57 | ); 58 | -------------------------------------------------------------------------------- /src/mp/sys/exclusive.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include "precomp.h" 7 | 8 | _IRQL_requires_max_(PASSIVE_LEVEL) 9 | VOID 10 | ExclusiveWatchdogTimeout( 11 | _In_ ADAPTER_CONTEXT *Adapter 12 | ) 13 | { 14 | if (MpOidWatchdogIsExpired(Adapter)) { 15 | MpWatchdogFailure(Adapter, "OID"); 16 | MpOidClearFilterAndFlush(Adapter); 17 | } 18 | } 19 | 20 | static 21 | _IRQL_requires_max_(PASSIVE_LEVEL) 22 | NTSTATUS 23 | ExclusiveIrpDeviceIoControl( 24 | _In_ IRP *Irp, 25 | _In_ IO_STACK_LOCATION *IrpSp 26 | ) 27 | { 28 | EXCLUSIVE_USER_CONTEXT *UserContext = IrpSp->FileObject->FsContext; 29 | NTSTATUS Status; 30 | 31 | UNREFERENCED_PARAMETER(Irp); 32 | 33 | switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { 34 | case FNMP_IOCTL_OID_FILTER: 35 | Status = MpIrpOidSetFilter(UserContext, Irp, IrpSp); 36 | break; 37 | 38 | case FNMP_IOCTL_OID_GET_REQUEST: 39 | Status = MpIrpOidGetRequest(UserContext, Irp, IrpSp); 40 | break; 41 | 42 | case FNMP_IOCTL_OID_COMPLETE_REQUEST: 43 | Status = MpIrpOidCompleteRequest(UserContext, Irp, IrpSp); 44 | break; 45 | 46 | case FNMP_IOCTL_MINIPORT_ALLOCATE_PORT: 47 | Status = MpIrpAllocatePort(UserContext, Irp, IrpSp); 48 | break; 49 | 50 | case FNMP_IOCTL_MINIPORT_FREE_PORT: 51 | Status = MpIrpFreePort(UserContext, Irp, IrpSp); 52 | break; 53 | 54 | case FNMP_IOCTL_MINIPORT_ACTIVATE_PORT: 55 | Status = MpIrpActivatePort(UserContext, Irp, IrpSp); 56 | break; 57 | 58 | case FNMP_IOCTL_MINIPORT_DEACTIVATE_PORT: 59 | Status = MpIrpDeactivatePort(UserContext, Irp, IrpSp); 60 | break; 61 | 62 | default: 63 | Status = STATUS_NOT_SUPPORTED; 64 | goto Exit; 65 | } 66 | 67 | Exit: 68 | 69 | return Status; 70 | } 71 | 72 | static 73 | VOID 74 | ExclusiveCleanup( 75 | _In_ EXCLUSIVE_USER_CONTEXT *UserContext 76 | ) 77 | { 78 | KIRQL OldIrql; 79 | 80 | if (UserContext->Adapter != NULL) { 81 | MpPortCleanup(UserContext->Adapter); 82 | 83 | if (UserContext->SetOidFilter) { 84 | MpOidClearFilterAndFlush(UserContext->Adapter); 85 | } 86 | 87 | KeAcquireSpinLock(&UserContext->Adapter->Lock, &OldIrql); 88 | if (UserContext->Adapter->UserContext == UserContext) { 89 | UserContext->Adapter->UserContext = NULL; 90 | } 91 | KeReleaseSpinLock(&UserContext->Adapter->Lock, OldIrql); 92 | 93 | MpDereferenceAdapter(UserContext->Adapter); 94 | } 95 | 96 | ExFreePoolWithTag(UserContext, POOLTAG_MP_EXCLUSIVE); 97 | } 98 | 99 | static 100 | _IRQL_requires_max_(PASSIVE_LEVEL) 101 | NTSTATUS 102 | ExclusiveIrpClose( 103 | _In_ IRP *Irp, 104 | _In_ IO_STACK_LOCATION *IrpSp 105 | ) 106 | { 107 | EXCLUSIVE_USER_CONTEXT *UserContext = (EXCLUSIVE_USER_CONTEXT *)IrpSp->FileObject->FsContext; 108 | 109 | UNREFERENCED_PARAMETER(Irp); 110 | 111 | ASSERT(UserContext == UserContext->Adapter->UserContext); 112 | 113 | ExclusiveCleanup(UserContext); 114 | 115 | return STATUS_SUCCESS; 116 | } 117 | 118 | static CONST FILE_DISPATCH ExclusiveFileDispatch = { 119 | .IoControl = ExclusiveIrpDeviceIoControl, 120 | .Close = ExclusiveIrpClose, 121 | }; 122 | 123 | NTSTATUS 124 | ExclusiveIrpCreate( 125 | _In_ IRP *Irp, 126 | _In_ IO_STACK_LOCATION *IrpSp, 127 | _In_ UCHAR Disposition, 128 | _In_ VOID *InputBuffer, 129 | _In_ SIZE_T InputBufferLength 130 | ) 131 | { 132 | NTSTATUS Status; 133 | EXCLUSIVE_USER_CONTEXT *UserContext = NULL; 134 | FNMP_OPEN_EXCLUSIVE *OpenExclusive; 135 | UINT32 IfIndex; 136 | KIRQL OldIrql; 137 | 138 | UNREFERENCED_PARAMETER(Irp); 139 | UNREFERENCED_PARAMETER(Disposition); 140 | 141 | if (InputBufferLength < sizeof(*OpenExclusive)) { 142 | Status = STATUS_BUFFER_TOO_SMALL; 143 | goto Exit; 144 | } 145 | OpenExclusive = InputBuffer; 146 | IfIndex = OpenExclusive->IfIndex; 147 | 148 | UserContext = ExAllocatePoolZero(NonPagedPoolNx, sizeof(*UserContext), POOLTAG_MP_EXCLUSIVE); 149 | if (UserContext == NULL) { 150 | Status = STATUS_INSUFFICIENT_RESOURCES; 151 | goto Exit; 152 | } 153 | 154 | UserContext->Header.ObjectType = FNMP_FILE_TYPE_EXCLUSIVE; 155 | UserContext->Header.Dispatch = &ExclusiveFileDispatch; 156 | 157 | UserContext->Adapter = MpFindAdapter(IfIndex); 158 | if (UserContext->Adapter == NULL) { 159 | Status = STATUS_NOT_FOUND; 160 | goto Exit; 161 | } 162 | 163 | KeAcquireSpinLock(&UserContext->Adapter->Lock, &OldIrql); 164 | 165 | if (UserContext->Adapter->UserContext != NULL) { 166 | Status = STATUS_DUPLICATE_OBJECTID; 167 | KeReleaseSpinLock(&UserContext->Adapter->Lock, OldIrql); 168 | goto Exit; 169 | } 170 | 171 | UserContext->Adapter->UserContext = UserContext; 172 | 173 | KeReleaseSpinLock(&UserContext->Adapter->Lock, OldIrql); 174 | 175 | IrpSp->FileObject->FsContext = UserContext; 176 | Status = STATUS_SUCCESS; 177 | 178 | Exit: 179 | 180 | if (!NT_SUCCESS(Status)) { 181 | if (UserContext != NULL) { 182 | ExclusiveCleanup(UserContext); 183 | } 184 | } 185 | 186 | return Status; 187 | } 188 | -------------------------------------------------------------------------------- /src/mp/sys/exclusive.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | typedef struct _EXCLUSIVE_USER_CONTEXT { 9 | FILE_OBJECT_HEADER Header; 10 | ADAPTER_CONTEXT *Adapter; 11 | BOOLEAN SetOidFilter; 12 | } EXCLUSIVE_USER_CONTEXT; 13 | 14 | NTSTATUS 15 | ExclusiveIrpCreate( 16 | _In_ IRP *Irp, 17 | _In_ IO_STACK_LOCATION *IrpSp, 18 | _In_ UCHAR Disposition, 19 | _In_ VOID *InputBuffer, 20 | _In_ SIZE_T InputBufferLength 21 | ); 22 | 23 | _IRQL_requires_max_(PASSIVE_LEVEL) 24 | VOID 25 | ExclusiveWatchdogTimeout( 26 | _In_ ADAPTER_CONTEXT *Adapter 27 | ); 28 | -------------------------------------------------------------------------------- /src/mp/sys/fnmp.rc: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include 7 | 8 | #define VER_FILETYPE VFT_DRV 9 | #define VER_FILESUBTYPE VFT2_DRV_NETWORK 10 | #define VER_FILEDESCRIPTION_STR "Functional Test Miniport Driver" 11 | #define VER_INTERNALNAME_STR "fnmp.sys" 12 | 13 | #include "undocked.ver" 14 | -------------------------------------------------------------------------------- /src/mp/sys/fnmp.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {ad2ed8d3-06f7-4b3b-89f4-e8e7065a6f82} 5 | fnmp 6 | sys 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | {4a8c9c36-9b11-4bcf-9c48-0f33d4470d66} 15 | 16 | 17 | {d07edeb2-006f-4b32-8cd1-2b8fabd5879e} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | true 36 | 37 | 38 | 39 | 40 | 41 | $(SolutionDir)inc; 42 | $(SolutionDir)src\common\inc; 43 | $(SolutionDir)src\mp\inc; 44 | %(AdditionalIncludeDirectories) 45 | 46 | 47 | NDIS_MINIPORT_DRIVER; 48 | NDIS685_MINIPORT=1; 49 | %(PreprocessorDefinitions) 50 | 51 | true 52 | $(ProjectDir)trace.h 53 | true 54 | -p:fnmp 55 | 56 | 57 | 58 | ndis.lib; 59 | netio.lib; 60 | %(AdditionalDependencies) 61 | 62 | 63 | volatileaccessk.lib; 64 | %(AdditionalDependencies) 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/mp/sys/miniport.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #define ETH_HDR_LEN 14 9 | #define MAC_ADDR_LEN 6 10 | #define MAX_MULTICAST_ADDRESSES 16 11 | 12 | #define MAX_RSS_QUEUES 64 13 | 14 | #define TRY_READ_INT_CONFIGURATION(hConfig, Keyword, pValue) \ 15 | { \ 16 | NDIS_STATUS _Status; \ 17 | PNDIS_CONFIGURATION_PARAMETER Parameter; \ 18 | NdisReadConfiguration(&_Status, &Parameter, (hConfig), RTL_CONST_CAST(PNDIS_STRING)(Keyword), NdisParameterInteger); \ 19 | if (_Status == NDIS_STATUS_SUCCESS) \ 20 | { \ 21 | *(pValue) = Parameter->ParameterData.IntegerData; \ 22 | } \ 23 | } 24 | 25 | typedef struct _ADAPTER_SHARED ADAPTER_SHARED; 26 | typedef struct _EXCLUSIVE_USER_CONTEXT EXCLUSIVE_USER_CONTEXT; 27 | 28 | typedef struct DECLSPEC_CACHEALIGN { 29 | UINT32 QueueId; 30 | UINT32 RssHash; 31 | UINT32 ProcessorIndex; 32 | } ADAPTER_QUEUE; 33 | 34 | typedef enum _CHECKSUM_OFFLOAD_STATE { 35 | ChecksumOffloadDisabled = 0, 36 | ChecksumOffloadTx = 1, 37 | ChecksumOffloadRx = 2, 38 | ChecksumOffloadRxTx = 3, 39 | } CHECKSUM_OFFLOAD_STATE; 40 | 41 | C_ASSERT((ChecksumOffloadTx & ChecksumOffloadRx) == 0); 42 | C_ASSERT((ChecksumOffloadTx | ChecksumOffloadRx) == ChecksumOffloadRxTx); 43 | 44 | typedef struct _ADAPTER_OFFLOAD { 45 | CHECKSUM_OFFLOAD_STATE IPChecksumOffloadIPv4; 46 | CHECKSUM_OFFLOAD_STATE TCPChecksumOffloadIPv4; 47 | CHECKSUM_OFFLOAD_STATE TCPChecksumOffloadIPv6; 48 | CHECKSUM_OFFLOAD_STATE UDPChecksumOffloadIPv4; 49 | CHECKSUM_OFFLOAD_STATE UDPChecksumOffloadIPv6; 50 | UINT32 LsoV2IPv4; 51 | UINT32 LsoV2IPv6; 52 | UINT32 UsoIPv4; 53 | UINT32 UsoIPv6; 54 | UINT32 RscIPv4; 55 | UINT32 RscIPv6; 56 | UINT32 UdpRsc; 57 | UINT32 GsoMaxOffloadSize; 58 | } ADAPTER_OFFLOAD; 59 | 60 | typedef struct _ADAPTER_CONTEXT { 61 | LIST_ENTRY AdapterListLink; 62 | NDIS_HANDLE MiniportHandle; 63 | NET_IFINDEX IfIndex; 64 | 65 | INT64 ReferenceCount; 66 | 67 | UCHAR MACAddress[MAC_ADDR_LEN]; 68 | ULONG MtuSize; 69 | ULONG CurrentPacketFilter; 70 | ULONG CurrentLookAhead; 71 | UCHAR MulticastAddressList[MAC_ADDR_LEN * MAX_MULTICAST_ADDRESSES]; 72 | ULONG NumMulticastAddresses; 73 | LARGE_INTEGER LastPauseTimestamp; 74 | 75 | ADAPTER_QUEUE *RssQueues; 76 | ULONG RssEnabled; 77 | ULONG NumRssProcs; 78 | ULONG NumRssQueues; 79 | 80 | UINT32 Encapsulation; 81 | ADAPTER_OFFLOAD OffloadConfig; 82 | ADAPTER_OFFLOAD OffloadCapabilities; 83 | 84 | KSPIN_LOCK Lock; 85 | EX_PUSH_LOCK PushLock; 86 | const OID_KEY *OidFilterKeys; 87 | UINT32 OidFilterKeyCount; 88 | LIST_ENTRY FilteredOidRequestLists[OID_REQUEST_INTERFACE_MAX]; 89 | LIST_ENTRY PortList; 90 | FN_TIMER_HANDLE WatchdogTimer; 91 | 92 | // 93 | // Context for an exclusive user mode handle for configuring the adapter. 94 | // 95 | EXCLUSIVE_USER_CONTEXT *UserContext; 96 | 97 | ADAPTER_SHARED *Shared; 98 | } ADAPTER_CONTEXT; 99 | 100 | typedef struct _GLOBAL_CONTEXT { 101 | EX_PUSH_LOCK Lock; 102 | LIST_ENTRY AdapterList; 103 | HANDLE NdisMiniportDriverHandle; 104 | UINT32 NdisVersion; 105 | 106 | NDIS_MEDIUM Medium; 107 | ULONG PacketFilter; 108 | ULONG LinkSpeed; 109 | ULONG64 MaxXmitLinkSpeed; 110 | ULONG64 XmitLinkSpeed; 111 | ULONG64 MaxRecvLinkSpeed; 112 | ULONG64 RecvLinkSpeed; 113 | } GLOBAL_CONTEXT; 114 | 115 | extern GLOBAL_CONTEXT MpGlobalContext; 116 | 117 | VOID 118 | MpDereferenceAdapter( 119 | _In_ ADAPTER_CONTEXT *Adapter 120 | ); 121 | 122 | ADAPTER_CONTEXT * 123 | MpFindAdapter( 124 | _In_ UINT32 IfIndex 125 | ); 126 | 127 | VOID 128 | MpIndicateStatus( 129 | _In_ CONST ADAPTER_CONTEXT *Adapter, 130 | _In_ VOID *Buffer, 131 | _In_ UINT32 BufferSize, 132 | _In_ UINT32 StatusCode 133 | ); 134 | 135 | NDIS_STATUS 136 | MpSetOffloadParameters( 137 | _Inout_ ADAPTER_CONTEXT *Adapter, 138 | _Inout_ ADAPTER_OFFLOAD *AdapterOffload, 139 | _In_ CONST NDIS_OFFLOAD_PARAMETERS *OffloadParameters, 140 | _In_ UINT32 OffloadParametersLength, 141 | _In_ UINT32 StatusCode 142 | ); 143 | 144 | NDIS_STATUS 145 | MpReadOffload( 146 | _Inout_ ADAPTER_CONTEXT *Adapter, 147 | _In_ NDIS_HANDLE ConfigHandle, 148 | _In_ FN_OFFLOAD_TYPE Store 149 | ); 150 | 151 | NDIS_STATUS 152 | MpOpenConfiguration( 153 | _Out_ NDIS_HANDLE *ConfigHandle, 154 | _In_ ADAPTER_CONTEXT *Adapter 155 | ); 156 | 157 | ADAPTER_OFFLOAD * 158 | MpGetOffload( 159 | _In_ ADAPTER_CONTEXT *Adapter, 160 | _In_ FN_OFFLOAD_TYPE Store 161 | ); 162 | 163 | VOID 164 | MpFillOffload( 165 | _Out_ NDIS_OFFLOAD *Offload, 166 | _In_ ADAPTER_CONTEXT *Adapter, 167 | _In_ ADAPTER_OFFLOAD *AdapterOffload 168 | ); 169 | 170 | _IRQL_requires_max_(DISPATCH_LEVEL) 171 | VOID 172 | MpWatchdogFailure( 173 | _In_ ADAPTER_CONTEXT *Adapter, 174 | _In_z_ CONST CHAR *WatchdogType 175 | ); 176 | -------------------------------------------------------------------------------- /src/mp/sys/oid.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | extern CONST NDIS_OID MpSupportedOidArray[]; 9 | extern CONST UINT32 MpSupportedOidArraySize; 10 | 11 | MINIPORT_CANCEL_OID_REQUEST MiniportCancelRequestHandler; 12 | MINIPORT_OID_REQUEST MiniportRequestHandler; 13 | MINIPORT_DIRECT_OID_REQUEST MiniportDirectRequestHandler; 14 | MINIPORT_CANCEL_DIRECT_OID_REQUEST MiniportCancelDirectRequestHandler; 15 | 16 | _IRQL_requires_max_(PASSIVE_LEVEL) 17 | NTSTATUS 18 | MpIrpOidSetFilter( 19 | _In_ EXCLUSIVE_USER_CONTEXT *UserContext, 20 | _In_ IRP *Irp, 21 | _In_ IO_STACK_LOCATION *IrpSp 22 | ); 23 | 24 | _IRQL_requires_max_(PASSIVE_LEVEL) 25 | NTSTATUS 26 | MpIrpOidGetRequest( 27 | _In_ EXCLUSIVE_USER_CONTEXT *UserContext, 28 | _In_ IRP *Irp, 29 | _In_ IO_STACK_LOCATION *IrpSp 30 | ); 31 | 32 | _IRQL_requires_max_(PASSIVE_LEVEL) 33 | NTSTATUS 34 | MpIrpOidCompleteRequest( 35 | _In_ EXCLUSIVE_USER_CONTEXT *UserContext, 36 | _In_ IRP *Irp, 37 | _In_ IO_STACK_LOCATION *IrpSp 38 | ); 39 | 40 | _IRQL_requires_max_(PASSIVE_LEVEL) 41 | VOID 42 | MpOidClearFilterAndFlush( 43 | _In_ ADAPTER_CONTEXT *Adapter 44 | ); 45 | 46 | _IRQL_requires_max_(DISPATCH_LEVEL) 47 | BOOLEAN 48 | MpOidWatchdogIsExpired( 49 | _In_ ADAPTER_CONTEXT *Adapter 50 | ); 51 | -------------------------------------------------------------------------------- /src/mp/sys/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/mp/sys/port.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | _IRQL_requires_max_(PASSIVE_LEVEL) 9 | VOID 10 | MpPortCleanup( 11 | _In_ ADAPTER_CONTEXT *Adapter 12 | ); 13 | 14 | _IRQL_requires_max_(PASSIVE_LEVEL) 15 | NTSTATUS 16 | MpIrpAllocatePort( 17 | _In_ EXCLUSIVE_USER_CONTEXT *UserContext, 18 | _In_ IRP *Irp, 19 | _In_ IO_STACK_LOCATION *IrpSp 20 | ); 21 | 22 | _IRQL_requires_max_(PASSIVE_LEVEL) 23 | NTSTATUS 24 | MpIrpFreePort( 25 | _In_ EXCLUSIVE_USER_CONTEXT *UserContext, 26 | _In_ IRP *Irp, 27 | _In_ IO_STACK_LOCATION *IrpSp 28 | ); 29 | 30 | _IRQL_requires_max_(PASSIVE_LEVEL) 31 | NTSTATUS 32 | MpIrpActivatePort( 33 | _In_ EXCLUSIVE_USER_CONTEXT *UserContext, 34 | _In_ IRP *Irp, 35 | _In_ IO_STACK_LOCATION *IrpSp 36 | ); 37 | 38 | _IRQL_requires_max_(PASSIVE_LEVEL) 39 | NTSTATUS 40 | MpIrpDeactivatePort( 41 | _In_ EXCLUSIVE_USER_CONTEXT *UserContext, 42 | _In_ IRP *Irp, 43 | _In_ IO_STACK_LOCATION *IrpSp 44 | ); 45 | -------------------------------------------------------------------------------- /src/mp/sys/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "dispatch.h" 24 | #include "miniport.h" 25 | 26 | #include "bounce.h" 27 | #include "exclusive.h" 28 | #include "pooltag.h" 29 | #include "oid.h" 30 | #include "port.h" 31 | #include "rss.h" 32 | #include "rx.h" 33 | #include "shared.h" 34 | #include "trace.h" 35 | #include "tx.h" 36 | 37 | #define MP_APIVER(_N) (_N) 38 | -------------------------------------------------------------------------------- /src/mp/sys/rss.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include "precomp.h" 7 | 8 | VOID 9 | MpCleanupRssQueues( 10 | _Inout_ ADAPTER_CONTEXT *Adapter 11 | ) 12 | { 13 | if (Adapter->RssQueues == NULL) { 14 | return; 15 | } 16 | 17 | ExFreePoolWithTag(Adapter->RssQueues, POOLTAG_MP_RSS); 18 | Adapter->RssQueues = NULL; 19 | } 20 | 21 | NDIS_STATUS 22 | MpCreateRssQueues( 23 | _Inout_ ADAPTER_CONTEXT *Adapter 24 | ) 25 | { 26 | NDIS_STATUS Status; 27 | NDIS_RSS_PROCESSOR_INFO *RssProcessorInfo = NULL; 28 | SIZE_T AllocationSize; 29 | SIZE_T Size = 0; 30 | 31 | Status = NdisGetRssProcessorInformation(Adapter->MiniportHandle, RssProcessorInfo, &Size); 32 | NT_FRE_ASSERT(Status == NDIS_STATUS_BUFFER_TOO_SHORT); 33 | RssProcessorInfo = ExAllocatePoolZero(NonPagedPoolNx, Size, POOLTAG_MP_RSS); 34 | if (RssProcessorInfo == NULL) { 35 | Status = NDIS_STATUS_RESOURCES; 36 | goto Exit; 37 | } 38 | 39 | Status = NdisGetRssProcessorInformation(Adapter->MiniportHandle, RssProcessorInfo, &Size); 40 | if (Status != NDIS_STATUS_SUCCESS) { 41 | goto Exit; 42 | } 43 | 44 | Adapter->NumRssProcs = RssProcessorInfo->RssProcessorCount; 45 | AllocationSize = sizeof(*Adapter->RssQueues) * Adapter->NumRssQueues; 46 | 47 | Adapter->RssQueues = ExAllocatePoolZero(NonPagedPoolNx, AllocationSize, POOLTAG_MP_RSS); 48 | if (Adapter->RssQueues == NULL) { 49 | Status = NDIS_STATUS_RESOURCES; 50 | goto Exit; 51 | } 52 | 53 | for (ULONG Index = 0; Index < Adapter->NumRssQueues; Index++) { 54 | ADAPTER_QUEUE *RssQueue = &Adapter->RssQueues[Index]; 55 | 56 | RssQueue->QueueId = Index; 57 | } 58 | 59 | Status = NDIS_STATUS_SUCCESS; 60 | 61 | Exit: 62 | 63 | if (RssProcessorInfo != NULL) { 64 | ExFreePool(RssProcessorInfo); 65 | } 66 | 67 | return Status; 68 | } 69 | 70 | VOID 71 | MpSetRss( 72 | _In_ ADAPTER_CONTEXT *Adapter, 73 | _In_ NDIS_RECEIVE_SCALE_PARAMETERS *RssParams, 74 | _In_ SIZE_T RssParamsLength 75 | ) 76 | { 77 | UINT32 EntryCount; 78 | PROCESSOR_NUMBER *RssTable; 79 | UINT32 AssignedProcessors[MAX_RSS_QUEUES]; 80 | UINT32 RssHashValues[MAX_RSS_QUEUES]; 81 | UINT32 AssignedProcessorCount = 0; 82 | 83 | UNREFERENCED_PARAMETER(Adapter); 84 | 85 | if (RssParamsLength < NDIS_SIZEOF_RECEIVE_SCALE_PARAMETERS_REVISION_2 || 86 | RssParams->Header.Type != NDIS_OBJECT_TYPE_RSS_PARAMETERS || 87 | RssParams->Header.Revision < NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 || 88 | RssParams->Header.Size < NDIS_SIZEOF_RECEIVE_SCALE_PARAMETERS_REVISION_2) { 89 | // 90 | // For simplicity, require RSS revision 2 which uses PROCESSOR_NUMBER 91 | // entries in the indirection table. 92 | // 93 | return; 94 | } 95 | 96 | if (NDIS_RSS_HASH_FUNC_FROM_HASH_INFO(RssParams->HashInformation) == 0 || 97 | (RssParams->Flags & NDIS_RSS_PARAM_FLAG_DISABLE_RSS)) { 98 | // 99 | // RSS is being disabled; ignore. 100 | // 101 | return; 102 | } 103 | 104 | EntryCount = RssParams->IndirectionTableSize / sizeof(PROCESSOR_NUMBER); 105 | RssTable = (PROCESSOR_NUMBER *) 106 | (((UCHAR *)RssParams) + RssParams->IndirectionTableOffset); 107 | 108 | for (ULONG Index = 0; Index < EntryCount; Index++) { 109 | ULONG TargetProcessor = KeGetProcessorIndexFromNumber(&RssTable[Index]); 110 | ULONG AssignedIndex; 111 | 112 | for (AssignedIndex = 0; AssignedIndex < AssignedProcessorCount; AssignedIndex++) { 113 | if (AssignedProcessors[AssignedIndex] == TargetProcessor) { 114 | break; 115 | } 116 | } 117 | 118 | if (AssignedIndex == AssignedProcessorCount) { 119 | if (AssignedProcessorCount == RTL_NUMBER_OF(AssignedProcessors)) { 120 | // 121 | // For simplicity, we support up to 64 queues. 122 | // 123 | return; 124 | } 125 | 126 | AssignedProcessors[AssignedProcessorCount] = TargetProcessor; 127 | RssHashValues[AssignedProcessorCount] = 0x80000000 | Index; 128 | AssignedProcessorCount++; 129 | } 130 | } 131 | 132 | for (ULONG Index = 0; Index < Adapter->NumRssQueues; Index++) { 133 | ADAPTER_QUEUE *RssQueue = &Adapter->RssQueues[Index]; 134 | UINT32 RssHash = 0; 135 | UINT32 ProcessorIndex = 0; 136 | 137 | if (Index < AssignedProcessorCount) { 138 | RssHash = RssHashValues[Index]; 139 | ProcessorIndex = AssignedProcessors[Index]; 140 | } 141 | 142 | RssQueue->RssHash = RssHash; 143 | RssQueue->ProcessorIndex = ProcessorIndex; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/mp/sys/rss.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | VOID 9 | MpCleanupRssQueues( 10 | _Inout_ ADAPTER_CONTEXT *Adapter 11 | ); 12 | 13 | NDIS_STATUS 14 | MpCreateRssQueues( 15 | _Inout_ ADAPTER_CONTEXT *Adapter 16 | ); 17 | 18 | VOID 19 | MpSetRss( 20 | _In_ ADAPTER_CONTEXT *Adapter, 21 | _In_ NDIS_RECEIVE_SCALE_PARAMETERS *RssParams, 22 | _In_ SIZE_T RssParamsLength 23 | ); 24 | -------------------------------------------------------------------------------- /src/mp/sys/rx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | typedef struct _SHARED_RX SHARED_RX; 9 | typedef struct _SHARED_CONTEXT SHARED_CONTEXT; 10 | 11 | VOID 12 | SharedRxCleanup( 13 | _In_ SHARED_RX *Rx 14 | ); 15 | 16 | SHARED_RX * 17 | SharedRxCreate( 18 | _In_ SHARED_CONTEXT *Shared 19 | ); 20 | 21 | _IRQL_requires_max_(PASSIVE_LEVEL) 22 | NTSTATUS 23 | SharedIrpRxEnqueue( 24 | _In_ SHARED_RX *Rx, 25 | _In_ IRP *Irp, 26 | _In_ IO_STACK_LOCATION *IrpSp 27 | ); 28 | 29 | _IRQL_requires_max_(PASSIVE_LEVEL) 30 | NTSTATUS 31 | SharedIrpRxFlush( 32 | _In_ SHARED_RX *Rx, 33 | _In_ IRP *Irp, 34 | _In_ IO_STACK_LOCATION *IrpSp 35 | ); 36 | 37 | extern CONST UINT16 SharedRxNblContextSize; 38 | -------------------------------------------------------------------------------- /src/mp/sys/shared.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | MINIPORT_RESTART MiniportRestartHandler; 9 | MINIPORT_PAUSE MiniportPauseHandler; 10 | MINIPORT_SEND_NET_BUFFER_LISTS MpSendNetBufferLists; 11 | MINIPORT_CANCEL_SEND MiniportCancelSendHandler; 12 | MINIPORT_RETURN_NET_BUFFER_LISTS MpReturnNetBufferLists; 13 | 14 | FILE_CREATE_ROUTINE SharedIrpCreate; 15 | 16 | typedef struct _SHARED_RX SHARED_RX; 17 | typedef struct _SHARED_TX SHARED_TX; 18 | 19 | typedef struct _ADAPTER_SHARED { 20 | ADAPTER_CONTEXT *Adapter; 21 | EX_RUNDOWN_REF NblRundown; 22 | NDIS_HANDLE NblPool; 23 | 24 | KSPIN_LOCK Lock; 25 | LIST_ENTRY TxFilterList; 26 | } ADAPTER_SHARED; 27 | 28 | typedef struct _SHARED_CONTEXT { 29 | FILE_OBJECT_HEADER Header; 30 | KSPIN_LOCK Lock; 31 | ADAPTER_CONTEXT *Adapter; 32 | SHARED_RX *Rx; 33 | SHARED_TX *Tx; 34 | } SHARED_CONTEXT; 35 | 36 | ADAPTER_SHARED * 37 | SharedAdapterCreate( 38 | _In_ ADAPTER_CONTEXT *Adapter 39 | ); 40 | 41 | VOID 42 | SharedAdapterCleanup( 43 | _In_ ADAPTER_SHARED *AdapterShared 44 | ); 45 | 46 | _IRQL_requires_max_(PASSIVE_LEVEL) 47 | VOID 48 | SharedWatchdogTimeout( 49 | _In_ ADAPTER_SHARED *AdapterShared 50 | ); 51 | -------------------------------------------------------------------------------- /src/mp/sys/trace.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include "precomp.h" 7 | #include "trace.tmh" 8 | 9 | VOID 10 | TraceNbls( 11 | _In_ NET_BUFFER_LIST *NblChain 12 | ) 13 | { 14 | while (NblChain != NULL) { 15 | TraceVerbose(TRACE_DATAPATH, "Nbl=%p", NblChain); 16 | NblChain = NblChain->Next; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/mp/sys/trace.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // {3207D515-BB97-4C97-9B49-5EB25829C43F} 13 | // 14 | #define WPP_CONTROL_GUIDS \ 15 | WPP_DEFINE_CONTROL_GUID( \ 16 | FnMpTraceGuid, \ 17 | (3207D515,BB97,4C97,9B49,5EB25829C43F), \ 18 | WPP_DEFINE_BIT(TRACE_CONTROL) \ 19 | WPP_DEFINE_BIT(TRACE_DATAPATH) \ 20 | ) 21 | 22 | // 23 | // The following system defined definitions may be used: 24 | // 25 | // TRACE_LEVEL_FATAL = 1 // Abnormal exit or termination. 26 | // TRACE_LEVEL_ERROR = 2 // Severe errors that need logging. 27 | // TRACE_LEVEL_WARNING = 3 // Warnings such as allocation failures. 28 | // TRACE_LEVEL_INFORMATION = 4 // Including non-error cases. 29 | // TRACE_LEVEL_VERBOSE = 5 // Detailed traces from intermediate steps. 30 | // 31 | // begin_wpp config 32 | // 33 | // USEPREFIX(TraceFatal,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 34 | // FUNC TraceFatal{LEVEL=TRACE_LEVEL_FATAL}(FLAGS,MSG,...); 35 | // 36 | // USEPREFIX(TraceError,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 37 | // FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR}(FLAGS,MSG,...); 38 | // 39 | // USEPREFIX(TraceWarn,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 40 | // FUNC TraceWarn{LEVEL=TRACE_LEVEL_WARNING}(FLAGS,MSG,...); 41 | // 42 | // USEPREFIX(TraceInfo,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 43 | // FUNC TraceInfo{LEVEL=TRACE_LEVEL_INFORMATION}(FLAGS,MSG,...); 44 | // 45 | // USEPREFIX(TraceVerbose,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 46 | // FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,MSG,...); 47 | // 48 | // USEPREFIX(TraceEnter,"%!STDPREFIX! %!FUNC!:%!LINE! --->%!SPACE!"); 49 | // FUNC TraceEnter{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,MSG,...); 50 | // 51 | // USEPREFIX(TraceExitSuccess,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE! "); 52 | // FUNC TraceExitSuccess{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS,...); 53 | // USESUFFIX (TraceExitSuccess, "STATUS_SUCCESS"); 54 | // 55 | // USEPREFIX(TraceExitStatus,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE!"); 56 | // FUNC TraceExitStatus{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS); 57 | // USESUFFIX (TraceExitStatus, "%!STATUS!", Status); 58 | // 59 | // DEFINE_CPLX_TYPE(HEXDUMP, WPP_LOGHEXDUMP, WPP_HEXDUMP, ItemHEXDump, "s", _HEX_, 0, 2); 60 | // 61 | // end_wpp 62 | // 63 | 64 | #define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) \ 65 | (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL)) 66 | #define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS) 67 | 68 | // 69 | // Opt-in to a WPP recorder feature that enables independent evaluation of 70 | // conditions to decide if a message needs to be sent to the recorder, an 71 | // enabled session, or both. 72 | // 73 | #define ENABLE_WPP_TRACE_FILTERING_WITH_WPP_RECORDER 1 74 | 75 | // 76 | // Logger and Enabled macros that support custom recorders. They simply delegate 77 | // to the default. 78 | // 79 | #define WPP_IFRLOG_LEVEL_FLAGS_ENABLED(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) 80 | #define WPP_IFRLOG_LEVEL_FLAGS_LOGGER(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) 81 | 82 | #define WPP_LOGHEXDUMP(x) \ 83 | WPP_LOGPAIR(sizeof(UINT16), &(x).Length) \ 84 | WPP_LOGPAIR((x).Length, (x).Buffer) 85 | 86 | typedef struct _WPP_HEXDUMP { 87 | CONST VOID *Buffer; 88 | UINT16 Length; 89 | } WPP_HEXDUMP; 90 | 91 | FORCEINLINE 92 | WPP_HEXDUMP 93 | WppHexDump( 94 | _In_ CONST VOID *Buffer, 95 | _In_ SIZE_T Length 96 | ) 97 | { 98 | WPP_HEXDUMP WppHexDump; 99 | 100 | WppHexDump.Buffer = Buffer; 101 | 102 | if (Buffer == NULL) { 103 | WppHexDump.Length = 0; 104 | } else { 105 | WppHexDump.Length = (UINT16)min(Length, MAXUINT16); 106 | } 107 | 108 | return WppHexDump; 109 | } 110 | 111 | VOID 112 | TraceNbls( 113 | _In_ NET_BUFFER_LIST *NblChain 114 | ); 115 | -------------------------------------------------------------------------------- /src/mp/sys/tx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | typedef struct _SHARED_TX SHARED_TX; 9 | 10 | VOID 11 | SharedTxCleanup( 12 | _In_ SHARED_TX *Tx 13 | ); 14 | 15 | SHARED_TX * 16 | SharedTxCreate( 17 | _In_ SHARED_CONTEXT *Shared 18 | ); 19 | 20 | _IRQL_requires_max_(PASSIVE_LEVEL) 21 | NTSTATUS 22 | SharedIrpTxFilter( 23 | _In_ SHARED_TX *Tx, 24 | _In_ IRP *Irp, 25 | _In_ IO_STACK_LOCATION *IrpSp 26 | ); 27 | 28 | _IRQL_requires_max_(PASSIVE_LEVEL) 29 | NTSTATUS 30 | SharedIrpTxGetFrame( 31 | _In_ SHARED_TX *Tx, 32 | _In_ IRP *Irp, 33 | _In_ IO_STACK_LOCATION *IrpSp 34 | ); 35 | 36 | _IRQL_requires_max_(PASSIVE_LEVEL) 37 | NTSTATUS 38 | SharedIrpTxDequeueFrame( 39 | _In_ SHARED_TX *Tx, 40 | _In_ IRP *Irp, 41 | _In_ IO_STACK_LOCATION *IrpSp 42 | ); 43 | 44 | _IRQL_requires_max_(PASSIVE_LEVEL) 45 | NTSTATUS 46 | SharedIrpTxFlush( 47 | _In_ SHARED_TX *Tx, 48 | _In_ IRP *Irp, 49 | _In_ IO_STACK_LOCATION *IrpSp 50 | ); 51 | 52 | _IRQL_requires_max_(PASSIVE_LEVEL) 53 | VOID 54 | SharedTxWatchdogTimeout( 55 | _In_ ADAPTER_SHARED *AdapterShared 56 | ); 57 | -------------------------------------------------------------------------------- /src/sock/km/fnsock_km.def: -------------------------------------------------------------------------------- 1 | LIBRARY fnsock_km.sys 2 | 3 | EXPORTS 4 | DllInitialize PRIVATE 5 | DllUnload PRIVATE 6 | -------------------------------------------------------------------------------- /src/sock/km/fnsock_km.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {ac661767-42c3-4525-8b90-d509a6048dc3} 5 | fnsock_km 6 | sys 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | {50f8f5ee-aa31-427f-9959-13de0d68bd06} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | $(SolutionDir)inc; 24 | $(SolutionDir)src\common\inc; 25 | $(SolutionDir)src\sock; 26 | %(AdditionalIncludeDirectories) 27 | 28 | true 29 | $(SolutionDir)src\sock\trace.h 30 | true 31 | -p:fnsock 32 | 33 | 34 | fnsock_km.def 35 | 36 | netio.lib; 37 | uuid.lib; 38 | %(AdditionalDependencies) 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/sock/trace.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // {9A90334B-68EE-43E5-8FFA-AEF115CE44A1} 13 | // 14 | #define WPP_CONTROL_GUIDS \ 15 | WPP_DEFINE_CONTROL_GUID( \ 16 | FnSockTraceGuid, \ 17 | (9A90334B,68EE,43E5,8FFA,AEF115CE44A1), \ 18 | WPP_DEFINE_BIT(TRACE_FNSOCK) \ 19 | ) 20 | 21 | // 22 | // The following system defined definitions may be used: 23 | // 24 | // TRACE_LEVEL_FATAL = 1 // Abnormal exit or termination. 25 | // TRACE_LEVEL_ERROR = 2 // Severe errors that need logging. 26 | // TRACE_LEVEL_WARNING = 3 // Warnings such as allocation failures. 27 | // TRACE_LEVEL_INFORMATION = 4 // Including non-error cases. 28 | // TRACE_LEVEL_VERBOSE = 5 // Detailed traces from intermediate steps. 29 | // 30 | // begin_wpp config 31 | // 32 | // USEPREFIX(TraceFatal,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 33 | // FUNC TraceFatal{LEVEL=TRACE_LEVEL_FATAL,FLAGS=TRACE_FNSOCK}(MSG,...); 34 | // 35 | // USEPREFIX(TraceError,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 36 | // FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR,FLAGS=TRACE_FNSOCK}(MSG,...); 37 | // 38 | // USEPREFIX(TraceWarn,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 39 | // FUNC TraceWarn{LEVEL=TRACE_LEVEL_WARNING,FLAGS=TRACE_FNSOCK}(MSG,...); 40 | // 41 | // USEPREFIX(TraceInfo,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 42 | // FUNC TraceInfo{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=TRACE_FNSOCK}(MSG,...); 43 | // 44 | // USEPREFIX(TraceVerbose,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 45 | // FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FNSOCK}(MSG,...); 46 | // 47 | // USEPREFIX(TraceEnter,"%!STDPREFIX! %!FUNC!:%!LINE! --->%!SPACE!"); 48 | // FUNC TraceEnter{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FNSOCK}(MSG,...); 49 | // 50 | // USEPREFIX(TraceExit,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE! "); 51 | // FUNC TraceExit{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FNSOCK}(MSG,...); 52 | // 53 | // end_wpp 54 | // 55 | 56 | #define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) \ 57 | (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL)) 58 | #define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS) 59 | -------------------------------------------------------------------------------- /src/sock/um/fnsock_um.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {dca385fb-b4b1-44cc-ba3f-9da4f619d86a} 5 | fnsock_um 6 | dll 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | tracewpp.exe -odir:$(IntDir) -scan:$(SolutionDir)src\sock\trace.h $(ProjectDir)*.c -p:fnsock -cfgdir:"$(WindowsSdkDir)bin\$(TargetPlatformVersion)\WppConfig\Rev1" 19 | 20 | 21 | 22 | 23 | $(SolutionDir)inc; 24 | $(SolutionDir)src\sock; 25 | %(AdditionalIncludeDirectories) 26 | 27 | 28 | 29 | 30 | ws2_32.lib; 31 | %(AdditionalDependencies) 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/wnt.cpp.kernel.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | $(SolutionDir)submodules\ndis-driver-library\src\include; 9 | $(SolutionDir)submodules\net-offloads\include; 10 | %(AdditionalIncludeDirectories) 11 | 12 | 13 | POOL_NX_OPTIN_AUTO=1; 14 | POOL_ZERO_DOWN_LEVEL_SUPPORT=1; 15 | %(PreprocessorDefinitions) 16 | 17 | 18 | 19 | SHA256 20 | 21 | 22 | 23 | true 24 | /rulever 10.0.17763 $(InfVerif_AdditionalOptions) 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/wnt.cpp.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10.0.26100.2454 4 | 5 | 6 | 7 | true 8 | 9 | 10 | 26812;5252;%(DisableSpecificWarnings) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/wskclient/wskclient.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {50f8f5ee-aa31-427f-9959-13de0d68bd06} 5 | wskclient 6 | drvlib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(SolutionDir)inc; 19 | %(AdditionalIncludeDirectories) 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/cxplat/inc/cxplat.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | // 7 | // This API is comprised of copied snippets of the cross-platform pieces of 8 | // https://github.com/microsoft/msquic, along with a hand-rolled sockets API. 9 | // Eventually this API should be replaced with https://github.com/microsoft/cxplat. 10 | // 11 | 12 | #pragma once 13 | 14 | EXTERN_C_START 15 | 16 | #if defined(_KERNEL_MODE) 17 | 18 | #define CXPLAT_STATUS NTSTATUS 19 | #define CXPLAT_FAILED(X) !NT_SUCCESS(X) 20 | #define CXPLAT_SUCCEEDED(X) NT_SUCCESS(X) 21 | #define CXPLAT_STATUS_SUCCESS STATUS_SUCCESS 22 | #define CXPLAT_STATUS_FAIL STATUS_UNSUCCESSFUL 23 | #ifndef KRTL_INIT_SEGMENT 24 | #define KRTL_INIT_SEGMENT "INIT" 25 | #endif 26 | #ifndef KRTL_PAGE_SEGMENT 27 | #define KRTL_PAGE_SEGMENT "PAGE" 28 | #endif 29 | #ifndef KRTL_NONPAGED_SEGMENT 30 | #define KRTL_NONPAGED_SEGMENT ".text" 31 | #endif 32 | // Use on code in the INIT segment. (Code is discarded after DriverEntry returns.) 33 | #define INITCODE __declspec(code_seg(KRTL_INIT_SEGMENT)) 34 | // Use on pageable functions. 35 | #define PAGEDX __declspec(code_seg(KRTL_PAGE_SEGMENT)) 36 | 37 | #else // defined(_KERNEL_MODE) 38 | 39 | #define CXPLAT_STATUS HRESULT 40 | #define CXPLAT_FAILED(X) FAILED(X) 41 | #define CXPLAT_SUCCEEDED(X) SUCCEEDED(X) 42 | #define CXPLAT_STATUS_SUCCESS S_OK 43 | #define CXPLAT_STATUS_FAIL E_FAIL 44 | #define PAGEDX 45 | 46 | #endif // defined(_KERNEL_MODE) 47 | 48 | PAGEDX 49 | _IRQL_requires_max_(PASSIVE_LEVEL) 50 | CXPLAT_STATUS 51 | CxPlatInitialize( 52 | VOID 53 | ); 54 | 55 | PAGEDX 56 | _IRQL_requires_max_(PASSIVE_LEVEL) 57 | VOID 58 | CxPlatUninitialize( 59 | VOID 60 | ); 61 | 62 | // 63 | // Time Measurement Interfaces 64 | // 65 | 66 | #define US_TO_MS(x) ((x) / 1000) 67 | #define MS_TO_US(x) ((x) * 1000) 68 | 69 | // 70 | // Performance counter frequency. 71 | // 72 | extern UINT64 CxPlatPerfFreq; 73 | 74 | // 75 | // Returns the current time in platform specific time units. 76 | // 77 | UINT64 78 | CxPlatTimePlat( 79 | VOID 80 | ); 81 | 82 | // 83 | // Converts platform time to microseconds. 84 | // 85 | inline 86 | UINT64 87 | CxPlatTimePlatToUs64( 88 | UINT64 Count 89 | ) 90 | { 91 | // 92 | // Multiply by a big number (1000000, to convert seconds to microseconds) 93 | // and divide by a big number (CxPlatPerfFreq, to convert counts to secs). 94 | // 95 | // Avoid overflow with separate multiplication/division of the high and low 96 | // bits. Taken from TcpConvertPerformanceCounterToMicroseconds. 97 | // 98 | UINT64 High = (Count >> 32) * 1000000; 99 | UINT64 Low = (Count & 0xFFFFFFFF) * 1000000; 100 | return 101 | ((High / CxPlatPerfFreq) << 32) + 102 | ((Low + ((High % CxPlatPerfFreq) << 32)) / CxPlatPerfFreq); 103 | } 104 | 105 | _IRQL_requires_max_(PASSIVE_LEVEL) 106 | VOID 107 | CxPlatSleep( 108 | _In_ UINT32 DurationMs 109 | ); 110 | 111 | // 112 | // Allocation/Memory Interfaces 113 | // 114 | 115 | _IRQL_requires_max_(DISPATCH_LEVEL) 116 | VOID* 117 | CxPlatAllocNonPaged( 118 | _In_ SIZE_T Size, 119 | _In_ ULONG Tag 120 | ); 121 | 122 | VOID 123 | CxPlatFree( 124 | _In_ VOID* Mem, 125 | _In_ ULONG Tag 126 | ); 127 | 128 | VOID 129 | CxPlatFreeNoTag( 130 | _In_opt_ VOID* Mem 131 | ); 132 | 133 | // 134 | // Create Thread Interfaces 135 | // 136 | 137 | DECLARE_HANDLE(CXPLAT_THREAD); 138 | 139 | #if defined(_KERNEL_MODE) 140 | typedef VOID CXPLAT_THREAD_RETURN_TYPE; 141 | #define CXPLAT_THREAD_RETURN(Status) PsTerminateSystemThread(Status) 142 | #else 143 | typedef DWORD CXPLAT_THREAD_RETURN_TYPE; 144 | #define CXPLAT_THREAD_RETURN(Status) return (DWORD)(Status) 145 | #endif 146 | 147 | typedef 148 | _IRQL_requires_same_ 149 | CXPLAT_THREAD_RETURN_TYPE 150 | CXPLAT_THREAD_ROUTINE( 151 | _In_ VOID* Context 152 | ); 153 | 154 | typedef enum CXPLAT_THREAD_FLAGS { 155 | CXPLAT_THREAD_FLAG_NONE = 0x0000, 156 | CXPLAT_THREAD_FLAG_SET_IDEAL_PROC = 0x0001, 157 | CXPLAT_THREAD_FLAG_SET_AFFINITIZE = 0x0002, 158 | CXPLAT_THREAD_FLAG_HIGH_PRIORITY = 0x0004 159 | } CXPLAT_THREAD_FLAGS; 160 | 161 | #ifdef DEFINE_ENUM_FLAG_OPERATORS 162 | DEFINE_ENUM_FLAG_OPERATORS(CXPLAT_THREAD_FLAGS); 163 | #endif 164 | 165 | typedef struct CXPLAT_THREAD_CONFIG { 166 | UINT16 Flags; 167 | UINT16 IdealProcessor; 168 | _Field_z_ const CHAR* Name; 169 | CXPLAT_THREAD_ROUTINE* Callback; 170 | VOID* Context; 171 | } CXPLAT_THREAD_CONFIG; 172 | 173 | CXPLAT_STATUS 174 | CxPlatThreadCreate( 175 | _In_ CXPLAT_THREAD_CONFIG* Config, 176 | _Out_ CXPLAT_THREAD* Thread 177 | ); 178 | 179 | VOID 180 | CxPlatThreadDelete( 181 | _In_ CXPLAT_THREAD 182 | ); 183 | 184 | BOOLEAN 185 | CxPlatThreadWait( 186 | _In_ CXPLAT_THREAD, 187 | _In_ UINT32 TimeoutMs 188 | ); 189 | 190 | EXTERN_C_END 191 | -------------------------------------------------------------------------------- /test/cxplat/lib/km/cxplat_km.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {06f8bd85-f946-40da-9173-e20fb69fedb0} 5 | cxplat_km 6 | drvlib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(SolutionDir)test\cxplat\lib; 19 | $(SolutionDir)test\cxplat\inc; 20 | %(AdditionalIncludeDirectories) 21 | 22 | true 23 | $(ProjectDir)..\trace.h 24 | true 25 | -p:cxplat 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/cxplat/lib/trace.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // {A9838682-ABBC-4CE9-B63E-E4E26C6F9979} 13 | // 14 | #define WPP_CONTROL_GUIDS \ 15 | WPP_DEFINE_CONTROL_GUID( \ 16 | CxPlatTraceGuid, \ 17 | (A9838682,ABBC,4CE9,B63E,E4E26C6F9979), \ 18 | WPP_DEFINE_BIT(TRACE_CXPLAT) \ 19 | ) 20 | 21 | // 22 | // The following system defined definitions may be used: 23 | // 24 | // TRACE_LEVEL_FATAL = 1 // Abnormal exit or termination. 25 | // TRACE_LEVEL_ERROR = 2 // Severe errors that need logging. 26 | // TRACE_LEVEL_WARNING = 3 // Warnings such as allocation failures. 27 | // TRACE_LEVEL_INFORMATION = 4 // Including non-error cases. 28 | // TRACE_LEVEL_VERBOSE = 5 // Detailed traces from intermediate steps. 29 | // 30 | // begin_wpp config 31 | // 32 | // USEPREFIX(TraceFatal,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 33 | // FUNC TraceFatal{LEVEL=TRACE_LEVEL_FATAL,FLAGS=TRACE_CXPLAT}(MSG,...); 34 | // 35 | // USEPREFIX(TraceError,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 36 | // FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR,FLAGS=TRACE_CXPLAT}(MSG,...); 37 | // 38 | // USEPREFIX(TraceWarn,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 39 | // FUNC TraceWarn{LEVEL=TRACE_LEVEL_WARNING,FLAGS=TRACE_CXPLAT}(MSG,...); 40 | // 41 | // USEPREFIX(TraceInfo,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 42 | // FUNC TraceInfo{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=TRACE_CXPLAT}(MSG,...); 43 | // 44 | // USEPREFIX(TraceVerbose,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 45 | // FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_CXPLAT}(MSG,...); 46 | // 47 | // USEPREFIX(TraceEnter,"%!STDPREFIX! %!FUNC!:%!LINE! --->%!SPACE!"); 48 | // FUNC TraceEnter{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_CXPLAT}(MSG,...); 49 | // 50 | // USEPREFIX(TraceExit,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE! "); 51 | // FUNC TraceExit{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_CXPLAT}(MSG,...); 52 | // 53 | // end_wpp 54 | // 55 | 56 | #define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) \ 57 | (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL)) 58 | #define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS) 59 | 60 | // 61 | // Opt-in to a WPP recorder feature that enables independent evaluation of 62 | // conditions to decide if a message needs to be sent to the recorder, an 63 | // enabled session, or both. 64 | // 65 | #define ENABLE_WPP_TRACE_FILTERING_WITH_WPP_RECORDER 1 66 | 67 | // 68 | // Logger and Enabled macros that support custom recorders. They simply delegate 69 | // to the default. 70 | // 71 | #define WPP_IFRLOG_LEVEL_FLAGS_ENABLED(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) 72 | #define WPP_IFRLOG_LEVEL_FLAGS_LOGGER(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) 73 | -------------------------------------------------------------------------------- /test/cxplat/lib/um/cxplat_um.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {93edb3a0-c6e4-42cc-85a3-92bfc44964d0} 5 | cxplat_um 6 | lib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | tracewpp.exe -odir:$(IntDir) -scan:$(SolutionDir)test\cxplat\lib\trace.h $(ProjectDir)*.cpp -p:cxplat -cfgdir:"$(WindowsSdkDir)bin\$(TargetPlatformVersion)\WppConfig\Rev1" 19 | 20 | 21 | 22 | 23 | $(SolutionDir)test\cxplat\lib; 24 | $(SolutionDir)test\cxplat\inc; 25 | %(AdditionalIncludeDirectories) 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/debugcrt/debugcrt.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16.0 5 | Win32Proj 6 | {74f5716d-c62f-45d4-9cc2-4637440d5e4e} 7 | debugcrt 8 | dll 9 | $(SolutionDir)artifacts\ 10 | 11 | 12 | 13 | Utility 14 | v143 15 | v142 16 | 17 | 18 | 19 | 20 | $([System.IO.File]::ReadAllText($(VCInstallDir)Auxiliary\Build\Microsoft.VCRedistVersion.default.txt).Trim()) 21 | 22 | 23 | 24 | xcopy "$(VCInstallDir)redist\MSVC\$(VCRedistVersion)\onecore\debug_nonredist\$(PlatformShortName)\Microsoft.VC$(PlatformToolsetVersion).DebugCRT\*.dll" "$(OutDir)" /D /Y && xcopy "$(UniversalDebugCRT_ExecutablePath_x64)\*.dll" "$(OutDir)" /D /Y 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/functional/bin/fnfunctionaltests.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {02D631DF-E2E7-4A6E-9773-94A45B19C367} 5 | fnfunctionaltests 6 | 7 | dll 8 | lib 9 | $(SolutionDir)submodules\undocked\ 10 | $(SolutionDir)artifacts\ 11 | true 12 | 13 | 14 | 15 | 16 | {fdaab453-4e69-4933-bc27-a917637b0df9} 17 | 18 | 19 | {f37c088b-c801-46c4-b210-ead7af7ffaee} 20 | 21 | 22 | {93edb3a0-c6e4-42cc-85a3-92bfc44964d0} 23 | 24 | 25 | {e84ff937-7445-4b8e-ba40-dffacc09c060} 26 | 27 | 28 | {dca385fb-b4b1-44cc-ba3f-9da4f619d86a} 29 | 30 | 31 | {32916b02-626c-4bdb-af0c-c586670bba0d} 32 | 33 | 34 | {644a5488-7fb8-4c8b-a45a-981df9a56aef} 35 | 36 | 37 | {74f5716d-c62f-45d4-9cc2-4637440d5e4e} 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | tracewpp.exe -odir:$(IntDir) -scan:$(SolutionDir)test\functional\fntrace.h $(ProjectDir)*.cpp -p:fntest -cfgdir:"$(WindowsSdkDir)bin\$(TargetPlatformVersion)\WppConfig\Rev1" 48 | 49 | 50 | 51 | 52 | $(SolutionDir)test\functional; 53 | $(SolutionDir)test\functional\bin\km; 54 | $(VCInstallDir)UnitTest\include; 55 | %(AdditionalIncludeDirectories) 56 | 57 | 58 | UM_NDIS687=1; 59 | %(PreprocessorDefinitions) 60 | 61 | 62 | 63 | Windows 64 | 65 | ntdll.lib; 66 | onecore.lib; 67 | ws2_32.lib; 68 | iphlpapi.lib; 69 | advapi32.lib; 70 | %(AdditionalDependencies) 71 | 72 | $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /test/functional/bin/km/driver.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. 4 | Licensed under the MIT License. 5 | 6 | Abstract: 7 | 8 | Kernel Mode Test Driver 9 | 10 | --*/ 11 | 12 | #include 13 | #include 14 | 15 | #include "fntrace.h" 16 | 17 | #include "driver.tmh" 18 | 19 | #ifndef KRTL_INIT_SEGMENT 20 | #define KRTL_INIT_SEGMENT "INIT" 21 | #endif 22 | #ifndef KRTL_PAGE_SEGMENT 23 | #define KRTL_PAGE_SEGMENT "PAGE" 24 | #endif 25 | #ifndef KRTL_NONPAGED_SEGMENT 26 | #define KRTL_NONPAGED_SEGMENT ".text" 27 | #endif 28 | 29 | // Use on code in the INIT segment. (Code is discarded after DriverEntry returns.) 30 | #define INITCODE __declspec(code_seg(KRTL_INIT_SEGMENT)) 31 | 32 | // Use on pageable functions. 33 | #define PAGEDX __declspec(code_seg(KRTL_PAGE_SEGMENT)) 34 | 35 | #define TEST_DRV_POOL 'vDsT' // TsDv 36 | 37 | EVT_WDF_DRIVER_UNLOAD TestDrvDriverUnload; 38 | PDRIVER_OBJECT GlobalDriverObject; 39 | 40 | _No_competing_thread_ 41 | INITCODE 42 | NTSTATUS 43 | TestDrvCtlInitialize( 44 | _In_ WDFDRIVER Driver 45 | ); 46 | 47 | _IRQL_requires_max_(PASSIVE_LEVEL) 48 | VOID 49 | TestDrvCtlUninitialize( 50 | ); 51 | 52 | extern "C" 53 | INITCODE 54 | _Function_class_(DRIVER_INITIALIZE) 55 | _IRQL_requires_same_ 56 | _IRQL_requires_(PASSIVE_LEVEL) 57 | NTSTATUS 58 | DriverEntry( 59 | _In_ PDRIVER_OBJECT DriverObject, 60 | _In_ PUNICODE_STRING RegistryPath 61 | ) 62 | /*++ 63 | 64 | Routine Description: 65 | 66 | DriverEntry initializes the driver and is the first routine called by the 67 | system after the driver is loaded. DriverEntry specifies the other entry 68 | points in the function driver, such as EvtDevice and DriverUnload. 69 | 70 | Parameters Description: 71 | 72 | DriverObject - represents the instance of the function driver that is loaded 73 | into memory. DriverEntry must initialize members of DriverObject before it 74 | returns to the caller. DriverObject is allocated by the system before the 75 | driver is loaded, and it is released by the system after the system unloads 76 | the function driver from memory. 77 | 78 | RegistryPath - represents the driver specific path in the Registry. 79 | The function driver can use the path to store driver related data between 80 | reboots. The path does not store hardware instance specific data. 81 | 82 | Return Value: 83 | 84 | A success status as determined by NT_SUCCESS macro, if successful. 85 | 86 | --*/ 87 | { 88 | NTSTATUS Status; 89 | WDF_DRIVER_CONFIG Config; 90 | WDFDRIVER Driver; 91 | 92 | GlobalDriverObject = DriverObject; 93 | 94 | WPP_INIT_TRACING(GlobalDriverObject, RegistryPath); 95 | 96 | // 97 | // Create the WdfDriver Object 98 | // 99 | WDF_DRIVER_CONFIG_INIT(&Config, NULL); 100 | Config.EvtDriverUnload = TestDrvDriverUnload; 101 | Config.DriverInitFlags = WdfDriverInitNonPnpDriver; 102 | Config.DriverPoolTag = TEST_DRV_POOL; 103 | 104 | Status = 105 | WdfDriverCreate( 106 | DriverObject, 107 | RegistryPath, 108 | WDF_NO_OBJECT_ATTRIBUTES, 109 | &Config, 110 | &Driver); 111 | if (!NT_SUCCESS(Status)) { 112 | TraceError( 113 | "[ lib] ERROR, %u, %s.", 114 | Status, 115 | "WdfDriverCreate failed"); 116 | goto Error; 117 | } 118 | 119 | // 120 | // Initialize the device control interface. 121 | // 122 | Status = TestDrvCtlInitialize(Driver); 123 | if (!NT_SUCCESS(Status)) { 124 | TraceError( 125 | "[ lib] ERROR, %u, %s.", 126 | Status, 127 | "TestDrvCtlInitialize failed"); 128 | goto Error; 129 | } 130 | 131 | TraceInfo( 132 | "[test] Started"); 133 | 134 | Error: 135 | 136 | return Status; 137 | } 138 | 139 | _Function_class_(EVT_WDF_DRIVER_UNLOAD) 140 | _IRQL_requires_same_ 141 | _IRQL_requires_max_(PASSIVE_LEVEL) 142 | void 143 | TestDrvDriverUnload( 144 | _In_ WDFDRIVER Driver 145 | ) 146 | /*++ 147 | 148 | Routine Description: 149 | 150 | TestDrvDriverUnload will clean up any resources that were allocated for 151 | this driver. 152 | 153 | Arguments: 154 | 155 | Driver - Handle to a framework driver object created in DriverEntry 156 | 157 | --*/ 158 | { 159 | UNREFERENCED_PARAMETER(Driver); 160 | NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 161 | 162 | TestDrvCtlUninitialize(); 163 | 164 | TraceInfo( 165 | "[test] Stopped"); 166 | 167 | WPP_CLEANUP(GlobalDriverObject); 168 | } 169 | -------------------------------------------------------------------------------- /test/functional/bin/km/fnfunctionaltestdrv.rc: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) Microsoft. All rights reserved. 3 | // 4 | 5 | #include 6 | 7 | #define VER_FILEDESCRIPTION_STR "Fn Functional Test Driver" 8 | #define VER_INTERNALNAME_STR "fnfunctionaltestdrv.sys" 9 | #define VER_FILETYPE VFT_DRV 10 | #define VER_FILESUBTYPE VFT2_DRV_NETWORK 11 | 12 | #include "undocked.ver" 13 | -------------------------------------------------------------------------------- /test/functional/bin/km/fnfunctionaltestdrv.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {fdaab453-4e69-4933-bc27-a917637b0df9} 5 | fnfunctionaltestdrv 6 | sys 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | {3539d1da-2355-4352-865f-5120a59846eb} 15 | 16 | 17 | {06f8bd85-f946-40da-9173-e20fb69fedb0} 18 | 19 | 20 | {ac661767-42c3-4525-8b90-d509a6048dc3} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | $(SolutionDir)test\functional; 32 | %(AdditionalIncludeDirectories) 33 | 34 | true 35 | $(ProjectDir)trace.h 36 | true 37 | -p:fntestdrv 38 | 39 | 40 | 41 | $(OutDir)fnsock_km.lib; 42 | netio.lib; 43 | wdmsec.lib; 44 | %(AdditionalDependencies) 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /test/functional/bin/km/fnfunctionaltestdrvioctl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | // 11 | // Kernel Mode Driver Interface 12 | // 13 | 14 | #define FUNCTIONAL_TEST_DRIVER_NAME "fnfunctionaltestdrv" 15 | 16 | #define IoGetFunctionCodeFromCtlCode( ControlCode ) (\ 17 | ( ControlCode >> 2) & 0x00000FFF ) 18 | 19 | // 20 | // IOCTL Interface 21 | // 22 | 23 | #define IOCTL_MP_BASIC_RX \ 24 | CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_DATA) 25 | 26 | #define IOCTL_MP_BASIC_TX \ 27 | CTL_CODE(FILE_DEVICE_NETWORK, 2, METHOD_BUFFERED, FILE_WRITE_DATA) 28 | 29 | #define IOCTL_MP_BASIC_RX_OFFLOAD \ 30 | CTL_CODE(FILE_DEVICE_NETWORK, 3, METHOD_BUFFERED, FILE_WRITE_DATA) 31 | 32 | #define IOCTL_MP_BASIC_TX_OFFLOAD \ 33 | CTL_CODE(FILE_DEVICE_NETWORK, 4, METHOD_BUFFERED, FILE_WRITE_DATA) 34 | 35 | #define IOCTL_LWF_BASIC_RX \ 36 | CTL_CODE(FILE_DEVICE_NETWORK, 5, METHOD_BUFFERED, FILE_WRITE_DATA) 37 | 38 | #define IOCTL_LWF_BASIC_TX \ 39 | CTL_CODE(FILE_DEVICE_NETWORK, 6, METHOD_BUFFERED, FILE_WRITE_DATA) 40 | 41 | #define IOCTL_LWF_BASIC_OID \ 42 | CTL_CODE(FILE_DEVICE_NETWORK, 7, METHOD_BUFFERED, FILE_WRITE_DATA) 43 | 44 | #define IOCTL_SOCK_BASIC_TCP \ 45 | CTL_CODE(FILE_DEVICE_NETWORK, 8, METHOD_BUFFERED, FILE_WRITE_DATA) 46 | 47 | #define IOCTL_SOCK_BASIC_RAW \ 48 | CTL_CODE(FILE_DEVICE_NETWORK, 9, METHOD_BUFFERED, FILE_WRITE_DATA) 49 | 50 | #define IOCTL_MP_BASIC_WATCHDOG \ 51 | CTL_CODE(FILE_DEVICE_NETWORK, 10, METHOD_BUFFERED, FILE_WRITE_DATA) 52 | 53 | #define IOCTL_MP_BASIC_PORT \ 54 | CTL_CODE(FILE_DEVICE_NETWORK, 11, METHOD_BUFFERED, FILE_WRITE_DATA) 55 | 56 | #define MAX_IOCTL_FUNC_CODE 11 57 | 58 | EXTERN_C_END 59 | -------------------------------------------------------------------------------- /test/functional/bin/km/trace.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // {DFBE8BE6-1134-4B47-B1E7-F925F7567B8A} 13 | // 14 | #define WPP_CONTROL_GUIDS \ 15 | WPP_DEFINE_CONTROL_GUID( \ 16 | FunctionalTestDrvTraceGuid, \ 17 | (DFBE8BE6,1134,4B47,B1E7,F925F7567B8A), \ 18 | WPP_DEFINE_BIT(TRACE_FUNCTIONAL) \ 19 | ) 20 | 21 | // 22 | // The following system defined definitions may be used: 23 | // 24 | // TRACE_LEVEL_FATAL = 1 // Abnormal exit or termination. 25 | // TRACE_LEVEL_ERROR = 2 // Severe errors that need logging. 26 | // TRACE_LEVEL_WARNING = 3 // Warnings such as allocation failures. 27 | // TRACE_LEVEL_INFORMATION = 4 // Including non-error cases. 28 | // TRACE_LEVEL_VERBOSE = 5 // Detailed traces from intermediate steps. 29 | // 30 | // begin_wpp config 31 | // 32 | // USEPREFIX(TraceFatal,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 33 | // FUNC TraceFatal{LEVEL=TRACE_LEVEL_FATAL,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 34 | // 35 | // USEPREFIX(TraceError,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 36 | // FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 37 | // 38 | // USEPREFIX(TraceWarn,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 39 | // FUNC TraceWarn{LEVEL=TRACE_LEVEL_WARNING,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 40 | // 41 | // USEPREFIX(TraceInfo,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 42 | // FUNC TraceInfo{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 43 | // 44 | // USEPREFIX(TraceVerbose,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 45 | // FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 46 | // 47 | // USEPREFIX(TraceEnter,"%!STDPREFIX! %!FUNC!:%!LINE! --->%!SPACE!"); 48 | // FUNC TraceEnter{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 49 | // 50 | // USEPREFIX(TraceExit,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE! "); 51 | // FUNC TraceExit{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 52 | // 53 | // end_wpp 54 | // 55 | 56 | #define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) \ 57 | (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL)) 58 | #define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS) 59 | -------------------------------------------------------------------------------- /test/functional/fntest.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // This is a layer of indirection to not call framework-dependent functions from test collateral. 10 | // 11 | 12 | #include 13 | #include "testframeworkapi.h" 14 | 15 | #define TEST_FAILURE(Format, ...) LogTestFailure(L"" __FILE__, L"" __FUNCTION__, __LINE__, L"" Format, ##__VA_ARGS__) 16 | 17 | #define TEST_WARNING(Format, ...) LogTestWarning(L"" __FILE__, L"" __FUNCTION__, __LINE__, L"" Format, ##__VA_ARGS__) 18 | 19 | #define TEST_EQUAL(expected, condition) { \ 20 | if ((condition) != (expected)) { \ 21 | TEST_FAILURE(#condition " not equal to " #expected); \ 22 | return; \ 23 | } \ 24 | } 25 | 26 | #define TEST_NOT_EQUAL(expected, condition) { \ 27 | if ((condition) == (expected)) { \ 28 | TEST_FAILURE(#condition " equals " #expected); \ 29 | return; \ 30 | } \ 31 | } 32 | 33 | #define TEST_TRUE(condition) { \ 34 | if (!(condition)) { \ 35 | TEST_FAILURE(#condition " not true"); \ 36 | return; \ 37 | } \ 38 | } 39 | 40 | #define TEST_FALSE(condition) { \ 41 | if (condition) { \ 42 | TEST_FAILURE(#condition " not false"); \ 43 | return; \ 44 | } \ 45 | } 46 | 47 | #define TEST_NOT_NULL(condition) { \ 48 | if ((condition) == NULL) { \ 49 | TEST_FAILURE(#condition " is NULL"); \ 50 | return; \ 51 | } \ 52 | } 53 | 54 | #define TEST_HRESULT(condition) { \ 55 | HRESULT hr_ = (condition); \ 56 | if (FAILED(hr_)) { \ 57 | TEST_FAILURE(#condition " failed, 0x%x", hr_); \ 58 | return; \ 59 | } \ 60 | } 61 | 62 | #define TEST_NTSTATUS(condition) { \ 63 | HRESULT hr_ = HRESULT_FROM_NT(condition); \ 64 | if (FAILED(hr_)) { \ 65 | TEST_FAILURE(#condition " failed, 0x%x", hr_); \ 66 | return; \ 67 | } \ 68 | } 69 | 70 | // 71 | // goto variants 72 | // 73 | 74 | #define TEST_EQUAL_GOTO(expected, condition, label) { \ 75 | if ((condition) != (expected)) { \ 76 | TEST_FAILURE(#condition " not equal to " #expected); \ 77 | goto label; \ 78 | } \ 79 | } 80 | 81 | #define TEST_NOT_EQUAL_GOTO(expected, condition, label) { \ 82 | if ((condition) == (expected)) { \ 83 | TEST_FAILURE(#condition " equals " #expected); \ 84 | goto label; \ 85 | } \ 86 | } 87 | 88 | #define TEST_TRUE_GOTO(condition, label) { \ 89 | if (!(condition)) { \ 90 | TEST_FAILURE(#condition " not true"); \ 91 | goto label; \ 92 | } \ 93 | } 94 | 95 | #define TEST_FALSE_GOTO(condition, label) { \ 96 | if (condition) { \ 97 | TEST_FAILURE(#condition " not false"); \ 98 | goto label; \ 99 | } \ 100 | } 101 | 102 | #define TEST_NOT_NULL_GOTO(condition, label) { \ 103 | if ((condition) == NULL) { \ 104 | TEST_FAILURE(#condition " is NULL"); \ 105 | goto label; \ 106 | } \ 107 | } 108 | 109 | #define TEST_HRESULT_GOTO(condition, label) { \ 110 | HRESULT hr_ = (condition); \ 111 | if (FAILED(hr_)) { \ 112 | TEST_FAILURE(#condition " failed, 0x%x", hr_); \ 113 | goto label; \ 114 | } \ 115 | } 116 | 117 | #define TEST_NTSTATUS_GOTO(condition, label) { \ 118 | HRESULT hr_ = HRESULT_FROM_NT(condition); \ 119 | if (FAILED(hr_)) { \ 120 | TEST_FAILURE(#condition " failed, 0x%x", hr_); \ 121 | goto label; \ 122 | } \ 123 | } 124 | 125 | // 126 | // return variants 127 | // 128 | 129 | #define TEST_EQUAL_RET(expected, condition, retval) { \ 130 | if ((condition) != (expected)) { \ 131 | TEST_FAILURE(#condition " not equal to " #expected); \ 132 | return retval; \ 133 | } \ 134 | } 135 | 136 | #define TEST_NOT_EQUAL_RET(expected, condition, retval) { \ 137 | if ((condition) == (expected)) { \ 138 | TEST_FAILURE(#condition " equals " #expected); \ 139 | return retval; \ 140 | } \ 141 | } 142 | 143 | #define TEST_TRUE_RET(condition, retval) { \ 144 | if (!(condition)) { \ 145 | TEST_FAILURE(#condition " not true"); \ 146 | return retval; \ 147 | } \ 148 | } 149 | 150 | #define TEST_FALSE_RET(condition, retval) { \ 151 | if (condition) { \ 152 | TEST_FAILURE(#condition " not false"); \ 153 | return retval; \ 154 | } \ 155 | } 156 | 157 | #define TEST_NOT_NULL_RET(condition, retval) { \ 158 | if ((condition) == NULL) { \ 159 | TEST_FAILURE(#condition " is NULL"); \ 160 | return retval; \ 161 | } \ 162 | } 163 | 164 | #define TEST_HRESULT_RET(condition, retval) { \ 165 | HRESULT hr_ = (condition); \ 166 | if (FAILED(hr_)) { \ 167 | TEST_FAILURE(#condition " failed, 0x%x", hr_); \ 168 | return retval; \ 169 | } \ 170 | } 171 | 172 | #define TEST_NTSTATUS_RET(condition, retval) { \ 173 | HRESULT hr_ = HRESULT_FROM_NT(condition); \ 174 | if (FAILED(hr_)) { \ 175 | TEST_FAILURE(#condition " failed, 0x%x", hr_); \ 176 | return retval; \ 177 | } \ 178 | } 179 | -------------------------------------------------------------------------------- /test/functional/fntrace.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // {3207D516-BB97-4C97-9B49-5EB25829C43F} 13 | // 14 | #define WPP_CONTROL_GUIDS \ 15 | WPP_DEFINE_CONTROL_GUID( \ 16 | FunctionalTestTraceGuid, \ 17 | (3207D516,BB97,4C97,9B49,5EB25829C43F), \ 18 | WPP_DEFINE_BIT(TRACE_FUNCTIONAL) \ 19 | ) 20 | 21 | // 22 | // The following system defined definitions may be used: 23 | // 24 | // TRACE_LEVEL_FATAL = 1 // Abnormal exit or termination. 25 | // TRACE_LEVEL_ERROR = 2 // Severe errors that need logging. 26 | // TRACE_LEVEL_WARNING = 3 // Warnings such as allocation failures. 27 | // TRACE_LEVEL_INFORMATION = 4 // Including non-error cases. 28 | // TRACE_LEVEL_VERBOSE = 5 // Detailed traces from intermediate steps. 29 | // 30 | // begin_wpp config 31 | // 32 | // USEPREFIX(TraceFatal,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 33 | // FUNC TraceFatal{LEVEL=TRACE_LEVEL_FATAL,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 34 | // 35 | // USEPREFIX(TraceError,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 36 | // FUNC TraceError{LEVEL=TRACE_LEVEL_ERROR,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 37 | // 38 | // USEPREFIX(TraceWarn,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 39 | // FUNC TraceWarn{LEVEL=TRACE_LEVEL_WARNING,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 40 | // 41 | // USEPREFIX(TraceInfo,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 42 | // FUNC TraceInfo{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 43 | // 44 | // USEPREFIX(TraceVerbose,"%!STDPREFIX! %!FUNC!:%!LINE!%!SPACE!"); 45 | // FUNC TraceVerbose{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 46 | // 47 | // USEPREFIX(TraceEnter,"%!STDPREFIX! %!FUNC!:%!LINE! --->%!SPACE!"); 48 | // FUNC TraceEnter{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 49 | // 50 | // USEPREFIX(TraceExit,"%!STDPREFIX! %!FUNC!:%!LINE! <---%!SPACE! "); 51 | // FUNC TraceExit{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=TRACE_FUNCTIONAL}(MSG,...); 52 | // 53 | // end_wpp 54 | // 55 | 56 | #define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) \ 57 | (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL)) 58 | #define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS) 59 | 60 | // 61 | // Opt-in to a WPP recorder feature that enables independent evaluation of 62 | // conditions to decide if a message needs to be sent to the recorder, an 63 | // enabled session, or both. 64 | // 65 | #define ENABLE_WPP_TRACE_FILTERING_WITH_WPP_RECORDER 1 66 | 67 | // 68 | // Logger and Enabled macros that support custom recorders. They simply delegate 69 | // to the default. 70 | // 71 | #define WPP_IFRLOG_LEVEL_FLAGS_ENABLED(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) 72 | #define WPP_IFRLOG_LEVEL_FLAGS_LOGGER(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) 73 | -------------------------------------------------------------------------------- /test/functional/lib/fnfunctionaltestlib_km.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {3539d1da-2355-4352-865f-5120a59846eb} 5 | fnfunctionaltestlib_km 6 | drvlib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(SolutionDir)inc; 19 | $(SolutionDir)test\cxplat\inc; 20 | $(SolutionDir)test\functional; 21 | $(SolutionDir)submodules\net-offloads\include; 22 | $(SolutionDir)submodules\wil\include; 23 | $(SolutionDir)test\pkthlp; 24 | %(AdditionalIncludeDirectories) 25 | 26 | 27 | NDIS683=1; 28 | %(PreprocessorDefinitions) 29 | 30 | true 31 | $(ProjectDir)..\bin\km\trace.h 32 | true 33 | -p:fntestdrv 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /test/functional/lib/fnfunctionaltestlib_um.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {F37C088B-C801-46C4-B210-EAD7AF7FFAEE} 5 | fnfunctionaltestlib_um 6 | lib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | tracewpp.exe -odir:$(IntDir) -scan:$(SolutionDir)test\functional\fntrace.h $(ProjectDir)*.cpp -p:fntest -cfgdir:"$(WindowsSdkDir)bin\$(TargetPlatformVersion)\WppConfig\Rev1" 19 | 20 | 21 | 22 | 23 | $(SolutionDir)inc; 24 | $(SolutionDir)test\cxplat\inc; 25 | $(SolutionDir)test\functional; 26 | $(SolutionDir)submodules\net-offloads\include; 27 | $(SolutionDir)submodules\wil\include; 28 | $(SolutionDir)test\pkthlp; 29 | %(AdditionalIncludeDirectories) 30 | 31 | 32 | UM_NDIS683=1; 33 | %(PreprocessorDefinitions) 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /test/functional/testframeworkapi.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Test framework abstraction layer. This interface exists so that tests may 10 | // use different test frameworks without changing test logic. 11 | // 12 | 13 | #if !defined(_KERNEL_MODE) 14 | #include 15 | #endif 16 | 17 | EXTERN_C_START 18 | 19 | VOID 20 | LogTestFailure( 21 | _In_z_ PCWSTR File, 22 | _In_z_ PCWSTR Function, 23 | INT Line, 24 | _Printf_format_string_ PCWSTR Format, 25 | ... 26 | ); 27 | 28 | VOID 29 | LogTestWarning( 30 | _In_z_ PCWSTR File, 31 | _In_z_ PCWSTR Function, 32 | INT Line, 33 | _Printf_format_string_ PCWSTR Format, 34 | ... 35 | ); 36 | 37 | EXTERN_C_END 38 | -------------------------------------------------------------------------------- /test/functional/tests.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | EXTERN_C_START 9 | 10 | bool 11 | TestSetup(); 12 | 13 | bool 14 | TestCleanup(); 15 | 16 | VOID 17 | MpBasicRx(); 18 | 19 | VOID 20 | MpBasicTx(); 21 | 22 | VOID 23 | MpBasicRxOffload(); 24 | 25 | VOID 26 | MpBasicTxOffload(); 27 | 28 | VOID 29 | MpBasicWatchdog(); 30 | 31 | VOID 32 | MpBasicPort(); 33 | 34 | VOID 35 | LwfBasicRx(); 36 | 37 | VOID 38 | LwfBasicTx(); 39 | 40 | VOID 41 | LwfBasicOid(); 42 | 43 | VOID 44 | SockBasicTcp(USHORT AddressFamily); 45 | 46 | VOID 47 | SockBasicRaw(USHORT AddressFamily); 48 | 49 | EXTERN_C_END 50 | -------------------------------------------------------------------------------- /test/pkthlp/km/pkthlp_km.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {091c094c-bf60-4bcb-9d38-1b439fc0ab7f} 5 | pkthlp_km 6 | drvlib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(SolutionDir)\inc; 19 | .\; 20 | ..\; 21 | %(AdditionalIncludeDirectories) 22 | 23 | 24 | POOL_NX_OPTIN_AUTO=1; 25 | POOL_ZERO_DOWN_LEVEL_SUPPORT=1; 26 | %(PreprocessorDefinitions) 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /test/pkthlp/km/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | -------------------------------------------------------------------------------- /test/pkthlp/pkthlp.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include "precomp.h" 7 | -------------------------------------------------------------------------------- /test/pkthlp/um/pkthlp_um.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | {e84ff937-7445-4b8e-ba40-dffacc09c060} 5 | pkthlp_um 6 | lib 7 | $(SolutionDir)submodules\undocked\ 8 | $(SolutionDir)artifacts\ 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(SolutionDir)\inc; 19 | .\; 20 | ..\; 21 | %(AdditionalIncludeDirectories) 22 | 23 | 24 | POOL_NX_OPTIN_AUTO=1; 25 | POOL_ZERO_DOWN_LEVEL_SUPPORT=1; 26 | %(PreprocessorDefinitions) 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /test/pkthlp/um/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | -------------------------------------------------------------------------------- /tools/build.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Build script. 3 | # 4 | 5 | param ( 6 | [ValidateSet("x64", "arm64")] 7 | [Parameter(Mandatory=$false)] 8 | [string]$Platform = "x64", 9 | 10 | [ValidateSet("Debug", "Release")] 11 | [Parameter(Mandatory=$false)] 12 | [string]$Config = "Debug", 13 | 14 | [Parameter(Mandatory=$false)] 15 | [string]$Project = "", 16 | 17 | [Parameter(Mandatory = $false)] 18 | [switch]$NoClean = $false, 19 | 20 | [Parameter(Mandatory = $false)] 21 | [switch]$UpdateDeps = $false 22 | ) 23 | 24 | Set-StrictMode -Version 'Latest' 25 | $ErrorActionPreference = 'Stop' 26 | 27 | $RootDir = Split-Path $PSScriptRoot -Parent 28 | 29 | $Tasks = @() 30 | if ([string]::IsNullOrEmpty($Project)) { 31 | $Tasks += "Build" 32 | 33 | if (!$NoClean) { 34 | $Tasks = @("Clean") + $Tasks 35 | } 36 | } else { 37 | $Clean = "" 38 | if (!$NoClean) { 39 | $Clean = ":Rebuild" 40 | } 41 | $Tasks += "$Project$Clean" 42 | } 43 | 44 | & $RootDir\tools\prepare-machine.ps1 -ForBuild -Force:$UpdateDeps 45 | 46 | msbuild.exe $RootDir\wnt.sln ` 47 | /t:restore ` 48 | /p:RestorePackagesConfig=true ` 49 | /p:Configuration=$Config ` 50 | /p:Platform=$Platform 51 | if (!$?) { 52 | Write-Error "Restoring NuGet packages failed: $LastExitCode" 53 | } 54 | 55 | # Unfortunately, global state cached by MsBuild.exe combined with WDK bugs 56 | # causes unreliable builds. Specifically, the Telemetry task implemented by 57 | # WDK's Microsoft.DriverKit.Build.Tasks.17.0.dll has breaking API changes 58 | # that are not invalidated by loading different WDKs. Therefore we disable 59 | # MsBuild.exe reuse with /nodeReuse:false. 60 | 61 | msbuild.exe $RootDir\wnt.sln ` 62 | /p:Configuration=$Config ` 63 | /p:Platform=$Platform ` 64 | /p:SignMode=TestSign ` 65 | /t:$($Tasks -join ",") ` 66 | /nodeReuse:false ` 67 | /maxCpuCount 68 | if (!$?) { 69 | Write-Error "Build failed: $LastExitCode" 70 | } 71 | -------------------------------------------------------------------------------- /tools/create-devkit.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Assembles a dev kit for FNMP/FNLWF client development. 3 | # Code must be built before running this script. 4 | # 5 | 6 | param ( 7 | [ValidateSet("x64", "arm64")] 8 | [Parameter(Mandatory=$false)] 9 | [string]$Platform = "x64", 10 | 11 | [ValidateSet("Debug", "Release")] 12 | [Parameter(Mandatory=$false)] 13 | [string]$Config = "Debug" 14 | ) 15 | 16 | Set-StrictMode -Version 'Latest' 17 | $ErrorActionPreference = 'Stop' 18 | 19 | $RootDir = Split-Path $PSScriptRoot -Parent 20 | . $RootDir\tools\common.ps1 21 | 22 | $Name = "fn-devkit-$Platform" 23 | if ($Config -eq "Debug") { 24 | $Name += "-debug" 25 | } 26 | $DstPath = "artifacts\kit\$Name" 27 | 28 | Remove-Item $DstPath -Recurse -ErrorAction Ignore 29 | New-Item -Path $DstPath -ItemType Directory > $null 30 | 31 | New-Item -Path $DstPath\include -ItemType Directory > $null 32 | copy -Recurse inc\* $DstPath\include 33 | 34 | Compress-Archive -DestinationPath "$DstPath\$Name.zip" -Path $DstPath\* 35 | -------------------------------------------------------------------------------- /tools/create-nuget-package.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Assembles a nuget package for development with win-net-test tools. 3 | # Code must be built before running this script. 4 | # 5 | 6 | param ( 7 | [ValidateSet("x64", "arm64")] 8 | [Parameter(Mandatory=$false)] 9 | [string[]]$Platform = "x64", 10 | 11 | [ValidateSet("Debug", "Release")] 12 | [Parameter(Mandatory=$false)] 13 | [string]$Config = "Debug" 14 | ) 15 | 16 | Set-StrictMode -Version 'Latest' 17 | $OriginalErrorActionPreference = $ErrorActionPreference 18 | $ErrorActionPreference = 'Stop' 19 | 20 | $RootDir = Split-Path $PSScriptRoot -Parent 21 | . $RootDir\tools\common.ps1 22 | 23 | try { 24 | $Version = Get-ProjectBuildVersionString 25 | 26 | $DstPath = "artifacts\pkg\$Config" 27 | New-Item -ItemType Directory -Path $DstPath -ErrorAction Ignore 28 | 29 | $Content = Get-Content "tools\nuget\win-net-test.nuspec.in" 30 | $Content = $Content.Replace("{version}", $Version) 31 | $Content = $Content.Replace("{config}", $Config) 32 | $ExpandedContent = @() 33 | 34 | foreach ($Line in $Content) { 35 | if ($Line -like "*{arch}*") { 36 | foreach ($PlatformName in $Platform) { 37 | $ExpandedContent += $Line.Replace("{arch}", $PlatformName) 38 | } 39 | } else { 40 | $ExpandedContent += $Line 41 | } 42 | } 43 | 44 | Set-Content $DstPath\win-net-test.nuspec $ExpandedContent 45 | 46 | nuget.exe pack $DstPath\win-net-test.nuspec -OutputDirectory $DstPath 47 | } catch { 48 | Write-Error $_ -ErrorAction $OriginalErrorActionPreference 49 | } 50 | -------------------------------------------------------------------------------- /tools/create-runtimekit.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Assembles a runtime kit for FNMP/FNLWF execution. 3 | # Code must be built before running this script. 4 | # 5 | 6 | param ( 7 | [ValidateSet("x64", "arm64")] 8 | [Parameter(Mandatory=$false)] 9 | [string]$Platform = "x64", 10 | 11 | [ValidateSet("Debug", "Release")] 12 | [Parameter(Mandatory=$false)] 13 | [string]$Config = "Debug" 14 | ) 15 | 16 | Set-StrictMode -Version 'Latest' 17 | $ErrorActionPreference = 'Stop' 18 | 19 | $RootDir = Split-Path $PSScriptRoot -Parent 20 | . $RootDir\tools\common.ps1 21 | 22 | $Name = "fn-runtime-$Platform" 23 | if ($Config -eq "Debug") { 24 | $Name += "-debug" 25 | } 26 | $DstPath = "artifacts\kit\$Name" 27 | 28 | Remove-Item $DstPath -Recurse -ErrorAction Ignore 29 | New-Item -Path $DstPath -ItemType Directory > $null 30 | 31 | New-Item -Path $DstPath\bin -ItemType Directory > $null 32 | New-Item -Path $DstPath\bin\isr -ItemType Directory > $null 33 | New-Item -Path $DstPath\bin\fnsock -ItemType Directory > $null 34 | copy -Recurse "artifacts\bin\$($Platform)_$($Config)\fnmp\" $DstPath\bin 35 | copy -Recurse "artifacts\bin\$($Platform)_$($Config)\fnlwf\" $DstPath\bin 36 | copy "artifacts\bin\$($Platform)_$($Config)\isrdrv.sys" $DstPath\bin\isr 37 | copy "artifacts\bin\$($Platform)_$($Config)\isrsvc.exe" $DstPath\bin\isr 38 | copy "artifacts\bin\$($Platform)_$($Config)\fnsock_um.dll" $DstPath\bin\fnsock 39 | copy "artifacts\bin\$($Platform)_$($Config)\fnsock_km.sys" $DstPath\bin\fnsock 40 | 41 | New-Item -Path $DstPath\symbols -ItemType Directory > $null 42 | copy "artifacts\bin\$($Platform)_$($Config)\fnmp.pdb" $DstPath\symbols 43 | copy "artifacts\bin\$($Platform)_$($Config)\fnlwf.pdb" $DstPath\symbols 44 | copy "artifacts\bin\$($Platform)_$($Config)\isrdrv.pdb" $DstPath\symbols 45 | copy "artifacts\bin\$($Platform)_$($Config)\isrsvc.pdb" $DstPath\symbols 46 | copy "artifacts\bin\$($Platform)_$($Config)\fnsock_um.pdb" $DstPath\symbols 47 | copy "artifacts\bin\$($Platform)_$($Config)\fnsock_km.pdb" $DstPath\symbols 48 | 49 | New-Item -Path $DstPath\tools -ItemType Directory > $null 50 | copy ".\tools\common.ps1" $DstPath\tools 51 | copy ".\tools\prepare-machine.ps1" $DstPath\tools 52 | copy ".\tools\setup.ps1" $DstPath\tools 53 | 54 | Compress-Archive -DestinationPath "$DstPath\$Name.zip" -Path $DstPath\* 55 | -------------------------------------------------------------------------------- /tools/log.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .SYNOPSIS 4 | This helps start and stop ETW logging. 5 | 6 | .PARAMETER Config 7 | When using an artifacts directory, specifies the build configuration to use. 8 | 9 | .PARAMETER Arch 10 | When using an artifacts directory, specifies the CPU architecture to use. 11 | 12 | .PARAMETER SymbolPath 13 | Specifies a directory containing symbol files. 14 | 15 | .PARAMETER Start 16 | Starts logging. 17 | 18 | .PARAMETER Profile 19 | Specifies the WPR profile to start logging. 20 | 21 | .PARAMETER Stop 22 | Stops logging. 23 | 24 | .PARAMETER Convert 25 | Converts the ETL to text. Requires a symbol path, either implicitly via the 26 | Config and Arch parameters or explicitly via SymbolPath. 27 | 28 | .PARAMETER Name 29 | The name or wildcard pattern of the tracing instance and output file. 30 | 31 | .PARAMETER EtlPath 32 | Overrides the output ETL file. 33 | 34 | #> 35 | 36 | param ( 37 | [Parameter(Mandatory = $false)] 38 | [ValidateSet("Debug", "Release")] 39 | [string]$Config = "Debug", 40 | 41 | [Parameter(Mandatory = $false)] 42 | [ValidateSet("x64", "arm64")] 43 | [string]$Arch = "x64", 44 | 45 | [Parameter(Mandatory = $false)] 46 | [string]$SymbolPath = $null, 47 | 48 | [Parameter(Mandatory = $false)] 49 | [switch]$Start = $false, 50 | 51 | [Parameter(Mandatory = $false)] 52 | [switch]$Stop = $false, 53 | 54 | [Parameter(Mandatory = $false)] 55 | [switch]$Convert = $false, 56 | 57 | [Parameter(Mandatory = $false)] 58 | [string]$Profile = "FNMP", 59 | 60 | [Parameter(Mandatory = $false)] 61 | [SupportsWildcards()] 62 | [string]$Name = "fn", 63 | 64 | [Parameter(Mandatory = $false)] 65 | [string]$EtlPath = $null, 66 | 67 | [Parameter(Mandatory = $false)] 68 | [ValidateSet("File", "Memory")] 69 | [string]$LogMode = "File" 70 | ) 71 | 72 | Set-StrictMode -Version 'Latest' 73 | $OriginalErrorActionPreference = $ErrorActionPreference 74 | $ErrorActionPreference = 'Stop' 75 | 76 | # Important paths. 77 | $RootDir = Split-Path $PSScriptRoot -Parent 78 | . $RootDir\tools\common.ps1 79 | 80 | $ArtifactsDir = "$RootDir\artifacts\bin\$($Arch)_$($Config)" 81 | $TracePdb = Get-CoreNetCiArtifactPath -Name "tracepdb.exe" 82 | $WprpFile = "$RootDir\tools\fntrace.wprp" 83 | $TmfPath = "$ArtifactsDir\tmfs" 84 | $LogsDir = "$RootDir\artifacts\logs" 85 | 86 | & $RootDir/tools/prepare-machine.ps1 -ForLogging 87 | 88 | if (!$EtlPath) { 89 | $EtlPath = "$LogsDir\$Name.etl" 90 | } 91 | 92 | try { 93 | if ($Start) { 94 | if (!(Test-Path $WprpFile)) { 95 | Write-Error "$WprpFile does not exist!" 96 | } 97 | 98 | $LogArg = "" 99 | if ($LogMode -eq "File") { 100 | $LogArg = "-filemode" 101 | } 102 | 103 | Write-Verbose "wpr.exe -start $($WprpFile)!$($Profile) -instancename $Name $LogArg" 104 | cmd /c "wpr.exe -start `"$($WprpFile)!$($Profile)`" -instancename $Name $LogArg 2>&1" 105 | if ($LastExitCode -ne 0) { 106 | Write-Host "##vso[task.setvariable variable=NeedsReboot]true" 107 | Write-Error "wpr.exe failed: $LastExitCode" 108 | } 109 | } 110 | 111 | if ($Stop) { 112 | New-Item -ItemType Directory -Force -Path $LogsDir | Out-Null 113 | 114 | Write-Verbose "wpr.exe -stop $EtlPath -instancename $Name" 115 | cmd /c "wpr.exe -stop $EtlPath -instancename $Name 2>&1" 116 | if ($LastExitCode -ne 0) { 117 | Write-Host "##vso[task.setvariable variable=NeedsReboot]true" 118 | Write-Error "wpr.exe failed: $LastExitCode" 119 | } 120 | 121 | # Enumerate log file sizes. 122 | Get-ChildItem $LogsDir | Format-Table | Out-String | Write-Verbose 123 | } 124 | 125 | if ($Convert) { 126 | if (!(Get-ChildItem $EtlPath)) { 127 | Write-Error "$EtlPath does not exist!" 128 | } 129 | 130 | if (!$SymbolPath) { 131 | $SymbolPath = $ArtifactsDir 132 | } 133 | 134 | & $TracePdb -f "$SymbolPath\*.pdb" -p $TmfPath 135 | 136 | foreach ($Etl in Get-ChildItem $EtlPath) { 137 | Invoke-Expression "netsh trace convert $Etl tmfpath=$TmfPath overwrite=yes report=no" 138 | } 139 | } 140 | } catch { 141 | Write-Error $_ -ErrorAction $OriginalErrorActionPreference 142 | } 143 | -------------------------------------------------------------------------------- /tools/nuget/README.md: -------------------------------------------------------------------------------- 1 | # win-net-test NuGet Package 2 | 3 | This NuGet package includes all the headers, libraries, and debugger files 4 | needed to enable writing code that leverages the win-net-test tools. 5 | -------------------------------------------------------------------------------- /tools/nuget/win-net-test.nuspec.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | win-net-test SDK 5 | win-net-test 6 | {version} 7 | win-net-test Contributors 8 | win-net-test Contributors 9 | false 10 | MIT 11 | https://github.com/Microsoft/win-net-test 12 | 13 | native networking testing test 14 | win-net-test SDK 15 | README.md 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tools/nuget/win-net-test.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildThisFileDirectory)lib\$(Platform) 5 | $(MSBuildThisFileDirectory)bin\$(Platform) 6 | $(MSBuildThisFileDirectory)include 7 | 8 | 9 | 10 | %(AdditionalIncludeDirectories);$(WntIncPath) 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tools/prepare-onebranch-build.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Preparation script that runs before a OneBranch build. 3 | # 4 | # The preparation done in this script involves copying public include files to 5 | # the vpack directories so they get packaged in the vpack. 6 | # 7 | 8 | Set-StrictMode -Version 'Latest' 9 | $ErrorActionPreference = 'Stop' 10 | 11 | $RootDir = Split-Path $PSScriptRoot -Parent 12 | $BinDir = Join-Path $RootDir "artifacts\bin" 13 | $IncludeDir = Join-Path $RootDir "inc" 14 | 15 | $Configs = @("Debug", "Release") 16 | $Platforms = @("x64", "arm64") 17 | 18 | foreach ($Config in $Configs) { 19 | foreach ($Platform in $Platforms) { 20 | $VpackDir = Join-Path $BinDir "$($Platform)_$($Config)" 21 | New-Item -Path $VpackDir -ItemType Directory -Force | Out-Null 22 | Copy-Item $IncludeDir\* $VpackDir -Force | Out-Null 23 | Copy-Item $RootDir\tools\setup.ps1 $VpackDir -Force | Out-Null 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /version.json: -------------------------------------------------------------------------------- 1 | { "major": 1, "minor": 3, "patch": 0 } 2 | --------------------------------------------------------------------------------