├── .clang-format ├── .github └── workflows │ ├── codeql.yml │ └── msbuild.yml ├── BusFilter ├── BusFilter.inx ├── BusFilter.vcxproj ├── BusFilter.vcxproj.filters ├── Device.c ├── Device.h ├── Driver.c ├── Driver.h ├── Public.h ├── Queue.c ├── Queue.h ├── ReadMe.txt └── Trace.h ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── WDKStorPortVirtualMiniport ├── ReadMe.htm ├── ReadMe_files │ ├── colorschememapping.xml │ ├── filelist.xml │ ├── header.htm │ ├── item0007.xml │ ├── props008.xml │ └── themedata.thmx ├── WkRtn.c ├── inc │ ├── WkRtn.tmh │ ├── common.h │ ├── mp.h │ ├── mp.tmh │ ├── mpwmi.h │ ├── scsi.tmh │ ├── trace.h │ ├── trcmp.ini │ ├── utils.tmh │ └── wmi.tmh ├── install │ ├── README.txt │ ├── install.inx │ ├── install.vcxproj │ └── install.vcxproj.filters ├── makefile.inc ├── mp.c ├── mp.inx ├── mp.mof ├── mp.rc ├── mp │ ├── hbaapi.mof │ ├── mp.sln │ ├── mp.vcxproj │ └── mp.vcxproj.filters ├── scsi.c ├── sources ├── utils.c └── wmi.c └── bff ├── bff.c ├── bff.h ├── bff.vcxproj ├── bff.vcxproj.filters └── private.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Microsoft 4 | AccessModifierOffset: -2 5 | AlignAfterOpenBracket: Align 6 | AlignArrayOfStructures: None 7 | AlignConsecutiveAssignments: 8 | Enabled: false 9 | AcrossEmptyLines: false 10 | AcrossComments: false 11 | AlignCompound: false 12 | AlignFunctionPointers: false 13 | PadOperators: true 14 | AlignConsecutiveBitFields: 15 | Enabled: false 16 | AcrossEmptyLines: false 17 | AcrossComments: false 18 | AlignCompound: false 19 | AlignFunctionPointers: false 20 | PadOperators: false 21 | AlignConsecutiveDeclarations: 22 | Enabled: false 23 | AcrossEmptyLines: false 24 | AcrossComments: false 25 | AlignCompound: false 26 | AlignFunctionPointers: false 27 | PadOperators: false 28 | AlignConsecutiveMacros: 29 | Enabled: false 30 | AcrossEmptyLines: false 31 | AcrossComments: false 32 | AlignCompound: false 33 | AlignFunctionPointers: false 34 | PadOperators: false 35 | AlignConsecutiveShortCaseStatements: 36 | Enabled: false 37 | AcrossEmptyLines: false 38 | AcrossComments: false 39 | AlignCaseColons: false 40 | AlignEscapedNewlines: Right 41 | AlignOperands: Align 42 | AlignTrailingComments: 43 | Kind: Always 44 | OverEmptyLines: 0 45 | AllowAllArgumentsOnNextLine: true 46 | AllowAllParametersOfDeclarationOnNextLine: true 47 | AllowBreakBeforeNoexceptSpecifier: Never 48 | AllowShortBlocksOnASingleLine: Never 49 | AllowShortCaseLabelsOnASingleLine: false 50 | AllowShortCompoundRequirementOnASingleLine: true 51 | AllowShortEnumsOnASingleLine: false 52 | AllowShortFunctionsOnASingleLine: None 53 | AllowShortIfStatementsOnASingleLine: Never 54 | AllowShortLambdasOnASingleLine: All 55 | AllowShortLoopsOnASingleLine: false 56 | AlwaysBreakAfterDefinitionReturnType: None 57 | AlwaysBreakAfterReturnType: None 58 | AlwaysBreakBeforeMultilineStrings: false 59 | AlwaysBreakTemplateDeclarations: MultiLine 60 | AttributeMacros: 61 | - __capability 62 | BinPackArguments: true 63 | BinPackParameters: true 64 | BitFieldColonSpacing: Both 65 | BraceWrapping: 66 | AfterCaseLabel: false 67 | AfterClass: true 68 | AfterControlStatement: Always 69 | AfterEnum: true 70 | AfterExternBlock: true 71 | AfterFunction: true 72 | AfterNamespace: true 73 | AfterObjCDeclaration: true 74 | AfterStruct: true 75 | AfterUnion: false 76 | BeforeCatch: true 77 | BeforeElse: true 78 | BeforeLambdaBody: false 79 | BeforeWhile: false 80 | IndentBraces: false 81 | SplitEmptyFunction: true 82 | SplitEmptyRecord: true 83 | SplitEmptyNamespace: true 84 | BreakAdjacentStringLiterals: true 85 | BreakAfterAttributes: Leave 86 | BreakAfterJavaFieldAnnotations: false 87 | BreakArrays: true 88 | BreakBeforeBinaryOperators: None 89 | BreakBeforeConceptDeclarations: Always 90 | BreakBeforeBraces: Custom 91 | BreakBeforeInlineASMColon: OnlyMultiline 92 | BreakBeforeTernaryOperators: true 93 | BreakConstructorInitializers: BeforeColon 94 | BreakInheritanceList: BeforeColon 95 | BreakStringLiterals: true 96 | ColumnLimit: 120 97 | CommentPragmas: '^ IWYU pragma:' 98 | CompactNamespaces: false 99 | ConstructorInitializerIndentWidth: 4 100 | ContinuationIndentWidth: 4 101 | Cpp11BracedListStyle: true 102 | DerivePointerAlignment: false 103 | DisableFormat: false 104 | EmptyLineAfterAccessModifier: Never 105 | EmptyLineBeforeAccessModifier: LogicalBlock 106 | ExperimentalAutoDetectBinPacking: false 107 | FixNamespaceComments: true 108 | ForEachMacros: 109 | - foreach 110 | - Q_FOREACH 111 | - BOOST_FOREACH 112 | IfMacros: 113 | - KJ_IF_MAYBE 114 | IncludeBlocks: Preserve 115 | IncludeCategories: 116 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 117 | Priority: 2 118 | SortPriority: 0 119 | CaseSensitive: false 120 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 121 | Priority: 3 122 | SortPriority: 0 123 | CaseSensitive: false 124 | - Regex: '.*' 125 | Priority: 1 126 | SortPriority: 0 127 | CaseSensitive: false 128 | IncludeIsMainRegex: '(Test)?$' 129 | IncludeIsMainSourceRegex: '' 130 | IndentAccessModifiers: false 131 | IndentCaseBlocks: false 132 | IndentCaseLabels: false 133 | IndentExternBlock: AfterExternBlock 134 | IndentGotoLabels: true 135 | IndentPPDirectives: None 136 | IndentRequiresClause: true 137 | IndentWidth: 4 138 | IndentWrappedFunctionNames: false 139 | InsertBraces: false 140 | InsertNewlineAtEOF: false 141 | InsertTrailingCommas: None 142 | IntegerLiteralSeparator: 143 | Binary: 0 144 | BinaryMinDigits: 0 145 | Decimal: 0 146 | DecimalMinDigits: 0 147 | Hex: 0 148 | HexMinDigits: 0 149 | JavaScriptQuotes: Leave 150 | JavaScriptWrapImports: true 151 | KeepEmptyLinesAtTheStartOfBlocks: true 152 | KeepEmptyLinesAtEOF: false 153 | LambdaBodyIndentation: Signature 154 | LineEnding: DeriveLF 155 | MacroBlockBegin: '' 156 | MacroBlockEnd: '' 157 | MaxEmptyLinesToKeep: 1 158 | NamespaceIndentation: None 159 | ObjCBinPackProtocolList: Auto 160 | ObjCBlockIndentWidth: 2 161 | ObjCBreakBeforeNestedBlockParam: true 162 | ObjCSpaceAfterProperty: false 163 | ObjCSpaceBeforeProtocolList: true 164 | PackConstructorInitializers: BinPack 165 | PenaltyBreakAssignment: 2 166 | PenaltyBreakBeforeFirstCallParameter: 19 167 | PenaltyBreakComment: 300 168 | PenaltyBreakFirstLessLess: 120 169 | PenaltyBreakOpenParenthesis: 0 170 | PenaltyBreakScopeResolution: 500 171 | PenaltyBreakString: 1000 172 | PenaltyBreakTemplateDeclaration: 10 173 | PenaltyExcessCharacter: 1000000 174 | PenaltyIndentedWhitespace: 0 175 | PenaltyReturnTypeOnItsOwnLine: 1000 176 | PointerAlignment: Right 177 | PPIndentWidth: -1 178 | QualifierAlignment: Leave 179 | ReferenceAlignment: Pointer 180 | ReflowComments: true 181 | RemoveBracesLLVM: false 182 | RemoveParentheses: Leave 183 | RemoveSemicolon: false 184 | RequiresClausePosition: OwnLine 185 | RequiresExpressionIndentation: OuterScope 186 | SeparateDefinitionBlocks: Leave 187 | ShortNamespaceLines: 1 188 | SkipMacroDefinitionBody: false 189 | SortIncludes: Never 190 | SortJavaStaticImport: Before 191 | SortUsingDeclarations: LexicographicNumeric 192 | SpaceAfterCStyleCast: false 193 | SpaceAfterLogicalNot: false 194 | SpaceAfterTemplateKeyword: true 195 | SpaceAroundPointerQualifiers: Default 196 | SpaceBeforeAssignmentOperators: true 197 | SpaceBeforeCaseColon: false 198 | SpaceBeforeCpp11BracedList: false 199 | SpaceBeforeCtorInitializerColon: true 200 | SpaceBeforeInheritanceColon: true 201 | SpaceBeforeJsonColon: false 202 | SpaceBeforeParens: ControlStatements 203 | SpaceBeforeParensOptions: 204 | AfterControlStatements: true 205 | AfterForeachMacros: true 206 | AfterFunctionDefinitionName: false 207 | AfterFunctionDeclarationName: false 208 | AfterIfMacros: true 209 | AfterOverloadedOperator: false 210 | AfterPlacementOperator: true 211 | AfterRequiresInClause: false 212 | AfterRequiresInExpression: false 213 | BeforeNonEmptyParentheses: false 214 | SpaceBeforeRangeBasedForLoopColon: true 215 | SpaceBeforeSquareBrackets: false 216 | SpaceInEmptyBlock: false 217 | SpacesBeforeTrailingComments: 1 218 | SpacesInAngles: Never 219 | SpacesInContainerLiterals: true 220 | SpacesInLineCommentPrefix: 221 | Minimum: 1 222 | Maximum: -1 223 | SpacesInParens: Never 224 | SpacesInParensOptions: 225 | InCStyleCasts: false 226 | InConditionalStatements: false 227 | InEmptyParentheses: false 228 | Other: false 229 | SpacesInSquareBrackets: false 230 | Standard: Latest 231 | StatementAttributeLikeMacros: 232 | - Q_EMIT 233 | StatementMacros: 234 | - Q_UNUSED 235 | - QT_REQUIRE_VERSION 236 | TabWidth: 4 237 | UseTab: Never 238 | VerilogBreakBetweenInstancePorts: true 239 | WhitespaceSensitiveMacros: 240 | - BOOST_PP_STRINGIZE 241 | - CF_SWIFT_NAME 242 | - NS_SWIFT_NAME 243 | - PP_STRINGIZE 244 | - STRINGIZE 245 | ... 246 | 247 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL Advanced" 13 | 14 | on: 15 | push: 16 | branches: [ "master" ] 17 | pull_request: 18 | branches: [ "master" ] 19 | schedule: 20 | - cron: '38 7 * * 5' 21 | 22 | jobs: 23 | analyze: 24 | name: Analyze (${{ matrix.language }}) 25 | # Runner size impacts CodeQL analysis time. To learn more, please see: 26 | # - https://gh.io/recommended-hardware-resources-for-running-codeql 27 | # - https://gh.io/supported-runners-and-hardware-resources 28 | # - https://gh.io/using-larger-runners (GitHub.com only) 29 | # Consider using larger runners or machines with greater resources for possible analysis time improvements. 30 | runs-on: 'windows-latest' 31 | permissions: 32 | # required for all workflows 33 | security-events: write 34 | 35 | # required to fetch internal or private CodeQL packs 36 | packages: read 37 | 38 | # only required for workflows in private repositories 39 | actions: read 40 | contents: read 41 | 42 | strategy: 43 | fail-fast: false 44 | matrix: 45 | include: 46 | - language: c-cpp 47 | build-mode: autobuild 48 | # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' 49 | # Use `c-cpp` to analyze code written in C, C++ or both 50 | # Use 'java-kotlin' to analyze code written in Java, Kotlin or both 51 | # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both 52 | # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, 53 | # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. 54 | # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how 55 | # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages 56 | steps: 57 | - name: Checkout repository 58 | uses: actions/checkout@v4 59 | 60 | # Initializes the CodeQL tools for scanning. 61 | - name: Initialize CodeQL 62 | uses: github/codeql-action/init@v3 63 | with: 64 | languages: ${{ matrix.language }} 65 | build-mode: ${{ matrix.build-mode }} 66 | # If you wish to specify custom queries, you can do so here or in a config file. 67 | # By default, queries listed here will override any specified in a config file. 68 | # Prefix the list here with "+" to use these queries and those in the config file. 69 | 70 | # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 71 | # queries: security-extended,security-and-quality 72 | queries: security-and-quality 73 | 74 | # If the analyze step fails for one of the languages you are analyzing with 75 | # "We were unable to automatically build your code", modify the matrix above 76 | # to set the build mode to "manual" for that language. Then modify this step 77 | # to build your code. 78 | # ℹ️ Command-line programs to run using the OS shell. 79 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 80 | - if: matrix.build-mode == 'manual' 81 | env: 82 | # Path to the solution file relative to the root of the project. 83 | SOLUTION_FILE_PATH: .\WDKStorPortVirtualMiniport\mp\mp.sln 84 | 85 | # Configuration type to build. 86 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 87 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 88 | BUILD_CONFIGURATION: Release 89 | BUILD_PLATFORM: x64 90 | TARGET_VERSION: Windows10 91 | shell: cmd 92 | working-directory: . 93 | run: | 94 | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat" 95 | msbuild /t:clean /t:build /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{env.BUILD_PLATFORM}} /p:TargetVersion=${{env.TARGET_VERSION}} ${{env.SOLUTION_FILE_PATH}} 96 | 97 | - name: Perform CodeQL Analysis 98 | uses: github/codeql-action/analyze@v3 99 | with: 100 | category: "/language:${{matrix.language}}" 101 | -------------------------------------------------------------------------------- /.github/workflows/msbuild.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: MSBuild 7 | 8 | on: 9 | push: 10 | branches: [ "master" ] 11 | pull_request: 12 | branches: [ "master" ] 13 | 14 | env: 15 | # Path to the solution file relative to the root of the project. 16 | SOLUTION_FILE_PATH: .\WDKStorPortVirtualMiniport\mp\mp.sln 17 | 18 | # Configuration type to build. 19 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 20 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 21 | BUILD_CONFIGURATION: Release 22 | BUILD_PLATFORM: x64 23 | TARGET_VERSION: Windows10 24 | 25 | permissions: 26 | contents: read 27 | 28 | jobs: 29 | build: 30 | runs-on: windows-latest 31 | 32 | steps: 33 | - uses: actions/checkout@v4 34 | 35 | - name: Add MSBuild to PATH 36 | uses: microsoft/setup-msbuild@v1.0.2 37 | 38 | - name: Restore NuGet packages 39 | working-directory: ${{env.GITHUB_WORKSPACE}} 40 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 41 | 42 | - name: Build 43 | working-directory: ${{env.GITHUB_WORKSPACE}} 44 | # Add additional options to the MSBuild command line here (like platform or verbosity level). 45 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference 46 | run: msbuild /t:clean /t:build /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{env.BUILD_PLATFORM}} /p:TargetVersion=${{env.TARGET_VERSION}} ${{env.SOLUTION_FILE_PATH}} 47 | -------------------------------------------------------------------------------- /BusFilter/BusFilter.inx: -------------------------------------------------------------------------------- 1 | ; 2 | ; BusFilter.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=BusFilter.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | BusFilter_Device_CoInstaller_CopyFiles = 11 16 | 17 | ; ================= Class section ===================== 18 | 19 | [ClassInstall32] 20 | Addreg=SampleClassReg 21 | 22 | [SampleClassReg] 23 | HKR,,,0,%ClassName% 24 | HKR,,Icon,,-5 25 | 26 | [SourceDisksNames] 27 | 1 = %DiskName%,,,"" 28 | 29 | [SourceDisksFiles] 30 | BusFilter.sys = 1,, 31 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 32 | 33 | ;***************************************** 34 | ; Install Section 35 | ;***************************************** 36 | 37 | [Manufacturer] 38 | %ManufacturerName%=Standard,NT$ARCH$ 39 | 40 | [Standard.NT$ARCH$] 41 | %BusFilter.DeviceDesc%=BusFilter_Device, Root\BusFilter ; TODO: edit hw-id 42 | 43 | [BusFilter_Device.NT] 44 | CopyFiles=Drivers_Dir 45 | 46 | [Drivers_Dir] 47 | BusFilter.sys 48 | 49 | ;-------------- Service installation 50 | [BusFilter_Device.NT.Services] 51 | AddService = BusFilter,%SPSVCINST_ASSOCSERVICE%, BusFilter_Service_Inst 52 | 53 | ; -------------- BusFilter driver install sections 54 | [BusFilter_Service_Inst] 55 | DisplayName = %BusFilter.SVCDESC% 56 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 57 | StartType = 3 ; SERVICE_DEMAND_START 58 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 59 | ServiceBinary = %12%\BusFilter.sys 60 | 61 | ; 62 | ;--- BusFilter_Device Coinstaller installation ------ 63 | ; 64 | 65 | ;[DestinationDirs] 66 | ;BusFilter_Device_CoInstaller_CopyFiles = 11 67 | 68 | [BusFilter_Device.NT.CoInstallers] 69 | AddReg=BusFilter_Device_CoInstaller_AddReg 70 | CopyFiles=BusFilter_Device_CoInstaller_CopyFiles 71 | 72 | [BusFilter_Device_CoInstaller_AddReg] 73 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 74 | 75 | [BusFilter_Device_CoInstaller_CopyFiles] 76 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 77 | 78 | ;[SourceDisksFiles] 79 | ;WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 80 | 81 | [BusFilter_Device.NT.Wdf] 82 | KmdfService = BusFilter, BusFilter_wdfsect 83 | [BusFilter_wdfsect] 84 | KmdfLibraryVersion = $KMDFVERSION$ 85 | 86 | [Strings] 87 | SPSVCINST_ASSOCSERVICE= 0x00000002 88 | ManufacturerName="" ;TODO: Replace with your manufacturer name 89 | ClassName="Samples" ; TODO: edit ClassName 90 | DiskName = "BusFilter Installation Disk" 91 | BusFilter.DeviceDesc = "BusFilter Device" 92 | BusFilter.SVCDESC = "BusFilter Service" 93 | -------------------------------------------------------------------------------- /BusFilter/BusFilter.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | %(DisableSpecificWarnings) 43 | %(DisableSpecificWarnings) 44 | %(DisableSpecificWarnings) 45 | %(DisableSpecificWarnings) 46 | %(DisableSpecificWarnings) 47 | %(DisableSpecificWarnings) 48 | %(DisableSpecificWarnings) 49 | %(DisableSpecificWarnings) 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {E65D39A3-0DA9-4A25-BA70-2A5092C2EC5E} 63 | {497e31cb-056b-4f31-abb8-447fd55ee5a5} 64 | v4.5 65 | 12.0 66 | Debug 67 | Win32 68 | BusFilter 69 | 70 | 71 | 72 | Windows7 73 | true 74 | WindowsKernelModeDriver10.0 75 | Driver 76 | KMDF 77 | Desktop 78 | 79 | 80 | Windows7 81 | false 82 | WindowsKernelModeDriver10.0 83 | Driver 84 | KMDF 85 | Desktop 86 | 87 | 88 | Windows7 89 | true 90 | WindowsKernelModeDriver10.0 91 | Driver 92 | KMDF 93 | Desktop 94 | 95 | 96 | Windows10 97 | false 98 | WindowsKernelModeDriver10.0 99 | Driver 100 | KMDF 101 | Desktop 102 | 103 | 104 | Windows7 105 | true 106 | WindowsKernelModeDriver10.0 107 | Driver 108 | KMDF 109 | Desktop 110 | 111 | 112 | Windows7 113 | false 114 | WindowsKernelModeDriver10.0 115 | Driver 116 | KMDF 117 | Desktop 118 | 119 | 120 | Windows7 121 | true 122 | WindowsKernelModeDriver10.0 123 | Driver 124 | KMDF 125 | Desktop 126 | 127 | 128 | Windows7 129 | false 130 | WindowsKernelModeDriver10.0 131 | Driver 132 | KMDF 133 | Desktop 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | DbgengKernelDebugger 145 | true 146 | false 147 | 148 | 149 | DbgengKernelDebugger 150 | true 151 | false 152 | 153 | 154 | DbgengKernelDebugger 155 | true 156 | false 157 | 158 | 159 | DbgengKernelDebugger 160 | true 161 | false 162 | 163 | 164 | DbgengKernelDebugger 165 | true 166 | 167 | 168 | DbgengKernelDebugger 169 | true 170 | 171 | 172 | DbgengKernelDebugger 173 | true 174 | 175 | 176 | DbgengKernelDebugger 177 | true 178 | 179 | 180 | 181 | true 182 | true 183 | trace.h 184 | true 185 | 4100;%(DisableSpecificWarnings) 186 | 187 | 188 | copy *.c ..\bffsample\BusFilter & copy *.h ..\bffsample\BusFilter 189 | 190 | 191 | Copy source code files to ..\bffsample\BusFilter 192 | 193 | 194 | 195 | 196 | true 197 | true 198 | trace.h 199 | true 200 | 4100;%(DisableSpecificWarnings) 201 | 202 | 203 | copy *.c ..\bffsample\BusFilter & copy *.h ..\bffsample\BusFilter 204 | 205 | 206 | Copy source code files to ..\bffsample\BusFilter 207 | 208 | 209 | 210 | 211 | true 212 | true 213 | trace.h 214 | true 215 | 4100;%(DisableSpecificWarnings) 216 | 217 | 218 | copy *.c ..\bffsample\BusFilter & copy *.h ..\bffsample\BusFilter 219 | 220 | 221 | Copy source code files to ..\bffsample\BusFilter 222 | 223 | 224 | 225 | 226 | true 227 | true 228 | trace.h 229 | true 230 | 4100;%(DisableSpecificWarnings) 231 | 232 | 233 | copy *.c ..\bffsample\BusFilter & copy *.h ..\bffsample\BusFilter 234 | 235 | 236 | Copy source code files to ..\bffsample\BusFilter 237 | 238 | 239 | 240 | /fd SHA256 %(AdditionalOptions) 241 | 242 | 243 | 244 | 245 | true 246 | true 247 | trace.h 248 | true 249 | 4100;%(DisableSpecificWarnings) 250 | 251 | 252 | copy *.c ..\bffsample\BusFilter & copy *.h ..\bffsample\BusFilter 253 | 254 | 255 | Copy source code files to ..\bffsample\BusFilter 256 | 257 | 258 | 259 | 260 | true 261 | true 262 | trace.h 263 | true 264 | 4100;%(DisableSpecificWarnings) 265 | 266 | 267 | copy *.c ..\bffsample\BusFilter & copy *.h ..\bffsample\BusFilter 268 | 269 | 270 | Copy source code files to ..\bffsample\BusFilter 271 | 272 | 273 | 274 | 275 | true 276 | true 277 | trace.h 278 | true 279 | 4100;%(DisableSpecificWarnings) 280 | 281 | 282 | copy *.c ..\bffsample\BusFilter & copy *.h ..\bffsample\BusFilter 283 | 284 | 285 | Copy source code files to ..\bffsample\BusFilter 286 | 287 | 288 | 289 | 290 | true 291 | true 292 | trace.h 293 | true 294 | 4100;%(DisableSpecificWarnings) 295 | 296 | 297 | copy *.c ..\bffsample\BusFilter & copy *.h ..\bffsample\BusFilter 298 | 299 | 300 | Copy source code files to ..\bffsample\BusFilter 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | {a1e905cb-21af-4167-87d9-90927a7a67c6} 309 | 310 | 311 | 312 | 313 | 314 | -------------------------------------------------------------------------------- /BusFilter/BusFilter.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Header Files 27 | 28 | 29 | Header Files 30 | 31 | 32 | Header Files 33 | 34 | 35 | Header Files 36 | 37 | 38 | Header Files 39 | 40 | 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | -------------------------------------------------------------------------------- /BusFilter/Device.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework Sample Driver 3 | Copyright (C) 2017 Yang Yuanzhi 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | *******************************************************************************/ 18 | /*++ 19 | 20 | Bus filter sameple driver, based on Bus Filter Framework, or BFF for short, 21 | which is a framework for KMDF-based upper filter drivers to behave as bus 22 | filters. You don't need to write WDM drivers any more! 23 | 24 | https://bus-filter-framework.blogspot.com/ 25 | 26 | This sample driver registers a device interface for every child device, and 27 | prepends "BffDevice" to the compatible IDs list. 28 | 29 | Module Name: 30 | 31 | device.c - Device handling events for example driver. 32 | 33 | Abstract: 34 | 35 | This file contains the device entry points and callbacks. 36 | 37 | Environment: 38 | 39 | Kernel-mode Driver Framework 40 | 41 | --*/ 42 | 43 | #include "driver.h" 44 | #include "device.tmh" 45 | #include "..\bff\bff.h" 46 | 47 | #ifdef ALLOC_PRAGMA 48 | #pragma alloc_text(PAGE, BusFilterCreateDevice) 49 | #endif 50 | 51 | NTSTATUS 52 | BusFilterCreateDevice(_Inout_ PWDFDEVICE_INIT DeviceInit) 53 | /*++ 54 | 55 | Routine Description: 56 | 57 | Worker routine called to create a device and its software resources. 58 | 59 | Arguments: 60 | 61 | DeviceInit - Pointer to an opaque init structure. Memory for this 62 | structure will be freed by the framework when the WdfDeviceCreate 63 | succeeds. So don't access the structure after that point. 64 | 65 | Return Value: 66 | 67 | NTSTATUS 68 | 69 | --*/ 70 | { 71 | WDF_OBJECT_ATTRIBUTES deviceAttributes; 72 | PDEVICE_CONTEXT deviceContext; 73 | WDFDEVICE device; 74 | NTSTATUS status; 75 | UCHAR minorPnP = IRP_MN_QUERY_DEVICE_RELATIONS; 76 | 77 | PAGED_CODE(); 78 | 79 | status = WdfDeviceInitAssignWdmIrpPreprocessCallback(DeviceInit, BffPreprocessQueryBusRelations, IRP_MJ_PNP, 80 | &minorPnP, 1); 81 | if (!NT_SUCCESS(status)) 82 | { 83 | KdPrint(("%s: WdfDeviceInitAssignWdmIrpPreprocessCallback failed: %x\n", __FUNCTION__, status)); 84 | return status; 85 | } 86 | 87 | WdfFdoInitSetFilter(DeviceInit); 88 | 89 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); 90 | 91 | status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); 92 | 93 | if (NT_SUCCESS(status)) 94 | { 95 | // 96 | // Get a pointer to the device context structure that we just associated 97 | // with the device object. We define this structure in the device.h 98 | // header file. DeviceGetContext is an inline function generated by 99 | // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h. 100 | // This function will do the type checking and return the device context. 101 | // If you pass a wrong object handle it will return NULL and assert if 102 | // run under framework verifier mode. 103 | // 104 | deviceContext = DeviceGetContext(device); 105 | 106 | // 107 | // Initialize the context. 108 | // 109 | deviceContext->PrivateDeviceData = 0; 110 | 111 | #if 0 112 | // 113 | // Create a device interface so that applications can find and talk 114 | // to us. 115 | // 116 | status = WdfDeviceCreateDeviceInterface( 117 | device, 118 | &GUID_DEVINTERFACE_BusFilter, 119 | NULL // ReferenceString 120 | ); 121 | #else 122 | status = BffAllocateContext(device); 123 | #endif 124 | 125 | if (NT_SUCCESS(status)) 126 | { 127 | // 128 | // Initialize the I/O Package and any Queues 129 | // 130 | status = BusFilterQueueInitialize(device); 131 | } 132 | } 133 | 134 | return status; 135 | } 136 | -------------------------------------------------------------------------------- /BusFilter/Device.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework Sample Driver 3 | Copyright (C) 2017 Yang Yuanzhi 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | *******************************************************************************/ 18 | /*++ 19 | 20 | Bus filter sameple driver, based on Bus Filter Framework, or BFF for short, 21 | which is a framework for KMDF-based upper filter drivers to behave as bus 22 | filters. You don't need to write WDM drivers any more! 23 | 24 | https://bus-filter-framework.blogspot.com/ 25 | 26 | This sample driver registers a device interface for every child device, and 27 | prepends "BffDevice" to the compatible IDs list. 28 | 29 | Module Name: 30 | 31 | device.h 32 | 33 | Abstract: 34 | 35 | This file contains the device definitions. 36 | 37 | Environment: 38 | 39 | Kernel-mode Driver Framework 40 | 41 | --*/ 42 | 43 | #pragma once 44 | #include "public.h" 45 | 46 | EXTERN_C_START 47 | 48 | typedef struct _BUS_FILTER_CONTEXT 49 | { 50 | WDFDEVICE Parent; 51 | BOOLEAN IsRegistered; 52 | UNICODE_STRING SymbolicLink; 53 | } BUS_FILTER_CONTEXT, *PBUS_FILTER_CONTEXT; 54 | 55 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(BUS_FILTER_CONTEXT, BusFilterGetContext) 56 | 57 | // 58 | // The device context performs the same job as 59 | // a WDM device extension in the driver frameworks 60 | // 61 | typedef struct _DEVICE_CONTEXT 62 | { 63 | ULONG PrivateDeviceData; // just a placeholder 64 | 65 | } DEVICE_CONTEXT, *PDEVICE_CONTEXT; 66 | 67 | // 68 | // This macro will generate an inline function called DeviceGetContext 69 | // which will be used to get a pointer to the device context memory 70 | // in a type safe manner. 71 | // 72 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext) 73 | 74 | // 75 | // Function to initialize the device and its callbacks 76 | // 77 | NTSTATUS 78 | BusFilterCreateDevice(_Inout_ PWDFDEVICE_INIT DeviceInit); 79 | 80 | EXTERN_C_END 81 | -------------------------------------------------------------------------------- /BusFilter/Driver.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework Sample Driver 3 | Copyright (C) 2017 Yang Yuanzhi 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | *******************************************************************************/ 18 | /*++ 19 | 20 | Bus filter sameple driver, based on Bus Filter Framework, or BFF for short, 21 | which is a framework for KMDF-based upper filter drivers to behave as bus 22 | filters. You don't need to write WDM drivers any more! 23 | 24 | https://bus-filter-framework.blogspot.com/ 25 | 26 | This sample driver registers a device interface for every child device, and 27 | prepends "BffDevice" to the compatible IDs list. 28 | 29 | Module Name: 30 | 31 | driver.c 32 | 33 | Abstract: 34 | 35 | This file contains the driver entry points and callbacks. 36 | 37 | Environment: 38 | 39 | Kernel-mode Driver Framework 40 | 41 | --*/ 42 | 43 | #include 44 | #include "driver.h" 45 | #include "driver.tmh" 46 | #include "..\bff\bff.h" 47 | 48 | #ifdef ALLOC_PRAGMA 49 | #pragma alloc_text(INIT, DriverEntry) 50 | #pragma alloc_text(PAGE, BusFilterEvtDeviceAdd) 51 | #pragma alloc_text(PAGE, BusFilterEvtDriverContextCleanup) 52 | #endif 53 | 54 | NTSTATUS 55 | BusFilterDeviceEnumerated(WDFOBJECT BffDevice, PIRP Irp) 56 | { 57 | PBUS_FILTER_CONTEXT busFilterContext = BusFilterGetContext(BffDevice); 58 | KIRQL irql = KeGetCurrentIrql(); 59 | if (irql != PASSIVE_LEVEL) 60 | { 61 | KdPrint(("IRP_MN_DEVICE_ENUMERATED not at PASSIVE_LEVEL\n")); 62 | } 63 | else 64 | { 65 | NTSTATUS status = 66 | IoRegisterDeviceInterface(BffDeviceWdmGetPhysicalDevice(BffDevice), &GUID_DEVINTERFACE_BusFilter, NULL, 67 | &busFilterContext->SymbolicLink); 68 | if (NT_SUCCESS(status)) 69 | busFilterContext->IsRegistered = TRUE; 70 | } 71 | 72 | // 73 | // Forward to the parent bus driver 74 | // 75 | IoSkipCurrentIrpStackLocation(Irp); 76 | return IoCallDriver(BffDeviceWdmGetAttachedDevice(BffDevice), Irp); 77 | } 78 | 79 | NTSTATUS 80 | BusFilterStartDevice(IN WDFOBJECT BffDevice, IN PIRP Irp) 81 | { 82 | PBUS_FILTER_CONTEXT busFilterContext = BusFilterGetContext(BffDevice); 83 | NTSTATUS status; 84 | 85 | PAGED_CODE(); 86 | 87 | if (!IoForwardIrpSynchronously(BffDeviceWdmGetAttachedDevice(BffDevice), Irp)) 88 | Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE; 89 | else if (NT_SUCCESS(Irp->IoStatus.Status) && busFilterContext->IsRegistered) 90 | Irp->IoStatus.Status = IoSetDeviceInterfaceState(&busFilterContext->SymbolicLink, TRUE); 91 | 92 | // 93 | // Complete the Irp 94 | // 95 | status = Irp->IoStatus.Status; 96 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 97 | 98 | return status; 99 | } 100 | 101 | static NTSTATUS BusFilterAddDevice(WDFDEVICE Device, WDFOBJECT BffDevice) 102 | { 103 | NTSTATUS status; 104 | WDF_OBJECT_ATTRIBUTES attr; 105 | PBUS_FILTER_CONTEXT busFilterContext; 106 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, BUS_FILTER_CONTEXT); 107 | // 108 | // According to WDF document: 109 | // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdfobject/nf-wdfobject-wdfobjectallocatecontext 110 | // we shall not specify ParentObject here. 111 | // Thanks to HSY, https://github.com/hsy2019cn 112 | // 113 | // attr.ParentObject = Device; 114 | status = WdfObjectAllocateContext(BffDevice, &attr, &busFilterContext); 115 | if (!NT_SUCCESS(status)) 116 | KdPrint(("%s: failed to allocate BUS_FILTER_CONTEXT: %x\n", __FUNCTION__, status)); 117 | else 118 | { 119 | ASSERT(BusFilterGetContext(BffDevice) == busFilterContext); 120 | busFilterContext->Parent = Device; 121 | } 122 | return status; 123 | } 124 | 125 | static VOID BusFilterRemoveDevice(WDFDEVICE Device, WDFOBJECT BffDevice) 126 | { 127 | PBUS_FILTER_CONTEXT busFilterContext = BusFilterGetContext(BffDevice); 128 | if (busFilterContext->IsRegistered) 129 | { 130 | IoSetDeviceInterfaceState(&busFilterContext->SymbolicLink, FALSE); 131 | RtlFreeUnicodeString(&busFilterContext->SymbolicLink); 132 | } 133 | } 134 | 135 | static NTSTATUS BusFilterQueryID(WDFOBJECT BffDevice, PIRP Irp) 136 | { 137 | NTSTATUS status; 138 | PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); 139 | ASSERT(stack->MajorFunction == IRP_MJ_PNP); 140 | ASSERT(stack->MinorFunction == IRP_MN_QUERY_ID); 141 | if (stack->Parameters.QueryId.IdType != BusQueryCompatibleIDs) 142 | { 143 | IoSkipCurrentIrpStackLocation(Irp); 144 | return IoCallDriver(BffDeviceWdmGetAttachedDevice(BffDevice), Irp); 145 | } 146 | 147 | if (!IoForwardIrpSynchronously(BffDeviceWdmGetAttachedDevice(BffDevice), Irp)) 148 | Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE; 149 | else if (NT_SUCCESS(Irp->IoStatus.Status) && Irp->IoStatus.Information) 150 | { 151 | WCHAR *newCompatibleIDs = ExAllocatePoolWithTag(PagedPool, 200 * sizeof(WCHAR), 'tFFB'); 152 | if (newCompatibleIDs) 153 | { 154 | WCHAR *newIDs = newCompatibleIDs; 155 | WCHAR *oldIDs = (WCHAR *)Irp->IoStatus.Information; 156 | size_t length = wcslen(L"BffDevice") + 1; 157 | wcscpy(newIDs, L"BffDevice"); 158 | newIDs += length; 159 | // 160 | // oldIDs is a multi-sz list, hence two NULL characters 161 | // terminated. 162 | // 163 | while (oldIDs && *oldIDs && length + wcslen(oldIDs) + 2 <= 200) 164 | { 165 | wcscpy(newIDs, oldIDs); 166 | length += wcslen(oldIDs) + 1; 167 | newIDs += wcslen(oldIDs) + 1; 168 | oldIDs += wcslen(oldIDs) + 1; 169 | } 170 | *newIDs = 0; 171 | ExFreePoolWithTag((PVOID)Irp->IoStatus.Information, 0); 172 | Irp->IoStatus.Information = (ULONG_PTR)newCompatibleIDs; 173 | } 174 | } 175 | // 176 | // Complete the Irp 177 | // 178 | status = Irp->IoStatus.Status; 179 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 180 | 181 | return status; 182 | } 183 | 184 | NTSTATUS 185 | DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) 186 | /*++ 187 | 188 | Routine Description: 189 | DriverEntry initializes the driver and is the first routine called by the 190 | system after the driver is loaded. DriverEntry specifies the other entry 191 | points in the function driver, such as EvtDevice and DriverUnload. 192 | 193 | Parameters Description: 194 | 195 | DriverObject - represents the instance of the function driver that is loaded 196 | into memory. DriverEntry must initialize members of DriverObject before it 197 | returns to the caller. DriverObject is allocated by the system before the 198 | driver is loaded, and it is released by the system after the system unloads 199 | the function driver from memory. 200 | 201 | RegistryPath - represents the driver specific path in the Registry. 202 | The function driver can use the path to store driver related data between 203 | reboots. The path does not store hardware instance specific data. 204 | 205 | Return Value: 206 | 207 | STATUS_SUCCESS if successful, 208 | STATUS_UNSUCCESSFUL otherwise. 209 | 210 | --*/ 211 | { 212 | WDF_DRIVER_CONFIG config; 213 | NTSTATUS status; 214 | WDF_OBJECT_ATTRIBUTES attributes; 215 | BFF_INITIALIZATION_DATA initData; 216 | BffSetInitializationData(&initData, FILE_DEVICE_DISK, 0, BusFilterAddDevice, BusFilterRemoveDevice); 217 | initData.PnPMinorFunction[IRP_MN_START_DEVICE] = BusFilterStartDevice; 218 | initData.PnPMinorFunction[IRP_MN_DEVICE_ENUMERATED] = BusFilterDeviceEnumerated; 219 | initData.PnPMinorFunction[IRP_MN_QUERY_ID] = BusFilterQueryID; 220 | 221 | // 222 | // Initialize WPP Tracing 223 | // 224 | WPP_INIT_TRACING(DriverObject, RegistryPath); 225 | 226 | TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); 227 | 228 | // 229 | // Register a cleanup callback so that we can call WPP_CLEANUP when 230 | // the framework driver object is deleted during driver unload. 231 | // 232 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 233 | attributes.EvtCleanupCallback = BusFilterEvtDriverContextCleanup; 234 | 235 | WDF_DRIVER_CONFIG_INIT(&config, BusFilterEvtDeviceAdd); 236 | 237 | status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, WDF_NO_HANDLE); 238 | 239 | if (!NT_SUCCESS(status)) 240 | { 241 | TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status); 242 | WPP_CLEANUP(DriverObject); 243 | return status; 244 | } 245 | 246 | status = BffInitialize(DriverObject, RegistryPath, &initData); 247 | if (!NT_SUCCESS(status)) 248 | { 249 | KdPrint(("%s: failed to initialize BFF:%x\n", __FUNCTION__, status)); 250 | WPP_CLEANUP(DriverObject); 251 | return status; 252 | } 253 | 254 | TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); 255 | 256 | return status; 257 | } 258 | 259 | NTSTATUS 260 | BusFilterEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit) 261 | /*++ 262 | Routine Description: 263 | 264 | EvtDeviceAdd is called by the framework in response to AddDevice 265 | call from the PnP manager. We create and initialize a device object to 266 | represent a new instance of the device. 267 | 268 | Arguments: 269 | 270 | Driver - Handle to a framework driver object created in DriverEntry 271 | 272 | DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure. 273 | 274 | Return Value: 275 | 276 | NTSTATUS 277 | 278 | --*/ 279 | { 280 | NTSTATUS status; 281 | 282 | UNREFERENCED_PARAMETER(Driver); 283 | 284 | PAGED_CODE(); 285 | 286 | TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); 287 | 288 | status = BusFilterCreateDevice(DeviceInit); 289 | 290 | TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); 291 | 292 | return status; 293 | } 294 | 295 | VOID BusFilterEvtDriverContextCleanup(_In_ WDFOBJECT DriverObject) 296 | /*++ 297 | Routine Description: 298 | 299 | Free all the resources allocated in DriverEntry. 300 | 301 | Arguments: 302 | 303 | DriverObject - handle to a WDF Driver object. 304 | 305 | Return Value: 306 | 307 | VOID. 308 | 309 | --*/ 310 | { 311 | UNREFERENCED_PARAMETER(DriverObject); 312 | 313 | PAGED_CODE(); 314 | 315 | TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); 316 | 317 | // 318 | // Stop WPP Tracing 319 | // 320 | WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject)); 321 | } 322 | -------------------------------------------------------------------------------- /BusFilter/Driver.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework Sample Driver 3 | Copyright (C) 2017 Yang Yuanzhi 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | *******************************************************************************/ 18 | /*++ 19 | 20 | Bus filter sameple driver, based on Bus Filter Framework, or BFF for short, 21 | which is a framework for KMDF-based upper filter drivers to behave as bus 22 | filters. You don't need to write WDM drivers any more! 23 | 24 | https://bus-filter-framework.blogspot.com/ 25 | 26 | This sample driver registers a device interface for every child device, and 27 | prepends "BffDevice" to the compatible IDs list. 28 | 29 | Module Name: 30 | 31 | driver.h 32 | 33 | Abstract: 34 | 35 | This file contains the driver definitions. 36 | 37 | Environment: 38 | 39 | Kernel-mode Driver Framework 40 | 41 | --*/ 42 | 43 | #pragma once 44 | #include 45 | #include 46 | 47 | #include "device.h" 48 | #include "queue.h" 49 | #include "trace.h" 50 | 51 | EXTERN_C_START 52 | 53 | // 54 | // WDFDRIVER Events 55 | // 56 | 57 | DRIVER_INITIALIZE DriverEntry; 58 | EVT_WDF_DRIVER_DEVICE_ADD BusFilterEvtDeviceAdd; 59 | EVT_WDF_OBJECT_CONTEXT_CLEANUP BusFilterEvtDriverContextCleanup; 60 | 61 | EXTERN_C_END 62 | -------------------------------------------------------------------------------- /BusFilter/Public.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework Sample Driver 3 | Copyright (C) 2017 Yang Yuanzhi 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | *******************************************************************************/ 18 | /*++ 19 | 20 | Bus filter sameple driver, based on Bus Filter Framework, or BFF for short, 21 | which is a framework for KMDF-based upper filter drivers to behave as bus 22 | filters. You don't need to write WDM drivers any more! 23 | 24 | https://bus-filter-framework.blogspot.com/ 25 | 26 | This sample driver registers a device interface for every child device, and 27 | prepends "BffDevice" to the compatible IDs list. 28 | 29 | Module Name: 30 | 31 | public.h 32 | 33 | Abstract: 34 | 35 | This module contains the common declarations shared by driver 36 | and user applications. 37 | 38 | Environment: 39 | 40 | user and kernel 41 | 42 | --*/ 43 | 44 | #pragma once 45 | // 46 | // Define an Interface Guid so that app can find the device and talk to it. 47 | // 48 | 49 | DEFINE_GUID(GUID_DEVINTERFACE_BusFilter, 0x4ce515f5, 0x2aeb, 0x43ca, 0x80, 0xc2, 0x34, 0x13, 0xcf, 0x20, 0xcb, 0x85); 50 | // {4ce515f5-2aeb-43ca-80c2-3413cf20cb85} 51 | -------------------------------------------------------------------------------- /BusFilter/Queue.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework Sample Driver 3 | Copyright (C) 2017 Yang Yuanzhi 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | *******************************************************************************/ 18 | /*++ 19 | 20 | Bus filter sameple driver, based on Bus Filter Framework, or BFF for short, 21 | which is a framework for KMDF-based upper filter drivers to behave as bus 22 | filters. You don't need to write WDM drivers any more! 23 | 24 | https://bus-filter-framework.blogspot.com/ 25 | 26 | This sample driver registers a device interface for every child device, and 27 | prepends "BffDevice" to the compatible IDs list. 28 | 29 | Module Name: 30 | 31 | queue.c 32 | 33 | Abstract: 34 | 35 | This file contains the queue entry points and callbacks. 36 | 37 | Environment: 38 | 39 | Kernel-mode Driver Framework 40 | 41 | --*/ 42 | 43 | #include "driver.h" 44 | #include "queue.tmh" 45 | 46 | #ifdef ALLOC_PRAGMA 47 | #pragma alloc_text(PAGE, BusFilterQueueInitialize) 48 | #endif 49 | 50 | NTSTATUS 51 | BusFilterQueueInitialize(_In_ WDFDEVICE Device) 52 | /*++ 53 | 54 | Routine Description: 55 | 56 | 57 | The I/O dispatch callbacks for the frameworks device object 58 | are configured in this function. 59 | 60 | A single default I/O Queue is configured for parallel request 61 | processing, and a driver context memory allocation is created 62 | to hold our structure QUEUE_CONTEXT. 63 | 64 | Arguments: 65 | 66 | Device - Handle to a framework device object. 67 | 68 | Return Value: 69 | 70 | VOID 71 | 72 | --*/ 73 | { 74 | WDFQUEUE queue; 75 | NTSTATUS status; 76 | WDF_IO_QUEUE_CONFIG queueConfig; 77 | 78 | PAGED_CODE(); 79 | 80 | // 81 | // Configure a default queue so that requests that are not 82 | // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto 83 | // other queues get dispatched here. 84 | // 85 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel); 86 | 87 | queueConfig.EvtIoDeviceControl = BusFilterEvtIoDeviceControl; 88 | queueConfig.EvtIoStop = BusFilterEvtIoStop; 89 | 90 | status = WdfIoQueueCreate(Device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &queue); 91 | 92 | if (!NT_SUCCESS(status)) 93 | { 94 | TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfIoQueueCreate failed %!STATUS!", status); 95 | return status; 96 | } 97 | 98 | return status; 99 | } 100 | 101 | VOID BusFilterEvtIoDeviceControl(_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, 102 | _In_ size_t InputBufferLength, _In_ ULONG IoControlCode) 103 | /*++ 104 | 105 | Routine Description: 106 | 107 | This event is invoked when the framework receives IRP_MJ_DEVICE_CONTROL request. 108 | 109 | Arguments: 110 | 111 | Queue - Handle to the framework queue object that is associated with the 112 | I/O request. 113 | 114 | Request - Handle to a framework request object. 115 | 116 | OutputBufferLength - Size of the output buffer in bytes 117 | 118 | InputBufferLength - Size of the input buffer in bytes 119 | 120 | IoControlCode - I/O control code. 121 | 122 | Return Value: 123 | 124 | VOID 125 | 126 | --*/ 127 | { 128 | TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, 129 | "%!FUNC! Queue 0x%p, Request 0x%p OutputBufferLength %d InputBufferLength %d IoControlCode %d", Queue, 130 | Request, (int)OutputBufferLength, (int)InputBufferLength, IoControlCode); 131 | 132 | WdfRequestComplete(Request, STATUS_SUCCESS); 133 | 134 | return; 135 | } 136 | 137 | VOID BusFilterEvtIoStop(_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ ULONG ActionFlags) 138 | /*++ 139 | 140 | Routine Description: 141 | 142 | This event is invoked for a power-managed queue before the device leaves the working state (D0). 143 | 144 | Arguments: 145 | 146 | Queue - Handle to the framework queue object that is associated with the 147 | I/O request. 148 | 149 | Request - Handle to a framework request object. 150 | 151 | ActionFlags - A bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS-typed flags 152 | that identify the reason that the callback function is being called 153 | and whether the request is cancelable. 154 | 155 | Return Value: 156 | 157 | VOID 158 | 159 | --*/ 160 | { 161 | TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Queue 0x%p, Request 0x%p ActionFlags %d", Queue, Request, 162 | ActionFlags); 163 | 164 | // 165 | // In most cases, the EvtIoStop callback function completes, cancels, or postpones 166 | // further processing of the I/O request. 167 | // 168 | // Typically, the driver uses the following rules: 169 | // 170 | // - If the driver owns the I/O request, it calls WdfRequestUnmarkCancelable 171 | // (if the request is cancelable) and either calls WdfRequestStopAcknowledge 172 | // with a Requeue value of TRUE, or it calls WdfRequestComplete with a 173 | // completion status value of STATUS_SUCCESS or STATUS_CANCELLED. 174 | // 175 | // Before it can call these methods safely, the driver must make sure that 176 | // its implementation of EvtIoStop has exclusive access to the request. 177 | // 178 | // In order to do that, the driver must synchronize access to the request 179 | // to prevent other threads from manipulating the request concurrently. 180 | // The synchronization method you choose will depend on your driver's design. 181 | // 182 | // For example, if the request is held in a shared context, the EvtIoStop callback 183 | // might acquire an internal driver lock, take the request from the shared context, 184 | // and then release the lock. At this point, the EvtIoStop callback owns the request 185 | // and can safely complete or requeue the request. 186 | // 187 | // - If the driver has forwarded the I/O request to an I/O target, it either calls 188 | // WdfRequestCancelSentRequest to attempt to cancel the request, or it postpones 189 | // further processing of the request and calls WdfRequestStopAcknowledge with 190 | // a Requeue value of FALSE. 191 | // 192 | // A driver might choose to take no action in EvtIoStop for requests that are 193 | // guaranteed to complete in a small amount of time. 194 | // 195 | // In this case, the framework waits until the specified request is complete 196 | // before moving the device (or system) to a lower power state or removing the device. 197 | // Potentially, this inaction can prevent a system from entering its hibernation state 198 | // or another low system power state. In extreme cases, it can cause the system 199 | // to crash with bugcheck code 9F. 200 | // 201 | 202 | return; 203 | } 204 | -------------------------------------------------------------------------------- /BusFilter/Queue.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework Sample Driver 3 | Copyright (C) 2017 Yang Yuanzhi 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | *******************************************************************************/ 18 | /*++ 19 | 20 | Bus filter sameple driver, based on Bus Filter Framework, or BFF for short, 21 | which is a framework for KMDF-based upper filter drivers to behave as bus 22 | filters. You don't need to write WDM drivers any more! 23 | 24 | https://bus-filter-framework.blogspot.com/ 25 | 26 | This sample driver registers a device interface for every child device, and 27 | prepends "BffDevice" to the compatible IDs list. 28 | 29 | Module Name: 30 | 31 | queue.h 32 | 33 | Abstract: 34 | 35 | This file contains the queue definitions. 36 | 37 | Environment: 38 | 39 | Kernel-mode Driver Framework 40 | 41 | --*/ 42 | 43 | #pragma once 44 | EXTERN_C_START 45 | 46 | // 47 | // This is the context that can be placed per queue 48 | // and would contain per queue information. 49 | // 50 | typedef struct _QUEUE_CONTEXT 51 | { 52 | 53 | ULONG PrivateDeviceData; // just a placeholder 54 | 55 | } QUEUE_CONTEXT, *PQUEUE_CONTEXT; 56 | 57 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, QueueGetContext) 58 | 59 | NTSTATUS 60 | BusFilterQueueInitialize(_In_ WDFDEVICE hDevice); 61 | 62 | // 63 | // Events from the IoQueue object 64 | // 65 | EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL BusFilterEvtIoDeviceControl; 66 | EVT_WDF_IO_QUEUE_IO_STOP BusFilterEvtIoStop; 67 | 68 | EXTERN_C_END 69 | -------------------------------------------------------------------------------- /BusFilter/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | BusFilter Project Overview 3 | ======================================================================== 4 | 5 | This file contains a summary of what you will find in each of the files that make up your project. 6 | 7 | BusFilter.vcxproj 8 | This is the main project file for projects generated using an Application Wizard. 9 | It contains information about the version of the product that generated the file, and 10 | information about the platforms, configurations, and project features selected with the 11 | Application Wizard. 12 | 13 | BusFilter.vcxproj.filters 14 | This is the filters file for VC++ projects generated using an Application Wizard. 15 | It contains information about the association between the files in your project 16 | and the filters. This association is used in the IDE to show grouping of files with 17 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 18 | "Source Files" filter). 19 | 20 | Public.h 21 | Header file to be shared with applications. 22 | 23 | Driver.c & Driver.h 24 | DriverEntry and WDFDRIVER related functionality and callbacks. 25 | 26 | Device.cpp & Device.h 27 | WDFDEVICE related functionality and callbacks. 28 | 29 | IoQueue.cpp & IoQueue.h 30 | WDFQUEUE related functionality and callbacks. 31 | 32 | Trace.h 33 | Definitions for WPP tracing. 34 | 35 | ///////////////////////////////////////////////////////////////////////////// 36 | 37 | Learn more about Kernel Mode Driver Framework here: 38 | 39 | http://msdn.microsoft.com/en-us/library/ff544296(v=VS.85).aspx 40 | 41 | ///////////////////////////////////////////////////////////////////////////// 42 | -------------------------------------------------------------------------------- /BusFilter/Trace.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework Sample Driver 3 | Copyright (C) 2017 Yang Yuanzhi 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | *******************************************************************************/ 18 | /*++ 19 | 20 | Bus filter sameple driver, based on Bus Filter Framework, or BFF for short, 21 | which is a framework for KMDF-based upper filter drivers to behave as bus 22 | filters. You don't need to write WDM drivers any more! 23 | 24 | https://bus-filter-framework.blogspot.com/ 25 | 26 | This sample driver registers a device interface for every child device, and 27 | prepends "BffDevice" to the compatible IDs list. 28 | 29 | Module Name: 30 | 31 | Trace.h 32 | 33 | Abstract: 34 | 35 | Header file for the debug tracing related function defintions and macros. 36 | 37 | Environment: 38 | 39 | Kernel mode 40 | 41 | --*/ 42 | 43 | // 44 | // Define the tracing flags. 45 | // 46 | // Tracing GUID - 1f9fafa2-7eb8-4104-ba4d-6f202867d18e 47 | // 48 | 49 | #define WPP_CONTROL_GUIDS \ 50 | WPP_DEFINE_CONTROL_GUID(BusFilterTraceGuid, (1f9fafa2, 7eb8, 4104, ba4d, 6f202867d18e), \ 51 | \ 52 | WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) WPP_DEFINE_BIT(TRACE_DRIVER) \ 53 | WPP_DEFINE_BIT(TRACE_DEVICE) WPP_DEFINE_BIT(TRACE_QUEUE)) 54 | 55 | #define WPP_FLAG_LEVEL_LOGGER(flag, level) WPP_LEVEL_LOGGER(flag) 56 | 57 | #define WPP_FLAG_LEVEL_ENABLED(flag, level) (WPP_LEVEL_ENABLED(flag) && WPP_CONTROL(WPP_BIT_##flag).Level >= level) 58 | 59 | #define WPP_LEVEL_FLAGS_LOGGER(lvl, flags) WPP_LEVEL_LOGGER(flags) 60 | 61 | #define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_##flags).Level >= lvl) 62 | 63 | // 64 | // This comment block is scanned by the trace preprocessor to define our 65 | // Trace function. 66 | // 67 | // begin_wpp config 68 | // FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); 69 | // FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); 70 | // end_wpp 71 | // 72 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bus Filter Framework 2 | A framework for KMDF-based upper filter drivers to behave as bus filters. You don't need to write WDM drivers any more! 3 | # Sample Driver 4 | Check the code in the BusFilter directory as well as ReadMe.htm in the WDKStorPortVirtualMiniport directory. To build the sample driver, open WDKStorPortVirtualMiniport\mp\mp.sln with Visual Studio Community Edition. 5 | # Documentation 6 | Please navigate to [here](https://bus-filter-framework.blogspot.tw/p/documentation.html). 7 | # FAQ 8 | Please navigate to [here](https://bus-filter-framework.blogspot.tw/p/faq.html). 9 | # Donations 10 | If this piece of work eases your pains and you would like to encourage the author, [donations](https://bus-filter-framework.blogspot.com/p/donation.html) are welcome and appreciated! 11 | # License 12 | If you need a software license other than GNU GPL v3, please contact the author. 13 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/ReadMe.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abysdom/bus-filter-framework/ce366417e2831116634cce54d4e2586f04ad4eb8/WDKStorPortVirtualMiniport/ReadMe.htm -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/ReadMe_files/colorschememapping.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/ReadMe_files/filelist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/ReadMe_files/header.htm: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |

