├── .gitignore ├── HyperVPCapExt.sln ├── LICENSE ├── PCapExt ├── PCapExt.c ├── PCapExt.h ├── PCapExt.inf ├── PCapExt.rc ├── PCapExt.vcxproj ├── PCapExtBase.c ├── install.cmd ├── pcap.h ├── precomp.h ├── precompsrc.c ├── resource.h └── uninstall.cmd ├── Package ├── package.VcxProj └── package.VcxProj.Filters ├── README.md └── base ├── SxApi.h ├── SxBase.c ├── SxBase.h ├── SxLibrary.c ├── SxLibrary.h ├── license.rtf ├── precomp.h ├── precompsrc.c ├── sxbase.vcxproj └── sxbase.vcxproj.Filters /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | bld/ 16 | [Bb]in/ 17 | [Oo]bj/ 18 | 19 | # Roslyn cache directories 20 | *.ide 21 | 22 | # MSTest test Results 23 | [Tt]est[Rr]esult*/ 24 | [Bb]uild[Ll]og.* 25 | 26 | #NUNIT 27 | *.VisualState.xml 28 | TestResult.xml 29 | 30 | # Build Results of an ATL Project 31 | [Dd]ebugPS/ 32 | [Rr]eleasePS/ 33 | dlldata.c 34 | 35 | *_i.c 36 | *_p.c 37 | *_i.h 38 | *.ilk 39 | *.meta 40 | *.obj 41 | *.pch 42 | *.pdb 43 | *.pgc 44 | *.pgd 45 | *.rsp 46 | *.sbr 47 | *.tlb 48 | *.tli 49 | *.tlh 50 | *.tmp 51 | *.tmp_proj 52 | *.log 53 | *.vspscc 54 | *.vssscc 55 | .builds 56 | *.pidb 57 | *.svclog 58 | *.scc 59 | 60 | # Chutzpah Test files 61 | _Chutzpah* 62 | 63 | # Visual C++ cache files 64 | ipch/ 65 | *.aps 66 | *.ncb 67 | *.opensdf 68 | *.sdf 69 | *.cachefile 70 | 71 | # Visual Studio profiler 72 | *.psess 73 | *.vsp 74 | *.vspx 75 | 76 | # TFS 2012 Local Workspace 77 | $tf/ 78 | 79 | # Guidance Automation Toolkit 80 | *.gpState 81 | 82 | # ReSharper is a .NET coding add-in 83 | _ReSharper*/ 84 | *.[Rr]e[Ss]harper 85 | *.DotSettings.user 86 | 87 | # JustCode is a .NET coding addin-in 88 | .JustCode 89 | 90 | # TeamCity is a build add-in 91 | _TeamCity* 92 | 93 | # DotCover is a Code Coverage Tool 94 | *.dotCover 95 | 96 | # NCrunch 97 | _NCrunch_* 98 | .*crunch*.local.xml 99 | 100 | # MightyMoose 101 | *.mm.* 102 | AutoTest.Net/ 103 | 104 | # Web workbench (sass) 105 | .sass-cache/ 106 | 107 | # Installshield output folder 108 | [Ee]xpress/ 109 | 110 | # DocProject is a documentation generator add-in 111 | DocProject/buildhelp/ 112 | DocProject/Help/*.HxT 113 | DocProject/Help/*.HxC 114 | DocProject/Help/*.hhc 115 | DocProject/Help/*.hhk 116 | DocProject/Help/*.hhp 117 | DocProject/Help/Html2 118 | DocProject/Help/html 119 | 120 | # Click-Once directory 121 | publish/ 122 | 123 | # Publish Web Output 124 | *.[Pp]ublish.xml 125 | *.azurePubxml 126 | ## TODO: Comment the next line if you want to checkin your web deploy settings but do note that will include unencrypted passwords 127 | *.pubxml 128 | 129 | # NuGet Packages Directory 130 | packages/* 131 | ## TODO: If the tool you use requires repositories.config uncomment the next line 132 | #!packages/repositories.config 133 | 134 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 135 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 136 | !packages/build/ 137 | 138 | # Windows Azure Build Output 139 | csx/ 140 | *.build.csdef 141 | 142 | # Windows Store app package directory 143 | AppPackages/ 144 | 145 | # Others 146 | sql/ 147 | *.Cache 148 | ClientBin/ 149 | [Ss]tyle[Cc]op.* 150 | ~$* 151 | *~ 152 | *.dbmdl 153 | *.dbproj.schemaview 154 | *.pfx 155 | *.publishsettings 156 | node_modules/ 157 | 158 | # RIA/Silverlight projects 159 | Generated_Code/ 160 | 161 | # Backup & report files from converting an old project file to a newer 162 | # Visual Studio version. Backup files are not needed, because we have git ;-) 163 | _UpgradeReport_Files/ 164 | Backup*/ 165 | UpgradeLog*.XML 166 | UpgradeLog*.htm 167 | 168 | # SQL Server files 169 | *.mdf 170 | *.ldf 171 | 172 | # Business Intelligence projects 173 | *.rdl.data 174 | *.bim.layout 175 | *.bim_*.settings 176 | 177 | # Microsoft Fakes 178 | FakesAssemblies/ 179 | -------------------------------------------------------------------------------- /HyperVPCapExt.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30501.0 5 | MinimumVisualStudioVersion = 12.0 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{9B04D8FB-E65F-4462-8EFE-E5F1F1DE6256}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Base", "Base", "{B38BD8B1-99E3-40C3-9C7D-70ACBA733008}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}" 11 | ProjectSection(ProjectDependencies) = postProject 12 | {33806260-1507-469E-BA3A-6BB73CD75C0D} = {33806260-1507-469E-BA3A-6BB73CD75C0D} 13 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5} = {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5} 14 | EndProjectSection 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sxbase", "base\sxbase.vcxproj", "{33806260-1507-469E-BA3A-6BB73CD75C0D}" 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PCapExt", "PCapExt\PCapExt.vcxproj", "{1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}" 19 | ProjectSection(ProjectDependencies) = postProject 20 | {33806260-1507-469E-BA3A-6BB73CD75C0D} = {33806260-1507-469E-BA3A-6BB73CD75C0D} 21 | EndProjectSection 22 | EndProject 23 | Global 24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 25 | Win8 Debug|x64 = Win8 Debug|x64 26 | Win8 Release|x64 = Win8 Release|x64 27 | Win8.1 Debug|x64 = Win8.1 Debug|x64 28 | Win8.1 Release|x64 = Win8.1 Release|x64 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 32 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 33 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 34 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}.Win8 Release|x64.Build.0 = Win8 Release|x64 35 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 36 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 37 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 38 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 39 | {33806260-1507-469E-BA3A-6BB73CD75C0D}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 40 | {33806260-1507-469E-BA3A-6BB73CD75C0D}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 41 | {33806260-1507-469E-BA3A-6BB73CD75C0D}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 42 | {33806260-1507-469E-BA3A-6BB73CD75C0D}.Win8 Release|x64.Build.0 = Win8 Release|x64 43 | {33806260-1507-469E-BA3A-6BB73CD75C0D}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 44 | {33806260-1507-469E-BA3A-6BB73CD75C0D}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 45 | {33806260-1507-469E-BA3A-6BB73CD75C0D}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 46 | {33806260-1507-469E-BA3A-6BB73CD75C0D}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 47 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 48 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 49 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 50 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 51 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8 Release|x64.Build.0 = Win8 Release|x64 52 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 53 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 54 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 55 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 56 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 57 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 58 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 59 | EndGlobalSection 60 | GlobalSection(SolutionProperties) = preSolution 61 | HideSolutionNode = FALSE 62 | EndGlobalSection 63 | GlobalSection(NestedProjects) = preSolution 64 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9} = {9B04D8FB-E65F-4462-8EFE-E5F1F1DE6256} 65 | {33806260-1507-469E-BA3A-6BB73CD75C0D} = {B38BD8B1-99E3-40C3-9C7D-70ACBA733008} 66 | EndGlobalSection 67 | EndGlobal 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | -------------------------------------------------------------------------------- /PCapExt/PCapExt.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright(c) Cloudbase Solutions Srl.All Rights Reserved. 3 | */ 4 | 5 | #include "precomp.h" 6 | #include "pcap.h" 7 | 8 | HANDLE g_CaptureFileHandle; 9 | ERESOURCE g_CaptureFileResource; 10 | 11 | #define EPOCH_OFFSET 11644473600 12 | #define BUFFER_SIZE 30 13 | 14 | // TODO: must be configurable. For the time being it works only if C:\ exists and is writable 15 | // Alternative hardcoded path: "\\SystemRoot\\PCapExt.pcap 16 | #define PCAP_FILE L"\\DosDevices\\C:\\PCapExt.pcap" 17 | 18 | extern NDIS_HANDLE SxDriverObject; 19 | 20 | typedef struct PcapRecordWorkItemData_s 21 | { 22 | PIO_WORKITEM pWorkItem; 23 | ULONG BufferLen; 24 | void* Buffer; 25 | } PcapRecordWorkItemData; 26 | 27 | 28 | VOID InitPcapCapture() 29 | { 30 | ExInitializeResourceLite(&g_CaptureFileResource); 31 | } 32 | 33 | VOID EndPcapCapture() 34 | { 35 | ExDeleteResourceLite(&g_CaptureFileResource); 36 | } 37 | 38 | VOID CreatePcapCaptureFile() 39 | { 40 | UNICODE_STRING uniName; 41 | OBJECT_ATTRIBUTES objAttr; 42 | NTSTATUS ntstatus; 43 | IO_STATUS_BLOCK ioStatusBlock; 44 | HANDLE handle; 45 | pcap_hdr_t pcapHeader; 46 | 47 | RtlInitUnicodeString(&uniName, PCAP_FILE); 48 | InitializeObjectAttributes(&objAttr, &uniName, 49 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 50 | NULL, NULL); 51 | 52 | ntstatus = ZwCreateFile(&handle, 53 | GENERIC_WRITE | SYNCHRONIZE, 54 | &objAttr, &ioStatusBlock, NULL, 55 | FILE_ATTRIBUTE_NORMAL, 56 | FILE_SHARE_READ, 57 | FILE_OVERWRITE_IF, 58 | FILE_SYNCHRONOUS_IO_NONALERT | FILE_WRITE_THROUGH, 59 | NULL, 0); 60 | 61 | if (NT_SUCCESS(ntstatus)) { 62 | pcapHeader.magic_number = PCAP_MAGIC_NUMBER; 63 | pcapHeader.version_major = PCAP_VERSION_MAJOR; 64 | pcapHeader.version_minor = PCAP_VERSION_MINOR; 65 | pcapHeader.thiszone = 0; 66 | pcapHeader.sigfigs = 0; 67 | pcapHeader.snaplen = 65535; 68 | pcapHeader.network = 1; // Ethernet 69 | 70 | ntstatus = ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock, &pcapHeader, 71 | (ULONG)sizeof(pcap_hdr_t), NULL, NULL); 72 | 73 | if (NT_SUCCESS(ntstatus)) 74 | g_CaptureFileHandle = handle; 75 | else 76 | ZwClose(handle); 77 | } 78 | else 79 | { 80 | // Ignore for now 81 | } 82 | } 83 | 84 | VOID ClosePcapCaptureFile() 85 | { 86 | KeEnterCriticalRegion(); 87 | ExAcquireResourceExclusiveLite(&g_CaptureFileResource, TRUE); 88 | 89 | if (g_CaptureFileHandle) 90 | { 91 | ZwClose(g_CaptureFileHandle); 92 | g_CaptureFileHandle = NULL; 93 | } 94 | 95 | ExReleaseResourceLite(&g_CaptureFileResource); 96 | KeLeaveCriticalRegion(); 97 | } 98 | 99 | VOID WritePcapRecordWorkItem(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context) 100 | { 101 | UNREFERENCED_PARAMETER(DeviceObject); 102 | 103 | IO_STATUS_BLOCK ioStatusBlock = { 0 }; 104 | PcapRecordWorkItemData* pPcapRecordWorkItemData = Context; 105 | 106 | KeEnterCriticalRegion(); 107 | ExAcquireResourceExclusiveLite(&g_CaptureFileResource, TRUE); 108 | 109 | // Ignore write errors 110 | if (g_CaptureFileHandle) 111 | ZwWriteFile(g_CaptureFileHandle, NULL, NULL, NULL, &ioStatusBlock, 112 | pPcapRecordWorkItemData->Buffer, 113 | pPcapRecordWorkItemData->BufferLen, NULL, NULL); 114 | 115 | ExReleaseResourceLite(&g_CaptureFileResource); 116 | KeLeaveCriticalRegion(); 117 | 118 | IoFreeWorkItem(pPcapRecordWorkItemData->pWorkItem); 119 | ExFreePool(pPcapRecordWorkItemData); 120 | } 121 | 122 | VOID WindowsToEpochTime(PLARGE_INTEGER CurrentTime, PULONG EpochSeconds, PULONG MicroSeconds) 123 | { 124 | *EpochSeconds = (ULONG)(CurrentTime->QuadPart / 10000000); 125 | *MicroSeconds = (ULONG)((CurrentTime->QuadPart % 10000000) / 10); 126 | *EpochSeconds = (ULONG)(*EpochSeconds - EPOCH_OFFSET); 127 | } 128 | 129 | VOID DecodeNetBufferListAndQueueForPCap(PNET_BUFFER_LIST NetBufferLists) 130 | { 131 | NET_BUFFER* netBuffer = NULL; 132 | ULONG dataLength = 0; 133 | PcapRecordWorkItemData* pPcapRecordWorkItemData = NULL; 134 | pcaprec_hdr_t* pPcapRecHeader = NULL; 135 | void* data = NULL; 136 | void* dataStorage = NULL; 137 | LARGE_INTEGER currentTime = { 0 }; 138 | ULONG epochSeconds = 0; 139 | ULONG microSeconds = 0; 140 | PIO_WORKITEM pWorkItem = NULL; 141 | 142 | if (g_CaptureFileHandle) 143 | { 144 | netBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferLists); 145 | 146 | KeQuerySystemTime(¤tTime); 147 | WindowsToEpochTime(¤tTime, &epochSeconds, µSeconds); 148 | 149 | while (netBuffer != NULL) 150 | { 151 | dataLength = NET_BUFFER_DATA_LENGTH(netBuffer); 152 | if (dataLength) 153 | { 154 | pPcapRecordWorkItemData = ExAllocatePoolWithTag(NonPagedPoolNx, 155 | sizeof(PcapRecordWorkItemData) + sizeof(pcaprec_hdr_t) + dataLength, 156 | SxExtAllocationTag); 157 | NT_ASSERT(pPcapRecordWorkItemData); 158 | 159 | pPcapRecordWorkItemData->BufferLen = sizeof(pcaprec_hdr_t) + dataLength; 160 | pPcapRecordWorkItemData->Buffer = (char*)pPcapRecordWorkItemData + sizeof(PcapRecordWorkItemData); 161 | 162 | pPcapRecHeader = pPcapRecordWorkItemData->Buffer; 163 | pPcapRecHeader->ts_sec = epochSeconds; 164 | pPcapRecHeader->ts_usec = microSeconds; 165 | pPcapRecHeader->incl_len = dataLength; 166 | pPcapRecHeader->orig_len = dataLength; 167 | 168 | dataStorage = (char*)pPcapRecordWorkItemData->Buffer + sizeof(pcaprec_hdr_t); 169 | data = NdisGetDataBuffer(netBuffer, dataLength, dataStorage, 1, 0); 170 | if (data) 171 | { 172 | if (data != dataStorage) 173 | RtlCopyMemory(dataStorage, data, dataLength); 174 | 175 | pWorkItem = IoAllocateWorkItem(SxDriverObject); 176 | NT_ASSERT(pWorkItem); 177 | 178 | pPcapRecordWorkItemData->pWorkItem = pWorkItem; 179 | IoQueueWorkItem(pWorkItem, WritePcapRecordWorkItem, DelayedWorkQueue, pPcapRecordWorkItemData); 180 | } 181 | else 182 | { 183 | ExFreePool(pPcapRecordWorkItemData); 184 | pPcapRecordWorkItemData = NULL; 185 | } 186 | } 187 | 188 | netBuffer = NET_BUFFER_NEXT_NB(netBuffer); 189 | } 190 | } 191 | } -------------------------------------------------------------------------------- /PCapExt/PCapExt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | VOID InitPcapCapture(); 6 | VOID EndPcapCapture(); 7 | VOID CreatePcapCaptureFile(); 8 | VOID ClosePcapCaptureFile(); 9 | VOID WritePcapRecordWorkItem(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context); 10 | VOID WindowsToEpochTime(PLARGE_INTEGER CurrentTime, PULONG EpochSeconds, PULONG MicroSeconds); 11 | VOID DecodeNetBufferListAndQueueForPCap(PNET_BUFFER_LIST NetBufferLists); 12 | -------------------------------------------------------------------------------- /PCapExt/PCapExt.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) Cloudbase Solutions Srl. All Rights Reserved. 3 | ; 4 | 5 | [version] 6 | Signature = "$Windows NT$" 7 | Class = NetService 8 | ClassGUID = {4D36E974-E325-11CE-BFC1-08002BE10318} 9 | Provider = %Msft% 10 | CatalogFile = PCapExt.cat 11 | DriverVer = 05/30/2014,1.0 12 | 13 | [Manufacturer] 14 | %Msft%=MSFT,NTx86,NTia64,NTamd64 15 | 16 | [MSFT.NTx86] 17 | %PCapExt_Desc%=Install, PCapExt 18 | 19 | [MSFT.NTia64] 20 | %PCapExt_Desc%=Install, PCapExt 21 | 22 | [MSFT.NTamd64] 23 | %PCapExt_Desc%=Install, PCapExt 24 | 25 | ;------------------------------------------------------------------------- 26 | ; Installation Section 27 | ;------------------------------------------------------------------------- 28 | [Install] 29 | AddReg=Inst_Ndi 30 | Characteristics=0x40000 31 | NetCfgInstanceId="{9D283D4B-2343-42E2-98C8-2D0511169E8D}" 32 | Copyfiles = PCapExt.copyfiles.sys 33 | 34 | [SourceDisksNames] 35 | 1=%PCapExt_Desc%,"",, 36 | 37 | [SourceDisksFiles] 38 | PCapExt.sys=1 39 | 40 | [DestinationDirs] 41 | DefaultDestDir=12 42 | PCapExt.copyfiles.sys=12 43 | 44 | [PCapExt.copyfiles.sys] 45 | PCapExt.sys,,,2 46 | 47 | 48 | ;------------------------------------------------------------------------- 49 | ; Ndi installation support 50 | ;------------------------------------------------------------------------- 51 | [Inst_Ndi] 52 | HKR, Ndi,Service,,"PCapExt" 53 | HKR, Ndi,CoServices,0x00010000,"PCapExt" 54 | HKR, Ndi,HelpText,,%PCapExt_HelpText% 55 | HKR, Ndi,FilterClass,,"ms_switch_capture" 56 | HKR, Ndi,FilterType,0x00010001,0x00000002 57 | HKR, Ndi\Interfaces,UpperRange,,"noupper" 58 | HKR, Ndi\Interfaces,LowerRange,,"nolower" 59 | HKR, Ndi\Interfaces, FilterMediaTypes,,"vmnetextension" 60 | HKR, Ndi,FilterRunType, 0x00010001, 2 ; optional 61 | 62 | ;------------------------------------------------------------------------- 63 | ; Service installation support, common.EventLog here is to demonstrate how to 64 | ; write an enent log 65 | ;------------------------------------------------------------------------- 66 | [Install.Services] 67 | AddService=PCapExt,,PCapExt_Service_Inst;, common.EventLog 68 | 69 | [PCapExt_Service_Inst] 70 | DisplayName = %PCapExt_Desc% 71 | ServiceType = 1 ;SERVICE_KERNEL_DRIVER 72 | StartType = 1 ;SERVICE_SYSTEM_START 73 | ErrorControl = 1 ;SERVICE_ERROR_NORMAL 74 | ServiceBinary = %12%\PCapExt.sys 75 | LoadOrderGroup = NDIS 76 | Description = %PCapExt_Desc% 77 | AddReg = Common.Params.reg 78 | 79 | [Install.Remove.Services] 80 | DelService=PCapExt,0x200 81 | 82 | [Strings] 83 | Msft = "Cloudbase Solutions Srl" 84 | PCapExt_Desc = "Hyper-V packet capture extension" 85 | PCapExt_HelpText = "Captured packets are available in libpcap format" 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /PCapExt/PCapExt.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudbase/HyperVPCapExt/5fe966cc64a1b658252d7c3dd2459905b87babc5/PCapExt/PCapExt.rc -------------------------------------------------------------------------------- /PCapExt/PCapExt.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Win8.1 Debug 6 | x64 7 | 8 | 9 | Win8 Debug 10 | x64 11 | 12 | 13 | Win8.1 Release 14 | x64 15 | 16 | 17 | Win8 Release 18 | x64 19 | 20 | 21 | 22 | {1FFAFEA1-AA92-48B0-BAFA-429C90C7B3C5} 23 | $(MSBuildProjectName) 24 | Win8.1 Debug 25 | x64 26 | {BC60F12B-3B29-47F9-AFFF-5598332010C2} 27 | 28 | 29 | 30 | Win8 31 | False 32 | WDM 33 | WindowsKernelModeDriver8.1 34 | Driver 35 | 36 | 37 | WindowsV6.3 38 | False 39 | WDM 40 | WindowsKernelModeDriver8.1 41 | Driver 42 | 43 | 44 | Win8 45 | True 46 | WDM 47 | WindowsKernelModeDriver8.1 48 | Driver 49 | 50 | 51 | WindowsV6.3 52 | True 53 | WDM 54 | WindowsKernelModeDriver8.1 55 | Driver 56 | 57 | 58 | 59 | $(IntDir) 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | PCapExt 76 | 77 | 78 | PCapExt 79 | 80 | 81 | PCapExt 82 | 83 | 84 | PCapExt 85 | 86 | 87 | 88 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 89 | 90 | 91 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 92 | 93 | 94 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 95 | 96 | 97 | 98 | 99 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 100 | 101 | 102 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 103 | 104 | 105 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 106 | 107 | 108 | 109 | 110 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 111 | 112 | 113 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 114 | 115 | 116 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 117 | 118 | 119 | 120 | 121 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 122 | 123 | 124 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 125 | 126 | 127 | %(PreprocessorDefinitions);NDIS_WDM=1;NDIS630=1 128 | 129 | 130 | 131 | 132 | %(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;.\..\base\$(IntDir)\sxbase.lib 133 | 134 | 135 | true 136 | Level4 137 | 138 | 139 | 140 | 141 | 142 | 143 | %(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;.\..\base\$(IntDir)\sxbase.lib 144 | 145 | 146 | true 147 | Level4 148 | 149 | 150 | 151 | 152 | 153 | 154 | %(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;.\..\base\$(IntDir)\sxbase.lib 155 | 156 | 157 | true 158 | Level4 159 | 160 | 161 | 162 | 163 | 164 | 165 | %(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib;.\..\base\$(IntDir)\sxbase.lib 166 | 167 | 168 | true 169 | Level4 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | ;%(AdditionalIncludeDirectories) 178 | precomp.h 179 | Use 180 | $(IntDir)\precomp.h.pch 181 | 182 | 183 | ;%(AdditionalIncludeDirectories) 184 | precomp.h 185 | Create 186 | $(IntDir)\precomp.h.pch 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | false 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | -------------------------------------------------------------------------------- /PCapExt/PCapExtBase.c: -------------------------------------------------------------------------------- 1 | #include "precomp.h" 2 | #include "PCapExt.h" 3 | 4 | UCHAR SxExtMajorNdisVersion = NDIS_FILTER_MAJOR_VERSION; 5 | UCHAR SxExtMinorNdisVersion = NDIS_FILTER_MINOR_VERSION; 6 | PWCHAR SxExtFriendlyName = L"Hyper-V packet capture extension"; 7 | PWCHAR SxExtUniqueName = L"{9D283D4B-2343-42E2-98C8-2D0511169E8D}"; 8 | PWCHAR SxExtServiceName = L"PCapExt"; 9 | ULONG SxExtAllocationTag = 'paCP'; 10 | ULONG SxExtOidRequestId = 'paCP'; 11 | 12 | 13 | NDIS_STATUS 14 | SxExtInitialize() 15 | { 16 | InitPcapCapture(); 17 | CreatePcapCaptureFile(); 18 | return NDIS_STATUS_SUCCESS; 19 | } 20 | 21 | 22 | VOID 23 | SxExtUninitialize() 24 | { 25 | ClosePcapCaptureFile(); 26 | EndPcapCapture(); 27 | return; 28 | } 29 | 30 | 31 | _Use_decl_annotations_ 32 | NDIS_STATUS 33 | SxExtCreateSwitch( 34 | PSX_SWITCH_OBJECT Switch, 35 | PNDIS_HANDLE *ExtensionContext 36 | ) 37 | { 38 | UNREFERENCED_PARAMETER(Switch); 39 | 40 | *ExtensionContext = NULL; 41 | return NDIS_STATUS_SUCCESS; 42 | } 43 | 44 | 45 | _Use_decl_annotations_ 46 | VOID 47 | SxExtDeleteSwitch( 48 | PSX_SWITCH_OBJECT Switch, 49 | NDIS_HANDLE ExtensionContext 50 | ) 51 | { 52 | UNREFERENCED_PARAMETER(Switch); 53 | UNREFERENCED_PARAMETER(ExtensionContext); 54 | 55 | return; 56 | } 57 | 58 | 59 | _Use_decl_annotations_ 60 | VOID 61 | SxExtActivateSwitch( 62 | PSX_SWITCH_OBJECT Switch, 63 | NDIS_HANDLE ExtensionContext 64 | ) 65 | { 66 | UNREFERENCED_PARAMETER(Switch); 67 | UNREFERENCED_PARAMETER(ExtensionContext); 68 | 69 | return; 70 | } 71 | 72 | 73 | _Use_decl_annotations_ 74 | NDIS_STATUS 75 | SxExtRestartSwitch( 76 | PSX_SWITCH_OBJECT Switch, 77 | NDIS_HANDLE ExtensionContext 78 | ) 79 | { 80 | UNREFERENCED_PARAMETER(Switch); 81 | UNREFERENCED_PARAMETER(ExtensionContext); 82 | 83 | return NDIS_STATUS_SUCCESS; 84 | } 85 | 86 | 87 | _Use_decl_annotations_ 88 | VOID 89 | SxExtPauseSwitch( 90 | PSX_SWITCH_OBJECT Switch, 91 | NDIS_HANDLE ExtensionContext 92 | ) 93 | { 94 | UNREFERENCED_PARAMETER(Switch); 95 | UNREFERENCED_PARAMETER(ExtensionContext); 96 | 97 | return; 98 | } 99 | 100 | 101 | _Use_decl_annotations_ 102 | NDIS_STATUS 103 | SxExtCreatePort( 104 | PSX_SWITCH_OBJECT Switch, 105 | NDIS_HANDLE ExtensionContext, 106 | PNDIS_SWITCH_PORT_PARAMETERS Port 107 | ) 108 | { 109 | UNREFERENCED_PARAMETER(Switch); 110 | UNREFERENCED_PARAMETER(ExtensionContext); 111 | UNREFERENCED_PARAMETER(Port); 112 | 113 | return NDIS_STATUS_SUCCESS; 114 | } 115 | 116 | 117 | _Use_decl_annotations_ 118 | VOID 119 | SxExtUpdatePort( 120 | PSX_SWITCH_OBJECT Switch, 121 | NDIS_HANDLE ExtensionContext, 122 | PNDIS_SWITCH_PORT_PARAMETERS Port 123 | ) 124 | { 125 | UNREFERENCED_PARAMETER(Switch); 126 | UNREFERENCED_PARAMETER(ExtensionContext); 127 | UNREFERENCED_PARAMETER(Port); 128 | 129 | return; 130 | } 131 | 132 | 133 | _Use_decl_annotations_ 134 | NDIS_STATUS 135 | SxExtCreateNic( 136 | PSX_SWITCH_OBJECT Switch, 137 | NDIS_HANDLE ExtensionContext, 138 | PNDIS_SWITCH_NIC_PARAMETERS Nic 139 | ) 140 | { 141 | UNREFERENCED_PARAMETER(Switch); 142 | UNREFERENCED_PARAMETER(ExtensionContext); 143 | UNREFERENCED_PARAMETER(Nic); 144 | 145 | return NDIS_STATUS_SUCCESS; 146 | } 147 | 148 | 149 | _Use_decl_annotations_ 150 | VOID 151 | SxExtConnectNic( 152 | PSX_SWITCH_OBJECT Switch, 153 | NDIS_HANDLE ExtensionContext, 154 | PNDIS_SWITCH_NIC_PARAMETERS Nic 155 | ) 156 | { 157 | UNREFERENCED_PARAMETER(Switch); 158 | UNREFERENCED_PARAMETER(ExtensionContext); 159 | UNREFERENCED_PARAMETER(Nic); 160 | 161 | return; 162 | } 163 | 164 | 165 | _Use_decl_annotations_ 166 | VOID 167 | SxExtUpdateNic( 168 | PSX_SWITCH_OBJECT Switch, 169 | NDIS_HANDLE ExtensionContext, 170 | PNDIS_SWITCH_NIC_PARAMETERS Nic 171 | ) 172 | { 173 | UNREFERENCED_PARAMETER(Switch); 174 | UNREFERENCED_PARAMETER(ExtensionContext); 175 | UNREFERENCED_PARAMETER(Nic); 176 | 177 | return; 178 | } 179 | 180 | 181 | _Use_decl_annotations_ 182 | VOID 183 | SxExtDisconnectNic( 184 | PSX_SWITCH_OBJECT Switch, 185 | NDIS_HANDLE ExtensionContext, 186 | PNDIS_SWITCH_NIC_PARAMETERS Nic 187 | ) 188 | { 189 | UNREFERENCED_PARAMETER(Switch); 190 | UNREFERENCED_PARAMETER(ExtensionContext); 191 | UNREFERENCED_PARAMETER(Nic); 192 | 193 | return; 194 | } 195 | 196 | 197 | _Use_decl_annotations_ 198 | VOID 199 | SxExtDeleteNic( 200 | PSX_SWITCH_OBJECT Switch, 201 | NDIS_HANDLE ExtensionContext, 202 | PNDIS_SWITCH_NIC_PARAMETERS Nic 203 | ) 204 | { 205 | UNREFERENCED_PARAMETER(Switch); 206 | UNREFERENCED_PARAMETER(ExtensionContext); 207 | UNREFERENCED_PARAMETER(Nic); 208 | 209 | return; 210 | } 211 | 212 | 213 | _Use_decl_annotations_ 214 | VOID 215 | SxExtTeardownPort( 216 | PSX_SWITCH_OBJECT Switch, 217 | NDIS_HANDLE ExtensionContext, 218 | PNDIS_SWITCH_PORT_PARAMETERS Port 219 | ) 220 | { 221 | UNREFERENCED_PARAMETER(Switch); 222 | UNREFERENCED_PARAMETER(ExtensionContext); 223 | UNREFERENCED_PARAMETER(Port); 224 | 225 | return; 226 | } 227 | 228 | 229 | _Use_decl_annotations_ 230 | VOID 231 | SxExtDeletePort( 232 | PSX_SWITCH_OBJECT Switch, 233 | NDIS_HANDLE ExtensionContext, 234 | PNDIS_SWITCH_PORT_PARAMETERS Port 235 | ) 236 | { 237 | UNREFERENCED_PARAMETER(Switch); 238 | UNREFERENCED_PARAMETER(ExtensionContext); 239 | UNREFERENCED_PARAMETER(Port); 240 | 241 | return; 242 | } 243 | 244 | 245 | _Use_decl_annotations_ 246 | NDIS_STATUS 247 | SxExtSaveNic( 248 | PSX_SWITCH_OBJECT Switch, 249 | NDIS_HANDLE ExtensionContext, 250 | PNDIS_SWITCH_NIC_SAVE_STATE SaveState, 251 | PULONG BytesWritten, 252 | PULONG BytesNeeded 253 | ) 254 | { 255 | UNREFERENCED_PARAMETER(Switch); 256 | UNREFERENCED_PARAMETER(ExtensionContext); 257 | UNREFERENCED_PARAMETER(SaveState); 258 | 259 | *BytesWritten = 0; 260 | *BytesNeeded = 0; 261 | return NDIS_STATUS_SUCCESS; 262 | } 263 | 264 | 265 | _Use_decl_annotations_ 266 | VOID 267 | SxExtSaveNicComplete( 268 | PSX_SWITCH_OBJECT Switch, 269 | NDIS_HANDLE ExtensionContext, 270 | PNDIS_SWITCH_NIC_SAVE_STATE SaveState 271 | ) 272 | { 273 | UNREFERENCED_PARAMETER(Switch); 274 | UNREFERENCED_PARAMETER(ExtensionContext); 275 | UNREFERENCED_PARAMETER(SaveState); 276 | 277 | return; 278 | } 279 | 280 | 281 | _Use_decl_annotations_ 282 | NDIS_STATUS 283 | SxExtNicRestore( 284 | PSX_SWITCH_OBJECT Switch, 285 | NDIS_HANDLE ExtensionContext, 286 | PNDIS_SWITCH_NIC_SAVE_STATE SaveState, 287 | PULONG BytesRestored 288 | ) 289 | { 290 | UNREFERENCED_PARAMETER(Switch); 291 | UNREFERENCED_PARAMETER(ExtensionContext); 292 | UNREFERENCED_PARAMETER(SaveState); 293 | 294 | *BytesRestored = 0; 295 | return NDIS_STATUS_SUCCESS; 296 | } 297 | 298 | 299 | _Use_decl_annotations_ 300 | VOID 301 | SxExtNicRestoreComplete( 302 | PSX_SWITCH_OBJECT Switch, 303 | NDIS_HANDLE ExtensionContext, 304 | PNDIS_SWITCH_NIC_SAVE_STATE SaveState 305 | ) 306 | { 307 | UNREFERENCED_PARAMETER(Switch); 308 | UNREFERENCED_PARAMETER(ExtensionContext); 309 | UNREFERENCED_PARAMETER(SaveState); 310 | 311 | return; 312 | } 313 | 314 | 315 | _Use_decl_annotations_ 316 | NDIS_STATUS 317 | SxExtAddSwitchProperty( 318 | PSX_SWITCH_OBJECT Switch, 319 | NDIS_HANDLE ExtensionContext, 320 | PNDIS_SWITCH_PROPERTY_PARAMETERS SwitchProperty 321 | ) 322 | { 323 | UNREFERENCED_PARAMETER(Switch); 324 | UNREFERENCED_PARAMETER(ExtensionContext); 325 | UNREFERENCED_PARAMETER(SwitchProperty); 326 | 327 | return NDIS_STATUS_NOT_SUPPORTED; 328 | } 329 | 330 | 331 | _Use_decl_annotations_ 332 | NDIS_STATUS 333 | SxExtUpdateSwitchProperty( 334 | PSX_SWITCH_OBJECT Switch, 335 | NDIS_HANDLE ExtensionContext, 336 | PNDIS_SWITCH_PROPERTY_PARAMETERS SwitchProperty 337 | ) 338 | { 339 | UNREFERENCED_PARAMETER(Switch); 340 | UNREFERENCED_PARAMETER(ExtensionContext); 341 | UNREFERENCED_PARAMETER(SwitchProperty); 342 | 343 | return NDIS_STATUS_NOT_SUPPORTED; 344 | } 345 | 346 | 347 | _Use_decl_annotations_ 348 | BOOLEAN 349 | SxExtDeleteSwitchProperty( 350 | PSX_SWITCH_OBJECT Switch, 351 | NDIS_HANDLE ExtensionContext, 352 | PNDIS_SWITCH_PROPERTY_DELETE_PARAMETERS SwitchProperty 353 | ) 354 | { 355 | UNREFERENCED_PARAMETER(Switch); 356 | UNREFERENCED_PARAMETER(ExtensionContext); 357 | UNREFERENCED_PARAMETER(SwitchProperty); 358 | 359 | return FALSE; 360 | } 361 | 362 | 363 | _Use_decl_annotations_ 364 | NDIS_STATUS 365 | SxExtAddPortProperty( 366 | PSX_SWITCH_OBJECT Switch, 367 | NDIS_HANDLE ExtensionContext, 368 | PNDIS_SWITCH_PORT_PROPERTY_PARAMETERS PortProperty 369 | ) 370 | { 371 | UNREFERENCED_PARAMETER(Switch); 372 | UNREFERENCED_PARAMETER(ExtensionContext); 373 | UNREFERENCED_PARAMETER(PortProperty); 374 | 375 | return NDIS_STATUS_NOT_SUPPORTED; 376 | } 377 | 378 | 379 | _Use_decl_annotations_ 380 | NDIS_STATUS 381 | SxExtUpdatePortProperty( 382 | PSX_SWITCH_OBJECT Switch, 383 | NDIS_HANDLE ExtensionContext, 384 | PNDIS_SWITCH_PORT_PROPERTY_PARAMETERS PortProperty 385 | ) 386 | { 387 | UNREFERENCED_PARAMETER(Switch); 388 | UNREFERENCED_PARAMETER(ExtensionContext); 389 | UNREFERENCED_PARAMETER(PortProperty); 390 | 391 | return NDIS_STATUS_NOT_SUPPORTED; 392 | } 393 | 394 | 395 | _Use_decl_annotations_ 396 | BOOLEAN 397 | SxExtDeletePortProperty( 398 | PSX_SWITCH_OBJECT Switch, 399 | NDIS_HANDLE ExtensionContext, 400 | PNDIS_SWITCH_PORT_PROPERTY_DELETE_PARAMETERS PortProperty 401 | ) 402 | { 403 | UNREFERENCED_PARAMETER(Switch); 404 | UNREFERENCED_PARAMETER(ExtensionContext); 405 | UNREFERENCED_PARAMETER(PortProperty); 406 | 407 | return FALSE; 408 | } 409 | 410 | 411 | _Use_decl_annotations_ 412 | BOOLEAN 413 | SxExtQuerySwitchFeatureStatus( 414 | PSX_SWITCH_OBJECT Switch, 415 | NDIS_HANDLE ExtensionContext, 416 | PNDIS_SWITCH_FEATURE_STATUS_PARAMETERS SwitchFeatureStatus, 417 | PULONG BytesNeeded 418 | ) 419 | { 420 | UNREFERENCED_PARAMETER(Switch); 421 | UNREFERENCED_PARAMETER(ExtensionContext); 422 | UNREFERENCED_PARAMETER(SwitchFeatureStatus); 423 | UNREFERENCED_PARAMETER(BytesNeeded); 424 | 425 | return FALSE; 426 | } 427 | 428 | 429 | _Use_decl_annotations_ 430 | BOOLEAN 431 | SxExtQueryPortFeatureStatus( 432 | PSX_SWITCH_OBJECT Switch, 433 | NDIS_HANDLE ExtensionContext, 434 | PNDIS_SWITCH_PORT_FEATURE_STATUS_PARAMETERS PortFeatureStatus, 435 | PULONG BytesNeeded 436 | ) 437 | { 438 | UNREFERENCED_PARAMETER(Switch); 439 | UNREFERENCED_PARAMETER(ExtensionContext); 440 | UNREFERENCED_PARAMETER(PortFeatureStatus); 441 | UNREFERENCED_PARAMETER(BytesNeeded); 442 | 443 | return FALSE; 444 | } 445 | 446 | 447 | _Use_decl_annotations_ 448 | NDIS_STATUS 449 | SxExtProcessNicRequest( 450 | PSX_SWITCH_OBJECT Switch, 451 | NDIS_HANDLE ExtensionContext, 452 | PNDIS_OID_REQUEST OidRequest, 453 | PNDIS_SWITCH_PORT_ID SourcePortId, 454 | PNDIS_SWITCH_NIC_INDEX SourceNicIndex, 455 | PNDIS_SWITCH_PORT_ID DestinationPortId, 456 | PNDIS_SWITCH_NIC_INDEX DestinationNicIndex 457 | ) 458 | { 459 | UNREFERENCED_PARAMETER(Switch); 460 | UNREFERENCED_PARAMETER(ExtensionContext); 461 | UNREFERENCED_PARAMETER(OidRequest); 462 | UNREFERENCED_PARAMETER(SourcePortId); 463 | UNREFERENCED_PARAMETER(SourceNicIndex); 464 | UNREFERENCED_PARAMETER(DestinationPortId); 465 | UNREFERENCED_PARAMETER(DestinationNicIndex); 466 | 467 | return NDIS_STATUS_SUCCESS; 468 | } 469 | 470 | 471 | _Use_decl_annotations_ 472 | NDIS_STATUS 473 | SxExtProcessNicRequestComplete( 474 | PSX_SWITCH_OBJECT Switch, 475 | NDIS_HANDLE ExtensionContext, 476 | PNDIS_OID_REQUEST OidRequest, 477 | NDIS_SWITCH_PORT_ID SourcePortId, 478 | NDIS_SWITCH_NIC_INDEX SourceNicIndex, 479 | NDIS_SWITCH_PORT_ID DestinationPortId, 480 | NDIS_SWITCH_NIC_INDEX DestinationNicIndex, 481 | NDIS_STATUS Status 482 | ) 483 | { 484 | UNREFERENCED_PARAMETER(Switch); 485 | UNREFERENCED_PARAMETER(ExtensionContext); 486 | UNREFERENCED_PARAMETER(OidRequest); 487 | UNREFERENCED_PARAMETER(SourcePortId); 488 | UNREFERENCED_PARAMETER(SourceNicIndex); 489 | UNREFERENCED_PARAMETER(DestinationPortId); 490 | UNREFERENCED_PARAMETER(DestinationNicIndex); 491 | UNREFERENCED_PARAMETER(Status); 492 | 493 | return NDIS_STATUS_SUCCESS; 494 | } 495 | 496 | 497 | _Use_decl_annotations_ 498 | NDIS_STATUS 499 | SxExtProcessNicStatus( 500 | PSX_SWITCH_OBJECT Switch, 501 | NDIS_HANDLE ExtensionContext, 502 | PNDIS_STATUS_INDICATION StatusIndication, 503 | NDIS_SWITCH_PORT_ID SourcePortId, 504 | NDIS_SWITCH_NIC_INDEX SourceNicIndex 505 | ) 506 | { 507 | UNREFERENCED_PARAMETER(Switch); 508 | UNREFERENCED_PARAMETER(ExtensionContext); 509 | UNREFERENCED_PARAMETER(StatusIndication); 510 | UNREFERENCED_PARAMETER(SourcePortId); 511 | UNREFERENCED_PARAMETER(SourceNicIndex); 512 | 513 | return NDIS_STATUS_SUCCESS; 514 | } 515 | 516 | _Use_decl_annotations_ 517 | VOID 518 | SxExtStartNetBufferListsIngress( 519 | PSX_SWITCH_OBJECT Switch, 520 | NDIS_HANDLE ExtensionContext, 521 | PNET_BUFFER_LIST NetBufferLists, 522 | ULONG SendFlags 523 | ) 524 | { 525 | UNREFERENCED_PARAMETER(ExtensionContext); 526 | 527 | DecodeNetBufferListAndQueueForPCap(NetBufferLists); 528 | 529 | SxLibSendNetBufferListsIngress(Switch, 530 | NetBufferLists, 531 | SendFlags, 532 | 0); 533 | } 534 | 535 | 536 | _Use_decl_annotations_ 537 | VOID 538 | SxExtStartNetBufferListsEgress( 539 | PSX_SWITCH_OBJECT Switch, 540 | NDIS_HANDLE ExtensionContext, 541 | PNET_BUFFER_LIST NetBufferLists, 542 | ULONG NumberOfNetBufferLists, 543 | ULONG ReceiveFlags 544 | ) 545 | { 546 | UNREFERENCED_PARAMETER(ExtensionContext); 547 | 548 | SxLibSendNetBufferListsEgress(Switch, 549 | NetBufferLists, 550 | NumberOfNetBufferLists, 551 | ReceiveFlags); 552 | } 553 | 554 | 555 | _Use_decl_annotations_ 556 | VOID 557 | SxExtStartCompleteNetBufferListsEgress( 558 | PSX_SWITCH_OBJECT Switch, 559 | NDIS_HANDLE ExtensionContext, 560 | PNET_BUFFER_LIST NetBufferLists, 561 | ULONG ReturnFlags 562 | ) 563 | { 564 | UNREFERENCED_PARAMETER(ExtensionContext); 565 | 566 | SxLibCompleteNetBufferListsEgress(Switch, 567 | NetBufferLists, 568 | ReturnFlags); 569 | } 570 | 571 | 572 | _Use_decl_annotations_ 573 | VOID 574 | SxExtStartCompleteNetBufferListsIngress( 575 | PSX_SWITCH_OBJECT Switch, 576 | NDIS_HANDLE ExtensionContext, 577 | PNET_BUFFER_LIST NetBufferLists, 578 | ULONG SendCompleteFlags 579 | ) 580 | { 581 | UNREFERENCED_PARAMETER(ExtensionContext); 582 | 583 | SxLibCompleteNetBufferListsIngress(Switch, 584 | NetBufferLists, 585 | SendCompleteFlags); 586 | } 587 | 588 | -------------------------------------------------------------------------------- /PCapExt/install.cmd: -------------------------------------------------------------------------------- 1 | netcfg -l .\PCapExt.inf -c s -i PCapExt -------------------------------------------------------------------------------- /PCapExt/pcap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // PCAP format data structures. See: http://wiki.wireshark.org/Development/LibpcapFileFormat 4 | 5 | typedef signed int gint32; 6 | typedef unsigned int guint32; 7 | typedef signed short gint16; 8 | typedef unsigned short guint16; 9 | 10 | #define PCAP_MAGIC_NUMBER 0xa1b2c3d4 11 | #define PCAP_VERSION_MAJOR 2 12 | #define PCAP_VERSION_MINOR 4 13 | 14 | typedef struct pcap_hdr_s { 15 | guint32 magic_number; /* magic number */ 16 | guint16 version_major; /* major version number */ 17 | guint16 version_minor; /* minor version number */ 18 | gint32 thiszone; /* GMT to local correction */ 19 | guint32 sigfigs; /* accuracy of timestamps */ 20 | guint32 snaplen; /* max length of captured packets, in octets */ 21 | guint32 network; /* data link type */ 22 | } pcap_hdr_t; 23 | 24 | typedef struct pcaprec_hdr_s { 25 | guint32 ts_sec; /* timestamp seconds */ 26 | guint32 ts_usec; /* timestamp microseconds */ 27 | guint32 incl_len; /* number of octets of packet saved in file */ 28 | guint32 orig_len; /* actual length of packet */ 29 | } pcaprec_hdr_t; 30 | -------------------------------------------------------------------------------- /PCapExt/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "..\base\SxBase.h" 12 | #include "..\base\SxApi.h" 13 | #include "..\base\SxLibrary.h" 14 | -------------------------------------------------------------------------------- /PCapExt/precompsrc.c: -------------------------------------------------------------------------------- 1 | #include "precomp.h" -------------------------------------------------------------------------------- /PCapExt/uninstall.cmd: -------------------------------------------------------------------------------- 1 | netcfg -u PCapExt -------------------------------------------------------------------------------- /Package/package.VcxProj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Win8.1 Debug 6 | x64 7 | 8 | 9 | Win8.1 Release 10 | x64 11 | 12 | 13 | Win8 Debug 14 | x64 15 | 16 | 17 | Win8 Release 18 | x64 19 | 20 | 21 | 22 | WindowsKernelModeDriver8.1 23 | Utility 24 | Package 25 | true 26 | Win8.1 Debug 27 | 28 | 29 | 30 | {043FC3A3-BA8A-4B0E-9E0D-EBA13CF25FD9} 31 | {178167A1-839A-472E-A348-4B5D30FB9995} 32 | $(MSBuildProjectName) 33 | 34 | 35 | WindowsV6.3 36 | true 37 | 38 | 39 | WindowsV6.3 40 | false 41 | 42 | 43 | Windows8 44 | true 45 | 46 | 47 | Windows8 48 | false 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | DbgengKernelDebugger 60 | False 61 | False 62 | None 63 | 64 | 65 | 66 | 67 | 68 | %PathToInf% 69 | False 70 | False 71 | True 72 | 73 | 133563 74 | 75 | 76 | 77 | true 78 | 79 | 80 | 81 | 82 | true 83 | 84 | 85 | 86 | 87 | true 88 | 89 | 90 | 91 | 92 | true 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | {1ffafea1-aa92-48b0-bafa-429c90c7b3c5} 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /Package/package.VcxProj.Filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;* 6 | {053E6DB9-D840-45EC-8E38-E1DA2D1E83BA} 7 | 8 | 9 | h;hpp;hxx;hm;inl;inc;xsd 10 | {CCEFEB6F-74C6-4161-AE24-7A9F9D763992} 11 | 12 | 13 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml 14 | {B242988A-FACC-4D39-9EE5-A325D87DDB1C} 15 | 16 | 17 | inf;inv;inx;mof;mc; 18 | {56B87BF6-D1BD-4CB8-B17B-45FFD2B3CF1D} 19 | 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HyperVPCapExt 2 | ============= 3 | 4 | Hyper-V virtual switch packet capturing extension with libpcap / Wireshark format. 5 | -------------------------------------------------------------------------------- /base/SxApi.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All Rights Reserved. 4 | 5 | Module Name: 6 | 7 | SxApi.h 8 | 9 | Abstract: 10 | 11 | This file contains the API that must be implemented to 12 | create a switch extension using the SxBase library. 13 | 14 | 15 | --*/ 16 | 17 | // 18 | // The major version of NDIS the driver is using. 19 | // For NDIS 6.30, use NDIS_FILTER_MAJOR_VERSION. 20 | // 21 | extern UCHAR SxExtMajorNdisVersion; 22 | 23 | // 24 | // The minor version of NDIS the driver is using. 25 | // For NDIS 6.30, use NDIS_FILTER_MINOR_VERSION. 26 | // 27 | extern UCHAR SxExtMinorNdisVersion; 28 | 29 | // 30 | // The friendly name of the extension. 31 | // 32 | extern PWCHAR SxExtFriendlyName; 33 | 34 | // 35 | // The unique name of the extension. 36 | // 37 | extern PWCHAR SxExtUniqueName; 38 | 39 | // 40 | // The service name of the extension from the INF. 41 | // 42 | extern PWCHAR SxExtServiceName; 43 | 44 | // 45 | // The memory pool tag using in the extension. 46 | // 47 | extern ULONG SxExtAllocationTag; 48 | 49 | // 50 | // The request ID used to identify OIDs initiated from this extension. 51 | // 52 | extern ULONG SxExtOidRequestId; 53 | 54 | 55 | /*++ 56 | 57 | SxExtInitialize 58 | 59 | Routine Description: 60 | This function is called from the SxBase Library during DriverEntry. 61 | An extension should allocate/initalize all global data in this function. 62 | 63 | Arguments: 64 | NULL 65 | 66 | Return Value: 67 | NDIS_STATUS_SUCCESS succeeds driver entry. 68 | 69 | NDIS_STATUS_*** fails driver entry. 70 | 71 | --*/ 72 | NDIS_STATUS 73 | SxExtInitialize(); 74 | 75 | 76 | /*++ 77 | 78 | SxExtUninitialize 79 | 80 | Routine Description: 81 | This function is called from the SxBase Library during DriverUnload. 82 | An extension should free/reset all global data in this function. 83 | 84 | Arguments: 85 | NULL 86 | 87 | Return Value: 88 | VOID 89 | 90 | --*/ 91 | VOID 92 | SxExtUninitialize(); 93 | 94 | 95 | /*++ 96 | 97 | SxExtCreateSwitch 98 | 99 | Routine Description: 100 | This function is called when an extension binds to a new switch. 101 | All switch specific data should be allocated during this function. 102 | OIDs cannot be sent from this function, and both the control 103 | and data paths are inactive. 104 | 105 | Arguments: 106 | Switch - the Switch Object currently being created 107 | 108 | ExtensionContext - Extension context specific to the switch being 109 | createf. This context will be passed back to the 110 | extension for all function calls in SxApi 111 | 112 | Return Value: 113 | NDIS_STATUS_SUCCESS succeeds switch creation. 114 | 115 | NDIS_STATUS_RESOURCES fails switch creation because of insufficient 116 | resources. 117 | 118 | NDIS_STATUS_FAILURE fails switch creation. 119 | 120 | --*/ 121 | NDIS_STATUS 122 | SxExtCreateSwitch( 123 | _In_ PSX_SWITCH_OBJECT Switch, 124 | _Outptr_result_maybenull_ PNDIS_HANDLE *ExtensionContext 125 | ); 126 | 127 | 128 | /*++ 129 | 130 | SxExtDeleteSwitch 131 | 132 | Routine Description: 133 | This function is called when an extension binds to a new switch. 134 | All switch specific data should be allocated/initialized during 135 | this function. 136 | 137 | Arguments: 138 | Switch - the Switch being deleted 139 | 140 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 141 | for the switch being deleted. 142 | 143 | Return Value: 144 | VOID 145 | 146 | --*/ 147 | VOID 148 | SxExtDeleteSwitch( 149 | _In_ PSX_SWITCH_OBJECT Switch, 150 | _In_ NDIS_HANDLE ExtensionContext 151 | ); 152 | 153 | 154 | /*++ 155 | 156 | SxExtActivateSwitch 157 | 158 | Routine Description: 159 | This function is called to activate a switch. The function can be called 160 | while the switch is Running or Paused and should be used to bootstrap 161 | the switch if it was not Active when it was created. 162 | 163 | Arguments: 164 | Switch - the Switch being activated 165 | 166 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 167 | for the switch being restarted. 168 | 169 | Return Value: 170 | VOID 171 | 172 | --*/ 173 | VOID 174 | SxExtActivateSwitch( 175 | _In_ PSX_SWITCH_OBJECT Switch, 176 | _In_ NDIS_HANDLE ExtensionContext 177 | ); 178 | 179 | 180 | /*++ 181 | 182 | SxExtRestartSwitch 183 | 184 | Routine Description: 185 | This function is called to restart a switch from a paused state. 186 | 187 | Arguments: 188 | Switch - the Switch being restarted 189 | 190 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 191 | for the switch being restarted. 192 | 193 | Return Value: 194 | NDIS_STATUS_SUCCESS succeeds switch restart. 195 | 196 | NDIS_STATUS_RESOURCES fails switch restart because of insufficient 197 | resources. 198 | 199 | NDIS_STATUS_FAILURE fails switch restart. 200 | 201 | --*/ 202 | NDIS_STATUS 203 | SxExtRestartSwitch( 204 | _In_ PSX_SWITCH_OBJECT Switch, 205 | _In_ NDIS_HANDLE ExtensionContext 206 | ); 207 | 208 | 209 | /*++ 210 | 211 | SxExtPauseSwitch 212 | 213 | Routine Description: 214 | This function is called to pause a switch from a running state. 215 | 216 | Arguments: 217 | Switch - the Switch being paused 218 | 219 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 220 | for the switch being paused 221 | 222 | Return Value: 223 | VOID 224 | 225 | --*/ 226 | VOID 227 | SxExtPauseSwitch( 228 | _In_ PSX_SWITCH_OBJECT Switch, 229 | _In_ NDIS_HANDLE ExtensionContext 230 | ); 231 | 232 | 233 | /*++ 234 | 235 | SxExtCreatePort 236 | 237 | Routine Description: 238 | This function is called to create a new port on a switch. 239 | 240 | Arguments: 241 | Switch - the Switch context 242 | 243 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 244 | for the switch 245 | 246 | Port - the Port being created 247 | 248 | Return Value: 249 | NDIS_STATUS_SUCCESS to succeed port creation 250 | 251 | NDIS_STATUS_*** to fail port creation 252 | 253 | --*/ 254 | NDIS_STATUS 255 | SxExtCreatePort( 256 | _In_ PSX_SWITCH_OBJECT Switch, 257 | _In_ NDIS_HANDLE ExtensionContext, 258 | _In_ PNDIS_SWITCH_PORT_PARAMETERS Port 259 | ); 260 | 261 | 262 | /*++ 263 | 264 | SxExtUpdatePort 265 | 266 | Routine Description: 267 | This function is called to update an already created port. 268 | 269 | Arguments: 270 | Switch - the Switch context 271 | 272 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 273 | for the switch 274 | 275 | Port - the port being updated 276 | 277 | Return Value: 278 | VOID 279 | 280 | --*/ 281 | VOID 282 | SxExtUpdatePort( 283 | _In_ PSX_SWITCH_OBJECT Switch, 284 | _In_ NDIS_HANDLE ExtensionContext, 285 | _In_ PNDIS_SWITCH_PORT_PARAMETERS Port 286 | ); 287 | 288 | 289 | /*++ 290 | 291 | SxExtCreateNic 292 | 293 | Routine Description: 294 | This function is called to create a new NIC to be connected 295 | to a switch. 296 | The extension may allocate context for this NIC, and traffic may 297 | start to flow from this NIC, but it may not be used as a destination 298 | until SxExtConnectNic has been called. 299 | 300 | Arguments: 301 | Switch - the Switch context 302 | 303 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 304 | for the switch 305 | 306 | Nic - the NIC being created 307 | 308 | Return Value: 309 | NDIS_STATUS_SUCCESS to succeed NIC creation 310 | 311 | NDIS_STATUS_*** to fail NIC creation 312 | 313 | --*/ 314 | NDIS_STATUS 315 | SxExtCreateNic( 316 | _In_ PSX_SWITCH_OBJECT Switch, 317 | _In_ NDIS_HANDLE ExtensionContext, 318 | _In_ PNDIS_SWITCH_NIC_PARAMETERS Nic 319 | ); 320 | 321 | 322 | /*++ 323 | 324 | SxExtConnectNic 325 | 326 | Routine Description: 327 | This function is called to connect a NIC to a switch. 328 | After returning from this function the extension can use this NIC 329 | as a destination. 330 | 331 | Arguments: 332 | Switch - the Switch context 333 | 334 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 335 | for the switch 336 | 337 | Nic - the NIC being connected 338 | 339 | Return Value: 340 | VOID 341 | 342 | --*/ 343 | VOID 344 | SxExtConnectNic( 345 | _In_ PSX_SWITCH_OBJECT Switch, 346 | _In_ NDIS_HANDLE ExtensionContext, 347 | _In_ PNDIS_SWITCH_NIC_PARAMETERS Nic 348 | ); 349 | 350 | 351 | /*++ 352 | 353 | SxExtUpdateNic 354 | 355 | Routine Description: 356 | This function is called to update an already created NIC. 357 | 358 | Arguments: 359 | Switch - the Switch context 360 | 361 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 362 | for the switch 363 | 364 | Nic - the NIC being updated 365 | 366 | Return Value: 367 | VOID 368 | 369 | --*/ 370 | VOID 371 | SxExtUpdateNic( 372 | _In_ PSX_SWITCH_OBJECT Switch, 373 | _In_ NDIS_HANDLE ExtensionContext, 374 | _In_ PNDIS_SWITCH_NIC_PARAMETERS Nic 375 | ); 376 | 377 | 378 | /*++ 379 | 380 | SxExtDisconnectNic 381 | 382 | Routine Description: 383 | This function is called to disconnect a NIC from a switch. 384 | After returning from this function the extension cannot use 385 | this NIC as a destination. 386 | 387 | Arguments: 388 | Switch - the Switch context 389 | 390 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 391 | for the switch 392 | 393 | Nic - the NIC being disconnected 394 | 395 | Return Value: 396 | VOID 397 | 398 | --*/ 399 | VOID 400 | SxExtDisconnectNic( 401 | _In_ PSX_SWITCH_OBJECT Switch, 402 | _In_ NDIS_HANDLE ExtensionContext, 403 | _In_ PNDIS_SWITCH_NIC_PARAMETERS Nic 404 | ); 405 | 406 | 407 | /*++ 408 | 409 | SxExtDeleteNic 410 | 411 | Routine Description: 412 | This function is called to delete a NIC from a switch. 413 | No futher traffic/control will be recieved for this NIC. 414 | 415 | Arguments: 416 | Switch - the Switch context 417 | 418 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 419 | for the switch 420 | 421 | Nic - the NIC being deleted 422 | 423 | Return Value: 424 | VOID 425 | 426 | --*/ 427 | VOID 428 | SxExtDeleteNic( 429 | _In_ PSX_SWITCH_OBJECT Switch, 430 | _In_ NDIS_HANDLE ExtensionContext, 431 | _In_ PNDIS_SWITCH_NIC_PARAMETERS Nic 432 | ); 433 | 434 | 435 | /*++ 436 | 437 | SxExtTeardownPort 438 | 439 | Routine Description: 440 | This function is called to start deletion of a port on a switch. 441 | Upon recieving this call, no further references may be taken 442 | on the given port. 443 | 444 | Arguments: 445 | Switch - the Switch context 446 | 447 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 448 | for the switch 449 | 450 | Port - the Port being deleted 451 | 452 | Return Value: 453 | VOID 454 | 455 | --*/ 456 | VOID 457 | SxExtTeardownPort( 458 | _In_ PSX_SWITCH_OBJECT Switch, 459 | _In_ NDIS_HANDLE ExtensionContext, 460 | _In_ PNDIS_SWITCH_PORT_PARAMETERS Port 461 | ); 462 | 463 | 464 | /*++ 465 | 466 | SxExtDeletePort 467 | 468 | Routine Description: 469 | This function is called to finish deletion of a port on a switch. 470 | Upon recieving this call, no traffic/control will be recieved 471 | for this port. 472 | 473 | Arguments: 474 | Switch - the Switch context 475 | 476 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 477 | for the switch 478 | 479 | Port - the Port being deleted 480 | 481 | Return Value: 482 | VOID 483 | 484 | --*/ 485 | VOID 486 | SxExtDeletePort( 487 | _In_ PSX_SWITCH_OBJECT Switch, 488 | _In_ NDIS_HANDLE ExtensionContext, 489 | _In_ PNDIS_SWITCH_PORT_PARAMETERS Port 490 | ); 491 | 492 | 493 | /*++ 494 | 495 | SxExtSaveNic 496 | 497 | Routine Description: 498 | This function is called to retrieve save data for a given NIC. 499 | This function will be called until all extensions have finished 500 | saving data. 501 | 502 | An new save for this NIC will not start until SxExtSaveNicComplete 503 | has been received. 504 | 505 | If returning NDIS_STATUS_SUCCESS from this function, and 506 | BytesWritten > 0 you must write to the ExtensionId, 507 | ExtensionFriendlyName, SaveDataSize and SaveData fields in 508 | SaveState. SxExtUniqueName MUST be written to ExtensionId. 509 | SxExtFriendlyName should be written to ExtensionFriendlyName. 510 | 511 | If returning NDIS_STATUS_SUCCESS with BytesWritten == 0, 512 | DO NOT write any data to any fields. 513 | 514 | Arguments: 515 | Switch - the Switch context 516 | 517 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 518 | for the switch 519 | 520 | SaveState - the save information and buffer to save to 521 | 522 | BytesWritten - the # of bytes written to the save buffer 523 | 524 | BytesNeeded - the length of the save buffer needed 525 | 526 | Return Value: 527 | NDIS_STATUS_SUCCESS - if the buffer was successfully written, or not 528 | needed and BytesWritten is set to 0 529 | 530 | NDIS_STATUS_BUFFER_TOO_SHORT - if the buffer is too short for the 531 | necessary save, write the length needed 532 | in BytesNeeded 533 | 534 | NDIS_STATUS_*** - to fail the save operation 535 | 536 | --*/ 537 | NDIS_STATUS 538 | SxExtSaveNic( 539 | _In_ PSX_SWITCH_OBJECT Switch, 540 | _In_ NDIS_HANDLE ExtensionContext, 541 | _Inout_ PNDIS_SWITCH_NIC_SAVE_STATE SaveState, 542 | _Out_ PULONG BytesWritten, 543 | _Out_ PULONG BytesNeeded 544 | ); 545 | 546 | 547 | /*++ 548 | 549 | SxExtSaveNicComplete 550 | 551 | Routine Description: 552 | This function is called to notify the extension that saving 553 | the given NIC has been completed by all extensions. 554 | 555 | Arguments: 556 | Switch - the Switch context 557 | 558 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 559 | for the switch 560 | 561 | SaveState - the save information 562 | 563 | Return Value: 564 | VOID 565 | 566 | --*/ 567 | VOID 568 | SxExtSaveNicComplete( 569 | _In_ PSX_SWITCH_OBJECT Switch, 570 | _In_ NDIS_HANDLE ExtensionContext, 571 | _In_ PNDIS_SWITCH_NIC_SAVE_STATE SaveState 572 | ); 573 | 574 | 575 | /*++ 576 | 577 | SxExtNicRestore 578 | 579 | Routine Description: 580 | This function is called to restore previously saved data. 581 | 582 | Arguments: 583 | Switch - the Switch context 584 | 585 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 586 | for the switch 587 | 588 | SaveState - the save information 589 | 590 | BytesRestored - the number of bytes restored from the saved data 591 | 592 | Return Value: 593 | NDIS_STATUS_SUCCESS - if this data belongs to this extension, and was 594 | successfully restored (BytesRestored written) 595 | OR 596 | this data does not belong to this extension 597 | (BytesRestored == 0) 598 | 599 | NDIS_STATUS_*** - there was an error while attempting to restore 600 | this data 601 | 602 | --*/ 603 | NDIS_STATUS 604 | SxExtNicRestore( 605 | _In_ PSX_SWITCH_OBJECT Switch, 606 | _In_ NDIS_HANDLE ExtensionContext, 607 | _In_ PNDIS_SWITCH_NIC_SAVE_STATE SaveState, 608 | _Out_ PULONG BytesRestored 609 | ); 610 | 611 | 612 | /*++ 613 | 614 | SxExtNicRestoreComplete 615 | 616 | Routine Description: 617 | This function is called to signify the end of a restore operation. 618 | 619 | Arguments: 620 | Switch - the Switch context 621 | 622 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 623 | for the switch 624 | 625 | SaveState - the save information 626 | 627 | Return Value: 628 | VOID 629 | 630 | --*/ 631 | VOID 632 | SxExtNicRestoreComplete( 633 | _In_ PSX_SWITCH_OBJECT Switch, 634 | _In_ NDIS_HANDLE ExtensionContext, 635 | _In_ PNDIS_SWITCH_NIC_SAVE_STATE SaveState 636 | ); 637 | 638 | 639 | /*++ 640 | 641 | SxExtAddSwitchProperty 642 | 643 | Routine Description: 644 | This function is called to add a property on the given switch. 645 | 646 | Arguments: 647 | Switch - the Switch context 648 | 649 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 650 | for the switch 651 | 652 | SwitchProperty - the property to be applied 653 | 654 | Return Value: 655 | NDIS_STATUS_NOT_SUPPORTED - if the policy is not consumed by this extension 656 | 657 | NDIS_STATUS_SUCCESS - if the policy is consumed by this extension, and 658 | can successfully be enforced 659 | 660 | STATUS_DATA_NOT_ACCEPTED - if the policy is consumed by this 661 | extension, but cannot be enforced 662 | 663 | NDIS_STATUS_*** - if the policy is consumed by this extension, and 664 | setting the valid policy failed 665 | 666 | --*/ 667 | NDIS_STATUS 668 | SxExtAddSwitchProperty( 669 | _In_ PSX_SWITCH_OBJECT Switch, 670 | _In_ NDIS_HANDLE ExtensionContext, 671 | _In_ PNDIS_SWITCH_PROPERTY_PARAMETERS SwitchProperty 672 | ); 673 | 674 | 675 | /*++ 676 | 677 | SxExtUpdateSwitchProperty 678 | 679 | Routine Description: 680 | This function is called to update a property on the given switch. 681 | 682 | Arguments: 683 | Switch - the Switch context 684 | 685 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 686 | for the switch 687 | 688 | SwitchProperty - the property to be updated 689 | 690 | Return Value: 691 | NDIS_STATUS_NOT_SUPPORTED - if the policy is not consumed by this extension 692 | 693 | NDIS_STATUS_SUCCESS - if the policy is consumed by this extension, and 694 | can successfully be enforced 695 | 696 | STATUS_DATA_NOT_ACCEPTED - if the policy is consumed by this 697 | extension, but cannot be enforced 698 | 699 | NDIS_STATUS_*** - if the policy is consumed by this extension, and 700 | setting the valid policy failed 701 | 702 | --*/ 703 | NDIS_STATUS 704 | SxExtUpdateSwitchProperty( 705 | _In_ PSX_SWITCH_OBJECT Switch, 706 | _In_ NDIS_HANDLE ExtensionContext, 707 | _In_ PNDIS_SWITCH_PROPERTY_PARAMETERS SwitchProperty 708 | ); 709 | 710 | 711 | /*++ 712 | 713 | SxExtDeleteSwitchProperty 714 | 715 | Routine Description: 716 | This function is called to delete a property on the given switch. 717 | 718 | Arguments: 719 | Switch - the Switch context 720 | 721 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 722 | for the switch 723 | 724 | SwitchProperty - the property to be deleted 725 | 726 | Return Value: 727 | TRUE - if the policy belongs to this extension 728 | 729 | FALSE - otherwise 730 | 731 | --*/ 732 | BOOLEAN 733 | SxExtDeleteSwitchProperty( 734 | _In_ PSX_SWITCH_OBJECT Switch, 735 | _In_ NDIS_HANDLE ExtensionContext, 736 | _In_ PNDIS_SWITCH_PROPERTY_DELETE_PARAMETERS SwitchProperty 737 | ); 738 | 739 | 740 | /*++ 741 | 742 | SxExtAddPortProperty 743 | 744 | Routine Description: 745 | This function is called to add a property on the given port, 746 | on the given switch. 747 | 748 | Arguments: 749 | Switch - the Switch context 750 | 751 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 752 | for the switch 753 | 754 | PortProperty - the property to be applied 755 | 756 | Return Value: 757 | NDIS_STATUS_NOT_SUPPORTED - if the policy is not consumed by this extension 758 | 759 | NDIS_STATUS_SUCCESS - if the policy is consumed by this extension, and 760 | can successfully be enforced 761 | 762 | STATUS_DATA_NOT_ACCEPTED - if the policy is consumed by this 763 | extension, but cannot be enforced 764 | 765 | NDIS_STATUS_*** - if the policy is consumed by this extension, and 766 | setting the valid policy failed 767 | 768 | --*/ 769 | NDIS_STATUS 770 | SxExtAddPortProperty( 771 | _In_ PSX_SWITCH_OBJECT Switch, 772 | _In_ NDIS_HANDLE ExtensionContext, 773 | _In_ PNDIS_SWITCH_PORT_PROPERTY_PARAMETERS PortProperty 774 | ); 775 | 776 | 777 | /*++ 778 | 779 | SxExtUpdatePortProperty 780 | 781 | Routine Description: 782 | This function is called to update a property on the given port, 783 | on the given switch. 784 | 785 | Arguments: 786 | Switch - the Switch context 787 | 788 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 789 | for the switch 790 | 791 | PortProperty - the property to be applied 792 | 793 | Return Value: 794 | NDIS_STATUS_NOT_SUPPORTED - if the policy is not consumed by this extension 795 | 796 | NDIS_STATUS_SUCCESS - if the policy is consumed by this extension, and 797 | can successfully be enforced 798 | 799 | STATUS_DATA_NOT_ACCEPTED - if the policy is consumed by this 800 | extension, but cannot be enforced 801 | 802 | NDIS_STATUS_*** - if the policy is consumed by this extension, and 803 | setting the valid policy failed 804 | 805 | --*/ 806 | NDIS_STATUS 807 | SxExtUpdatePortProperty( 808 | _In_ PSX_SWITCH_OBJECT Switch, 809 | _In_ NDIS_HANDLE ExtensionContext, 810 | _In_ PNDIS_SWITCH_PORT_PROPERTY_PARAMETERS PortProperty 811 | ); 812 | 813 | 814 | /*++ 815 | 816 | SxExtDeletePortProperty 817 | 818 | Routine Description: 819 | This function is called to delete a property on the given port, 820 | on the given switch. 821 | 822 | Arguments: 823 | Switch - the Switch context 824 | 825 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 826 | for the switch 827 | 828 | SwitchProperty - the property to be deleted 829 | 830 | Return Value: 831 | TRUE - if the policy is not consumed by this extension 832 | 833 | FALSE - otherwise 834 | 835 | --*/ 836 | BOOLEAN 837 | SxExtDeletePortProperty( 838 | _In_ PSX_SWITCH_OBJECT Switch, 839 | _In_ NDIS_HANDLE ExtensionContext, 840 | _In_ PNDIS_SWITCH_PORT_PROPERTY_DELETE_PARAMETERS PortProperty 841 | ); 842 | 843 | 844 | /*++ 845 | 846 | SxExtQuerySwitchFeatureStatus 847 | 848 | Routine Description: 849 | This function is called to query the status of a custom property 850 | on the given switch. 851 | 852 | Arguments: 853 | Switch - the Switch context 854 | 855 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 856 | for the switch 857 | 858 | SwitchFeatureStatus - the property buffer 859 | 860 | BytesNeeded - if SwitchFeatureStatus is too small, this should be set 861 | to the size buffer needed 862 | 863 | Return Value: 864 | TRUE - return true if this property belongs to this extension, if 865 | BytesNeeded > 0, the buffer will be reallocated and 866 | this function will be called again 867 | 868 | FALSE - otherwise 869 | 870 | --*/ 871 | BOOLEAN 872 | SxExtQuerySwitchFeatureStatus( 873 | _In_ PSX_SWITCH_OBJECT Switch, 874 | _In_ NDIS_HANDLE ExtensionContext, 875 | _Inout_ PNDIS_SWITCH_FEATURE_STATUS_PARAMETERS SwitchFeatureStatus, 876 | _Inout_ PULONG BytesNeeded 877 | ); 878 | 879 | 880 | /*++ 881 | 882 | SxExtQueryPortFeatureStatus 883 | 884 | Routine Description: 885 | This function is called to query the status of a custom property 886 | on the given port, on the given switch. 887 | 888 | Arguments: 889 | Switch - the Switch context 890 | 891 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 892 | for the switch 893 | 894 | PortFeatureStatus - the property buffer 895 | 896 | BytesNeeded - if PortFeatureStatus is too small, this should be set 897 | to the size buffer needed 898 | 899 | Return Value: 900 | TRUE - return true if this property belongs to this extension, if 901 | BytesNeeded > 0, the buffer will be reallocated and 902 | this function will be called again 903 | 904 | FALSE - otherwise 905 | 906 | --*/ 907 | BOOLEAN 908 | SxExtQueryPortFeatureStatus( 909 | _In_ PSX_SWITCH_OBJECT Switch, 910 | _In_ NDIS_HANDLE ExtensionContext, 911 | _Inout_ PNDIS_SWITCH_PORT_FEATURE_STATUS_PARAMETERS PortFeatureStatus, 912 | _Inout_ PULONG BytesNeeded 913 | ); 914 | 915 | 916 | /*++ 917 | 918 | SxExtProcessNicRequest 919 | 920 | Routine Description: 921 | This function is called upon the reciept of an OID_SWITCH_NIC_REQUEST 922 | to the extension. 923 | If an extension wishes to redirect the OID, it must return a valid 924 | DestinationPortId and DestinationNicIndex, which it has taken a 925 | reference on. 926 | If an extension wishes to set source information, it must return 927 | a valid SourcePortId and SourceNicIndex, which it has taken a 928 | reference on. 929 | The extension can change the OidRequest if it needs to. 930 | 931 | !! This function should only be used by forwarding extensions. !! 932 | 933 | Arguments: 934 | Switch - the Switch context 935 | 936 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 937 | for the switch 938 | 939 | OidRequest - the OID wrapped by the NIC request 940 | 941 | SourcePortId - the source PortId to set 942 | 943 | SourceNicIndex - the source NicIndex to set 944 | 945 | DestinationPortId - the destination PortId to set 946 | 947 | DestinationNicIndex - the destination NicIndex to set 948 | 949 | Return Value: 950 | NDIS_STATUS_SUCCESS - sends OID 951 | 952 | NDIS_STATUS_*** - complete OID with given status 953 | 954 | --*/ 955 | NDIS_STATUS 956 | SxExtProcessNicRequest( 957 | _In_ PSX_SWITCH_OBJECT Switch, 958 | _In_ NDIS_HANDLE ExtensionContext, 959 | _Inout_ PNDIS_OID_REQUEST OidRequest, 960 | _Inout_ PNDIS_SWITCH_PORT_ID SourcePortId, 961 | _Inout_ PNDIS_SWITCH_NIC_INDEX SourceNicIndex, 962 | _Inout_ PNDIS_SWITCH_PORT_ID DestinationPortId, 963 | _Inout_ PNDIS_SWITCH_NIC_INDEX DestinationNicIndex 964 | ); 965 | 966 | 967 | /*++ 968 | 969 | SxExtProcessNicRequestComplete 970 | 971 | Routine Description: 972 | This function is called upon the completion of an OID_SWITCH_NIC_REQUEST 973 | that this extension has previously altered. 974 | The extension must derefernce all NICs it had previously taken references 975 | on. 976 | If the OidRequest buffer was changed (along with underlying buffers), 977 | the previous data must be replaced. 978 | 979 | Arguments: 980 | Switch - the Switch context 981 | 982 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 983 | for the switch 984 | 985 | NicOidRequest - the OID buffer, encapsulated with source/destination info 986 | 987 | Status - the status the OID completed with 988 | 989 | Return Value: 990 | NDIS_STATUS - the status to complete the OID request with 991 | 992 | --*/ 993 | NDIS_STATUS 994 | SxExtProcessNicRequestComplete( 995 | _In_ PSX_SWITCH_OBJECT Switch, 996 | _In_ NDIS_HANDLE ExtensionContext, 997 | _Inout_ PNDIS_OID_REQUEST OidRequest, 998 | _In_ NDIS_SWITCH_PORT_ID SourcePortId, 999 | _In_ NDIS_SWITCH_NIC_INDEX SourceNicIndex, 1000 | _In_ NDIS_SWITCH_PORT_ID DestinationPortId, 1001 | _In_ NDIS_SWITCH_NIC_INDEX DestinationNicIndex, 1002 | _In_ NDIS_STATUS Status 1003 | ); 1004 | 1005 | 1006 | /*++ 1007 | 1008 | SxExtProcessNicStatus 1009 | 1010 | Routine Description: 1011 | This function is called upon the reciept of an NDIS_STATUS_SWITCH_NIC_STATUS 1012 | to the extension. 1013 | If the extension wishes to modify the status indication, it should 1014 | send its own status indication using NdisFIndicateStatus and return a 1015 | failure status. 1016 | If the extension wishes to drop the status indiction, it should return 1017 | failure status, though this should be done very sparingly and carefully. 1018 | 1019 | !! This function should only be used by forwarding extensions. !! 1020 | 1021 | Arguments: 1022 | Switch - the Switch context 1023 | 1024 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 1025 | for the switch 1026 | 1027 | StatusIndication - the indication wrapped by the NIC status indication 1028 | 1029 | SourcePortId - the source PortId of the indication 1030 | 1031 | SourceNicIndex - the source NicIndex of the indication 1032 | 1033 | Return Value: 1034 | NDIS_STATUS_SUCCESS - return to continue forwarding this indication 1035 | 1036 | NDIS_STATUS_*** - if the extension wants to modify the status 1037 | if modifying the status the extension should indicate 1038 | its own modified status using 1039 | SxLibIssueNicStatusIndicationUnsafe as soon as possible 1040 | 1041 | --*/ 1042 | NDIS_STATUS 1043 | SxExtProcessNicStatus( 1044 | _In_ PSX_SWITCH_OBJECT Switch, 1045 | _In_ NDIS_HANDLE ExtensionContext, 1046 | _In_ PNDIS_STATUS_INDICATION StatusIndication, 1047 | _In_ NDIS_SWITCH_PORT_ID SourcePortId, 1048 | _In_ NDIS_SWITCH_NIC_INDEX SourceNicIndex 1049 | ); 1050 | 1051 | 1052 | /*++ 1053 | 1054 | SxExtStartNetBufferListsIngress 1055 | 1056 | Routine Description: 1057 | This function is called upon the receipt on an NBL on ingress. 1058 | The extension should call SxLibSendNetBufferListsIngress to continue 1059 | the send of the NBL on ingress. 1060 | The extension should call SxLibCompleteNetBufferListsIngress to 1061 | drop the NBL. 1062 | This function may also be call from egress to inject an NBL. 1063 | 1064 | Arguments: 1065 | Switch - the Switch context 1066 | 1067 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 1068 | for the switch 1069 | 1070 | NetBufferLists - the NBL to be sent 1071 | 1072 | SendFlags - the send flags from NDIS, equivalent to NDIS send flags for 1073 | NdisFSendNetBufferLists 1074 | 1075 | Return Value: 1076 | VOID 1077 | 1078 | --*/ 1079 | VOID 1080 | SxExtStartNetBufferListsIngress( 1081 | _In_ PSX_SWITCH_OBJECT Switch, 1082 | _In_ NDIS_HANDLE ExtensionContext, 1083 | _In_ PNET_BUFFER_LIST NetBufferLists, 1084 | _In_ ULONG SendFlags 1085 | ); 1086 | 1087 | 1088 | /*++ 1089 | 1090 | SxExtStartNetBufferListsEgress 1091 | 1092 | Routine Description: 1093 | This function is called upon the receipt on an NBL on egress. 1094 | The extension should call SxLibSendNetBufferListsEgress to continue 1095 | the send of the NBL on egress. 1096 | The extension should call SxLibSendNetBufferListsEgressComplete to 1097 | drop the NBL. 1098 | 1099 | Arguments: 1100 | Switch - the Switch context 1101 | 1102 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 1103 | for the switch 1104 | 1105 | NetBufferLists - the NBL to be sent 1106 | 1107 | NumberOfNetBufferLists - the number of NBLs in NetBufferLists 1108 | 1109 | ReceiveFlags - the receive flags from NDIS, equivalent to NDIS receive flags for 1110 | NdisFIndicateReceiveNetBufferLists 1111 | 1112 | Return Value: 1113 | VOID 1114 | 1115 | --*/ 1116 | VOID 1117 | SxExtStartNetBufferListsEgress( 1118 | _In_ PSX_SWITCH_OBJECT Switch, 1119 | _In_ NDIS_HANDLE ExtensionContext, 1120 | _In_ PNET_BUFFER_LIST NetBufferLists, 1121 | _In_ ULONG NumberOfNetBufferLists, 1122 | _In_ ULONG ReceiveFlags 1123 | ); 1124 | 1125 | 1126 | /*++ 1127 | 1128 | SxExtStartCompleteNetBufferListsEgress 1129 | 1130 | Routine Description: 1131 | This function is called upon the completion of an NBL on egress. 1132 | The extension must call SxLibCompleteNetBufferListsEgress 1133 | once it has finished processing the NBL. 1134 | 1135 | Arguments: 1136 | Switch - the Switch context 1137 | 1138 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 1139 | for the switch 1140 | 1141 | NetBufferLists - the NBL being completed 1142 | 1143 | ReturnFlags - the return flags from NDIS, equivalent to NDIS return flags for 1144 | NdisFReturnNetBufferLists 1145 | 1146 | Return Value: 1147 | VOID 1148 | 1149 | --*/ 1150 | VOID 1151 | SxExtStartCompleteNetBufferListsEgress( 1152 | _In_ PSX_SWITCH_OBJECT Switch, 1153 | _In_ NDIS_HANDLE ExtensionContext, 1154 | _In_ PNET_BUFFER_LIST NetBufferLists, 1155 | _In_ ULONG ReturnFlags 1156 | ); 1157 | 1158 | 1159 | /*++ 1160 | 1161 | SxExtStartCompleteNetBufferListsIngress 1162 | 1163 | Routine Description: 1164 | This function is called upon the completion of an NBL on ingress. 1165 | The extension must call SxLibCompleteNetBufferListsIngress 1166 | once it has finished processing the NBL. 1167 | 1168 | If there are NBLs injected by this extension in NetBufferLists, 1169 | the extension must NOT call SxLibCompleteNetBufferListsIngress, and 1170 | instead call SxLibCompletedInjectedNetBufferLists with the number 1171 | of injected NBLs completed. 1172 | 1173 | Arguments: 1174 | Switch - the Switch context 1175 | 1176 | ExtensionContext - The extension context allocated in SxExtCreateSwitch 1177 | for the switch 1178 | 1179 | NetBufferLists - the NBL being completed 1180 | 1181 | SendCompleteFlags - the send complete flags from NDIS, equivalent to 1182 | NDIS send complete flags for 1183 | NdisFSendNetBufferListsComplete 1184 | 1185 | Return Value: 1186 | VOID 1187 | 1188 | --*/ 1189 | VOID 1190 | SxExtStartCompleteNetBufferListsIngress( 1191 | _In_ PSX_SWITCH_OBJECT Switch, 1192 | _In_ NDIS_HANDLE ExtensionContext, 1193 | _In_ PNET_BUFFER_LIST NetBufferLists, 1194 | _In_ ULONG SendCompleteFlags 1195 | ); 1196 | 1197 | -------------------------------------------------------------------------------- /base/SxBase.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All Rights Reserved. 4 | 5 | Module Name: 6 | 7 | SxBase.c 8 | 9 | Abstract: 10 | 11 | This file contains the common code for building a switch extension. This 12 | file includes all the standard NDIS handling and exposes a function based 13 | interface for the control path and data path. This also has reusable code 14 | for basic operations such as pause/resume handling etc. 15 | 16 | 17 | --*/ 18 | 19 | #include "precomp.h" 20 | 21 | ULONG SxDebugLevel; 22 | NDIS_HANDLE SxDriverHandle = NULL; 23 | NDIS_HANDLE SxDriverObject; 24 | NDIS_SPIN_LOCK SxExtensionListLock; 25 | LIST_ENTRY SxExtensionList; 26 | 27 | NDIS_STRING SxExtensionFriendlyName; 28 | NDIS_STRING SxExtensionGuid; 29 | 30 | NDIS_STATUS 31 | SxpNdisProcessSetOid( 32 | __in PSX_SWITCH_OBJECT Switch, 33 | __inout PNDIS_OID_REQUEST OidRequest, 34 | __out PBOOLEAN Complete 35 | ); 36 | 37 | NDIS_STATUS 38 | SxpNdisProcessMethodOid( 39 | __in PSX_SWITCH_OBJECT Switch, 40 | __inout PNDIS_OID_REQUEST OidRequest, 41 | __out PBOOLEAN Complete, 42 | __out PULONG BytesNeeded 43 | ); 44 | 45 | 46 | // 47 | // DriverEntry 48 | // http://msdn.microsoft.com/en-us/library/ff544113(v=VS.85).aspx 49 | // 50 | _Use_decl_annotations_ 51 | NTSTATUS 52 | DriverEntry( 53 | PDRIVER_OBJECT DriverObject, 54 | PUNICODE_STRING RegistryPath 55 | ) 56 | { 57 | NDIS_STATUS status; 58 | NDIS_FILTER_DRIVER_CHARACTERISTICS fChars; 59 | NDIS_STRING serviceName; 60 | 61 | UNREFERENCED_PARAMETER(RegistryPath); 62 | 63 | // 64 | // Initialize extension specific data. 65 | // 66 | status = SxExtInitialize(); 67 | if (status != NDIS_STATUS_SUCCESS) 68 | { 69 | goto Cleanup; 70 | } 71 | 72 | RtlInitUnicodeString(&serviceName, SxExtServiceName); 73 | RtlInitUnicodeString(&SxExtensionFriendlyName, SxExtFriendlyName); 74 | RtlInitUnicodeString(&SxExtensionGuid, SxExtUniqueName); 75 | SxDriverObject = DriverObject; 76 | 77 | NdisZeroMemory(&fChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS)); 78 | fChars.Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS; 79 | fChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS); 80 | fChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_2; 81 | fChars.MajorNdisVersion = SxExtMajorNdisVersion; 82 | fChars.MinorNdisVersion = SxExtMinorNdisVersion; 83 | fChars.MajorDriverVersion = 1; 84 | fChars.MinorDriverVersion = 0; 85 | fChars.Flags = 0; 86 | fChars.FriendlyName = SxExtensionFriendlyName; 87 | fChars.UniqueName = SxExtensionGuid; 88 | fChars.ServiceName = serviceName; 89 | 90 | fChars.SetOptionsHandler = SxNdisSetOptions; 91 | fChars.SetFilterModuleOptionsHandler = SxNdisSetFilterModuleOptions; 92 | 93 | fChars.AttachHandler = SxNdisAttach; 94 | fChars.DetachHandler = SxNdisDetach; 95 | fChars.PauseHandler = SxNdisPause; 96 | fChars.RestartHandler = SxNdisRestart; 97 | 98 | fChars.SendNetBufferListsHandler = SxNdisSendNetBufferLists; 99 | fChars.SendNetBufferListsCompleteHandler = SxNdisSendNetBufferListsComplete; 100 | fChars.CancelSendNetBufferListsHandler = SxNdisCancelSendNetBufferLists; 101 | fChars.ReceiveNetBufferListsHandler = SxNdisReceiveNetBufferLists; 102 | fChars.ReturnNetBufferListsHandler = SxNdisReturnNetBufferLists; 103 | 104 | fChars.OidRequestHandler = SxNdisOidRequest; 105 | fChars.OidRequestCompleteHandler = SxNdisOidRequestComplete; 106 | fChars.CancelOidRequestHandler = SxNdisCancelOidRequest; 107 | 108 | fChars.NetPnPEventHandler = SxNdisNetPnPEvent; 109 | fChars.StatusHandler = SxNdisStatus; 110 | 111 | NdisAllocateSpinLock(&SxExtensionListLock); 112 | InitializeListHead(&SxExtensionList); 113 | 114 | DriverObject->DriverUnload = SxNdisUnload; 115 | 116 | status = NdisFRegisterFilterDriver(DriverObject, 117 | (NDIS_HANDLE)SxDriverObject, 118 | &fChars, 119 | &SxDriverHandle); 120 | 121 | Cleanup: 122 | 123 | if (status != NDIS_STATUS_SUCCESS) 124 | { 125 | if (SxDriverHandle != NULL) 126 | { 127 | NdisFDeregisterFilterDriver(SxDriverHandle); 128 | SxDriverHandle = NULL; 129 | } 130 | 131 | NdisFreeSpinLock(&SxExtensionListLock); 132 | 133 | SxExtUninitialize(); 134 | } 135 | 136 | return status; 137 | } 138 | 139 | 140 | // 141 | // Unload Routine 142 | // http://msdn.microsoft.com/en-us/library/ff564886(v=VS.85).aspx 143 | // 144 | _Use_decl_annotations_ 145 | VOID 146 | SxNdisUnload( 147 | PDRIVER_OBJECT DriverObject 148 | ) 149 | { 150 | UNREFERENCED_PARAMETER(DriverObject); 151 | 152 | SxExtUninitialize(); 153 | 154 | NdisFDeregisterFilterDriver(SxDriverHandle); 155 | NdisFreeSpinLock(&SxExtensionListLock); 156 | } 157 | 158 | 159 | // 160 | // FilterSetOptions Function 161 | // http://msdn.microsoft.com/en-us/library/ff549972(v=VS.85).aspx 162 | // 163 | _Use_decl_annotations_ 164 | NDIS_STATUS 165 | SxNdisSetOptions( 166 | NDIS_HANDLE NdisDriverHandle, 167 | NDIS_HANDLE DriverContext 168 | ) 169 | { 170 | UNREFERENCED_PARAMETER(NdisDriverHandle); 171 | UNREFERENCED_PARAMETER(DriverContext); 172 | return NDIS_STATUS_SUCCESS; 173 | } 174 | 175 | 176 | // 177 | // FilterSetModuleOptions Function 178 | // http://msdn.microsoft.com/en-us/library/ff549970(v=VS.85).aspx 179 | // 180 | _Use_decl_annotations_ 181 | NDIS_STATUS 182 | SxNdisSetFilterModuleOptions( 183 | NDIS_HANDLE FilterModuleContext 184 | ) 185 | { 186 | UNREFERENCED_PARAMETER(FilterModuleContext); 187 | return NDIS_STATUS_SUCCESS; 188 | } 189 | 190 | 191 | // 192 | // FilterAttach Function 193 | // http://msdn.microsoft.com/en-us/library/ff549905(v=VS.85).aspx 194 | // 195 | _Use_decl_annotations_ 196 | NDIS_STATUS 197 | SxNdisAttach( 198 | NDIS_HANDLE NdisFilterHandle, 199 | NDIS_HANDLE SxDriverContext, 200 | PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters 201 | ) 202 | { 203 | NDIS_STATUS status; 204 | NDIS_FILTER_ATTRIBUTES sxAttributes; 205 | ULONG switchObjectSize; 206 | NDIS_SWITCH_CONTEXT switchContext; 207 | NDIS_SWITCH_OPTIONAL_HANDLERS switchHandler; 208 | PSX_SWITCH_OBJECT switchObject; 209 | 210 | UNREFERENCED_PARAMETER(SxDriverContext); 211 | 212 | DEBUGP(DL_TRACE, ("===>SxAttach: NdisFilterHandle %p\n", NdisFilterHandle)); 213 | 214 | status = NDIS_STATUS_SUCCESS; 215 | switchObject = NULL; 216 | 217 | NT_ASSERT(SxDriverContext == (NDIS_HANDLE)SxDriverObject); 218 | 219 | if (AttachParameters->MiniportMediaType != NdisMedium802_3) 220 | { 221 | status = NDIS_STATUS_INVALID_PARAMETER; 222 | goto Cleanup; 223 | } 224 | 225 | switchHandler.Header.Type = NDIS_OBJECT_TYPE_SWITCH_OPTIONAL_HANDLERS; 226 | switchHandler.Header.Size = NDIS_SIZEOF_SWITCH_OPTIONAL_HANDLERS_REVISION_1; 227 | switchHandler.Header.Revision = NDIS_SWITCH_OPTIONAL_HANDLERS_REVISION_1; 228 | 229 | status = NdisFGetOptionalSwitchHandlers(NdisFilterHandle, 230 | &switchContext, 231 | &switchHandler); 232 | 233 | if (status != NDIS_STATUS_SUCCESS) 234 | { 235 | DEBUGP(DL_ERROR, 236 | ("SxAttach: Extension is running in non-switch environment.\n")); 237 | goto Cleanup; 238 | } 239 | 240 | switchObjectSize = sizeof(SX_SWITCH_OBJECT); 241 | switchObject = ExAllocatePoolWithTag(NonPagedPoolNx, 242 | switchObjectSize, 243 | SxExtAllocationTag); 244 | 245 | if (switchObject == NULL) 246 | { 247 | status = NDIS_STATUS_RESOURCES; 248 | goto Cleanup; 249 | } 250 | 251 | RtlZeroMemory(switchObject, switchObjectSize); 252 | 253 | // 254 | // Initialize NDIS related information. 255 | // 256 | switchObject->NdisFilterHandle = NdisFilterHandle; 257 | switchObject->NdisSwitchContext = switchContext; 258 | RtlCopyMemory(&switchObject->NdisSwitchHandlers, 259 | &switchHandler, 260 | sizeof(NDIS_SWITCH_OPTIONAL_HANDLERS)); 261 | 262 | // 263 | // Let the extension create its own context. 264 | // 265 | status = SxExtCreateSwitch(switchObject, 266 | &(switchObject->ExtensionContext)); 267 | 268 | if (status != NDIS_STATUS_SUCCESS) 269 | { 270 | goto Cleanup; 271 | } 272 | 273 | // 274 | // Register the object with NDIS because NDIS passes this object when it 275 | // calls into the driver. 276 | // 277 | NdisZeroMemory(&sxAttributes, sizeof(NDIS_FILTER_ATTRIBUTES)); 278 | sxAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1; 279 | sxAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES); 280 | sxAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES; 281 | sxAttributes.Flags = 0; 282 | 283 | NDIS_DECLARE_FILTER_MODULE_CONTEXT(SX_SWITCH_OBJECT); 284 | status = NdisFSetAttributes(NdisFilterHandle, switchObject, &sxAttributes); 285 | 286 | if (status != NDIS_STATUS_SUCCESS) 287 | { 288 | DEBUGP(DL_ERROR, ("SxBase: Failed to set attributes.\n")); 289 | goto Cleanup; 290 | } 291 | 292 | switchObject->ControlFlowState = SxSwitchAttached; 293 | switchObject->DataFlowState = SxSwitchPaused; 294 | 295 | NdisAcquireSpinLock(&SxExtensionListLock); 296 | InsertHeadList(&SxExtensionList, &switchObject->Link); 297 | NdisReleaseSpinLock(&SxExtensionListLock); 298 | 299 | Cleanup: 300 | 301 | if (status != NDIS_STATUS_SUCCESS) 302 | { 303 | if (switchObject != NULL) 304 | { 305 | ExFreePool(switchObject); 306 | } 307 | } 308 | 309 | DEBUGP(DL_TRACE, ("<===SxAttach: status %x\n", status)); 310 | 311 | return status; 312 | } 313 | 314 | 315 | // 316 | // FilterDetach Function 317 | // http://msdn.microsoft.com/en-us/library/ff549918(v=VS.85).aspx 318 | // 319 | _Use_decl_annotations_ 320 | VOID 321 | SxNdisDetach( 322 | NDIS_HANDLE FilterModuleContext 323 | ) 324 | { 325 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 326 | 327 | DEBUGP(DL_TRACE, ("===>SxDetach: SxInstance %p\n", FilterModuleContext)); 328 | 329 | // 330 | // The extension must be in paused state. 331 | // 332 | NT_ASSERT(switchObject->DataFlowState == SxSwitchPaused); 333 | switchObject->ControlFlowState = SxSwitchDetached; 334 | 335 | KeMemoryBarrier(); 336 | 337 | while(switchObject->PendingOidCount > 0) 338 | { 339 | NdisMSleep(1000); 340 | } 341 | 342 | SxExtDeleteSwitch(switchObject, switchObject->ExtensionContext); 343 | 344 | NdisAcquireSpinLock(&SxExtensionListLock); 345 | RemoveEntryList(&switchObject->Link); 346 | NdisReleaseSpinLock(&SxExtensionListLock); 347 | 348 | ExFreePool(switchObject); 349 | 350 | // 351 | // Alway return success. 352 | // 353 | DEBUGP(DL_TRACE, ("<===SxDetach Successfully\n")); 354 | 355 | return; 356 | } 357 | 358 | 359 | // 360 | // FilterRestart Function 361 | // http://msdn.microsoft.com/en-us/library/ff549962(v=VS.85).aspx 362 | // 363 | _Use_decl_annotations_ 364 | NDIS_STATUS 365 | SxNdisPause( 366 | NDIS_HANDLE FilterModuleContext, 367 | PNDIS_FILTER_PAUSE_PARAMETERS PauseParameters 368 | ) 369 | { 370 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)(FilterModuleContext); 371 | 372 | UNREFERENCED_PARAMETER(PauseParameters); 373 | 374 | DEBUGP(DL_TRACE, 375 | ("===>NDISLWF SxPause: SxInstance %p\n", FilterModuleContext)); 376 | 377 | SxExtPauseSwitch(switchObject, switchObject->ExtensionContext); 378 | 379 | // 380 | // Set the flag that the filter is going to pause. 381 | // 382 | NT_ASSERT(switchObject->DataFlowState == SxSwitchRunning); 383 | switchObject->DataFlowState = SxSwitchPaused; 384 | 385 | KeMemoryBarrier(); 386 | 387 | while(switchObject->PendingInjectedNblCount > 0) 388 | { 389 | NdisMSleep(1000); 390 | } 391 | 392 | DEBUGP(DL_TRACE, ("<===SxPause: status %x\n", NDIS_STATUS_SUCCESS)); 393 | 394 | return NDIS_STATUS_SUCCESS; 395 | } 396 | 397 | 398 | // 399 | // FilterPause Function 400 | // http://msdn.microsoft.com/en-us/library/ff549957(v=VS.85).aspx 401 | // 402 | _Use_decl_annotations_ 403 | NDIS_STATUS 404 | SxNdisRestart( 405 | NDIS_HANDLE FilterModuleContext, 406 | PNDIS_FILTER_RESTART_PARAMETERS RestartParameters 407 | ) 408 | { 409 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 410 | NDIS_STATUS status = NDIS_STATUS_SUCCESS; 411 | 412 | UNREFERENCED_PARAMETER(RestartParameters); 413 | 414 | DEBUGP(DL_TRACE, 415 | ("===>SxRestart: FilterModuleContext %p\n", FilterModuleContext)); 416 | 417 | status = SxExtRestartSwitch(switchObject, 418 | switchObject->ExtensionContext); 419 | if (status != NDIS_STATUS_SUCCESS) 420 | { 421 | status = NDIS_STATUS_RESOURCES; 422 | goto Cleanup; 423 | } 424 | 425 | NT_ASSERT(switchObject->DataFlowState == SxSwitchPaused); 426 | switchObject->DataFlowState = SxSwitchRunning; 427 | 428 | DEBUGP(DL_TRACE, 429 | ("<===SxRestart: FilterModuleContext %p, status %x\n", 430 | FilterModuleContext, 431 | NDIS_STATUS_SUCCESS)); 432 | 433 | Cleanup: 434 | return status; 435 | } 436 | 437 | 438 | // 439 | // FilterOidRequest Function 440 | // http://msdn.microsoft.com/en-us/library/ff549954(v=VS.85).aspx 441 | // 442 | _Use_decl_annotations_ 443 | NDIS_STATUS 444 | SxNdisOidRequest( 445 | NDIS_HANDLE FilterModuleContext, 446 | PNDIS_OID_REQUEST OidRequest 447 | ) 448 | { 449 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 450 | NDIS_STATUS status; 451 | PNDIS_OID_REQUEST clonedRequest=NULL; 452 | PVOID *cloneRequestContext; 453 | BOOLEAN completeOid = FALSE; 454 | ULONG bytesNeeded = 0; 455 | 456 | status = NDIS_STATUS_SUCCESS; 457 | 458 | DEBUGP(DL_TRACE, ("===>SxOidRequest: OidRequest %p.\n", OidRequest)); 459 | 460 | NdisInterlockedIncrement(&switchObject->PendingOidCount); 461 | 462 | status = NdisAllocateCloneOidRequest(switchObject->NdisFilterHandle, 463 | OidRequest, 464 | SxExtAllocationTag, 465 | &clonedRequest); 466 | if (status != NDIS_STATUS_SUCCESS) 467 | { 468 | DEBUGP(DL_WARN, ("FilerOidRequest: Cannot Clone OidRequest\n")); 469 | goto Cleanup; 470 | } 471 | 472 | cloneRequestContext = (PVOID*)(&clonedRequest->SourceReserved[0]); 473 | *cloneRequestContext = OidRequest; 474 | 475 | switch (clonedRequest->RequestType) 476 | { 477 | case NdisRequestSetInformation: 478 | status = SxpNdisProcessSetOid(switchObject, 479 | clonedRequest, 480 | &completeOid); 481 | break; 482 | 483 | case NdisRequestMethod: 484 | status = SxpNdisProcessMethodOid(switchObject, 485 | clonedRequest, 486 | &completeOid, 487 | &bytesNeeded); 488 | 489 | break; 490 | } 491 | 492 | if (completeOid) 493 | { 494 | NdisFreeCloneOidRequest(switchObject->NdisFilterHandle, clonedRequest); 495 | OidRequest->DATA.METHOD_INFORMATION.BytesNeeded = bytesNeeded; 496 | NdisInterlockedDecrement(&switchObject->PendingOidCount); 497 | goto Cleanup; 498 | } 499 | 500 | status = NdisFOidRequest(switchObject->NdisFilterHandle, clonedRequest); 501 | 502 | if (status != NDIS_STATUS_PENDING) 503 | { 504 | SxNdisOidRequestComplete(switchObject, clonedRequest, status); 505 | 506 | // 507 | // We must still return status as pending because we complete the 508 | // request using NdisFOidRequestComplete() in SxOidRequestComplete(). 509 | // 510 | status = NDIS_STATUS_PENDING; 511 | } 512 | 513 | Cleanup: 514 | 515 | DEBUGP(DL_TRACE, ("<===SxOidRequest: status %8x.\n", status)); 516 | return status; 517 | } 518 | 519 | 520 | // 521 | // FilterCancelOidRequest Function 522 | // http://msdn.microsoft.com/en-us/library/ff549911(v=VS.85).aspx 523 | // 524 | _Use_decl_annotations_ 525 | VOID 526 | SxNdisCancelOidRequest( 527 | NDIS_HANDLE FilterModuleContext, 528 | PVOID RequestId 529 | ) 530 | { 531 | UNREFERENCED_PARAMETER(FilterModuleContext); 532 | UNREFERENCED_PARAMETER(RequestId); 533 | } 534 | 535 | 536 | // 537 | // FilterOidRequestComplete Function 538 | // http://msdn.microsoft.com/en-us/library/ff549956(v=VS.85).aspx 539 | // 540 | _Use_decl_annotations_ 541 | VOID 542 | SxNdisOidRequestComplete( 543 | NDIS_HANDLE FilterModuleContext, 544 | PNDIS_OID_REQUEST NdisOidRequest, 545 | NDIS_STATUS Status 546 | ) 547 | { 548 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 549 | PNDIS_OID_REQUEST originalRequest; 550 | PVOID *oidRequestContext; 551 | PNDIS_SWITCH_NIC_OID_REQUEST nicOidRequestBuf; 552 | PNDIS_OBJECT_HEADER header; 553 | 554 | DEBUGP(DL_TRACE, 555 | ("===>SxOidRequestComplete, NdisOidRequest %p.\n", NdisOidRequest)); 556 | 557 | oidRequestContext = (PVOID*)(&NdisOidRequest->SourceReserved[0]); 558 | originalRequest = (*oidRequestContext); 559 | 560 | // 561 | // This is the internal request 562 | // 563 | if (originalRequest == NULL) 564 | { 565 | SxpNdisCompleteInternalOidRequest(switchObject, NdisOidRequest, Status); 566 | goto Cleanup; 567 | } 568 | 569 | // 570 | // Copy the information from the returned request to the original request 571 | // 572 | switch(NdisOidRequest->RequestType) 573 | { 574 | case NdisRequestMethod: 575 | originalRequest->DATA.METHOD_INFORMATION.OutputBufferLength = 576 | NdisOidRequest->DATA.METHOD_INFORMATION.OutputBufferLength; 577 | originalRequest->DATA.METHOD_INFORMATION.BytesRead = 578 | NdisOidRequest->DATA.METHOD_INFORMATION.BytesRead; 579 | originalRequest->DATA.METHOD_INFORMATION.BytesNeeded = 580 | NdisOidRequest->DATA.METHOD_INFORMATION.BytesNeeded; 581 | originalRequest->DATA.METHOD_INFORMATION.BytesWritten = 582 | NdisOidRequest->DATA.METHOD_INFORMATION.BytesWritten; 583 | 584 | if (NdisOidRequest->DATA.METHOD_INFORMATION.Oid == OID_SWITCH_NIC_REQUEST && 585 | switchObject->OldNicRequest != NULL) 586 | { 587 | nicOidRequestBuf = NdisOidRequest->DATA.METHOD_INFORMATION.InformationBuffer; 588 | Status = SxExtProcessNicRequestComplete(switchObject, 589 | switchObject->ExtensionContext, 590 | nicOidRequestBuf->OidRequest, 591 | nicOidRequestBuf->SourcePortId, 592 | nicOidRequestBuf->SourceNicIndex, 593 | nicOidRequestBuf->DestinationPortId, 594 | nicOidRequestBuf->DestinationNicIndex, 595 | Status); 596 | 597 | originalRequest->DATA.METHOD_INFORMATION.InformationBuffer = 598 | switchObject->OldNicRequest; 599 | switchObject->OldNicRequest = NULL; 600 | ExFreePoolWithTag(nicOidRequestBuf, SxExtAllocationTag); 601 | } 602 | 603 | break; 604 | 605 | case NdisRequestSetInformation: 606 | header = originalRequest->DATA.SET_INFORMATION.InformationBuffer; 607 | 608 | originalRequest->DATA.SET_INFORMATION.BytesRead = 609 | NdisOidRequest->DATA.SET_INFORMATION.BytesRead; 610 | originalRequest->DATA.SET_INFORMATION.BytesNeeded = 611 | NdisOidRequest->DATA.SET_INFORMATION.BytesNeeded; 612 | 613 | if (NdisOidRequest->DATA.METHOD_INFORMATION.Oid == OID_SWITCH_PORT_CREATE && 614 | Status != NDIS_STATUS_SUCCESS) 615 | { 616 | SxExtDeletePort(switchObject, 617 | switchObject->ExtensionContext, 618 | (PNDIS_SWITCH_PORT_PARAMETERS)header); 619 | } 620 | else if (NdisOidRequest->DATA.METHOD_INFORMATION.Oid == OID_SWITCH_PORT_CREATE && 621 | Status != NDIS_STATUS_SUCCESS) 622 | { 623 | SxExtDeleteNic(switchObject, 624 | switchObject->ExtensionContext, 625 | (PNDIS_SWITCH_NIC_PARAMETERS)header); 626 | 627 | } 628 | 629 | break; 630 | 631 | case NdisRequestQueryInformation: 632 | case NdisRequestQueryStatistics: 633 | default: 634 | originalRequest->DATA.QUERY_INFORMATION.BytesWritten = 635 | NdisOidRequest->DATA.QUERY_INFORMATION.BytesWritten; 636 | originalRequest->DATA.QUERY_INFORMATION.BytesNeeded = 637 | NdisOidRequest->DATA.QUERY_INFORMATION.BytesNeeded; 638 | break; 639 | } 640 | 641 | (*oidRequestContext) = NULL; 642 | 643 | NdisFreeCloneOidRequest(switchObject->NdisFilterHandle, NdisOidRequest); 644 | 645 | NdisFOidRequestComplete(switchObject->NdisFilterHandle, 646 | originalRequest, 647 | Status); 648 | 649 | DEBUGP(DL_TRACE, ("<===SxOidRequestComplete.\n")); 650 | 651 | Cleanup: 652 | NdisInterlockedDecrement(&switchObject->PendingOidCount); 653 | } 654 | 655 | 656 | // 657 | // FilterSendNetBufferLists Function 658 | // http://msdn.microsoft.com/en-us/library/ff549966(v=VS.85).aspx 659 | // 660 | _Use_decl_annotations_ 661 | VOID 662 | SxNdisSendNetBufferLists( 663 | NDIS_HANDLE FilterModuleContext, 664 | PNET_BUFFER_LIST NetBufferLists, 665 | NDIS_PORT_NUMBER PortNumber, 666 | ULONG SendFlags 667 | ) 668 | { 669 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 670 | 671 | UNREFERENCED_PARAMETER(PortNumber); 672 | 673 | SxExtStartNetBufferListsIngress(switchObject, 674 | switchObject->ExtensionContext, 675 | NetBufferLists, 676 | SendFlags); 677 | } 678 | 679 | 680 | // 681 | // FilterSendNetBufferListsComplete Function 682 | // http://msdn.microsoft.com/en-us/library/ff549967(v=VS.85).aspx 683 | // 684 | _Use_decl_annotations_ 685 | VOID 686 | SxNdisSendNetBufferListsComplete( 687 | NDIS_HANDLE FilterModuleContext, 688 | PNET_BUFFER_LIST NetBufferLists, 689 | ULONG SendCompleteFlags 690 | ) 691 | { 692 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 693 | 694 | SxExtStartCompleteNetBufferListsIngress(switchObject, 695 | switchObject->ExtensionContext, 696 | NetBufferLists, 697 | SendCompleteFlags); 698 | } 699 | 700 | 701 | // 702 | // FilterReceiveNetBufferLists Function 703 | // http://msdn.microsoft.com/en-us/library/ff549960(v=VS.85).aspx 704 | // 705 | _Use_decl_annotations_ 706 | VOID 707 | SxNdisReceiveNetBufferLists( 708 | NDIS_HANDLE FilterModuleContext, 709 | PNET_BUFFER_LIST NetBufferLists, 710 | NDIS_PORT_NUMBER PortNumber, 711 | ULONG NumberOfNetBufferLists, 712 | ULONG ReceiveFlags 713 | ) 714 | { 715 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 716 | 717 | UNREFERENCED_PARAMETER(PortNumber); 718 | 719 | SxExtStartNetBufferListsEgress(switchObject, 720 | switchObject->ExtensionContext, 721 | NetBufferLists, 722 | NumberOfNetBufferLists, 723 | ReceiveFlags); 724 | } 725 | 726 | 727 | // 728 | // FilterReturnNetBufferLists Function 729 | // http://msdn.microsoft.com/en-us/library/ff549964(v=VS.85).aspx 730 | // 731 | _Use_decl_annotations_ 732 | VOID 733 | SxNdisReturnNetBufferLists( 734 | NDIS_HANDLE FilterModuleContext, 735 | PNET_BUFFER_LIST NetBufferLists, 736 | ULONG ReturnFlags 737 | ) 738 | { 739 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 740 | 741 | SxExtStartCompleteNetBufferListsEgress(switchObject, 742 | switchObject->ExtensionContext, 743 | NetBufferLists, 744 | ReturnFlags); 745 | } 746 | 747 | 748 | // 749 | // FilterCancelSendNetBufferLists Function 750 | // http://msdn.microsoft.com/en-us/library/ff549915(v=VS.85).aspx 751 | // 752 | _Use_decl_annotations_ 753 | VOID 754 | SxNdisCancelSendNetBufferLists( 755 | NDIS_HANDLE FilterModuleContext, 756 | PVOID CancelId 757 | ) 758 | { 759 | UNREFERENCED_PARAMETER(FilterModuleContext); 760 | UNREFERENCED_PARAMETER(CancelId); 761 | } 762 | 763 | 764 | // 765 | // FilterNetPnPEvent Function 766 | // http://msdn.microsoft.com/en-us/library/ff549952(v=vs.85).aspx 767 | // 768 | _Use_decl_annotations_ 769 | NDIS_STATUS 770 | SxNdisNetPnPEvent( 771 | NDIS_HANDLE FilterModuleContext, 772 | PNET_PNP_EVENT_NOTIFICATION NetPnPEvent 773 | ) 774 | { 775 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 776 | 777 | if (NetPnPEvent->NetPnPEvent.NetEvent == NetEventSwitchActivate) 778 | { 779 | // 780 | // Switch Activation must be passed along regardless of successful 781 | // initialization. 782 | // 783 | SxExtActivateSwitch(switchObject, 784 | switchObject->ExtensionContext); 785 | } 786 | 787 | return NdisFNetPnPEvent(switchObject->NdisFilterHandle, 788 | NetPnPEvent); 789 | } 790 | 791 | 792 | // 793 | // FilterStatus Function 794 | // http://msdn.microsoft.com/en-us/library/ff549973(v=VS.85).aspx 795 | // 796 | _Use_decl_annotations_ 797 | VOID 798 | SxNdisStatus( 799 | NDIS_HANDLE FilterModuleContext, 800 | PNDIS_STATUS_INDICATION StatusIndication 801 | ) 802 | { 803 | NDIS_STATUS status = NDIS_STATUS_SUCCESS; 804 | PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; 805 | PNDIS_SWITCH_NIC_STATUS_INDICATION nicIndication; 806 | PNDIS_STATUS_INDICATION originalIndication; 807 | 808 | if (StatusIndication->Header.Type != NDIS_OBJECT_TYPE_STATUS_INDICATION || 809 | StatusIndication->Header.Revision != NDIS_STATUS_INDICATION_REVISION_1 || 810 | StatusIndication->Header.Size < NDIS_SIZEOF_STATUS_INDICATION_REVISION_1) 811 | { 812 | goto Cleanup; 813 | } 814 | 815 | // 816 | // Only NDIS_STATUS_SWITCH_NIC_STAUTUS indications need to be processed 817 | // by switch extensions. 818 | // 819 | if (StatusIndication->StatusCode != NDIS_STATUS_SWITCH_NIC_STATUS) 820 | { 821 | goto Cleanup; 822 | } 823 | 824 | nicIndication = StatusIndication->StatusBuffer; 825 | 826 | if (nicIndication->Header.Type != NDIS_OBJECT_TYPE_STATUS_INDICATION || 827 | nicIndication->Header.Revision != NDIS_SWITCH_NIC_STATUS_INDICATION_REVISION_1 || 828 | nicIndication->Header.Size < NDIS_SIZEOF_SWITCH_NIC_STATUS_REVISION_1) 829 | { 830 | goto Cleanup; 831 | } 832 | 833 | originalIndication = nicIndication->StatusIndication; 834 | 835 | status = SxExtProcessNicStatus(switchObject, 836 | switchObject->ExtensionContext, 837 | originalIndication, 838 | nicIndication->SourcePortId, 839 | nicIndication->SourceNicIndex); 840 | 841 | Cleanup: 842 | if (status == NDIS_STATUS_SUCCESS) 843 | { 844 | NdisFIndicateStatus(switchObject->NdisFilterHandle, 845 | StatusIndication); 846 | } 847 | 848 | return; 849 | 850 | } 851 | 852 | 853 | NDIS_STATUS 854 | SxpNdisProcessSetOid( 855 | __in PSX_SWITCH_OBJECT Switch, 856 | __inout PNDIS_OID_REQUEST OidRequest, 857 | __out PBOOLEAN Complete 858 | ) 859 | { 860 | NDIS_STATUS status = NDIS_STATUS_SUCCESS; 861 | NDIS_OID oid = OidRequest->DATA.SET_INFORMATION.Oid; 862 | PNDIS_OBJECT_HEADER header; 863 | ULONG bytesRestored = 0; 864 | 865 | *Complete = FALSE; 866 | 867 | header = OidRequest->DATA.SET_INFORMATION.InformationBuffer; 868 | 869 | if (OidRequest->DATA.SET_INFORMATION.InformationBufferLength != 0 && 870 | OidRequest->DATA.SET_INFORMATION.InformationBufferLength < 871 | sizeof(NDIS_OBJECT_HEADER)) 872 | { 873 | status = NDIS_STATUS_NOT_SUPPORTED; 874 | *Complete = TRUE; 875 | goto Cleanup; 876 | } 877 | 878 | if (OidRequest->DATA.SET_INFORMATION.InformationBufferLength == 0) 879 | { 880 | *Complete = FALSE; 881 | goto Cleanup; 882 | } 883 | 884 | switch(oid) 885 | { 886 | case OID_SWITCH_PROPERTY_ADD: 887 | case OID_SWITCH_PROPERTY_UPDATE: 888 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 889 | header->Revision < NDIS_SWITCH_PROPERTY_PARAMETERS_REVISION_1 || 890 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_PROPERTY_PARAMETERS_REVISION_1) 891 | { 892 | status = NDIS_STATUS_NOT_SUPPORTED; 893 | *Complete = TRUE; 894 | goto Cleanup; 895 | } 896 | 897 | if (oid == OID_SWITCH_PROPERTY_ADD) 898 | { 899 | status = SxExtAddSwitchProperty(Switch, 900 | Switch->ExtensionContext, 901 | (PNDIS_SWITCH_PROPERTY_PARAMETERS)header); 902 | } 903 | else 904 | { 905 | status = SxExtUpdateSwitchProperty(Switch, 906 | Switch->ExtensionContext, 907 | (PNDIS_SWITCH_PROPERTY_PARAMETERS)header); 908 | } 909 | 910 | if (status == NDIS_STATUS_NOT_SUPPORTED) 911 | { 912 | status = NDIS_STATUS_SUCCESS; 913 | } 914 | else 915 | { 916 | *Complete = TRUE; 917 | goto Cleanup; 918 | } 919 | 920 | break; 921 | case OID_SWITCH_PROPERTY_DELETE: 922 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 923 | header->Revision < NDIS_SWITCH_PROPERTY_DELETE_PARAMETERS_REVISION_1 || 924 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_PROPERTY_DELETE_PARAMETERS_REVISION_1) 925 | { 926 | status = NDIS_STATUS_NOT_SUPPORTED; 927 | *Complete = TRUE; 928 | goto Cleanup; 929 | } 930 | 931 | *Complete = SxExtDeleteSwitchProperty(Switch, 932 | Switch->ExtensionContext, 933 | (PNDIS_SWITCH_PROPERTY_DELETE_PARAMETERS)header); 934 | 935 | break; 936 | 937 | case OID_SWITCH_PORT_PROPERTY_ADD: 938 | case OID_SWITCH_PORT_PROPERTY_UPDATE: 939 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 940 | header->Revision < NDIS_SWITCH_PORT_PROPERTY_PARAMETERS_REVISION_1 || 941 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_PORT_PROPERTY_PARAMETERS_REVISION_1) 942 | { 943 | status = NDIS_STATUS_NOT_SUPPORTED; 944 | *Complete = TRUE; 945 | goto Cleanup; 946 | } 947 | 948 | if (oid == OID_SWITCH_PORT_PROPERTY_ADD) 949 | { 950 | status = SxExtAddPortProperty(Switch, 951 | Switch->ExtensionContext, 952 | (PNDIS_SWITCH_PORT_PROPERTY_PARAMETERS)header); 953 | } 954 | else 955 | { 956 | status = SxExtUpdatePortProperty(Switch, 957 | Switch->ExtensionContext, 958 | (PNDIS_SWITCH_PORT_PROPERTY_PARAMETERS)header); 959 | } 960 | 961 | if (status == NDIS_STATUS_NOT_SUPPORTED) 962 | { 963 | status = NDIS_STATUS_SUCCESS; 964 | } 965 | else 966 | { 967 | *Complete = TRUE; 968 | goto Cleanup; 969 | } 970 | 971 | break; 972 | 973 | case OID_SWITCH_PORT_PROPERTY_DELETE: 974 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 975 | header->Revision < NDIS_SWITCH_PORT_PROPERTY_DELETE_PARAMETERS_REVISION_1 || 976 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_PORT_PROPERTY_DELETE_PARAMETERS_REVISION_1) 977 | { 978 | status = NDIS_STATUS_NOT_SUPPORTED; 979 | *Complete = TRUE; 980 | goto Cleanup; 981 | } 982 | 983 | *Complete = SxExtDeletePortProperty(Switch, 984 | Switch->ExtensionContext, 985 | (PNDIS_SWITCH_PORT_PROPERTY_DELETE_PARAMETERS)header); 986 | 987 | break; 988 | 989 | case OID_SWITCH_PORT_CREATE: 990 | case OID_SWITCH_PORT_UPDATED: 991 | case OID_SWITCH_PORT_TEARDOWN: 992 | case OID_SWITCH_PORT_DELETE: 993 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 994 | header->Revision < NDIS_SWITCH_PORT_PARAMETERS_REVISION_1 || 995 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_PORT_PARAMETERS_REVISION_1) 996 | { 997 | status = NDIS_STATUS_NOT_SUPPORTED; 998 | *Complete = TRUE; 999 | goto Cleanup; 1000 | } 1001 | 1002 | if (oid == OID_SWITCH_PORT_CREATE) 1003 | { 1004 | status = SxExtCreatePort(Switch, 1005 | Switch->ExtensionContext, 1006 | (PNDIS_SWITCH_PORT_PARAMETERS)header); 1007 | 1008 | if (status != NDIS_STATUS_SUCCESS) 1009 | { 1010 | *Complete = TRUE; 1011 | } 1012 | } 1013 | else if (oid == OID_SWITCH_PORT_UPDATED) 1014 | { 1015 | SxExtUpdatePort(Switch, 1016 | Switch->ExtensionContext, 1017 | (PNDIS_SWITCH_PORT_PARAMETERS)header); 1018 | } 1019 | else if (oid == OID_SWITCH_PORT_TEARDOWN) 1020 | { 1021 | SxExtTeardownPort(Switch, 1022 | Switch->ExtensionContext, 1023 | (PNDIS_SWITCH_PORT_PARAMETERS)header); 1024 | } 1025 | else 1026 | { 1027 | SxExtDeletePort(Switch, 1028 | Switch->ExtensionContext, 1029 | (PNDIS_SWITCH_PORT_PARAMETERS)header); 1030 | } 1031 | 1032 | break; 1033 | 1034 | case OID_SWITCH_NIC_CREATE: 1035 | case OID_SWITCH_NIC_CONNECT: 1036 | case OID_SWITCH_NIC_UPDATED: 1037 | case OID_SWITCH_NIC_DISCONNECT: 1038 | case OID_SWITCH_NIC_DELETE: 1039 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 1040 | header->Revision < NDIS_SWITCH_NIC_PARAMETERS_REVISION_1 || 1041 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_NIC_PARAMETERS_REVISION_1) 1042 | { 1043 | status = NDIS_STATUS_NOT_SUPPORTED; 1044 | *Complete = TRUE; 1045 | goto Cleanup; 1046 | } 1047 | 1048 | if (oid == OID_SWITCH_NIC_CREATE) 1049 | { 1050 | status = SxExtCreateNic(Switch, 1051 | Switch->ExtensionContext, 1052 | (PNDIS_SWITCH_NIC_PARAMETERS)header); 1053 | if (status != NDIS_STATUS_SUCCESS) 1054 | { 1055 | *Complete = TRUE; 1056 | } 1057 | } 1058 | else if (oid == OID_SWITCH_NIC_CONNECT) 1059 | { 1060 | SxExtConnectNic(Switch, 1061 | Switch->ExtensionContext, 1062 | (PNDIS_SWITCH_NIC_PARAMETERS)header); 1063 | } 1064 | else if (oid == OID_SWITCH_NIC_UPDATED) 1065 | { 1066 | SxExtUpdateNic(Switch, 1067 | Switch->ExtensionContext, 1068 | (PNDIS_SWITCH_NIC_PARAMETERS)header); 1069 | } 1070 | else if (oid == OID_SWITCH_NIC_DISCONNECT) 1071 | { 1072 | SxExtDisconnectNic(Switch, 1073 | Switch->ExtensionContext, 1074 | (PNDIS_SWITCH_NIC_PARAMETERS)header); 1075 | } 1076 | else 1077 | { 1078 | SxExtDeleteNic(Switch, 1079 | Switch->ExtensionContext, 1080 | (PNDIS_SWITCH_NIC_PARAMETERS)header); 1081 | } 1082 | 1083 | break; 1084 | 1085 | case OID_SWITCH_NIC_RESTORE: 1086 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 1087 | header->Revision < NDIS_SWITCH_NIC_SAVE_STATE_REVISION_1 || 1088 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_NIC_SAVE_STATE_REVISION_1) 1089 | { 1090 | status = NDIS_STATUS_NOT_SUPPORTED; 1091 | goto Cleanup; 1092 | } 1093 | 1094 | status = SxExtNicRestore(Switch, 1095 | Switch->ExtensionContext, 1096 | (PNDIS_SWITCH_NIC_SAVE_STATE)header, 1097 | &bytesRestored); 1098 | 1099 | if (status != NDIS_STATUS_SUCCESS) 1100 | { 1101 | *Complete = TRUE; 1102 | } 1103 | else if (bytesRestored > 0) 1104 | { 1105 | *Complete = TRUE; 1106 | } 1107 | 1108 | break; 1109 | 1110 | case OID_SWITCH_NIC_SAVE_COMPLETE: 1111 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 1112 | header->Revision < NDIS_SWITCH_NIC_SAVE_STATE_REVISION_1 || 1113 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_NIC_SAVE_STATE_REVISION_1) 1114 | { 1115 | status = NDIS_STATUS_NOT_SUPPORTED; 1116 | *Complete = TRUE; 1117 | goto Cleanup; 1118 | } 1119 | 1120 | SxExtSaveNicComplete(Switch, 1121 | Switch->ExtensionContext, 1122 | (PNDIS_SWITCH_NIC_SAVE_STATE)header); 1123 | 1124 | break; 1125 | 1126 | case OID_SWITCH_NIC_RESTORE_COMPLETE: 1127 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 1128 | header->Revision < NDIS_SWITCH_NIC_SAVE_STATE_REVISION_1 || 1129 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_NIC_SAVE_STATE_REVISION_1) 1130 | { 1131 | status = NDIS_STATUS_NOT_SUPPORTED; 1132 | *Complete = TRUE; 1133 | goto Cleanup; 1134 | } 1135 | 1136 | SxExtNicRestoreComplete(Switch, 1137 | Switch->ExtensionContext, 1138 | (PNDIS_SWITCH_NIC_SAVE_STATE)header); 1139 | 1140 | break; 1141 | 1142 | default: 1143 | break; 1144 | } 1145 | 1146 | Cleanup: 1147 | return status; 1148 | } 1149 | 1150 | 1151 | NDIS_STATUS 1152 | SxpNdisProcessMethodOid( 1153 | __in PSX_SWITCH_OBJECT Switch, 1154 | __inout PNDIS_OID_REQUEST OidRequest, 1155 | __out PBOOLEAN Complete, 1156 | __out PULONG BytesNeeded 1157 | ) 1158 | { 1159 | NDIS_STATUS status = NDIS_STATUS_SUCCESS; 1160 | NDIS_OID oid = OidRequest->DATA.SET_INFORMATION.Oid; 1161 | PNDIS_OBJECT_HEADER header; 1162 | PNDIS_SWITCH_NIC_OID_REQUEST nicOidRequest; 1163 | PNDIS_SWITCH_NIC_OID_REQUEST newNicOidRequest = NULL; 1164 | NDIS_SWITCH_PORT_ID destPort, sourcePort; 1165 | NDIS_SWITCH_NIC_INDEX destNic, sourceNic; 1166 | ULONG bytesWritten = 0; 1167 | ULONG bytesNeeded = 0; 1168 | 1169 | *Complete = FALSE; 1170 | *BytesNeeded = 0; 1171 | 1172 | header = OidRequest->DATA.METHOD_INFORMATION.InformationBuffer; 1173 | 1174 | switch(oid) 1175 | { 1176 | case OID_SWITCH_FEATURE_STATUS_QUERY: 1177 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 1178 | header->Revision < NDIS_SWITCH_FEATURE_STATUS_PARAMETERS_REVISION_1 || 1179 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_FEATURE_STATUS_PARAMETERS_REVISION_1) 1180 | { 1181 | status = NDIS_STATUS_NOT_SUPPORTED; 1182 | *Complete = TRUE; 1183 | goto Cleanup; 1184 | } 1185 | 1186 | *Complete = SxExtQuerySwitchFeatureStatus(Switch, 1187 | Switch->ExtensionContext, 1188 | (PNDIS_SWITCH_FEATURE_STATUS_PARAMETERS)header, 1189 | BytesNeeded); 1190 | 1191 | if (*BytesNeeded > 0) 1192 | { 1193 | status = NDIS_STATUS_BUFFER_TOO_SHORT; 1194 | } 1195 | 1196 | break; 1197 | 1198 | case OID_SWITCH_PORT_FEATURE_STATUS_QUERY: 1199 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 1200 | header->Revision < NDIS_SWITCH_FEATURE_STATUS_PARAMETERS_REVISION_1 || 1201 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_FEATURE_STATUS_PARAMETERS_REVISION_1) 1202 | { 1203 | status = NDIS_STATUS_NOT_SUPPORTED; 1204 | *Complete = TRUE; 1205 | goto Cleanup; 1206 | } 1207 | 1208 | *Complete = SxExtQueryPortFeatureStatus(Switch, 1209 | Switch->ExtensionContext, 1210 | (PNDIS_SWITCH_PORT_FEATURE_STATUS_PARAMETERS)header, 1211 | BytesNeeded); 1212 | 1213 | if (*BytesNeeded > 0) 1214 | { 1215 | status = NDIS_STATUS_BUFFER_TOO_SHORT; 1216 | } 1217 | 1218 | break; 1219 | 1220 | case OID_SWITCH_NIC_REQUEST: 1221 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 1222 | header->Revision < NDIS_SWITCH_NIC_OID_REQUEST_REVISION_1 || 1223 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_NIC_OID_REQUEST_REVISION_1) 1224 | { 1225 | status = NDIS_STATUS_NOT_SUPPORTED; 1226 | *Complete = TRUE; 1227 | goto Cleanup; 1228 | } 1229 | 1230 | nicOidRequest = (PNDIS_SWITCH_NIC_OID_REQUEST)header; 1231 | 1232 | sourcePort = nicOidRequest->SourcePortId; 1233 | sourceNic = nicOidRequest->SourceNicIndex; 1234 | destPort = nicOidRequest->DestinationPortId; 1235 | destNic = nicOidRequest->DestinationNicIndex; 1236 | 1237 | status = SxExtProcessNicRequest(Switch, 1238 | Switch->ExtensionContext, 1239 | nicOidRequest->OidRequest, 1240 | &sourcePort, 1241 | &sourceNic, 1242 | &destPort, 1243 | &destNic); 1244 | 1245 | if (status != NDIS_STATUS_SUCCESS) 1246 | { 1247 | *Complete = TRUE; 1248 | goto Cleanup; 1249 | } 1250 | 1251 | if (sourcePort != nicOidRequest->SourcePortId || 1252 | sourceNic != nicOidRequest->SourceNicIndex || 1253 | destPort != nicOidRequest->DestinationPortId || 1254 | destNic != nicOidRequest->DestinationNicIndex) 1255 | { 1256 | ASSERT(Switch->OldNicRequest == NULL); 1257 | Switch->OldNicRequest = nicOidRequest; 1258 | 1259 | newNicOidRequest = (PNDIS_SWITCH_NIC_OID_REQUEST)ExAllocatePoolWithTag( 1260 | NonPagedPoolNx, 1261 | sizeof(NDIS_SWITCH_NIC_OID_REQUEST), 1262 | SxExtAllocationTag); 1263 | 1264 | if (newNicOidRequest == NULL) 1265 | { 1266 | status = NDIS_STATUS_RESOURCES; 1267 | *Complete = TRUE; 1268 | goto Cleanup; 1269 | } 1270 | 1271 | newNicOidRequest->Header = nicOidRequest->Header; 1272 | newNicOidRequest->SourcePortId = sourcePort; 1273 | newNicOidRequest->SourceNicIndex = sourceNic; 1274 | newNicOidRequest->DestinationPortId = destPort; 1275 | newNicOidRequest->DestinationNicIndex = destNic; 1276 | newNicOidRequest->OidRequest = nicOidRequest->OidRequest; 1277 | 1278 | OidRequest->DATA.METHOD_INFORMATION.InformationBuffer = newNicOidRequest; 1279 | } 1280 | 1281 | break; 1282 | 1283 | case OID_SWITCH_NIC_SAVE: 1284 | if (header->Type != NDIS_OBJECT_TYPE_DEFAULT || 1285 | header->Revision < NDIS_SWITCH_NIC_SAVE_STATE_REVISION_1 || 1286 | header->Size < NDIS_SIZEOF_NDIS_SWITCH_NIC_SAVE_STATE_REVISION_1) 1287 | { 1288 | status = NDIS_STATUS_NOT_SUPPORTED; 1289 | *Complete = TRUE; 1290 | goto Cleanup; 1291 | } 1292 | 1293 | status = SxExtSaveNic(Switch, 1294 | Switch->ExtensionContext, 1295 | (PNDIS_SWITCH_NIC_SAVE_STATE)header, 1296 | &bytesWritten, 1297 | &bytesNeeded); 1298 | 1299 | if (status == NDIS_STATUS_SUCCESS && 1300 | bytesWritten > 0) 1301 | { 1302 | *Complete = TRUE; 1303 | } 1304 | else if (status == NDIS_STATUS_BUFFER_TOO_SHORT) 1305 | { 1306 | *BytesNeeded = ((PNDIS_SWITCH_NIC_SAVE_STATE)header)->SaveDataOffset + 1307 | bytesNeeded; 1308 | *Complete = TRUE; 1309 | } 1310 | else if (status != NDIS_STATUS_SUCCESS) 1311 | { 1312 | *Complete = TRUE; 1313 | } 1314 | 1315 | break; 1316 | 1317 | default: 1318 | break; 1319 | } 1320 | 1321 | Cleanup: 1322 | return status; 1323 | } 1324 | 1325 | 1326 | VOID 1327 | SxpNdisCompleteInternalOidRequest( 1328 | __in PSX_SWITCH_OBJECT Switch, 1329 | __in PNDIS_OID_REQUEST NdisRequest, 1330 | __in NDIS_STATUS Status 1331 | ) 1332 | /*++ 1333 | 1334 | Routine Description: 1335 | 1336 | NDIS entry point indicating completion of a pended NDIS_OID_REQUEST. 1337 | 1338 | Arguments: 1339 | 1340 | Switch - pointer to switch object. 1341 | 1342 | NdisRequest - pointer to NDIS request 1343 | 1344 | Status - Status of request completion 1345 | 1346 | Return Value: 1347 | 1348 | None 1349 | 1350 | --*/ 1351 | { 1352 | PSX_OID_REQUEST oidRequest; 1353 | ULONG bytesNeeded; 1354 | 1355 | UNREFERENCED_PARAMETER(Switch); 1356 | 1357 | bytesNeeded = 0; 1358 | oidRequest = NULL; 1359 | 1360 | switch (NdisRequest->RequestType) 1361 | { 1362 | case NdisRequestSetInformation: 1363 | bytesNeeded = NdisRequest->DATA.SET_INFORMATION.BytesNeeded; 1364 | break; 1365 | 1366 | case NdisRequestQueryInformation: 1367 | bytesNeeded = NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded; 1368 | break; 1369 | 1370 | case NdisRequestMethod: 1371 | bytesNeeded = NdisRequest->DATA.METHOD_INFORMATION.BytesNeeded; 1372 | break; 1373 | } 1374 | 1375 | // 1376 | // Get at the request context. 1377 | // 1378 | oidRequest = CONTAINING_RECORD(NdisRequest, SX_OID_REQUEST, NdisOidRequest); 1379 | 1380 | // 1381 | // Save away the completion status. 1382 | // 1383 | oidRequest->Status = Status; 1384 | 1385 | // 1386 | // Save bytesNeeded 1387 | // 1388 | oidRequest->BytesNeeded = bytesNeeded; 1389 | 1390 | // 1391 | // Wake up the thread blocked for this request to complete. 1392 | // 1393 | NdisSetEvent(&oidRequest->ReqEvent); 1394 | } 1395 | 1396 | -------------------------------------------------------------------------------- /base/SxBase.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All Rights Reserved. 4 | 5 | Module Name: 6 | 7 | SxBase.c 8 | 9 | Abstract: 10 | 11 | This file contains the common code for building a switch extension. This 12 | file includes all the standard NDIS handling and exposes a function based 13 | interface for the control path and data path. This also has reusable code 14 | for basic operations such as pause/resume handling etc. 15 | 16 | 17 | --*/ 18 | 19 | extern NDIS_STRING SxExtensionFriendlyName; 20 | extern NDIS_STRING SxExtensionGuid; 21 | 22 | typedef enum _SX_SWITCH_DATAFLOW_STATE 23 | { 24 | SxSwitchPaused, 25 | SxSwitchRunning 26 | } SX_SWITCH_DATAFLOW_STATE, *PSX_SWITCH_DATAFLOW_STATE; 27 | 28 | typedef enum _SX_SWITCH_CONTROFLOW_STATE 29 | { 30 | SxSwitchUnknown, 31 | SxSwitchAttached, 32 | SxSwitchDetached 33 | } SX_SWITCH_CONTROLFLOW_STATE, *PSX_SWITCH_CONTROLFLOW_STATE; 34 | 35 | typedef struct _SX_SWITCH_OBJECT 36 | { 37 | // 38 | // The Link *must* always be the first field. 39 | // 40 | LIST_ENTRY Link; 41 | 42 | // 43 | // The extension context is the context used in the specific logic 44 | // of this extension. 45 | // This is allocated and returned in SxExtSwitchCreate 46 | // 47 | PNDIS_HANDLE ExtensionContext; 48 | 49 | // 50 | // Ndis related fields. 51 | // 52 | NDIS_HANDLE NdisFilterHandle; 53 | NDIS_SWITCH_CONTEXT NdisSwitchContext; 54 | NDIS_SWITCH_OPTIONAL_HANDLERS NdisSwitchHandlers; 55 | 56 | // 57 | // Switch state. 58 | // 59 | SX_SWITCH_DATAFLOW_STATE DataFlowState; 60 | SX_SWITCH_CONTROLFLOW_STATE ControlFlowState; 61 | 62 | // 63 | // Management fields. 64 | // 65 | volatile LONG PendingInjectedNblCount; 66 | volatile LONG PendingOidCount; 67 | 68 | // 69 | // Control Path Management. 70 | // 71 | PNDIS_SWITCH_NIC_OID_REQUEST OldNicRequest; 72 | 73 | } SX_SWITCH_OBJECT, *PSX_SWITCH_OBJECT; 74 | 75 | typedef struct _SX_OID_REQUEST 76 | { 77 | NDIS_OID_REQUEST NdisOidRequest; 78 | NDIS_EVENT ReqEvent; 79 | NDIS_STATUS Status; 80 | ULONG BytesNeeded; 81 | 82 | } SX_OID_REQUEST, *PSX_OID_REQUEST; 83 | 84 | typedef struct _FILTER_DEVICE_EXTENSION 85 | { 86 | ULONG Signature; 87 | NDIS_HANDLE Handle; 88 | } FILTER_DEVICE_EXTENSION, *PFILTER_DEVICE_EXTENSION; 89 | 90 | 91 | // 92 | // Function prototypes 93 | // 94 | DRIVER_INITIALIZE DriverEntry; 95 | 96 | DRIVER_UNLOAD SxNdisUnload; 97 | 98 | FILTER_SET_OPTIONS SxNdisSetOptions; 99 | 100 | FILTER_SET_MODULE_OPTIONS SxNdisSetFilterModuleOptions; 101 | 102 | FILTER_ATTACH SxNdisAttach; 103 | 104 | FILTER_DETACH SxNdisDetach; 105 | 106 | FILTER_PAUSE SxNdisPause; 107 | 108 | FILTER_RESTART SxNdisRestart; 109 | 110 | FILTER_OID_REQUEST SxNdisOidRequest; 111 | 112 | FILTER_CANCEL_OID_REQUEST SxNdisCancelOidRequest; 113 | 114 | FILTER_OID_REQUEST_COMPLETE SxNdisOidRequestComplete; 115 | 116 | FILTER_SEND_NET_BUFFER_LISTS SxNdisSendNetBufferLists; 117 | 118 | FILTER_RETURN_NET_BUFFER_LISTS SxNdisReturnNetBufferLists; 119 | 120 | FILTER_SEND_NET_BUFFER_LISTS_COMPLETE SxNdisSendNetBufferListsComplete; 121 | 122 | FILTER_RECEIVE_NET_BUFFER_LISTS SxNdisReceiveNetBufferLists; 123 | 124 | FILTER_CANCEL_SEND_NET_BUFFER_LISTS SxNdisCancelSendNetBufferLists; 125 | 126 | FILTER_STATUS SxNdisStatus; 127 | 128 | FILTER_NET_PNP_EVENT SxNdisNetPnPEvent; 129 | 130 | VOID 131 | SxpNdisCompleteInternalOidRequest( 132 | __in PSX_SWITCH_OBJECT Switch, 133 | __in PNDIS_OID_REQUEST NdisRequest, 134 | __in NDIS_STATUS Status 135 | ); 136 | 137 | 138 | // 139 | // Some debug stuff. 140 | // 141 | #define DL_EXTRA_LOUD 20 142 | #define DL_VERY_LOUD 10 143 | #define DL_LOUD 8 144 | #define DL_INFO 6 145 | #define DL_TRACE 5 146 | #define DL_WARN 4 147 | #define DL_ERROR 2 148 | #define DL_FATAL 0 149 | 150 | #if DBG 151 | 152 | extern ULONG SxDebugLevel; 153 | 154 | #define DEBUGP(lev, stmt) \ 155 | { \ 156 | if ((lev) <= SxDebugLevel) \ 157 | { \ 158 | DbgPrint("%S: ",SxExtServiceName); DbgPrint stmt; \ 159 | } \ 160 | } 161 | 162 | #else 163 | 164 | #define DEBUGP(lev, stmt) 165 | 166 | #endif 167 | 168 | 169 | -------------------------------------------------------------------------------- /base/SxLibrary.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All Rights Reserved. 4 | 5 | Module Name: 6 | 7 | SxLibrary.c 8 | 9 | Abstract: 10 | 11 | This file contains the common library functions that can be used 12 | by any extension using the SxBase library. 13 | 14 | 15 | --*/ 16 | 17 | #include "precomp.h" 18 | 19 | VOID 20 | SxLibSendNetBufferListsIngress( 21 | _In_ PSX_SWITCH_OBJECT Switch, 22 | _In_ PNET_BUFFER_LIST NetBufferLists, 23 | _In_ ULONG SendFlags, 24 | _In_ ULONG NumInjectedNetBufferLists 25 | ) 26 | { 27 | BOOLEAN dispatch; 28 | BOOLEAN sameSource; 29 | ULONG sendCompleteFlags; 30 | PNDIS_SWITCH_FORWARDING_DETAIL_NET_BUFFER_LIST_INFO fwdDetail; 31 | PNET_BUFFER_LIST curNbl, nextNbl; 32 | ULONG numNbls = 0; 33 | PNET_BUFFER_LIST dropNbl = NULL; 34 | PNET_BUFFER_LIST *curDropNbl = &dropNbl; 35 | NDIS_SWITCH_PORT_ID curSourcePort; 36 | NDIS_STRING filterReason; 37 | 38 | dispatch = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags); 39 | sameSource = NDIS_TEST_SEND_FLAG(SendFlags, NDIS_SEND_FLAGS_SWITCH_SINGLE_SOURCE); 40 | 41 | InterlockedAdd(&Switch->PendingInjectedNblCount, NumInjectedNetBufferLists); 42 | KeMemoryBarrier(); 43 | 44 | if (Switch->DataFlowState != SxSwitchRunning) 45 | { 46 | RtlInitUnicodeString(&filterReason, L"Extension Paused"); 47 | 48 | sendCompleteFlags = (dispatch) ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0; 49 | sendCompleteFlags |= (sameSource) ? NDIS_SEND_COMPLETE_FLAGS_SWITCH_SINGLE_SOURCE : 0; 50 | 51 | fwdDetail = NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(NetBufferLists); 52 | 53 | if (sameSource) 54 | { 55 | for (curNbl = NetBufferLists; curNbl != NULL; curNbl = curNbl->Next) 56 | { 57 | ++numNbls; 58 | } 59 | 60 | Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists( 61 | Switch->NdisSwitchContext, 62 | &SxExtensionGuid, 63 | &SxExtensionFriendlyName, 64 | fwdDetail->SourcePortId, 65 | NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING, 66 | numNbls, 67 | NetBufferLists, 68 | &filterReason); 69 | 70 | SxExtStartCompleteNetBufferListsIngress(Switch, 71 | Switch->ExtensionContext, 72 | NetBufferLists, 73 | sendCompleteFlags); 74 | } 75 | else 76 | { 77 | curSourcePort = fwdDetail->SourcePortId; 78 | for (curNbl = NetBufferLists; curNbl != NULL; curNbl = nextNbl) 79 | { 80 | nextNbl = curNbl->Next; 81 | curNbl->Next = NULL; 82 | 83 | fwdDetail = NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(curNbl); 84 | 85 | if(curSourcePort == fwdDetail->SourcePortId) 86 | { 87 | *curDropNbl = curNbl; 88 | curDropNbl = &(curNbl->Next); 89 | ++numNbls; 90 | } 91 | else 92 | { 93 | Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists( 94 | Switch->NdisSwitchContext, 95 | &SxExtensionGuid, 96 | &SxExtensionFriendlyName, 97 | curSourcePort, 98 | NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING, 99 | numNbls, 100 | dropNbl, 101 | &filterReason); 102 | 103 | SxExtStartCompleteNetBufferListsIngress(Switch, 104 | Switch->ExtensionContext, 105 | dropNbl, 106 | sendCompleteFlags); 107 | 108 | numNbls = 1; 109 | dropNbl = curNbl; 110 | curDropNbl = &(curNbl->Next); 111 | curSourcePort = fwdDetail->SourcePortId; 112 | } 113 | } 114 | 115 | Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists( 116 | Switch->NdisSwitchContext, 117 | &SxExtensionGuid, 118 | &SxExtensionFriendlyName, 119 | curSourcePort, 120 | NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING, 121 | numNbls, 122 | dropNbl, 123 | &filterReason); 124 | 125 | SxExtStartCompleteNetBufferListsIngress(Switch, 126 | Switch->ExtensionContext, 127 | dropNbl, 128 | sendCompleteFlags); 129 | } 130 | 131 | goto Cleanup; 132 | } 133 | 134 | NdisFSendNetBufferLists(Switch->NdisFilterHandle, 135 | NetBufferLists, 136 | NDIS_DEFAULT_PORT_NUMBER, 137 | SendFlags); 138 | 139 | Cleanup: 140 | return; 141 | } 142 | 143 | 144 | VOID 145 | SxLibSendNetBufferListsEgress( 146 | _In_ PSX_SWITCH_OBJECT Switch, 147 | _In_ PNET_BUFFER_LIST NetBufferLists, 148 | _In_ ULONG NumberOfNetBufferLists, 149 | _In_ ULONG ReceiveFlags 150 | ) 151 | { 152 | BOOLEAN dispatch, sameSource; 153 | NDIS_SWITCH_PORT_ID sourcePortId; 154 | PNDIS_SWITCH_FORWARDING_DETAIL_NET_BUFFER_LIST_INFO fwdDetail; 155 | ULONG returnFlags; 156 | NDIS_SWITCH_PORT_ID curSourcePort; 157 | PNET_BUFFER_LIST curNbl, nextNbl; 158 | ULONG numNbls; 159 | PNET_BUFFER_LIST dropNbl = NULL; 160 | PNET_BUFFER_LIST *curDropNbl = &dropNbl; 161 | NDIS_STRING filterReason; 162 | 163 | dispatch = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags); 164 | sameSource = NDIS_TEST_RECEIVE_FLAG(ReceiveFlags, NDIS_RECEIVE_FLAGS_SWITCH_SINGLE_SOURCE); 165 | 166 | if (Switch->DataFlowState != SxSwitchRunning) 167 | { 168 | RtlInitUnicodeString(&filterReason, L"Extension Paused"); 169 | 170 | returnFlags = (dispatch) ? NDIS_RETURN_FLAGS_DISPATCH_LEVEL : 0; 171 | returnFlags |= NDIS_RETURN_FLAGS_SWITCH_SINGLE_SOURCE; 172 | 173 | fwdDetail = NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(NetBufferLists); 174 | 175 | if (sameSource) 176 | { 177 | sourcePortId = fwdDetail->SourcePortId; 178 | 179 | Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists( 180 | Switch->NdisSwitchContext, 181 | &SxExtensionGuid, 182 | &SxExtensionFriendlyName, 183 | sourcePortId, 184 | NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING, 185 | NumberOfNetBufferLists, 186 | NetBufferLists, 187 | &filterReason); 188 | 189 | SxExtStartCompleteNetBufferListsEgress(Switch, 190 | Switch->ExtensionContext, 191 | NetBufferLists, 192 | returnFlags); 193 | } 194 | else 195 | { 196 | curSourcePort = fwdDetail->SourcePortId; 197 | numNbls = 0; 198 | for (curNbl = NetBufferLists; curNbl != NULL; curNbl = nextNbl) 199 | { 200 | nextNbl = curNbl->Next; 201 | curNbl->Next = NULL; 202 | 203 | fwdDetail = NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(curNbl); 204 | 205 | if(curSourcePort == fwdDetail->SourcePortId) 206 | { 207 | *curDropNbl = curNbl; 208 | curDropNbl = &(curNbl->Next); 209 | ++numNbls; 210 | } 211 | else 212 | { 213 | Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists( 214 | Switch->NdisSwitchContext, 215 | &SxExtensionGuid, 216 | &SxExtensionFriendlyName, 217 | curSourcePort, 218 | NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING, 219 | numNbls, 220 | dropNbl, 221 | &filterReason); 222 | 223 | SxExtStartCompleteNetBufferListsEgress(Switch, 224 | Switch->ExtensionContext, 225 | dropNbl, 226 | returnFlags); 227 | 228 | numNbls = 1; 229 | dropNbl = curNbl; 230 | curDropNbl = &(curNbl->Next); 231 | curSourcePort = fwdDetail->SourcePortId; 232 | } 233 | } 234 | 235 | Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists( 236 | Switch->NdisSwitchContext, 237 | &SxExtensionGuid, 238 | &SxExtensionFriendlyName, 239 | curSourcePort, 240 | NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING, 241 | numNbls, 242 | dropNbl, 243 | &filterReason); 244 | 245 | SxExtStartCompleteNetBufferListsEgress(Switch, 246 | Switch->ExtensionContext, 247 | dropNbl, 248 | returnFlags); 249 | } 250 | 251 | goto Cleanup; 252 | } 253 | 254 | NdisFIndicateReceiveNetBufferLists(Switch->NdisFilterHandle, 255 | NetBufferLists, 256 | NDIS_DEFAULT_PORT_NUMBER, 257 | NumberOfNetBufferLists, 258 | ReceiveFlags); 259 | 260 | Cleanup: 261 | return; 262 | } 263 | 264 | VOID 265 | SxLibCompleteNetBufferListsEgress( 266 | _In_ PSX_SWITCH_OBJECT Switch, 267 | _In_ PNET_BUFFER_LIST NetBufferLists, 268 | _In_ ULONG ReturnFlags 269 | ) 270 | { 271 | NdisFReturnNetBufferLists(Switch->NdisFilterHandle, 272 | NetBufferLists, 273 | ReturnFlags); 274 | } 275 | 276 | 277 | VOID 278 | SxLibCompleteNetBufferListsIngress( 279 | _In_ PSX_SWITCH_OBJECT Switch, 280 | _In_ PNET_BUFFER_LIST NetBufferLists, 281 | _In_ ULONG SendCompleteFlags 282 | ) 283 | { 284 | NdisFSendNetBufferListsComplete(Switch->NdisFilterHandle, 285 | NetBufferLists, 286 | SendCompleteFlags); 287 | } 288 | 289 | VOID 290 | SxLibCompletedInjectedNetBufferLists( 291 | _In_ PSX_SWITCH_OBJECT Switch, 292 | _In_ ULONG NumInjectedNetBufferLists 293 | ) 294 | { 295 | LONG subtract = -(LONG)NumInjectedNetBufferLists; 296 | InterlockedAdd(&Switch->PendingInjectedNblCount, subtract); 297 | } 298 | 299 | 300 | NDIS_STATUS 301 | SxLibIssueOidRequest( 302 | _In_ PSX_SWITCH_OBJECT Switch, 303 | _In_ NDIS_REQUEST_TYPE RequestType, 304 | _In_ NDIS_OID Oid, 305 | _In_opt_ PVOID InformationBuffer, 306 | _In_ ULONG InformationBufferLength, 307 | _In_ ULONG OutputBufferLength, 308 | _In_ ULONG MethodId, 309 | _In_ UINT Timeout, 310 | _Out_ PULONG BytesNeeded 311 | ) 312 | { 313 | NDIS_STATUS status; 314 | PSX_OID_REQUEST oidRequest; 315 | PNDIS_OID_REQUEST ndisOidRequest; 316 | ULONG bytesNeeded; 317 | BOOLEAN asyncCompletion; 318 | 319 | status = NDIS_STATUS_SUCCESS; 320 | oidRequest = NULL; 321 | bytesNeeded = 0; 322 | asyncCompletion = FALSE; 323 | 324 | NdisInterlockedIncrement(&Switch->PendingOidCount); 325 | 326 | if (Switch->ControlFlowState != SxSwitchAttached) 327 | { 328 | status = NDIS_STATUS_CLOSING; 329 | goto Cleanup; 330 | } 331 | 332 | // 333 | // Dynamically allocate filter request so that we can handle asynchronous 334 | // completion. 335 | // 336 | oidRequest = (PSX_OID_REQUEST)ExAllocatePoolWithTag(NonPagedPoolNx, 337 | sizeof(SX_OID_REQUEST), 338 | SxExtAllocationTag); 339 | if (oidRequest == NULL) 340 | { 341 | goto Cleanup; 342 | } 343 | 344 | NdisZeroMemory(oidRequest, sizeof(SX_OID_REQUEST)); 345 | ndisOidRequest = &oidRequest->NdisOidRequest; 346 | NdisInitializeEvent(&oidRequest->ReqEvent); 347 | 348 | ndisOidRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST; 349 | ndisOidRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1; 350 | ndisOidRequest->Header.Size = sizeof(NDIS_OID_REQUEST); 351 | ndisOidRequest->RequestType = RequestType; 352 | ndisOidRequest->Timeout = Timeout; 353 | 354 | switch (RequestType) 355 | { 356 | case NdisRequestQueryInformation: 357 | ndisOidRequest->DATA.QUERY_INFORMATION.Oid = Oid; 358 | ndisOidRequest->DATA.QUERY_INFORMATION.InformationBuffer = 359 | InformationBuffer; 360 | ndisOidRequest->DATA.QUERY_INFORMATION.InformationBufferLength = 361 | InformationBufferLength; 362 | break; 363 | 364 | case NdisRequestSetInformation: 365 | ndisOidRequest->DATA.SET_INFORMATION.Oid = Oid; 366 | ndisOidRequest->DATA.SET_INFORMATION.InformationBuffer = 367 | InformationBuffer; 368 | ndisOidRequest->DATA.SET_INFORMATION.InformationBufferLength = 369 | InformationBufferLength; 370 | break; 371 | 372 | case NdisRequestMethod: 373 | ndisOidRequest->DATA.METHOD_INFORMATION.Oid = Oid; 374 | ndisOidRequest->DATA.METHOD_INFORMATION.MethodId = MethodId; 375 | ndisOidRequest->DATA.METHOD_INFORMATION.InformationBuffer = 376 | InformationBuffer; 377 | ndisOidRequest->DATA.METHOD_INFORMATION.InputBufferLength = 378 | InformationBufferLength; 379 | ndisOidRequest->DATA.METHOD_INFORMATION.OutputBufferLength = 380 | OutputBufferLength; 381 | break; 382 | 383 | default: 384 | NT_ASSERT(FALSE); 385 | break; 386 | } 387 | 388 | ndisOidRequest->RequestId = (PVOID)SxExtOidRequestId; 389 | status = NdisFOidRequest(Switch->NdisFilterHandle, ndisOidRequest); 390 | 391 | if (status == NDIS_STATUS_PENDING) 392 | { 393 | asyncCompletion = TRUE; 394 | NdisWaitEvent(&oidRequest->ReqEvent, 0); 395 | } 396 | else 397 | { 398 | SxpNdisCompleteInternalOidRequest(Switch, ndisOidRequest, status); 399 | } 400 | 401 | bytesNeeded = oidRequest->BytesNeeded; 402 | status = oidRequest->Status; 403 | 404 | Cleanup: 405 | 406 | if (BytesNeeded != NULL) 407 | { 408 | *BytesNeeded = bytesNeeded; 409 | } 410 | 411 | if (!asyncCompletion) 412 | { 413 | NdisInterlockedDecrement(&Switch->PendingOidCount); 414 | } 415 | 416 | if (oidRequest != NULL) 417 | { 418 | ExFreePoolWithTag(oidRequest, SxExtAllocationTag); 419 | } 420 | 421 | return status; 422 | } 423 | 424 | 425 | NDIS_STATUS 426 | SxLibGetSwitchParametersUnsafe( 427 | _In_ PSX_SWITCH_OBJECT Switch, 428 | _Out_ PNDIS_SWITCH_PARAMETERS SwitchParameters 429 | ) 430 | { 431 | NDIS_STATUS status; 432 | 433 | SwitchParameters->Header.Revision = NDIS_SWITCH_PARAMETERS_REVISION_1; 434 | SwitchParameters->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; 435 | SwitchParameters->Header.Size = sizeof(NDIS_SWITCH_PARAMETERS); 436 | 437 | status = SxLibIssueOidRequest(Switch, 438 | NdisRequestQueryInformation, 439 | OID_SWITCH_PARAMETERS, 440 | SwitchParameters, 441 | sizeof(NDIS_SWITCH_PARAMETERS), 442 | 0, 443 | 0, 444 | 0, 445 | NULL); 446 | 447 | return status; 448 | } 449 | 450 | 451 | NDIS_STATUS 452 | SxLibGetPortArrayUnsafe( 453 | _In_ PSX_SWITCH_OBJECT Switch, 454 | _Out_ PNDIS_SWITCH_PORT_ARRAY *PortArray 455 | ) 456 | { 457 | NDIS_STATUS status = NDIS_STATUS_SUCCESS; 458 | ULONG BytesNeeded = 0; 459 | PNDIS_SWITCH_PORT_ARRAY portArray = NULL; 460 | ULONG arrayLength = 0; 461 | 462 | do 463 | { 464 | if (portArray != NULL) 465 | { 466 | ExFreePoolWithTag(portArray, SxExtAllocationTag); 467 | } 468 | 469 | if (BytesNeeded != 0) 470 | { 471 | arrayLength = BytesNeeded; 472 | portArray = ExAllocatePoolWithTag(NonPagedPoolNx, 473 | arrayLength, 474 | SxExtAllocationTag); 475 | 476 | if (portArray == NULL) 477 | { 478 | status = NDIS_STATUS_RESOURCES; 479 | goto Cleanup; 480 | } 481 | 482 | portArray->Header.Revision = NDIS_SWITCH_PORT_ARRAY_REVISION_1; 483 | portArray->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; 484 | portArray->Header.Size = (USHORT)arrayLength; 485 | } 486 | 487 | status = SxLibIssueOidRequest(Switch, 488 | NdisRequestQueryInformation, 489 | OID_SWITCH_PORT_ARRAY, 490 | portArray, 491 | arrayLength, 492 | 0, 493 | 0, 494 | 0, 495 | &BytesNeeded); 496 | 497 | } while(status == NDIS_STATUS_INVALID_LENGTH); 498 | 499 | *PortArray = portArray; 500 | Cleanup: 501 | if (status != NDIS_STATUS_SUCCESS && 502 | portArray != NULL) 503 | { 504 | ExFreePoolWithTag(portArray, SxExtAllocationTag); 505 | } 506 | 507 | return status; 508 | } 509 | 510 | 511 | NDIS_STATUS 512 | SxLibGetNicArrayUnsafe( 513 | _In_ PSX_SWITCH_OBJECT Switch, 514 | _Out_ PNDIS_SWITCH_NIC_ARRAY *NicArray 515 | ) 516 | { 517 | NDIS_STATUS status = NDIS_STATUS_SUCCESS; 518 | ULONG BytesNeeded = 0; 519 | PNDIS_SWITCH_NIC_ARRAY nicArray = NULL; 520 | ULONG arrayLength = 0; 521 | 522 | do 523 | { 524 | if (nicArray != NULL) 525 | { 526 | ExFreePoolWithTag(nicArray, SxExtAllocationTag); 527 | } 528 | 529 | if (BytesNeeded != 0) 530 | { 531 | arrayLength = BytesNeeded; 532 | nicArray = ExAllocatePoolWithTag(NonPagedPoolNx, 533 | arrayLength, 534 | SxExtAllocationTag); 535 | 536 | if (nicArray == NULL) 537 | { 538 | status = NDIS_STATUS_RESOURCES; 539 | goto Cleanup; 540 | } 541 | 542 | nicArray->Header.Revision = NDIS_SWITCH_PORT_ARRAY_REVISION_1; 543 | nicArray->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; 544 | nicArray->Header.Size = (USHORT)arrayLength; 545 | } 546 | 547 | status = SxLibIssueOidRequest(Switch, 548 | NdisRequestQueryInformation, 549 | OID_SWITCH_NIC_ARRAY, 550 | nicArray, 551 | arrayLength, 552 | 0, 553 | 0, 554 | 0, 555 | &BytesNeeded); 556 | 557 | } while(status == NDIS_STATUS_INVALID_LENGTH); 558 | 559 | *NicArray = nicArray; 560 | Cleanup: 561 | if (status != NDIS_STATUS_SUCCESS && 562 | nicArray != NULL) 563 | { 564 | ExFreePoolWithTag(nicArray, SxExtAllocationTag); 565 | } 566 | 567 | return status; 568 | } 569 | 570 | 571 | NDIS_STATUS 572 | SxLibGetSwitchPropertyUnsafe( 573 | _In_ PSX_SWITCH_OBJECT Switch, 574 | _In_ NDIS_SWITCH_PROPERTY_TYPE PropertyType, 575 | _In_opt_ PNDIS_SWITCH_OBJECT_ID PropertyId, 576 | _Outptr_ PNDIS_SWITCH_PROPERTY_ENUM_PARAMETERS *SwitchPropertyEnumParameters 577 | ) 578 | { 579 | NDIS_STATUS status = NDIS_STATUS_SUCCESS; 580 | NDIS_SWITCH_PROPERTY_ENUM_PARAMETERS propertyParameters; 581 | ULONG bytesNeeded = 0; 582 | PNDIS_SWITCH_PROPERTY_ENUM_PARAMETERS outputBuffer = NULL; 583 | USHORT outputBufferLength = sizeof(NDIS_SWITCH_PROPERTY_ENUM_PARAMETERS); 584 | 585 | propertyParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; 586 | propertyParameters.Header.Revision = NDIS_SWITCH_PROPERTY_ENUM_PARAMETERS_REVISION_1; 587 | 588 | propertyParameters.PropertyType = PropertyType; 589 | propertyParameters.SerializationVersion = NDIS_SWITCH_OBJECT_SERIALIZATION_VERSION_1; 590 | 591 | // 592 | // For Built-in properties, the ID is unnecessary. 593 | // 594 | if (PropertyId != NULL) 595 | { 596 | NdisMoveMemory(&propertyParameters.PropertyId, 597 | PropertyId, 598 | sizeof(NDIS_SWITCH_OBJECT_ID)); 599 | } 600 | else 601 | { 602 | ASSERT(PropertyType != NdisSwitchPropertyTypeCustom); 603 | } 604 | 605 | outputBuffer = ExAllocatePoolWithTag(NonPagedPoolNx, 606 | outputBufferLength, 607 | SxExtAllocationTag); 608 | 609 | if (outputBuffer == NULL) 610 | { 611 | status = NDIS_STATUS_RESOURCES; 612 | goto Cleanup; 613 | } 614 | 615 | do 616 | { 617 | if (bytesNeeded != 0) 618 | { 619 | ExFreePoolWithTag(outputBuffer, SxExtAllocationTag); 620 | 621 | outputBufferLength = (USHORT)bytesNeeded; 622 | outputBuffer = ExAllocatePoolWithTag(NonPagedPoolNx, 623 | outputBufferLength, 624 | SxExtAllocationTag); 625 | 626 | if (outputBuffer == NULL) 627 | { 628 | status = NDIS_STATUS_RESOURCES; 629 | goto Cleanup; 630 | } 631 | } 632 | 633 | if(outputBufferLength >= sizeof(propertyParameters)) 634 | { 635 | NdisMoveMemory(outputBuffer, &propertyParameters, sizeof(propertyParameters)); 636 | 637 | } 638 | 639 | status = SxLibIssueOidRequest(Switch, 640 | NdisRequestMethod, 641 | OID_SWITCH_PROPERTY_ENUM, 642 | outputBuffer, 643 | sizeof(propertyParameters), 644 | outputBufferLength, 645 | 0, 646 | 0, 647 | &bytesNeeded); 648 | 649 | } while(status == NDIS_STATUS_INVALID_LENGTH); 650 | 651 | Cleanup: 652 | if (status != NDIS_STATUS_SUCCESS && 653 | outputBuffer != NULL) 654 | { 655 | ExFreePoolWithTag(outputBuffer, SxExtAllocationTag); 656 | outputBuffer = NULL; 657 | } 658 | 659 | *SwitchPropertyEnumParameters = outputBuffer; 660 | 661 | return status; 662 | } 663 | 664 | 665 | NDIS_STATUS 666 | SxLibGetPortPropertyUnsafe( 667 | _In_ PSX_SWITCH_OBJECT Switch, 668 | _In_ NDIS_SWITCH_PORT_ID PortId, 669 | _In_ NDIS_SWITCH_PORT_PROPERTY_TYPE PropertyType, 670 | _In_opt_ PNDIS_SWITCH_OBJECT_ID PropertyId, 671 | _Outptr_ PNDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS *PortPropertyEnumParameters 672 | ) 673 | { 674 | NDIS_STATUS status = NDIS_STATUS_SUCCESS; 675 | NDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS propertyParameters; 676 | ULONG bytesNeeded = 0; 677 | PNDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS outputBuffer = NULL; 678 | USHORT outputBufferLength = sizeof(NDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS); 679 | 680 | propertyParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; 681 | propertyParameters.Header.Revision = NDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS_REVISION_1; 682 | 683 | propertyParameters.PortId = PortId; 684 | propertyParameters.PropertyType = PropertyType; 685 | propertyParameters.SerializationVersion = NDIS_SWITCH_OBJECT_SERIALIZATION_VERSION_1; 686 | 687 | // 688 | // For Built-in properties, the ID is unnecessary. 689 | // 690 | if (PropertyId != NULL) 691 | { 692 | NdisMoveMemory(&propertyParameters.PropertyId, 693 | PropertyId, 694 | sizeof(NDIS_SWITCH_OBJECT_ID)); 695 | } 696 | else 697 | { 698 | ASSERT(PropertyType != NdisSwitchPortPropertyTypeCustom); 699 | } 700 | 701 | outputBuffer = ExAllocatePoolWithTag(NonPagedPoolNx, 702 | outputBufferLength, 703 | SxExtAllocationTag); 704 | 705 | if (outputBuffer == NULL) 706 | { 707 | status = NDIS_STATUS_RESOURCES; 708 | goto Cleanup; 709 | } 710 | 711 | do 712 | { 713 | if (bytesNeeded != 0) 714 | { 715 | ExFreePoolWithTag(outputBuffer, SxExtAllocationTag); 716 | 717 | outputBufferLength = (USHORT)bytesNeeded; 718 | outputBuffer = ExAllocatePoolWithTag(NonPagedPoolNx, 719 | outputBufferLength, 720 | SxExtAllocationTag); 721 | 722 | if (outputBuffer == NULL) 723 | { 724 | status = NDIS_STATUS_RESOURCES; 725 | goto Cleanup; 726 | } 727 | } 728 | 729 | if(outputBufferLength >= sizeof(propertyParameters)) 730 | { 731 | outputBuffer->Header.Size = outputBufferLength; 732 | NdisMoveMemory(outputBuffer, &propertyParameters, sizeof(propertyParameters)); 733 | } 734 | 735 | status = SxLibIssueOidRequest(Switch, 736 | NdisRequestMethod, 737 | OID_SWITCH_PORT_PROPERTY_ENUM, 738 | outputBuffer, 739 | sizeof(propertyParameters), 740 | outputBufferLength, 741 | 0, 742 | 0, 743 | &bytesNeeded); 744 | 745 | } while(status == NDIS_STATUS_INVALID_LENGTH); 746 | 747 | Cleanup: 748 | if (status != NDIS_STATUS_SUCCESS && 749 | outputBuffer != NULL) 750 | { 751 | ExFreePoolWithTag(outputBuffer, SxExtAllocationTag); 752 | outputBuffer = NULL; 753 | } 754 | 755 | *PortPropertyEnumParameters = outputBuffer; 756 | 757 | return status; 758 | } 759 | 760 | 761 | VOID 762 | SxLibRevokeVfUnsafe( 763 | _In_ PSX_SWITCH_OBJECT Switch, 764 | _In_ NDIS_SWITCH_PORT_ID PortId 765 | ) 766 | { 767 | SxLibIssueNicStatusIndicationUnsafe(Switch, 768 | NDIS_STATUS_SWITCH_PORT_REMOVE_VF, 769 | PortId, 770 | NDIS_SWITCH_DEFAULT_NIC_INDEX, 771 | TRUE, 772 | NULL, 773 | 0); 774 | } 775 | 776 | 777 | VOID 778 | SxLibIssueNicStatusIndicationUnsafe( 779 | _In_ PSX_SWITCH_OBJECT Switch, 780 | _In_ NDIS_STATUS StatusCode, 781 | _In_ NDIS_SWITCH_PORT_ID PortId, 782 | _In_ NDIS_SWITCH_NIC_INDEX NicIndex, 783 | _In_ BOOLEAN IsDestination, 784 | _In_opt_ PVOID StatusBuffer, 785 | _In_ ULONG StatusBufferSize 786 | ) 787 | { 788 | NDIS_STATUS_INDICATION statusIndication; 789 | NDIS_STATUS_INDICATION wrappedIndication; 790 | NDIS_SWITCH_NIC_STATUS_INDICATION nicIndication; 791 | 792 | NdisZeroMemory(&wrappedIndication, sizeof(wrappedIndication)); 793 | 794 | wrappedIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; 795 | wrappedIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; 796 | wrappedIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; 797 | 798 | wrappedIndication.SourceHandle = Switch->NdisFilterHandle; 799 | wrappedIndication.PortNumber = NDIS_DEFAULT_PORT_NUMBER; 800 | 801 | wrappedIndication.StatusCode = StatusCode; 802 | wrappedIndication.StatusBuffer = StatusBuffer; 803 | wrappedIndication.StatusBufferSize = StatusBufferSize; 804 | 805 | NdisZeroMemory(&nicIndication, sizeof(nicIndication)); 806 | 807 | nicIndication.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; 808 | nicIndication.Header.Revision = NDIS_SWITCH_NIC_STATUS_INDICATION_REVISION_1; 809 | nicIndication.Header.Size = NDIS_SIZEOF_SWITCH_NIC_STATUS_REVISION_1; 810 | nicIndication.StatusIndication = &wrappedIndication; 811 | 812 | if (IsDestination) 813 | { 814 | nicIndication.DestinationPortId = PortId; 815 | nicIndication.DestinationNicIndex = NicIndex; 816 | } 817 | else 818 | { 819 | nicIndication.SourcePortId = PortId; 820 | nicIndication.SourceNicIndex = NicIndex; 821 | } 822 | 823 | NdisZeroMemory(&statusIndication, sizeof(statusIndication)); 824 | 825 | statusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION; 826 | statusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1; 827 | statusIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1; 828 | 829 | statusIndication.SourceHandle = Switch->NdisFilterHandle; 830 | statusIndication.PortNumber = NDIS_DEFAULT_PORT_NUMBER; 831 | 832 | statusIndication.StatusCode = NDIS_STATUS_SWITCH_NIC_STATUS; 833 | statusIndication.StatusBuffer = &nicIndication; 834 | statusIndication.StatusBufferSize = sizeof(nicIndication); 835 | 836 | NdisFIndicateStatus(Switch->NdisFilterHandle, 837 | &statusIndication); 838 | } 839 | 840 | -------------------------------------------------------------------------------- /base/SxLibrary.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation. All Rights Reserved. 4 | 5 | Module Name: 6 | 7 | SxLibrary.h 8 | 9 | Abstract: 10 | 11 | This file contains the common library function headers that can be 12 | used by any extension using the SxBase library. 13 | 14 | 15 | --*/ 16 | 17 | 18 | /*++ 19 | 20 | SxLibSendNetBufferListsIngress 21 | 22 | Routine Description: 23 | This function is called to forward NBLs on ingress. 24 | The extension MUST call this function, or call 25 | SxLibCompleteNetBufferListsIngress for every NBL in NetBufferLists, 26 | recieved in SxExtStartNetBufferListsIngress. 27 | 28 | This function can also be called to inject NBLs. 29 | If there are NBLs in NetBufferLists that are initiated by the 30 | extension, NumInjectedNetBufferLists must be the number of new NBLs. 31 | 32 | Arguments: 33 | 34 | Switch - the Switch context 35 | 36 | NetBufferLists - the NBLs to send 37 | 38 | SendFlags - the SendFlags equivalent to NDIS flags for 39 | NdisFSendNetBufferLists 40 | 41 | NumInjectedNetBufferLists - the number of NBLs in NetBufferLists initiated 42 | by the extension 43 | 44 | Return Value: 45 | VOID 46 | 47 | --*/ 48 | VOID 49 | SxLibSendNetBufferListsIngress( 50 | _In_ PSX_SWITCH_OBJECT Switch, 51 | _In_ PNET_BUFFER_LIST NetBufferLists, 52 | _In_ ULONG SendFlags, 53 | _In_ ULONG NumInjectedNetBufferLists 54 | ); 55 | 56 | 57 | /*++ 58 | 59 | SxLibSendNetBufferListsEgress 60 | 61 | Routine Description: 62 | This function is called to forward NBLs on egress. 63 | The extension MUST call this function, or call 64 | SxLibCompleteNetBufferListsEgress for every NBL in NetBufferLists 65 | recieved in SxExtStartNetBufferListsEgress. 66 | 67 | Arguments: 68 | 69 | Switch - the Switch context 70 | 71 | NetBufferLists - the NBLs to send 72 | 73 | NumberOfNetBufferLists - the number of NBLs in NetBufferLists 74 | 75 | ReceiveFlags - the ReceiveFlags equivalent to NDIS flags for 76 | NdisFIndicateReceiveNetBufferLists 77 | 78 | Return Value: 79 | VOID 80 | 81 | --*/ 82 | VOID 83 | SxLibSendNetBufferListsEgress( 84 | _In_ PSX_SWITCH_OBJECT Switch, 85 | _In_ PNET_BUFFER_LIST NetBufferLists, 86 | _In_ ULONG NumberOfNetBufferLists, 87 | _In_ ULONG ReceiveFlags 88 | ); 89 | 90 | 91 | /*++ 92 | 93 | SxLibCompleteNetBufferListsEgress 94 | 95 | Routine Description: 96 | This function is called to complete NBLs on egress. 97 | The extension MUST call this function for all NBLs recieved 98 | in SxExtStartCompleteNetBufferListsEgress. 99 | 100 | Arguments: 101 | 102 | Switch - the Switch context 103 | 104 | NetBufferLists - the NBLs to send 105 | 106 | ReturnFlags - the ReceiveFlags equivalent to NDIS flags for 107 | NdisFReturnNetBufferLists 108 | 109 | Return Value: 110 | VOID 111 | 112 | --*/ 113 | VOID 114 | SxLibCompleteNetBufferListsEgress( 115 | _In_ PSX_SWITCH_OBJECT Switch, 116 | _In_ PNET_BUFFER_LIST NetBufferLists, 117 | _In_ ULONG ReturnFlags 118 | ); 119 | 120 | /*++ 121 | 122 | SxLibCompleteNetBufferListsIngress 123 | 124 | Routine Description: 125 | This function is called to complete NBLs on ingress. 126 | The extension MUST call this function, or 127 | SxLibCompletedInjectedNetBufferLists for all NBLs recieved in 128 | SxExtStartCompleteNetBufferListsEgress. 129 | 130 | Arguments: 131 | 132 | Switch - the Switch context 133 | 134 | NetBufferLists - the NBLs to send 135 | 136 | SendCompleteFlags - the ReceiveFlags equivalent to NDIS flags for 137 | NdisFSendNetBufferListsComplete 138 | 139 | Return Value: 140 | VOID 141 | 142 | --*/ 143 | VOID 144 | SxLibCompleteNetBufferListsIngress( 145 | _In_ PSX_SWITCH_OBJECT Switch, 146 | _In_ PNET_BUFFER_LIST NetBufferLists, 147 | _In_ ULONG SendCompleteFlags 148 | ); 149 | 150 | 151 | /*++ 152 | 153 | SxLibCompletedInjectedNetBufferLists 154 | 155 | Routine Description: 156 | This function is called after completing NBLs injected 157 | by the extension. 158 | 159 | Arguments: 160 | 161 | Switch - the Switch context 162 | 163 | NumInjectedNetBufferLists - the number of NBLs completed 164 | 165 | Return Value: 166 | VOID 167 | 168 | --*/ 169 | VOID 170 | SxLibCompletedInjectedNetBufferLists( 171 | _In_ PSX_SWITCH_OBJECT Switch, 172 | _In_ ULONG NumInjectedNetBufferLists 173 | ); 174 | 175 | 176 | /*++ 177 | 178 | SxLibIssueOidRequest 179 | 180 | Routine Description: 181 | 182 | Utility routine that forms and sends an NDIS_OID_REQUEST to the 183 | miniport, waits for it to complete, and returns status 184 | to the caller. 185 | 186 | NOTE: this assumes that the calling routine ensures validity 187 | of the filter handle until this returns. 188 | 189 | This function can only be called at PASSIVE_LEVEL. 190 | 191 | Arguments: 192 | 193 | Switch - pointer to our switch object. 194 | 195 | RequestType - NdisRequest[Set|Query|method]Information. 196 | 197 | Oid - the object being set/queried. 198 | 199 | InformationBuffer - data for the request. 200 | 201 | InformationBufferLength - length of the above. 202 | 203 | OutputBufferLength - valid only for method request. 204 | 205 | MethodId - valid only for method request. 206 | 207 | Timeout - The timeout in seconds for the OID. 208 | 209 | BytesNeeded - place to return bytes read/written. 210 | 211 | Return Value: 212 | 213 | NDIS_STATUS_*** 214 | 215 | --*/ 216 | NDIS_STATUS 217 | SxLibIssueOidRequest( 218 | _In_ PSX_SWITCH_OBJECT SxSwitch, 219 | _In_ NDIS_REQUEST_TYPE RequestType, 220 | _In_ NDIS_OID Oid, 221 | _In_opt_ PVOID InformationBuffer, 222 | _In_ ULONG InformationBufferLength, 223 | _In_ ULONG OutputBufferLength, 224 | _In_ ULONG MethodId, 225 | _In_ UINT Timeout, 226 | _Out_ PULONG BytesNeeded 227 | ); 228 | 229 | 230 | /*++ 231 | 232 | SxLibGetSwitchParametersUnsafe 233 | 234 | Routine Description: 235 | This function is called to get the current state of the switch. 236 | 237 | Arguments: 238 | 239 | Switch - the Switch context 240 | 241 | SwitchParameters - the returned switch parameters 242 | 243 | Return Value: 244 | NDIS_STATUS_SUCCESS - if SwitchParameters was successfully returned 245 | 246 | NDIS_STATUS_*** - otherwise 247 | 248 | --*/ 249 | NDIS_STATUS 250 | SxLibGetSwitchParametersUnsafe( 251 | _In_ PSX_SWITCH_OBJECT Switch, 252 | _Out_ PNDIS_SWITCH_PARAMETERS SwitchParameters 253 | ); 254 | 255 | 256 | /*++ 257 | 258 | SxLibGetPortArrayUnsafe 259 | 260 | Routine Description: 261 | This function is called to get the current array 262 | of ports. 263 | 264 | NOTE: It is necessary to synchonize this with SxExtPortCreate 265 | and SxExtPortTeardown. 266 | 267 | Arguments: 268 | 269 | Switch - the Switch context 270 | 271 | PortArray - the returned port array 272 | 273 | Return Value: 274 | NDIS_STATUS_SUCCESS - if PortArray was successfully allocated 275 | and returned 276 | 277 | NDIS_STATUS_*** - otherwise 278 | 279 | --*/ 280 | NDIS_STATUS 281 | SxLibGetPortArrayUnsafe( 282 | _In_ PSX_SWITCH_OBJECT Switch, 283 | _Out_ PNDIS_SWITCH_PORT_ARRAY *PortArray 284 | ); 285 | 286 | 287 | /*++ 288 | 289 | SxLibGetNicArrayUnsafe 290 | 291 | Routine Description: 292 | This function is called to get the current array 293 | of NICs. 294 | 295 | NOTE: It is necessary to synchonize this with SxExtNicConnect 296 | and SxExtNicDisconnect. 297 | 298 | Arguments: 299 | 300 | Switch - the Switch context 301 | 302 | NicArray - the returned NIC array 303 | 304 | Return Value: 305 | NDIS_STATUS_SUCCESS - if NicArray was successfully allocated 306 | and returned 307 | 308 | NDIS_STATUS_*** - otherwise 309 | 310 | --*/ 311 | NDIS_STATUS 312 | SxLibGetNicArrayUnsafe( 313 | _In_ PSX_SWITCH_OBJECT SxSwitch, 314 | _Out_ PNDIS_SWITCH_NIC_ARRAY *NicArray 315 | ); 316 | 317 | /*++ 318 | 319 | SxLibGetSwitchPropertyUnsafe 320 | 321 | Routine Description: 322 | This function is called to get the current array of the switch 323 | property queried. 324 | 325 | NOTE: It is necessary to synchonize this with SxExtAddSwitchProperty 326 | and SxExtDeleteSwitchProperty. 327 | 328 | Arguments: 329 | 330 | Switch - the Switch context 331 | 332 | PropertyType - the PropertyType to query for 333 | 334 | PropertyId - the GUID of the property (from mof file) 335 | 336 | PropertyVersion - the version of the property 337 | 338 | SwitchPropertyEnumParameters - the returned property enum 339 | 340 | Return Value: 341 | NDIS_STATUS_SUCCESS - if SwitchPropertyEnumParameters was 342 | successfully allocated and returned 343 | 344 | NDIS_STATUS_*** - otherwise 345 | 346 | --*/ 347 | NDIS_STATUS 348 | SxLibGetSwitchPropertyUnsafe( 349 | _In_ PSX_SWITCH_OBJECT Switch, 350 | _In_ NDIS_SWITCH_PROPERTY_TYPE PropertyType, 351 | _In_opt_ PNDIS_SWITCH_OBJECT_ID PropertyId, 352 | _Outptr_ PNDIS_SWITCH_PROPERTY_ENUM_PARAMETERS *SwitchPropertyEnumParameters 353 | ); 354 | 355 | /*++ 356 | 357 | SxLibGetPortPropertyUnsafe 358 | 359 | Routine Description: 360 | This function is called to get the current array of the switch 361 | property queried. 362 | 363 | NOTE: It is necessary to synchonize this with SxExtAddPortProperty 364 | and SxExtDeletePortProperty. 365 | 366 | Arguments: 367 | 368 | Switch - the Switch context 369 | 370 | PortId - the port to query from 371 | 372 | PropertyType - the PropertyType to query for 373 | 374 | PropertyId - the GUID of the property (from mof file) 375 | 376 | PortPropertyEnumParameters - the returned property enum 377 | 378 | Return Value: 379 | NDIS_STATUS_SUCCESS - if PortPropertyEnumParameters was 380 | successfully allocated and returned 381 | 382 | NDIS_STATUS_*** - otherwise 383 | 384 | --*/ 385 | NDIS_STATUS 386 | SxLibGetPortPropertyUnsafe( 387 | _In_ PSX_SWITCH_OBJECT Switch, 388 | _In_ NDIS_SWITCH_PORT_ID PortId, 389 | _In_ NDIS_SWITCH_PORT_PROPERTY_TYPE PropertyType, 390 | _In_opt_ PNDIS_SWITCH_OBJECT_ID PropertyId, 391 | _Outptr_ PNDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS *PortPropertyEnumParameters 392 | ); 393 | 394 | /*++ 395 | 396 | SxLibRevokeVfUnsafe 397 | 398 | Routine Description: 399 | This function is called revoke the VF assignment for the 400 | given VM. 401 | 402 | NOTE: This must be synchonized with SxExtNicConnect and 403 | SxExtNicDisconnect for the PortId given, and ReferenceSwitchNic 404 | must have been successfully called. 405 | 406 | Arguments: 407 | 408 | Switch - the Switch context 409 | 410 | PortId - the port the VM is connected to 411 | 412 | Return Value: 413 | VOID 414 | 415 | --*/ 416 | VOID 417 | SxLibRevokeVfUnsafe( 418 | _In_ PSX_SWITCH_OBJECT Switch, 419 | _In_ NDIS_SWITCH_PORT_ID PortId 420 | ); 421 | 422 | /*++ 423 | 424 | SxLibIssueNicStatusIndicationUnsafe 425 | 426 | Routine Description: 427 | This function is called issue a NIC status indication. 428 | 429 | NOTE: This must be synchonized with SxExtNicConnect and 430 | SxExtNicDisconnect for the PortId given, and ReferenceSwitchNic 431 | must have been successfully called. 432 | 433 | Arguments: 434 | 435 | Switch - the Switch context 436 | 437 | StatusCode - the status code to indicate 438 | 439 | PortId - the port to indicate to/from 440 | 441 | NicIndex - the nic index to indicate to/from 442 | 443 | IsDestination - TRUE if PortId/NicIndex is destination info 444 | FALSE if PortId/NicIndex is source info 445 | 446 | StatusBuffer - the StatusBuffer for the indication 447 | 448 | StatusBufferSize - the size of StatusBuffer 449 | 450 | Return Value: 451 | VOID 452 | 453 | --*/ 454 | VOID 455 | SxLibIssueNicStatusIndicationUnsafe( 456 | _In_ PSX_SWITCH_OBJECT Switch, 457 | _In_ NDIS_STATUS StatusCode, 458 | _In_ NDIS_SWITCH_PORT_ID PortId, 459 | _In_ NDIS_SWITCH_NIC_INDEX NicIndex, 460 | _In_ BOOLEAN IsDestination, 461 | _In_opt_ PVOID StatusBuffer, 462 | _In_ ULONG StatusBufferSize 463 | ); 464 | 465 | -------------------------------------------------------------------------------- /base/license.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\uc1\htmautsp\deff2{\fonttbl{\f0\fcharset0 Times New Roman;}{\f2\fcharset0 MS Shell Dlg;}}{\colortbl\red0\green0\blue0;\red255\green255\blue255;}\loch\hich\dbch\pard\plain\ltrpar\itap0{\lang1033\fs16\f2\cf0 \cf0\ql{\f2 \line \li0\ri0\sa0\sb0\fi0\ql\par} 2 | {\fs40\f2 {\ltrch MICROSOFT LIMITED PUBLIC LICENSE version 1.1}\li0\ri0\sa0\sb0\fi0\ql\par} 3 | {\f2 \line {\ltrch ----------------------}\line \li0\ri0\sa0\sb0\fi0\ql\par} 4 | {\f2 {\ltrch This license governs use of code marked as \ldblquote sample\rdblquote or \ldblquote example\rdblquote available on this web site without a license agreement, as provided under the section above titled \ldblquote NOTICE SPECIFIC TO SOFTWARE AVAILABLE ON THIS WEB SITE.\rdblquote If you use such code (the \ldblquote software\rdblquote ), you accept this license. If you do not accept the license, do not use the software.}\li0\ri0\sa0\sb0\fi0\ql\par} 5 | {\f2 \line \li0\ri0\sa0\sb0\fi0\ql\par} 6 | {\f2 {\ltrch 1. Definitions}\li0\ri0\sa0\sb0\fi0\ql\par} 7 | {\f2 {\ltrch The terms \ldblquote reproduce,\rdblquote \ldblquote reproduction,\rdblquote \ldblquote derivative works,\rdblquote and \ldblquote distribution\rdblquote have the same meaning here as under U.S. copyright law. }\li0\ri0\sa0\sb0\fi0\ql\par} 8 | {\f2 {\ltrch A \ldblquote contribution\rdblquote is the original software, or any additions or changes to the software.}\li0\ri0\sa0\sb0\fi0\ql\par} 9 | {\f2 {\ltrch A \ldblquote contributor\rdblquote is any person that distributes its contribution under this license.}\li0\ri0\sa0\sb0\fi0\ql\par} 10 | {\f2 {\ltrch \ldblquote Licensed patents\rdblquote are a contributor\rquote s patent claims that read directly on its contribution.}\li0\ri0\sa0\sb0\fi0\ql\par} 11 | {\f2 \line \li0\ri0\sa0\sb0\fi0\ql\par} 12 | {\f2 {\ltrch 2. Grant of Rights}\li0\ri0\sa0\sb0\fi0\ql\par} 13 | {\f2 {\ltrch (A) Copyright Grant - Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.}\li0\ri0\sa0\sb0\fi0\ql\par} 14 | {\f2 {\ltrch (B) Patent Grant - Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.}\li0\ri0\sa0\sb0\fi0\ql\par} 15 | {\f2 \line \li0\ri0\sa0\sb0\fi0\ql\par} 16 | {\f2 {\ltrch 3. Conditions and Limitations}\li0\ri0\sa0\sb0\fi0\ql\par} 17 | {\f2 {\ltrch (A) No Trademark License- This license does not grant you rights to use any contributors\rquote name, logo, or trademarks.}\li0\ri0\sa0\sb0\fi0\ql\par} 18 | {\f2 {\ltrch (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.}\li0\ri0\sa0\sb0\fi0\ql\par} 19 | {\f2 {\ltrch (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.}\li0\ri0\sa0\sb0\fi0\ql\par} 20 | {\f2 {\ltrch (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.}\li0\ri0\sa0\sb0\fi0\ql\par} 21 | {\f2 {\ltrch (E) The software is licensed \ldblquote as-is.\rdblquote You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.}\li0\ri0\sa0\sb0\fi0\ql\par} 22 | {\f2 {\ltrch (F) Platform Limitation - The licenses granted in sections 2(A) and 2(B) extend only to the software or derivative works that you create that run directly on a Microsoft Windows operating system product, Microsoft run-time technology (such as the .NET Framework or Silverlight), or Microsoft application platform (such as Microsoft Office or Microsoft Dynamics).}\li0\ri0\sa0\sb0\fi0\ql\par} 23 | {\f2 \line \li0\ri0\sa0\sb0\fi0\ql\par} 24 | } 25 | } -------------------------------------------------------------------------------- /base/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. All Rights Reserved. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "SxBase.h" 10 | #include "SxApi.h" 11 | #include "SxLibrary.h" 12 | -------------------------------------------------------------------------------- /base/precompsrc.c: -------------------------------------------------------------------------------- 1 | #include "precomp.h" -------------------------------------------------------------------------------- /base/sxbase.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Win8.1 Debug 6 | x64 7 | 8 | 9 | Win8 Debug 10 | x64 11 | 12 | 13 | Win8.1 Release 14 | x64 15 | 16 | 17 | Win8 Release 18 | x64 19 | 20 | 21 | 22 | {33806260-1507-469E-BA3A-6BB73CD75C0D} 23 | $(MSBuildProjectName) 24 | Win8.1 Debug 25 | x64 26 | {5FF7BE81-DFAC-4FB3-B526-55347C34B820} 27 | 28 | 29 | 30 | Win8 31 | False 32 | WDM 33 | WindowsKernelModeDriver8.1 34 | StaticLibrary 35 | 36 | 37 | WindowsV6.3 38 | False 39 | WDM 40 | WindowsKernelModeDriver8.1 41 | StaticLibrary 42 | 43 | 44 | Win8 45 | True 46 | WDM 47 | WindowsKernelModeDriver8.1 48 | StaticLibrary 49 | 50 | 51 | WindowsV6.3 52 | True 53 | WDM 54 | WindowsKernelModeDriver8.1 55 | StaticLibrary 56 | 57 | 58 | 59 | $(IntDir) 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | sxbase 76 | 77 | 78 | sxbase 79 | 80 | 81 | sxbase 82 | 83 | 84 | sxbase 85 | 86 | 87 | 88 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 89 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 90 | 91 | 92 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 93 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 94 | true 95 | Level4 96 | 97 | 98 | 99 | 100 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 101 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 102 | 103 | 104 | %(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib 105 | 106 | 107 | 108 | 109 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 110 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 111 | 112 | 113 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 114 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 115 | true 116 | Level4 117 | 118 | 119 | 120 | 121 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 122 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 123 | 124 | 125 | %(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib 126 | 127 | 128 | 129 | 130 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 131 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 132 | 133 | 134 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 135 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 136 | true 137 | Level4 138 | 139 | 140 | 141 | 142 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 143 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 144 | 145 | 146 | %(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib 147 | 148 | 149 | 150 | 151 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 152 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 153 | 154 | 155 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 156 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 157 | true 158 | Level4 159 | 160 | 161 | 162 | 163 | %(AdditionalIncludeDirectories);$(DDK_INC_PATH) 164 | %(PreprocessorDefinitions);NDIS630=1;NDIS_WDM=1 165 | 166 | 167 | %(AdditionalDependencies);$(DDK_LIB_PATH)\ndis.lib 168 | 169 | 170 | 171 | 172 | ;%(AdditionalIncludeDirectories) 173 | precomp.h 174 | Create 175 | $(IntDir)\precomp.h.pch 176 | 177 | 178 | ;%(AdditionalIncludeDirectories) 179 | precomp.h 180 | Use 181 | $(IntDir)\precomp.h.pch 182 | 183 | 184 | ;%(AdditionalIncludeDirectories) 185 | precomp.h 186 | Use 187 | $(IntDir)\precomp.h.pch 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /base/sxbase.vcxproj.Filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;* 6 | {09648DAC-D607-4F29-AAC7-211462697AB2} 7 | 8 | 9 | h;hpp;hxx;hm;inl;inc;xsd 10 | {46BB3948-7036-46A1-B7CF-D3761BCD41D8} 11 | 12 | 13 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml 14 | {A4F19547-3593-49D1-972C-60895DDEAFD3} 15 | 16 | 17 | --------------------------------------------------------------------------------