21 | 22 |


23 | 24 |

25 | 26 |
27 | 28 |
29 | 30 |

32 | 33 |


34 | 35 |

36 | 37 |
38 | 39 |
40 | 41 |

43 | 44 |


45 | 46 |

47 | 48 |
49 | 50 |
51 | 52 |

54 | 55 |


56 | 57 |

58 | 59 |
60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/ReadMe_files/item0007.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/ReadMe_files/props008.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/ReadMe_files/themedata.thmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abysdom/bus-filter-framework/ce366417e2831116634cce54d4e2586f04ad4eb8/WDKStorPortVirtualMiniport/ReadMe_files/themedata.thmx -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/WkRtn.c: -------------------------------------------------------------------------------- 1 | /****************************** Module Header ******************************\ 2 | * Module Name: WkRtn.c 3 | * Project: CppWDKStorPortVirtualMiniport 4 | * 5 | * Copyright (c) Microsoft Corporation. 6 | * 7 | * a. MpGeneralWkRtn() 8 | * Handles queued work elements by calling MpWkRtn. 9 | * 10 | * b. MpWkRtn() 11 | * Handles work elements, completes them. 12 | * 13 | * 14 | * This source is subject to the Microsoft Public License. 15 | * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. 16 | * All other rights reserved. 17 | * 18 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 19 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 21 | \***************************************************************************/ 22 | #define WkRtnVer "1.013" 23 | 24 | #define _MP_H_skip_includes 25 | 26 | #include "mp.h" 27 | 28 | #pragma warning(push) 29 | #pragma warning(disable : 4204) /* Prevent C4204 messages from stortrce.h. */ 30 | #include 31 | #pragma warning(pop) 32 | 33 | #include "trace.h" 34 | #include "WkRtn.tmh" 35 | 36 | /**************************************************************************************************/ 37 | /* */ 38 | /* Globals, forward definitions, etc. */ 39 | /* */ 40 | /**************************************************************************************************/ 41 | 42 | /**************************************************************************************************/ 43 | /* */ 44 | /* This is the work routine, which always runs in System under an OS-supplied worker thread. */ 45 | /* */ 46 | /**************************************************************************************************/ 47 | VOID 48 | MpGeneralWkRtn( 49 | __in PVOID pDummy, // Not used. 50 | __in PVOID pWkParms // Parm list pointer. 51 | ) 52 | { 53 | pMP_WorkRtnParms pWkRtnParms = (pMP_WorkRtnParms)pWkParms; 54 | 55 | UNREFERENCED_PARAMETER(pDummy); 56 | 57 | IoFreeWorkItem(pWkRtnParms->pQueueWorkItem); // Free queue item. 58 | 59 | pWkRtnParms->pQueueWorkItem = NULL; // Be neat. 60 | 61 | // If the next starts, it has to be stopped by a kernel debugger. 62 | 63 | while (pWkRtnParms->SecondsToDelay) { 64 | LARGE_INTEGER delay; 65 | 66 | delay.QuadPart = - 10 * 1000 * 1000 * pWkRtnParms->SecondsToDelay; 67 | 68 | KeDelayExecutionThread(KernelMode, TRUE, &delay); 69 | } 70 | 71 | MpWkRtn(pWkParms); // Do the actual work. 72 | } // End MpGeneralWkRtn(). 73 | 74 | /**************************************************************************************************/ 75 | /* */ 76 | /* This routine does the "read"/"write" work, by copying to/from the miniport's buffers. */ 77 | /* */ 78 | /**************************************************************************************************/ 79 | VOID 80 | MpWkRtn(__in PVOID pWkParms) // Parm list pointer. 81 | { 82 | pMP_WorkRtnParms pWkRtnParms = (pMP_WorkRtnParms)pWkParms; 83 | pHW_HBA_EXT pHBAExt = pWkRtnParms->pHBAExt; 84 | pHW_LU_EXTENSION pLUExt = pWkRtnParms->pLUExt; 85 | PSCSI_REQUEST_BLOCK pSrb = pWkRtnParms->pSrb; 86 | PCDB pCdb = (PCDB)pSrb->Cdb; 87 | ULONG startingSector, 88 | sectorOffset, 89 | lclStatus; 90 | PVOID pX = NULL; 91 | UCHAR status; 92 | 93 | startingSector = pCdb->CDB10.LogicalBlockByte3 | 94 | pCdb->CDB10.LogicalBlockByte2 << 8 | 95 | pCdb->CDB10.LogicalBlockByte1 << 16 | 96 | pCdb->CDB10.LogicalBlockByte0 << 24; 97 | 98 | sectorOffset = startingSector * MP_BLOCK_SIZE; 99 | 100 | DoStorageTraceEtw(DbgLvlInfo, MpDemoDebugInfo, "MpWkRtn Action: %X, starting sector: 0x%X, sector offset: 0x%X\n", pWkRtnParms->Action, startingSector, sectorOffset); 101 | DoStorageTraceEtw(DbgLvlInfo, MpDemoDebugInfo, "MpWkRtn pSrb: 0x%p, pSrb->DataBuffer: 0x%p\n", pSrb, pSrb->DataBuffer); 102 | 103 | // Note: Obviously there's going to be a problem if pSrb->DataBuffer points to something in user space, since the correct user space 104 | // is probably not that of the System process. Less obviously, in the paging path at least, even an address in kernel space 105 | // proved not valid; that is, not merely not backed by real storage but actually not valid. The reason for this behavior is 106 | // still under investigation. For now, in all cases observed, it has been found sufficient to get a new kernel-space address 107 | // to use. 108 | 109 | lclStatus = StorPortGetSystemAddress(pHBAExt, pSrb, &pX); 110 | 111 | if (STOR_STATUS_SUCCESS!=lclStatus || !pX) { 112 | DoStorageTraceEtw(DbgLvlInfo, MpDemoDebugInfo, "MpWkRtn Failed to get system address for pSrb = 0x%p, pSrb->DataBuffer=0x%p, status = 0x%08x, pX = 0x%p\n", 113 | pSrb, pSrb->DataBuffer, lclStatus, pX); 114 | status = SRB_STATUS_ERROR; 115 | 116 | goto Done; 117 | } 118 | 119 | DoStorageTraceEtw(DbgLvlInfo, MpDemoDebugInfo, "MpWkRtn Using pX=0x%p\n", pX); 120 | 121 | if (ActionRead==pWkRtnParms->Action) { // Read? 122 | RtlMoveMemory(pX, &pLUExt->pDiskBuf[sectorOffset], pSrb->DataTransferLength); 123 | } 124 | else { // Write. 125 | RtlMoveMemory(&pLUExt->pDiskBuf[sectorOffset], pX, pSrb->DataTransferLength); 126 | } 127 | 128 | status = SRB_STATUS_SUCCESS; 129 | 130 | Done: 131 | pSrb->SrbStatus = status; 132 | 133 | // Tell StorPort this action has been completed. 134 | 135 | StorPortNotification(RequestComplete, pHBAExt, pSrb); 136 | 137 | ExFreePoolWithTag(pWkParms, MP_TAG_GENERAL); // Free parm list. 138 | } // End MpWkRtn(). 139 | 140 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/inc/common.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 1990-2011 Microsoft Corporation. All Rights Reserved 4 | 5 | Module Name: 6 | common.h 7 | 8 | Abstract: 9 | 10 | Author: 11 | 12 | Enviroment: 13 | 14 | Revision History: 15 | 16 | --*/ 17 | 18 | #ifndef _COMMON_H_ 19 | #define _COMMON_H_ 20 | 21 | #define DISK_DEVICE 0x00 22 | 23 | typedef struct _MP_DEVICE_INFO { 24 | UCHAR DeviceType; 25 | UCHAR TargetID; 26 | UCHAR LunID; 27 | } MP_DEVICE_INFO, *pMP_DEVICE_INFO; 28 | 29 | typedef struct _MP_DEVICE_LIST { 30 | ULONG DeviceCount; 31 | MP_DEVICE_INFO DeviceInfo[1]; 32 | } MP_DEVICE_LIST, *pMP_DEVICE_LIST; 33 | 34 | #endif // _COMMON_H_ 35 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/inc/mp.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************/ 2 | /* */ 3 | /* Copyright (c) 2008-2011 Microsoft Corporation. All Rights Reserved. */ 4 | /* */ 5 | /**************************************************************************************************/ 6 | 7 | /*++ 8 | 9 | Module Name: 10 | 11 | mp.h 12 | 13 | Abstract: 14 | 15 | Author: 16 | 17 | Environment: 18 | 19 | --*/ 20 | 21 | 22 | #ifndef _MP_H_ 23 | #define _MP_H_ 24 | 25 | #if !defined(_MP_User_Mode_Only) // User-mode only. 26 | 27 | #if !defined(_MP_H_skip_WDM_includes) 28 | 29 | #include 30 | 31 | #endif // !defined(_MP_H_skip_WDM_includes) 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "common.h" 39 | 40 | #if !defined(_MP_H_skip_includes) 41 | 42 | #include 43 | #include 44 | 45 | #endif // !defined(_MP_H_skip_includes) 46 | 47 | #define VENDOR_ID L"PSS_LAB " 48 | #define VENDOR_ID_ascii "PSS_LAB " 49 | #define PRODUCT_ID L"PHANTOM " 50 | #define PRODUCT_ID_ascii "PHANTOM " 51 | #define PRODUCT_REV L"1234" 52 | #define PRODUCT_REV_ascii "1234" 53 | #define MP_TAG_GENERAL 'gTpM' 54 | 55 | #define MAX_TARGETS 8 56 | #define MAX_LUNS 24 57 | #define MP_MAX_TRANSFER_SIZE (32 * 1024) 58 | #define TIME_INTERVAL (1 * 1000 * 1000) //1 second. 59 | #define DEVLIST_BUFFER_SIZE 1024 60 | #define DEVICE_NOT_FOUND 0xFF 61 | #define SECTOR_NOT_FOUND 0xFFFF 62 | 63 | #define MINIMUM_DISK_SIZE (1540 * 1024) // Minimum size required for Disk Manager 64 | #define MAXIMUM_MAP_DISK_SIZE (256 * 1024) 65 | 66 | #define MP_BLOCK_SIZE (512) 67 | #define BUF_SIZE (1540 * 1024) 68 | #define MAX_BLOCKS (BUF_SIZE / MP_BLOCK_SIZE) 69 | 70 | #define DEFAULT_BREAK_ON_ENTRY 0 // No break 71 | #define DEFAULT_DEBUG_LEVEL 2 72 | #define DEFAULT_INITIATOR_ID 7 73 | #define DEFAULT_VIRTUAL_DISK_SIZE (8 * 1024 * 1024) // 8 MB. JAntogni, 03.12.2005. 74 | #define DEFAULT_PHYSICAL_DISK_SIZE DEFAULT_VIRTUAL_DISK_SIZE 75 | #define DEFAULT_USE_LBA_LIST 0 76 | #define DEFAULT_NUMBER_OF_BUSES 1 77 | #define DEFAULT_NbrVirtDisks 1 78 | #define DEFAULT_NbrLUNsperHBA 1 79 | #define DEFAULT_bCombineVirtDisks FALSE 80 | 81 | #define GET_FLAG(Flags, Bit) ((Flags) & (Bit)) 82 | #define SET_FLAG(Flags, Bit) ((Flags) |= (Bit)) 83 | #define CLEAR_FLAG(Flags, Bit) ((Flags) &= ~(Bit)) 84 | 85 | typedef struct _DEVICE_LIST DEVICE_LIST, *pDEVICE_LIST; 86 | typedef struct _MPDriverInfo MPDriverInfo, *pMPDriverInfo; 87 | typedef struct _MP_REG_INFO MP_REG_INFO, *pMP_REG_INFO; 88 | typedef struct _HW_LU_EXTENSION HW_LU_EXTENSION, *pHW_LU_EXTENSION; 89 | typedef struct _HW_LU_EXTENSION_MPIO HW_LU_EXTENSION_MPIO, *pHW_LU_EXTENSION_MPIO; 90 | typedef struct _LBA_LIST LBA_LIST, *PLBA_LIST; 91 | 92 | extern 93 | pMPDriverInfo pMPDrvInfoGlobal; 94 | 95 | typedef struct _MP_REG_INFO { 96 | UNICODE_STRING VendorId; 97 | UNICODE_STRING ProductId; 98 | UNICODE_STRING ProductRevision; 99 | ULONG BreakOnEntry; // Break into debugger 100 | ULONG DebugLevel; // Debug log level 101 | ULONG InitiatorID; // Adapter's target ID 102 | ULONG VirtualDiskSize; // Disk size to be reported 103 | ULONG PhysicalDiskSize; // Disk size to be allocated 104 | ULONG NbrVirtDisks; // Number of virtual disks. 105 | ULONG NbrLUNsperHBA; // Number of LUNs per HBA. 106 | ULONG bCombineVirtDisks; // 0 => do not combine virtual disks a la MPIO. 107 | } MP_REG_INFO, * pMP_REG_INFO; 108 | 109 | typedef struct _MPDriverInfo { // The master miniport object. In effect, an extension of the driver object for the miniport. 110 | MP_REG_INFO MPRegInfo; 111 | KSPIN_LOCK DrvInfoLock; 112 | KSPIN_LOCK MPIOExtLock; // Lock for ListMPIOExt, header of list of HW_LU_EXTENSION_MPIO objects, 113 | LIST_ENTRY ListMPHBAObj; // Header of list of HW_HBA_EXT objects. 114 | LIST_ENTRY ListMPIOExt; // Header of list of HW_LU_EXTENSION_MPIO objects. 115 | PDRIVER_OBJECT pDriverObj; 116 | ULONG DrvInfoNbrMPHBAObj;// Count of items in ListMPHBAObj. 117 | ULONG DrvInfoNbrMPIOExtObj; // Count of items in ListMPIOExt. 118 | } MPDriverInfo, * pMPDriverInfo; 119 | 120 | typedef struct _LUNInfo { 121 | UCHAR bReportLUNsDontUse; 122 | UCHAR bIODontUse; 123 | } LUNInfo, *pLUNInfo; 124 | 125 | #define LUNInfoMax 8 126 | 127 | typedef struct _HW_HBA_EXT { // Adapter device-object extension allocated by StorPort. 128 | LIST_ENTRY List; // Pointers to next and previous HW_HBA_EXT objects. 129 | LIST_ENTRY LUList; // Pointers to HW_LU_EXTENSION objects. 130 | LIST_ENTRY MPIOLunList; 131 | pMPDriverInfo pMPDrvObj; 132 | PDRIVER_OBJECT pDrvObj; 133 | pMP_DEVICE_LIST pDeviceList; 134 | pMP_DEVICE_LIST pPrevDeviceList; 135 | SCSI_WMILIB_CONTEXT WmiLibContext; 136 | PIRP pReverseCallIrp; 137 | KSPIN_LOCK WkItemsLock; 138 | KSPIN_LOCK WkRoutinesLock; 139 | KSPIN_LOCK MPHBAObjLock; 140 | KSPIN_LOCK LUListLock; 141 | ULONG SRBsSeen; 142 | ULONG WMISRBsSeen; 143 | ULONG NbrMPIOLuns; 144 | ULONG NbrLUNsperHBA; 145 | ULONG Test; 146 | UCHAR HostTargetId; 147 | UCHAR AdapterState; 148 | UCHAR VendorId[9]; 149 | UCHAR ProductId[17]; 150 | UCHAR ProductRevision[5]; 151 | BOOLEAN bDontReport; // TRUE => no Report LUNs. This is to be set/unset only by a kernel debugger. 152 | BOOLEAN bReportAdapterDone; 153 | LUNInfo LUNInfoArray[LUNInfoMax]; // To be set only by a kernel debugger. 154 | } HW_HBA_EXT, * pHW_HBA_EXT; 155 | 156 | typedef struct _HW_LU_EXTENSION_MPIO { // Collector for LUNs that are represented by MPIO as 1 pseudo-LUN. 157 | LIST_ENTRY List; // Pointers to next and previous HW_LU_EXTENSION_MPIO objects. 158 | LIST_ENTRY LUExtList; // Header of list of HW_LU_EXTENSION objects. 159 | KSPIN_LOCK LUExtMPIOLock; 160 | ULONG NbrRealLUNs; 161 | SCSI_ADDRESS ScsiAddr; 162 | PUCHAR pDiskBuf; 163 | USHORT MaxBlocks; 164 | BOOLEAN bIsMissingOnAnyPath; // At present, this is set only by a kernel debugger, for testing. 165 | } HW_LU_EXTENSION_MPIO, * pHW_LU_EXTENSION_MPIO; 166 | 167 | // Flag definitions for LUFlags. 168 | 169 | #define LU_DEVICE_INITIALIZED 0x0001 170 | #define LU_MPIO_MAPPED 0x0004 171 | 172 | typedef struct _HW_LU_EXTENSION { // LUN extension allocated by StorPort. 173 | LIST_ENTRY List; // Pointers to next and previous HW_LU_EXTENSION objects, used in HW_HBA_EXT. 174 | LIST_ENTRY MPIOList; // Pointers to next and previous HW_LU_EXTENSION objects, used in HW_LU_EXTENSION_MPIO. 175 | pHW_LU_EXTENSION_MPIO pLUMPIOExt; 176 | PUCHAR pDiskBuf; 177 | ULONG LUFlags; 178 | USHORT MaxBlocks; 179 | USHORT BlocksUsed; 180 | BOOLEAN bIsMissing; // At present, this is set only by a kernel debugger, for testing. 181 | UCHAR DeviceType; 182 | UCHAR TargetId; 183 | UCHAR Lun; 184 | } HW_LU_EXTENSION, * pHW_LU_EXTENSION; 185 | 186 | typedef struct _HW_SRB_EXTENSION { 187 | SCSIWMI_REQUEST_CONTEXT WmiRequestContext; 188 | } HW_SRB_EXTENSION, * PHW_SRB_EXTENSION; 189 | 190 | typedef enum { 191 | ActionRead, 192 | ActionWrite 193 | } MpWkRtnAction; 194 | 195 | typedef struct _MP_WorkRtnParms { 196 | pHW_HBA_EXT pHBAExt; 197 | pHW_LU_EXTENSION pLUExt; 198 | PSCSI_REQUEST_BLOCK pSrb; 199 | PIO_WORKITEM pQueueWorkItem; 200 | PEPROCESS pReqProcess; 201 | MpWkRtnAction Action; 202 | ULONG SecondsToDelay; 203 | } MP_WorkRtnParms, * pMP_WorkRtnParms; 204 | 205 | enum ResultType { 206 | ResultDone, 207 | ResultQueued 208 | } ; 209 | 210 | #define RegWkBfrSz 0x1000 211 | 212 | typedef struct _RegWorkBuffer { 213 | pHW_HBA_EXT pAdapterExt; 214 | UCHAR Work[256]; 215 | } RegWorkBuffer, * pRegWorkBuffer; 216 | 217 | __declspec(dllexport) // Ensure DriverEntry entry point visible to WinDbg even without a matching .pdb. 218 | ULONG 219 | DriverEntry( 220 | IN PVOID, 221 | IN PUNICODE_STRING 222 | ); 223 | 224 | ULONG 225 | MpHwFindAdapter( 226 | __in pHW_HBA_EXT DevExt, 227 | __in PVOID HwContext, 228 | __in PVOID BusInfo, 229 | __in PVOID LowerDevice, 230 | __in PCHAR ArgumentString, 231 | __in __out PPORT_CONFIGURATION_INFORMATION ConfigInfo, 232 | __out PBOOLEAN Again 233 | ); 234 | 235 | VOID 236 | MpHwTimer( 237 | __in pHW_HBA_EXT DevExt 238 | ); 239 | 240 | BOOLEAN 241 | MpHwInitialize( 242 | __in pHW_HBA_EXT 243 | ); 244 | 245 | void 246 | MpHwReportAdapter( 247 | __in pHW_HBA_EXT 248 | ); 249 | 250 | void 251 | MpHwReportLink( 252 | __in pHW_HBA_EXT 253 | ); 254 | 255 | void 256 | MpHwReportLog(__in pHW_HBA_EXT); 257 | 258 | VOID 259 | MpHwFreeAdapterResources( 260 | __in pHW_HBA_EXT 261 | ); 262 | 263 | BOOLEAN 264 | MpHwStartIo( 265 | __in pHW_HBA_EXT, 266 | __in PSCSI_REQUEST_BLOCK 267 | ); 268 | 269 | BOOLEAN 270 | MpHwResetBus( 271 | __in pHW_HBA_EXT, 272 | __in ULONG 273 | ); 274 | 275 | SCSI_ADAPTER_CONTROL_STATUS 276 | MpHwAdapterControl( 277 | __in pHW_HBA_EXT DevExt, 278 | __in SCSI_ADAPTER_CONTROL_TYPE ControlType, 279 | __in PVOID Parameters 280 | ); 281 | 282 | UCHAR 283 | ScsiExecuteMain( 284 | __in pHW_HBA_EXT DevExt, 285 | __in PSCSI_REQUEST_BLOCK, 286 | __in PUCHAR 287 | ); 288 | 289 | UCHAR 290 | ScsiExecute( 291 | __in pHW_HBA_EXT DevExt, 292 | __in PSCSI_REQUEST_BLOCK Srb 293 | ); 294 | 295 | UCHAR 296 | ScsiOpInquiry( 297 | __in pHW_HBA_EXT DevExt, 298 | __in pHW_LU_EXTENSION LuExt, 299 | __in PSCSI_REQUEST_BLOCK Srb 300 | ); 301 | 302 | UCHAR 303 | ScsiOpReadCapacity( 304 | IN pHW_HBA_EXT DevExt, 305 | IN pHW_LU_EXTENSION LuExt, 306 | IN PSCSI_REQUEST_BLOCK Srb 307 | ); 308 | 309 | UCHAR 310 | ScsiOpRead( 311 | IN pHW_HBA_EXT DevExt, 312 | IN pHW_LU_EXTENSION LuExt, 313 | IN PSCSI_REQUEST_BLOCK Srb, 314 | IN PUCHAR Action 315 | ); 316 | 317 | UCHAR 318 | ScsiOpWrite( 319 | IN pHW_HBA_EXT DevExt, 320 | IN pHW_LU_EXTENSION LuExt, 321 | IN PSCSI_REQUEST_BLOCK Srb, 322 | IN PUCHAR Action 323 | ); 324 | 325 | UCHAR 326 | ScsiOpModeSense( 327 | IN pHW_HBA_EXT DevExt, 328 | IN pHW_LU_EXTENSION LuExt, 329 | IN PSCSI_REQUEST_BLOCK pSrb 330 | ); 331 | 332 | UCHAR 333 | ScsiOpReportLuns( 334 | IN pHW_HBA_EXT DevExt, 335 | IN pHW_LU_EXTENSION LuExt, 336 | IN PSCSI_REQUEST_BLOCK Srb 337 | ); 338 | 339 | VOID 340 | MpQueryRegParameters( 341 | IN PUNICODE_STRING, 342 | IN pMP_REG_INFO 343 | ); 344 | 345 | NTSTATUS 346 | MpCreateDeviceList( 347 | __in pHW_HBA_EXT, 348 | __in ULONG 349 | ); 350 | 351 | UCHAR 352 | MpGetDeviceType( 353 | __in pHW_HBA_EXT DevExt, 354 | __in UCHAR PathId, 355 | __in UCHAR TargetId, 356 | __in UCHAR Lun 357 | ); 358 | 359 | UCHAR MpFindRemovedDevice( 360 | __in pHW_HBA_EXT, 361 | __in PSCSI_REQUEST_BLOCK 362 | ); 363 | 364 | VOID MpStopAdapter( 365 | __in pHW_HBA_EXT DevExt 366 | ); 367 | 368 | VOID 369 | MPTracingInit( 370 | __in PVOID, 371 | __in PVOID 372 | ); 373 | 374 | VOID 375 | MPTracingCleanup(__in PVOID); 376 | 377 | VOID 378 | MpProcServReq( 379 | __in pHW_HBA_EXT, 380 | __in PIRP 381 | ); 382 | 383 | VOID 384 | MpCompServReq( 385 | __in pHW_HBA_EXT 386 | ); 387 | 388 | UCHAR 389 | ScsiOpVPD( 390 | __in pHW_HBA_EXT, 391 | __in pHW_LU_EXTENSION, 392 | __in PSCSI_REQUEST_BLOCK 393 | ); 394 | 395 | void 396 | InitializeWmiContext(__in pHW_HBA_EXT); 397 | 398 | BOOLEAN 399 | HandleWmiSrb( 400 | __in pHW_HBA_EXT, 401 | __in __out PSCSI_WMI_REQUEST_BLOCK 402 | ); 403 | 404 | UCHAR 405 | ScsiReadWriteSetup( 406 | __in pHW_HBA_EXT pDevExt, 407 | __in pHW_LU_EXTENSION pLUExt, 408 | __in PSCSI_REQUEST_BLOCK pSrb, 409 | __in MpWkRtnAction WkRtnAction, 410 | __in PUCHAR pResult 411 | ); 412 | 413 | VOID 414 | MpGeneralWkRtn( 415 | __in PVOID, 416 | __in PVOID 417 | ); 418 | ULONG 419 | MpThreadWkRtn(__in PVOID); 420 | 421 | VOID 422 | MpWkRtn(IN PVOID); 423 | 424 | VOID 425 | MpCompleteIrp( 426 | __in pHW_HBA_EXT, 427 | __in PIRP 428 | ); 429 | 430 | VOID 431 | MpQueueServiceIrp( 432 | __in pHW_HBA_EXT pDevExt, 433 | __in PIRP pIrp 434 | ); 435 | 436 | VOID 437 | MpProcServReq( 438 | __in pHW_HBA_EXT pDevExt, 439 | __in PIRP pIrp 440 | ); 441 | 442 | VOID 443 | MpCompServReq( 444 | __in pHW_HBA_EXT pDevExt 445 | ); 446 | 447 | #endif // #if !defined(_MP_User_Mode_Only) 448 | #endif // _MP_H_ 449 | 450 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/inc/trace.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************/ 2 | /* */ 3 | /* Copyright (c) 2008-2011 Microsoft Corporation. All Rights Reserved. */ 4 | /* */ 5 | /**************************************************************************************************/ 6 | 7 | #ifndef _TRACE_H_ 8 | #define _TRACE_H_ 9 | 10 | /* 11 | 12 | WPP_DEFINE_CONTROL_GUID specifies the GUID used for this filter. 13 | *** REPLACE THE GUID WITH YOUR OWN UNIQUE ID *** 14 | WPP_DEFINE_BIT allows setting debug bit masks to selectively print. 15 | 16 | */ 17 | 18 | // In order to send trace statements directly to the kernel 19 | // debugger, the following two #defines are required. It is 20 | // recommended to always include these. 21 | // 22 | #define WPP_AUTOLOGGER L"mpStor" 23 | #define WPP_GLOBALLOGGER 24 | 25 | // This definition is required. Here, you define the control 26 | // GUID for your driver. This is the GUID any listening 27 | // application interested in receiving trace events from your 28 | // driver will register for. 29 | // 30 | // This is where you categorize your trace statements. A listening 31 | // application may register to listen to only the events in which 32 | // it is interested. So if a listening application only wishes to 33 | // listen for Io and Enum events from your driver. All other 34 | // trace statements will be disabled. 35 | // 36 | 37 | #define WPP_CONTROL_GUIDS \ 38 | WPP_DEFINE_CONTROL_GUID( \ 39 | vvHBA,(C689C5E6,5219,4774,BE15,9B1F92F949FD), \ 40 | WPP_DEFINE_BIT(MpDemoDebugError) /* bit 0 = 0x00000001 */ \ 41 | WPP_DEFINE_BIT(MpDemoDebugWarning) /* bit 1 = 0x00000002 */ \ 42 | WPP_DEFINE_BIT(MpDemoDebugTrace) /* bit 2 = 0x00000004 */ \ 43 | WPP_DEFINE_BIT(MpDemoDebugInfo) /* bit 3 = 0x00000008 */ \ 44 | WPP_DEFINE_BIT(MpDemoDebug04) /* bit 4 = 0x00000010 */ \ 45 | WPP_DEFINE_BIT(MpDemoDebug05) /* bit 5 = 0x00000020 */ \ 46 | WPP_DEFINE_BIT(MpDemoDebug06) /* bit 6 = 0x00000040 */ \ 47 | WPP_DEFINE_BIT(MpDemoDebug07) /* bit 7 = 0x00000080 */ \ 48 | WPP_DEFINE_BIT(MpDemoDebug08) /* bit 8 = 0x00000100 */ \ 49 | WPP_DEFINE_BIT(MpDemoDebug09) /* bit 9 = 0x00000200 */ \ 50 | WPP_DEFINE_BIT(MpDemoDebug10) /* bit 10 = 0x00000400 */ \ 51 | WPP_DEFINE_BIT(MpDemoDebug11) /* bit 11 = 0x00000800 */ \ 52 | WPP_DEFINE_BIT(MpDemoDebug12) /* bit 12 = 0x00001000 */ \ 53 | WPP_DEFINE_BIT(MpDemoDebug13) /* bit 13 = 0x00002000 */ \ 54 | WPP_DEFINE_BIT(MpDemoDebug14) /* bit 14 = 0x00004000 */ \ 55 | WPP_DEFINE_BIT(MpDemoDebug15) /* bit 15 = 0x00008000 */ \ 56 | WPP_DEFINE_BIT(MpDemoDebug16) /* bit 16 = 0x00010000 */ \ 57 | WPP_DEFINE_BIT(MpDemoDebug17) /* bit 17 = 0x00020000 */ \ 58 | WPP_DEFINE_BIT(MpDemoDebug18) /* bit 18 = 0x00040000 */ \ 59 | WPP_DEFINE_BIT(MpDemoDebug19) /* bit 19 = 0x00080000 */ \ 60 | WPP_DEFINE_BIT(MpDemoDebug20) /* bit 20 = 0x00100000 */ \ 61 | WPP_DEFINE_BIT(MpDemoDebug21) /* bit 21 = 0x00200000 */ \ 62 | WPP_DEFINE_BIT(MpDemoDebug22) /* bit 22 = 0x00400000 */ \ 63 | WPP_DEFINE_BIT(MpDemoDebug23) /* bit 23 = 0x00800000 */ \ 64 | WPP_DEFINE_BIT(MpDemoDebug24) /* bit 24 = 0x01000000 */ \ 65 | WPP_DEFINE_BIT(MpDemoDebug25) /* bit 25 = 0x02000000 */ \ 66 | WPP_DEFINE_BIT(MpDemoDebug26) /* bit 26 = 0x04000000 */ \ 67 | WPP_DEFINE_BIT(MpDemoDebug27) /* bit 27 = 0x08000000 */ \ 68 | WPP_DEFINE_BIT(MpDemoDebug28) /* bit 28 = 0x10000000 */ \ 69 | WPP_DEFINE_BIT(MpDemoDebug29) /* bit 29 = 0x20000000 */ \ 70 | WPP_DEFINE_BIT(MpDemoDebug30) /* bit 30 = 0x40000000 */ \ 71 | WPP_DEFINE_BIT(MpDemoDebug31) /* bit 31 = 0x80000000 */ \ 72 | ) 73 | 74 | // 75 | // The trace formatting engine understands how to format a 76 | // SCSI_REQUEST_BLOCK and a REQUEST SENSE buffer. To use these 77 | // custom formats, however, you must include the following two 78 | // #defines. 79 | // 80 | #define WPP_LOGSRB(x) WPP_LOGPAIR((x)->Length, (x)) 81 | #define WPP_LOGSENSE(x) WPP_LOGPAIR((sizeof(SENSE_DATA)), (x)) 82 | 83 | // 84 | // The following #defines are optional levels you may utilize to 85 | // further control the level of trace output a listening 86 | // application will receive from your driver. You may define up 87 | // to 32 levels to be used in conjunction with the above flag 88 | // bits to control trace output. 89 | // 90 | #define DbgLvlErr 0x00000001 91 | #define DbgLvlWrn 0x00000002 92 | #define DbgLvlInfo 0x00000003 93 | #define DbgLvlLoud 0x00000004 94 | 95 | // 96 | // To use levels and flag bits together to control tracing, the 97 | // following two #defines are required. By default, WPP tracing 98 | // only uses the flag bits defined with the control GUID 99 | // 100 | #define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags) 101 | #define WPP_LEVEL_FLAGS_ENABLED(lvl,flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level & lvl) 102 | 103 | //********************************************************* 104 | // MACRO: DoStorageTraceEtw 105 | // 106 | // begin_wpp config 107 | // USEPREFIX (DoStorageTraceEtw,"%!STDPREFIX!"); 108 | // FUNC DoStorageTraceEtw(LVL, FLG, MSG, ...); 109 | // end_wpp 110 | 111 | #define WPP_LVL_FLG_PRE(LVL, FLG) 112 | #define WPP_LVL_FLG_POST(LVL, FLG) 113 | #define WPP_LVL_FLG_ENABLED(LVL, FLG) WPP_LEVEL_FLAGS_ENABLED(LVL,FLG) 114 | #define WPP_LVL_FLG_LOGGER(LVL, FLG) WPP_LEVEL_FLAGS_LOGGER(LVL,FLG) 115 | 116 | // 117 | // To handle NULL strings in trace arguements 118 | // 119 | #define WPP_CHECK_FOR_NULL_STRING 120 | 121 | #endif // _TRACE_H_ 122 | 123 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/inc/trcmp.ini: -------------------------------------------------------------------------------- 1 | DEFINE_CPLX_TYPE(SRB, WPP_LOGSRB, PSCSI_REQUEST_BLOCK, ItemSRB, "s", _SRB_, 0, 2); 2 | DEFINE_CPLX_TYPE(SENSE, WPP_LOGSENSE, PSENSE_DATA, ItemSenseData, "s", _SENSE_, 0, 2); 3 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/install/README.txt: -------------------------------------------------------------------------------- 1 | Bus Filter Framework Sample Driver 2 | Copyright (c) 2016 Yang Yuanzhi 3 | 4 | This sample driver, based upon Bus Filter Framework, adds a bus filter to the device stack of a disk drive enumerated by the storport virtual miniport driver. Furthermore, a device interface is registered for such a disk drive, and a new compatible ID, "BffDevice", is prepended to the existing compatible IDs list thereof. -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/install/install.inx: -------------------------------------------------------------------------------- 1 | 2 | ; MP.INF 3 | ; 4 | ; Copyright (c) 1998-2011, Microsoft Corporation. 5 | 6 | [Version] 7 | Signature="$WINDOWS NT$" 8 | Class=SCSIAdapter 9 | ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318} 10 | ;Provider=%MSFT% 11 | Provider=BFF 12 | DriverVer=01/30/2007,6.0.6000.16386 13 | CatalogFile = install.cat 14 | PnpLockdown=1 15 | 16 | [DestinationDirs] 17 | DefaultDestDir = 12 18 | MP_Device_CoInstaller_CopyFiles = 11 19 | 20 | [Manufacturer] 21 | %MSFT%=MSFT, NT$ARCH$ 22 | 23 | [MSFT.NT$ARCH$] 24 | %MPDeviceDesc%=MP_Device, %rootstr% 25 | 26 | [MP_Device] 27 | CopyFiles=@mp.sys 28 | CopyFiles=@BusFilter.sys 29 | 30 | [MP_Device.HW] 31 | AddReg = MP_Device_AddReg 32 | 33 | [MP_Device_AddReg] 34 | HKR, "ScsiPort", "NeedsSystemShutdownNotification", 0x00010001, 1 35 | HKR,,"UpperFilters",0x00010000,"BusFilter" ; REG_MULTI_SZ value 36 | 37 | [MP_Device.Services] 38 | AddService = mp, %SPSVCINST_ASSOCSERVICE%, MP_Service_Inst 39 | AddService = BusFilter,, BusFilter_Service_Inst, BusFilter_EventLog_Inst 40 | 41 | ; -------------- BusFilter driver install sections 42 | [BusFilter_Service_Inst] 43 | DisplayName = %BusFilter.SVCDESC% 44 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 45 | StartType = 3 ; SERVICE_DEMAND_START 46 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 47 | ServiceBinary = %12%\BusFilter.sys 48 | AddReg = BusFilter_Service_AddReg 49 | 50 | [BusFilter_Service_AddReg] 51 | HKR,,BffLicensee,%REG_SZ%,"Yang Yuanzhi" 52 | HKR,,BffSerialNumber,%REG_SZ%,"FOR PRIVATE USE ONLY" 53 | HKR,,BffLicenseKey,%REG_SZ%,"A8FB4AC6D1C16BFF" 54 | 55 | [BusFilter_EventLog_Inst] 56 | AddReg=BusFilter_EventLog_AddReg 57 | 58 | [BusFilter_EventLog_AddReg] 59 | HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\BusFilter.sys" 60 | HKR,,TypesSupported,0x00010001,7 61 | 62 | [SourceDisksNames.$ARCH$] 63 | 1 = %DiskId1%,,, 64 | 65 | [SourceDisksFiles.$ARCH$] 66 | mp.sys = 1, 67 | BusFilter.sys = 1, 68 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1, ; make sure the number matches with SourceDisksNames 69 | 70 | ; 71 | ;--- MP_Device Coinstaller installation ------ 72 | ; 73 | ;[DestinationDirs] 74 | ;MP_Device_CoInstaller_CopyFiles = 11 75 | 76 | [MP_Device.CoInstallers] 77 | AddReg=MP_Device_CoInstaller_AddReg 78 | CopyFiles=MP_Device_CoInstaller_CopyFiles 79 | 80 | [MP_Device_CoInstaller_AddReg] 81 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 82 | 83 | [MP_Device_CoInstaller_CopyFiles] 84 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 85 | 86 | ;[SourceDisksFiles.$ARCH$] 87 | ;WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1, ; make sure the number matches with SourceDisksNames 88 | 89 | [MP_Device.Wdf] 90 | KmdfService = mp, MP_Device_wdfsect 91 | 92 | [MP_Device_wdfsect] 93 | KmdfLibraryVersion = $KMDFVERSION$ 94 | 95 | [MP_Service_Inst] 96 | DisplayName = %MPDeviceDesc% 97 | ServiceType = %SERVICE_KERNEL_DRIVER% 98 | StartType = %SERVICE_BOOT_START% 99 | ErrorControl = %SERVICE_ERROR_NORMAL% 100 | ServiceBinary = %12%\mp.sys 101 | LoadOrderGroup = SCSI Miniport 102 | AddReg = pnpsafe_isa_addreg 103 | 104 | [pnpsafe_isa_addreg] 105 | HKR, "Parameters\PnpInterface", "1", %REG_DWORD%, 0x00000001 106 | ;;;HKR, "Parameters", "BreakOnEntry", %REG_DWORD%, 0x00000000 107 | ;;;HKR, "Parameters", "DebugLevel", %REG_DWORD%, 0x000000ff 108 | ;;; The next 2 values will allow a 16 MB virtual harddisk as reported in Disk Manager (diskmgmt.msc). 109 | HKR, "Parameters", "VirtualDiskSize", %REG_DWORD%, 0x01000000 110 | HKR, "Parameters", "PhysicalDiskSize", %REG_DWORD%, 0x01000000 111 | HKR, "Parameters", "NbrLUNsperHBA", %REG_DWORD%, 0x00000002 112 | ;;;HKR, "Parameters", "CombineVirtDisks", %REG_DWORD%, 0x00000001 113 | 114 | [Strings] 115 | MSFT = "Microsoft" 116 | SCSIClassName = "SCSI and RAID controllers" 117 | MPDeviceDesc = "Demo StorPort Virtual Adapter" 118 | DiskId1 = "Virtual Miniport Device Installation Disk #1" 119 | rootstr = "root\mp" 120 | BusFilter.SVCDESC = "BusFilter Service" 121 | 122 | ;******************************************* 123 | ;Handy macro substitutions (non-localizable) 124 | SPSVCINST_ASSOCSERVICE = 0x00000002 125 | SERVICE_KERNEL_DRIVER = 1 126 | SERVICE_BOOT_START = 0 127 | SERVICE_ERROR_NORMAL = 1 128 | 129 | REG_DWORD = 0x00010001 130 | REG_BINARY = 0x00000001 131 | REG_SZ = 0x00000000 -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/install/install.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | 39 | {e65d39a3-0da9-4a25-ba70-2a5092c2ec5e} 40 | 41 | 42 | {325a9717-af6f-41b9-98a7-aeca1923e108} 43 | 44 | 45 | 46 | 47 | 48 | 49 | {F1030D64-1140-4EC8-8D65-C7821B7DD8A1} 50 | {4605da2c-74a5-4865-98e1-152ef136825f} 51 | v4.5 52 | 12.0 53 | Debug 54 | Win32 55 | install 56 | 57 | 58 | 59 | Windows7 60 | true 61 | WindowsKernelModeDriver10.0 62 | Utility 63 | Package 64 | true 65 | Desktop 66 | 67 | 68 | Windows7 69 | false 70 | WindowsKernelModeDriver10.0 71 | Utility 72 | Package 73 | true 74 | Desktop 75 | 76 | 77 | Windows7 78 | true 79 | WindowsKernelModeDriver10.0 80 | Utility 81 | Package 82 | true 83 | Desktop 84 | 85 | 86 | Windows10 87 | false 88 | WindowsKernelModeDriver10.0 89 | Utility 90 | Package 91 | true 92 | Desktop 93 | 94 | 95 | Windows7 96 | true 97 | WindowsKernelModeDriver10.0 98 | Utility 99 | Package 100 | true 101 | Desktop 102 | 103 | 104 | Windows7 105 | false 106 | WindowsKernelModeDriver10.0 107 | Utility 108 | Package 109 | true 110 | Desktop 111 | 112 | 113 | Windows7 114 | true 115 | WindowsKernelModeDriver10.0 116 | Utility 117 | Package 118 | true 119 | Desktop 120 | 121 | 122 | Windows7 123 | false 124 | WindowsKernelModeDriver10.0 125 | Utility 126 | Package 127 | true 128 | Desktop 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | DbgengKernelDebugger 140 | 141 | 142 | 143 | False 144 | False 145 | True 146 | 147 | 133563 148 | true 149 | 150 | 151 | DbgengKernelDebugger 152 | 153 | 154 | 155 | False 156 | False 157 | True 158 | 159 | 133563 160 | true 161 | 162 | 163 | DbgengKernelDebugger 164 | 165 | 166 | 167 | False 168 | False 169 | True 170 | 171 | 133563 172 | true 173 | 174 | 175 | DbgengKernelDebugger 176 | 177 | 178 | 179 | False 180 | False 181 | True 182 | 183 | 133563 184 | true 185 | 186 | 187 | DbgengKernelDebugger 188 | 189 | 190 | 191 | False 192 | False 193 | True 194 | 195 | 133563 196 | true 197 | 198 | 199 | DbgengKernelDebugger 200 | 201 | 202 | 203 | False 204 | False 205 | True 206 | 207 | 133563 208 | true 209 | 210 | 211 | DbgengKernelDebugger 212 | 213 | 214 | 215 | False 216 | False 217 | True 218 | 219 | 133563 220 | true 221 | 222 | 223 | DbgengKernelDebugger 224 | 225 | 226 | 227 | False 228 | False 229 | True 230 | 231 | 133563 232 | true 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | /fd SHA256 %(AdditionalOptions) 332 | 333 | 334 | 335 | 336 | 337 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/install/install.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {8E41214B-6785-4CFE-B992-037D68949A14} 6 | inf;inv;inx;mof;mc; 7 | 8 | 9 | 10 | 11 | Driver Files 12 | 13 | 14 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/makefile.inc: -------------------------------------------------------------------------------- 1 | LNG=$(LANGUAGE) 2 | _INX=. 3 | STAMP=stampinf -n -f $@ -a $(_BUILDARCH) -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR) 4 | 5 | $(OBJ_PATH)\$(O)\$(INF_NAME).inf: $(_INX)\$(INF_NAME).inx 6 | copy $(_INX)\$(@B).inx $@ 7 | $(STAMP) 8 | 9 | $(OBJ_PATH)\$O\hbaapi.mof $(OBJ_PATH)\$O\hbaapi.mfl: hbaapi.mof 10 | ## Pre-process .mof file. 11 | $(C_PREPROCESSOR_NAME) $(C_PREPROCESSOR_FLAGS) hbaapi.mof > $(OBJ_PATH)\$(O)\hbaapi.tmp 12 | 13 | ## Make a copy, for the mof-compilation step below 14 | copy $(OBJ_PATH)\$(O)\hbaapi.tmp .\hbaapi.mof 15 | 16 | ## Compile the base .mof file, which will include the new .mof file. 17 | mofcomp -WMI -B:$(OBJ_PATH)\$(O)\\mp.bmf mp.mof 18 | 19 | ## Build mpwmi.h 20 | wmimofck -h.\inc\mpwmi.h -m -u -w.\html $(OBJ_PATH)\$(O)\mp.bmf 21 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/mp.inx: -------------------------------------------------------------------------------- 1 | 2 | ; MP.INF 3 | ; 4 | ; Copyright (c) 1998-2011, Microsoft Corporation. 5 | 6 | [Version] 7 | Signature="$WINDOWS NT$" 8 | Class=SCSIAdapter 9 | ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318} 10 | ;Provider=%MSFT% 11 | Provider=BFF 12 | DriverVer=01/30/2007,6.0.6000.16386 13 | CatalogFile = mp.cat 14 | 15 | [DestinationDirs] 16 | DefaultDestDir = 12 17 | MP_Device_CoInstaller_CopyFiles = 11 18 | 19 | [Manufacturer] 20 | %MSFT%=MSFT, NT$ARCH$ 21 | 22 | [MSFT.NT$ARCH$] 23 | %MPDeviceDesc%=MP_Device, %rootstr% 24 | 25 | [MP_Device] 26 | CopyFiles=@mp.sys 27 | CopyFiles=@BusFilter.sys 28 | 29 | [MP_Device.HW] 30 | AddReg = MP_Device_AddReg 31 | 32 | [MP_Device_AddReg] 33 | HKR, "ScsiPort", "NeedsSystemShutdownNotification", 0x00010001, 1 34 | HKR,,"UpperFilters",0x00010000,"BusFilter" ; REG_MULTI_SZ value 35 | 36 | [MP_Device.Services] 37 | AddService = mp, %SPSVCINST_ASSOCSERVICE%, MP_Service_Inst 38 | AddService = BusFilter,, BusFilter_Service_Inst, BusFilter_EventLog_Inst 39 | 40 | ; -------------- BusFilter driver install sections 41 | [BusFilter_Service_Inst] 42 | DisplayName = %BusFilter.SVCDESC% 43 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 44 | StartType = 3 ; SERVICE_DEMAND_START 45 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 46 | ServiceBinary = %12%\BusFilter.sys 47 | AddReg = BusFilter_Service_AddReg 48 | 49 | [BusFilter_Service_AddReg] 50 | HKR,,BffLicensee,%REG_SZ%,"Yang Yuanzhi" 51 | HKR,,BffSerialNumber,%REG_SZ%,"FOR PRIVATE USE ONLY" 52 | HKR,,BffLicenseKey,%REG_SZ%,"A8FB4AC6D1C16BFF" 53 | 54 | [BusFilter_EventLog_Inst] 55 | AddReg=BusFilter_EventLog_AddReg 56 | 57 | [BusFilter_EventLog_AddReg] 58 | HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\BusFilter.sys" 59 | HKR,,TypesSupported,0x00010001,7 60 | 61 | [SourceDisksNames.$ARCH$] 62 | 1 = %DiskId1%,,, 63 | 64 | [SourceDisksFiles.$ARCH$] 65 | mp.sys = 1, 66 | BusFilter.sys = 1, 67 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1, ; make sure the number matches with SourceDisksNames 68 | 69 | ; 70 | ;--- MP_Device Coinstaller installation ------ 71 | ; 72 | ;[DestinationDirs] 73 | ;MP_Device_CoInstaller_CopyFiles = 11 74 | 75 | [MP_Device.CoInstallers] 76 | AddReg=MP_Device_CoInstaller_AddReg 77 | CopyFiles=MP_Device_CoInstaller_CopyFiles 78 | 79 | [MP_Device_CoInstaller_AddReg] 80 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 81 | 82 | [MP_Device_CoInstaller_CopyFiles] 83 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 84 | 85 | ;[SourceDisksFiles.$ARCH$] 86 | ;WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1, ; make sure the number matches with SourceDisksNames 87 | 88 | [MP_Device.Wdf] 89 | KmdfService = mp, MP_Device_wdfsect 90 | 91 | [MP_Device_wdfsect] 92 | KmdfLibraryVersion = $KMDFVERSION$ 93 | 94 | [MP_Service_Inst] 95 | DisplayName = %MPDeviceDesc% 96 | ServiceType = %SERVICE_KERNEL_DRIVER% 97 | StartType = %SERVICE_BOOT_START% 98 | ErrorControl = %SERVICE_ERROR_NORMAL% 99 | ServiceBinary = %12%\mp.sys 100 | LoadOrderGroup = SCSI Miniport 101 | AddReg = pnpsafe_isa_addreg 102 | 103 | [pnpsafe_isa_addreg] 104 | HKR, "Parameters\PnpInterface", "1", %REG_DWORD%, 0x00000001 105 | ;;;HKR, "Parameters", "BreakOnEntry", %REG_DWORD%, 0x00000000 106 | ;;;HKR, "Parameters", "DebugLevel", %REG_DWORD%, 0x000000ff 107 | ;;; The next 2 values will allow a 16 MB virtual harddisk as reported in Disk Manager (diskmgmt.msc). 108 | HKR, "Parameters", "VirtualDiskSize", %REG_DWORD%, 0x01000000 109 | HKR, "Parameters", "PhysicalDiskSize", %REG_DWORD%, 0x01000000 110 | HKR, "Parameters", "NbrLUNsperHBA", %REG_DWORD%, 0x00000002 111 | ;;;HKR, "Parameters", "CombineVirtDisks", %REG_DWORD%, 0x00000001 112 | 113 | [Strings] 114 | MSFT = "Microsoft" 115 | SCSIClassName = "SCSI and RAID controllers" 116 | MPDeviceDesc = "Demo StorPort Virtual Adapter" 117 | DiskId1 = "Virtual Miniport Device Installation Disk #1" 118 | rootstr = "root\mp" 119 | BusFilter.SVCDESC = "BusFilter Service" 120 | 121 | ;******************************************* 122 | ;Handy macro substitutions (non-localizable) 123 | SPSVCINST_ASSOCSERVICE = 0x00000002 124 | SERVICE_KERNEL_DRIVER = 1 125 | SERVICE_BOOT_START = 0 126 | SERVICE_ERROR_NORMAL = 1 127 | 128 | REG_DWORD = 0x00010001 129 | REG_BINARY = 0x00000001 130 | REG_SZ = 0x00000000 -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/mp.mof: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************/ 2 | /* */ 3 | /* Copyright (c) 2007-2011. Microsoft Corporation. All Rights Reserved */ 4 | /* */ 5 | /**************************************************************************************************/ 6 | 7 | #pragma namespace ("\\root\\wmi") 8 | 9 | #include ("hbaapi.mof") 10 | 11 | [Dynamic, Provider("WMIProv"), 12 | WMI, 13 | Description("GmDemoDriver Schema") : amended, 14 | guid("33168F61-67A8-408e-B262-1240AAC03447"), 15 | 16 | DisplayName("GmDemoDriver counters") : amended, 17 | locale("MS\\0x409")] 18 | 19 | // Driver logic assumes the next class comprises (besides boilerplate) 2 ULONGs and a string. 20 | 21 | class GmDemoDriver 22 | { 23 | [key, read] 24 | string InstanceName; 25 | 26 | [read] 27 | boolean Active; 28 | 29 | [read, 30 | WmiDataId(1), 31 | Description("The Answer") 32 | ] 33 | uint32 TheAnswer; 34 | 35 | [read, 36 | WmiDataId(2), 37 | Description("The Next Answer") 38 | ] 39 | uint32 TheNextAnswer; 40 | 41 | [read, 42 | WmiDataId(3), 43 | Description("SRBs seen") 44 | ] 45 | uint32 SRBsSeen; 46 | 47 | [read, 48 | WmiDataId(4), 49 | Description("WMI SRBs seen") 50 | ] 51 | uint32 WMISRBsSeen; 52 | 53 | }; 54 | 55 | [Dynamic, Provider("WMIProv"), 56 | WMI, 57 | Description("GmDemoDriver Schema2"), 58 | guid("33168F62-67A8-408e-B262-1240AAC03447"), 59 | PerfDetail(100), 60 | HiPerf, 61 | DisplayName("GmDemoDriver") : amended, 62 | locale("MS\\0x409")] 63 | 64 | class GmDemoDriver2 65 | { 66 | [key, read] 67 | string InstanceName; 68 | 69 | [read] 70 | boolean Active; 71 | 72 | [read, write, 73 | WmiDataId(1), 74 | DisplayName("Number array elements") : amended, 75 | Description("Number of array elements") 76 | ] 77 | uint32 NumberElements; 78 | 79 | [read, write, 80 | WmiDataId(2), 81 | Description("The array"), 82 | WmiSizeIs("NumberElements") 83 | ] 84 | uint32 UlongArray[]; 85 | }; 86 | 87 | [WMI, 88 | Dynamic, 89 | Provider("WmiProv"), 90 | Locale("MS\\0x409"), 91 | Description("Performance counter class that keeps counts of SRBs") : amended, 92 | DisplayName("GmDemoDriver SRB Counts") : amended, 93 | guid("33168F63-67A8-408e-B262-1240AAC03447"), 94 | PerfDetail(100), 95 | HiPerf 96 | ] 97 | class GmDemoDriverSrbActivity : Win32_PerfRawData 98 | { 99 | [key, read] 100 | string InstanceName; 101 | [read] boolean Active; 102 | 103 | [WmiDataId(1), 104 | DisplayName("Total CREATE SRBs") : amended, 105 | 106 | PerfDefault, 107 | CounterType(0x00000000), // PERF_COUNTER_RAWCOUNT 108 | DefaultScale(0), 109 | PerfDetail(100), 110 | 111 | read, 112 | Description("Count of CREATE SRBs received") : amended 113 | ] uint32 TotalCreateSRBs; 114 | 115 | [WmiDataId(2), 116 | DisplayName("Total CLOSE SRBs") : amended, 117 | 118 | CounterType(0x00000000), // PERF_COUNTER_RAWCOUNT 119 | DefaultScale(0), 120 | PerfDetail(100), 121 | 122 | read, 123 | Description("Count of CLOSE SRBs received") : amended 124 | ] uint32 TotalCloseSRBs; 125 | 126 | [WmiDataId(3), 127 | DisplayName("Total IOCTL SRBs") : amended, 128 | 129 | CounterType(0x00000000), // PERF_COUNTER_RAWCOUNT 130 | DefaultScale(0), 131 | PerfDetail(100), 132 | 133 | read, 134 | Description("Count of IOCTL SRBs received") : amended 135 | ] uint32 TotalIoCtlSrbs; 136 | }; 137 | 138 | [WMI, 139 | Dynamic, 140 | Provider("WmiProv"), 141 | Locale("MS\\0x409"), 142 | Description("WMI method") : amended, 143 | guid("33168F64-67A8-408e-B262-1240AAC03447") 144 | ] 145 | class GmDrvDrvMethod 146 | { 147 | [key, read] 148 | string InstanceName; 149 | 150 | [read] boolean Active; 151 | 152 | [Implemented, WmiMethodId(1)] void 153 | GmDrvDemoMethod1([in] uint32 inDatum, [out] uint32 outDatum); 154 | 155 | [Implemented, WmiMethodId(2)] void 156 | GmDrvDemoMethod2([in] uint32 inDatum1, [in] uint32 inDatum2, [out] uint32 outDatum1); 157 | 158 | [Implemented, WmiMethodId(3)] void 159 | GmDrvDemoMethod3([in] uint32 inDatum1, [in] uint32 inDatum2, [out] uint32 outDatum1, [out] uint32 outDatum2); 160 | 161 | }; 162 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/mp.rc: -------------------------------------------------------------------------------- 1 | //Microsoft Developer Studio generated resource script. 2 | // 3 | //#include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #define APSTUDIO_HIDDEN_SYMBOLS 11 | #include "windows.h" 12 | #undef APSTUDIO_HIDDEN_SYMBOLS 13 | #include "ntverp.h" 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | #undef APSTUDIO_READONLY_SYMBOLS 17 | 18 | ///////////////////////////////////////////////////////////////////////////// 19 | // English (U.S.) resources 20 | 21 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 22 | #ifdef _WIN32 23 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 24 | #pragma code_page(1252) 25 | #endif //_WIN32 26 | 27 | #ifdef APSTUDIO_INVOKED 28 | ///////////////////////////////////////////////////////////////////////////// 29 | // 30 | // TEXTINCLUDE 31 | // 32 | 33 | 1 TEXTINCLUDE DISCARDABLE 34 | BEGIN 35 | "resource.h\0" 36 | END 37 | 38 | 2 TEXTINCLUDE DISCARDABLE 39 | BEGIN 40 | "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" 41 | "#include ""windows.h""\r\n" 42 | "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" 43 | "#include ""ntverp.h""\r\n" 44 | "\0" 45 | END 46 | 47 | 3 TEXTINCLUDE DISCARDABLE 48 | BEGIN 49 | "\r\n" 50 | "\0" 51 | END 52 | 53 | #endif // APSTUDIO_INVOKED 54 | 55 | #endif // English (U.S.) resources 56 | ///////////////////////////////////////////////////////////////////////////// 57 | 58 | MofResource MOFDATA mp.bmf 59 | 60 | 61 | #ifndef APSTUDIO_INVOKED 62 | ///////////////////////////////////////////////////////////////////////////// 63 | // 64 | // Generated from the TEXTINCLUDE 3 resource. 65 | // 66 | 67 | 68 | ///////////////////////////////////////////////////////////////////////////// 69 | #endif // not APSTUDIO_INVOKED 70 | 71 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/mp/hbaapi.mof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abysdom/bus-filter-framework/ce366417e2831116634cce54d4e2586f04ad4eb8/WDKStorPortVirtualMiniport/mp/hbaapi.mof -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/mp/mp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.12.35514.174 d17.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp", "mp.vcxproj", "{325A9717-AF6F-41B9-98A7-AECA1923E108}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bff", "..\..\bff\bff.vcxproj", "{A1E905CB-21AF-4167-87D9-90927A7A67C6}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BusFilter", "..\..\BusFilter\BusFilter.vcxproj", "{E65D39A3-0DA9-4A25-BA70-2A5092C2EC5E}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "install", "..\install\install.vcxproj", "{F1030D64-1140-4EC8-8D65-C7821B7DD8A1}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {325A9717-AF6F-41B9-98A7-AECA1923E108}.Release|x64.ActiveCfg = Release|x64 21 | {325A9717-AF6F-41B9-98A7-AECA1923E108}.Release|x64.Build.0 = Release|x64 22 | {325A9717-AF6F-41B9-98A7-AECA1923E108}.Release|x86.ActiveCfg = Release|Win32 23 | {325A9717-AF6F-41B9-98A7-AECA1923E108}.Release|x86.Build.0 = Release|Win32 24 | {A1E905CB-21AF-4167-87D9-90927A7A67C6}.Release|x64.ActiveCfg = Release|x64 25 | {A1E905CB-21AF-4167-87D9-90927A7A67C6}.Release|x64.Build.0 = Release|x64 26 | {A1E905CB-21AF-4167-87D9-90927A7A67C6}.Release|x64.Deploy.0 = Release|x64 27 | {A1E905CB-21AF-4167-87D9-90927A7A67C6}.Release|x86.ActiveCfg = Release|Win32 28 | {A1E905CB-21AF-4167-87D9-90927A7A67C6}.Release|x86.Build.0 = Release|Win32 29 | {A1E905CB-21AF-4167-87D9-90927A7A67C6}.Release|x86.Deploy.0 = Release|Win32 30 | {E65D39A3-0DA9-4A25-BA70-2A5092C2EC5E}.Release|x64.ActiveCfg = Release|x64 31 | {E65D39A3-0DA9-4A25-BA70-2A5092C2EC5E}.Release|x64.Build.0 = Release|x64 32 | {E65D39A3-0DA9-4A25-BA70-2A5092C2EC5E}.Release|x64.Deploy.0 = Release|x64 33 | {E65D39A3-0DA9-4A25-BA70-2A5092C2EC5E}.Release|x86.ActiveCfg = Release|Win32 34 | {E65D39A3-0DA9-4A25-BA70-2A5092C2EC5E}.Release|x86.Build.0 = Release|Win32 35 | {E65D39A3-0DA9-4A25-BA70-2A5092C2EC5E}.Release|x86.Deploy.0 = Release|Win32 36 | {F1030D64-1140-4EC8-8D65-C7821B7DD8A1}.Release|x64.ActiveCfg = Release|x64 37 | {F1030D64-1140-4EC8-8D65-C7821B7DD8A1}.Release|x64.Build.0 = Release|x64 38 | {F1030D64-1140-4EC8-8D65-C7821B7DD8A1}.Release|x64.Deploy.0 = Release|x64 39 | {F1030D64-1140-4EC8-8D65-C7821B7DD8A1}.Release|x86.ActiveCfg = Release|Win32 40 | {F1030D64-1140-4EC8-8D65-C7821B7DD8A1}.Release|x86.Build.0 = Release|Win32 41 | {F1030D64-1140-4EC8-8D65-C7821B7DD8A1}.Release|x86.Deploy.0 = Release|Win32 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {6A6BF602-4990-4CA6-BE6A-59C7DCB1E31D} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/mp/mp.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {325A9717-AF6F-41B9-98A7-AECA1923E108} 39 | {1bc93793-694f-48fe-9372-81e2b05556fd} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | mp 45 | 46 | 47 | 48 | Windows7 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | KMDF 53 | Desktop 54 | 55 | 56 | Windows7 57 | false 58 | WindowsKernelModeDriver10.0 59 | Driver 60 | KMDF 61 | Desktop 62 | 63 | 64 | Windows7 65 | true 66 | WindowsKernelModeDriver10.0 67 | Driver 68 | KMDF 69 | Desktop 70 | 71 | 72 | Windows10 73 | false 74 | WindowsKernelModeDriver10.0 75 | Driver 76 | KMDF 77 | Desktop 78 | 79 | 80 | Windows10 81 | true 82 | WindowsKernelModeDriver10.0 83 | Driver 84 | KMDF 85 | Universal 86 | 87 | 88 | Windows10 89 | false 90 | WindowsKernelModeDriver10.0 91 | Driver 92 | KMDF 93 | Universal 94 | 95 | 96 | Windows10 97 | true 98 | WindowsKernelModeDriver10.0 99 | Driver 100 | KMDF 101 | Universal 102 | 103 | 104 | Windows10 105 | false 106 | WindowsKernelModeDriver10.0 107 | Driver 108 | KMDF 109 | Universal 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | DbgengKernelDebugger 121 | $(ProjectDir);$(IncludePath);..\inc 122 | false 123 | 124 | 125 | DbgengKernelDebugger 126 | $(ProjectDir);$(IncludePath);..\inc 127 | false 128 | 129 | 130 | DbgengKernelDebugger 131 | $(ProjectDir);$(IncludePath);..\inc 132 | false 133 | 134 | 135 | DbgengKernelDebugger 136 | $(ProjectDir);$(IncludePath);..\inc 137 | false 138 | 139 | 140 | DbgengKernelDebugger 141 | $(ProjectDir);$(IncludePath);..\inc 142 | 143 | 144 | DbgengKernelDebugger 145 | $(ProjectDir);$(IncludePath);..\inc 146 | 147 | 148 | DbgengKernelDebugger 149 | $(ProjectDir);$(IncludePath);..\inc 150 | 151 | 152 | DbgengKernelDebugger 153 | $(ProjectDir);$(IncludePath);..\inc 154 | 155 | 156 | 157 | copy %WinDir%\system32\wbem\hbaapi.mof $(ProjectDir) 158 | 159 | 160 | 161 | 162 | Copying HbaApi.mof... 163 | 164 | 165 | _ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions) 166 | true 167 | {km-w2k.tpl}*.tmh 168 | ..\inc\trace.h 169 | ..\inc\trcmp.ini 170 | ..\inc 171 | 172 | 173 | storport.lib;scsiwmi.lib;%(AdditionalDependencies) 174 | 175 | 176 | true 177 | 178 | 179 | true 180 | 181 | 182 | copy ..\LICENSE-2.0.txt $(OutDir) 183 | 184 | 185 | Copy LICENSE-2.0.txt... 186 | 187 | 188 | 189 | 190 | copy %WinDir%\system32\wbem\hbaapi.mof $(ProjectDir) 191 | 192 | 193 | 194 | 195 | Copying HbaApi.mof... 196 | 197 | 198 | _ARM64_;ARM64;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions) 199 | true 200 | {km-w2k.tpl}*.tmh 201 | ..\inc\trace.h 202 | ..\inc\trcmp.ini 203 | ..\inc 204 | 205 | 206 | storport.lib;scsiwmi.lib;%(AdditionalDependencies) 207 | 208 | 209 | true 210 | 211 | 212 | true 213 | 214 | 215 | copy ..\LICENSE-2.0.txt $(OutDir) 216 | 217 | 218 | Copy LICENSE-2.0.txt... 219 | 220 | 221 | 222 | 223 | copy %WinDir%\system32\wbem\hbaapi.mof $(ProjectDir) 224 | 225 | 226 | 227 | 228 | Copying HbaApi.mof... 229 | 230 | 231 | _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) 232 | true 233 | {km-w2k.tpl}*.tmh 234 | ..\inc\trace.h 235 | ..\inc\trcmp.ini 236 | ..\inc 237 | 238 | 239 | storport.lib;scsiwmi.lib;%(AdditionalDependencies) 240 | 241 | 242 | true 243 | 244 | 245 | true 246 | 247 | 248 | copy ..\LICENSE-2.0.txt $(OutDir) 249 | 250 | 251 | Copy LICENSE-2.0.txt... 252 | 253 | 254 | 255 | 256 | copy %WinDir%\system32\wbem\hbaapi.mof $(ProjectDir) 257 | 258 | 259 | 260 | 261 | Copying HbaApi.mof... 262 | 263 | 264 | _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) 265 | true 266 | {km-w2k.tpl}*.tmh 267 | ..\inc\trace.h 268 | ..\inc\trcmp.ini 269 | ..\inc 270 | 271 | 272 | storport.lib;scsiwmi.lib;%(AdditionalDependencies) 273 | 274 | 275 | true 276 | 277 | 278 | true 279 | 280 | 281 | copy ..\LICENSE-2.0.txt $(OutDir) 282 | 283 | 284 | Copy LICENSE-2.0.txt... 285 | 286 | 287 | 288 | 289 | copy %WinDir%\system32\wbem\hbaapi.mof $(ProjectDir) 290 | 291 | 292 | 293 | 294 | Copying HbaApi.mof... 295 | 296 | 297 | _ARM_;ARM;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions) 298 | true 299 | {km-w2k.tpl}*.tmh 300 | ..\inc\trace.h 301 | ..\inc\trcmp.ini 302 | ..\inc 303 | 304 | 305 | storport.lib;scsiwmi.lib;%(AdditionalDependencies) 306 | 307 | 308 | true 309 | 310 | 311 | true 312 | 313 | 314 | copy ..\LICENSE-2.0.txt $(OutDir) 315 | 316 | 317 | Copy LICENSE-2.0.txt... 318 | 319 | 320 | 321 | 322 | copy %WinDir%\system32\wbem\hbaapi.mof $(ProjectDir) 323 | 324 | 325 | 326 | 327 | Copying HbaApi.mof... 328 | 329 | 330 | _ARM_;ARM;_USE_DECLSPECS_FOR_SAL=1;STD_CALL;%(PreprocessorDefinitions) 331 | true 332 | {km-w2k.tpl}*.tmh 333 | ..\inc\trace.h 334 | ..\inc\trcmp.ini 335 | ..\inc 336 | 337 | 338 | storport.lib;scsiwmi.lib;%(AdditionalDependencies) 339 | 340 | 341 | true 342 | 343 | 344 | true 345 | 346 | 347 | copy ..\LICENSE-2.0.txt $(OutDir) 348 | 349 | 350 | Copy LICENSE-2.0.txt... 351 | 352 | 353 | 354 | 355 | copy %WinDir%\system32\wbem\hbaapi.mof $(ProjectDir) 356 | 357 | 358 | 359 | 360 | Copying HbaApi.mof... 361 | 362 | 363 | _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) 364 | true 365 | {km-w2k.tpl}*.tmh 366 | ..\inc\trace.h 367 | ..\inc\trcmp.ini 368 | ..\inc 369 | 370 | 371 | storport.lib;scsiwmi.lib;%(AdditionalDependencies) 372 | 373 | 374 | true 375 | 376 | 377 | true 378 | 379 | 380 | copy ..\LICENSE-2.0.txt $(OutDir) 381 | 382 | 383 | Copy LICENSE-2.0.txt... 384 | 385 | 386 | 387 | 388 | copy %WinDir%\system32\wbem\hbaapi.mof $(ProjectDir) 389 | 390 | 391 | 392 | 393 | Copying HbaApi.mof... 394 | 395 | 396 | _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) 397 | true 398 | {km-w2k.tpl}*.tmh 399 | ..\inc\trace.h 400 | ..\inc\trcmp.ini 401 | ..\inc 402 | 403 | 404 | storport.lib;scsiwmi.lib;%(AdditionalDependencies) 405 | 406 | 407 | true 408 | 409 | 410 | true 411 | 412 | 413 | copy ..\LICENSE-2.0.txt $(OutDir) 414 | 415 | 416 | Copy LICENSE-2.0.txt... 417 | 418 | 419 | 420 | /fd SHA256 %(AdditionalOptions) 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/mp/mp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | Source Files 27 | 28 | 29 | Source Files 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | 50 | 51 | Driver Files 52 | 53 | 54 | 55 | 56 | Resource Files 57 | 58 | 59 | 60 | 61 | Header Files 62 | 63 | 64 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/sources: -------------------------------------------------------------------------------- 1 | TARGETNAME=mp 2 | TARGETTYPE=DRIVER 3 | 4 | # Set warning level. 5 | MSC_WARNING_LEVEL=/W4 /WX 6 | 7 | # no optimization, to ease debugging. 8 | MSC_OPTIMIZATION=$(MSC_OPTIMIZATION) /Odi 9 | 10 | ##The next causes DriverEntry to use an inline copy of the driver global stucture. 11 | ##C_DEFINES=$(C_DEFINES) -DMP_DrvInfo_Inline 12 | 13 | !if !defined(_NT_TARGET_VERSION_LONGHORN) 14 | _NT_TARGET_VERSION_LONGHORN =0x600 15 | !endif 16 | 17 | !if !defined(_NT_TARGET_VERSION_WIN7) 18 | _NT_TARGET_VERSION_WIN7 =0x601 19 | !endif 20 | 21 | KMDF_VERSION_MAJOR=1 22 | 23 | TARGETLIBS=$(DDK_LIB_PATH)\storport.lib \ 24 | $(DDK_LIB_PATH)\scsiwmi.lib \ 25 | $(DDK_LIB_PATH)\hal.lib \ 26 | $(DDK_LIB_PATH)\ntoskrnl.lib \ 27 | $(DDK_LIB_PATH)\wdm.lib \ 28 | $(KMDF_LIB_PATH)\$(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)\wdfldr.lib \ 29 | $(KMDF_LIB_PATH)\$(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)\WdfDriverEntry.lib 30 | 31 | INF_NAME=mp 32 | 33 | INCLUDES=.\inc; \ 34 | $(PUBLIC_ROOT)\ddk\inc;\ 35 | 36 | 37 | DRIVERTYPE=WDM 38 | 39 | SOURCES = mp.c \ 40 | scsi.c \ 41 | wmi.c \ 42 | utils.c \ 43 | mp.rc \ 44 | WkRtn.c 45 | 46 | RUN_WPP=$(SOURCES) \ 47 | -km \ 48 | -gen:{km-w2k.tpl}*.tmh \ 49 | -scan:inc\trace.h \ 50 | -ini:.\inc\trcmp.ini 51 | 52 | NTTARGETFILE1=$(OBJ_PATH)\$(O)\$(INF_NAME).inf 53 | 54 | PASS1_BINPLACE=$(NTTARGETFILE1) 55 | 56 | # Ensure a .bmf is built and a resulting header file as well as HTML to test paths. 57 | NTTARGETFILE0=$(OBJ_PATH)\$(O)\hbaapi.mof 58 | 59 | -------------------------------------------------------------------------------- /WDKStorPortVirtualMiniport/utils.c: -------------------------------------------------------------------------------- 1 | /****************************** Module Header ******************************\ 2 | * Module Name: utils.c 3 | * Project: CppWDKStorPortVirtualMiniport 4 | * 5 | * Copyright (c) Microsoft Corporation. 6 | * 7 | * MpQueryRegParameters() 8 | * Does registry lookup of parameters. 9 | * 10 | * This source is subject to the Microsoft Public License. 11 | * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. 12 | * All other rights reserved. 13 | * 14 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 15 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 17 | \***************************************************************************/ 18 | 19 | #define localVersion "2.07" 20 | 21 | #include "mp.h" 22 | #include "trace.h" 23 | 24 | #pragma warning(push) 25 | #pragma warning(disable : 4204) /* Prevent C4204 messages from stortrce.h. */ 26 | #include 27 | #pragma warning(pop) 28 | 29 | #include "utils.tmh" 30 | 31 | /**************************************************************************************************/ 32 | /* */ 33 | /* Note: DoStorageTraceETW may not be used here, since tracing won't have been set up. */ 34 | /* */ 35 | /**************************************************************************************************/ 36 | VOID 37 | MpQueryRegParameters( 38 | __in PUNICODE_STRING pRegistryPath, 39 | __in pMP_REG_INFO pRegInfo 40 | ) 41 | /*++ 42 | 43 | Routine Description: 44 | 45 | This routine is called from DriverEntry to get parameters from the registry. If the registry query 46 | fails, default values are used. 47 | 48 | Return Value: 49 | 50 | None 51 | 52 | --*/ 53 | { 54 | MP_REG_INFO defRegInfo; 55 | 56 | // Set default values. 57 | 58 | defRegInfo.BreakOnEntry = DEFAULT_BREAK_ON_ENTRY; 59 | defRegInfo.DebugLevel = DEFAULT_DEBUG_LEVEL; 60 | defRegInfo.InitiatorID = DEFAULT_INITIATOR_ID; 61 | defRegInfo.PhysicalDiskSize = DEFAULT_PHYSICAL_DISK_SIZE; 62 | defRegInfo.VirtualDiskSize = DEFAULT_VIRTUAL_DISK_SIZE; 63 | defRegInfo.NbrVirtDisks = DEFAULT_NbrVirtDisks; 64 | defRegInfo.NbrLUNsperHBA = DEFAULT_NbrLUNsperHBA; 65 | defRegInfo.bCombineVirtDisks = DEFAULT_bCombineVirtDisks; 66 | 67 | RtlInitUnicodeString(&defRegInfo.VendorId, VENDOR_ID); 68 | RtlInitUnicodeString(&defRegInfo.ProductId, PRODUCT_ID); 69 | RtlInitUnicodeString(&defRegInfo.ProductRevision, PRODUCT_REV); 70 | 71 | // The initialization of lclRtlQueryRegTbl is put into a subordinate block so that the initialized Buffer members of Unicode strings 72 | // in defRegInfo will be used. 73 | 74 | { 75 | NTSTATUS status; 76 | 77 | #pragma warning(push) 78 | #pragma warning(disable : 4204) 79 | #pragma warning(disable : 4221) 80 | 81 | RTL_QUERY_REGISTRY_TABLE lclRtlQueryRegTbl[] = { 82 | // The Parameters entry causes the registry to be searched under that subkey for the subsequent set of entries. 83 | {NULL, RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_NOEXPAND, L"Parameters", NULL, (ULONG_PTR)NULL, NULL, (ULONG_PTR)NULL}, 84 | 85 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"BreakOnEntry", &pRegInfo->BreakOnEntry, REG_DWORD, &defRegInfo.BreakOnEntry, sizeof(ULONG)}, 86 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"DebugLevel", &pRegInfo->DebugLevel, REG_DWORD, &defRegInfo.DebugLevel, sizeof(ULONG)}, 87 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"InitiatorID", &pRegInfo->InitiatorID, REG_DWORD, &defRegInfo.InitiatorID, sizeof(ULONG)}, 88 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"VirtualDiskSize", &pRegInfo->VirtualDiskSize, REG_DWORD, &defRegInfo.VirtualDiskSize, sizeof(ULONG)}, 89 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"PhysicalDiskSize", &pRegInfo->PhysicalDiskSize, REG_DWORD, &defRegInfo.PhysicalDiskSize, sizeof(ULONG)}, 90 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"VendorId", &pRegInfo->VendorId, REG_SZ, defRegInfo.VendorId.Buffer, 0}, 91 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"ProductId", &pRegInfo->ProductId, REG_SZ, defRegInfo.ProductId.Buffer, 0}, 92 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"ProductRevision", &pRegInfo->ProductRevision, REG_SZ, defRegInfo.ProductRevision.Buffer, 0}, 93 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"NbrVirtDisks", &pRegInfo->NbrVirtDisks, REG_DWORD, &defRegInfo.NbrVirtDisks, sizeof(ULONG)}, 94 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"NbrLUNsperHBA", &pRegInfo->NbrLUNsperHBA, REG_DWORD, &defRegInfo.NbrLUNsperHBA, sizeof(ULONG)}, 95 | {NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, L"CombineVirtDisks", &pRegInfo->bCombineVirtDisks, REG_DWORD, &defRegInfo.bCombineVirtDisks, sizeof(ULONG)}, 96 | 97 | // The null entry denotes the end of the array. 98 | {NULL, 0, NULL, NULL, (ULONG_PTR)NULL, NULL, (ULONG_PTR)NULL}, 99 | }; 100 | 101 | #pragma warning(pop) 102 | 103 | status = RtlQueryRegistryValues( 104 | RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, 105 | pRegistryPath->Buffer, 106 | lclRtlQueryRegTbl, 107 | NULL, 108 | NULL 109 | ); 110 | 111 | if (!NT_SUCCESS(status)) { // A problem? 112 | pRegInfo->BreakOnEntry = defRegInfo.BreakOnEntry; 113 | pRegInfo->DebugLevel = defRegInfo.DebugLevel; 114 | pRegInfo->InitiatorID = defRegInfo.InitiatorID; 115 | pRegInfo->PhysicalDiskSize = defRegInfo.PhysicalDiskSize; 116 | pRegInfo->VirtualDiskSize = defRegInfo.VirtualDiskSize; 117 | RtlCopyUnicodeString(&pRegInfo->VendorId, &defRegInfo.VendorId); 118 | RtlCopyUnicodeString(&pRegInfo->ProductId, &defRegInfo.ProductId); 119 | RtlCopyUnicodeString(&pRegInfo->ProductRevision, &defRegInfo.ProductRevision); 120 | pRegInfo->NbrVirtDisks = defRegInfo.NbrVirtDisks; 121 | pRegInfo->NbrLUNsperHBA = defRegInfo.NbrLUNsperHBA; 122 | pRegInfo->bCombineVirtDisks = defRegInfo.bCombineVirtDisks; 123 | } 124 | } 125 | } // End MpQueryRegParameters(). 126 | 127 | -------------------------------------------------------------------------------- /bff/bff.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework (BFF) 3 | 4 | A framework for KMDF-based upper filter drivers to behave as bus filters. 5 | You don't need to write WDM drivers any more! 6 | 7 | https://bus-filter-framework.blogspot.com/ 8 | 9 | Copyright (C) 2017 Yang Yuanzhi 10 | 11 | This program is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program. If not, see . 23 | *******************************************************************************/ 24 | #pragma once 25 | #include 26 | #include 27 | 28 | /** Callback function for creation of a bus filter device object. Before this 29 | * call, a WDF object, BffDevice, and its underlying WDM device object had 30 | * been created, and the latter in particular was then attached to the next 31 | * lower device object. 32 | * @param Device The parent WDF device object, i.e., the upper filter 33 | * device object. 34 | * @param BffDevice The WDF object as a bus filter device object. 35 | * @return 0 or any positive value for success; otherwise for 36 | * failure. 37 | */ 38 | typedef NTSTATUS BFF_DEVICE_ADD(WDFDEVICE Device, WDFOBJECT BffDevice); 39 | typedef BFF_DEVICE_ADD *PBFF_DEVICE_ADD; 40 | 41 | /** Callback function for removal of a bus filter device object. After this 42 | * call, the WDF object, BffDevice, will be deleted, and its underlying WDM 43 | * device object will be detached, and then deleted as well. 44 | * @param Device The parent WDF device object, i.e., the upper filter 45 | * device object. 46 | * @param BffDevice The WDF object as a bus filter device object. 47 | */ 48 | typedef VOID BFF_DEVICE_REMOVE(WDFDEVICE Device, WDFOBJECT BffDevice); 49 | typedef BFF_DEVICE_REMOVE *PBFF_DEVICE_REMOVE; 50 | 51 | /** Data structure for configuration of a bus filter device object. 52 | */ 53 | typedef struct _BFF_DEVICE_CONFIG 54 | { 55 | /// 56 | /// Same as DeviceType parameter of IoCreateDevice (Mandatory) 57 | /// 58 | DEVICE_TYPE DeviceType; 59 | 60 | /// 61 | /// Same as DeviceCharacteristics parameter of IoCreateDevice (Mandatory) 62 | /// 63 | ULONG DeviceCharacteristics; 64 | 65 | /// 66 | /// Callback function for creation of a bus filter device object (Optional) 67 | /// 68 | PBFF_DEVICE_ADD DeviceAdd; 69 | 70 | /// 71 | /// Callback function for removal of a bus filter device object (Optional) 72 | /// 73 | PBFF_DEVICE_REMOVE DeviceRemove; 74 | } BFF_DEVICE_CONFIG, *PBFF_DEVICE_CONFIG; 75 | 76 | /** Callback function for processing a PnP IRP. It must either complete that IRP 77 | * or, optionally register an IoCompletion routine, and pass that IRP to the 78 | * next lower driver before returning to BFF. 79 | * Example#1: 80 | * NTSTATUS callback1(WDFOBJECT BffDevice, PIRP Irp) 81 | * { 82 | * ... 83 | * IoCompleteRequest(Irp, IO_NO_INCREMENT); 84 | * return status; 85 | * } 86 | * 87 | * Example#2: 88 | * NTSTATUS callback2(WDFOBJECT BffDevice, PIRP Irp) 89 | * { 90 | * ... 91 | * IoSkipCurrentIrpStackLocation(Irp); 92 | * status = IoCallDriver(BffDeviceWdmGetAttachedDevice(BffDevice), Irp); 93 | * ... 94 | * return status; 95 | * } 96 | * 97 | * Example#3: 98 | * NTSTATUS callback3(WDFOBJECT BffDevice, PIRP Irp) 99 | * { 100 | * ... 101 | * IoCopyCurrentIrpStackLocationToNext(Irp); 102 | * IoSetCompletionRoutine(Irp, IoCompletion, BffDevice, ...); 103 | * status = IoCallDriver(BffDeviceWdmGetAttachedDevice(BffDevice), Irp); 104 | * ... 105 | * return status; 106 | * } 107 | * @param BffDevice The WDF object as a bus filter device object. 108 | * @param Irp The PnP I/O request packet. 109 | * @return 0 or any positive value for success; otherwise for 110 | * failure. 111 | */ 112 | typedef NTSTATUS BFF_DISPATCH_PNP(WDFOBJECT BffDevice, PIRP Irp); 113 | typedef BFF_DISPATCH_PNP *PBFF_DISPATCH_PNP; 114 | 115 | /** Data structure for initialization of Bus Filter Framework. Typically, you 116 | * declare a local variable of this type, and call BffSetInitializationData to 117 | * initialize it. Then, you selectively re-initialize 118 | * PnPMinorFunction[IRP_MN_*] with your own handlers before calling 119 | * BffInitialize. 120 | */ 121 | typedef struct _BFF_INITIALIZATION_DATA 122 | { 123 | /// 124 | /// Size of this structure (Mandatory) 125 | /// 126 | ULONG Size; 127 | 128 | BFF_DEVICE_CONFIG DeviceConfig; 129 | 130 | PBFF_DISPATCH_PNP PnPMinorFunction[IRP_MN_DEVICE_ENUMERATED + 1]; 131 | } BFF_INITIALIZATION_DATA, *PBFF_INITIALIZATION_DATA; 132 | 133 | /******************************************************************************* 134 | * APIs for upper filter device objects. 135 | ******************************************************************************/ 136 | /** Prepare the initialization data for BFF. Obviously, this routine must be 137 | * called before BffInitialize. After this call, 138 | * InitData->PnPMinorFunction[IRP_MN_*] will be NULL-initialized. You may 139 | * selectively re-initialize InitData->PnPMinorFunction[IRP_MN_*] with your own 140 | * handlers before calling BffInitialize. 141 | * @param InitData The pointer to the initialization data, 142 | * typically declared as a local variable. 143 | * @param Type The device type for creation of a bus filter 144 | * device object. 145 | * @param Characteristics The device characteristics for creation of a bus 146 | * filter device object. 147 | * @param DeviceAdd The callback function for creation of a bus 148 | * filter device object. 149 | * @param DeviceRemove The callback function for removal of a bus 150 | * filter device object. 151 | */ 152 | VOID BffSetInitializationData(PBFF_INITIALIZATION_DATA InitData, DEVICE_TYPE Type, ULONG Characteristics, 153 | PBFF_DEVICE_ADD DeviceAdd, PBFF_DEVICE_REMOVE DeviceRemove); 154 | 155 | /** Initialize Bus Filter Framework with the initialization data. This routine 156 | * must be invoked in DriverEntry after a call to WdfDriverCreate. Furthermore, 157 | * a BFF-based driver must be installed with a valid license key to unlock 158 | * functionality of BFF. 159 | * @param DriverObject The same as DriverEntry's first parameter. 160 | * @param RegistryPath The same as DriverEntry's second parameter. 161 | * @param InitData The initialization data previously prepared by a call to 162 | * BffSetInitializationData. 163 | * @return One of the following values: 164 | * (a) 0 or any positive value for success; 165 | * (b) STATUS_NOT_SUPPORTED if the driver has not called 166 | * WdfDriverCreate; 167 | * (c) STATUS_INVALID_PARAMETER if an invalid parameter is 168 | * speciifed; 169 | * (d) STATUS_INVALID_SIGNATURE if no valid license key in 170 | * registry; or 171 | * (e) Any other negative value for failure. 172 | */ 173 | NTSTATUS BffInitialize(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath, PBFF_INITIALIZATION_DATA InitData); 174 | 175 | /** Allocate context space for an upper filter device object on behalf of Bus 176 | * Filter Framework. This routine is typically called in the EvtDriverDeviceAdd 177 | * callback function. 178 | * @param Device The WDF device object representing an upper filter 179 | * device object. 180 | * @return The value that WdfObjectAllocateContext returns. 181 | */ 182 | NTSTATUS BffAllocateContext(WDFDEVICE Device); 183 | 184 | /** The callback function for an upper filter driver to preprocess 185 | * IRP_MN_QUERY_DEVICE_RELATIONS/BusRelations before KMDF. This routine can be 186 | * passed as EvtDeviceWdmIrpPreprocess into 187 | * WdfDeviceInitAssignWdmIrpPreprocessCallback for IRP_MJ_PNP/ 188 | * IRP_MN_QUERY_DEVICE_RELATIONS, or be invoked in an upper filter driver's 189 | * EvtDeviceWdmIrpPreprocess callback function. In the latter case, the upper 190 | * filter driver must return the value that this routine returns. 191 | * @param Device The WDF device object representing an upper filter 192 | * device object. 193 | * @param Irp The IRP_MN_QUERY_DEVICE_RELATIONS I/O request packet. 194 | * @return The value that WdfDeviceWdmDispatchPreprocessedIrp returns. 195 | */ 196 | NTSTATUS BffPreprocessQueryBusRelations(WDFDEVICE Device, PIRP Irp); 197 | 198 | /******************************************************************************* 199 | * APIs for bus filter device objects. 200 | ******************************************************************************/ 201 | /** Retrieve the WDM bus filter device object that is associated with the 202 | * specified WDF object. 203 | * @param BffDevice The WDF object as a bus filter device object. 204 | * @return The WDM bus filter device object for success; NULL 205 | * otherwise. 206 | */ 207 | PDEVICE_OBJECT BffDeviceWdmGetDeviceObject(WDFOBJECT BffDevice); 208 | 209 | /** Retrieve the next lower WDM device object in the device stack of the 210 | * specified WDF object. 211 | * @param BffDevice The WDF object as a bus filter device object. 212 | * @return The next lower WDM device object for success; NULL 213 | * otherwise. 214 | */ 215 | PDEVICE_OBJECT BffDeviceWdmGetAttachedDevice(WDFOBJECT BffDevice); 216 | 217 | /** Retrieve the PDO from the device stack of the specified WDF object. 218 | * @param BffDevice The WDF object as a bus filter device object. 219 | * @return The PDO for success; NULL otherwise. 220 | */ 221 | PDEVICE_OBJECT BffDeviceWdmGetPhysicalDevice(WDFOBJECT BffDevice); 222 | -------------------------------------------------------------------------------- /bff/bff.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {A1E905CB-21AF-4167-87D9-90927A7A67C6} 46 | {0a049372-4c4d-4ea0-a64e-dc6ad88ceca1} 47 | v4.5 48 | 12.0 49 | Debug 50 | Win32 51 | bff 52 | KMDF 53 | 54 | 55 | 56 | Windows7 57 | true 58 | WindowsKernelModeDriver10.0 59 | StaticLibrary 60 | Desktop 61 | 62 | 63 | Windows7 64 | false 65 | WindowsKernelModeDriver10.0 66 | StaticLibrary 67 | Desktop 68 | 69 | 70 | Windows7 71 | true 72 | WindowsKernelModeDriver10.0 73 | StaticLibrary 74 | Desktop 75 | 76 | 77 | Windows10 78 | false 79 | WindowsKernelModeDriver10.0 80 | StaticLibrary 81 | Desktop 82 | 83 | 84 | Windows7 85 | true 86 | WindowsKernelModeDriver10.0 87 | StaticLibrary 88 | Desktop 89 | 90 | 91 | Windows7 92 | false 93 | WindowsKernelModeDriver10.0 94 | StaticLibrary 95 | Desktop 96 | 97 | 98 | Windows7 99 | true 100 | WindowsKernelModeDriver10.0 101 | StaticLibrary 102 | Desktop 103 | 104 | 105 | Windows7 106 | false 107 | WindowsKernelModeDriver10.0 108 | StaticLibrary 109 | Desktop 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | false 120 | 121 | 122 | false 123 | 124 | 125 | false 126 | 127 | 128 | false 129 | 130 | 131 | 132 | copy bff.h ..\bffsample\bff 133 | 134 | 135 | 136 | 137 | copy bff.h ..\bffsample\bff 138 | 139 | 140 | 4100;%(DisableSpecificWarnings) 141 | 142 | 143 | 144 | 145 | copy bff.h ..\bffsample\bff 146 | 147 | 148 | 149 | 150 | copy bff.h ..\bffsample\bff 151 | 152 | 153 | 4100;%(DisableSpecificWarnings) 154 | 155 | 156 | 157 | 158 | copy bff.h ..\bffsample\bff 159 | 160 | 161 | 162 | 163 | copy bff.h ..\bffsample\bff 164 | 165 | 166 | 4100;%(DisableSpecificWarnings) 167 | 168 | 169 | 170 | 171 | copy bff.h ..\bffsample\bff 172 | 173 | 174 | 175 | 176 | copy bff.h ..\bffsample\bff 177 | 178 | 179 | 4100;%(DisableSpecificWarnings) 180 | 181 | 182 | 183 | 184 | copy bff.h ..\bffsample\bff 185 | 186 | 187 | 188 | 189 | copy bff.h ..\bffsample\bff 190 | 191 | 192 | 4100;%(DisableSpecificWarnings) 193 | 194 | 195 | 196 | 197 | copy bff.h ..\bffsample\bff 198 | 199 | 200 | 201 | 202 | copy bff.h ..\bffsample\bff 203 | 204 | 205 | 4100;%(DisableSpecificWarnings) 206 | 207 | 208 | 209 | 210 | copy bff.h ..\bffsample\bff 211 | 212 | 213 | 214 | 215 | copy bff.h ..\bffsample\bff 216 | 217 | 218 | 4100;%(DisableSpecificWarnings) 219 | 220 | 221 | 222 | 223 | copy bff.h ..\bffsample\bff 224 | 225 | 226 | 227 | 228 | copy bff.h ..\bffsample\bff 229 | 230 | 231 | 4100;%(DisableSpecificWarnings) 232 | 233 | 234 | 235 | 236 | 237 | -------------------------------------------------------------------------------- /bff/bff.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /bff/private.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Bus Filter Framework (BFF) 3 | 4 | A framework for KMDF-based upper filter drivers to behave as bus filters. 5 | You don't need to write WDM drivers any more! 6 | 7 | https://bus-filter-framework.blogspot.com/ 8 | 9 | Copyright (C) 2017 Yang Yuanzhi 10 | 11 | This program is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program. If not, see . 23 | *******************************************************************************/ 24 | #pragma once 25 | #include 26 | #include 27 | 28 | // 29 | // Bus Filter Device Extension 30 | // 31 | 32 | typedef struct _DEVICE_EXTENSION 33 | { 34 | GUID Signature; 35 | // 36 | // Target Device Object 37 | // 38 | 39 | PDEVICE_OBJECT TargetDeviceObject; 40 | 41 | // 42 | // Physical device object 43 | // 44 | PDEVICE_OBJECT PhysicalDeviceObject; 45 | 46 | LIST_ENTRY List; 47 | WDFDEVICE Parent; // The upper filter of the parent bus 48 | WDFOBJECT Child; 49 | BOOLEAN Existing; 50 | } DEVICE_EXTENSION, *PDEVICE_EXTENSION; 51 | 52 | #define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION) 53 | 54 | typedef struct _BFF_DEVICE_CONTEXT 55 | { 56 | // 57 | // Back pointer to device object 58 | // 59 | 60 | PDEVICE_OBJECT DeviceObject; 61 | } BFF_DEVICE_CONTEXT, *PBFF_DEVICE_CONTEXT; 62 | 63 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(BFF_DEVICE_CONTEXT, BffGetDeviceContext) 64 | 65 | // 66 | // The device context performs the same job as 67 | // a WDM device extension in the driver frameworks 68 | // 69 | typedef struct _BFF_PARENT_CONTEXT 70 | { 71 | LIST_ENTRY List; // Child list 72 | KSPIN_LOCK Lock; // Lock for child list 73 | } BFF_PARENT_CONTEXT, *PBFF_PARENT_CONTEXT; 74 | 75 | // 76 | // This macro will generate an inline function called BffGetParentContext 77 | // which will be used to get a pointer to the device context memory 78 | // in a type safe manner. 79 | // 80 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(BFF_PARENT_CONTEXT, BffGetParentContext) 81 | --------------------------------------------------------------------------------